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 WM_EXPECTED_VALUE WM_APP 751 #define DROPTEST_FILENAME "c:\\wintest.bin" 752 struct DragParam { 753 HWND hwnd; 754 HANDLE ready; 755 }; 756 757 static 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 792 static 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 839 static 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, ¶m, 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 886 static 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 933 static 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 949 START_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 } 969