1 /*
2  * Unit tests for Windows property system
3  *
4  * Copyright 2006 Paul Vriens
5  * Copyright 2010 Andrew Nguyen
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 
22 #define COBJMACROS
23 
24 #include <stdarg.h>
25 #include <stdio.h>
26 
27 #define NONAMELESSUNION
28 
29 #include "windef.h"
30 #include "winbase.h"
31 #include "objbase.h"
32 #include "initguid.h"
33 #include "propsys.h"
34 #include "propvarutil.h"
35 #include "strsafe.h"
36 #include "wine/test.h"
37 
38 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
39 DEFINE_GUID(dummy_guid, 0xdeadbeef, 0xdead, 0xbeef, 0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0xba, 0xbe);
40 DEFINE_GUID(expect_guid, 0x12345678, 0x1234, 0x1234, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12);
41 
42 #define GUID_MEMBERS(g) {(g).Data1, (g).Data2, (g).Data3, {(g).Data4[0], (g).Data4[1], (g).Data4[2], (g).Data4[3], (g).Data4[4], (g).Data4[5], (g).Data4[6], (g).Data4[7]}}
43 
44 static const char topic[] = "wine topic";
45 static const WCHAR topicW[] = {'w','i','n','e',' ','t','o','p','i','c',0};
46 static const WCHAR emptyW[] = {0};
47 
48 static int strcmp_wa(LPCWSTR strw, const char *stra)
49 {
50     CHAR buf[512];
51     WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL);
52     return lstrcmpA(stra, buf);
53 }
54 
55 static void test_PSStringFromPropertyKey(void)
56 {
57     static const WCHAR fillerW[] = {'X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X',
58                                     'X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X',
59                                     'X','X','X','X','X','X','X','X','X','X'};
60     static const WCHAR zero_fillerW[] = {'\0','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X',
61                                          'X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X',
62                                          'X','X','X','X','X','X','X','X','X','X','X','X','X','X'};
63     static const WCHAR zero_truncatedW[] = {'\0','0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0',
64                                             '0','0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0',
65                                             '0','0','0','}',' ','\0','9','X','X','X','X','X','X','X','X','X'};
66     static const WCHAR zero_truncated2W[] = {'\0','0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0',
67                                              '0','0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0',
68                                              '0','0','0','}',' ','\0','9','2','7','6','9','4','9','2','X','X'};
69     static const WCHAR zero_truncated3W[] = {'\0','0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0',
70                                             '0','0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0',
71                                             '0','0','0','}',' ','\0','9','2','7','6','9','4','9','2','4','X'};
72     static const WCHAR zero_truncated4W[] = {'\0','0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0',
73                                              '0','0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0',
74                                              '0','0','0','}',' ','\0','7','X','X','X','X','X','X','X','X','X'};
75     static const WCHAR truncatedW[] = {'{','0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0','0',
76                                         '0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0',
77                                         '0','}',' ','\0','9','X','X','X','X','X','X','X','X','X'};
78     static const WCHAR truncated2W[] = {'{','0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0','0',
79                                         '0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0',
80                                         '0','}',' ','\0','9','2','7','6','9','4','9','2','X','X'};
81     static const WCHAR truncated3W[] = {'{','0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0','0',
82                                        '0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0',
83                                        '0','}',' ','\0','9','2','7','6','9','4','9','2','4','X'};
84     static const WCHAR truncated4W[] = {'{','0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0','0',
85                                         '0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0',
86                                         '0','}',' ','\0','7','X','X','X','X','X','X','X','X','X'};
87     static const WCHAR expectedW[] = {'{','0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0','0',
88                                       '0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0',
89                                       '0','}',' ','4','2','9','4','9','6','7','2','9','5',0};
90     static const WCHAR expected2W[] = {'{','0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0','0',
91                                        '0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0',
92                                        '0','}',' ','1','3','5','7','9','\0','X','X','X','X','X'};
93     static const WCHAR expected3W[] = {'{','0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0','0',
94                                        '0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0',
95                                        '0','}',' ','0','\0','X','X','X','X','X','X','X','X','X'};
96     PROPERTYKEY prop = {GUID_MEMBERS(GUID_NULL), ~0U};
97     PROPERTYKEY prop2 = {GUID_MEMBERS(GUID_NULL), 13579};
98     PROPERTYKEY prop3 = {GUID_MEMBERS(GUID_NULL), 0};
99     WCHAR out[PKEYSTR_MAX];
100     HRESULT ret;
101 
102     const struct
103     {
104         REFPROPERTYKEY pkey;
105         LPWSTR psz;
106         UINT cch;
107         HRESULT hr_expect;
108         const WCHAR *buf_expect;
109         BOOL hr_broken;
110         HRESULT hr2;
111         BOOL buf_broken;
112         const WCHAR *buf2;
113     } testcases[] =
114     {
115         {NULL, NULL, 0, E_POINTER},
116         {&prop, NULL, 0, E_POINTER},
117         {&prop, NULL, PKEYSTR_MAX, E_POINTER},
118         {NULL, out, 0, E_NOT_SUFFICIENT_BUFFER, fillerW},
119         {NULL, out, PKEYSTR_MAX, E_NOT_SUFFICIENT_BUFFER, zero_fillerW, FALSE, 0, TRUE, fillerW},
120         {&prop, out, 0, E_NOT_SUFFICIENT_BUFFER, fillerW},
121         {&prop, out, GUIDSTRING_MAX, E_NOT_SUFFICIENT_BUFFER, fillerW},
122         {&prop, out, GUIDSTRING_MAX + 1, E_NOT_SUFFICIENT_BUFFER, fillerW},
123         {&prop, out, GUIDSTRING_MAX + 2, E_NOT_SUFFICIENT_BUFFER, zero_truncatedW, TRUE, S_OK, TRUE, truncatedW},
124         {&prop, out, PKEYSTR_MAX - 2, E_NOT_SUFFICIENT_BUFFER, zero_truncated2W, TRUE, S_OK, TRUE, truncated2W},
125         {&prop, out, PKEYSTR_MAX - 1, E_NOT_SUFFICIENT_BUFFER, zero_truncated3W, TRUE, S_OK, TRUE, truncated3W},
126         {&prop, out, PKEYSTR_MAX, S_OK, expectedW},
127         {&prop2, out, GUIDSTRING_MAX + 2, E_NOT_SUFFICIENT_BUFFER, zero_truncated4W, TRUE, S_OK, TRUE, truncated4W},
128         {&prop2, out, GUIDSTRING_MAX + 6, S_OK, expected2W},
129         {&prop2, out, PKEYSTR_MAX, S_OK, expected2W},
130         {&prop3, out, GUIDSTRING_MAX + 1, E_NOT_SUFFICIENT_BUFFER, fillerW},
131         {&prop3, out, GUIDSTRING_MAX + 2, S_OK, expected3W},
132         {&prop3, out, PKEYSTR_MAX, S_OK, expected3W},
133     };
134 
135     int i;
136 
137     for (i = 0; i < ARRAY_SIZE(testcases); i++)
138     {
139         if (testcases[i].psz)
140             memcpy(testcases[i].psz, fillerW, PKEYSTR_MAX * sizeof(WCHAR));
141 
142         ret = PSStringFromPropertyKey(testcases[i].pkey,
143                                       testcases[i].psz,
144                                       testcases[i].cch);
145         ok(ret == testcases[i].hr_expect ||
146            broken(testcases[i].hr_broken && ret == testcases[i].hr2), /* Vista/Win2k8 */
147            "[%d] Expected PSStringFromPropertyKey to return 0x%08x, got 0x%08x\n",
148            i, testcases[i].hr_expect, ret);
149 
150         if (testcases[i].psz)
151             ok(!memcmp(testcases[i].psz, testcases[i].buf_expect, PKEYSTR_MAX * sizeof(WCHAR)) ||
152                 broken(testcases[i].buf_broken &&
153                        !memcmp(testcases[i].psz, testcases[i].buf2, PKEYSTR_MAX * sizeof(WCHAR))), /* Vista/Win2k8 */
154                "[%d] Unexpected output contents\n", i);
155     }
156 }
157 
158 static void test_PSPropertyKeyFromString(void)
159 {
160     static const WCHAR fmtid_clsidW[] = {'S','t','d','F','o','n','t',' ','1',0};
161     static const WCHAR fmtid_truncatedW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
162                                              '1','2','3','4','-',0};
163     static const WCHAR fmtid_nobracketsW[] = {'1','2','3','4','5','6','7','8','-','1','2','3','4','-',
164                                               '1','2','3','4','-','1','2','3','4','-',
165                                               '1','2','3','4','5','6','7','8','9','0','1','2',0};
166     static const WCHAR fmtid_badbracketW[] = {'X','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
167                                               '1','2','3','4','-','1','2','3','4','-',
168                                               '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
169     static const WCHAR fmtid_badcharW[] = {'{','X','2','3','4','5','6','7','8','-','1','2','3','4','-',
170                                            '1','2','3','4','-','1','2','3','4','-',
171                                            '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
172     static const WCHAR fmtid_badchar2W[] = {'{','1','2','3','4','5','6','7','X','-','1','2','3','4','-',
173                                             '1','2','3','4','-','1','2','3','4','-',
174                                             '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
175     static const WCHAR fmtid_baddashW[] = {'{','1','2','3','4','5','6','7','8','X','1','2','3','4','-',
176                                            '1','2','3','4','-','1','2','3','4','-',
177                                            '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
178     static const WCHAR fmtid_badchar3W[] = {'{','1','2','3','4','5','6','7','8','-','X','2','3','4','-',
179                                             '1','2','3','4','-','1','2','3','4','-',
180                                             '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
181     static const WCHAR fmtid_badchar4W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','X','-',
182                                             '1','2','3','4','-','1','2','3','4','-',
183                                             '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
184     static const WCHAR fmtid_baddash2W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','X',
185                                             '1','2','3','4','-','1','2','3','4','-',
186                                             '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
187     static const WCHAR fmtid_badchar5W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
188                                             'X','2','3','4','-','1','2','3','4','-',
189                                             '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
190     static const WCHAR fmtid_badchar6W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
191                                             '1','2','3','X','-','1','2','3','4','-',
192                                             '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
193     static const WCHAR fmtid_baddash3W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
194                                             '1','2','3','4','X','1','2','3','4','-',
195                                             '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
196     static const WCHAR fmtid_badchar7W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
197                                             '1','2','3','4','-','X','2','3','4','-',
198                                             '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
199     static const WCHAR fmtid_badchar8W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
200                                             '1','2','3','4','-','1','2','3','X','-',
201                                             '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
202     static const WCHAR fmtid_baddash4W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
203                                             '1','2','3','4','-','1','2','3','4','X',
204                                             '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
205     static const WCHAR fmtid_badchar9W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
206                                             '1','2','3','4','-','1','2','3','4','-',
207                                             'X','2','3','4','5','6','7','8','9','0','1','2','}',0};
208     static const WCHAR fmtid_badchar9_adjW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
209                                                 '1','2','3','4','-','1','2','3','4','-',
210                                                 '1','X','3','4','5','6','7','8','9','0','1','2','}',0};
211     static const WCHAR fmtid_badchar10W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
212                                              '1','2','3','4','-','1','2','3','4','-',
213                                              '1','2','X','4','5','6','7','8','9','0','1','2','}',0};
214     static const WCHAR fmtid_badchar11W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
215                                              '1','2','3','4','-','1','2','3','4','-',
216                                              '1','2','3','4','X','6','7','8','9','0','1','2','}',0};
217     static const WCHAR fmtid_badchar12W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
218                                              '1','2','3','4','-','1','2','3','4','-',
219                                              '1','2','3','4','5','6','X','8','9','0','1','2','}',0};
220     static const WCHAR fmtid_badchar13W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
221                                              '1','2','3','4','-','1','2','3','4','-',
222                                              '1','2','3','4','5','6','7','8','X','0','1','2','}',0};
223     static const WCHAR fmtid_badchar14W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
224                                              '1','2','3','4','-','1','2','3','4','-',
225                                              '1','2','3','4','5','6','7','8','9','0','X','2','}',0};
226     static const WCHAR fmtid_badbracket2W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
227                                                '1','2','3','4','-','1','2','3','4','-',
228                                                '1','2','3','4','5','6','7','8','9','0','1','2','X',0};
229     static const WCHAR fmtid_spaceW[] = {' ','{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
230                                          '1','2','3','4','-','1','2','3','4','-',
231                                          '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
232     static const WCHAR fmtid_spaceendW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
233                                             '1','2','3','4','-','1','2','3','4','-',
234                                             '1','2','3','4','5','6','7','8','9','0','1','2','}',' ',0};
235     static const WCHAR fmtid_spacesendW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
236                                              '1','2','3','4','-','1','2','3','4','-',
237                                              '1','2','3','4','5','6','7','8','9','0','1','2','}',' ',' ',' ',0};
238     static const WCHAR fmtid_nopidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
239                                          '1','2','3','4','-','1','2','3','4','-',
240                                          '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
241     static const WCHAR fmtid_badpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
242                                           '1','2','3','4','-','1','2','3','4','-',
243                                           '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','D','E','A','D',0};
244     static const WCHAR fmtid_adjpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
245                                           '1','2','3','4','-','1','2','3','4','-',
246                                           '1','2','3','4','5','6','7','8','9','0','1','2','}','1','3','5','7','9',0};
247     static const WCHAR fmtid_spacespidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
248                                              '1','2','3','4','-','1','2','3','4','-',
249                                              '1','2','3','4','5','6','7','8','9','0','1','2','}',' ',' ',' ','1','3','5','7','9',0};
250     static const WCHAR fmtid_negpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
251                                           '1','2','3','4','-','1','2','3','4','-',
252                                           '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','-','1','3','5','7','9',0};
253     static const WCHAR fmtid_negnegpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
254                                              '1','2','3','4','-','1','2','3','4','-',
255                                              '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','-','-','1','3','5','7','9',0};
256     static const WCHAR fmtid_negnegnegpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
257                                                 '1','2','3','4','-','1','2','3','4','-',
258                                                 '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','-','-','-','1','3','5','7','9',0};
259     static const WCHAR fmtid_negspacepidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
260                                                '1','2','3','4','-','1','2','3','4','-',
261                                                '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','-',' ','1','3','5','7','9',0};
262     static const WCHAR fmtid_negspacenegpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
263                                                '1','2','3','4','-','1','2','3','4','-',
264                                                '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','-',' ','-','1','3','5','7','9',0};
265     static const WCHAR fmtid_negspacespidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
266                                                '1','2','3','4','-','1','2','3','4','-',
267                                                '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','-',' ','-',' ','-','1','3','5','7','9',0};
268     static const WCHAR fmtid_pospidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
269                                           '1','2','3','4','-','1','2','3','4','-',
270                                           '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','+','1','3','5','7','9',0};
271     static const WCHAR fmtid_posnegpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
272                                              '1','2','3','4','-','1','2','3','4','-',
273                                              '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','+','-','+','-','1','3','5','7','9',0};
274     static const WCHAR fmtid_symbolpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
275                                              '1','2','3','4','-','1','2','3','4','-',
276                                              '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','+','/','$','-','1','3','5','7','9',0};
277     static const WCHAR fmtid_letterpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
278                                              '1','2','3','4','-','1','2','3','4','-',
279                                              '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','A','B','C','D','1','3','5','7','9',0};
280     static const WCHAR fmtid_spacepadpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
281                                                '1','2','3','4','-','1','2','3','4','-',
282                                                '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','1','3','5','7','9',' ',' ',' ',0};
283     static const WCHAR fmtid_spacemixpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
284                                                '1','2','3','4','-','1','2','3','4','-',
285                                                '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','1',' ','3',' ','5','7','9',' ',' ',' ',0};
286     static const WCHAR fmtid_tabpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
287                                           '1','2','3','4','-','1','2','3','4','-',
288                                           '1','2','3','4','5','6','7','8','9','0','1','2','}','\t','1','3','5','7','9',0};
289     static const WCHAR fmtid_hexpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
290                                           '1','2','3','4','-','1','2','3','4','-',
291                                           '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','0','x','D','E','A','D',0};
292     static const WCHAR fmtid_mixedpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
293                                             '1','2','3','4','-','1','2','3','4','-',
294                                             '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','A','9','B','5','C','3','D','1',0};
295     static const WCHAR fmtid_overflowpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
296                                                '1','2','3','4','-','1','2','3','4','-',
297                                                '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','1','2','3','4','5','6','7','8','9','0','1',0};
298     static const WCHAR fmtid_commapidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
299                                              '1','2','3','4','-','1','2','3','4','-',
300                                              '1','2','3','4','5','6','7','8','9','0','1','2','}',',','1','3','5','7','9',0};
301     static const WCHAR fmtid_commaspidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
302                                              '1','2','3','4','-','1','2','3','4','-',
303                                              '1','2','3','4','5','6','7','8','9','0','1','2','}',',',',',',','1','3','5','7','9',0};
304     static const WCHAR fmtid_commaspacepidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
305                                                  '1','2','3','4','-','1','2','3','4','-',
306                                                  '1','2','3','4','5','6','7','8','9','0','1','2','}',',',' ','1','3','5','7','9',0};
307     static const WCHAR fmtid_spacecommapidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
308                                                  '1','2','3','4','-','1','2','3','4','-',
309                                                  '1','2','3','4','5','6','7','8','9','0','1','2','}',' ',',','1','3','5','7','9',0};
310     static const WCHAR fmtid_spccommaspcpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
311                                                   '1','2','3','4','-','1','2','3','4','-',
312                                                   '1','2','3','4','5','6','7','8','9','0','1','2','}',' ',',',' ','1','3','5','7','9',0};
313     static const WCHAR fmtid_spacescommaspidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
314                                                    '1','2','3','4','-','1','2','3','4','-',
315                                                    '1','2','3','4','5','6','7','8','9','0','1','2','}',' ',',',' ',',','1','3','5','7','9',0};
316     static const WCHAR fmtid_commanegpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
317                                                '1','2','3','4','-','1','2','3','4','-',
318                                                '1','2','3','4','5','6','7','8','9','0','1','2','}',',','-','1','3','5','7','9',0};
319     static const WCHAR fmtid_spccommanegpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
320                                                '1','2','3','4','-','1','2','3','4','-',
321                                                '1','2','3','4','5','6','7','8','9','0','1','2','}',' ',',','-','1','3','5','7','9',0};
322     static const WCHAR fmtid_commaspcnegpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
323                                                '1','2','3','4','-','1','2','3','4','-',
324                                                '1','2','3','4','5','6','7','8','9','0','1','2','}',',',' ','-','1','3','5','7','9',0};
325     static const WCHAR fmtid_spccommaspcnegpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
326                                                '1','2','3','4','-','1','2','3','4','-',
327                                                '1','2','3','4','5','6','7','8','9','0','1','2','}',' ',',',' ','-','1','3','5','7','9',0};
328     static const WCHAR fmtid_commanegspcpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
329                                                '1','2','3','4','-','1','2','3','4','-',
330                                                '1','2','3','4','5','6','7','8','9','0','1','2','}',',','-',' ','1','3','5','7','9',0};
331     static const WCHAR fmtid_negcommapidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
332                                                '1','2','3','4','-','1','2','3','4','-',
333                                                '1','2','3','4','5','6','7','8','9','0','1','2','}','-',',','1','3','5','7','9',0};
334     static const WCHAR fmtid_normalpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
335                                              '1','2','3','4','-','1','2','3','4','-',
336                                              '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','1','3','5','7','9',0};
337     PROPERTYKEY out_init = {GUID_MEMBERS(dummy_guid), 0xdeadbeef};
338     PROPERTYKEY out;
339     HRESULT ret;
340 
341     const struct
342     {
343         LPCWSTR pwzString;
344         PROPERTYKEY *pkey;
345         HRESULT hr_expect;
346         PROPERTYKEY pkey_expect;
347     } testcases[] =
348     {
349         {NULL, NULL, E_POINTER},
350         {NULL, &out, E_POINTER, {GUID_MEMBERS(out_init.fmtid), out_init.pid}},
351         {emptyW, NULL, E_POINTER},
352         {emptyW, &out, E_INVALIDARG, {GUID_MEMBERS(GUID_NULL), 0}},
353         {fmtid_clsidW, &out, E_INVALIDARG, {GUID_MEMBERS(GUID_NULL), 0}},
354         {fmtid_truncatedW, &out, E_INVALIDARG, { {0x12345678,0x1234,0x1234,{0,0,0,0,0,0,0,0}}, 0}},
355         {fmtid_nobracketsW, &out, E_INVALIDARG, {GUID_MEMBERS(GUID_NULL), 0}},
356         {fmtid_badbracketW, &out, E_INVALIDARG, {GUID_MEMBERS(GUID_NULL), 0}},
357         {fmtid_badcharW, &out, E_INVALIDARG, {GUID_MEMBERS(GUID_NULL), 0}},
358         {fmtid_badchar2W, &out, E_INVALIDARG, {GUID_MEMBERS(GUID_NULL), 0}},
359         {fmtid_baddashW, &out, E_INVALIDARG, { {0x12345678,0,0,{0,0,0,0,0,0,0,0}}, 0}},
360         {fmtid_badchar3W, &out, E_INVALIDARG, { {0x12345678,0,0,{0,0,0,0,0,0,0,0}}, 0}},
361         {fmtid_badchar4W, &out, E_INVALIDARG, { {0x12345678,0,0,{0,0,0,0,0,0,0,0}}, 0}},
362         {fmtid_baddash2W, &out, E_INVALIDARG, { {0x12345678,0,0,{0,0,0,0,0,0,0,0}}, 0}},
363         {fmtid_badchar5W, &out, E_INVALIDARG, { {0x12345678,0x1234,0,{0,0,0,0,0,0,0,0}}, 0}},
364         {fmtid_badchar6W, &out, E_INVALIDARG, { {0x12345678,0x1234,0,{0,0,0,0,0,0,0,0}}, 0}},
365         {fmtid_baddash3W, &out, E_INVALIDARG, { {0x12345678,0x1234,0,{0,0,0,0,0,0,0,0}}, 0}},
366         {fmtid_badchar7W, &out, E_INVALIDARG, { {0x12345678,0x1234,0x1234,{0,0,0,0,0,0,0,0}}, 0}},
367         {fmtid_badchar8W, &out, E_INVALIDARG, { {0x12345678,0x1234,0x1234,{0x12,0,0,0,0,0,0,0}}, 0}},
368         {fmtid_baddash4W, &out, E_INVALIDARG, { {0x12345678,0x1234,0x1234,{0x12,0,0,0,0,0,0,0}}, 0}},
369         {fmtid_badchar9W, &out, E_INVALIDARG, { {0x12345678,0x1234,0x1234,{0x12,0x34,0,0,0,0,0,0}}, 0}},
370         {fmtid_badchar9_adjW, &out, E_INVALIDARG, { {0x12345678,0x1234,0x1234,{0x12,0x34,0,0,0,0,0,0}}, 0}},
371         {fmtid_badchar10W, &out, E_INVALIDARG, { {0x12345678,0x1234,0x1234,{0x12,0x34,0x12,0,0,0,0,0}}, 0}},
372         {fmtid_badchar11W, &out, E_INVALIDARG, { {0x12345678,0x1234,0x1234,{0x12,0x34,0x12,0x34,0,0,0,0}}, 0}},
373         {fmtid_badchar12W, &out, E_INVALIDARG, { {0x12345678,0x1234,0x1234,{0x12,0x34,0x12,0x34,0x56,0,0,0}}, 0}},
374         {fmtid_badchar13W, &out, E_INVALIDARG, { {0x12345678,0x1234,0x1234,{0x12,0x34,0x12,0x34,0x56,0x78,0,0}}, 0}},
375         {fmtid_badchar14W, &out, E_INVALIDARG, { {0x12345678,0x1234,0x1234,{0x12,0x34,0x12,0x34,0x56,0x78,0x90,0}}, 0}},
376         {fmtid_badbracket2W, &out, E_INVALIDARG, { {0x12345678,0x1234,0x1234,{0x12,0x34,0x12,0x34,0x56,0x78,0x90,0x00}}, 0 }},
377         {fmtid_spaceW, &out, E_INVALIDARG, {GUID_MEMBERS(GUID_NULL), 0 }},
378         {fmtid_spaceendW, &out, E_INVALIDARG, {GUID_MEMBERS(expect_guid), 0}},
379         {fmtid_spacesendW, &out, E_INVALIDARG, {GUID_MEMBERS(expect_guid), 0}},
380         {fmtid_nopidW, &out, E_INVALIDARG, {GUID_MEMBERS(expect_guid), 0}},
381         {fmtid_badpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}},
382         {fmtid_adjpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 13579}},
383         {fmtid_spacespidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 13579}},
384         {fmtid_negpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 13579}},
385         {fmtid_negnegpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 4294953717U}},
386         {fmtid_negnegnegpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}},
387         {fmtid_negspacepidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 13579}},
388         {fmtid_negspacenegpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 4294953717U}},
389         {fmtid_negspacespidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}},
390         {fmtid_pospidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}},
391         {fmtid_posnegpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}},
392         {fmtid_symbolpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}},
393         {fmtid_letterpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}},
394         {fmtid_spacepadpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 13579}},
395         {fmtid_spacemixpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 1}},
396         {fmtid_tabpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}},
397         {fmtid_hexpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}},
398         {fmtid_mixedpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}},
399         {fmtid_overflowpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 3755744309U}},
400         {fmtid_commapidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 13579}},
401         {fmtid_commaspidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}},
402         {fmtid_commaspacepidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 13579}},
403         {fmtid_spacecommapidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 13579}},
404         {fmtid_spccommaspcpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 13579}},
405         {fmtid_spacescommaspidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}},
406         {fmtid_commanegpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 4294953717U}},
407         {fmtid_spccommanegpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 4294953717U}},
408         {fmtid_commaspcnegpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 4294953717U}},
409         {fmtid_spccommaspcnegpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 4294953717U}},
410         {fmtid_commanegspcpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0U}},
411         {fmtid_negcommapidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}},
412         {fmtid_normalpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 13579}},
413     };
414 
415     int i;
416 
417     for (i = 0; i < ARRAY_SIZE(testcases); i++)
418     {
419         if (testcases[i].pkey)
420             *testcases[i].pkey = out_init;
421 
422         ret = PSPropertyKeyFromString(testcases[i].pwzString, testcases[i].pkey);
423         ok(ret == testcases[i].hr_expect,
424            "[%d] Expected PSPropertyKeyFromString to return 0x%08x, got 0x%08x\n",
425            i, testcases[i].hr_expect, ret);
426 
427         if (testcases[i].pkey)
428         {
429             ok(IsEqualGUID(&testcases[i].pkey->fmtid, &testcases[i].pkey_expect.fmtid),
430                "[%d] Expected GUID %s, got %s\n",
431                i, wine_dbgstr_guid(&testcases[i].pkey_expect.fmtid), wine_dbgstr_guid(&testcases[i].pkey->fmtid));
432             ok(testcases[i].pkey->pid == testcases[i].pkey_expect.pid,
433                "[%d] Expected property ID %u, got %u\n",
434                i, testcases[i].pkey_expect.pid, testcases[i].pkey->pid);
435         }
436     }
437 }
438 
439 static void test_PSRefreshPropertySchema(void)
440 {
441     HRESULT ret;
442 
443     ret = PSRefreshPropertySchema();
444     todo_wine
445     ok(ret == CO_E_NOTINITIALIZED,
446        "Expected PSRefreshPropertySchema to return CO_E_NOTINITIALIZED, got 0x%08x\n", ret);
447 
448     CoInitialize(NULL);
449 
450     ret = PSRefreshPropertySchema();
451     ok(ret == S_OK,
452        "Expected PSRefreshPropertySchema to return S_OK, got 0x%08x\n", ret);
453 
454     CoUninitialize();
455 }
456 
457 static void test_InitPropVariantFromGUIDAsString(void)
458 {
459     PROPVARIANT propvar;
460     VARIANT var;
461     HRESULT hres;
462     int i;
463 
464     const struct {
465         REFGUID guid;
466         const char *str;
467     } testcases[] = {
468         {&IID_NULL,             "{00000000-0000-0000-0000-000000000000}" },
469         {&dummy_guid,           "{DEADBEEF-DEAD-BEEF-DEAD-BEEFCAFEBABE}" },
470     };
471 
472     hres = InitPropVariantFromGUIDAsString(NULL, &propvar);
473     ok(hres == E_FAIL, "InitPropVariantFromGUIDAsString returned %x\n", hres);
474 
475     if(0) {
476         /* Returns strange data on Win7, crashes on older systems */
477         InitVariantFromGUIDAsString(NULL, &var);
478 
479         /* Crashes on windows */
480         InitPropVariantFromGUIDAsString(&IID_NULL, NULL);
481         InitVariantFromGUIDAsString(&IID_NULL, NULL);
482     }
483 
484     for(i=0; i < ARRAY_SIZE(testcases); i++) {
485         memset(&propvar, 0, sizeof(PROPVARIANT));
486         hres = InitPropVariantFromGUIDAsString(testcases[i].guid, &propvar);
487         ok(hres == S_OK, "%d) InitPropVariantFromGUIDAsString returned %x\n", i, hres);
488         ok(propvar.vt == VT_LPWSTR, "%d) propvar.vt = %d\n", i, propvar.vt);
489         ok(!strcmp_wa(propvar.u.pwszVal, testcases[i].str), "%d) propvar.u.pwszVal = %s\n",
490                 i, wine_dbgstr_w(propvar.u.pwszVal));
491         CoTaskMemFree(propvar.u.pwszVal);
492 
493         memset(&var, 0, sizeof(VARIANT));
494         hres = InitVariantFromGUIDAsString(testcases[i].guid, &var);
495         ok(hres == S_OK, "%d) InitVariantFromGUIDAsString returned %x\n", i, hres);
496         ok(V_VT(&var) == VT_BSTR, "%d) V_VT(&var) = %d\n", i, V_VT(&var));
497         ok(SysStringLen(V_BSTR(&var)) == 38, "SysStringLen returned %d\n",
498                 SysStringLen(V_BSTR(&var)));
499         ok(!strcmp_wa(V_BSTR(&var), testcases[i].str), "%d) V_BSTR(&var) = %s\n",
500                 i, wine_dbgstr_w(V_BSTR(&var)));
501         VariantClear(&var);
502     }
503 }
504 
505 static void test_InitPropVariantFromBuffer(void)
506 {
507     static const char data_in[] = "test";
508     PROPVARIANT propvar;
509     VARIANT var;
510     HRESULT hres;
511     void *data_out;
512     LONG size;
513 
514     hres = InitPropVariantFromBuffer(NULL, 0, &propvar);
515     ok(hres == S_OK, "InitPropVariantFromBuffer returned %x\n", hres);
516     ok(propvar.vt == (VT_VECTOR|VT_UI1), "propvar.vt = %d\n", propvar.vt);
517     ok(propvar.u.caub.cElems == 0, "cElems = %d\n", propvar.u.caub.cElems == 0);
518     PropVariantClear(&propvar);
519 
520     hres = InitPropVariantFromBuffer(data_in, 4, &propvar);
521     ok(hres == S_OK, "InitPropVariantFromBuffer returned %x\n", hres);
522     ok(propvar.vt == (VT_VECTOR|VT_UI1), "propvar.vt = %d\n", propvar.vt);
523     ok(propvar.u.caub.cElems == 4, "cElems = %d\n", propvar.u.caub.cElems == 0);
524     ok(!memcmp(propvar.u.caub.pElems, data_in, 4), "Data inside array is incorrect\n");
525     PropVariantClear(&propvar);
526 
527     hres = InitVariantFromBuffer(NULL, 0, &var);
528     ok(hres == S_OK, "InitVariantFromBuffer returned %x\n", hres);
529     ok(V_VT(&var) == (VT_ARRAY|VT_UI1), "V_VT(&var) = %d\n", V_VT(&var));
530     size = SafeArrayGetDim(V_ARRAY(&var));
531     ok(size == 1, "SafeArrayGetDim returned %d\n", size);
532     hres = SafeArrayGetLBound(V_ARRAY(&var), 1, &size);
533     ok(hres == S_OK, "SafeArrayGetLBound returned %x\n", hres);
534     ok(size == 0, "LBound = %d\n", size);
535     hres = SafeArrayGetUBound(V_ARRAY(&var), 1, &size);
536     ok(hres == S_OK, "SafeArrayGetUBound returned %x\n", hres);
537     ok(size == -1, "UBound = %d\n", size);
538     VariantClear(&var);
539 
540     hres = InitVariantFromBuffer(data_in, 4, &var);
541     ok(hres == S_OK, "InitVariantFromBuffer returned %x\n", hres);
542     ok(V_VT(&var) == (VT_ARRAY|VT_UI1), "V_VT(&var) = %d\n", V_VT(&var));
543     size = SafeArrayGetDim(V_ARRAY(&var));
544     ok(size == 1, "SafeArrayGetDim returned %d\n", size);
545     hres = SafeArrayGetLBound(V_ARRAY(&var), 1, &size);
546     ok(hres == S_OK, "SafeArrayGetLBound returned %x\n", hres);
547     ok(size == 0, "LBound = %d\n", size);
548     hres = SafeArrayGetUBound(V_ARRAY(&var), 1, &size);
549     ok(hres == S_OK, "SafeArrayGetUBound returned %x\n", hres);
550     ok(size == 3, "UBound = %d\n", size);
551     hres = SafeArrayAccessData(V_ARRAY(&var), &data_out);
552     ok(hres == S_OK, "SafeArrayAccessData failed %x\n", hres);
553     ok(!memcmp(data_in, data_out, 4), "Data inside safe array is incorrect\n");
554     hres = SafeArrayUnaccessData(V_ARRAY(&var));
555     ok(hres == S_OK, "SafeArrayUnaccessData failed %x\n", hres);
556     VariantClear(&var);
557 }
558 
559 static void test_PropVariantToGUID(void)
560 {
561     PROPVARIANT propvar;
562     VARIANT var;
563     GUID guid;
564     HRESULT hres;
565 
566     hres = InitPropVariantFromGUIDAsString(&IID_NULL, &propvar);
567     ok(hres == S_OK, "InitPropVariantFromGUIDAsString failed %x\n", hres);
568 
569     hres = PropVariantToGUID(&propvar, &guid);
570     ok(hres == S_OK, "PropVariantToGUID failed %x\n", hres);
571     ok(IsEqualGUID(&IID_NULL, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid));
572     PropVariantClear(&propvar);
573 
574     hres = InitPropVariantFromGUIDAsString(&dummy_guid, &propvar);
575     ok(hres == S_OK, "InitPropVariantFromGUIDAsString failed %x\n", hres);
576 
577     hres = PropVariantToGUID(&propvar, &guid);
578     ok(hres == S_OK, "PropVariantToGUID failed %x\n", hres);
579     ok(IsEqualGUID(&dummy_guid, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid));
580 
581     ok(propvar.vt == VT_LPWSTR, "incorrect PROPVARIANT type: %d\n", propvar.vt);
582     propvar.u.pwszVal[1] = 'd';
583     propvar.u.pwszVal[2] = 'E';
584     propvar.u.pwszVal[3] = 'a';
585     hres = PropVariantToGUID(&propvar, &guid);
586     ok(hres == S_OK, "PropVariantToGUID failed %x\n", hres);
587     ok(IsEqualGUID(&dummy_guid, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid));
588 
589     propvar.u.pwszVal[1] = 'z';
590     hres = PropVariantToGUID(&propvar, &guid);
591     ok(hres == E_INVALIDARG, "PropVariantToGUID returned %x\n", hres);
592     PropVariantClear(&propvar);
593 
594 
595     hres = InitVariantFromGUIDAsString(&IID_NULL, &var);
596     ok(hres == S_OK, "InitVariantFromGUIDAsString failed %x\n", hres);
597 
598     hres = VariantToGUID(&var, &guid);
599     ok(hres == S_OK, "VariantToGUID failed %x\n", hres);
600     ok(IsEqualGUID(&IID_NULL, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid));
601     VariantClear(&var);
602 
603     hres = InitVariantFromGUIDAsString(&dummy_guid, &var);
604     ok(hres == S_OK, "InitVariantFromGUIDAsString failed %x\n", hres);
605 
606     hres = VariantToGUID(&var, &guid);
607     ok(hres == S_OK, "VariantToGUID failed %x\n", hres);
608     ok(IsEqualGUID(&dummy_guid, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid));
609 
610     ok(V_VT(&var) == VT_BSTR, "incorrect VARIANT type: %d\n", V_VT(&var));
611     V_BSTR(&var)[1] = 'z';
612     hres = VariantToGUID(&var, &guid);
613     ok(hres == E_FAIL, "VariantToGUID returned %x\n", hres);
614 
615     V_BSTR(&var)[1] = 'd';
616     propvar.vt = V_VT(&var);
617     propvar.u.bstrVal = V_BSTR(&var);
618     V_VT(&var) = VT_EMPTY;
619     hres = PropVariantToGUID(&propvar, &guid);
620     ok(hres == S_OK, "PropVariantToGUID failed %x\n", hres);
621     ok(IsEqualGUID(&dummy_guid, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid));
622     PropVariantClear(&propvar);
623 
624     memset(&guid, 0, sizeof(guid));
625     InitPropVariantFromCLSID(&dummy_guid, &propvar);
626     hres = PropVariantToGUID(&propvar, &guid);
627     ok(hres == S_OK, "PropVariantToGUID failed %x\n", hres);
628     ok(IsEqualGUID(&dummy_guid, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid));
629     PropVariantClear(&propvar);
630 }
631 
632 static void test_PropVariantToStringAlloc(void)
633 {
634     PROPVARIANT prop;
635     WCHAR *str;
636     HRESULT hres;
637 
638     prop.vt = VT_NULL;
639     hres = PropVariantToStringAlloc(&prop, &str);
640     ok(hres == S_OK, "returned %x\n", hres);
641     ok(!lstrcmpW(str, emptyW), "got %s\n", wine_dbgstr_w(str));
642     CoTaskMemFree(str);
643 
644     prop.vt = VT_LPSTR;
645     prop.u.pszVal = CoTaskMemAlloc(strlen(topic)+1);
646     strcpy(prop.u.pszVal, topic);
647     hres = PropVariantToStringAlloc(&prop, &str);
648     ok(hres == S_OK, "returned %x\n", hres);
649     ok(!lstrcmpW(str, topicW), "got %s\n", wine_dbgstr_w(str));
650     CoTaskMemFree(str);
651     PropVariantClear(&prop);
652 
653     prop.vt = VT_EMPTY;
654     hres = PropVariantToStringAlloc(&prop, &str);
655     ok(hres == S_OK, "returned %x\n", hres);
656     ok(!lstrcmpW(str, emptyW), "got %s\n", wine_dbgstr_w(str));
657     CoTaskMemFree(str);
658 }
659 
660 static void test_PropVariantCompare(void)
661 {
662     PROPVARIANT empty, null, emptyarray, i2_0, i2_2, i4_large, i4_largeneg, i4_2, str_2, str_02, str_b;
663     PROPVARIANT clsid_null, clsid, clsid2, r4_0, r4_2, r8_0, r8_2;
664     INT res;
665     static const WCHAR str_2W[] = {'2', 0};
666     static const WCHAR str_02W[] = {'0', '2', 0};
667     static const WCHAR str_bW[] = {'b', 0};
668     SAFEARRAY emptysafearray;
669 
670     PropVariantInit(&empty);
671     PropVariantInit(&null);
672     PropVariantInit(&emptyarray);
673     PropVariantInit(&i2_0);
674     PropVariantInit(&i2_2);
675     PropVariantInit(&i4_large);
676     PropVariantInit(&i4_largeneg);
677     PropVariantInit(&i4_2);
678     PropVariantInit(&str_2);
679     PropVariantInit(&str_b);
680 
681     empty.vt = VT_EMPTY;
682     null.vt = VT_NULL;
683     emptyarray.vt = VT_ARRAY | VT_I4;
684     emptyarray.u.parray = &emptysafearray;
685     emptysafearray.cDims = 1;
686     emptysafearray.fFeatures = FADF_FIXEDSIZE;
687     emptysafearray.cbElements = 4;
688     emptysafearray.cLocks = 0;
689     emptysafearray.pvData = NULL;
690     emptysafearray.rgsabound[0].cElements = 0;
691     emptysafearray.rgsabound[0].lLbound = 0;
692     i2_0.vt = VT_I2;
693     i2_0.u.iVal = 0;
694     i2_2.vt = VT_I2;
695     i2_2.u.iVal = 2;
696     i4_large.vt = VT_I4;
697     i4_large.u.lVal = 65536;
698     i4_largeneg.vt = VT_I4;
699     i4_largeneg.u.lVal = -65536;
700     i4_2.vt = VT_I4;
701     i4_2.u.lVal = 2;
702     str_2.vt = VT_BSTR;
703     str_2.u.bstrVal = SysAllocString(str_2W);
704     str_02.vt = VT_BSTR;
705     str_02.u.bstrVal = SysAllocString(str_02W);
706     str_b.vt = VT_BSTR;
707     str_b.u.bstrVal = SysAllocString(str_bW);
708     clsid_null.vt = VT_CLSID;
709     clsid_null.u.puuid = NULL;
710     clsid.vt = VT_CLSID;
711     clsid.u.puuid = (GUID *)&dummy_guid;
712     clsid2.vt = VT_CLSID;
713     clsid2.u.puuid = (GUID *)&GUID_NULL;
714     r4_0.vt = VT_R4;
715     r4_0.u.fltVal = 0.0f;
716     r4_2.vt = VT_R4;
717     r4_2.u.fltVal = 2.0f;
718     r8_0.vt = VT_R8;
719     r8_0.u.dblVal = 0.0;
720     r8_2.vt = VT_R8;
721     r8_2.u.dblVal = 2.0;
722 
723     res = PropVariantCompareEx(&empty, &empty, 0, 0);
724     ok(res == 0, "res=%i\n", res);
725 
726     res = PropVariantCompareEx(&empty, &null, 0, 0);
727     ok(res == 0, "res=%i\n", res);
728 
729     res = PropVariantCompareEx(&null, &emptyarray, 0, 0);
730     ok(res == 0, "res=%i\n", res);
731 
732     res = PropVariantCompareEx(&null, &i2_0, 0, 0);
733     ok(res == -1, "res=%i\n", res);
734 
735     res = PropVariantCompareEx(&i2_0, &null, 0, 0);
736     ok(res == 1, "res=%i\n", res);
737 
738     res = PropVariantCompareEx(&null, &i2_0, 0, PVCF_TREATEMPTYASGREATERTHAN);
739     ok(res == 1, "res=%i\n", res);
740 
741     res = PropVariantCompareEx(&i2_0, &null, 0, PVCF_TREATEMPTYASGREATERTHAN);
742     ok(res == -1, "res=%i\n", res);
743 
744     res = PropVariantCompareEx(&i2_2, &i2_0, 0, 0);
745     ok(res == 1, "res=%i\n", res);
746 
747     res = PropVariantCompareEx(&i2_0, &i2_2, 0, 0);
748     ok(res == -1, "res=%i\n", res);
749 
750     /* Always return -1 if second value cannot be converted to first type */
751     res = PropVariantCompareEx(&i2_0, &i4_large, 0, 0);
752     ok(res == -1, "res=%i\n", res);
753 
754     res = PropVariantCompareEx(&i2_0, &i4_largeneg, 0, 0);
755     ok(res == -1, "res=%i\n", res);
756 
757     res = PropVariantCompareEx(&i4_large, &i2_0, 0, 0);
758     ok(res == 1, "res=%i\n", res);
759 
760     res = PropVariantCompareEx(&i4_largeneg, &i2_0, 0, 0);
761     ok(res == -1, "res=%i\n", res);
762 
763     res = PropVariantCompareEx(&i2_2, &i4_2, 0, 0);
764     ok(res == 0, "res=%i\n", res);
765 
766     res = PropVariantCompareEx(&i2_2, &str_2, 0, 0);
767     ok(res == 0, "res=%i\n", res);
768 
769     res = PropVariantCompareEx(&i2_2, &str_02, 0, 0);
770     ok(res == 0, "res=%i\n", res);
771 
772     res = PropVariantCompareEx(&str_2, &i2_2, 0, 0);
773     todo_wine ok(res == 0, "res=%i\n", res);
774 
775     res = PropVariantCompareEx(&str_02, &i2_2, 0, 0);
776     ok(res == -1, "res=%i\n", res);
777 
778     res = PropVariantCompareEx(&str_02, &str_2, 0, 0);
779     ok(res == -1, "res=%i\n", res);
780 
781     res = PropVariantCompareEx(&str_02, &str_b, 0, 0);
782     ok(res == -1, "res=%i\n", res);
783 
784     res = PropVariantCompareEx(&str_2, &str_02, 0, 0);
785     ok(res == 1, "res=%i\n", res);
786 
787     res = PropVariantCompareEx(&i4_large, &str_b, 0, 0);
788     todo_wine ok(res == -5 /* ??? */, "res=%i\n", res);
789 
790     /* VT_CLSID */
791     res = PropVariantCompareEx(&clsid_null, &clsid_null, 0, 0);
792     ok(res == 0, "res=%i\n", res);
793 
794     res = PropVariantCompareEx(&clsid_null, &clsid_null, 0, PVCF_TREATEMPTYASGREATERTHAN);
795     ok(res == 0, "res=%i\n", res);
796 
797     res = PropVariantCompareEx(&clsid, &clsid, 0, 0);
798     ok(res == 0, "res=%i\n", res);
799 
800     res = PropVariantCompareEx(&clsid, &clsid2, 0, 0);
801     ok(res == 1, "res=%i\n", res);
802 
803     res = PropVariantCompareEx(&clsid2, &clsid, 0, 0);
804     ok(res == -1, "res=%i\n", res);
805 
806     res = PropVariantCompareEx(&clsid_null, &clsid, 0, 0);
807     ok(res == -1, "res=%i\n", res);
808 
809     res = PropVariantCompareEx(&clsid, &clsid_null, 0, 0);
810     ok(res == 1, "res=%i\n", res);
811 
812     res = PropVariantCompareEx(&clsid_null, &clsid, 0, PVCF_TREATEMPTYASGREATERTHAN);
813     ok(res == 1, "res=%i\n", res);
814 
815     res = PropVariantCompareEx(&clsid, &clsid_null, 0, PVCF_TREATEMPTYASGREATERTHAN);
816     ok(res == -1, "res=%i\n", res);
817 
818     /* VT_R4/VT_R8 */
819     res = PropVariantCompareEx(&r4_0, &r8_0, 0, 0);
820 todo_wine
821     ok(res == 0, "res=%i\n", res);
822 
823     res = PropVariantCompareEx(&r4_0, &r4_0, 0, 0);
824     ok(res == 0, "res=%i\n", res);
825 
826     res = PropVariantCompareEx(&r4_0, &r4_2, 0, 0);
827     ok(res == -1, "res=%i\n", res);
828 
829     res = PropVariantCompareEx(&r4_2, &r4_0, 0, 0);
830     ok(res == 1, "res=%i\n", res);
831 
832     res = PropVariantCompareEx(&r8_0, &r8_0, 0, 0);
833     ok(res == 0, "res=%i\n", res);
834 
835     res = PropVariantCompareEx(&r8_0, &r8_2, 0, 0);
836     ok(res == -1, "res=%i\n", res);
837 
838     res = PropVariantCompareEx(&r8_2, &r8_0, 0, 0);
839     ok(res == 1, "res=%i\n", res);
840 
841     SysFreeString(str_2.u.bstrVal);
842     SysFreeString(str_02.u.bstrVal);
843     SysFreeString(str_b.u.bstrVal);
844 }
845 
846 static void test_intconversions(void)
847 {
848     PROPVARIANT propvar;
849     SHORT sval;
850     USHORT usval;
851     LONG lval;
852     ULONG ulval;
853     LONGLONG llval;
854     ULONGLONG ullval;
855     HRESULT hr;
856 
857     propvar.vt = 0xdead;
858     hr = PropVariantClear(&propvar);
859     ok (FAILED(hr), "PropVariantClear fails on invalid vt.\n");
860 
861     propvar.vt = VT_I8;
862     PropVariantClear(&propvar);
863 
864     propvar.vt = VT_I8;
865     propvar.u.hVal.QuadPart = (ULONGLONG)1 << 63;
866 
867     hr = PropVariantToInt64(&propvar, &llval);
868     ok(hr == S_OK, "hr=%x\n", hr);
869     ok(llval == (ULONGLONG)1 << 63, "got wrong value %s\n", wine_dbgstr_longlong(llval));
870 
871     hr = PropVariantToUInt64(&propvar, &ullval);
872     ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
873 
874     hr = PropVariantToInt32(&propvar, &lval);
875     ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
876 
877     hr = PropVariantToUInt32(&propvar, &ulval);
878     ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
879 
880     hr = PropVariantToInt16(&propvar, &sval);
881     ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
882 
883     hr = PropVariantToUInt16(&propvar, &usval);
884     ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
885 
886     propvar.vt = VT_UI8;
887     propvar.u.uhVal.QuadPart = 5;
888 
889     hr = PropVariantToInt64(&propvar, &llval);
890     ok(hr == S_OK, "hr=%x\n", hr);
891     ok(llval == 5, "got wrong value %s\n", wine_dbgstr_longlong(llval));
892 
893     hr = PropVariantToUInt64(&propvar, &ullval);
894     ok(hr == S_OK, "hr=%x\n", hr);
895     ok(ullval == 5, "got wrong value %s\n", wine_dbgstr_longlong(ullval));
896 
897     hr = PropVariantToInt32(&propvar, &lval);
898     ok(hr == S_OK, "hr=%x\n", hr);
899     ok(lval == 5, "got wrong value %d\n", lval);
900 
901     hr = PropVariantToUInt32(&propvar, &ulval);
902     ok(hr == S_OK, "hr=%x\n", hr);
903     ok(ulval == 5, "got wrong value %d\n", ulval);
904 
905     hr = PropVariantToInt16(&propvar, &sval);
906     ok(hr == S_OK, "hr=%x\n", hr);
907     ok(sval == 5, "got wrong value %d\n", sval);
908 
909     hr = PropVariantToUInt16(&propvar, &usval);
910     ok(hr == S_OK, "hr=%x\n", hr);
911     ok(usval == 5, "got wrong value %d\n", usval);
912 
913     propvar.vt = VT_I8;
914     propvar.u.hVal.QuadPart = -5;
915 
916     hr = PropVariantToInt64(&propvar, &llval);
917     ok(hr == S_OK, "hr=%x\n", hr);
918     ok(llval == -5, "got wrong value %s\n", wine_dbgstr_longlong(llval));
919 
920     hr = PropVariantToUInt64(&propvar, &ullval);
921     ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
922 
923     hr = PropVariantToInt32(&propvar, &lval);
924     ok(hr == S_OK, "hr=%x\n", hr);
925     ok(lval == -5, "got wrong value %d\n", lval);
926 
927     hr = PropVariantToUInt32(&propvar, &ulval);
928     ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
929 
930     hr = PropVariantToInt16(&propvar, &sval);
931     ok(hr == S_OK, "hr=%x\n", hr);
932     ok(sval == -5, "got wrong value %d\n", sval);
933 
934     hr = PropVariantToUInt16(&propvar, &usval);
935     ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
936 
937     propvar.vt = VT_UI4;
938     propvar.u.ulVal = 6;
939 
940     hr = PropVariantToInt64(&propvar, &llval);
941     ok(hr == S_OK, "hr=%x\n", hr);
942     ok(llval == 6, "got wrong value %s\n", wine_dbgstr_longlong(llval));
943 
944     propvar.vt = VT_I4;
945     propvar.u.lVal = -6;
946 
947     hr = PropVariantToInt64(&propvar, &llval);
948     ok(hr == S_OK, "hr=%x\n", hr);
949     ok(llval == -6, "got wrong value %s\n", wine_dbgstr_longlong(llval));
950 
951     propvar.vt = VT_UI2;
952     propvar.u.uiVal = 7;
953 
954     hr = PropVariantToInt64(&propvar, &llval);
955     ok(hr == S_OK, "hr=%x\n", hr);
956     ok(llval == 7, "got wrong value %s\n", wine_dbgstr_longlong(llval));
957 
958     propvar.vt = VT_I2;
959     propvar.u.iVal = -7;
960 
961     hr = PropVariantToInt64(&propvar, &llval);
962     ok(hr == S_OK, "hr=%x\n", hr);
963     ok(llval == -7, "got wrong value %s\n", wine_dbgstr_longlong(llval));
964 }
965 
966 static void test_PropVariantToBoolean(void)
967 {
968     static WCHAR str_0[] = {'0',0};
969     static WCHAR str_1[] = {'1',0};
970     static WCHAR str_7[] = {'7',0};
971     static WCHAR str_n7[] = {'-','7',0};
972     static WCHAR str_true[] = {'t','r','u','e',0};
973     static WCHAR str_true2[] = {'#','T','R','U','E','#',0};
974     static WCHAR str_true_case[] = {'t','R','U','e',0};
975     static WCHAR str_false[] = {'f','a','l','s','e',0};
976     static WCHAR str_false2[] = {'#','F','A','L','S','E','#',0};
977     static WCHAR str_true_space[] = {'t','r','u','e',' ',0};
978     static WCHAR str_yes[] = {'y','e','s',0};
979     PROPVARIANT propvar;
980     HRESULT hr;
981     BOOL val;
982 
983     /* VT_BOOL */
984     propvar.vt = VT_BOOL;
985     propvar.u.boolVal = VARIANT_FALSE;
986     val = TRUE;
987     hr = PropVariantToBoolean(&propvar, &val);
988     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
989     ok(val == FALSE, "Unexpected value %d\n", val);
990 
991     propvar.vt = VT_BOOL;
992     propvar.u.boolVal = 1;
993     val = TRUE;
994     hr = PropVariantToBoolean(&propvar, &val);
995     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
996     ok(val == FALSE, "Unexpected value %d\n", val);
997 
998     propvar.vt = VT_BOOL;
999     propvar.u.boolVal = VARIANT_TRUE;
1000     val = FALSE;
1001     hr = PropVariantToBoolean(&propvar, &val);
1002     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1003     ok(val == TRUE, "Unexpected value %d\n", val);
1004 
1005     /* VT_EMPTY */
1006     propvar.vt = VT_EMPTY;
1007     propvar.u.boolVal = VARIANT_TRUE;
1008     val = TRUE;
1009     hr = PropVariantToBoolean(&propvar, &val);
1010     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1011     ok(val == FALSE, "Unexpected value %d\n", val);
1012 
1013     /* test integer conversion */
1014     propvar.vt = VT_I4;
1015     propvar.u.lVal = 0;
1016     val = TRUE;
1017     hr = PropVariantToBoolean(&propvar, &val);
1018     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1019     ok(val == FALSE, "Unexpected value %d\n", val);
1020 
1021     propvar.vt = VT_I4;
1022     propvar.u.lVal = 1;
1023     val = FALSE;
1024     hr = PropVariantToBoolean(&propvar, &val);
1025     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1026     ok(val == TRUE, "Unexpected value %d\n", val);
1027 
1028     propvar.vt = VT_I4;
1029     propvar.u.lVal = 67;
1030     val = FALSE;
1031     hr = PropVariantToBoolean(&propvar, &val);
1032     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1033     ok(val == TRUE, "Unexpected value %d\n", val);
1034 
1035     propvar.vt = VT_I4;
1036     propvar.u.lVal = -67;
1037     val = FALSE;
1038     hr = PropVariantToBoolean(&propvar, &val);
1039     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1040     ok(val == TRUE, "Unexpected value %d\n", val);
1041 
1042     /* test string conversion */
1043     propvar.vt = VT_LPWSTR;
1044     propvar.u.pwszVal = str_0;
1045     val = TRUE;
1046     hr = PropVariantToBoolean(&propvar, &val);
1047     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1048     ok(val == FALSE, "Unexpected value %d\n", val);
1049 
1050     propvar.vt = VT_LPWSTR;
1051     propvar.u.pwszVal = str_1;
1052     val = FALSE;
1053     hr = PropVariantToBoolean(&propvar, &val);
1054     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1055     ok(val == TRUE, "Unexpected value %d\n", val);
1056 
1057     propvar.vt = VT_LPWSTR;
1058     propvar.u.pwszVal = str_7;
1059     val = FALSE;
1060     hr = PropVariantToBoolean(&propvar, &val);
1061     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1062     ok(val == TRUE, "Unexpected value %d\n", val);
1063 
1064     propvar.vt = VT_LPWSTR;
1065     propvar.u.pwszVal = str_n7;
1066     val = FALSE;
1067     hr = PropVariantToBoolean(&propvar, &val);
1068     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1069     ok(val == TRUE, "Unexpected value %d\n", val);
1070 
1071     propvar.vt = VT_LPWSTR;
1072     propvar.u.pwszVal = str_true;
1073     val = FALSE;
1074     hr = PropVariantToBoolean(&propvar, &val);
1075     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1076     ok(val == TRUE, "Unexpected value %d\n", val);
1077 
1078     propvar.vt = VT_LPWSTR;
1079     propvar.u.pwszVal = str_true_case;
1080     val = FALSE;
1081     hr = PropVariantToBoolean(&propvar, &val);
1082     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1083     ok(val == TRUE, "Unexpected value %d\n", val);
1084 
1085     propvar.vt = VT_LPWSTR;
1086     propvar.u.pwszVal = str_true2;
1087     val = FALSE;
1088     hr = PropVariantToBoolean(&propvar, &val);
1089     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1090     ok(val == TRUE, "Unexpected value %d\n", val);
1091 
1092     propvar.vt = VT_LPWSTR;
1093     propvar.u.pwszVal = str_false;
1094     val = TRUE;
1095     hr = PropVariantToBoolean(&propvar, &val);
1096     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1097     ok(val == FALSE, "Unexpected value %d\n", val);
1098 
1099     propvar.vt = VT_LPWSTR;
1100     propvar.u.pwszVal = str_false2;
1101     val = TRUE;
1102     hr = PropVariantToBoolean(&propvar, &val);
1103     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1104     ok(val == FALSE, "Unexpected value %d\n", val);
1105 
1106     propvar.vt = VT_LPWSTR;
1107     propvar.u.pwszVal = str_true_space;
1108     val = TRUE;
1109     hr = PropVariantToBoolean(&propvar, &val);
1110     ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#x.\n", hr);
1111     ok(val == FALSE, "Unexpected value %d\n", val);
1112 
1113     propvar.vt = VT_LPWSTR;
1114     propvar.u.pwszVal = str_yes;
1115     val = TRUE;
1116     hr = PropVariantToBoolean(&propvar, &val);
1117     ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#x.\n", hr);
1118     ok(val == FALSE, "Unexpected value %d\n", val);
1119 
1120     propvar.vt = VT_LPWSTR;
1121     propvar.u.pwszVal = NULL;
1122     val = TRUE;
1123     hr = PropVariantToBoolean(&propvar, &val);
1124     ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#x.\n", hr);
1125     ok(val == FALSE, "Unexpected value %d\n", val);
1126 
1127     /* VT_LPSTR */
1128     propvar.vt = VT_LPSTR;
1129     propvar.u.pszVal = (char *)"#TruE#";
1130     val = TRUE;
1131     hr = PropVariantToBoolean(&propvar, &val);
1132     ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#x.\n", hr);
1133     ok(val == FALSE, "Unexpected value %d\n", val);
1134 
1135     propvar.vt = VT_LPSTR;
1136     propvar.u.pszVal = (char *)"#TRUE#";
1137     val = FALSE;
1138     hr = PropVariantToBoolean(&propvar, &val);
1139     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1140     ok(val == TRUE, "Unexpected value %d\n", val);
1141 
1142     propvar.vt = VT_LPSTR;
1143     propvar.u.pszVal = (char *)"tRUe";
1144     val = FALSE;
1145     hr = PropVariantToBoolean(&propvar, &val);
1146     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1147     ok(val == TRUE, "Unexpected value %d\n", val);
1148 
1149     propvar.vt = VT_LPSTR;
1150     propvar.u.pszVal = (char *)"#FALSE#";
1151     val = TRUE;
1152     hr = PropVariantToBoolean(&propvar, &val);
1153     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1154     ok(val == FALSE, "Unexpected value %d\n", val);
1155 
1156     propvar.vt = VT_LPSTR;
1157     propvar.u.pszVal = (char *)"fALSe";
1158     val = TRUE;
1159     hr = PropVariantToBoolean(&propvar, &val);
1160     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1161     ok(val == FALSE, "Unexpected value %d\n", val);
1162 
1163     propvar.vt = VT_LPSTR;
1164     propvar.u.pszVal = (char *)"1";
1165     val = FALSE;
1166     hr = PropVariantToBoolean(&propvar, &val);
1167     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1168     ok(val == TRUE, "Unexpected value %d\n", val);
1169 
1170     propvar.vt = VT_LPSTR;
1171     propvar.u.pszVal = (char *)"-1";
1172     hr = PropVariantToBoolean(&propvar, &val);
1173     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1174     ok(val == TRUE, "Unexpected value %d\n", val);
1175 }
1176 
1177 static void test_PropVariantToStringWithDefault(void)
1178 {
1179     PROPVARIANT propvar;
1180     static WCHAR default_value[] = {'t', 'e', 's', 't', 0};
1181     static WCHAR wstr_test2[] =  {'t', 'e', 's', 't', '2', 0};
1182     static WCHAR wstr_empty[] = {0};
1183     static WCHAR wstr_space[] = {' ', 0};
1184     static CHAR str_test2[] =  "test2";
1185     static CHAR str_empty[] = "";
1186     static CHAR str_space[] = " ";
1187     LPCWSTR result;
1188 
1189     propvar.vt = VT_EMPTY;
1190     result = PropVariantToStringWithDefault(&propvar, default_value);
1191     ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result));
1192 
1193     propvar.vt = VT_NULL;
1194     result = PropVariantToStringWithDefault(&propvar, default_value);
1195     ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result));
1196 
1197     propvar.vt = VT_BOOL;
1198     propvar.u.boolVal = VARIANT_TRUE;
1199     result = PropVariantToStringWithDefault(&propvar, default_value);
1200     ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result));
1201 
1202     propvar.vt = VT_I4;
1203     propvar.u.lVal = 15;
1204     result = PropVariantToStringWithDefault(&propvar, default_value);
1205     ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result));
1206 
1207     /* VT_LPWSTR */
1208 
1209     propvar.vt = VT_LPWSTR;
1210     propvar.u.pwszVal = NULL;
1211     result = PropVariantToStringWithDefault(&propvar, default_value);
1212     ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result));
1213 
1214     propvar.vt = VT_LPWSTR;
1215     propvar.u.pwszVal = wstr_empty;
1216     result = PropVariantToStringWithDefault(&propvar, default_value);
1217     ok(result == wstr_empty, "Unexpected value %s\n", wine_dbgstr_w(result));
1218 
1219     propvar.vt = VT_LPWSTR;
1220     propvar.u.pwszVal = wstr_space;
1221     result = PropVariantToStringWithDefault(&propvar, default_value);
1222     ok(result == wstr_space, "Unexpected value %s\n", wine_dbgstr_w(result));
1223 
1224     propvar.vt = VT_LPWSTR;
1225     propvar.u.pwszVal = wstr_test2;
1226     result = PropVariantToStringWithDefault(&propvar, default_value);
1227     ok(result == wstr_test2, "Unexpected value %s\n", wine_dbgstr_w(result));
1228 
1229     /* VT_LPSTR */
1230 
1231     propvar.vt = VT_LPSTR;
1232     propvar.u.pszVal = NULL;
1233     result = PropVariantToStringWithDefault(&propvar, default_value);
1234     ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result));
1235 
1236     propvar.vt = VT_LPSTR;
1237     propvar.u.pszVal = str_empty;
1238     result = PropVariantToStringWithDefault(&propvar, default_value);
1239     ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result));
1240 
1241     propvar.vt = VT_LPSTR;
1242     propvar.u.pszVal = str_space;
1243     result = PropVariantToStringWithDefault(&propvar, default_value);
1244     ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result));
1245 
1246     propvar.vt = VT_LPSTR;
1247     propvar.u.pszVal = str_test2;
1248     result = PropVariantToStringWithDefault(&propvar, default_value);
1249     ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result));
1250 
1251     /* VT_BSTR */
1252 
1253     propvar.vt = VT_BSTR;
1254     propvar.u.bstrVal = NULL;
1255     result = PropVariantToStringWithDefault(&propvar, default_value);
1256     ok(!lstrcmpW(result, wstr_empty), "Unexpected value %s\n", wine_dbgstr_w(result));
1257 
1258     propvar.vt = VT_BSTR;
1259     propvar.u.bstrVal = SysAllocString(wstr_empty);
1260     result = PropVariantToStringWithDefault(&propvar, default_value);
1261     ok(!lstrcmpW(result, wstr_empty), "Unexpected value %s\n", wine_dbgstr_w(result));
1262     SysFreeString(propvar.u.bstrVal);
1263 
1264     propvar.vt = VT_BSTR;
1265     propvar.u.bstrVal = SysAllocString(wstr_space);
1266     result = PropVariantToStringWithDefault(&propvar, default_value);
1267     ok(!lstrcmpW(result, wstr_space), "Unexpected value %s\n", wine_dbgstr_w(result));
1268     SysFreeString(propvar.u.bstrVal);
1269 
1270     propvar.vt = VT_BSTR;
1271     propvar.u.bstrVal = SysAllocString(wstr_test2);
1272     result = PropVariantToStringWithDefault(&propvar, default_value);
1273     ok(!lstrcmpW(result, wstr_test2), "Unexpected value %s\n", wine_dbgstr_w(result));
1274     SysFreeString(propvar.u.bstrVal);
1275 }
1276 
1277 static void test_PropVariantChangeType_LPWSTR(void)
1278 {
1279     PROPVARIANT dest, src;
1280     HRESULT hr;
1281 
1282     PropVariantInit(&dest);
1283 
1284     src.vt = VT_NULL;
1285     hr = PropVariantChangeType(&dest, &src, 0, VT_LPWSTR);
1286     ok(hr == S_OK, "hr=%x\n", hr);
1287     ok(dest.vt == VT_LPWSTR, "got %d\n", dest.vt);
1288     ok(!lstrcmpW(dest.u.pwszVal, emptyW), "got %s\n", wine_dbgstr_w(dest.u.pwszVal));
1289     PropVariantClear(&dest);
1290     PropVariantClear(&src);
1291 
1292     src.vt = VT_LPSTR;
1293     src.u.pszVal = CoTaskMemAlloc(strlen(topic)+1);
1294     strcpy(src.u.pszVal, topic);
1295     hr = PropVariantChangeType(&dest, &src, 0, VT_LPWSTR);
1296     ok(hr == S_OK, "hr=%x\n", hr);
1297     ok(dest.vt == VT_LPWSTR, "got %d\n", dest.vt);
1298     ok(!lstrcmpW(dest.u.pwszVal, topicW), "got %s\n", wine_dbgstr_w(dest.u.pwszVal));
1299     PropVariantClear(&dest);
1300     PropVariantClear(&src);
1301 
1302     src.vt = VT_LPWSTR;
1303     src.u.pwszVal = CoTaskMemAlloc( (lstrlenW(topicW)+1) * sizeof(WCHAR));
1304     lstrcpyW(src.u.pwszVal, topicW);
1305     hr = PropVariantChangeType(&dest, &src, 0, VT_LPWSTR);
1306     ok(hr == S_OK, "hr=%x\n", hr);
1307     ok(dest.vt == VT_LPWSTR, "got %d\n", dest.vt);
1308     ok(!lstrcmpW(dest.u.pwszVal, topicW), "got %s\n", wine_dbgstr_w(dest.u.pwszVal));
1309     PropVariantClear(&dest);
1310     PropVariantClear(&src);
1311 }
1312 
1313 static void test_InitPropVariantFromCLSID(void)
1314 {
1315     PROPVARIANT propvar;
1316     GUID clsid;
1317     HRESULT hr;
1318 
1319     memset(&propvar, 0, sizeof(propvar));
1320     propvar.vt = VT_I4;
1321     propvar.u.lVal = 15;
1322 
1323     memset(&clsid, 0xcc, sizeof(clsid));
1324     hr = InitPropVariantFromCLSID(&clsid, &propvar);
1325     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1326     ok(propvar.vt == VT_CLSID, "Unexpected type %d.\n", propvar.vt);
1327     ok(IsEqualGUID(propvar.u.puuid, &clsid), "Unexpected puuid value.\n");
1328     PropVariantClear(&propvar);
1329 }
1330 
1331 static void test_PropVariantToDouble(void)
1332 {
1333     PROPVARIANT propvar;
1334     double value;
1335     HRESULT hr;
1336 
1337     PropVariantInit(&propvar);
1338     propvar.vt = VT_R8;
1339     propvar.u.dblVal = 15.0;
1340     hr = PropVariantToDouble(&propvar, &value);
1341     ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr);
1342     ok(value == 15.0, "Unexpected value: %f.\n", value);
1343 
1344     PropVariantClear(&propvar);
1345     propvar.vt = VT_I4;
1346     propvar.u.lVal = 123;
1347     hr = PropVariantToDouble(&propvar, &value);
1348     ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr);
1349     ok(value == 123.0, "Unexpected value: %f.\n", value);
1350 
1351     PropVariantClear(&propvar);
1352     propvar.vt = VT_I4;
1353     propvar.u.lVal = -256;
1354     hr = PropVariantToDouble(&propvar, &value);
1355     ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr);
1356     ok(value == -256, "Unexpected value: %f\n", value);
1357 
1358     PropVariantClear(&propvar);
1359     propvar.vt = VT_I8;
1360     propvar.u.lVal = 65536;
1361     hr = PropVariantToDouble(&propvar, &value);
1362     ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr);
1363     ok(value == 65536.0, "Unexpected value: %f.\n", value);
1364 
1365     PropVariantClear(&propvar);
1366     propvar.vt = VT_I8;
1367     propvar.u.lVal = -321;
1368     hr = PropVariantToDouble(&propvar, &value);
1369     ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr);
1370     ok(value == 4294966975.0, "Unexpected value: %f.\n", value);
1371 
1372     PropVariantClear(&propvar);
1373     propvar.vt = VT_UI4;
1374     propvar.u.ulVal = 6;
1375     hr = PropVariantToDouble(&propvar, &value);
1376     ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr);
1377     ok(value == 6.0, "Unexpected value: %f.\n", value);
1378 
1379     PropVariantClear(&propvar);
1380     propvar.vt = VT_UI8;
1381     propvar.u.uhVal.QuadPart = 8;
1382     hr = PropVariantToDouble(&propvar, &value);
1383     ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr);
1384     ok(value == 8.0, "Unexpected value: %f.\n", value);
1385 }
1386 
1387 static void test_PropVariantToString(void)
1388 {
1389     PROPVARIANT propvar;
1390     static CHAR string[] = "Wine";
1391     static WCHAR stringW[] = {'W','i','n','e',0};
1392     WCHAR bufferW[256] = {0};
1393     HRESULT hr;
1394 
1395     PropVariantInit(&propvar);
1396     propvar.vt = VT_EMPTY;
1397     U(propvar).pwszVal = stringW;
1398     bufferW[0] = 65;
1399     hr = PropVariantToString(&propvar, bufferW, 0);
1400     ok(hr == E_INVALIDARG, "PropVariantToString should fail: 0x%08x.\n", hr);
1401     ok(!bufferW[0], "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW));
1402     memset(bufferW, 0, sizeof(bufferW));
1403     PropVariantClear(&propvar);
1404 
1405     PropVariantInit(&propvar);
1406     propvar.vt = VT_EMPTY;
1407     U(propvar).pwszVal = stringW;
1408     bufferW[0] = 65;
1409     hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW));
1410     ok(hr == S_OK, "PropVariantToString failed: 0x%08x.\n", hr);
1411     ok(!bufferW[0], "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW));
1412     memset(bufferW, 0, sizeof(bufferW));
1413     PropVariantClear(&propvar);
1414 
1415     PropVariantInit(&propvar);
1416     propvar.vt = VT_NULL;
1417     U(propvar).pwszVal = stringW;
1418     bufferW[0] = 65;
1419     hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW));
1420     ok(hr == S_OK, "PropVariantToString failed: 0x%08x.\n", hr);
1421     ok(!bufferW[0], "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW));
1422     memset(bufferW, 0, sizeof(bufferW));
1423     PropVariantClear(&propvar);
1424 
1425     PropVariantInit(&propvar);
1426     propvar.vt = VT_I4;
1427     U(propvar).lVal = 22;
1428     hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW));
1429     todo_wine ok(hr == S_OK, "PropVariantToString failed: 0x%08x.\n", hr);
1430     todo_wine ok(!strcmp_wa(bufferW, "22"), "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW));
1431     memset(bufferW, 0, sizeof(bufferW));
1432     PropVariantClear(&propvar);
1433 
1434     PropVariantInit(&propvar);
1435     propvar.vt = VT_LPWSTR;
1436     U(propvar).pwszVal = stringW;
1437     hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW));
1438     ok(hr == S_OK, "PropVariantToString failed: 0x%08x.\n", hr);
1439     ok(!lstrcmpW(bufferW, stringW), "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW));
1440     memset(bufferW, 0, sizeof(bufferW));
1441 
1442     PropVariantInit(&propvar);
1443     propvar.vt = VT_LPSTR;
1444     U(propvar).pszVal = string;
1445     hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW));
1446     ok(hr == S_OK, "PropVariantToString failed: 0x%08x.\n", hr);
1447     ok(!lstrcmpW(bufferW, stringW), "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW));
1448     memset(bufferW, 0, sizeof(bufferW));
1449 
1450     PropVariantInit(&propvar);
1451     propvar.vt = VT_LPWSTR;
1452     U(propvar).pwszVal = stringW;
1453     hr = PropVariantToString(&propvar, bufferW, 4);
1454     ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "PropVariantToString returned: 0x%08x.\n", hr);
1455     ok(!memcmp(bufferW, stringW, 4), "got wrong string.\n");
1456     memset(bufferW, 0, sizeof(bufferW));
1457 
1458     PropVariantInit(&propvar);
1459     propvar.vt = VT_LPSTR;
1460     U(propvar).pszVal = string;
1461     hr = PropVariantToString(&propvar, bufferW, 4);
1462     ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "PropVariantToString returned: 0x%08x.\n", hr);
1463     ok(!memcmp(bufferW, stringW, 4), "got wrong string.\n");
1464     memset(bufferW, 0, sizeof(bufferW));
1465 
1466     PropVariantInit(&propvar);
1467     propvar.vt = VT_BSTR;
1468     propvar.u.bstrVal = SysAllocString(stringW);
1469     hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW));
1470     ok(hr == S_OK, "PropVariantToString failed: 0x%08x.\n", hr);
1471     ok(!lstrcmpW(bufferW, stringW), "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW));
1472     memset(bufferW, 0, sizeof(bufferW));
1473     SysFreeString(propvar.u.bstrVal);
1474 }
1475 
1476 static void test_PropVariantToBuffer(void)
1477 {
1478     PROPVARIANT propvar;
1479     HRESULT hr;
1480     UINT8 data[] = {1,2,3,4,5,6,7,8,9,10};
1481     INT8 data_int8[] = {1,2,3,4,5,6,7,8,9,10};
1482     SAFEARRAY *sa;
1483     SAFEARRAYBOUND sabound;
1484     void *pdata;
1485     UINT8 buffer[256];
1486 
1487     hr = InitPropVariantFromBuffer(data, 10, &propvar);
1488     ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08x.\n", hr);
1489     hr = PropVariantToBuffer(&propvar, NULL, 0); /* crash when cb isn't zero */
1490     ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08x.\n", hr);
1491     PropVariantClear(&propvar);
1492 
1493     hr = InitPropVariantFromBuffer(data, 10, &propvar);
1494     ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08x.\n", hr);
1495     hr = PropVariantToBuffer(&propvar, buffer, 10);
1496     ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08x.\n", hr);
1497     ok(!memcmp(buffer, data, 10) && !buffer[10], "got wrong buffer.\n");
1498     memset(buffer, 0, sizeof(buffer));
1499     PropVariantClear(&propvar);
1500 
1501     hr = InitPropVariantFromBuffer(data, 10, &propvar);
1502     ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08x.\n", hr);
1503     buffer[0] = 99;
1504     hr = PropVariantToBuffer(&propvar, buffer, 11);
1505     ok(hr == E_FAIL, "PropVariantToBuffer returned: 0x%08x.\n", hr);
1506     ok(buffer[0] == 99, "got wrong buffer.\n");
1507     memset(buffer, 0, sizeof(buffer));
1508     PropVariantClear(&propvar);
1509 
1510     hr = InitPropVariantFromBuffer(data, 10, &propvar);
1511     ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08x.\n", hr);
1512     hr = PropVariantToBuffer(&propvar, buffer, 9);
1513     ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08x.\n", hr);
1514     ok(!memcmp(buffer, data, 9) && !buffer[9], "got wrong buffer.\n");
1515     memset(buffer, 0, sizeof(buffer));
1516     PropVariantClear(&propvar);
1517 
1518     PropVariantInit(&propvar);
1519     propvar.vt = VT_ARRAY|VT_UI1;
1520     sabound.lLbound = 0;
1521     sabound.cElements = sizeof(data);
1522     sa = NULL;
1523     sa = SafeArrayCreate(VT_UI1, 1, &sabound);
1524     ok(sa != NULL, "SafeArrayCreate failed.\n");
1525     hr = SafeArrayAccessData(sa, &pdata);
1526     ok(hr == S_OK, "SafeArrayAccessData failed: 0x%08x.\n", hr);
1527     memcpy(pdata, data, sizeof(data));
1528     hr = SafeArrayUnaccessData(sa);
1529     ok(hr == S_OK, "SafeArrayUnaccessData failed: 0x%08x.\n", hr);
1530     U(propvar).parray = sa;
1531     buffer[0] = 99;
1532     hr = PropVariantToBuffer(&propvar, buffer, 11);
1533     todo_wine ok(hr == E_FAIL, "PropVariantToBuffer returned: 0x%08x.\n", hr);
1534     ok(buffer[0] == 99, "got wrong buffer.\n");
1535     memset(buffer, 0, sizeof(buffer));
1536     PropVariantClear(&propvar);
1537 
1538     PropVariantInit(&propvar);
1539     propvar.vt = VT_ARRAY|VT_UI1;
1540     sabound.lLbound = 0;
1541     sabound.cElements = sizeof(data);
1542     sa = NULL;
1543     sa = SafeArrayCreate(VT_UI1, 1, &sabound);
1544     ok(sa != NULL, "SafeArrayCreate failed.\n");
1545     hr = SafeArrayAccessData(sa, &pdata);
1546     ok(hr == S_OK, "SafeArrayAccessData failed: 0x%08x.\n", hr);
1547     memcpy(pdata, data, sizeof(data));
1548     hr = SafeArrayUnaccessData(sa);
1549     ok(hr == S_OK, "SafeArrayUnaccessData failed: 0x%08x.\n", hr);
1550     U(propvar).parray = sa;
1551     hr = PropVariantToBuffer(&propvar, buffer, sizeof(data));
1552     todo_wine ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08x.\n", hr);
1553     todo_wine ok(!memcmp(buffer, data, 10) && !buffer[10], "got wrong buffer.\n");
1554     memset(buffer, 0, sizeof(buffer));
1555     PropVariantClear(&propvar);
1556 
1557     PropVariantInit(&propvar);
1558     propvar.vt = VT_VECTOR|VT_I1;
1559     U(propvar).caub.pElems = CoTaskMemAlloc(sizeof(data_int8));
1560     U(propvar).caub.cElems = sizeof(data_int8);
1561     memcpy(U(propvar).caub.pElems, data_int8, sizeof(data_int8));
1562     hr = PropVariantToBuffer(&propvar, buffer, sizeof(data_int8));
1563     ok(hr == E_INVALIDARG, "PropVariantToBuffer failed: 0x%08x.\n", hr);
1564     PropVariantClear(&propvar);
1565 
1566     PropVariantInit(&propvar);
1567     propvar.vt = VT_ARRAY|VT_I1;
1568     sabound.lLbound = 0;
1569     sabound.cElements = sizeof(data_int8);
1570     sa = NULL;
1571     sa = SafeArrayCreate(VT_I1, 1, &sabound);
1572     ok(sa != NULL, "SafeArrayCreate failed.\n");
1573     hr = SafeArrayAccessData(sa, &pdata);
1574     ok(hr == S_OK, "SafeArrayAccessData failed: 0x%08x.\n", hr);
1575     memcpy(pdata, data_int8, sizeof(data_int8));
1576     hr = SafeArrayUnaccessData(sa);
1577     ok(hr == S_OK, "SafeArrayUnaccessData failed: 0x%08x.\n", hr);
1578     U(propvar).parray = sa;
1579     hr = PropVariantToBuffer(&propvar, buffer, sizeof(data_int8));
1580     ok(hr == E_INVALIDARG, "PropVariantToBuffer failed: 0x%08x.\n", hr);
1581     PropVariantClear(&propvar);
1582 }
1583 
1584 START_TEST(propsys)
1585 {
1586     test_PSStringFromPropertyKey();
1587     test_PSPropertyKeyFromString();
1588     test_PSRefreshPropertySchema();
1589     test_InitPropVariantFromGUIDAsString();
1590     test_InitPropVariantFromBuffer();
1591     test_PropVariantToGUID();
1592     test_PropVariantToStringAlloc();
1593     test_PropVariantCompare();
1594     test_intconversions();
1595     test_PropVariantChangeType_LPWSTR();
1596     test_PropVariantToBoolean();
1597     test_PropVariantToStringWithDefault();
1598     test_InitPropVariantFromCLSID();
1599     test_PropVariantToDouble();
1600     test_PropVariantToString();
1601     test_PropVariantToBuffer();
1602 }
1603