ReactOS  0.4.13-dev-464-g6b95727
stg_prop.c
Go to the documentation of this file.
1 /* IPropertyStorage unit tests
2  * Copyright 2005 Juan Lang
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 #include <stdio.h>
19 #define COBJMACROS
20 #include "objbase.h"
21 #include "wine/test.h"
22 
23 #ifndef PID_BEHAVIOR
24 #define PID_BEHAVIOR 0x80000003
25 #endif
26 
27 static HRESULT (WINAPI *pFmtIdToPropStgName)(const FMTID *, LPOLESTR);
28 static HRESULT (WINAPI *pPropStgNameToFmtId)(const LPOLESTR, FMTID *);
29 static HRESULT (WINAPI *pStgCreatePropSetStg)(IStorage *, DWORD, IPropertySetStorage **);
30 static HRESULT (WINAPI *pStgCreatePropStg)(IUnknown *, REFFMTID, const CLSID *, DWORD, DWORD, IPropertyStorage **);
31 static HRESULT (WINAPI *pStgOpenPropStg)(IUnknown *, REFFMTID, DWORD, DWORD, IPropertyStorage **);
32 
33 static void init_function_pointers(void)
34 {
35  HMODULE hmod = GetModuleHandleA("ole32.dll");
36  pFmtIdToPropStgName = (void*)GetProcAddress(hmod, "FmtIdToPropStgName");
37  pPropStgNameToFmtId = (void*)GetProcAddress(hmod, "PropStgNameToFmtId");
38  pStgCreatePropSetStg = (void*)GetProcAddress(hmod, "StgCreatePropSetStg");
39  pStgCreatePropStg = (void*)GetProcAddress(hmod, "StgCreatePropStg");
40  pStgOpenPropStg = (void*)GetProcAddress(hmod, "StgOpenPropStg");
41 }
42 
43 /* FIXME: this creates an ANSI storage, try to find conditions under which
44  * Unicode translation fails
45  */
46 static void testPropsHelper(IPropertySetStorage **propSetStorage)
47 {
48  static const WCHAR szDot[] = { '.',0 };
49  static const WCHAR szPrefix[] = { 's','t','g',0 };
50  static const WCHAR szSummaryInfo[] = { 5,'S','u','m','m','a','r','y',
51  'I','n','f','o','r','m','a','t','i','o','n',0 };
52  static WCHAR propName[] = { 'p','r','o','p',0 };
53  static char val[] = "l33t auth0r";
55  HRESULT hr;
56  IStorage *storage = NULL;
57  IStream *stream = NULL;
58  IPropertyStorage *propertyStorage = NULL;
59  PROPSPEC spec;
60  PROPVARIANT var;
61  CLIPDATA clipdata;
62  unsigned char clipcontent[] = "foobar";
63  GUID anyOldGuid = { 0x12345678,0xdead,0xbeef, {
64  0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 } };
65 
66  if(propSetStorage)
67  trace("Testing property storage with a set...\n");
68  else
69  trace("Testing property storage without a set...\n");
70 
71  if(!GetTempFileNameW(szDot, szPrefix, 0, filename))
72  return;
73 
75 
78  ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
79 
80  if(propSetStorage)
81  {
82  if(!pStgCreatePropSetStg)
83  {
84  IStorage_Release(storage);
86  return;
87  }
88  hr = pStgCreatePropSetStg(storage, 0, propSetStorage);
89  ok(hr == S_OK, "StgCreatePropSetStg failed: 0x%08x\n", hr);
90 
91  hr = IPropertySetStorage_Create(*propSetStorage,
92  &FMTID_SummaryInformation, NULL, PROPSETFLAG_ANSI,
94  &propertyStorage);
95  ok(hr == S_OK, "IPropertySetStorage_Create failed: 0x%08x\n", hr);
96  }
97  else
98  {
99  hr = IStorage_CreateStream(storage, szSummaryInfo,
101  ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr);
102 
103  if(!pStgCreatePropStg)
104  {
105  IStorage_Release(storage);
106  IUnknown_Release(stream);
108  return;
109  }
110  hr = pStgCreatePropStg((IUnknown *)stream, &FMTID_SummaryInformation,
111  NULL, PROPSETFLAG_ANSI, 0, &propertyStorage);
112  ok(hr == S_OK, "StgCreatePropStg failed: 0x%08x\n", hr);
113  }
114 
115  hr = IPropertyStorage_WriteMultiple(propertyStorage, 0, NULL, NULL, 0);
116  ok(hr == S_OK, "WriteMultiple with 0 args failed: 0x%08x\n", hr);
117  hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, NULL, NULL, 0);
118  ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got 0x%08x\n", hr);
119 
120  /* test setting one that I can't set */
121  spec.ulKind = PRSPEC_PROPID;
122  U(spec).propid = PID_DICTIONARY;
123  var.vt = VT_I4;
124  U(var).lVal = 1;
125  hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
127  "Expected STG_E_INVALIDPARAMETER, got 0x%08x\n", hr);
128 
129  /* test setting one by name with an invalid propidNameFirst */
130  spec.ulKind = PRSPEC_LPWSTR;
131  U(spec).lpwstr = propName;
132  hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var,
135  "Expected STG_E_INVALIDPARAMETER, got 0x%08x\n", hr);
136 
137  /* test setting behavior (case-sensitive) */
138  spec.ulKind = PRSPEC_PROPID;
139  U(spec).propid = PID_BEHAVIOR;
140  U(var).lVal = 1;
141  hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
143  "Expected STG_E_INVALIDPARAMETER, got 0x%08x\n", hr);
144 
145  /* set one by value.. */
146  spec.ulKind = PRSPEC_PROPID;
147  U(spec).propid = PID_FIRST_USABLE;
148  U(var).lVal = 1;
149  hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
150  ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
151 
152  /* set one by name */
153  spec.ulKind = PRSPEC_LPWSTR;
154  U(spec).lpwstr = propName;
155  U(var).lVal = 2;
156  hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var,
158  ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
159 
160  /* set a string value */
161  spec.ulKind = PRSPEC_PROPID;
162  U(spec).propid = PIDSI_AUTHOR;
163  var.vt = VT_LPSTR;
164  U(var).pszVal = val;
165  hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
166  ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
167 
168  /* set a clipboard value */
169  spec.ulKind = PRSPEC_PROPID;
170  U(spec).propid = PIDSI_THUMBNAIL;
171  var.vt = VT_CF;
172  clipdata.cbSize = sizeof clipcontent + sizeof (ULONG);
173  clipdata.ulClipFmt = CF_ENHMETAFILE;
174  clipdata.pClipData = clipcontent;
175  U(var).pclipdata = &clipdata;
176  hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
177  ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
178 
179 
180  /* check reading */
181  hr = IPropertyStorage_ReadMultiple(propertyStorage, 0, NULL, NULL);
182  ok(hr == S_FALSE, "ReadMultiple with 0 args failed: 0x%08x\n", hr);
183  hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, NULL, NULL);
184  ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got 0x%08x\n", hr);
185  /* read by propid */
186  spec.ulKind = PRSPEC_PROPID;
187  U(spec).propid = PID_FIRST_USABLE;
188  hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
189  ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
190  ok(var.vt == VT_I4 && U(var).lVal == 1,
191  "Didn't get expected type or value for property (got type %d, value %d)\n",
192  var.vt, U(var).lVal);
193  /* read by name */
194  spec.ulKind = PRSPEC_LPWSTR;
195  U(spec).lpwstr = propName;
196  hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
197  ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
198  ok(var.vt == VT_I4 && U(var).lVal == 2,
199  "Didn't get expected type or value for property (got type %d, value %d)\n",
200  var.vt, U(var).lVal);
201  /* read string value */
202  spec.ulKind = PRSPEC_PROPID;
203  U(spec).propid = PIDSI_AUTHOR;
204  hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
205  ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
206  ok(var.vt == VT_LPSTR && !lstrcmpA(U(var).pszVal, val),
207  "Didn't get expected type or value for property (got type %d, value %s)\n",
208  var.vt, U(var).pszVal);
209  PropVariantClear(&var);
210 
211  /* read clipboard format */
212  spec.ulKind = PRSPEC_PROPID;
213  U(spec).propid = PIDSI_THUMBNAIL;
214  hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
215  ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
216  ok(var.vt == VT_CF, "variant type wrong\n");
217  ok(U(var).pclipdata->ulClipFmt == CF_ENHMETAFILE,
218  "clipboard type wrong\n");
219  ok(U(var).pclipdata->cbSize == sizeof clipcontent + sizeof (ULONG),
220  "clipboard size wrong\n");
221  ok(!memcmp(U(var).pclipdata->pClipData, clipcontent, sizeof clipcontent),
222  "clipboard contents wrong\n");
223  ok(S_OK == PropVariantClear(&var), "failed to clear variant\n");
224 
225  /* check deleting */
226  hr = IPropertyStorage_DeleteMultiple(propertyStorage, 0, NULL);
227  ok(hr == S_OK, "DeleteMultiple with 0 args failed: 0x%08x\n", hr);
228  hr = IPropertyStorage_DeleteMultiple(propertyStorage, 1, NULL);
229  ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got 0x%08x\n", hr);
230  /* contrary to what the docs say, you can't delete the dictionary */
231  spec.ulKind = PRSPEC_PROPID;
232  U(spec).propid = PID_DICTIONARY;
233  hr = IPropertyStorage_DeleteMultiple(propertyStorage, 1, &spec);
235  "Expected STG_E_INVALIDPARAMETER, got 0x%08x\n", hr);
236  /* now delete the first value.. */
237  U(spec).propid = PID_FIRST_USABLE;
238  hr = IPropertyStorage_DeleteMultiple(propertyStorage, 1, &spec);
239  ok(hr == S_OK, "DeleteMultiple failed: 0x%08x\n", hr);
240  /* and check that it's no longer readable */
241  hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
242  ok(hr == S_FALSE, "Expected S_FALSE, got 0x%08x\n", hr);
243 
244  hr = IPropertyStorage_Commit(propertyStorage, STGC_DEFAULT);
245  ok(hr == S_OK, "Commit failed: 0x%08x\n", hr);
246 
247  /* check reverting */
248  spec.ulKind = PRSPEC_PROPID;
249  U(spec).propid = PID_FIRST_USABLE;
250  hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
251  ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
252  hr = IPropertyStorage_Revert(propertyStorage);
253  ok(hr == S_OK, "Revert failed: 0x%08x\n", hr);
254  /* now check that it's still not there */
255  hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
256  ok(hr == S_FALSE, "Expected S_FALSE, got 0x%08x\n", hr);
257  /* set an integer value again */
258  spec.ulKind = PRSPEC_PROPID;
259  U(spec).propid = PID_FIRST_USABLE;
260  var.vt = VT_I4;
261  U(var).lVal = 1;
262  hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
263  ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
264  /* commit it */
265  hr = IPropertyStorage_Commit(propertyStorage, STGC_DEFAULT);
266  ok(hr == S_OK, "Commit failed: 0x%08x\n", hr);
267  /* set it to a string value */
268  var.vt = VT_LPSTR;
269  U(var).pszVal = val;
270  hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
271  ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
272  /* revert it */
273  hr = IPropertyStorage_Revert(propertyStorage);
274  ok(hr == S_OK, "Revert failed: 0x%08x\n", hr);
275  /* Oddly enough, there's no guarantee that a successful revert actually
276  * implies the value wasn't saved. Maybe transactional mode needs to be
277  * used for that?
278  */
279 
280  IPropertyStorage_Release(propertyStorage);
281  if(propSetStorage) IPropertySetStorage_Release(*propSetStorage);
282  IStorage_Release(storage);
283  if(stream) IUnknown_Release(stream);
284 
285  /* now open it again */
287  NULL, 0, &storage);
288  ok(hr == S_OK, "StgOpenStorage failed: 0x%08x\n", hr);
289 
290  if(propSetStorage)
291  {
292  hr = pStgCreatePropSetStg(storage, 0, propSetStorage);
293  ok(hr == S_OK, "StgCreatePropSetStg failed: 0x%08x\n", hr);
294 
295  hr = IPropertySetStorage_Open(*propSetStorage, &FMTID_SummaryInformation,
296  STGM_READWRITE | STGM_SHARE_EXCLUSIVE, &propertyStorage);
297  ok(hr == S_OK, "IPropertySetStorage_Open failed: 0x%08x\n", hr);
298  }
299  else
300  {
301  hr = IStorage_OpenStream(storage, szSummaryInfo,
303  ok(hr == S_OK, "IStorage_OpenStream failed: 0x%08x\n", hr);
304 
305  if(!pStgOpenPropStg)
306  {
307  IStorage_Release(storage);
308  IUnknown_Release(stream);
310  return;
311  }
312  hr = pStgOpenPropStg((IUnknown *)stream, &FMTID_SummaryInformation,
313  PROPSETFLAG_DEFAULT, 0, &propertyStorage);
314  ok(hr == S_OK, "StgOpenPropStg failed: 0x%08x\n", hr);
315  }
316 
317  /* check properties again */
318  spec.ulKind = PRSPEC_LPWSTR;
319  U(spec).lpwstr = propName;
320  hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
321  ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
322  ok(var.vt == VT_I4 && U(var).lVal == 2,
323  "Didn't get expected type or value for property (got type %d, value %d)\n",
324  var.vt, U(var).lVal);
325  spec.ulKind = PRSPEC_PROPID;
326  U(spec).propid = PIDSI_AUTHOR;
327  hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
328  ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
329  ok(var.vt == VT_LPSTR && !lstrcmpA(U(var).pszVal, val),
330  "Didn't get expected type or value for property (got type %d, value %s)\n",
331  var.vt, U(var).pszVal);
332  PropVariantClear(&var);
333 
334  IPropertyStorage_Release(propertyStorage);
335  if(propSetStorage) IPropertySetStorage_Release(*propSetStorage);
336  IStorage_Release(storage);
337  if(stream) IUnknown_Release(stream);
338 
340 
341  /* Test creating a property set storage with a random GUID */
344  ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
345 
346  if(propSetStorage)
347  {
348  hr = pStgCreatePropSetStg(storage, 0, propSetStorage);
349  ok(hr == S_OK, "StgCreatePropSetStg failed: 0x%08x\n", hr);
350 
351  hr = IPropertySetStorage_Create(*propSetStorage,
352  &anyOldGuid, NULL, PROPSETFLAG_ANSI,
354  &propertyStorage);
355  ok(hr == S_OK, "IPropertySetStorage_Create failed: 0x%08x\n", hr);
356  }
357  else
358  {
359  hr = IStorage_CreateStream(storage, szSummaryInfo,
361  ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr);
362 
363  hr = pStgCreatePropStg((IUnknown *)stream, &anyOldGuid, NULL,
364  PROPSETFLAG_DEFAULT, 0, &propertyStorage);
365  ok(hr == S_OK, "StgCreatePropStg failed: 0x%08x\n", hr);
366  }
367 
368  spec.ulKind = PRSPEC_PROPID;
369  U(spec).propid = PID_FIRST_USABLE;
370  var.vt = VT_I4;
371  U(var).lVal = 1;
372  hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
373  ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
374 
375  hr = IPropertyStorage_Commit(propertyStorage, STGC_DEFAULT);
376  ok(hr == S_OK, "Commit failed: 0x%08x\n", hr);
377 
378  IPropertyStorage_Release(propertyStorage);
379  if(propSetStorage) IPropertySetStorage_Release(*propSetStorage);
380  IStorage_Release(storage);
381  if(stream) IUnknown_Release(stream);
382 
383  /* now open it again */
385  NULL, 0, &storage);
386  ok(hr == S_OK, "StgOpenStorage failed: 0x%08x\n", hr);
387 
388  if(propSetStorage)
389  {
390  hr = pStgCreatePropSetStg(storage, 0, propSetStorage);
391  ok(hr == S_OK, "StgCreatePropSetStg failed: 0x%08x\n", hr);
392 
393  hr = IPropertySetStorage_Open(*propSetStorage, &anyOldGuid,
394  STGM_READWRITE | STGM_SHARE_EXCLUSIVE, &propertyStorage);
395  ok(hr == S_OK, "IPropertySetStorage_Open failed: 0x%08x\n", hr);
396  }
397  else
398  {
399  hr = IStorage_OpenStream(storage, szSummaryInfo,
401  ok(hr == S_OK, "IStorage_OpenStream failed: 0x%08x\n", hr);
402 
403  hr = pStgOpenPropStg((IUnknown *)stream, &anyOldGuid,
404  PROPSETFLAG_DEFAULT, 0, &propertyStorage);
405  ok(hr == S_OK, "StgOpenPropStg failed: 0x%08x\n", hr);
406  }
407 
408  spec.ulKind = PRSPEC_PROPID;
409  U(spec).propid = PID_FIRST_USABLE;
410  hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
411  ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
412 
413  ok(var.vt == VT_I4 && U(var).lVal == 1,
414  "Didn't get expected type or value for property (got type %d, value %d)\n",
415  var.vt, U(var).lVal);
416 
417  IPropertyStorage_Release(propertyStorage);
418  if(propSetStorage) IPropertySetStorage_Release(*propSetStorage);
419  IStorage_Release(storage);
420  if(stream) IUnknown_Release(stream);
421 
423 }
424 
425 static void testProps(void)
426 {
427  IPropertySetStorage *propSetStorage = NULL;
428 
429  testPropsHelper(&propSetStorage);
431 }
432 
433 static void testCodepage(void)
434 {
435  static const WCHAR szDot[] = { '.',0 };
436  static const WCHAR szPrefix[] = { 's','t','g',0 };
437  static CHAR aval[] = "hi";
438  static WCHAR wval[] = { 'h','i',0 };
439  HRESULT hr;
440  IStorage *storage = NULL;
441  IPropertySetStorage *propSetStorage = NULL;
442  IPropertyStorage *propertyStorage = NULL;
443  PROPSPEC spec;
444  PROPVARIANT var;
445  WCHAR fileName[MAX_PATH];
446 
447  if(!GetTempFileNameW(szDot, szPrefix, 0, fileName))
448  return;
449 
450  hr = StgCreateDocfile(fileName,
452  ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
453 
454  if(!pStgCreatePropSetStg)
455  {
456  IStorage_Release(storage);
457  DeleteFileW(fileName);
458  return;
459  }
460  hr = pStgCreatePropSetStg(storage, 0, &propSetStorage);
461  ok(hr == S_OK, "StgCreatePropSetStg failed: 0x%08x\n", hr);
462 
463  hr = IPropertySetStorage_Create(propSetStorage,
464  &FMTID_SummaryInformation, NULL, PROPSETFLAG_DEFAULT,
466  &propertyStorage);
467  ok(hr == S_OK, "IPropertySetStorage_Create failed: 0x%08x\n", hr);
468 
469  PropVariantInit(&var);
470  spec.ulKind = PRSPEC_PROPID;
471  U(spec).propid = PID_CODEPAGE;
472  /* check code page before it's been explicitly set */
473  hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
474  ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
475  ok(var.vt == VT_I2 && U(var).iVal == 1200,
476  "Didn't get expected type or value for property\n");
477  /* Set the code page to ascii */
478  var.vt = VT_I2;
479  U(var).iVal = 1252;
480  hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
481  ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
482  /* check code page */
483  hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
484  ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
485  ok(var.vt == VT_I2 && U(var).iVal == 1252,
486  "Didn't get expected type or value for property\n");
487  /* Set code page to Unicode */
488  U(var).iVal = 1200;
489  hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
490  ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
491  /* check code page */
492  hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
493  ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
494  ok(var.vt == VT_I2 && U(var).iVal == 1200,
495  "Didn't get expected type or value for property\n");
496  /* Set a string value */
497  spec.ulKind = PRSPEC_PROPID;
498  U(spec).propid = PID_FIRST_USABLE;
499  var.vt = VT_LPSTR;
500  U(var).pszVal = aval;
501  hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
502  ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
503  hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
504  ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
505  ok(var.vt == VT_LPSTR && !strcmp(U(var).pszVal, "hi"),
506  "Didn't get expected type or value for property\n");
507  PropVariantClear(&var);
508  /* This seemingly non-sensical test is to show that the string is indeed
509  * interpreted according to the current system code page, not according to
510  * the property set's code page. (If the latter were true, the whole
511  * string would be maintained. As it is, only the first character is.)
512  */
513  var.vt = VT_LPSTR;
514  U(var).pszVal = (LPSTR)wval;
515  hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
516  ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
517  hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
518  ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
519  ok(var.vt == VT_LPSTR && !strcmp(U(var).pszVal, "h"),
520  "Didn't get expected type or value for property\n");
521  PropVariantClear(&var);
522 
523  /* now that a property's been set, you can't change the code page */
524  spec.ulKind = PRSPEC_PROPID;
525  U(spec).propid = PID_CODEPAGE;
526  var.vt = VT_I2;
527  U(var).iVal = 1200;
528  hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
530  "Expected STG_E_INVALIDPARAMETER, got 0x%08x\n", hr);
531 
532  IPropertyStorage_Release(propertyStorage);
533  IPropertySetStorage_Release(propSetStorage);
534  IStorage_Release(storage);
535 
536  DeleteFileW(fileName);
537 
538  /* same tests, but with PROPSETFLAG_ANSI */
539  hr = StgCreateDocfile(fileName,
541  ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
542 
543  hr = pStgCreatePropSetStg(storage, 0, &propSetStorage);
544  ok(hr == S_OK, "StgCreatePropSetStg failed: 0x%08x\n", hr);
545 
546  hr = IPropertySetStorage_Create(propSetStorage,
547  &FMTID_SummaryInformation, NULL, PROPSETFLAG_ANSI,
549  &propertyStorage);
550  ok(hr == S_OK, "IPropertySetStorage_Create failed: 0x%08x\n", hr);
551 
552  /* check code page before it's been explicitly set */
553  hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
554  ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
555  ok(var.vt == VT_I2, "Didn't get expected type for property (%u)\n", var.vt);
556  /* Set code page to Unicode */
557  U(var).iVal = 1200;
558  hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
559  ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
560  /* check code page */
561  hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
562  ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
563  ok(var.vt == VT_I2 && U(var).iVal == 1200,
564  "Didn't get expected type or value for property\n");
565  /* This test is commented out for documentation. It fails under Wine,
566  * and I expect it would under Windows as well, yet it succeeds. There's
567  * obviously something about string conversion I don't understand.
568  */
569  if(0) {
570  static unsigned char strVal[] = { 0x81, 0xff, 0x04, 0 };
571  /* Set code page to 950 (Traditional Chinese) */
572  U(var).iVal = 950;
573  hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
574  ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
575  /* Try writing an invalid string: lead byte 0x81 is unused in Traditional
576  * Chinese.
577  */
578  spec.ulKind = PRSPEC_PROPID;
579  U(spec).propid = PID_FIRST_USABLE;
580  var.vt = VT_LPSTR;
581  U(var).pszVal = (LPSTR)strVal;
582  hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
583  ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
584  /* Check returned string */
585  hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
586  ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
587  ok(var.vt == VT_LPSTR && !strcmp(U(var).pszVal, (LPCSTR)strVal),
588  "Didn't get expected type or value for property\n");
589  }
590 
591  IPropertyStorage_Release(propertyStorage);
592  IPropertySetStorage_Release(propSetStorage);
593  IStorage_Release(storage);
594 
595  DeleteFileW(fileName);
596 }
597 
598 static void testFmtId(void)
599 {
600  WCHAR szSummaryInfo[] = { 5,'S','u','m','m','a','r','y',
601  'I','n','f','o','r','m','a','t','i','o','n',0 };
602  WCHAR szDocSummaryInfo[] = { 5,'D','o','c','u','m','e','n','t',
603  'S','u','m','m','a','r','y','I','n','f','o','r','m','a','t','i','o','n',
604  0 };
605  WCHAR szIID_IPropSetStg[] = { 5,'0','j','a','a','a','a','a',
606  'a','A','a','a','a','a','a','d','a','A','a','a','a','a','a','a','a','G',
607  'c',0 };
608  WCHAR name[32];
609  FMTID fmtid;
610  HRESULT hr;
611 
612  if (pFmtIdToPropStgName) {
613  hr = pFmtIdToPropStgName(NULL, name);
614  ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got 0x%08x\n", hr);
615  hr = pFmtIdToPropStgName(&FMTID_SummaryInformation, NULL);
616  ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got 0x%08x\n", hr);
617  hr = pFmtIdToPropStgName(&FMTID_SummaryInformation, name);
618  ok(hr == S_OK, "FmtIdToPropStgName failed: 0x%08x\n", hr);
620  sizeof(WCHAR)), "Got wrong name for FMTID_SummaryInformation\n");
621  hr = pFmtIdToPropStgName(&FMTID_DocSummaryInformation, name);
622  ok(hr == S_OK, "FmtIdToPropStgName failed: 0x%08x\n", hr);
624  sizeof(WCHAR)), "Got wrong name for FMTID_DocSummaryInformation\n");
625  hr = pFmtIdToPropStgName(&FMTID_UserDefinedProperties, name);
626  ok(hr == S_OK, "FmtIdToPropStgName failed: 0x%08x\n", hr);
628  sizeof(WCHAR)), "Got wrong name for FMTID_DocSummaryInformation\n");
629  hr = pFmtIdToPropStgName(&IID_IPropertySetStorage, name);
630  ok(hr == S_OK, "FmtIdToPropStgName failed: 0x%08x\n", hr);
631  ok(!memcmp(name, szIID_IPropSetStg, (lstrlenW(szIID_IPropSetStg) + 1) *
632  sizeof(WCHAR)), "Got wrong name for IID_IPropertySetStorage\n");
633  }
634 
635  if(pPropStgNameToFmtId) {
636  /* test args first */
637  hr = pPropStgNameToFmtId(NULL, NULL);
638  ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got 0x%08x\n", hr);
639  hr = pPropStgNameToFmtId(NULL, &fmtid);
640  ok(hr == STG_E_INVALIDNAME, "Expected STG_E_INVALIDNAME, got 0x%08x\n",
641  hr);
642  hr = pPropStgNameToFmtId(szDocSummaryInfo, NULL);
643  ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got 0x%08x\n", hr);
644  /* test the known format IDs */
645  hr = pPropStgNameToFmtId(szSummaryInfo, &fmtid);
646  ok(hr == S_OK, "PropStgNameToFmtId failed: 0x%08x\n", hr);
647  ok(!memcmp(&fmtid, &FMTID_SummaryInformation, sizeof(fmtid)),
648  "Got unexpected FMTID, expected FMTID_SummaryInformation\n");
649  hr = pPropStgNameToFmtId(szDocSummaryInfo, &fmtid);
650  ok(hr == S_OK, "PropStgNameToFmtId failed: 0x%08x\n", hr);
651  ok(!memcmp(&fmtid, &FMTID_DocSummaryInformation, sizeof(fmtid)),
652  "Got unexpected FMTID, expected FMTID_DocSummaryInformation\n");
653  /* test another GUID */
654  hr = pPropStgNameToFmtId(szIID_IPropSetStg, &fmtid);
655  ok(hr == S_OK, "PropStgNameToFmtId failed: 0x%08x\n", hr);
656  ok(!memcmp(&fmtid, &IID_IPropertySetStorage, sizeof(fmtid)),
657  "Got unexpected FMTID, expected IID_IPropertySetStorage\n");
658  /* now check case matching */
660  hr = pPropStgNameToFmtId(szDocSummaryInfo, &fmtid);
661  ok(hr == S_OK, "PropStgNameToFmtId failed: 0x%08x\n", hr);
662  ok(!memcmp(&fmtid, &FMTID_DocSummaryInformation, sizeof(fmtid)),
663  "Got unexpected FMTID, expected FMTID_DocSummaryInformation\n");
664  CharUpperW(szIID_IPropSetStg + 1);
665  hr = pPropStgNameToFmtId(szIID_IPropSetStg, &fmtid);
666  ok(hr == S_OK, "PropStgNameToFmtId failed: 0x%08x\n", hr);
667  ok(!memcmp(&fmtid, &IID_IPropertySetStorage, sizeof(fmtid)),
668  "Got unexpected FMTID, expected IID_IPropertySetStorage\n");
669  }
670 }
671 
672 START_TEST(stg_prop)
673 {
675  testProps();
676  testCodepage();
677  testFmtId();
678 }
#define trace(...)
Definition: kmt_test.h:217
#define STG_E_INVALIDNAME
Definition: winerror.h:2584
Definition: compat.h:1939
static void testCodepage(void)
Definition: stg_prop.c:433
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
static void testPropsHelper(IPropertySetStorage **propSetStorage)
Definition: stg_prop.c:46
#define CF_ENHMETAFILE
Definition: constants.h:409
HRESULT hr
Definition: shlfolder.c:183
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
#define STGM_SHARE_EXCLUSIVE
Definition: objbase.h:922
#define PID_BEHAVIOR
Definition: stg_prop.c:24
HRESULT WINAPI PropVariantClear(PROPVARIANT *pvar)
Definition: ole2.c:2952
static void testProps(void)
Definition: stg_prop.c:425
char CHAR
Definition: xmlstorage.h:175
#define U(x)
Definition: wordpad.c:44
#define STGM_CREATE
Definition: objbase.h:925
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
static FMTID *static IPropertySetStorage **static const CLSID IPropertyStorage **static IPropertyStorage **static void init_function_pointers(void)
Definition: stg_prop.c:33
char * LPSTR
Definition: xmlstorage.h:182
const char * filename
Definition: ioapi.h:135
static LPOLESTR
Definition: stg_prop.c:27
#define lstrlenW
Definition: compat.h:407
const FMTID FMTID_UserDefinedProperties
#define PID_CODEPAGE
Definition: suminfo.c:43
LPWSTR WINAPI CharUpperW(_Inout_ LPWSTR)
static FMTID *static IPropertySetStorage **static REFFMTID
Definition: stg_prop.c:30
#define PID_FIRST_USABLE
Definition: propkeydef.h:20
const FMTID FMTID_SummaryInformation
#define ok(value,...)
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
smooth NULL
Definition: ftsmooth.c:416
const char * LPCSTR
Definition: xmlstorage.h:183
static HRESULT(WINAPI *pFmtIdToPropStgName)(const FMTID *
GLuint GLfloat * val
Definition: glext.h:7180
static FMTID *static DWORD
Definition: stg_prop.c:29
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:77
HRESULT WINAPI StgOpenStorage(const OLECHAR *pwcsName, IStorage *pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8756
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:8
UINT WINAPI GetTempFileNameW(IN LPCWSTR lpPathName, IN LPCWSTR lpPrefixString, IN UINT uUnique, OUT LPWSTR lpTempFileName)
Definition: filename.c:84
#define STG_E_INVALIDPARAMETER
Definition: winerror.h:2580
const FMTID FMTID_DocSummaryInformation
Definition: parse.h:22
static const WCHAR szDot[]
Definition: msipriv.h:1113
HRESULT WINAPI StgCreateDocfile(LPCOLESTR pwcsName, DWORD grfMode, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8637
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:819
static const WCHAR szSummaryInfo[]
Definition: stg_prop.c:2619
#define STGM_READWRITE
Definition: objbase.h:918
static PEXPLICIT_ACCESSW *static HMODULE hmod
Definition: security.c:141
Definition: compat.h:1977
#define S_OK
Definition: intsafe.h:59
static void testFmtId(void)
Definition: stg_prop.c:598
#define PID_DICTIONARY
Definition: suminfo.c:42
Definition: name.c:36
static const WCHAR szDocSummaryInfo[]
Definition: stg_prop.c:2621
unsigned int ULONG
Definition: retypes.h:1
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define GetProcAddress(x, y)
Definition: compat.h:410
Definition: compat.h:1938
START_TEST(stg_prop)
Definition: stg_prop.c:672