wmiutils: Implement IWbemPath::GetNamespaceAt.
[wine] / dlls / shell32 / tests / 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 #define NONAMELESSUNION
22
23 #include <stdio.h>
24 #include <wine/test.h>
25
26 #include "winbase.h"
27 #include "shlobj.h"
28 #include "initguid.h"
29
30 DEFINE_GUID(FMTID_Test,0x12345678,0x1234,0x1234,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12);
31 DEFINE_GUID(FMTID_NotExisting, 0x12345678,0x1234,0x1234,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x13);
32
33 #define DEFINE_EXPECT(func) \
34     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
35
36 #define SET_EXPECT(func) \
37     expect_ ## func = TRUE
38
39 #define CHECK_EXPECT2(func) \
40     do { \
41         ok(expect_ ##func, "unexpected call " #func "\n"); \
42         called_ ## func = TRUE; \
43     }while(0)
44
45 #define CHECK_EXPECT(func) \
46     do { \
47         CHECK_EXPECT2(func); \
48         expect_ ## func = FALSE; \
49     }while(0)
50
51 #define CHECK_CALLED(func) \
52     do { \
53         ok(called_ ## func, "expected " #func "\n"); \
54         expect_ ## func = called_ ## func = FALSE; \
55     }while(0)
56
57 DEFINE_EXPECT(Create);
58 DEFINE_EXPECT(Delete);
59 DEFINE_EXPECT(Open);
60 DEFINE_EXPECT(ReadMultiple);
61 DEFINE_EXPECT(ReadMultipleCodePage);
62 DEFINE_EXPECT(Release);
63 DEFINE_EXPECT(Stat);
64 DEFINE_EXPECT(WriteMultiple);
65
66 static HRESULT (WINAPI *pSHPropStgCreate)(IPropertySetStorage*, REFFMTID, const CLSID*,
67         DWORD, DWORD, DWORD, IPropertyStorage**, UINT*);
68 static HRESULT (WINAPI *pSHPropStgReadMultiple)(IPropertyStorage*, UINT,
69         ULONG, const PROPSPEC*, PROPVARIANT*);
70 static HRESULT (WINAPI *pSHPropStgWriteMultiple)(IPropertyStorage*, UINT*,
71         ULONG, const PROPSPEC*, PROPVARIANT*, PROPID);
72
73 static void init(void)
74 {
75     HMODULE hmod = GetModuleHandleA("shell32.dll");
76
77     pSHPropStgCreate = (void*)GetProcAddress(hmod, "SHPropStgCreate");
78     pSHPropStgReadMultiple = (void*)GetProcAddress(hmod, "SHPropStgReadMultiple");
79     pSHPropStgWriteMultiple = (void*)GetProcAddress(hmod, "SHPropStgWriteMultiple");
80 }
81
82 static HRESULT WINAPI PropertyStorage_QueryInterface(IPropertyStorage *This,
83         REFIID riid, void **ppvObject)
84 {
85     ok(0, "unexpected call\n");
86     return E_NOTIMPL;
87 }
88
89 static ULONG WINAPI PropertyStorage_AddRef(IPropertyStorage *This)
90 {
91     ok(0, "unexpected call\n");
92     return 2;
93 }
94
95 static ULONG WINAPI PropertyStorage_Release(IPropertyStorage *This)
96 {
97     CHECK_EXPECT(Release);
98     return 1;
99 }
100
101 static HRESULT WINAPI PropertyStorage_ReadMultiple(IPropertyStorage *This, ULONG cpspec,
102         const PROPSPEC *rgpspec, PROPVARIANT *rgpropvar)
103 {
104     if(cpspec == 1) {
105         CHECK_EXPECT(ReadMultipleCodePage);
106
107         ok(rgpspec != NULL, "rgpspec = NULL\n");
108         ok(rgpropvar != NULL, "rgpropvar = NULL\n");
109
110         ok(rgpspec[0].ulKind == PRSPEC_PROPID, "rgpspec[0].ulKind = %d\n", rgpspec[0].ulKind);
111         ok(rgpspec[0].u.propid == PID_CODEPAGE, "rgpspec[0].propid = %d\n", rgpspec[0].u.propid);
112
113         rgpropvar[0].vt = VT_I2;
114         rgpropvar[0].u.iVal = 1234;
115     } else {
116         CHECK_EXPECT(ReadMultiple);
117
118         ok(cpspec == 10, "cpspec = %u\n", cpspec);
119         ok(rgpspec == (void*)0xdeadbeef, "rgpspec = %p\n", rgpspec);
120         ok(rgpropvar != NULL, "rgpropvar = NULL\n");
121
122         ok(rgpropvar[0].vt==0 || broken(rgpropvar[0].vt==VT_BSTR), "rgpropvar[0].vt = %d\n", rgpropvar[0].vt);
123
124         rgpropvar[0].vt = VT_BSTR;
125         rgpropvar[0].u.bstrVal = (void*)0xdeadbeef;
126         rgpropvar[1].vt = VT_LPSTR;
127         rgpropvar[1].u.pszVal = (void*)0xdeadbeef;
128         rgpropvar[2].vt = VT_BYREF|VT_I1;
129         rgpropvar[2].u.pcVal = (void*)0xdeadbeef;
130         rgpropvar[3].vt = VT_BYREF|VT_VARIANT;
131         rgpropvar[3].u.pvarVal = (void*)0xdeadbeef;
132     }
133
134     return S_OK;
135 }
136
137 static HRESULT WINAPI PropertyStorage_WriteMultiple(IPropertyStorage *This, ULONG cpspec,
138         const PROPSPEC *rgpspec, const PROPVARIANT *rgpropvar,
139         PROPID propidNameFirst)
140 {
141     CHECK_EXPECT(WriteMultiple);
142
143     ok(cpspec == 20, "cpspec = %d\n", cpspec);
144     ok(rgpspec == (void*)0xdeadbeef, "rgpspec = %p\n", rgpspec);
145     ok(rgpropvar == (void*)0xdeadbeef, "rgpropvar = %p\n", rgpspec);
146     ok(propidNameFirst == PID_FIRST_USABLE, "propidNameFirst = %d\n", propidNameFirst);
147     return S_OK;
148 }
149
150 static HRESULT WINAPI PropertyStorage_DeleteMultiple(IPropertyStorage *This, ULONG cpspec,
151         const PROPSPEC *rgpspec)
152 {
153     ok(0, "unexpected call\n");
154     return E_NOTIMPL;
155 }
156
157 static HRESULT WINAPI PropertyStorage_ReadPropertyNames(IPropertyStorage *This, ULONG cpropid,
158         const PROPID *rgpropid, LPOLESTR *rglpwstrName)
159 {
160     ok(0, "unexpected call\n");
161     return E_NOTIMPL;
162 }
163
164 static HRESULT WINAPI PropertyStorage_WritePropertyNames(IPropertyStorage *This, ULONG cpropid,
165         const PROPID *rgpropid, const LPOLESTR *rglpwstrName)
166 {
167     ok(0, "unexpected call\n");
168     return E_NOTIMPL;
169 }
170
171 static HRESULT WINAPI PropertyStorage_DeletePropertyNames(IPropertyStorage *This, ULONG cpropid,
172         const PROPID *rgpropid)
173 {
174     ok(0, "unexpected call\n");
175     return E_NOTIMPL;
176 }
177
178 static HRESULT WINAPI PropertyStorage_Commit(IPropertyStorage *This, DWORD grfCommitFlags)
179 {
180     ok(0, "unexpected call\n");
181     return E_NOTIMPL;
182 }
183
184 static HRESULT WINAPI PropertyStorage_Revert(IPropertyStorage *This)
185 {
186     ok(0, "unexpected call\n");
187     return E_NOTIMPL;
188 }
189
190 static HRESULT WINAPI PropertyStorage_Enum(IPropertyStorage *This, IEnumSTATPROPSTG **ppenum)
191 {
192     ok(0, "unexpected call\n");
193     return E_NOTIMPL;
194 }
195
196 static HRESULT WINAPI PropertyStorage_SetTimes(IPropertyStorage *This, const FILETIME *pctime,
197         const FILETIME *patime, const FILETIME *pmtime)
198 {
199     ok(0, "unexpected call\n");
200     return E_NOTIMPL;
201 }
202
203 static HRESULT WINAPI PropertyStorage_SetClass(IPropertyStorage *This, REFCLSID clsid)
204 {
205     ok(0, "unexpected call\n");
206     return E_NOTIMPL;
207 }
208
209 static HRESULT WINAPI PropertyStorage_Stat(IPropertyStorage *This, STATPROPSETSTG *statpsstg)
210 {
211     CHECK_EXPECT(Stat);
212
213     memset(statpsstg, 0, sizeof(STATPROPSETSTG));
214     memcpy(&statpsstg->fmtid, &FMTID_Test, sizeof(FMTID));
215     statpsstg->grfFlags = PROPSETFLAG_ANSI;
216     return S_OK;
217 }
218
219 static IPropertyStorageVtbl PropertyStorageVtbl = {
220     PropertyStorage_QueryInterface,
221     PropertyStorage_AddRef,
222     PropertyStorage_Release,
223     PropertyStorage_ReadMultiple,
224     PropertyStorage_WriteMultiple,
225     PropertyStorage_DeleteMultiple,
226     PropertyStorage_ReadPropertyNames,
227     PropertyStorage_WritePropertyNames,
228     PropertyStorage_DeletePropertyNames,
229     PropertyStorage_Commit,
230     PropertyStorage_Revert,
231     PropertyStorage_Enum,
232     PropertyStorage_SetTimes,
233     PropertyStorage_SetClass,
234     PropertyStorage_Stat
235 };
236
237 static IPropertyStorage PropertyStorage = { &PropertyStorageVtbl };
238
239 static HRESULT WINAPI PropertySetStorage_QueryInterface(IPropertySetStorage *This,
240         REFIID riid, void **ppvObject)
241 {
242     ok(0, "unexpected call\n");
243     return E_NOTIMPL;
244 }
245
246 static ULONG WINAPI PropertySetStorage_AddRef(IPropertySetStorage *This)
247 {
248     ok(0, "unexpected call\n");
249     return 2;
250 }
251
252 static ULONG WINAPI PropertySetStorage_Release(IPropertySetStorage *This)
253 {
254     ok(0, "unexpected call\n");
255     return 1;
256 }
257
258 static HRESULT WINAPI PropertySetStorage_Create(IPropertySetStorage *This,
259         REFFMTID rfmtid, const CLSID *pclsid, DWORD grfFlags,
260         DWORD grfMode, IPropertyStorage **ppprstg)
261 {
262     CHECK_EXPECT(Create);
263     ok(IsEqualGUID(rfmtid, &FMTID_Test) || IsEqualGUID(rfmtid, &FMTID_NotExisting),
264             "Incorrect rfmtid value\n");
265     ok(pclsid == NULL, "pclsid != NULL\n");
266     ok(grfFlags == PROPSETFLAG_ANSI, "grfFlags = %x\n", grfFlags);
267     ok(grfMode == STGM_READ, "grfMode = %x\n", grfMode);
268
269     *ppprstg = &PropertyStorage;
270     return S_OK;
271 }
272
273 static HRESULT WINAPI PropertySetStorage_Open(IPropertySetStorage *This,
274         REFFMTID rfmtid, DWORD grfMode, IPropertyStorage **ppprstg)
275 {
276     CHECK_EXPECT(Open);
277
278     if(IsEqualGUID(rfmtid, &FMTID_Test)) {
279         ok(grfMode == STGM_READ, "grfMode = %x\n", grfMode);
280
281         *ppprstg = &PropertyStorage;
282         return S_OK;
283     }
284
285     return STG_E_FILENOTFOUND;
286 }
287
288 static HRESULT WINAPI PropertySetStorage_Delete(IPropertySetStorage *This,
289         REFFMTID rfmtid)
290 {
291     CHECK_EXPECT(Delete);
292     ok(IsEqualGUID(rfmtid, &FMTID_Test), "wrong rfmtid value\n");
293     return S_OK;
294 }
295
296 static HRESULT WINAPI PropertySetStorage_Enum(IPropertySetStorage *This,
297         IEnumSTATPROPSETSTG **ppenum)
298 {
299     ok(0, "unexpected call\n");
300     return E_NOTIMPL;
301 }
302
303 static IPropertySetStorageVtbl PropertySetStorageVtbl = {
304     PropertySetStorage_QueryInterface,
305     PropertySetStorage_AddRef,
306     PropertySetStorage_Release,
307     PropertySetStorage_Create,
308     PropertySetStorage_Open,
309     PropertySetStorage_Delete,
310     PropertySetStorage_Enum
311 };
312
313 static IPropertySetStorage PropertySetStorage = { &PropertySetStorageVtbl };
314
315 static void test_SHPropStg_functions(void)
316 {
317     IPropertyStorage *property_storage;
318     UINT codepage;
319     PROPVARIANT read[10];
320     HRESULT hres;
321
322     if(!pSHPropStgCreate || !pSHPropStgReadMultiple || !pSHPropStgWriteMultiple) {
323         win_skip("SHPropStg* functions are missing\n");
324         return;
325     }
326
327     if(0) {
328         /* Crashes on Windows */
329         pSHPropStgCreate(NULL, &FMTID_Test, NULL, PROPSETFLAG_DEFAULT,
330                 STGM_READ, OPEN_EXISTING, &property_storage, &codepage);
331         pSHPropStgCreate(&PropertySetStorage, NULL, NULL, PROPSETFLAG_DEFAULT,
332                 STGM_READ, OPEN_EXISTING, &property_storage, &codepage);
333         pSHPropStgCreate(&PropertySetStorage, &FMTID_Test, NULL, PROPSETFLAG_DEFAULT,
334                 STGM_READ, OPEN_EXISTING, NULL, &codepage);
335     }
336
337     SET_EXPECT(Open);
338     SET_EXPECT(ReadMultipleCodePage);
339     hres = pSHPropStgCreate(&PropertySetStorage, &FMTID_Test, NULL, PROPSETFLAG_DEFAULT,
340             STGM_READ, OPEN_EXISTING, &property_storage, &codepage);
341     ok(codepage == 1234, "codepage = %d\n", codepage);
342     ok(hres == S_OK, "hres = %x\n", hres);
343     CHECK_CALLED(Open);
344     CHECK_CALLED(ReadMultipleCodePage);
345
346     SET_EXPECT(Open);
347     hres = pSHPropStgCreate(&PropertySetStorage, &FMTID_NotExisting, NULL,
348             PROPSETFLAG_DEFAULT, STGM_READ, OPEN_EXISTING, &property_storage, &codepage);
349     ok(hres == STG_E_FILENOTFOUND, "hres = %x\n", hres);
350     CHECK_CALLED(Open);
351
352     SET_EXPECT(Open);
353     SET_EXPECT(Release);
354     SET_EXPECT(Delete);
355     SET_EXPECT(Create);
356     SET_EXPECT(ReadMultipleCodePage);
357     hres = pSHPropStgCreate(&PropertySetStorage, &FMTID_Test, NULL, PROPSETFLAG_ANSI,
358             STGM_READ, CREATE_ALWAYS, &property_storage, &codepage);
359     ok(codepage == 1234, "codepage = %d\n", codepage);
360     ok(hres == S_OK, "hres = %x\n", hres);
361     CHECK_CALLED(Open);
362     CHECK_CALLED(Release);
363     CHECK_CALLED(Delete);
364     CHECK_CALLED(Create);
365     CHECK_CALLED(ReadMultipleCodePage);
366
367     SET_EXPECT(Open);
368     SET_EXPECT(Create);
369     SET_EXPECT(ReadMultipleCodePage);
370     hres = pSHPropStgCreate(&PropertySetStorage, &FMTID_NotExisting, NULL, PROPSETFLAG_ANSI,
371             STGM_READ, CREATE_ALWAYS, &property_storage, &codepage);
372     ok(codepage == 1234, "codepage = %d\n", codepage);
373     ok(hres == S_OK, "hres = %x\n", hres);
374     CHECK_CALLED(Open);
375     CHECK_CALLED(Create);
376     CHECK_CALLED(ReadMultipleCodePage);
377
378     SET_EXPECT(Open);
379     hres = pSHPropStgCreate(&PropertySetStorage, &FMTID_Test, &FMTID_NotExisting,
380             PROPSETFLAG_DEFAULT, STGM_READ, OPEN_EXISTING, &property_storage, NULL);
381     ok(hres == S_OK, "hres = %x\n", hres);
382     CHECK_CALLED(Open);
383
384     SET_EXPECT(Stat);
385     SET_EXPECT(ReadMultipleCodePage);
386     SET_EXPECT(WriteMultiple);
387     codepage = 0;
388     hres = pSHPropStgWriteMultiple(property_storage, &codepage, 20, (void*)0xdeadbeef, (void*)0xdeadbeef, PID_FIRST_USABLE);
389     ok(hres == S_OK, "hres = %x\n", hres);
390     ok(codepage == 1234, "codepage = %d\n", codepage);
391     CHECK_CALLED(Stat);
392     CHECK_CALLED(ReadMultipleCodePage);
393     CHECK_CALLED(WriteMultiple);
394
395     SET_EXPECT(Stat);
396     SET_EXPECT(ReadMultipleCodePage);
397     SET_EXPECT(WriteMultiple);
398     hres = pSHPropStgWriteMultiple(property_storage, NULL, 20, (void*)0xdeadbeef, (void*)0xdeadbeef, PID_FIRST_USABLE);
399     ok(hres == S_OK, "hres = %x\n", hres);
400     CHECK_CALLED(Stat);
401     CHECK_CALLED(ReadMultipleCodePage);
402     CHECK_CALLED(WriteMultiple);
403
404     SET_EXPECT(Stat);
405     SET_EXPECT(WriteMultiple);
406     codepage = 1000;
407     hres = pSHPropStgWriteMultiple(property_storage, &codepage, 20, (void*)0xdeadbeef, (void*)0xdeadbeef, PID_FIRST_USABLE);
408     ok(hres == S_OK, "hres = %x\n", hres);
409     ok(codepage == 1000, "codepage = %d\n", codepage);
410     CHECK_CALLED(Stat);
411     CHECK_CALLED(WriteMultiple);
412
413     read[0].vt = VT_BSTR;
414     read[0].u.bstrVal = (void*)0xdeadbeef;
415     SET_EXPECT(ReadMultiple);
416     SET_EXPECT(ReadMultipleCodePage);
417     SET_EXPECT(Stat);
418     hres = pSHPropStgReadMultiple(property_storage, 0, 10, (void*)0xdeadbeef, read);
419     ok(hres == S_OK, "hres = %x\n", hres);
420     CHECK_CALLED(ReadMultiple);
421     CHECK_CALLED(ReadMultipleCodePage);
422     CHECK_CALLED(Stat);
423
424     SET_EXPECT(ReadMultiple);
425     SET_EXPECT(Stat);
426     hres = pSHPropStgReadMultiple(property_storage, 1251, 10, (void*)0xdeadbeef, read);
427     ok(hres == S_OK, "hres = %x\n", hres);
428     CHECK_CALLED(ReadMultiple);
429     CHECK_CALLED(Stat);
430 }
431
432 START_TEST(shellole)
433 {
434     init();
435
436     test_SHPropStg_functions();
437 }