ReactOS  0.4.14-dev-50-g13bb5e2
propvariant.c
Go to the documentation of this file.
1 /*
2  * PropVariant Tests
3  *
4  * Copyright 2004 Robert Shearman
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include "windows.h"
22 #include "wtypes.h"
23 #include "ddeml.h"
24 
25 #include "wine/test.h"
26 
27 /* invalid in all versions */
28 #define PROP_INV 0x7f
29 /* valid in v0 and above (NT4+) */
30 #define PROP_V0 0
31 /* valid in v1 and above (Win2k+) */
32 #define PROP_V1 1
33 /* valid in v1a and above (WinXP+) */
34 #define PROP_V1A 2
35 #define PROP_TODO 0x80
36 
37 static const struct valid_mapping
38 {
43 } valid_types[] =
44 {
45  { PROP_V0 , PROP_INV, PROP_INV, PROP_INV }, /* VT_EMPTY */
46  { PROP_V0 , PROP_INV, PROP_INV, PROP_INV }, /* VT_NULL */
47  { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_I2 */
48  { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_I4 */
49  { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_R4 */
50  { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_R8 */
51  { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_CY */
52  { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_DATE */
53  { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_BSTR */
54  { PROP_V1 , PROP_V1 | PROP_TODO , PROP_INV, PROP_V1 | PROP_TODO }, /* VT_DISPATCH */
55  { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_ERROR */
56  { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_BOOL */
57  { PROP_V1 | PROP_TODO , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_VARIANT */
58  { PROP_V1 , PROP_V1 | PROP_TODO , PROP_INV, PROP_V1 | PROP_TODO }, /* VT_UNKNOWN */
59  { PROP_V1 , PROP_V1 | PROP_TODO , PROP_INV, PROP_V1 | PROP_TODO }, /* VT_DECIMAL */
60  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 15 */
61  { PROP_V1 , PROP_V1 | PROP_TODO , PROP_V1 , PROP_V1 | PROP_TODO }, /* VT_I1 */
62  { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_UI1 */
63  { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_UI2 */
64  { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_UI4 */
65  { PROP_V0 , PROP_V1A | PROP_TODO, PROP_V0 , PROP_V1A | PROP_TODO }, /* VT_I8 */
66  { PROP_V0 , PROP_V1A | PROP_TODO, PROP_V0 , PROP_V1A | PROP_TODO }, /* VT_UI8 */
67  { PROP_V1 , PROP_V1 | PROP_TODO , PROP_INV, PROP_V1 | PROP_TODO }, /* VT_INT */
68  { PROP_V1 , PROP_V1 | PROP_TODO , PROP_INV, PROP_V1 | PROP_TODO }, /* VT_UINT */
69  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* VT_VOID */
70  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* VT_HRESULT */
71  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* VT_PTR */
72  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* VT_SAFEARRAY */
73  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* VT_CARRAY */
74  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* VT_USERDEFINED */
75  { PROP_V0 , PROP_INV, PROP_V0 , PROP_INV }, /* VT_LPSTR */
76  { PROP_V0 , PROP_INV, PROP_V0 , PROP_INV }, /* VT_LPWSTR */
77  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 32 */
78  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 33 */
79  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 34 */
80  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 35 */
81  { PROP_V1 | PROP_TODO , PROP_V1 | PROP_TODO , PROP_INV, PROP_V1 | PROP_TODO }, /* VT_RECORD */
82  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* VT_INT_PTR */
83  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* VT_UINT_PTR */
84  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 39 */
85  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 40 */
86  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 41 */
87  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 42 */
88  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 43 */
89  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 44 */
90  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 45 */
91  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 46 */
92  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 47 */
93  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 48 */
94  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 49 */
95  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 50 */
96  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 51 */
97  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 52 */
98  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 53 */
99  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 54 */
100  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 55 */
101  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 56 */
102  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 57 */
103  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 58 */
104  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 59 */
105  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 60 */
106  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 61 */
107  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 62 */
108  { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 63 */
109  { PROP_V0 , PROP_INV, PROP_V0 , PROP_INV }, /* VT_FILETIME */
110  { PROP_V0 , PROP_INV, PROP_INV, PROP_INV }, /* VT_BLOB */
111  { PROP_V0 , PROP_INV, PROP_INV, PROP_INV }, /* VT_STREAM */
112  { PROP_V0 , PROP_INV, PROP_INV, PROP_INV }, /* VT_STORAGE */
113  { PROP_V0 , PROP_INV, PROP_INV, PROP_INV }, /* VT_STREAMED_OBJECT */
114  { PROP_V0 , PROP_INV, PROP_INV, PROP_INV }, /* VT_STORED_OBJECT */
115  { PROP_V0 , PROP_INV, PROP_INV, PROP_INV }, /* VT_BLOB_OBJECT */
116  { PROP_V0 , PROP_INV, PROP_V0 , PROP_INV } /* VT_CF */
117 };
118 
119 static const char* wine_vtypes[VT_CLSID+1] =
120 {
121  "VT_EMPTY","VT_NULL","VT_I2","VT_I4","VT_R4","VT_R8","VT_CY","VT_DATE",
122  "VT_BSTR","VT_DISPATCH","VT_ERROR","VT_BOOL","VT_VARIANT","VT_UNKNOWN",
123  "VT_DECIMAL","15","VT_I1","VT_UI1","VT_UI2","VT_UI4","VT_I8","VT_UI8",
124  "VT_INT","VT_UINT","VT_VOID","VT_HRESULT","VT_PTR","VT_SAFEARRAY",
125  "VT_CARRAY","VT_USERDEFINED","VT_LPSTR","VT_LPWSTR","32","33","34","35",
126  "VT_RECORD","VT_INT_PTR","VT_UINT_PTR","39","40","41","42","43","44","45",
127  "46","47","48","49","50","51","52","53","54","55","56","57","58","59","60",
128  "61","62","63","VT_FILETIME","VT_BLOB","VT_STREAM","VT_STORAGE",
129  "VT_STREAMED_OBJECT","VT_STORED_OBJECT","VT_BLOB_OBJECT","VT_CF","VT_CLSID"
130 };
131 
132 
133 static void expect(HRESULT hr, VARTYPE vt, BOOL copy, int line)
134 {
135  int idx = vt & VT_TYPEMASK;
136  BYTE flags;
137  const char *modifier;
138 
139  if(vt & VT_BYREF)
140  {
141  flags = valid_types[idx].byref;
142  modifier = "byref";
143  }
144  else if(vt & VT_ARRAY)
145  {
146  flags = valid_types[idx].with_array;
147  modifier = "array";
148  }
149  else if(vt & VT_VECTOR)
150  {
151  flags = valid_types[idx].with_vector;
152  modifier = "vector";
153  }
154  else
155  {
156  flags = valid_types[idx].simple;
157  modifier = "simple";
158  }
159 
160  if(flags == PROP_INV)
161  {
162  if (copy && (vt & VT_VECTOR))
163  ok(hr == DISP_E_BADVARTYPE || hr == STG_E_INVALIDPARAMETER, "%s (%s): got %08x (line %d)\n", wine_vtypes[idx], modifier, hr, line);
164  else
165  ok(hr == (copy ? DISP_E_BADVARTYPE : STG_E_INVALIDPARAMETER), "%s (%s): got %08x (line %d)\n", wine_vtypes[idx], modifier, hr, line);
166  }
167  else if(flags == PROP_V0)
168  ok(hr == S_OK, "%s (%s): got %08x\n", wine_vtypes[idx], modifier, hr);
170  {
171  if(hr != S_OK)
172  win_skip("%s (%s): unsupported\n", wine_vtypes[idx], modifier);
173  else ok(hr == S_OK, "%s (%s): got %08x\n", wine_vtypes[idx], modifier, hr);
174  }
175 }
176 
177 static void test_validtypes(void)
178 {
179  PROPVARIANT propvar, copy, uninit;
180  HRESULT hr;
181  unsigned int i, ret;
182 
183  memset(&uninit, 0x77, sizeof(uninit));
184 
185  memset(&propvar, 0x55, sizeof(propvar));
186  hr = PropVariantClear(&propvar);
187  ok(hr == STG_E_INVALIDPARAMETER, "expected STG_E_INVALIDPARAMETER, got %08x\n", hr);
188  ok(propvar.vt == 0, "expected 0, got %d\n", propvar.vt);
189  ok(U(propvar).uhVal.QuadPart == 0, "expected 0, got %#x/%#x\n",
190  U(propvar).uhVal.u.LowPart, U(propvar).uhVal.u.HighPart);
191 
192  for (i = 0; i < ARRAY_SIZE(valid_types); i++)
193  {
194  VARTYPE vt;
195 
196  memset(&propvar, 0x55, sizeof(propvar));
197  if (i == VT_RECORD)
198  memset(&propvar, 0, sizeof(propvar));
199  else if (i == VT_BLOB || i == VT_BLOB_OBJECT)
200  {
201  U(propvar).blob.cbSize = 0;
202  U(propvar).blob.pBlobData = NULL;
203  }
204  else
205  U(propvar).pszVal = NULL;
206  vt = propvar.vt = i;
207  memset(&copy, 0x77, sizeof(copy));
208  hr = PropVariantCopy(&copy, &propvar);
209  expect(hr, vt, TRUE, __LINE__);
210  if (hr == S_OK)
211  {
212  ok(copy.vt == propvar.vt, "expected %d, got %d\n", propvar.vt, copy.vt);
213  ok(U(copy).uhVal.QuadPart == U(propvar).uhVal.QuadPart, "%u: expected %#x/%#x, got %#x/%#x\n",
214  i, U(propvar).uhVal.u.LowPart, U(propvar).uhVal.u.HighPart,
215  U(copy).uhVal.u.LowPart, U(copy).uhVal.u.HighPart);
216  }
217  else
218  {
219  ret = memcmp(&copy, &uninit, sizeof(copy));
220  ok(!ret || broken(ret) /* win2000 */, "%d: copy should stay unchanged\n", i);
221  }
222  hr = PropVariantClear(&propvar);
223  expect(hr, vt, FALSE, __LINE__);
224  ok(propvar.vt == 0, "expected 0, got %d\n", propvar.vt);
225  ok(U(propvar).uhVal.QuadPart == 0, "%u: expected 0, got %#x/%#x\n",
226  i, U(propvar).uhVal.u.LowPart, U(propvar).uhVal.u.HighPart);
227 
228  memset(&propvar, 0x55, sizeof(propvar));
229  U(propvar).pszVal = NULL;
230  vt = propvar.vt = i | VT_ARRAY;
231  memset(&copy, 0x77, sizeof(copy));
232  hr = PropVariantCopy(&copy, &propvar);
233  expect(hr, vt, TRUE, __LINE__);
234  if (hr == S_OK)
235  {
236  ok(copy.vt == propvar.vt, "expected %d, got %d\n", propvar.vt, copy.vt);
237  ok(U(copy).uhVal.QuadPart == 0, "%u: expected 0, got %#x/%#x\n",
238  i, U(copy).uhVal.u.LowPart, U(copy).uhVal.u.HighPart);
239  }
240  else
241  {
242  ret = memcmp(&copy, &uninit, sizeof(copy));
243  ok(!ret || broken(ret) /* win2000 */, "%d: copy should stay unchanged\n", i);
244  }
245  hr = PropVariantClear(&propvar);
246  expect(hr, vt, FALSE, __LINE__);
247  ok(propvar.vt == 0, "expected 0, got %d\n", propvar.vt);
248  ok(U(propvar).uhVal.QuadPart == 0, "%u: expected 0, got %#x/%#x\n",
249  i, U(propvar).uhVal.u.LowPart, U(propvar).uhVal.u.HighPart);
250 
251  memset(&propvar, 0x55, sizeof(propvar));
252  U(propvar).caub.cElems = 0;
253  U(propvar).caub.pElems = NULL;
254  vt = propvar.vt = i | VT_VECTOR;
255  memset(&copy, 0x77, sizeof(copy));
256  hr = PropVariantCopy(&copy, &propvar);
257  expect(hr, vt, TRUE, __LINE__);
258  if (hr == S_OK)
259  {
260  ok(copy.vt == propvar.vt, "expected %d, got %d\n", propvar.vt, copy.vt);
261  ok(!U(copy).caub.cElems, "%u: expected 0, got %d\n", i, U(copy).caub.cElems);
262  ok(!U(copy).caub.pElems, "%u: expected NULL, got %p\n", i, U(copy).caub.pElems);
263  }
264  else
265  {
266  ret = memcmp(&copy, &uninit, sizeof(copy));
267  ok(!ret || broken(ret) /* win2000 */, "%d: copy should stay unchanged\n", i);
268  }
269  hr = PropVariantClear(&propvar);
270  expect(hr, vt, FALSE, __LINE__);
271  ok(propvar.vt == 0, "expected 0, got %d\n", propvar.vt);
272  ok(U(propvar).uhVal.QuadPart == 0, "%u: expected 0, got %#x/%#x\n",
273  i, U(propvar).uhVal.u.LowPart, U(propvar).uhVal.u.HighPart);
274 
275  memset(&propvar, 0x55, sizeof(propvar));
276  U(propvar).pszVal = NULL;
277  vt = propvar.vt = i | VT_BYREF;
278  memset(&copy, 0x77, sizeof(copy));
279  hr = PropVariantCopy(&copy, &propvar);
280  expect(hr, vt, TRUE, __LINE__);
281  if (hr == S_OK)
282  {
283  ok(copy.vt == propvar.vt, "expected %d, got %d\n", propvar.vt, copy.vt);
284  ok(U(copy).uhVal.QuadPart == U(propvar).uhVal.QuadPart, "%u: expected %#x/%#x, got %#x/%#x\n",
285  i, U(propvar).uhVal.u.LowPart, U(propvar).uhVal.u.HighPart,
286  U(copy).uhVal.u.LowPart, U(copy).uhVal.u.HighPart);
287  }
288  else
289  {
290  ret = memcmp(&copy, &uninit, sizeof(copy));
291  ok(!ret || broken(ret) /* win2000 */, "%d: copy should stay unchanged\n", i);
292  }
293  hr = PropVariantClear(&propvar);
294  expect(hr, vt, FALSE, __LINE__);
295  ok(propvar.vt == 0, "expected 0, got %d\n", propvar.vt);
296  ok(U(propvar).uhVal.QuadPart == 0, "%u: expected 0, got %#x/%#x\n",
297  i, U(propvar).uhVal.u.LowPart, U(propvar).uhVal.u.HighPart);
298  }
299 }
300 
301 static void test_copy(void)
302 {
303  static char szTestString[] = "Test String";
304  static WCHAR wszTestString[] = {'T','e','s','t',' ','S','t','r','i','n','g',0};
305  PROPVARIANT propvarSrc;
306  PROPVARIANT propvarDst;
307  HRESULT hr;
308 
309  propvarSrc.vt = VT_BSTR;
310  U(propvarSrc).bstrVal = SysAllocString(wszTestString);
311 
312  hr = PropVariantCopy(&propvarDst, &propvarSrc);
313  ok(hr == S_OK, "PropVariantCopy(...VT_BSTR...) failed\n");
314  ok(!lstrcmpW(U(propvarSrc).bstrVal, U(propvarDst).bstrVal), "BSTR not copied properly\n");
316  ok(hr == S_OK, "PropVariantClear(...VT_BSTR...) failed\n");
317  hr = PropVariantClear(&propvarDst);
318  ok(hr == S_OK, "PropVariantClear(...VT_BSTR...) failed\n");
319 
320  propvarSrc.vt = VT_LPWSTR;
321  U(propvarSrc).pwszVal = wszTestString;
322  hr = PropVariantCopy(&propvarDst, &propvarSrc);
323  ok(hr == S_OK, "PropVariantCopy(...VT_LPWSTR...) failed\n");
324  ok(!lstrcmpW(U(propvarSrc).pwszVal, U(propvarDst).pwszVal), "Wide string not copied properly\n");
325  hr = PropVariantClear(&propvarDst);
326  ok(hr == S_OK, "PropVariantClear(...VT_LPWSTR...) failed\n");
327  memset(&propvarSrc, 0, sizeof(propvarSrc));
328 
329  propvarSrc.vt = VT_LPSTR;
330  U(propvarSrc).pszVal = szTestString;
331  hr = PropVariantCopy(&propvarDst, &propvarSrc);
332  ok(hr == S_OK, "PropVariantCopy(...VT_LPSTR...) failed\n");
333  ok(!strcmp(U(propvarSrc).pszVal, U(propvarDst).pszVal), "String not copied properly\n");
334  hr = PropVariantClear(&propvarDst);
335  ok(hr == S_OK, "PropVariantClear(...VT_LPSTR...) failed\n");
336  memset(&propvarSrc, 0, sizeof(propvarSrc));
337 }
338 
340  void *Allocate; /* virtual void* Allocate(ULONG cbSize); */
341  void *Free; /* virtual void Free(void *pv); */
342 };
343 
344 typedef struct _PMemoryAllocator {
347 
349 {
350  return CoTaskMemAlloc(cbSize);
351 }
352 
353 static void WINAPI PMemoryAllocator_Free(PMemoryAllocator *_this, void *pv)
354 {
355  CoTaskMemFree(pv);
356 }
357 
358 #ifdef __i386__
359 
360 #include "pshpack1.h"
361 typedef struct
362 {
363  BYTE pop_eax; /* popl %eax */
364  BYTE push_ecx; /* pushl %ecx */
365  BYTE push_eax; /* pushl %eax */
366  BYTE jmp_func; /* jmp $func */
367  DWORD func;
369 #include "poppack.h"
370 
372 
373 static void fill_thunk(THISCALL_TO_STDCALL_THUNK *thunk, void *fn)
374 {
375  thunk->pop_eax = 0x58;
376  thunk->push_ecx = 0x51;
377  thunk->push_eax = 0x50;
378  thunk->jmp_func = 0xe9;
379  thunk->func = (char*)fn - (char*)(&thunk->func + 1);
380 }
381 
382 static void setup_vtable(struct _PMemoryAllocator_vtable *vtable)
383 {
386 
387  fill_thunk(&wrapperCodeMem[0], PMemoryAllocator_Allocate);
388  fill_thunk(&wrapperCodeMem[1], PMemoryAllocator_Free);
389 
390  vtable->Allocate = &wrapperCodeMem[0];
391  vtable->Free = &wrapperCodeMem[1];
392 }
393 
394 #else
395 
397 {
398  vtable->Allocate = PMemoryAllocator_Allocate;
400 }
401 
402 #endif
403 
404 static const char serialized_empty[] = {
405  0,0, /* VT_EMPTY */
406  0,0, /* padding */
407 };
408 
409 static const char serialized_null[] = {
410  1,0, /* VT_NULL */
411  0,0, /* padding */
412 };
413 
414 static const char serialized_i4[] = {
415  3,0, /* VT_I4 */
416  0,0, /* padding */
417  0xef,0xcd,0xab,0xfe
418 };
419 
420 static const char serialized_bstr_wc[] = {
421  8,0, /* VT_BSTR */
422  0,0, /* padding */
423  10,0,0,0, /* size */
424  't',0,'e',0,
425  's',0,'t',0,
426  0,0,0,0
427 };
428 
429 static const char serialized_bstr_mb[] = {
430  8,0, /* VT_BSTR */
431  0,0, /* padding */
432  5,0,0,0, /* size */
433  't','e','s','t',
434  0,0,0,0
435 };
436 
437 static void test_propertytovariant(void)
438 {
439  HANDLE hole32;
440  BOOLEAN (__stdcall *pStgConvertPropertyToVariant)(const SERIALIZEDPROPERTYVALUE*,USHORT,PROPVARIANT*,PMemoryAllocator*);
441  PROPVARIANT propvar;
444  BOOLEAN ret;
445  static const WCHAR test_string[] = {'t','e','s','t',0};
446 
447  hole32 = GetModuleHandleA("ole32");
448 
449  pStgConvertPropertyToVariant = (void*)GetProcAddress(hole32, "StgConvertPropertyToVariant");
450 
451  if (!pStgConvertPropertyToVariant)
452  {
453  win_skip("StgConvertPropertyToVariant not available\n");
454  return;
455  }
456 
458  allocator.vt = &vtable;
459 
460  ret = pStgConvertPropertyToVariant((SERIALIZEDPROPERTYVALUE*)serialized_empty,
461  CP_WINUNICODE, &propvar, &allocator);
462 
463  ok(ret == 0, "StgConvertPropertyToVariant returned %i\n", ret);
464  ok(propvar.vt == VT_EMPTY, "unexpected vt %x\n", propvar.vt);
465 
466  ret = pStgConvertPropertyToVariant((SERIALIZEDPROPERTYVALUE*)serialized_null,
467  CP_WINUNICODE, &propvar, &allocator);
468 
469  ok(ret == 0, "StgConvertPropertyToVariant returned %i\n", ret);
470  ok(propvar.vt == VT_NULL, "unexpected vt %x\n", propvar.vt);
471 
472  ret = pStgConvertPropertyToVariant((SERIALIZEDPROPERTYVALUE*)serialized_i4,
473  CP_WINUNICODE, &propvar, &allocator);
474 
475  ok(ret == 0, "StgConvertPropertyToVariant returned %i\n", ret);
476  ok(propvar.vt == VT_I4, "unexpected vt %x\n", propvar.vt);
477  ok(U(propvar).lVal == 0xfeabcdef, "unexpected lVal %x\n", U(propvar).lVal);
478 
479  ret = pStgConvertPropertyToVariant((SERIALIZEDPROPERTYVALUE*)serialized_bstr_wc,
480  CP_WINUNICODE, &propvar, &allocator);
481 
482  ok(ret == 0, "StgConvertPropertyToVariant returned %i\n", ret);
483  ok(propvar.vt == VT_BSTR, "unexpected vt %x\n", propvar.vt);
484  ok(!lstrcmpW(U(propvar).bstrVal, test_string), "unexpected string value\n");
485  PropVariantClear(&propvar);
486 
487  ret = pStgConvertPropertyToVariant((SERIALIZEDPROPERTYVALUE*)serialized_bstr_mb,
488  CP_UTF8, &propvar, &allocator);
489 
490  ok(ret == 0, "StgConvertPropertyToVariant returned %i\n", ret);
491  ok(propvar.vt == VT_BSTR, "unexpected vt %x\n", propvar.vt);
492  ok(!lstrcmpW(U(propvar).bstrVal, test_string), "unexpected string value\n");
493  PropVariantClear(&propvar);
494 }
495 
496 static void test_varianttoproperty(void)
497 {
498  HANDLE hole32;
499  PROPVARIANT propvar;
500  SERIALIZEDPROPERTYVALUE *propvalue, *own_propvalue;
501  SERIALIZEDPROPERTYVALUE* (__stdcall *pStgConvertVariantToProperty)(
502  const PROPVARIANT*,USHORT,SERIALIZEDPROPERTYVALUE*,ULONG*,PROPID,BOOLEAN,ULONG*);
503  ULONG len;
504  static const WCHAR test_string[] = {'t','e','s','t',0};
505  BSTR test_string_bstr;
506 
507  hole32 = GetModuleHandleA("ole32");
508 
509  pStgConvertVariantToProperty = (void*)GetProcAddress(hole32, "StgConvertVariantToProperty");
510 
511  if (!pStgConvertVariantToProperty)
512  {
513  win_skip("StgConvertVariantToProperty not available\n");
514  return;
515  }
516 
517  own_propvalue = HeapAlloc(GetProcessHeap(), 0, sizeof(SERIALIZEDPROPERTYVALUE) + 20);
518 
519  PropVariantInit(&propvar);
520 
521  propvar.vt = VT_I4;
522  U(propvar).lVal = 0xfeabcdef;
523 
524  len = 0xdeadbeef;
525  propvalue = pStgConvertVariantToProperty(&propvar, CP_WINUNICODE, NULL, &len,
526  0, FALSE, 0);
527 
528  ok(propvalue == NULL, "got nonnull propvalue\n");
529  todo_wine ok(len == 8, "unexpected length %d\n", len);
530 
531  if (len == 0xdeadbeef)
532  {
533  HeapFree(GetProcessHeap(), 0, own_propvalue);
534  return;
535  }
536 
537  len = 20;
538  propvalue = pStgConvertVariantToProperty(&propvar, CP_WINUNICODE, own_propvalue, &len,
539  0, FALSE, 0);
540 
541  ok(propvalue == own_propvalue, "unexpected propvalue %p\n", propvalue);
542  ok(len == 8, "unexpected length %d\n", len);
543  ok(!memcmp(propvalue, serialized_i4, 8), "got wrong data\n");
544 
545  propvar.vt = VT_EMPTY;
546  len = 20;
547  own_propvalue->dwType = 0xdeadbeef;
548  propvalue = pStgConvertVariantToProperty(&propvar, CP_WINUNICODE, own_propvalue, &len,
549  0, FALSE, 0);
550 
551  ok(propvalue == own_propvalue, "unexpected propvalue %p\n", propvalue);
552  ok(len == 4 || broken(len == 0) /* before Vista */, "unexpected length %d\n", len);
553  if (len) ok(!memcmp(propvalue, serialized_empty, 4), "got wrong data\n");
554  else ok(propvalue->dwType == 0xdeadbeef, "unexpected type %d\n", propvalue->dwType);
555 
556  propvar.vt = VT_NULL;
557  len = 20;
558  propvalue = pStgConvertVariantToProperty(&propvar, CP_WINUNICODE, own_propvalue, &len,
559  0, FALSE, 0);
560 
561  ok(propvalue == own_propvalue, "unexpected propvalue %p\n", propvalue);
562  ok(len == 4, "unexpected length %d\n", len);
563  ok(!memcmp(propvalue, serialized_null, 4), "got wrong data\n");
564 
565  test_string_bstr = SysAllocString(test_string);
566 
567  propvar.vt = VT_BSTR;
568  U(propvar).bstrVal = test_string_bstr;
569  len = 20;
570  propvalue = pStgConvertVariantToProperty(&propvar, CP_WINUNICODE, own_propvalue, &len,
571  0, FALSE, 0);
572 
573  ok(propvalue == own_propvalue, "unexpected propvalue %p\n", propvalue);
574  ok(len == 20, "unexpected length %d\n", len);
575  ok(!memcmp(propvalue, serialized_bstr_wc, 20), "got wrong data\n");
576 
577  len = 20;
578  propvalue = pStgConvertVariantToProperty(&propvar, CP_UTF8, own_propvalue, &len,
579  0, FALSE, 0);
580 
581  ok(propvalue == own_propvalue, "unexpected propvalue %p\n", propvalue);
582  ok(len == 16, "unexpected length %d\n", len);
583  ok(!memcmp(propvalue, serialized_bstr_mb, 16), "got wrong data\n");
584 
585  SysFreeString(test_string_bstr);
586 
587  HeapFree(GetProcessHeap(), 0, own_propvalue);
588 }
589 
590 START_TEST(propvariant)
591 {
592  test_validtypes();
593  test_copy();
596 }
GLenum func
Definition: glext.h:6028
#define TRUE
Definition: types.h:120
static void test_varianttoproperty(void)
Definition: propvariant.c:496
Definition: compat.h:1939
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:422
static void * vtable[]
Definition: typelib.c:1231
SERIALIZEDPROPERTYVALUE
Definition: propidl.idl:439
HRESULT hr
Definition: shlfolder.c:183
Definition: cproxy.c:203
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159
HRESULT WINAPI PropVariantClear(PROPVARIANT *pvar)
Definition: ole2.c:2952
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
#define U(x)
Definition: wordpad.c:44
static void expect(HRESULT hr, VARTYPE vt, BOOL copy, int line)
Definition: propvariant.c:133
#define PROP_TODO
Definition: propvariant.c:35
OLECHAR * BSTR
Definition: compat.h:1934
void uninit(_In_ device_extension *Vcb)
Definition: btrfs.c:1970
static const CLSID IPropertyStorage UINT *static const PROPSPEC PROPVARIANT *static UINT const PROPSPEC PROPVARIANT PROPID
Definition: shellole.c:77
static void test_propertytovariant(void)
Definition: propvariant.c:437
#define MEM_COMMIT
Definition: nt_native.h:1313
static REFPROPVARIANT propvarSrc
Definition: suminfo.c:85
static const char serialized_bstr_mb[]
Definition: propvariant.c:429
struct _PMemoryAllocator_vtable * vt
Definition: propvariant.c:345
static const char serialized_empty[]
Definition: propvariant.c:404
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
LPVOID NTAPI VirtualAlloc(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD flAllocationType, IN DWORD flProtect)
Definition: virtmem.c:74
#define CP_UTF8
Definition: nls.h:20
#define PROP_V0
Definition: propvariant.c:30
unsigned int BOOL
Definition: ntddk_ex.h:94
static const char serialized_null[]
Definition: propvariant.c:409
unsigned int idx
Definition: utils.c:41
unsigned char BOOLEAN
static void setup_vtable(struct _PMemoryAllocator_vtable *vtable)
Definition: propvariant.c:396
START_TEST(propvariant)
Definition: propvariant.c:590
smooth NULL
Definition: ftsmooth.c:416
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:241
Definition: parser.c:48
#define PROP_V1
Definition: propvariant.c:32
static void test_copy(void)
Definition: propvariant.c:301
HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, const PROPVARIANT *pvarSrc)
Definition: ole2.c:3068
#define todo_wine_if(is_todo)
Definition: test.h:155
static void * wrapperCodeMem
Definition: txtsrv.c:509
BYTE with_vector
Definition: propvariant.c:41
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:77
#define WINAPI
Definition: msvc.h:8
unsigned long DWORD
Definition: ntddk_ex.h:95
#define PROP_INV
Definition: propvariant.c:28
#define __stdcall
Definition: typedefs.h:25
static REFPROPVARIANT PROPVAR_CHANGE_FLAGS VARTYPE vt
Definition: suminfo.c:85
#define STG_E_INVALIDPARAMETER
Definition: winerror.h:2580
GLbitfield flags
Definition: glext.h:7161
#define DISP_E_BADVARTYPE
Definition: winerror.h:2517
int ret
#define todo_wine
Definition: test.h:154
GLenum GLsizei len
Definition: glext.h:6722
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:821
unsigned char BYTE
Definition: mem.h:68
static const char serialized_bstr_wc[]
Definition: propvariant.c:420
#define broken(x)
Definition: _sntprintf.h:21
static const char serialized_i4[]
Definition: propvariant.c:414
#define PROP_V1A
Definition: propvariant.c:34
static void test_validtypes(void)
Definition: propvariant.c:177
#define S_OK
Definition: intsafe.h:59
unsigned short USHORT
Definition: pedump.c:61
#define ARRAY_SIZE(a)
Definition: main.h:24
#define ok(value,...)
Definition: atltest.h:57
unsigned short VARTYPE
Definition: compat.h:1895
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
#define CP_WINUNICODE
Definition: ddeml.h:33
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:274
void test_string()
Definition: test_string.cpp:38
#define BOOLEAN
Definition: pedump.c:73
static void WINAPI PMemoryAllocator_Free(PMemoryAllocator *_this, void *pv)
Definition: propvariant.c:353
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
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
static const char * wine_vtypes[VT_CLSID+1]
Definition: propvariant.c:119
struct _PMemoryAllocator PMemoryAllocator
#define memset(x, y, z)
Definition: compat.h:39
static const struct valid_mapping valid_types[]
#define win_skip
Definition: test.h:141
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:406
static void *WINAPI PMemoryAllocator_Allocate(PMemoryAllocator *_this, ULONG cbSize)
Definition: propvariant.c:348
#define HeapFree(x, y, z)
Definition: compat.h:394