ReactOS  0.4.14-dev-606-g14ebc0b
propvar.c
Go to the documentation of this file.
1 /*
2  * PropVariant implementation
3  *
4  * Copyright 2008 James Hawkins for CodeWeavers
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 
22 #include <stdarg.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 
26 #define NONAMELESSUNION
27 
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winerror.h"
31 #include "winreg.h"
32 #include "winuser.h"
33 #include "shlobj.h"
34 #include "propvarutil.h"
35 #include "strsafe.h"
36 
37 #include "wine/debug.h"
38 
40 
41 static HRESULT PROPVAR_ConvertFILETIME(const FILETIME *ft, PROPVARIANT *ppropvarDest, VARTYPE vt)
42 {
44 
46 
47  switch (vt)
48  {
49  case VT_LPSTR:
50  ppropvarDest->u.pszVal = HeapAlloc(GetProcessHeap(), 0, 64);
51  if (!ppropvarDest->u.pszVal)
52  return E_OUTOFMEMORY;
53 
54  sprintf( ppropvarDest->u.pszVal, "%04d/%02d/%02d:%02d:%02d:%02d.%03d",
55  time.wYear, time.wMonth, time.wDay,
56  time.wHour, time.wMinute, time.wSecond,
57  time.wMilliseconds );
58 
59  return S_OK;
60 
61  default:
62  FIXME("Unhandled target type: %d\n", vt);
63  }
64 
65  return E_FAIL;
66 }
67 
68 static HRESULT PROPVAR_ConvertNumber(REFPROPVARIANT pv, int dest_bits,
69  BOOL dest_signed, LONGLONG *res)
70 {
71  BOOL src_signed;
72 
73  switch (pv->vt)
74  {
75  case VT_I1:
76  src_signed = TRUE;
77  *res = pv->u.cVal;
78  break;
79  case VT_UI1:
80  src_signed = FALSE;
81  *res = pv->u.bVal;
82  break;
83  case VT_I2:
84  src_signed = TRUE;
85  *res = pv->u.iVal;
86  break;
87  case VT_UI2:
88  src_signed = FALSE;
89  *res = pv->u.uiVal;
90  break;
91  case VT_I4:
92  src_signed = TRUE;
93  *res = pv->u.lVal;
94  break;
95  case VT_UI4:
96  src_signed = FALSE;
97  *res = pv->u.ulVal;
98  break;
99  case VT_I8:
100  src_signed = TRUE;
101  *res = pv->u.hVal.QuadPart;
102  break;
103  case VT_UI8:
104  src_signed = FALSE;
105  *res = pv->u.uhVal.QuadPart;
106  break;
107  case VT_EMPTY:
108  src_signed = FALSE;
109  *res = 0;
110  break;
111  case VT_LPSTR:
112  {
113  char *end;
114  *res = _strtoi64(pv->u.pszVal, &end, 0);
115  if (pv->u.pszVal == end)
116  return DISP_E_TYPEMISMATCH;
117  src_signed = *res < 0;
118  break;
119  }
120  case VT_LPWSTR:
121  case VT_BSTR:
122  {
123  WCHAR *end;
124  *res = wcstol(pv->u.pwszVal, &end, 0);
125  if (pv->u.pwszVal == end)
126  return DISP_E_TYPEMISMATCH;
127  src_signed = *res < 0;
128  break;
129  }
130  case VT_R8:
131  {
132  src_signed = TRUE;
133  *res = pv->u.dblVal;
134  break;
135  }
136  default:
137  FIXME("unhandled vt %d\n", pv->vt);
138  return E_NOTIMPL;
139  }
140 
141  if (*res < 0 && src_signed != dest_signed)
143 
144  if (dest_bits < 64)
145  {
146  if (dest_signed)
147  {
148  if (*res >= ((LONGLONG)1 << (dest_bits-1)) ||
149  *res < ((LONGLONG)-1 << (dest_bits-1)))
151  }
152  else
153  {
154  if ((ULONGLONG)(*res) >= ((ULONGLONG)1 << dest_bits))
156  }
157  }
158 
159  return S_OK;
160 }
161 
162 HRESULT WINAPI PropVariantToDouble(REFPROPVARIANT propvarIn, double *ret)
163 {
164  LONGLONG res;
165  HRESULT hr;
166 
167  TRACE("(%p, %p)\n", propvarIn, ret);
168 
169  hr = PROPVAR_ConvertNumber(propvarIn, 64, TRUE, &res);
170  if (SUCCEEDED(hr)) *ret = (double)res;
171  return hr;
172 }
173 
174 HRESULT WINAPI PropVariantToInt16(REFPROPVARIANT propvarIn, SHORT *ret)
175 {
176  LONGLONG res;
177  HRESULT hr;
178 
179  TRACE("%p,%p\n", propvarIn, ret);
180 
181  hr = PROPVAR_ConvertNumber(propvarIn, 16, TRUE, &res);
182  if (SUCCEEDED(hr)) *ret = (SHORT)res;
183  return hr;
184 }
185 
186 HRESULT WINAPI PropVariantToInt32(REFPROPVARIANT propvarIn, LONG *ret)
187 {
188  LONGLONG res;
189  HRESULT hr;
190 
191  TRACE("%p,%p\n", propvarIn, ret);
192 
193  hr = PROPVAR_ConvertNumber(propvarIn, 32, TRUE, &res);
194  if (SUCCEEDED(hr)) *ret = (LONG)res;
195  return hr;
196 }
197 
198 HRESULT WINAPI PropVariantToInt64(REFPROPVARIANT propvarIn, LONGLONG *ret)
199 {
200  LONGLONG res;
201  HRESULT hr;
202 
203  TRACE("%p,%p\n", propvarIn, ret);
204 
205  hr = PROPVAR_ConvertNumber(propvarIn, 64, TRUE, &res);
206  if (SUCCEEDED(hr)) *ret = res;
207  return hr;
208 }
209 
210 HRESULT WINAPI PropVariantToUInt16(REFPROPVARIANT propvarIn, USHORT *ret)
211 {
212  LONGLONG res;
213  HRESULT hr;
214 
215  TRACE("%p,%p\n", propvarIn, ret);
216 
217  hr = PROPVAR_ConvertNumber(propvarIn, 16, FALSE, &res);
218  if (SUCCEEDED(hr)) *ret = (USHORT)res;
219  return hr;
220 }
221 
222 HRESULT WINAPI PropVariantToUInt32(REFPROPVARIANT propvarIn, ULONG *ret)
223 {
224  LONGLONG res;
225  HRESULT hr;
226 
227  TRACE("%p,%p\n", propvarIn, ret);
228 
229  hr = PROPVAR_ConvertNumber(propvarIn, 32, FALSE, &res);
230  if (SUCCEEDED(hr)) *ret = (ULONG)res;
231  return hr;
232 }
233 
234 HRESULT WINAPI PropVariantToUInt64(REFPROPVARIANT propvarIn, ULONGLONG *ret)
235 {
236  LONGLONG res;
237  HRESULT hr;
238 
239  TRACE("%p,%p\n", propvarIn, ret);
240 
241  hr = PROPVAR_ConvertNumber(propvarIn, 64, FALSE, &res);
242  if (SUCCEEDED(hr)) *ret = (ULONGLONG)res;
243  return hr;
244 }
245 
246 HRESULT WINAPI PropVariantToBoolean(REFPROPVARIANT propvarIn, BOOL *ret)
247 {
248  static const WCHAR trueW[] = {'t','r','u','e',0};
249  static const WCHAR falseW[] = {'f','a','l','s','e',0};
250  static const WCHAR true2W[] = {'#','T','R','U','E','#',0};
251  static const WCHAR false2W[] = {'#','F','A','L','S','E','#',0};
252  LONGLONG res;
253  HRESULT hr;
254 
255  TRACE("%p,%p\n", propvarIn, ret);
256 
257  *ret = FALSE;
258 
259  switch (propvarIn->vt)
260  {
261  case VT_BOOL:
262  *ret = propvarIn->u.boolVal == VARIANT_TRUE;
263  return S_OK;
264 
265  case VT_LPWSTR:
266  case VT_BSTR:
267  if (!propvarIn->u.pwszVal)
268  return DISP_E_TYPEMISMATCH;
269 
270  if (!lstrcmpiW(propvarIn->u.pwszVal, trueW) || !lstrcmpW(propvarIn->u.pwszVal, true2W))
271  {
272  *ret = TRUE;
273  return S_OK;
274  }
275 
276  if (!lstrcmpiW(propvarIn->u.pwszVal, falseW) || !lstrcmpW(propvarIn->u.pwszVal, false2W))
277  {
278  *ret = FALSE;
279  return S_OK;
280  }
281  break;
282 
283  case VT_LPSTR:
284  if (!propvarIn->u.pszVal)
285  return DISP_E_TYPEMISMATCH;
286 
287  if (!lstrcmpiA(propvarIn->u.pszVal, "true") || !lstrcmpA(propvarIn->u.pszVal, "#TRUE#"))
288  {
289  *ret = TRUE;
290  return S_OK;
291  }
292 
293  if (!lstrcmpiA(propvarIn->u.pszVal, "false") || !lstrcmpA(propvarIn->u.pszVal, "#FALSE#"))
294  {
295  *ret = FALSE;
296  return S_OK;
297  }
298  break;
299  }
300 
301  hr = PROPVAR_ConvertNumber(propvarIn, 64, TRUE, &res);
302  *ret = !!res;
303  return hr;
304 }
305 
306 HRESULT WINAPI PropVariantToBuffer(REFPROPVARIANT propvarIn, void *ret, UINT cb)
307 {
308  HRESULT hr = S_OK;
309 
310  TRACE("(%p, %p, %d)\n", propvarIn, ret, cb);
311 
312  switch(propvarIn->vt)
313  {
314  case VT_VECTOR|VT_UI1:
315  if(cb > propvarIn->u.caub.cElems)
316  return E_FAIL;
317  memcpy(ret, propvarIn->u.caub.pElems, cb);
318  break;
319  case VT_ARRAY|VT_UI1:
320  FIXME("Unsupported type: VT_ARRAY|VT_UI1\n");
321  hr = E_NOTIMPL;
322  break;
323  default:
324  WARN("Unexpected type: %x\n", propvarIn->vt);
325  hr = E_INVALIDARG;
326  }
327 
328  return hr;
329 }
330 
331 
332 HRESULT WINAPI PropVariantToString(REFPROPVARIANT propvarIn, PWSTR ret, UINT cch)
333 {
334  HRESULT hr;
335  WCHAR *stringW = NULL;
336 
337  TRACE("(%p, %p, %d)\n", propvarIn, ret, cch);
338 
339  ret[0] = '\0';
340 
341  if(!cch)
342  return E_INVALIDARG;
343 
344  hr = PropVariantToStringAlloc(propvarIn, &stringW);
345  if(SUCCEEDED(hr))
346  {
347  if(lstrlenW(stringW) >= cch)
351  }
352 
353  return hr;
354 }
355 
356 HRESULT WINAPI PropVariantToStringAlloc(REFPROPVARIANT propvarIn, WCHAR **ret)
357 {
358  WCHAR *res = NULL;
359  HRESULT hr = S_OK;
360 
361  TRACE("%p,%p semi-stub\n", propvarIn, ret);
362 
363  switch(propvarIn->vt)
364  {
365  case VT_EMPTY:
366  case VT_NULL:
367  res = CoTaskMemAlloc(1*sizeof(WCHAR));
368  res[0] = '\0';
369  break;
370 
371  case VT_LPSTR:
372  if(propvarIn->u.pszVal)
373  {
374  DWORD len;
375 
376  len = MultiByteToWideChar(CP_ACP, 0, propvarIn->u.pszVal, -1, NULL, 0);
377  res = CoTaskMemAlloc(len*sizeof(WCHAR));
378  if(!res)
379  return E_OUTOFMEMORY;
380 
381  MultiByteToWideChar(CP_ACP, 0, propvarIn->u.pszVal, -1, res, len);
382  }
383  break;
384 
385  case VT_LPWSTR:
386  case VT_BSTR:
387  if (propvarIn->u.pwszVal)
388  {
389  DWORD size = (lstrlenW(propvarIn->u.pwszVal) + 1) * sizeof(WCHAR);
391  if(!res) return E_OUTOFMEMORY;
392  memcpy(res, propvarIn->u.pwszVal, size);
393  }
394  break;
395 
396  default:
397  FIXME("Unsupported conversion (%d)\n", propvarIn->vt);
398  hr = E_FAIL;
399  break;
400  }
401 
402  *ret = res;
403 
404  return hr;
405 }
406 
407 PCWSTR WINAPI PropVariantToStringWithDefault(REFPROPVARIANT propvarIn, LPCWSTR pszDefault)
408 {
409  static const WCHAR str_empty[] = {0};
410  if (propvarIn->vt == VT_BSTR)
411  {
412  if (propvarIn->u.bstrVal == NULL)
413  return str_empty;
414 
415  return propvarIn->u.bstrVal;
416  }
417 
418  if (propvarIn->vt == VT_LPWSTR && propvarIn->u.pwszVal != NULL)
419  return propvarIn->u.pwszVal;
420 
421  return pszDefault;
422 }
423 
424 
425 /******************************************************************
426  * PropVariantChangeType (PROPSYS.@)
427  */
428 HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT propvarSrc,
430 {
431  HRESULT hr;
432 
433  FIXME("(%p, %p, %d, %d, %d): semi-stub!\n", ppropvarDest, propvarSrc,
434  propvarSrc->vt, flags, vt);
435 
436  if (vt == propvarSrc->vt)
437  return PropVariantCopy(ppropvarDest, propvarSrc);
438 
439  if (propvarSrc->vt == VT_FILETIME)
440  return PROPVAR_ConvertFILETIME(&propvarSrc->u.filetime, ppropvarDest, vt);
441 
442  switch (vt)
443  {
444  case VT_I1:
445  {
446  LONGLONG res;
447 
449  if (SUCCEEDED(hr))
450  {
451  ppropvarDest->vt = VT_I1;
452  ppropvarDest->u.cVal = (char)res;
453  }
454  return hr;
455  }
456 
457  case VT_UI1:
458  {
459  LONGLONG res;
460 
462  if (SUCCEEDED(hr))
463  {
464  ppropvarDest->vt = VT_UI1;
465  ppropvarDest->u.bVal = (UCHAR)res;
466  }
467  return hr;
468  }
469 
470  case VT_I2:
471  {
472  SHORT res;
474  if (SUCCEEDED(hr))
475  {
476  ppropvarDest->vt = VT_I2;
477  ppropvarDest->u.iVal = res;
478  }
479  return hr;
480  }
481  case VT_UI2:
482  {
483  USHORT res;
485  if (SUCCEEDED(hr))
486  {
487  ppropvarDest->vt = VT_UI2;
488  ppropvarDest->u.uiVal = res;
489  }
490  return hr;
491  }
492  case VT_I4:
493  {
494  LONG res;
496  if (SUCCEEDED(hr))
497  {
498  ppropvarDest->vt = VT_I4;
499  ppropvarDest->u.lVal = res;
500  }
501  return hr;
502  }
503  case VT_UI4:
504  {
505  ULONG res;
507  if (SUCCEEDED(hr))
508  {
509  ppropvarDest->vt = VT_UI4;
510  ppropvarDest->u.ulVal = res;
511  }
512  return hr;
513  }
514  case VT_I8:
515  {
516  LONGLONG res;
518  if (SUCCEEDED(hr))
519  {
520  ppropvarDest->vt = VT_I8;
521  ppropvarDest->u.hVal.QuadPart = res;
522  }
523  return hr;
524  }
525  case VT_UI8:
526  {
527  ULONGLONG res;
529  if (SUCCEEDED(hr))
530  {
531  ppropvarDest->vt = VT_UI8;
532  ppropvarDest->u.uhVal.QuadPart = res;
533  }
534  return hr;
535  }
536 
537  case VT_LPWSTR:
538  case VT_BSTR:
539  {
540  WCHAR *res;
542  if (SUCCEEDED(hr))
543  {
544  ppropvarDest->vt = VT_LPWSTR;
545  ppropvarDest->u.pwszVal = res;
546  }
547  return hr;
548  }
549 
550  case VT_LPSTR:
551  {
552  WCHAR *resW;
554  if (SUCCEEDED(hr))
555  {
556  char *res;
557  DWORD len;
558 
559  len = WideCharToMultiByte(CP_ACP, 0, resW, -1, NULL, 0, NULL, NULL);
561  if (res)
562  {
563  WideCharToMultiByte(CP_ACP, 0, resW, -1, res, len, NULL, NULL);
564  ppropvarDest->vt = VT_LPSTR;
565  ppropvarDest->u.pszVal = res;
566  }
567  else
568  hr = E_OUTOFMEMORY;
569 
570  CoTaskMemFree(resW);
571  }
572  return hr;
573  }
574 
575  default:
576  FIXME("Unhandled dest type: %d\n", vt);
577  return E_FAIL;
578  }
579 }
580 
582 {
583  static const WCHAR format[] = {'{','%','0','8','X','-','%','0','4','X','-','%','0','4','X',
584  '-','%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2','X',
585  '%','0','2','X','%','0','2','X','%','0','2','X','}',0};
586 
587  swprintf(str, format, guid->Data1, guid->Data2, guid->Data3,
588  guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
589  guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
590 }
591 
593 {
594  TRACE("(%p %p)\n", guid, ppropvar);
595 
596  if(!guid)
597  return E_FAIL;
598 
599  ppropvar->vt = VT_LPWSTR;
600  ppropvar->u.pwszVal = CoTaskMemAlloc(39*sizeof(WCHAR));
601  if(!ppropvar->u.pwszVal)
602  return E_OUTOFMEMORY;
603 
604  PROPVAR_GUIDToWSTR(guid, ppropvar->u.pwszVal);
605  return S_OK;
606 }
607 
609 {
610  TRACE("(%p %p)\n", guid, pvar);
611 
612  if(!guid) {
613  FIXME("guid == NULL\n");
614  return E_FAIL;
615  }
616 
617  V_VT(pvar) = VT_BSTR;
618  V_BSTR(pvar) = SysAllocStringLen(NULL, 38);
619  if(!V_BSTR(pvar))
620  return E_OUTOFMEMORY;
621 
623  return S_OK;
624 }
625 
626 HRESULT WINAPI InitPropVariantFromBuffer(const VOID *pv, UINT cb, PROPVARIANT *ppropvar)
627 {
628  TRACE("(%p %u %p)\n", pv, cb, ppropvar);
629 
630  ppropvar->u.caub.pElems = CoTaskMemAlloc(cb);
631  if(!ppropvar->u.caub.pElems)
632  return E_OUTOFMEMORY;
633 
634  ppropvar->vt = VT_VECTOR|VT_UI1;
635  ppropvar->u.caub.cElems = cb;
636  memcpy(ppropvar->u.caub.pElems, pv, cb);
637  return S_OK;
638 }
639 
641 {
642  TRACE("(%s %p)\n", debugstr_guid(clsid), ppropvar);
643 
644  ppropvar->u.puuid = CoTaskMemAlloc(sizeof(*ppropvar->u.puuid));
645  if(!ppropvar->u.puuid)
646  return E_OUTOFMEMORY;
647 
648  ppropvar->vt = VT_CLSID;
649  memcpy(ppropvar->u.puuid, clsid, sizeof(*ppropvar->u.puuid));
650  return S_OK;
651 }
652 
654 {
655  SAFEARRAY *arr;
656  void *data;
657  HRESULT hres;
658 
659  TRACE("(%p %u %p)\n", pv, cb, pvar);
660 
661  arr = SafeArrayCreateVector(VT_UI1, 0, cb);
662  if(!arr)
663  return E_OUTOFMEMORY;
664 
665  hres = SafeArrayAccessData(arr, &data);
666  if(FAILED(hres)) {
667  SafeArrayDestroy(arr);
668  return hres;
669  }
670 
671  memcpy(data, pv, cb);
672 
674  if(FAILED(hres)) {
675  SafeArrayDestroy(arr);
676  return hres;
677  }
678 
679  V_VT(pvar) = VT_ARRAY|VT_UI1;
680  V_ARRAY(pvar) = arr;
681  return S_OK;
682 }
683 
684 static inline DWORD PROPVAR_HexToNum(const WCHAR *hex)
685 {
686  DWORD ret;
687 
688  if(hex[0]>='0' && hex[0]<='9')
689  ret = hex[0]-'0';
690  else if(hex[0]>='a' && hex[0]<='f')
691  ret = hex[0]-'a'+10;
692  else if(hex[0]>='A' && hex[0]<='F')
693  ret = hex[0]-'A'+10;
694  else
695  return -1;
696 
697  ret <<= 4;
698  if(hex[1]>='0' && hex[1]<='9')
699  return ret + hex[1]-'0';
700  else if(hex[1]>='a' && hex[1]<='f')
701  return ret + hex[1]-'a'+10;
702  else if(hex[1]>='A' && hex[1]<='F')
703  return ret + hex[1]-'A'+10;
704  else
705  return -1;
706 }
707 
708 static inline HRESULT PROPVAR_WCHARToGUID(const WCHAR *str, int len, GUID *guid)
709 {
710  DWORD i, val=0;
711  const WCHAR *p;
712 
713  memset(guid, 0, sizeof(GUID));
714 
715  if(len!=38 || str[0]!='{' || str[9]!='-' || str[14]!='-'
716  || str[19]!='-' || str[24]!='-' || str[37]!='}') {
717  WARN("Error parsing %s\n", debugstr_w(str));
718  return E_INVALIDARG;
719  }
720 
721  p = str+1;
722  for(i=0; i<4 && val!=-1; i++) {
724  guid->Data1 = (guid->Data1<<8) + val;
725  p += 2;
726  }
727  p++;
728  for(i=0; i<2 && val!=-1; i++) {
730  guid->Data2 = (guid->Data2<<8) + val;
731  p += 2;
732  }
733  p++;
734  for(i=0; i<2 && val!=-1; i++) {
736  guid->Data3 = (guid->Data3<<8) + val;
737  p += 2;
738  }
739  p++;
740  for(i=0; i<8 && val!=-1; i++) {
741  if(i == 2)
742  p++;
743 
744  val = guid->Data4[i] = PROPVAR_HexToNum(p);
745  p += 2;
746  }
747 
748  if(val == -1) {
749  WARN("Error parsing %s\n", debugstr_w(str));
750  memset(guid, 0, sizeof(GUID));
751  return E_INVALIDARG;
752  }
753  return S_OK;
754 }
755 
756 HRESULT WINAPI PropVariantToGUID(const PROPVARIANT *ppropvar, GUID *guid)
757 {
758  TRACE("%p %p)\n", ppropvar, guid);
759 
760  switch(ppropvar->vt) {
761  case VT_BSTR:
762  return PROPVAR_WCHARToGUID(ppropvar->u.bstrVal, SysStringLen(ppropvar->u.bstrVal), guid);
763  case VT_LPWSTR:
764  return PROPVAR_WCHARToGUID(ppropvar->u.pwszVal, lstrlenW(ppropvar->u.pwszVal), guid);
765  case VT_CLSID:
766  memcpy(guid, ppropvar->u.puuid, sizeof(*ppropvar->u.puuid));
767  return S_OK;
768 
769  default:
770  FIXME("unsupported vt: %d\n", ppropvar->vt);
771  return E_NOTIMPL;
772  }
773 }
774 
776 {
777  TRACE("(%p %p)\n", pvar, guid);
778 
779  switch(V_VT(pvar)) {
780  case VT_BSTR: {
782  if(hres == E_INVALIDARG)
783  return E_FAIL;
784  return hres;
785  }
786 
787  default:
788  FIXME("unsupported vt: %d\n", V_VT(pvar));
789  return E_NOTIMPL;
790  }
791 }
792 
793 static BOOL isemptyornull(const PROPVARIANT *propvar)
794 {
795  if (propvar->vt == VT_EMPTY || propvar->vt == VT_NULL)
796  return TRUE;
797  if ((propvar->vt & VT_ARRAY) == VT_ARRAY)
798  {
799  int i;
800  for (i=0; i<propvar->u.parray->cDims; i++)
801  {
802  if (propvar->u.parray->rgsabound[i].cElements != 0)
803  break;
804  }
805  return i == propvar->u.parray->cDims;
806  }
807  if (propvar->vt == VT_CLSID)
808  return !propvar->u.puuid;
809 
810  /* FIXME: vectors, byrefs, errors? */
811  return FALSE;
812 }
813 
814 INT WINAPI PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2,
816 {
817  const PROPVARIANT *propvar2_converted;
818  PROPVARIANT propvar2_static;
819  HRESULT hr;
820  INT res=-1;
821 
822  TRACE("%p,%p,%x,%x\n", propvar1, propvar2, unit, flags);
823 
824  if (isemptyornull(propvar1))
825  {
826  if (isemptyornull(propvar2))
827  return 0;
828  return (flags & PVCF_TREATEMPTYASGREATERTHAN) ? 1 : -1;
829  }
830 
831  if (isemptyornull(propvar2))
832  return (flags & PVCF_TREATEMPTYASGREATERTHAN) ? -1 : 1;
833 
834  if (propvar1->vt != propvar2->vt)
835  {
836  hr = PropVariantChangeType(&propvar2_static, propvar2, 0, propvar1->vt);
837 
838  if (FAILED(hr))
839  return -1;
840 
841  propvar2_converted = &propvar2_static;
842  }
843  else
844  propvar2_converted = propvar2;
845 
846 #define CMP_NUM_VALUE(var) do { \
847  if (propvar1->u.var > propvar2_converted->u.var) \
848  res = 1; \
849  else if (propvar1->u.var < propvar2_converted->u.var) \
850  res = -1; \
851  else \
852  res = 0; \
853  } while (0)
854 
855  switch (propvar1->vt)
856  {
857  case VT_I1:
858  CMP_NUM_VALUE(cVal);
859  break;
860  case VT_UI1:
861  CMP_NUM_VALUE(bVal);
862  break;
863  case VT_I2:
864  CMP_NUM_VALUE(iVal);
865  break;
866  case VT_UI2:
867  CMP_NUM_VALUE(uiVal);
868  break;
869  case VT_I4:
870  CMP_NUM_VALUE(lVal);
871  break;
872  case VT_UI4:
873  CMP_NUM_VALUE(uiVal);
874  break;
875  case VT_I8:
876  CMP_NUM_VALUE(hVal.QuadPart);
877  break;
878  case VT_UI8:
879  CMP_NUM_VALUE(uhVal.QuadPart);
880  break;
881  case VT_R4:
882  CMP_NUM_VALUE(fltVal);
883  break;
884  case VT_R8:
885  CMP_NUM_VALUE(dblVal);
886  break;
887  case VT_BSTR:
888  case VT_LPWSTR:
889  /* FIXME: Use other string flags. */
891  res = lstrcmpiW(propvar1->u.bstrVal, propvar2_converted->u.bstrVal);
892  else
893  res = lstrcmpW(propvar1->u.bstrVal, propvar2_converted->u.bstrVal);
894  break;
895  case VT_LPSTR:
896  /* FIXME: Use other string flags. */
898  res = lstrcmpiA(propvar1->u.pszVal, propvar2_converted->u.pszVal);
899  else
900  res = lstrcmpA(propvar1->u.pszVal, propvar2_converted->u.pszVal);
901  break;
902  case VT_CLSID:
903  res = memcmp(propvar1->u.puuid, propvar2->u.puuid, sizeof(*propvar1->u.puuid));
904  if (res) res = res > 0 ? 1 : -1;
905  break;
906  default:
907  FIXME("vartype %#x not handled\n", propvar1->vt);
908  res = -1;
909  break;
910  }
911 
912  if (propvar2_converted == &propvar2_static)
913  PropVariantClear(&propvar2_static);
914 
915  return res;
916 }
HRESULT WINAPI PropVariantToUInt16(REFPROPVARIANT propvarIn, USHORT *ret)
Definition: propvar.c:210
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define TRUE
Definition: types.h:120
Definition: compat.h:1947
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:420
int WINAPI lstrcmpiA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:42
#define WideCharToMultiByte
Definition: compat.h:101
Definition: compat.h:1963
HRESULT hr
Definition: shlfolder.c:183
Definition: scsiwmi.h:51
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:339
Definition: compat.h:1959
HRESULT WINAPI PropVariantClear(PROPVARIANT *pvar)
Definition: ole2.c:2968
uint16_t * PWSTR
Definition: typedefs.h:54
int PROPVAR_COMPARE_FLAGS
Definition: propvarutil.h:64
#define REFCLSID
Definition: guiddef.h:117
#define CP_ACP
Definition: compat.h:99
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
static HRESULT PROPVAR_ConvertFILETIME(const FILETIME *ft, PROPVARIANT *ppropvarDest, VARTYPE vt)
Definition: propvar.c:41
int PROPVAR_COMPARE_UNIT
Definition: propvarutil.h:52
#define V_ARRAY(A)
Definition: oleauto.h:222
_Check_return_ __MINGW_EXTENSION _CRTIMP __int64 __cdecl _strtoi64(_In_z_ const char *_String, _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix)
#define CMP_NUM_VALUE(var)
#define WARN(fmt,...)
Definition: debug.h:111
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT propvarSrc, PROPVAR_CHANGE_FLAGS flags, VARTYPE vt)
Definition: propvar.c:428
HRESULT WINAPI PropVariantToBuffer(REFPROPVARIANT propvarIn, void *ret, UINT cb)
Definition: propvar.c:306
GLuint GLuint end
Definition: gl.h:1545
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
__u16 time
Definition: mkdosfs.c:366
static const char hex[16]
Definition: profile.c:123
HRESULT WINAPI VariantToGUID(const VARIANT *pvar, GUID *guid)
Definition: propvar.c:775
#define lstrlenW
Definition: compat.h:415
#define E_FAIL
Definition: ddrawi.h:102
INT WINAPI PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2, PROPVAR_COMPARE_UNIT unit, PROPVAR_COMPARE_FLAGS flags)
Definition: propvar.c:814
static REFPROPVARIANT propvarSrc
Definition: suminfo.c:85
#define STRSAFE_E_INSUFFICIENT_BUFFER
Definition: strsafe.h:103
int32_t INT
Definition: typedefs.h:56
static const WCHAR stringW[]
Definition: engine.c:38
int PROPVAR_CHANGE_FLAGS
Definition: propvarutil.h:39
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
#define lstrcpynW
Definition: compat.h:405
HRESULT WINAPI PropVariantToInt32(REFPROPVARIANT propvarIn, LONG *ret)
Definition: propvar.c:186
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
#define sprintf(buf, format,...)
Definition: sprintf.c:55
PCWSTR WINAPI PropVariantToStringWithDefault(REFPROPVARIANT propvarIn, LPCWSTR pszDefault)
Definition: propvar.c:407
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
const GUID * guid
WINE_DEFAULT_DEBUG_CHANNEL(propsys)
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
HRESULT WINAPI SafeArrayAccessData(SAFEARRAY *psa, void **ppvData)
Definition: safearray.c:1137
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
static HRESULT PROPVAR_WCHARToGUID(const WCHAR *str, int len, GUID *guid)
Definition: propvar.c:708
short SHORT
Definition: pedump.c:59
#define debugstr_w
Definition: kernel32.h:32
#define FIXME(fmt,...)
Definition: debug.h:110
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:80
#define E_INVALIDARG
Definition: ddrawi.h:101
png_const_structrp png_const_inforp int * unit
Definition: png.h:2161
const WCHAR * str
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:201
static HRESULT PROPVAR_ConvertNumber(REFPROPVARIANT pv, int dest_bits, BOOL dest_signed, LONGLONG *res)
Definition: propvar.c:68
smooth NULL
Definition: ftsmooth.c:416
unsigned char
Definition: typeof.h:29
static void PROPVAR_GUIDToWSTR(REFGUID guid, WCHAR *str)
Definition: propvar.c:581
HRESULT WINAPI PropVariantToStringAlloc(REFPROPVARIANT propvarIn, WCHAR **ret)
Definition: propvar.c:356
#define ERROR_ARITHMETIC_OVERFLOW
Definition: winerror.h:351
#define debugstr_guid
Definition: kernel32.h:35
GLuint GLfloat * val
Definition: glext.h:7180
HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, const PROPVARIANT *pvarSrc)
Definition: ole2.c:3086
HRESULT WINAPI InitPropVariantFromGUIDAsString(REFGUID guid, PROPVARIANT *ppropvar)
Definition: propvar.c:592
int64_t LONGLONG
Definition: typedefs.h:66
HRESULT WINAPI InitPropVariantFromBuffer(const VOID *pv, UINT cb, PROPVARIANT *ppropvar)
Definition: propvar.c:626
#define DISP_E_TYPEMISMATCH
Definition: winerror.h:2514
#define TRACE(s)
Definition: solgame.cpp:4
BOOL WINAPI FileTimeToSystemTime(IN CONST FILETIME *lpFileTime, OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:188
HRESULT WINAPI PropVariantToGUID(const PROPVARIANT *ppropvar, GUID *guid)
Definition: propvar.c:756
GLsizeiptr size
Definition: glext.h:5919
HRESULT hres
Definition: protocol.c:465
#define GetProcessHeap()
Definition: compat.h:403
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:77
uint64_t ULONGLONG
Definition: typedefs.h:65
static const WCHAR falseW[]
Definition: json.c:34
#define swprintf(buf, format,...)
Definition: sprintf.c:56
#define WINAPI
Definition: msvc.h:6
unsigned long DWORD
Definition: ntddk_ex.h:95
static REFPROPVARIANT PROPVAR_CHANGE_FLAGS VARTYPE vt
Definition: suminfo.c:85
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLbitfield flags
Definition: glext.h:7161
HRESULT WINAPI SafeArrayDestroy(SAFEARRAY *psa)
Definition: safearray.c:1347
SAFEARRAY *WINAPI SafeArrayCreateVector(VARTYPE vt, LONG lLbound, ULONG cElements)
Definition: safearray.c:677
unsigned char UCHAR
Definition: xmlstorage.h:181
int ret
HRESULT WINAPI PropVariantToUInt64(REFPROPVARIANT propvarIn, ULONGLONG *ret)
Definition: propvar.c:234
REFCLSID clsid
Definition: msctf.c:82
Definition: compat.h:1948
#define V_VT(A)
Definition: oleauto.h:211
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
HRESULT WINAPI PropVariantToUInt32(REFPROPVARIANT propvarIn, ULONG *ret)
Definition: propvar.c:222
UINT WINAPI SysStringLen(BSTR str)
Definition: oleaut.c:196
HRESULT WINAPI InitPropVariantFromCLSID(REFCLSID clsid, PROPVARIANT *ppropvar)
Definition: propvar.c:640
static DWORD PROPVAR_HexToNum(const WCHAR *hex)
Definition: propvar.c:684
#define V_BSTR(A)
Definition: oleauto.h:226
HRESULT WINAPI PropVariantToDouble(REFPROPVARIANT propvarIn, double *ret)
Definition: propvar.c:162
#define S_OK
Definition: intsafe.h:59
HRESULT WINAPI InitVariantFromGUIDAsString(REFGUID guid, VARIANT *pvar)
Definition: propvar.c:608
unsigned short USHORT
Definition: pedump.c:61
static IPropertySystem propsys
Definition: propsys_main.c:239
#define E_NOTIMPL
Definition: ddrawi.h:99
unsigned short VARTYPE
Definition: compat.h:1903
HRESULT WINAPI InitVariantFromBuffer(const VOID *pv, UINT cb, VARIANT *pvar)
Definition: propvar.c:653
unsigned int UINT
Definition: ndis.h:50
HRESULT WINAPI PropVariantToInt16(REFPROPVARIANT propvarIn, SHORT *ret)
Definition: propvar.c:174
HRESULT WINAPI PropVariantToString(REFPROPVARIANT propvarIn, PWSTR ret, UINT cch)
Definition: propvar.c:332
#define MultiByteToWideChar
Definition: compat.h:100
HRESULT WINAPI PropVariantToBoolean(REFPROPVARIANT propvarIn, BOOL *ret)
Definition: propvar.c:246
static BOOL isemptyornull(const PROPVARIANT *propvar)
Definition: propvar.c:793
static HMODULE MODULEINFO DWORD cb
Definition: module.c:32
HRESULT WINAPI PropVariantToInt64(REFPROPVARIANT propvarIn, LONGLONG *ret)
Definition: propvar.c:198
GLuint res
Definition: glext.h:9613
unsigned int ULONG
Definition: retypes.h:1
GLfloat GLfloat p
Definition: glext.h:8902
static const WCHAR trueW[]
Definition: json.c:33
#define memset(x, y, z)
Definition: compat.h:39
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:404
Definition: compat.h:1949
HRESULT WINAPI SafeArrayUnaccessData(SAFEARRAY *psa)
Definition: safearray.c:1168
Definition: compat.h:1946
#define SUCCEEDED(hr)
Definition: intsafe.h:57