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