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 33 DEFINE_GUID(FMTID_Test,0x12345678,0x1234,0x1234,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12); 34 DEFINE_GUID(FMTID_NotExisting, 0x12345678,0x1234,0x1234,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x13); 35 DEFINE_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 61 DEFINE_EXPECT(Create); 62 DEFINE_EXPECT(Delete); 63 DEFINE_EXPECT(Open); 64 DEFINE_EXPECT(ReadMultiple); 65 DEFINE_EXPECT(ReadMultipleCodePage); 66 DEFINE_EXPECT(Release); 67 DEFINE_EXPECT(Stat); 68 DEFINE_EXPECT(WriteMultiple); 69 70 DEFINE_EXPECT(autoplay_BindToObject); 71 DEFINE_EXPECT(autoplay_GetClassObject); 72 73 static HRESULT (WINAPI *pSHPropStgCreate)(IPropertySetStorage*, REFFMTID, const CLSID*, 74 DWORD, DWORD, DWORD, IPropertyStorage**, UINT*); 75 static HRESULT (WINAPI *pSHPropStgReadMultiple)(IPropertyStorage*, UINT, 76 ULONG, const PROPSPEC*, PROPVARIANT*); 77 static HRESULT (WINAPI *pSHPropStgWriteMultiple)(IPropertyStorage*, UINT*, 78 ULONG, const PROPSPEC*, PROPVARIANT*, PROPID); 79 static HRESULT (WINAPI *pSHCreateQueryCancelAutoPlayMoniker)(IMoniker**); 80 static HRESULT (WINAPI *pSHCreateSessionKey)(REGSAM, HKEY*); 81 82 static 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 93 static HRESULT WINAPI PropertyStorage_QueryInterface(IPropertyStorage *This, 94 REFIID riid, void **ppvObject) 95 { 96 ok(0, "unexpected call\n"); 97 return E_NOTIMPL; 98 } 99 100 static ULONG WINAPI PropertyStorage_AddRef(IPropertyStorage *This) 101 { 102 ok(0, "unexpected call\n"); 103 return 2; 104 } 105 106 static ULONG WINAPI PropertyStorage_Release(IPropertyStorage *This) 107 { 108 CHECK_EXPECT(Release); 109 return 1; 110 } 111 112 static 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 148 static 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 161 static 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 168 static 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 175 static 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 182 static 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 189 static HRESULT WINAPI PropertyStorage_Commit(IPropertyStorage *This, DWORD grfCommitFlags) 190 { 191 ok(0, "unexpected call\n"); 192 return E_NOTIMPL; 193 } 194 195 static HRESULT WINAPI PropertyStorage_Revert(IPropertyStorage *This) 196 { 197 ok(0, "unexpected call\n"); 198 return E_NOTIMPL; 199 } 200 201 static HRESULT WINAPI PropertyStorage_Enum(IPropertyStorage *This, IEnumSTATPROPSTG **ppenum) 202 { 203 ok(0, "unexpected call\n"); 204 return E_NOTIMPL; 205 } 206 207 static 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 214 static HRESULT WINAPI PropertyStorage_SetClass(IPropertyStorage *This, REFCLSID clsid) 215 { 216 ok(0, "unexpected call\n"); 217 return E_NOTIMPL; 218 } 219 220 static 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 230 static 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 248 static IPropertyStorage PropertyStorage = { &PropertyStorageVtbl }; 249 250 static HRESULT WINAPI PropertySetStorage_QueryInterface(IPropertySetStorage *This, 251 REFIID riid, void **ppvObject) 252 { 253 ok(0, "unexpected call\n"); 254 return E_NOTIMPL; 255 } 256 257 static ULONG WINAPI PropertySetStorage_AddRef(IPropertySetStorage *This) 258 { 259 ok(0, "unexpected call\n"); 260 return 2; 261 } 262 263 static ULONG WINAPI PropertySetStorage_Release(IPropertySetStorage *This) 264 { 265 ok(0, "unexpected call\n"); 266 return 1; 267 } 268 269 static 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 284 static 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 299 static 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 307 static HRESULT WINAPI PropertySetStorage_Enum(IPropertySetStorage *This, 308 IEnumSTATPROPSETSTG **ppenum) 309 { 310 ok(0, "unexpected call\n"); 311 return E_NOTIMPL; 312 } 313 314 static 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 324 static IPropertySetStorage PropertySetStorage = { &PropertySetStorageVtbl }; 325 326 static 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 443 static 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 460 static ULONG WINAPI test_activator_AddRef(IClassActivator *iface) 461 { 462 return 2; 463 } 464 465 static ULONG WINAPI test_activator_Release(IClassActivator *iface) 466 { 467 return 1; 468 } 469 470 static 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 479 static const IClassActivatorVtbl test_activator_vtbl = { 480 test_activator_QI, 481 test_activator_AddRef, 482 test_activator_Release, 483 test_activator_GetClassObject 484 }; 485 486 static IClassActivator test_activator = { &test_activator_vtbl }; 487 488 static 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 506 static ULONG WINAPI test_moniker_AddRef(IMoniker* iface) 507 { 508 return 2; 509 } 510 511 static ULONG WINAPI test_moniker_Release(IMoniker* iface) 512 { 513 return 1; 514 } 515 516 static HRESULT WINAPI test_moniker_GetClassID(IMoniker* iface, CLSID *pClassID) 517 { 518 ok(0, "unexpected call\n"); 519 return E_NOTIMPL; 520 } 521 522 static HRESULT WINAPI test_moniker_IsDirty(IMoniker* iface) 523 { 524 ok(0, "unexpected call\n"); 525 return E_NOTIMPL; 526 } 527 528 static HRESULT WINAPI test_moniker_Load(IMoniker* iface, IStream* pStm) 529 { 530 ok(0, "unexpected call\n"); 531 return E_NOTIMPL; 532 } 533 534 static HRESULT WINAPI test_moniker_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty) 535 { 536 ok(0, "unexpected call\n"); 537 return E_NOTIMPL; 538 } 539 540 static HRESULT WINAPI test_moniker_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize) 541 { 542 ok(0, "unexpected call\n"); 543 return E_NOTIMPL; 544 } 545 546 static 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 566 static 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 576 static 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 586 static 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 595 static HRESULT WINAPI test_moniker_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker) 596 { 597 ok(0, "unexpected call\n"); 598 return E_NOTIMPL; 599 } 600 601 static HRESULT WINAPI test_moniker_IsEqual(IMoniker* iface, IMoniker* pmkOtherMoniker) 602 { 603 ok(0, "unexpected call\n"); 604 return E_NOTIMPL; 605 } 606 607 static HRESULT WINAPI test_moniker_Hash(IMoniker* iface, DWORD* pdwHash) 608 { 609 ok(0, "unexpected call\n"); 610 return E_NOTIMPL; 611 } 612 613 static 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 622 static 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 631 static HRESULT WINAPI test_moniker_Inverse(IMoniker* iface, IMoniker** ppmk) 632 { 633 ok(0, "unexpected call\n"); 634 return E_NOTIMPL; 635 } 636 637 static HRESULT WINAPI test_moniker_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix) 638 { 639 ok(0, "unexpected call\n"); 640 return E_NOTIMPL; 641 } 642 643 static HRESULT WINAPI test_moniker_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath) 644 { 645 ok(0, "unexpected call\n"); 646 return E_NOTIMPL; 647 } 648 649 static 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 658 static 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 669 static HRESULT WINAPI test_moniker_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys) 670 { 671 ok(0, "unexpected call\n"); 672 return E_NOTIMPL; 673 } 674 675 static 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 702 static IMoniker test_moniker = { &test_moniker_vtbl }; 703 704 static 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 DROPTEST_FILENAME "c:\\wintest.bin" 751 struct DragParam { 752 HWND hwnd; 753 HANDLE ready; 754 }; 755 756 static LRESULT WINAPI drop_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) 757 { 758 switch (msg) { 759 case WM_DROPFILES: 760 { 761 HDROP hDrop = (HDROP)wparam; 762 char filename[MAX_PATH] = "dummy"; 763 UINT num; 764 num = DragQueryFileA(hDrop, 0xffffffff, NULL, 0); 765 ok(num == 1, "expected 1, got %u\n", num); 766 num = DragQueryFileA(hDrop, 0xffffffff, (char*)0xdeadbeef, 0xffffffff); 767 ok(num == 1, "expected 1, got %u\n", num); 768 num = DragQueryFileA(hDrop, 0, filename, sizeof(filename)); 769 ok(num == strlen(DROPTEST_FILENAME), "got %u\n", num); 770 ok(!strcmp(filename, DROPTEST_FILENAME), "got %s\n", filename); 771 DragFinish(hDrop); 772 return 0; 773 } 774 } 775 return DefWindowProcA(hwnd, msg, wparam, lparam); 776 } 777 778 static DWORD WINAPI drop_window_therad(void *arg) 779 { 780 struct DragParam *param = arg; 781 WNDCLASSA cls; 782 WINDOWINFO info; 783 BOOL r; 784 MSG msg; 785 786 memset(&cls, 0, sizeof(cls)); 787 cls.lpfnWndProc = drop_window_proc; 788 cls.hInstance = GetModuleHandleA(NULL); 789 cls.lpszClassName = "drop test"; 790 RegisterClassA(&cls); 791 792 param->hwnd = CreateWindowA("drop test", NULL, 0, 0, 0, 0, 0, 793 NULL, 0, NULL, 0); 794 ok(param->hwnd != NULL, "CreateWindow failed: %d\n", GetLastError()); 795 796 memset(&info, 0, sizeof(info)); 797 info.cbSize = sizeof(info); 798 r = GetWindowInfo(param->hwnd, &info); 799 ok(r, "got %d\n", r); 800 ok(!(info.dwExStyle & WS_EX_ACCEPTFILES), "got %08x\n", info.dwExStyle); 801 802 DragAcceptFiles(param->hwnd, TRUE); 803 804 memset(&info, 0, sizeof(info)); 805 info.cbSize = sizeof(info); 806 r = GetWindowInfo(param->hwnd, &info); 807 ok(r, "got %d\n", r); 808 ok((info.dwExStyle & WS_EX_ACCEPTFILES), "got %08x\n", info.dwExStyle); 809 810 SetEvent(param->ready); 811 812 while ((r = GetMessageA(&msg, NULL, 0, 0)) != 0) { 813 if (r == (BOOL)-1) { 814 ok(0, "unexpected return value, got %d\n", r); 815 break; 816 } 817 DispatchMessageA(&msg); 818 } 819 820 DestroyWindow(param->hwnd); 821 UnregisterClassA("drop test", GetModuleHandleA(NULL)); 822 return 0; 823 } 824 825 static void test_DragQueryFile(void) 826 { 827 struct DragParam param; 828 HANDLE hThread; 829 DWORD rc; 830 HGLOBAL hDrop; 831 DROPFILES *pDrop; 832 int ret; 833 BOOL r; 834 835 param.ready = CreateEventA(NULL, FALSE, FALSE, NULL); 836 ok(param.ready != NULL, "can't create event\n"); 837 hThread = CreateThread(NULL, 0, drop_window_therad, ¶m, 0, NULL); 838 839 rc = WaitForSingleObject(param.ready, 5000); 840 ok(rc == WAIT_OBJECT_0, "got %u\n", rc); 841 842 hDrop = GlobalAlloc(GHND, sizeof(DROPFILES) + (strlen(DROPTEST_FILENAME) + 2) * sizeof(WCHAR)); 843 pDrop = GlobalLock(hDrop); 844 pDrop->pFiles = sizeof(DROPFILES); 845 ret = MultiByteToWideChar(CP_ACP, 0, DROPTEST_FILENAME, -1, 846 (LPWSTR)(pDrop + 1), strlen(DROPTEST_FILENAME) + 1); 847 ok(ret > 0, "got %d\n", ret); 848 pDrop->fWide = TRUE; 849 GlobalUnlock(hDrop); 850 851 r = PostMessageA(param.hwnd, WM_DROPFILES, (WPARAM)hDrop, 0); 852 ok(r, "got %d\n", r); 853 854 r = PostMessageA(param.hwnd, WM_QUIT, 0, 0); 855 ok(r, "got %d\n", r); 856 857 rc = WaitForSingleObject(hThread, 5000); 858 ok(rc == WAIT_OBJECT_0, "got %d\n", rc); 859 860 CloseHandle(param.ready); 861 CloseHandle(hThread); 862 } 863 #undef DROPTEST_FILENAME 864 865 static void test_SHCreateSessionKey(void) 866 { 867 static const WCHAR session_format[] = { 868 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\', 869 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 870 'E','x','p','l','o','r','e','r','\\','S','e','s','s','i','o','n','I','n','f','o','\\','%','u',0}; 871 HKEY hkey, hkey2; 872 HRESULT hr; 873 DWORD session; 874 WCHAR sessionW[ARRAY_SIZE(session_format) + 16]; 875 LONG ret; 876 877 if (!pSHCreateSessionKey) 878 { 879 win_skip("SHCreateSessionKey is not implemented\n"); 880 return; 881 } 882 883 if (0) /* crashes on native */ 884 hr = pSHCreateSessionKey(KEY_READ, NULL); 885 886 hkey = (HKEY)0xdeadbeef; 887 hr = pSHCreateSessionKey(0, &hkey); 888 ok(hr == E_ACCESSDENIED, "got 0x%08x\n", hr); 889 ok(hkey == NULL, "got %p\n", hkey); 890 891 hr = pSHCreateSessionKey(KEY_READ, &hkey); 892 ok(hr == S_OK, "got 0x%08x\n", hr); 893 894 hr = pSHCreateSessionKey(KEY_READ, &hkey2); 895 ok(hr == S_OK, "got 0x%08x\n", hr); 896 ok(hkey != hkey2, "got %p, %p\n", hkey, hkey2); 897 898 RegCloseKey(hkey); 899 RegCloseKey(hkey2); 900 901 /* check the registry */ 902 ProcessIdToSessionId( GetCurrentProcessId(), &session); 903 if (session) 904 { 905 wsprintfW(sessionW, session_format, session); 906 ret = RegOpenKeyW(HKEY_CURRENT_USER, sessionW, &hkey); 907 ok(!ret, "key not found\n"); 908 RegCloseKey(hkey); 909 } 910 } 911 912 static void test_dragdrophelper(void) 913 { 914 IDragSourceHelper *dragsource; 915 IDropTargetHelper *target; 916 HRESULT hr; 917 918 hr = CoCreateInstance(&CLSID_DragDropHelper, NULL, CLSCTX_INPROC_SERVER, &IID_IDropTargetHelper, (void **)&target); 919 ok(hr == S_OK, "Failed to create IDropTargetHelper, %#x\n", hr); 920 921 hr = IDropTargetHelper_QueryInterface(target, &IID_IDragSourceHelper, (void **)&dragsource); 922 ok(hr == S_OK, "QI failed, %#x\n", hr); 923 IDragSourceHelper_Release(dragsource); 924 925 IDropTargetHelper_Release(target); 926 } 927 928 START_TEST(shellole) 929 { 930 HRESULT hr; 931 932 init(); 933 934 hr = CoInitialize(NULL); 935 ok(hr == S_OK, "CoInitialize failed (0x%08x)\n", hr); 936 if (hr != S_OK) 937 return; 938 939 test_SHPropStg_functions(); 940 test_SHCreateQueryCancelAutoPlayMoniker(); 941 test_DragQueryFile(); 942 test_SHCreateSessionKey(); 943 test_dragdrophelper(); 944 945 CoUninitialize(); 946 } 947