27964afcd365b00c3258d619828cb5bcfc551b2d
[reactos.git] / modules / rostests / winetests / shell32 / shellole.c
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, &param, 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 }