Reactos
at master 968 lines 30 kB view raw
1/* 2 * Copyright 2010 Piotr Caban for CodeWeavers 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 17 */ 18 19#define COBJMACROS 20#define CONST_VTABLE 21#ifndef __REACTOS__ 22#define NONAMELESSUNION 23#endif 24 25#include <stdio.h> 26#include <wine/test.h> 27 28#include "winbase.h" 29#include "shlobj.h" 30#include "shellapi.h" 31#include "initguid.h" 32 33DEFINE_GUID(FMTID_Test,0x12345678,0x1234,0x1234,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12); 34DEFINE_GUID(FMTID_NotExisting, 0x12345678,0x1234,0x1234,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x13); 35DEFINE_GUID(CLSID_ClassMoniker, 0x0000031a,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); 36 37#define DEFINE_EXPECT(func) \ 38 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE 39 40#define SET_EXPECT(func) \ 41 expect_ ## func = TRUE 42 43#define CHECK_EXPECT2(func) \ 44 do { \ 45 ok(expect_ ##func, "unexpected call " #func "\n"); \ 46 called_ ## func = TRUE; \ 47 }while(0) 48 49#define CHECK_EXPECT(func) \ 50 do { \ 51 CHECK_EXPECT2(func); \ 52 expect_ ## func = FALSE; \ 53 }while(0) 54 55#define CHECK_CALLED(func) \ 56 do { \ 57 ok(called_ ## func, "expected " #func "\n"); \ 58 expect_ ## func = called_ ## func = FALSE; \ 59 }while(0) 60 61DEFINE_EXPECT(Create); 62DEFINE_EXPECT(Delete); 63DEFINE_EXPECT(Open); 64DEFINE_EXPECT(ReadMultiple); 65DEFINE_EXPECT(ReadMultipleCodePage); 66DEFINE_EXPECT(Release); 67DEFINE_EXPECT(Stat); 68DEFINE_EXPECT(WriteMultiple); 69 70DEFINE_EXPECT(autoplay_BindToObject); 71DEFINE_EXPECT(autoplay_GetClassObject); 72 73static HRESULT (WINAPI *pSHPropStgCreate)(IPropertySetStorage*, REFFMTID, const CLSID*, 74 DWORD, DWORD, DWORD, IPropertyStorage**, UINT*); 75static HRESULT (WINAPI *pSHPropStgReadMultiple)(IPropertyStorage*, UINT, 76 ULONG, const PROPSPEC*, PROPVARIANT*); 77static HRESULT (WINAPI *pSHPropStgWriteMultiple)(IPropertyStorage*, UINT*, 78 ULONG, const PROPSPEC*, PROPVARIANT*, PROPID); 79static HRESULT (WINAPI *pSHCreateQueryCancelAutoPlayMoniker)(IMoniker**); 80static HRESULT (WINAPI *pSHCreateSessionKey)(REGSAM, HKEY*); 81 82static void init(void) 83{ 84 HMODULE hmod = GetModuleHandleA("shell32.dll"); 85 86 pSHPropStgCreate = (void*)GetProcAddress(hmod, "SHPropStgCreate"); 87 pSHPropStgReadMultiple = (void*)GetProcAddress(hmod, "SHPropStgReadMultiple"); 88 pSHPropStgWriteMultiple = (void*)GetProcAddress(hmod, "SHPropStgWriteMultiple"); 89 pSHCreateQueryCancelAutoPlayMoniker = (void*)GetProcAddress(hmod, "SHCreateQueryCancelAutoPlayMoniker"); 90 pSHCreateSessionKey = (void*)GetProcAddress(hmod, (char*)723); 91} 92 93static HRESULT WINAPI PropertyStorage_QueryInterface(IPropertyStorage *This, 94 REFIID riid, void **ppvObject) 95{ 96 ok(0, "unexpected call\n"); 97 return E_NOTIMPL; 98} 99 100static ULONG WINAPI PropertyStorage_AddRef(IPropertyStorage *This) 101{ 102 ok(0, "unexpected call\n"); 103 return 2; 104} 105 106static ULONG WINAPI PropertyStorage_Release(IPropertyStorage *This) 107{ 108 CHECK_EXPECT(Release); 109 return 1; 110} 111 112static HRESULT WINAPI PropertyStorage_ReadMultiple(IPropertyStorage *This, ULONG cpspec, 113 const PROPSPEC *rgpspec, PROPVARIANT *rgpropvar) 114{ 115 if(cpspec == 1) { 116 CHECK_EXPECT(ReadMultipleCodePage); 117 118 ok(rgpspec != NULL, "rgpspec = NULL\n"); 119 ok(rgpropvar != NULL, "rgpropvar = NULL\n"); 120 121 ok(rgpspec[0].ulKind == PRSPEC_PROPID, "rgpspec[0].ulKind = %d\n", rgpspec[0].ulKind); 122 ok(rgpspec[0].propid == PID_CODEPAGE, "rgpspec[0].propid = %d\n", rgpspec[0].propid); 123 124 rgpropvar[0].vt = VT_I2; 125 rgpropvar[0].iVal = 1234; 126 } else { 127 CHECK_EXPECT(ReadMultiple); 128 129 ok(cpspec == 10, "cpspec = %u\n", cpspec); 130 ok(rgpspec == (void*)0xdeadbeef, "rgpspec = %p\n", rgpspec); 131 ok(rgpropvar != NULL, "rgpropvar = NULL\n"); 132 133 ok(rgpropvar[0].vt==0 || broken(rgpropvar[0].vt==VT_BSTR), "rgpropvar[0].vt = %d\n", rgpropvar[0].vt); 134 135 rgpropvar[0].vt = VT_BSTR; 136 rgpropvar[0].bstrVal = (void*)0xdeadbeef; 137 rgpropvar[1].vt = VT_LPSTR; 138 rgpropvar[1].pszVal = (void*)0xdeadbeef; 139 rgpropvar[2].vt = VT_BYREF|VT_I1; 140 rgpropvar[2].pcVal = (void*)0xdeadbeef; 141 rgpropvar[3].vt = VT_BYREF|VT_VARIANT; 142 rgpropvar[3].pvarVal = (void*)0xdeadbeef; 143 } 144 145 return S_OK; 146} 147 148static HRESULT WINAPI PropertyStorage_WriteMultiple(IPropertyStorage *This, ULONG cpspec, 149 const PROPSPEC *rgpspec, const PROPVARIANT *rgpropvar, 150 PROPID propidNameFirst) 151{ 152 CHECK_EXPECT(WriteMultiple); 153 154 ok(cpspec == 20, "cpspec = %d\n", cpspec); 155 ok(rgpspec == (void*)0xdeadbeef, "rgpspec = %p\n", rgpspec); 156 ok(rgpropvar == (void*)0xdeadbeef, "rgpropvar = %p\n", rgpspec); 157 ok(propidNameFirst == PID_FIRST_USABLE, "propidNameFirst = %d\n", propidNameFirst); 158 return S_OK; 159} 160 161static HRESULT WINAPI PropertyStorage_DeleteMultiple(IPropertyStorage *This, ULONG cpspec, 162 const PROPSPEC *rgpspec) 163{ 164 ok(0, "unexpected call\n"); 165 return E_NOTIMPL; 166} 167 168static HRESULT WINAPI PropertyStorage_ReadPropertyNames(IPropertyStorage *This, ULONG cpropid, 169 const PROPID *rgpropid, LPOLESTR *rglpwstrName) 170{ 171 ok(0, "unexpected call\n"); 172 return E_NOTIMPL; 173} 174 175static HRESULT WINAPI PropertyStorage_WritePropertyNames(IPropertyStorage *This, ULONG cpropid, 176 const PROPID *rgpropid, const LPOLESTR *rglpwstrName) 177{ 178 ok(0, "unexpected call\n"); 179 return E_NOTIMPL; 180} 181 182static HRESULT WINAPI PropertyStorage_DeletePropertyNames(IPropertyStorage *This, ULONG cpropid, 183 const PROPID *rgpropid) 184{ 185 ok(0, "unexpected call\n"); 186 return E_NOTIMPL; 187} 188 189static HRESULT WINAPI PropertyStorage_Commit(IPropertyStorage *This, DWORD grfCommitFlags) 190{ 191 ok(0, "unexpected call\n"); 192 return E_NOTIMPL; 193} 194 195static HRESULT WINAPI PropertyStorage_Revert(IPropertyStorage *This) 196{ 197 ok(0, "unexpected call\n"); 198 return E_NOTIMPL; 199} 200 201static HRESULT WINAPI PropertyStorage_Enum(IPropertyStorage *This, IEnumSTATPROPSTG **ppenum) 202{ 203 ok(0, "unexpected call\n"); 204 return E_NOTIMPL; 205} 206 207static HRESULT WINAPI PropertyStorage_SetTimes(IPropertyStorage *This, const FILETIME *pctime, 208 const FILETIME *patime, const FILETIME *pmtime) 209{ 210 ok(0, "unexpected call\n"); 211 return E_NOTIMPL; 212} 213 214static HRESULT WINAPI PropertyStorage_SetClass(IPropertyStorage *This, REFCLSID clsid) 215{ 216 ok(0, "unexpected call\n"); 217 return E_NOTIMPL; 218} 219 220static HRESULT WINAPI PropertyStorage_Stat(IPropertyStorage *This, STATPROPSETSTG *statpsstg) 221{ 222 CHECK_EXPECT(Stat); 223 224 memset(statpsstg, 0, sizeof(STATPROPSETSTG)); 225 memcpy(&statpsstg->fmtid, &FMTID_Test, sizeof(FMTID)); 226 statpsstg->grfFlags = PROPSETFLAG_ANSI; 227 return S_OK; 228} 229 230static IPropertyStorageVtbl PropertyStorageVtbl = { 231 PropertyStorage_QueryInterface, 232 PropertyStorage_AddRef, 233 PropertyStorage_Release, 234 PropertyStorage_ReadMultiple, 235 PropertyStorage_WriteMultiple, 236 PropertyStorage_DeleteMultiple, 237 PropertyStorage_ReadPropertyNames, 238 PropertyStorage_WritePropertyNames, 239 PropertyStorage_DeletePropertyNames, 240 PropertyStorage_Commit, 241 PropertyStorage_Revert, 242 PropertyStorage_Enum, 243 PropertyStorage_SetTimes, 244 PropertyStorage_SetClass, 245 PropertyStorage_Stat 246}; 247 248static IPropertyStorage PropertyStorage = { &PropertyStorageVtbl }; 249 250static HRESULT WINAPI PropertySetStorage_QueryInterface(IPropertySetStorage *This, 251 REFIID riid, void **ppvObject) 252{ 253 ok(0, "unexpected call\n"); 254 return E_NOTIMPL; 255} 256 257static ULONG WINAPI PropertySetStorage_AddRef(IPropertySetStorage *This) 258{ 259 ok(0, "unexpected call\n"); 260 return 2; 261} 262 263static ULONG WINAPI PropertySetStorage_Release(IPropertySetStorage *This) 264{ 265 ok(0, "unexpected call\n"); 266 return 1; 267} 268 269static HRESULT WINAPI PropertySetStorage_Create(IPropertySetStorage *This, 270 REFFMTID rfmtid, const CLSID *pclsid, DWORD grfFlags, 271 DWORD grfMode, IPropertyStorage **ppprstg) 272{ 273 CHECK_EXPECT(Create); 274 ok(IsEqualGUID(rfmtid, &FMTID_Test) || IsEqualGUID(rfmtid, &FMTID_NotExisting), 275 "Incorrect rfmtid value\n"); 276 ok(pclsid == NULL, "pclsid != NULL\n"); 277 ok(grfFlags == PROPSETFLAG_ANSI, "grfFlags = %x\n", grfFlags); 278 ok(grfMode == STGM_READ, "grfMode = %x\n", grfMode); 279 280 *ppprstg = &PropertyStorage; 281 return S_OK; 282} 283 284static HRESULT WINAPI PropertySetStorage_Open(IPropertySetStorage *This, 285 REFFMTID rfmtid, DWORD grfMode, IPropertyStorage **ppprstg) 286{ 287 CHECK_EXPECT(Open); 288 289 if(IsEqualGUID(rfmtid, &FMTID_Test)) { 290 ok(grfMode == STGM_READ, "grfMode = %x\n", grfMode); 291 292 *ppprstg = &PropertyStorage; 293 return S_OK; 294 } 295 296 return STG_E_FILENOTFOUND; 297} 298 299static HRESULT WINAPI PropertySetStorage_Delete(IPropertySetStorage *This, 300 REFFMTID rfmtid) 301{ 302 CHECK_EXPECT(Delete); 303 ok(IsEqualGUID(rfmtid, &FMTID_Test), "wrong rfmtid value\n"); 304 return S_OK; 305} 306 307static HRESULT WINAPI PropertySetStorage_Enum(IPropertySetStorage *This, 308 IEnumSTATPROPSETSTG **ppenum) 309{ 310 ok(0, "unexpected call\n"); 311 return E_NOTIMPL; 312} 313 314static IPropertySetStorageVtbl PropertySetStorageVtbl = { 315 PropertySetStorage_QueryInterface, 316 PropertySetStorage_AddRef, 317 PropertySetStorage_Release, 318 PropertySetStorage_Create, 319 PropertySetStorage_Open, 320 PropertySetStorage_Delete, 321 PropertySetStorage_Enum 322}; 323 324static IPropertySetStorage PropertySetStorage = { &PropertySetStorageVtbl }; 325 326static void test_SHPropStg_functions(void) 327{ 328 IPropertyStorage *property_storage; 329 UINT codepage; 330 PROPVARIANT read[10]; 331 HRESULT hres; 332 333 if(!pSHPropStgCreate || !pSHPropStgReadMultiple || !pSHPropStgWriteMultiple) { 334 win_skip("SHPropStg* functions are missing\n"); 335 return; 336 } 337 338 if(0) { 339 /* Crashes on Windows */ 340 pSHPropStgCreate(NULL, &FMTID_Test, NULL, PROPSETFLAG_DEFAULT, 341 STGM_READ, OPEN_EXISTING, &property_storage, &codepage); 342 pSHPropStgCreate(&PropertySetStorage, NULL, NULL, PROPSETFLAG_DEFAULT, 343 STGM_READ, OPEN_EXISTING, &property_storage, &codepage); 344 pSHPropStgCreate(&PropertySetStorage, &FMTID_Test, NULL, PROPSETFLAG_DEFAULT, 345 STGM_READ, OPEN_EXISTING, NULL, &codepage); 346 } 347 348 SET_EXPECT(Open); 349 SET_EXPECT(ReadMultipleCodePage); 350 hres = pSHPropStgCreate(&PropertySetStorage, &FMTID_Test, NULL, PROPSETFLAG_DEFAULT, 351 STGM_READ, OPEN_EXISTING, &property_storage, &codepage); 352 ok(codepage == 1234, "codepage = %d\n", codepage); 353 ok(hres == S_OK, "hres = %x\n", hres); 354 CHECK_CALLED(Open); 355 CHECK_CALLED(ReadMultipleCodePage); 356 357 SET_EXPECT(Open); 358 hres = pSHPropStgCreate(&PropertySetStorage, &FMTID_NotExisting, NULL, 359 PROPSETFLAG_DEFAULT, STGM_READ, OPEN_EXISTING, &property_storage, &codepage); 360 ok(hres == STG_E_FILENOTFOUND, "hres = %x\n", hres); 361 CHECK_CALLED(Open); 362 363 SET_EXPECT(Open); 364 SET_EXPECT(Release); 365 SET_EXPECT(Delete); 366 SET_EXPECT(Create); 367 SET_EXPECT(ReadMultipleCodePage); 368 hres = pSHPropStgCreate(&PropertySetStorage, &FMTID_Test, NULL, PROPSETFLAG_ANSI, 369 STGM_READ, CREATE_ALWAYS, &property_storage, &codepage); 370 ok(codepage == 1234, "codepage = %d\n", codepage); 371 ok(hres == S_OK, "hres = %x\n", hres); 372 CHECK_CALLED(Open); 373 CHECK_CALLED(Release); 374 CHECK_CALLED(Delete); 375 CHECK_CALLED(Create); 376 CHECK_CALLED(ReadMultipleCodePage); 377 378 SET_EXPECT(Open); 379 SET_EXPECT(Create); 380 SET_EXPECT(ReadMultipleCodePage); 381 hres = pSHPropStgCreate(&PropertySetStorage, &FMTID_NotExisting, NULL, PROPSETFLAG_ANSI, 382 STGM_READ, CREATE_ALWAYS, &property_storage, &codepage); 383 ok(codepage == 1234, "codepage = %d\n", codepage); 384 ok(hres == S_OK, "hres = %x\n", hres); 385 CHECK_CALLED(Open); 386 CHECK_CALLED(Create); 387 CHECK_CALLED(ReadMultipleCodePage); 388 389 SET_EXPECT(Open); 390 hres = pSHPropStgCreate(&PropertySetStorage, &FMTID_Test, &FMTID_NotExisting, 391 PROPSETFLAG_DEFAULT, STGM_READ, OPEN_EXISTING, &property_storage, NULL); 392 ok(hres == S_OK, "hres = %x\n", hres); 393 CHECK_CALLED(Open); 394 395 SET_EXPECT(Stat); 396 SET_EXPECT(ReadMultipleCodePage); 397 SET_EXPECT(WriteMultiple); 398 codepage = 0; 399 hres = pSHPropStgWriteMultiple(property_storage, &codepage, 20, (void*)0xdeadbeef, (void*)0xdeadbeef, PID_FIRST_USABLE); 400 ok(hres == S_OK, "hres = %x\n", hres); 401 ok(codepage == 1234, "codepage = %d\n", codepage); 402 CHECK_CALLED(Stat); 403 CHECK_CALLED(ReadMultipleCodePage); 404 CHECK_CALLED(WriteMultiple); 405 406 SET_EXPECT(Stat); 407 SET_EXPECT(ReadMultipleCodePage); 408 SET_EXPECT(WriteMultiple); 409 hres = pSHPropStgWriteMultiple(property_storage, NULL, 20, (void*)0xdeadbeef, (void*)0xdeadbeef, PID_FIRST_USABLE); 410 ok(hres == S_OK, "hres = %x\n", hres); 411 CHECK_CALLED(Stat); 412 CHECK_CALLED(ReadMultipleCodePage); 413 CHECK_CALLED(WriteMultiple); 414 415 SET_EXPECT(Stat); 416 SET_EXPECT(WriteMultiple); 417 codepage = 1000; 418 hres = pSHPropStgWriteMultiple(property_storage, &codepage, 20, (void*)0xdeadbeef, (void*)0xdeadbeef, PID_FIRST_USABLE); 419 ok(hres == S_OK, "hres = %x\n", hres); 420 ok(codepage == 1000, "codepage = %d\n", codepage); 421 CHECK_CALLED(Stat); 422 CHECK_CALLED(WriteMultiple); 423 424 read[0].vt = VT_BSTR; 425 read[0].bstrVal = (void*)0xdeadbeef; 426 SET_EXPECT(ReadMultiple); 427 SET_EXPECT(ReadMultipleCodePage); 428 SET_EXPECT(Stat); 429 hres = pSHPropStgReadMultiple(property_storage, 0, 10, (void*)0xdeadbeef, read); 430 ok(hres == S_OK, "hres = %x\n", hres); 431 CHECK_CALLED(ReadMultiple); 432 CHECK_CALLED(ReadMultipleCodePage); 433 CHECK_CALLED(Stat); 434 435 SET_EXPECT(ReadMultiple); 436 SET_EXPECT(Stat); 437 hres = pSHPropStgReadMultiple(property_storage, 1251, 10, (void*)0xdeadbeef, read); 438 ok(hres == S_OK, "hres = %x\n", hres); 439 CHECK_CALLED(ReadMultiple); 440 CHECK_CALLED(Stat); 441} 442 443static HRESULT WINAPI test_activator_QI(IClassActivator *iface, REFIID riid, void **ppv) 444{ 445 *ppv = NULL; 446 447 if (IsEqualIID(riid, &IID_IUnknown) || 448 IsEqualIID(riid, &IID_IClassActivator)) 449 { 450 *ppv = iface; 451 } 452 453 if (!*ppv) return E_NOINTERFACE; 454 455 IClassActivator_AddRef(iface); 456 457 return S_OK; 458} 459 460static ULONG WINAPI test_activator_AddRef(IClassActivator *iface) 461{ 462 return 2; 463} 464 465static ULONG WINAPI test_activator_Release(IClassActivator *iface) 466{ 467 return 1; 468} 469 470static HRESULT WINAPI test_activator_GetClassObject(IClassActivator *iface, REFCLSID clsid, 471 DWORD context, LCID locale, REFIID riid, void **ppv) 472{ 473 CHECK_EXPECT(autoplay_GetClassObject); 474 ok(IsEqualGUID(clsid, &CLSID_QueryCancelAutoPlay), "clsid %s\n", wine_dbgstr_guid(clsid)); 475 ok(IsEqualIID(riid, &IID_IQueryCancelAutoPlay), "riid %s\n", wine_dbgstr_guid(riid)); 476 return E_NOTIMPL; 477} 478 479static const IClassActivatorVtbl test_activator_vtbl = { 480 test_activator_QI, 481 test_activator_AddRef, 482 test_activator_Release, 483 test_activator_GetClassObject 484}; 485 486static IClassActivator test_activator = { &test_activator_vtbl }; 487 488static HRESULT WINAPI test_moniker_QueryInterface(IMoniker* iface, REFIID riid, void **ppvObject) 489{ 490 *ppvObject = 0; 491 492 if (IsEqualIID(&IID_IUnknown, riid) || 493 IsEqualIID(&IID_IPersist, riid) || 494 IsEqualIID(&IID_IPersistStream, riid) || 495 IsEqualIID(&IID_IMoniker, riid)) 496 { 497 *ppvObject = iface; 498 } 499 500 if (!*ppvObject) 501 return E_NOINTERFACE; 502 503 return S_OK; 504} 505 506static ULONG WINAPI test_moniker_AddRef(IMoniker* iface) 507{ 508 return 2; 509} 510 511static ULONG WINAPI test_moniker_Release(IMoniker* iface) 512{ 513 return 1; 514} 515 516static HRESULT WINAPI test_moniker_GetClassID(IMoniker* iface, CLSID *pClassID) 517{ 518 ok(0, "unexpected call\n"); 519 return E_NOTIMPL; 520} 521 522static HRESULT WINAPI test_moniker_IsDirty(IMoniker* iface) 523{ 524 ok(0, "unexpected call\n"); 525 return E_NOTIMPL; 526} 527 528static HRESULT WINAPI test_moniker_Load(IMoniker* iface, IStream* pStm) 529{ 530 ok(0, "unexpected call\n"); 531 return E_NOTIMPL; 532} 533 534static HRESULT WINAPI test_moniker_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty) 535{ 536 ok(0, "unexpected call\n"); 537 return E_NOTIMPL; 538} 539 540static HRESULT WINAPI test_moniker_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize) 541{ 542 ok(0, "unexpected call\n"); 543 return E_NOTIMPL; 544} 545 546static HRESULT WINAPI test_moniker_BindToObject(IMoniker* iface, 547 IBindCtx* pbc, 548 IMoniker* moniker_to_left, 549 REFIID riid, 550 void** ppv) 551{ 552 CHECK_EXPECT(autoplay_BindToObject); 553 ok(pbc != NULL, "got %p\n", pbc); 554 ok(moniker_to_left == NULL, "got %p\n", moniker_to_left); 555 ok(IsEqualIID(riid, &IID_IClassActivator), "got riid %s\n", wine_dbgstr_guid(riid)); 556 557 if (IsEqualIID(riid, &IID_IClassActivator)) 558 { 559 *ppv = &test_activator; 560 return S_OK; 561 } 562 563 return E_NOTIMPL; 564} 565 566static HRESULT WINAPI test_moniker_BindToStorage(IMoniker* iface, 567 IBindCtx* pbc, 568 IMoniker* pmkToLeft, 569 REFIID riid, 570 VOID** ppvResult) 571{ 572 ok(0, "unexpected call\n"); 573 return E_NOTIMPL; 574} 575 576static HRESULT WINAPI test_moniker_Reduce(IMoniker* iface, 577 IBindCtx* pbc, 578 DWORD dwReduceHowFar, 579 IMoniker** ppmkToLeft, 580 IMoniker** ppmkReduced) 581{ 582 ok(0, "unexpected call\n"); 583 return E_NOTIMPL; 584} 585 586static HRESULT WINAPI test_moniker_ComposeWith(IMoniker* iface, 587 IMoniker* pmkRight, 588 BOOL fOnlyIfNotGeneric, 589 IMoniker** ppmkComposite) 590{ 591 ok(0, "unexpected call\n"); 592 return E_NOTIMPL; 593} 594 595static HRESULT WINAPI test_moniker_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker) 596{ 597 ok(0, "unexpected call\n"); 598 return E_NOTIMPL; 599} 600 601static HRESULT WINAPI test_moniker_IsEqual(IMoniker* iface, IMoniker* pmkOtherMoniker) 602{ 603 ok(0, "unexpected call\n"); 604 return E_NOTIMPL; 605} 606 607static HRESULT WINAPI test_moniker_Hash(IMoniker* iface, DWORD* pdwHash) 608{ 609 ok(0, "unexpected call\n"); 610 return E_NOTIMPL; 611} 612 613static HRESULT WINAPI test_moniker_IsRunning(IMoniker* iface, 614 IBindCtx* pbc, 615 IMoniker* pmkToLeft, 616 IMoniker* pmkNewlyRunning) 617{ 618 ok(0, "unexpected call\n"); 619 return E_NOTIMPL; 620} 621 622static HRESULT WINAPI test_moniker_GetTimeOfLastChange(IMoniker* iface, 623 IBindCtx* pbc, 624 IMoniker* pmkToLeft, 625 FILETIME* pItemTime) 626{ 627 ok(0, "unexpected call\n"); 628 return E_NOTIMPL; 629} 630 631static HRESULT WINAPI test_moniker_Inverse(IMoniker* iface, IMoniker** ppmk) 632{ 633 ok(0, "unexpected call\n"); 634 return E_NOTIMPL; 635} 636 637static HRESULT WINAPI test_moniker_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix) 638{ 639 ok(0, "unexpected call\n"); 640 return E_NOTIMPL; 641} 642 643static HRESULT WINAPI test_moniker_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath) 644{ 645 ok(0, "unexpected call\n"); 646 return E_NOTIMPL; 647} 648 649static HRESULT WINAPI test_moniker_GetDisplayName(IMoniker* iface, 650 IBindCtx* pbc, 651 IMoniker* pmkToLeft, 652 LPOLESTR *ppszDisplayName) 653{ 654 ok(0, "unexpected call\n"); 655 return E_NOTIMPL; 656} 657 658static HRESULT WINAPI test_moniker_ParseDisplayName(IMoniker* iface, 659 IBindCtx* pbc, 660 IMoniker* pmkToLeft, 661 LPOLESTR pszDisplayName, 662 ULONG* pchEaten, 663 IMoniker** ppmkOut) 664{ 665 ok(0, "unexpected call\n"); 666 return E_NOTIMPL; 667} 668 669static HRESULT WINAPI test_moniker_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys) 670{ 671 ok(0, "unexpected call\n"); 672 return E_NOTIMPL; 673} 674 675static const IMonikerVtbl test_moniker_vtbl = 676{ 677 test_moniker_QueryInterface, 678 test_moniker_AddRef, 679 test_moniker_Release, 680 test_moniker_GetClassID, 681 test_moniker_IsDirty, 682 test_moniker_Load, 683 test_moniker_Save, 684 test_moniker_GetSizeMax, 685 test_moniker_BindToObject, 686 test_moniker_BindToStorage, 687 test_moniker_Reduce, 688 test_moniker_ComposeWith, 689 test_moniker_Enum, 690 test_moniker_IsEqual, 691 test_moniker_Hash, 692 test_moniker_IsRunning, 693 test_moniker_GetTimeOfLastChange, 694 test_moniker_Inverse, 695 test_moniker_CommonPrefixWith, 696 test_moniker_RelativePathTo, 697 test_moniker_GetDisplayName, 698 test_moniker_ParseDisplayName, 699 test_moniker_IsSystemMoniker 700}; 701 702static IMoniker test_moniker = { &test_moniker_vtbl }; 703 704static void test_SHCreateQueryCancelAutoPlayMoniker(void) 705{ 706 IBindCtx *ctxt; 707 IMoniker *mon; 708 IUnknown *unk; 709 CLSID clsid; 710 HRESULT hr; 711 DWORD sys; 712 713 if (!pSHCreateQueryCancelAutoPlayMoniker) 714 { 715 win_skip("SHCreateQueryCancelAutoPlayMoniker is not available, skipping tests.\n"); 716 return; 717 } 718 719 hr = pSHCreateQueryCancelAutoPlayMoniker(NULL); 720 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 721 722 hr = pSHCreateQueryCancelAutoPlayMoniker(&mon); 723 ok(hr == S_OK, "got 0x%08x\n", hr); 724 725 sys = -1; 726 hr = IMoniker_IsSystemMoniker(mon, &sys); 727 ok(hr == S_OK, "got 0x%08x\n", hr); 728 ok(sys == MKSYS_CLASSMONIKER, "got %d\n", sys); 729 730 memset(&clsid, 0, sizeof(clsid)); 731 hr = IMoniker_GetClassID(mon, &clsid); 732 ok(hr == S_OK, "got 0x%08x\n", hr); 733 ok(IsEqualGUID(&clsid, &CLSID_ClassMoniker), "got %s\n", wine_dbgstr_guid(&clsid)); 734 735 /* extract used CLSID that implements this hook */ 736 SET_EXPECT(autoplay_BindToObject); 737 SET_EXPECT(autoplay_GetClassObject); 738 739 CreateBindCtx(0, &ctxt); 740 hr = IMoniker_BindToObject(mon, ctxt, &test_moniker, &IID_IQueryCancelAutoPlay, (void**)&unk); 741 ok(hr == E_NOTIMPL, "got 0x%08x\n", hr); 742 IBindCtx_Release(ctxt); 743 744 CHECK_CALLED(autoplay_BindToObject); 745 CHECK_CALLED(autoplay_GetClassObject); 746 747 IMoniker_Release(mon); 748} 749 750#define WM_EXPECTED_VALUE WM_APP 751#define DROPTEST_FILENAME "c:\\wintest.bin" 752struct DragParam { 753 HWND hwnd; 754 HANDLE ready; 755}; 756 757static LRESULT WINAPI drop_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) 758{ 759 static BOOL expected; 760 761 switch (msg) { 762 case WM_EXPECTED_VALUE: 763 { 764 expected = lparam; 765 break; 766 } 767 case WM_DROPFILES: 768 { 769 HDROP hDrop = (HDROP)wparam; 770 char filename[MAX_PATH] = "dummy"; 771 POINT pt; 772 BOOL r; 773 UINT num; 774 num = DragQueryFileA(hDrop, 0xffffffff, NULL, 0); 775 ok(num == 1, "expected 1, got %u\n", num); 776 num = DragQueryFileA(hDrop, 0xffffffff, (char*)0xdeadbeef, 0xffffffff); 777 ok(num == 1, "expected 1, got %u\n", num); 778 num = DragQueryFileA(hDrop, 0, filename, sizeof(filename)); 779 ok(num == strlen(DROPTEST_FILENAME), "got %u\n", num); 780 ok(!strcmp(filename, DROPTEST_FILENAME), "got %s\n", filename); 781 r = DragQueryPoint(hDrop, &pt); 782 ok(r == expected, "expected %d, got %d\n", expected, r); 783 ok(pt.x == 10, "expected 10, got %d\n", pt.x); 784 ok(pt.y == 20, "expected 20, got %d\n", pt.y); 785 DragFinish(hDrop); 786 return 0; 787 } 788 } 789 return DefWindowProcA(hwnd, msg, wparam, lparam); 790} 791 792static DWORD WINAPI drop_window_therad(void *arg) 793{ 794 struct DragParam *param = arg; 795 WNDCLASSA cls; 796 WINDOWINFO info; 797 BOOL r; 798 MSG msg; 799 800 memset(&cls, 0, sizeof(cls)); 801 cls.lpfnWndProc = drop_window_proc; 802 cls.hInstance = GetModuleHandleA(NULL); 803 cls.lpszClassName = "drop test"; 804 RegisterClassA(&cls); 805 806 param->hwnd = CreateWindowA("drop test", NULL, 0, 0, 0, 0, 0, 807 NULL, 0, NULL, 0); 808 ok(param->hwnd != NULL, "CreateWindow failed: %d\n", GetLastError()); 809 810 memset(&info, 0, sizeof(info)); 811 info.cbSize = sizeof(info); 812 r = GetWindowInfo(param->hwnd, &info); 813 ok(r, "got %d\n", r); 814 ok(!(info.dwExStyle & WS_EX_ACCEPTFILES), "got %08x\n", info.dwExStyle); 815 816 DragAcceptFiles(param->hwnd, TRUE); 817 818 memset(&info, 0, sizeof(info)); 819 info.cbSize = sizeof(info); 820 r = GetWindowInfo(param->hwnd, &info); 821 ok(r, "got %d\n", r); 822 ok((info.dwExStyle & WS_EX_ACCEPTFILES), "got %08x\n", info.dwExStyle); 823 824 SetEvent(param->ready); 825 826 while ((r = GetMessageA(&msg, NULL, 0, 0)) != 0) { 827 if (r == (BOOL)-1) { 828 ok(0, "unexpected return value, got %d\n", r); 829 break; 830 } 831 DispatchMessageA(&msg); 832 } 833 834 DestroyWindow(param->hwnd); 835 UnregisterClassA("drop test", GetModuleHandleA(NULL)); 836 return 0; 837} 838 839static void test_DragQueryFile(BOOL non_client_flag) 840{ 841 struct DragParam param; 842 HANDLE hThread; 843 DWORD rc; 844 HGLOBAL hDrop; 845 DROPFILES *pDrop; 846 int ret; 847 BOOL r; 848 849 param.ready = CreateEventA(NULL, FALSE, FALSE, NULL); 850 ok(param.ready != NULL, "can't create event\n"); 851 hThread = CreateThread(NULL, 0, drop_window_therad, &param, 0, NULL); 852 853 rc = WaitForSingleObject(param.ready, 5000); 854 ok(rc == WAIT_OBJECT_0, "got %u\n", rc); 855 856 hDrop = GlobalAlloc(GHND, sizeof(DROPFILES) + (strlen(DROPTEST_FILENAME) + 2) * sizeof(WCHAR)); 857 pDrop = GlobalLock(hDrop); 858 pDrop->pt.x = 10; 859 pDrop->pt.y = 20; 860 pDrop->fNC = non_client_flag; 861 pDrop->pFiles = sizeof(DROPFILES); 862 ret = MultiByteToWideChar(CP_ACP, 0, DROPTEST_FILENAME, -1, 863 (LPWSTR)(pDrop + 1), strlen(DROPTEST_FILENAME) + 1); 864 ok(ret > 0, "got %d\n", ret); 865 pDrop->fWide = TRUE; 866 GlobalUnlock(hDrop); 867 868 r = PostMessageA(param.hwnd, WM_EXPECTED_VALUE, 0, !non_client_flag); 869 ok(r, "got %d\n", r); 870 871 r = PostMessageA(param.hwnd, WM_DROPFILES, (WPARAM)hDrop, 0); 872 ok(r, "got %d\n", r); 873 874 r = PostMessageA(param.hwnd, WM_QUIT, 0, 0); 875 ok(r, "got %d\n", r); 876 877 rc = WaitForSingleObject(hThread, 5000); 878 ok(rc == WAIT_OBJECT_0, "got %d\n", rc); 879 880 CloseHandle(param.ready); 881 CloseHandle(hThread); 882} 883#undef WM_EXPECTED_VALUE 884#undef DROPTEST_FILENAME 885 886static void test_SHCreateSessionKey(void) 887{ 888 static const WCHAR session_format[] = { 889 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\', 890 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 891 'E','x','p','l','o','r','e','r','\\','S','e','s','s','i','o','n','I','n','f','o','\\','%','u',0}; 892 HKEY hkey, hkey2; 893 HRESULT hr; 894 DWORD session; 895 WCHAR sessionW[ARRAY_SIZE(session_format) + 16]; 896 LONG ret; 897 898 if (!pSHCreateSessionKey) 899 { 900 win_skip("SHCreateSessionKey is not implemented\n"); 901 return; 902 } 903 904 if (0) /* crashes on native */ 905 hr = pSHCreateSessionKey(KEY_READ, NULL); 906 907 hkey = (HKEY)0xdeadbeef; 908 hr = pSHCreateSessionKey(0, &hkey); 909 ok(hr == E_ACCESSDENIED, "got 0x%08x\n", hr); 910 ok(hkey == NULL, "got %p\n", hkey); 911 912 hr = pSHCreateSessionKey(KEY_READ, &hkey); 913 ok(hr == S_OK, "got 0x%08x\n", hr); 914 915 hr = pSHCreateSessionKey(KEY_READ, &hkey2); 916 ok(hr == S_OK, "got 0x%08x\n", hr); 917 ok(hkey != hkey2, "got %p, %p\n", hkey, hkey2); 918 919 RegCloseKey(hkey); 920 RegCloseKey(hkey2); 921 922 /* check the registry */ 923 ProcessIdToSessionId( GetCurrentProcessId(), &session); 924 if (session) 925 { 926 wsprintfW(sessionW, session_format, session); 927 ret = RegOpenKeyW(HKEY_CURRENT_USER, sessionW, &hkey); 928 ok(!ret, "key not found\n"); 929 RegCloseKey(hkey); 930 } 931} 932 933static void test_dragdrophelper(void) 934{ 935 IDragSourceHelper *dragsource; 936 IDropTargetHelper *target; 937 HRESULT hr; 938 939 hr = CoCreateInstance(&CLSID_DragDropHelper, NULL, CLSCTX_INPROC_SERVER, &IID_IDropTargetHelper, (void **)&target); 940 ok(hr == S_OK, "Failed to create IDropTargetHelper, %#x\n", hr); 941 942 hr = IDropTargetHelper_QueryInterface(target, &IID_IDragSourceHelper, (void **)&dragsource); 943 ok(hr == S_OK, "QI failed, %#x\n", hr); 944 IDragSourceHelper_Release(dragsource); 945 946 IDropTargetHelper_Release(target); 947} 948 949START_TEST(shellole) 950{ 951 HRESULT hr; 952 953 init(); 954 955 hr = CoInitialize(NULL); 956 ok(hr == S_OK, "CoInitialize failed (0x%08x)\n", hr); 957 if (hr != S_OK) 958 return; 959 960 test_SHPropStg_functions(); 961 test_SHCreateQueryCancelAutoPlayMoniker(); 962 test_DragQueryFile(TRUE); 963 test_DragQueryFile(FALSE); 964 test_SHCreateSessionKey(); 965 test_dragdrophelper(); 966 967 CoUninitialize(); 968}