ReactOS 0.4.16-dev-338-g34e76ad
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
41static 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
68static 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
162HRESULT WINAPI PropVariantToDouble(REFPROPVARIANT propvarIn, double *ret)
163{
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
174HRESULT WINAPI PropVariantToInt16(REFPROPVARIANT propvarIn, SHORT *ret)
175{
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
186HRESULT WINAPI PropVariantToInt32(REFPROPVARIANT propvarIn, LONG *ret)
187{
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
198HRESULT WINAPI PropVariantToInt64(REFPROPVARIANT propvarIn, LONGLONG *ret)
199{
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
210HRESULT WINAPI PropVariantToUInt16(REFPROPVARIANT propvarIn, USHORT *ret)
211{
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
222HRESULT WINAPI PropVariantToUInt32(REFPROPVARIANT propvarIn, ULONG *ret)
223{
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
234HRESULT WINAPI PropVariantToUInt64(REFPROPVARIANT propvarIn, ULONGLONG *ret)
235{
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
246HRESULT 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};
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
306HRESULT 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);
326 }
327
328 return hr;
329}
330
331
332HRESULT 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
356HRESULT 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
407PCWSTR 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 */
428HRESULT 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 {
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 {
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 {
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 {
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
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
626HRESULT 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;
658
659 TRACE("(%p %u %p)\n", pv, cb, pvar);
660
662 if(!arr)
663 return E_OUTOFMEMORY;
664
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
684static 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
708static 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
756HRESULT 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
793static 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
814INT 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}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define GetProcessHeap()
Definition: compat.h:736
#define CP_ACP
Definition: compat.h:109
#define HeapAlloc
Definition: compat.h:733
unsigned short VARTYPE
Definition: compat.h:2254
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
@ VT_UI8
Definition: compat.h:2315
@ VT_BSTR
Definition: compat.h:2303
@ VT_LPSTR
Definition: compat.h:2324
@ VT_R4
Definition: compat.h:2299
@ VT_NULL
Definition: compat.h:2296
@ VT_UI2
Definition: compat.h:2312
@ VT_CLSID
Definition: compat.h:2337
@ VT_ARRAY
Definition: compat.h:2341
@ VT_LPWSTR
Definition: compat.h:2325
@ VT_R8
Definition: compat.h:2300
@ VT_I8
Definition: compat.h:2314
@ VT_I1
Definition: compat.h:2310
@ VT_I4
Definition: compat.h:2298
@ VT_FILETIME
Definition: compat.h:2329
@ VT_BOOL
Definition: compat.h:2306
@ VT_I2
Definition: compat.h:2297
@ VT_UI4
Definition: compat.h:2313
@ VT_EMPTY
Definition: compat.h:2295
@ VT_VECTOR
Definition: compat.h:2340
@ VT_UI1
Definition: compat.h:2311
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
BOOL WINAPI FileTimeToSystemTime(IN CONST FILETIME *lpFileTime, OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:188
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4243
int WINAPI lstrcmpA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4195
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4262
int WINAPI lstrcmpiA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4224
static REFPROPVARIANT propvarSrc
Definition: suminfo.c:90
static REFPROPVARIANT PROPVAR_CHANGE_FLAGS VARTYPE vt
Definition: suminfo.c:91
HRESULT WINAPI PropVariantClear(PROPVARIANT *pvar)
Definition: ole2.c:2968
HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, const PROPVARIANT *pvarSrc)
Definition: ole2.c:3086
HRESULT WINAPI SafeArrayAccessData(SAFEARRAY *psa, void **ppvData)
Definition: safearray.c:1137
HRESULT WINAPI SafeArrayUnaccessData(SAFEARRAY *psa)
Definition: safearray.c:1168
SAFEARRAY *WINAPI SafeArrayCreateVector(VARTYPE vt, LONG lLbound, ULONG cElements)
Definition: safearray.c:677
HRESULT WINAPI SafeArrayDestroy(SAFEARRAY *psa)
Definition: safearray.c:1347
HRESULT WINAPI PropVariantToInt32(REFPROPVARIANT propvarIn, LONG *ret)
Definition: propvar.c:186
HRESULT WINAPI InitVariantFromGUIDAsString(REFGUID guid, VARIANT *pvar)
Definition: propvar.c:608
PCWSTR WINAPI PropVariantToStringWithDefault(REFPROPVARIANT propvarIn, LPCWSTR pszDefault)
Definition: propvar.c:407
static HRESULT PROPVAR_ConvertFILETIME(const FILETIME *ft, PROPVARIANT *ppropvarDest, VARTYPE vt)
Definition: propvar.c:41
INT WINAPI PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2, PROPVAR_COMPARE_UNIT unit, PROPVAR_COMPARE_FLAGS flags)
Definition: propvar.c:814
HRESULT WINAPI VariantToGUID(const VARIANT *pvar, GUID *guid)
Definition: propvar.c:775
HRESULT WINAPI PropVariantToBuffer(REFPROPVARIANT propvarIn, void *ret, UINT cb)
Definition: propvar.c:306
HRESULT WINAPI PropVariantToUInt16(REFPROPVARIANT propvarIn, USHORT *ret)
Definition: propvar.c:210
static HRESULT PROPVAR_WCHARToGUID(const WCHAR *str, int len, GUID *guid)
Definition: propvar.c:708
#define CMP_NUM_VALUE(var)
static BOOL isemptyornull(const PROPVARIANT *propvar)
Definition: propvar.c:793
HRESULT WINAPI InitPropVariantFromCLSID(REFCLSID clsid, PROPVARIANT *ppropvar)
Definition: propvar.c:640
HRESULT WINAPI PropVariantToStringAlloc(REFPROPVARIANT propvarIn, WCHAR **ret)
Definition: propvar.c:356
HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT propvarSrc, PROPVAR_CHANGE_FLAGS flags, VARTYPE vt)
Definition: propvar.c:428
static void PROPVAR_GUIDToWSTR(REFGUID guid, WCHAR *str)
Definition: propvar.c:581
HRESULT WINAPI InitPropVariantFromBuffer(const VOID *pv, UINT cb, PROPVARIANT *ppropvar)
Definition: propvar.c:626
static HRESULT PROPVAR_ConvertNumber(REFPROPVARIANT pv, int dest_bits, BOOL dest_signed, LONGLONG *res)
Definition: propvar.c:68
HRESULT WINAPI PropVariantToBoolean(REFPROPVARIANT propvarIn, BOOL *ret)
Definition: propvar.c:246
HRESULT WINAPI PropVariantToInt64(REFPROPVARIANT propvarIn, LONGLONG *ret)
Definition: propvar.c:198
static DWORD PROPVAR_HexToNum(const WCHAR *hex)
Definition: propvar.c:684
HRESULT WINAPI PropVariantToDouble(REFPROPVARIANT propvarIn, double *ret)
Definition: propvar.c:162
HRESULT WINAPI PropVariantToString(REFPROPVARIANT propvarIn, PWSTR ret, UINT cch)
Definition: propvar.c:332
HRESULT WINAPI PropVariantToUInt64(REFPROPVARIANT propvarIn, ULONGLONG *ret)
Definition: propvar.c:234
HRESULT WINAPI PropVariantToUInt32(REFPROPVARIANT propvarIn, ULONG *ret)
Definition: propvar.c:222
HRESULT WINAPI PropVariantToGUID(const PROPVARIANT *ppropvar, GUID *guid)
Definition: propvar.c:756
HRESULT WINAPI PropVariantToInt16(REFPROPVARIANT propvarIn, SHORT *ret)
Definition: propvar.c:174
HRESULT WINAPI InitVariantFromBuffer(const VOID *pv, UINT cb, VARIANT *pvar)
Definition: propvar.c:653
HRESULT WINAPI InitPropVariantFromGUIDAsString(REFGUID guid, PROPVARIANT *ppropvar)
Definition: propvar.c:592
unsigned char
Definition: typeof.h:29
#define swprintf
Definition: precomp.h:40
static const WCHAR stringW[]
Definition: engine.c:38
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint end
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
GLuint res
Definition: glext.h:9613
GLbitfield flags
Definition: glext.h:7161
GLuint GLfloat * val
Definition: glext.h:7180
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
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
int hex(char ch)
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
static const WCHAR falseW[]
Definition: json.c:34
static const WCHAR trueW[]
Definition: json.c:33
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_w
Definition: kernel32.h:32
const GUID * guid
__u16 time
Definition: mkdosfs.c:8
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:202
HRESULT hres
Definition: protocol.c:465
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:80
REFCLSID clsid
Definition: msctf.c:82
unsigned int UINT
Definition: ndis.h:50
UINT WINAPI SysStringLen(BSTR str)
Definition: oleaut.c:196
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:339
#define V_ARRAY(A)
Definition: oleauto.h:222
#define V_VT(A)
Definition: oleauto.h:211
#define V_BSTR(A)
Definition: oleauto.h:226
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
png_const_structrp png_const_inforp int * unit
Definition: png.h:2159
static IPropertySystem propsys
Definition: propsys_main.c:239
@ PVCF_USESTRCMPI
Definition: propvarutil.h:60
@ PVCF_USESTRCMPIC
Definition: propvarutil.h:61
@ PVCF_TREATEMPTYASGREATERTHAN
Definition: propvarutil.h:57
int PROPVAR_COMPARE_UNIT
Definition: propvarutil.h:52
int PROPVAR_CHANGE_FLAGS
Definition: propvarutil.h:39
int PROPVAR_COMPARE_FLAGS
Definition: propvarutil.h:64
#define REFCLSID
Definition: guiddef.h:117
const WCHAR * str
#define memset(x, y, z)
Definition: compat.h:39
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
#define STRSAFE_E_INSUFFICIENT_BUFFER
Definition: strsafe.h:103
__int64 _strtoi64(const char *nptr, char **endptr, int base)
Definition: strtoi64.c:90
Definition: scsiwmi.h:51
Definition: format.c:58
uint16_t * PWSTR
Definition: typedefs.h:56
const uint16_t * PCWSTR
Definition: typedefs.h:57
int64_t LONGLONG
Definition: typedefs.h:68
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
int ret
#define WINAPI
Definition: msvc.h:6
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define ERROR_ARITHMETIC_OVERFLOW
Definition: winerror.h:351
#define DISP_E_TYPEMISMATCH
Definition: winerror.h:2514
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185