gdi32: Try to parse font names without FreeType.
[wine/zf.git] / dlls / propsys / tests / propsys.c
bloba9b6e48827ab81999be7270aa1e6221095b8434a
1 /*
2 * Unit tests for Windows property system
4 * Copyright 2006 Paul Vriens
5 * Copyright 2010 Andrew Nguyen
6 * Copyright 2012 Vincent Povirk
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #define COBJMACROS
25 #include <stdarg.h>
26 #include <stdio.h>
28 #define NONAMELESSUNION
30 #include "windef.h"
31 #include "winbase.h"
32 #include "initguid.h"
33 #include "objbase.h"
34 #include "propsys.h"
35 #include "propvarutil.h"
36 #include "strsafe.h"
37 #include "wine/test.h"
39 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
40 DEFINE_GUID(dummy_guid, 0xdeadbeef, 0xdead, 0xbeef, 0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0xba, 0xbe);
41 DEFINE_GUID(expect_guid, 0x12345678, 0x1234, 0x1234, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12);
42 DEFINE_GUID(PKEY_WineTest, 0x7b317433, 0xdfa3, 0x4c44, 0xad, 0x3e, 0x2f, 0x80, 0x4b, 0x90, 0xdb, 0xf4);
43 DEFINE_GUID(DUMMY_GUID1, 0x12345678, 0x1234,0x1234, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19);
45 #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]}}
47 static const char topic[] = "wine topic";
48 static const WCHAR topicW[] = {'w','i','n','e',' ','t','o','p','i','c',0};
49 static const WCHAR emptyW[] = {0};
51 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown *)obj, ref, __LINE__)
52 static void _expect_ref(IUnknown *obj, ULONG ref, int line)
54 ULONG rc;
55 IUnknown_AddRef(obj);
56 rc = IUnknown_Release(obj);
57 ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc);
60 static void test_PSStringFromPropertyKey(void)
62 static const WCHAR fillerW[] = {'X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X',
63 'X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X',
64 'X','X','X','X','X','X','X','X','X','X'};
65 static const WCHAR zero_fillerW[] = {'\0','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X',
66 'X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X',
67 'X','X','X','X','X','X','X','X','X','X','X','X','X','X'};
68 static const WCHAR zero_truncatedW[] = {'\0','0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0',
69 '0','0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0',
70 '0','0','0','}',' ','\0','9','X','X','X','X','X','X','X','X','X'};
71 static const WCHAR zero_truncated2W[] = {'\0','0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0',
72 '0','0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0',
73 '0','0','0','}',' ','\0','9','2','7','6','9','4','9','2','X','X'};
74 static const WCHAR zero_truncated3W[] = {'\0','0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0',
75 '0','0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0',
76 '0','0','0','}',' ','\0','9','2','7','6','9','4','9','2','4','X'};
77 static const WCHAR zero_truncated4W[] = {'\0','0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0',
78 '0','0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0',
79 '0','0','0','}',' ','\0','7','X','X','X','X','X','X','X','X','X'};
80 static const WCHAR truncatedW[] = {'{','0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0','0',
81 '0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0',
82 '0','}',' ','\0','9','X','X','X','X','X','X','X','X','X'};
83 static const WCHAR truncated2W[] = {'{','0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0','0',
84 '0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0',
85 '0','}',' ','\0','9','2','7','6','9','4','9','2','X','X'};
86 static const WCHAR truncated3W[] = {'{','0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0','0',
87 '0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0',
88 '0','}',' ','\0','9','2','7','6','9','4','9','2','4','X'};
89 static const WCHAR truncated4W[] = {'{','0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0','0',
90 '0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0',
91 '0','}',' ','\0','7','X','X','X','X','X','X','X','X','X'};
92 static const WCHAR expectedW[] = {'{','0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0','0',
93 '0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0',
94 '0','}',' ','4','2','9','4','9','6','7','2','9','5',0};
95 static const WCHAR expected2W[] = {'{','0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0','0',
96 '0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0',
97 '0','}',' ','1','3','5','7','9','\0','X','X','X','X','X'};
98 static const WCHAR expected3W[] = {'{','0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0','0',
99 '0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0',
100 '0','}',' ','0','\0','X','X','X','X','X','X','X','X','X'};
101 PROPERTYKEY prop = {GUID_MEMBERS(GUID_NULL), ~0U};
102 PROPERTYKEY prop2 = {GUID_MEMBERS(GUID_NULL), 13579};
103 PROPERTYKEY prop3 = {GUID_MEMBERS(GUID_NULL), 0};
104 WCHAR out[PKEYSTR_MAX];
105 HRESULT ret;
107 const struct
109 REFPROPERTYKEY pkey;
110 LPWSTR psz;
111 UINT cch;
112 HRESULT hr_expect;
113 const WCHAR *buf_expect;
114 BOOL hr_broken;
115 HRESULT hr2;
116 BOOL buf_broken;
117 const WCHAR *buf2;
118 } testcases[] =
120 {NULL, NULL, 0, E_POINTER},
121 {&prop, NULL, 0, E_POINTER},
122 {&prop, NULL, PKEYSTR_MAX, E_POINTER},
123 {NULL, out, 0, E_NOT_SUFFICIENT_BUFFER, fillerW},
124 {NULL, out, PKEYSTR_MAX, E_NOT_SUFFICIENT_BUFFER, zero_fillerW, FALSE, 0, TRUE, fillerW},
125 {&prop, out, 0, E_NOT_SUFFICIENT_BUFFER, fillerW},
126 {&prop, out, GUIDSTRING_MAX, E_NOT_SUFFICIENT_BUFFER, fillerW},
127 {&prop, out, GUIDSTRING_MAX + 1, E_NOT_SUFFICIENT_BUFFER, fillerW},
128 {&prop, out, GUIDSTRING_MAX + 2, E_NOT_SUFFICIENT_BUFFER, zero_truncatedW, TRUE, S_OK, TRUE, truncatedW},
129 {&prop, out, PKEYSTR_MAX - 2, E_NOT_SUFFICIENT_BUFFER, zero_truncated2W, TRUE, S_OK, TRUE, truncated2W},
130 {&prop, out, PKEYSTR_MAX - 1, E_NOT_SUFFICIENT_BUFFER, zero_truncated3W, TRUE, S_OK, TRUE, truncated3W},
131 {&prop, out, PKEYSTR_MAX, S_OK, expectedW},
132 {&prop2, out, GUIDSTRING_MAX + 2, E_NOT_SUFFICIENT_BUFFER, zero_truncated4W, TRUE, S_OK, TRUE, truncated4W},
133 {&prop2, out, GUIDSTRING_MAX + 6, S_OK, expected2W},
134 {&prop2, out, PKEYSTR_MAX, S_OK, expected2W},
135 {&prop3, out, GUIDSTRING_MAX + 1, E_NOT_SUFFICIENT_BUFFER, fillerW},
136 {&prop3, out, GUIDSTRING_MAX + 2, S_OK, expected3W},
137 {&prop3, out, PKEYSTR_MAX, S_OK, expected3W},
140 int i;
142 for (i = 0; i < ARRAY_SIZE(testcases); i++)
144 if (testcases[i].psz)
145 memcpy(testcases[i].psz, fillerW, PKEYSTR_MAX * sizeof(WCHAR));
147 ret = PSStringFromPropertyKey(testcases[i].pkey,
148 testcases[i].psz,
149 testcases[i].cch);
150 ok(ret == testcases[i].hr_expect ||
151 broken(testcases[i].hr_broken && ret == testcases[i].hr2), /* Vista/Win2k8 */
152 "[%d] Expected PSStringFromPropertyKey to return 0x%08x, got 0x%08x\n",
153 i, testcases[i].hr_expect, ret);
155 if (testcases[i].psz)
156 ok(!memcmp(testcases[i].psz, testcases[i].buf_expect, PKEYSTR_MAX * sizeof(WCHAR)) ||
157 broken(testcases[i].buf_broken &&
158 !memcmp(testcases[i].psz, testcases[i].buf2, PKEYSTR_MAX * sizeof(WCHAR))), /* Vista/Win2k8 */
159 "[%d] Unexpected output contents\n", i);
163 static void test_PSPropertyKeyFromString(void)
165 static const WCHAR fmtid_clsidW[] = {'S','t','d','F','o','n','t',' ','1',0};
166 static const WCHAR fmtid_truncatedW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
167 '1','2','3','4','-',0};
168 static const WCHAR fmtid_nobracketsW[] = {'1','2','3','4','5','6','7','8','-','1','2','3','4','-',
169 '1','2','3','4','-','1','2','3','4','-',
170 '1','2','3','4','5','6','7','8','9','0','1','2',0};
171 static const WCHAR fmtid_badbracketW[] = {'X','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
172 '1','2','3','4','-','1','2','3','4','-',
173 '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
174 static const WCHAR fmtid_badcharW[] = {'{','X','2','3','4','5','6','7','8','-','1','2','3','4','-',
175 '1','2','3','4','-','1','2','3','4','-',
176 '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
177 static const WCHAR fmtid_badchar2W[] = {'{','1','2','3','4','5','6','7','X','-','1','2','3','4','-',
178 '1','2','3','4','-','1','2','3','4','-',
179 '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
180 static const WCHAR fmtid_baddashW[] = {'{','1','2','3','4','5','6','7','8','X','1','2','3','4','-',
181 '1','2','3','4','-','1','2','3','4','-',
182 '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
183 static const WCHAR fmtid_badchar3W[] = {'{','1','2','3','4','5','6','7','8','-','X','2','3','4','-',
184 '1','2','3','4','-','1','2','3','4','-',
185 '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
186 static const WCHAR fmtid_badchar4W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','X','-',
187 '1','2','3','4','-','1','2','3','4','-',
188 '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
189 static const WCHAR fmtid_baddash2W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','X',
190 '1','2','3','4','-','1','2','3','4','-',
191 '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
192 static const WCHAR fmtid_badchar5W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
193 'X','2','3','4','-','1','2','3','4','-',
194 '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
195 static const WCHAR fmtid_badchar6W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
196 '1','2','3','X','-','1','2','3','4','-',
197 '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
198 static const WCHAR fmtid_baddash3W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
199 '1','2','3','4','X','1','2','3','4','-',
200 '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
201 static const WCHAR fmtid_badchar7W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
202 '1','2','3','4','-','X','2','3','4','-',
203 '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
204 static const WCHAR fmtid_badchar8W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
205 '1','2','3','4','-','1','2','3','X','-',
206 '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
207 static const WCHAR fmtid_baddash4W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
208 '1','2','3','4','-','1','2','3','4','X',
209 '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
210 static const WCHAR fmtid_badchar9W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
211 '1','2','3','4','-','1','2','3','4','-',
212 'X','2','3','4','5','6','7','8','9','0','1','2','}',0};
213 static const WCHAR fmtid_badchar9_adjW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
214 '1','2','3','4','-','1','2','3','4','-',
215 '1','X','3','4','5','6','7','8','9','0','1','2','}',0};
216 static const WCHAR fmtid_badchar10W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
217 '1','2','3','4','-','1','2','3','4','-',
218 '1','2','X','4','5','6','7','8','9','0','1','2','}',0};
219 static const WCHAR fmtid_badchar11W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
220 '1','2','3','4','-','1','2','3','4','-',
221 '1','2','3','4','X','6','7','8','9','0','1','2','}',0};
222 static const WCHAR fmtid_badchar12W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
223 '1','2','3','4','-','1','2','3','4','-',
224 '1','2','3','4','5','6','X','8','9','0','1','2','}',0};
225 static const WCHAR fmtid_badchar13W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
226 '1','2','3','4','-','1','2','3','4','-',
227 '1','2','3','4','5','6','7','8','X','0','1','2','}',0};
228 static const WCHAR fmtid_badchar14W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
229 '1','2','3','4','-','1','2','3','4','-',
230 '1','2','3','4','5','6','7','8','9','0','X','2','}',0};
231 static const WCHAR fmtid_badbracket2W[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
232 '1','2','3','4','-','1','2','3','4','-',
233 '1','2','3','4','5','6','7','8','9','0','1','2','X',0};
234 static const WCHAR fmtid_spaceW[] = {' ','{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
235 '1','2','3','4','-','1','2','3','4','-',
236 '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
237 static const WCHAR fmtid_spaceendW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
238 '1','2','3','4','-','1','2','3','4','-',
239 '1','2','3','4','5','6','7','8','9','0','1','2','}',' ',0};
240 static const WCHAR fmtid_spacesendW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
241 '1','2','3','4','-','1','2','3','4','-',
242 '1','2','3','4','5','6','7','8','9','0','1','2','}',' ',' ',' ',0};
243 static const WCHAR fmtid_nopidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
244 '1','2','3','4','-','1','2','3','4','-',
245 '1','2','3','4','5','6','7','8','9','0','1','2','}',0};
246 static const WCHAR fmtid_badpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
247 '1','2','3','4','-','1','2','3','4','-',
248 '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','D','E','A','D',0};
249 static const WCHAR fmtid_adjpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
250 '1','2','3','4','-','1','2','3','4','-',
251 '1','2','3','4','5','6','7','8','9','0','1','2','}','1','3','5','7','9',0};
252 static const WCHAR fmtid_spacespidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
253 '1','2','3','4','-','1','2','3','4','-',
254 '1','2','3','4','5','6','7','8','9','0','1','2','}',' ',' ',' ','1','3','5','7','9',0};
255 static const WCHAR fmtid_negpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
256 '1','2','3','4','-','1','2','3','4','-',
257 '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','-','1','3','5','7','9',0};
258 static const WCHAR fmtid_negnegpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
259 '1','2','3','4','-','1','2','3','4','-',
260 '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','-','-','1','3','5','7','9',0};
261 static const WCHAR fmtid_negnegnegpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
262 '1','2','3','4','-','1','2','3','4','-',
263 '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','-','-','-','1','3','5','7','9',0};
264 static const WCHAR fmtid_negspacepidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
265 '1','2','3','4','-','1','2','3','4','-',
266 '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','-',' ','1','3','5','7','9',0};
267 static const WCHAR fmtid_negspacenegpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
268 '1','2','3','4','-','1','2','3','4','-',
269 '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','-',' ','-','1','3','5','7','9',0};
270 static const WCHAR fmtid_negspacespidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
271 '1','2','3','4','-','1','2','3','4','-',
272 '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','-',' ','-',' ','-','1','3','5','7','9',0};
273 static const WCHAR fmtid_pospidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
274 '1','2','3','4','-','1','2','3','4','-',
275 '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','+','1','3','5','7','9',0};
276 static const WCHAR fmtid_posnegpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
277 '1','2','3','4','-','1','2','3','4','-',
278 '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','+','-','+','-','1','3','5','7','9',0};
279 static const WCHAR fmtid_symbolpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
280 '1','2','3','4','-','1','2','3','4','-',
281 '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','+','/','$','-','1','3','5','7','9',0};
282 static const WCHAR fmtid_letterpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
283 '1','2','3','4','-','1','2','3','4','-',
284 '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','A','B','C','D','1','3','5','7','9',0};
285 static const WCHAR fmtid_spacepadpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
286 '1','2','3','4','-','1','2','3','4','-',
287 '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','1','3','5','7','9',' ',' ',' ',0};
288 static const WCHAR fmtid_spacemixpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
289 '1','2','3','4','-','1','2','3','4','-',
290 '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','1',' ','3',' ','5','7','9',' ',' ',' ',0};
291 static const WCHAR fmtid_tabpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
292 '1','2','3','4','-','1','2','3','4','-',
293 '1','2','3','4','5','6','7','8','9','0','1','2','}','\t','1','3','5','7','9',0};
294 static const WCHAR fmtid_hexpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
295 '1','2','3','4','-','1','2','3','4','-',
296 '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','0','x','D','E','A','D',0};
297 static const WCHAR fmtid_mixedpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
298 '1','2','3','4','-','1','2','3','4','-',
299 '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','A','9','B','5','C','3','D','1',0};
300 static const WCHAR fmtid_overflowpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
301 '1','2','3','4','-','1','2','3','4','-',
302 '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','1','2','3','4','5','6','7','8','9','0','1',0};
303 static const WCHAR fmtid_commapidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
304 '1','2','3','4','-','1','2','3','4','-',
305 '1','2','3','4','5','6','7','8','9','0','1','2','}',',','1','3','5','7','9',0};
306 static const WCHAR fmtid_commaspidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
307 '1','2','3','4','-','1','2','3','4','-',
308 '1','2','3','4','5','6','7','8','9','0','1','2','}',',',',',',','1','3','5','7','9',0};
309 static const WCHAR fmtid_commaspacepidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
310 '1','2','3','4','-','1','2','3','4','-',
311 '1','2','3','4','5','6','7','8','9','0','1','2','}',',',' ','1','3','5','7','9',0};
312 static const WCHAR fmtid_spacecommapidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
313 '1','2','3','4','-','1','2','3','4','-',
314 '1','2','3','4','5','6','7','8','9','0','1','2','}',' ',',','1','3','5','7','9',0};
315 static const WCHAR fmtid_spccommaspcpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
316 '1','2','3','4','-','1','2','3','4','-',
317 '1','2','3','4','5','6','7','8','9','0','1','2','}',' ',',',' ','1','3','5','7','9',0};
318 static const WCHAR fmtid_spacescommaspidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
319 '1','2','3','4','-','1','2','3','4','-',
320 '1','2','3','4','5','6','7','8','9','0','1','2','}',' ',',',' ',',','1','3','5','7','9',0};
321 static const WCHAR fmtid_commanegpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
322 '1','2','3','4','-','1','2','3','4','-',
323 '1','2','3','4','5','6','7','8','9','0','1','2','}',',','-','1','3','5','7','9',0};
324 static const WCHAR fmtid_spccommanegpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
325 '1','2','3','4','-','1','2','3','4','-',
326 '1','2','3','4','5','6','7','8','9','0','1','2','}',' ',',','-','1','3','5','7','9',0};
327 static const WCHAR fmtid_commaspcnegpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
328 '1','2','3','4','-','1','2','3','4','-',
329 '1','2','3','4','5','6','7','8','9','0','1','2','}',',',' ','-','1','3','5','7','9',0};
330 static const WCHAR fmtid_spccommaspcnegpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
331 '1','2','3','4','-','1','2','3','4','-',
332 '1','2','3','4','5','6','7','8','9','0','1','2','}',' ',',',' ','-','1','3','5','7','9',0};
333 static const WCHAR fmtid_commanegspcpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
334 '1','2','3','4','-','1','2','3','4','-',
335 '1','2','3','4','5','6','7','8','9','0','1','2','}',',','-',' ','1','3','5','7','9',0};
336 static const WCHAR fmtid_negcommapidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
337 '1','2','3','4','-','1','2','3','4','-',
338 '1','2','3','4','5','6','7','8','9','0','1','2','}','-',',','1','3','5','7','9',0};
339 static const WCHAR fmtid_normalpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
340 '1','2','3','4','-','1','2','3','4','-',
341 '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','1','3','5','7','9',0};
342 static const WCHAR fmtid_udigitW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-',
343 '1','2','3','4','-','1','2','3','4','-',
344 '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','1','2','3',0x661,'5','7','9',0};
345 PROPERTYKEY out_init = {GUID_MEMBERS(dummy_guid), 0xdeadbeef};
346 PROPERTYKEY out;
347 HRESULT ret;
349 const struct
351 LPCWSTR pwzString;
352 PROPERTYKEY *pkey;
353 HRESULT hr_expect;
354 PROPERTYKEY pkey_expect;
355 } testcases[] =
357 {NULL, NULL, E_POINTER},
358 {NULL, &out, E_POINTER, {GUID_MEMBERS(out_init.fmtid), out_init.pid}},
359 {emptyW, NULL, E_POINTER},
360 {emptyW, &out, E_INVALIDARG, {GUID_MEMBERS(GUID_NULL), 0}},
361 {fmtid_clsidW, &out, E_INVALIDARG, {GUID_MEMBERS(GUID_NULL), 0}},
362 {fmtid_truncatedW, &out, E_INVALIDARG, { {0x12345678,0x1234,0x1234,{0,0,0,0,0,0,0,0}}, 0}},
363 {fmtid_nobracketsW, &out, E_INVALIDARG, {GUID_MEMBERS(GUID_NULL), 0}},
364 {fmtid_badbracketW, &out, E_INVALIDARG, {GUID_MEMBERS(GUID_NULL), 0}},
365 {fmtid_badcharW, &out, E_INVALIDARG, {GUID_MEMBERS(GUID_NULL), 0}},
366 {fmtid_badchar2W, &out, E_INVALIDARG, {GUID_MEMBERS(GUID_NULL), 0}},
367 {fmtid_baddashW, &out, E_INVALIDARG, { {0x12345678,0,0,{0,0,0,0,0,0,0,0}}, 0}},
368 {fmtid_badchar3W, &out, E_INVALIDARG, { {0x12345678,0,0,{0,0,0,0,0,0,0,0}}, 0}},
369 {fmtid_badchar4W, &out, E_INVALIDARG, { {0x12345678,0,0,{0,0,0,0,0,0,0,0}}, 0}},
370 {fmtid_baddash2W, &out, E_INVALIDARG, { {0x12345678,0,0,{0,0,0,0,0,0,0,0}}, 0}},
371 {fmtid_badchar5W, &out, E_INVALIDARG, { {0x12345678,0x1234,0,{0,0,0,0,0,0,0,0}}, 0}},
372 {fmtid_badchar6W, &out, E_INVALIDARG, { {0x12345678,0x1234,0,{0,0,0,0,0,0,0,0}}, 0}},
373 {fmtid_baddash3W, &out, E_INVALIDARG, { {0x12345678,0x1234,0,{0,0,0,0,0,0,0,0}}, 0}},
374 {fmtid_badchar7W, &out, E_INVALIDARG, { {0x12345678,0x1234,0x1234,{0,0,0,0,0,0,0,0}}, 0}},
375 {fmtid_badchar8W, &out, E_INVALIDARG, { {0x12345678,0x1234,0x1234,{0x12,0,0,0,0,0,0,0}}, 0}},
376 {fmtid_baddash4W, &out, E_INVALIDARG, { {0x12345678,0x1234,0x1234,{0x12,0,0,0,0,0,0,0}}, 0}},
377 {fmtid_badchar9W, &out, E_INVALIDARG, { {0x12345678,0x1234,0x1234,{0x12,0x34,0,0,0,0,0,0}}, 0}},
378 {fmtid_badchar9_adjW, &out, E_INVALIDARG, { {0x12345678,0x1234,0x1234,{0x12,0x34,0,0,0,0,0,0}}, 0}},
379 {fmtid_badchar10W, &out, E_INVALIDARG, { {0x12345678,0x1234,0x1234,{0x12,0x34,0x12,0,0,0,0,0}}, 0}},
380 {fmtid_badchar11W, &out, E_INVALIDARG, { {0x12345678,0x1234,0x1234,{0x12,0x34,0x12,0x34,0,0,0,0}}, 0}},
381 {fmtid_badchar12W, &out, E_INVALIDARG, { {0x12345678,0x1234,0x1234,{0x12,0x34,0x12,0x34,0x56,0,0,0}}, 0}},
382 {fmtid_badchar13W, &out, E_INVALIDARG, { {0x12345678,0x1234,0x1234,{0x12,0x34,0x12,0x34,0x56,0x78,0,0}}, 0}},
383 {fmtid_badchar14W, &out, E_INVALIDARG, { {0x12345678,0x1234,0x1234,{0x12,0x34,0x12,0x34,0x56,0x78,0x90,0}}, 0}},
384 {fmtid_badbracket2W, &out, E_INVALIDARG, { {0x12345678,0x1234,0x1234,{0x12,0x34,0x12,0x34,0x56,0x78,0x90,0x00}}, 0 }},
385 {fmtid_spaceW, &out, E_INVALIDARG, {GUID_MEMBERS(GUID_NULL), 0 }},
386 {fmtid_spaceendW, &out, E_INVALIDARG, {GUID_MEMBERS(expect_guid), 0}},
387 {fmtid_spacesendW, &out, E_INVALIDARG, {GUID_MEMBERS(expect_guid), 0}},
388 {fmtid_nopidW, &out, E_INVALIDARG, {GUID_MEMBERS(expect_guid), 0}},
389 {fmtid_badpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}},
390 {fmtid_adjpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 13579}},
391 {fmtid_spacespidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 13579}},
392 {fmtid_negpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 13579}},
393 {fmtid_negnegpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 4294953717U}},
394 {fmtid_negnegnegpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}},
395 {fmtid_negspacepidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 13579}},
396 {fmtid_negspacenegpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 4294953717U}},
397 {fmtid_negspacespidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}},
398 {fmtid_pospidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}},
399 {fmtid_posnegpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}},
400 {fmtid_symbolpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}},
401 {fmtid_letterpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}},
402 {fmtid_spacepadpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 13579}},
403 {fmtid_spacemixpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 1}},
404 {fmtid_tabpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}},
405 {fmtid_hexpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}},
406 {fmtid_mixedpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}},
407 {fmtid_overflowpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 3755744309U}},
408 {fmtid_commapidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 13579}},
409 {fmtid_commaspidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}},
410 {fmtid_commaspacepidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 13579}},
411 {fmtid_spacecommapidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 13579}},
412 {fmtid_spccommaspcpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 13579}},
413 {fmtid_spacescommaspidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}},
414 {fmtid_commanegpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 4294953717U}},
415 {fmtid_spccommanegpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 4294953717U}},
416 {fmtid_commaspcnegpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 4294953717U}},
417 {fmtid_spccommaspcnegpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 4294953717U}},
418 {fmtid_commanegspcpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0U}},
419 {fmtid_negcommapidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}},
420 {fmtid_normalpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 13579}},
421 {fmtid_udigitW, &out, S_OK, {GUID_MEMBERS(expect_guid), 123}},
424 int i;
426 for (i = 0; i < ARRAY_SIZE(testcases); i++)
428 if (testcases[i].pkey)
429 *testcases[i].pkey = out_init;
431 ret = PSPropertyKeyFromString(testcases[i].pwzString, testcases[i].pkey);
432 ok(ret == testcases[i].hr_expect,
433 "[%d] Expected PSPropertyKeyFromString to return 0x%08x, got 0x%08x\n",
434 i, testcases[i].hr_expect, ret);
436 if (testcases[i].pkey)
438 ok(IsEqualGUID(&testcases[i].pkey->fmtid, &testcases[i].pkey_expect.fmtid),
439 "[%d] Expected GUID %s, got %s\n",
440 i, wine_dbgstr_guid(&testcases[i].pkey_expect.fmtid), wine_dbgstr_guid(&testcases[i].pkey->fmtid));
441 ok(testcases[i].pkey->pid == testcases[i].pkey_expect.pid,
442 "[%d] Expected property ID %u, got %u\n",
443 i, testcases[i].pkey_expect.pid, testcases[i].pkey->pid);
448 static void test_PSRefreshPropertySchema(void)
450 HRESULT ret;
452 ret = PSRefreshPropertySchema();
453 todo_wine
454 ok(ret == CO_E_NOTINITIALIZED,
455 "Expected PSRefreshPropertySchema to return CO_E_NOTINITIALIZED, got 0x%08x\n", ret);
457 CoInitialize(NULL);
459 ret = PSRefreshPropertySchema();
460 ok(ret == S_OK,
461 "Expected PSRefreshPropertySchema to return S_OK, got 0x%08x\n", ret);
463 CoUninitialize();
466 static void test_InitPropVariantFromGUIDAsString(void)
468 PROPVARIANT propvar;
469 VARIANT var;
470 HRESULT hres;
471 int i;
473 const struct {
474 REFGUID guid;
475 const WCHAR *str;
476 } testcases[] = {
477 {&IID_NULL, L"{00000000-0000-0000-0000-000000000000}" },
478 {&dummy_guid, L"{DEADBEEF-DEAD-BEEF-DEAD-BEEFCAFEBABE}" },
481 hres = InitPropVariantFromGUIDAsString(NULL, &propvar);
482 ok(hres == E_FAIL, "InitPropVariantFromGUIDAsString returned %x\n", hres);
484 if(0) {
485 /* Returns strange data on Win7, crashes on older systems */
486 InitVariantFromGUIDAsString(NULL, &var);
488 /* Crashes on windows */
489 InitPropVariantFromGUIDAsString(&IID_NULL, NULL);
490 InitVariantFromGUIDAsString(&IID_NULL, NULL);
493 for(i=0; i < ARRAY_SIZE(testcases); i++) {
494 memset(&propvar, 0, sizeof(PROPVARIANT));
495 hres = InitPropVariantFromGUIDAsString(testcases[i].guid, &propvar);
496 ok(hres == S_OK, "%d) InitPropVariantFromGUIDAsString returned %x\n", i, hres);
497 ok(propvar.vt == VT_LPWSTR, "%d) propvar.vt = %d\n", i, propvar.vt);
498 ok(!lstrcmpW(propvar.u.pwszVal, testcases[i].str), "%d) propvar.u.pwszVal = %s\n",
499 i, wine_dbgstr_w(propvar.u.pwszVal));
500 CoTaskMemFree(propvar.u.pwszVal);
502 memset(&var, 0, sizeof(VARIANT));
503 hres = InitVariantFromGUIDAsString(testcases[i].guid, &var);
504 ok(hres == S_OK, "%d) InitVariantFromGUIDAsString returned %x\n", i, hres);
505 ok(V_VT(&var) == VT_BSTR, "%d) V_VT(&var) = %d\n", i, V_VT(&var));
506 ok(SysStringLen(V_BSTR(&var)) == 38, "SysStringLen returned %d\n",
507 SysStringLen(V_BSTR(&var)));
508 ok(!lstrcmpW(V_BSTR(&var), testcases[i].str), "%d) V_BSTR(&var) = %s\n",
509 i, wine_dbgstr_w(V_BSTR(&var)));
510 VariantClear(&var);
514 static void test_InitPropVariantFromBuffer(void)
516 static const char data_in[] = "test";
517 PROPVARIANT propvar;
518 VARIANT var;
519 HRESULT hres;
520 void *data_out;
521 LONG size;
523 hres = InitPropVariantFromBuffer(NULL, 0, &propvar);
524 ok(hres == S_OK, "InitPropVariantFromBuffer returned %x\n", hres);
525 ok(propvar.vt == (VT_VECTOR|VT_UI1), "propvar.vt = %d\n", propvar.vt);
526 ok(propvar.u.caub.cElems == 0, "cElems = %d\n", propvar.u.caub.cElems == 0);
527 PropVariantClear(&propvar);
529 hres = InitPropVariantFromBuffer(data_in, 4, &propvar);
530 ok(hres == S_OK, "InitPropVariantFromBuffer returned %x\n", hres);
531 ok(propvar.vt == (VT_VECTOR|VT_UI1), "propvar.vt = %d\n", propvar.vt);
532 ok(propvar.u.caub.cElems == 4, "cElems = %d\n", propvar.u.caub.cElems == 0);
533 ok(!memcmp(propvar.u.caub.pElems, data_in, 4), "Data inside array is incorrect\n");
534 PropVariantClear(&propvar);
536 hres = InitVariantFromBuffer(NULL, 0, &var);
537 ok(hres == S_OK, "InitVariantFromBuffer returned %x\n", hres);
538 ok(V_VT(&var) == (VT_ARRAY|VT_UI1), "V_VT(&var) = %d\n", V_VT(&var));
539 size = SafeArrayGetDim(V_ARRAY(&var));
540 ok(size == 1, "SafeArrayGetDim returned %d\n", size);
541 hres = SafeArrayGetLBound(V_ARRAY(&var), 1, &size);
542 ok(hres == S_OK, "SafeArrayGetLBound returned %x\n", hres);
543 ok(size == 0, "LBound = %d\n", size);
544 hres = SafeArrayGetUBound(V_ARRAY(&var), 1, &size);
545 ok(hres == S_OK, "SafeArrayGetUBound returned %x\n", hres);
546 ok(size == -1, "UBound = %d\n", size);
547 VariantClear(&var);
549 hres = InitVariantFromBuffer(data_in, 4, &var);
550 ok(hres == S_OK, "InitVariantFromBuffer returned %x\n", hres);
551 ok(V_VT(&var) == (VT_ARRAY|VT_UI1), "V_VT(&var) = %d\n", V_VT(&var));
552 size = SafeArrayGetDim(V_ARRAY(&var));
553 ok(size == 1, "SafeArrayGetDim returned %d\n", size);
554 hres = SafeArrayGetLBound(V_ARRAY(&var), 1, &size);
555 ok(hres == S_OK, "SafeArrayGetLBound returned %x\n", hres);
556 ok(size == 0, "LBound = %d\n", size);
557 hres = SafeArrayGetUBound(V_ARRAY(&var), 1, &size);
558 ok(hres == S_OK, "SafeArrayGetUBound returned %x\n", hres);
559 ok(size == 3, "UBound = %d\n", size);
560 hres = SafeArrayAccessData(V_ARRAY(&var), &data_out);
561 ok(hres == S_OK, "SafeArrayAccessData failed %x\n", hres);
562 ok(!memcmp(data_in, data_out, 4), "Data inside safe array is incorrect\n");
563 hres = SafeArrayUnaccessData(V_ARRAY(&var));
564 ok(hres == S_OK, "SafeArrayUnaccessData failed %x\n", hres);
565 VariantClear(&var);
568 static void test_PropVariantToGUID(void)
570 PROPVARIANT propvar;
571 VARIANT var;
572 GUID guid;
573 HRESULT hres;
575 hres = InitPropVariantFromGUIDAsString(&IID_NULL, &propvar);
576 ok(hres == S_OK, "InitPropVariantFromGUIDAsString failed %x\n", hres);
578 hres = PropVariantToGUID(&propvar, &guid);
579 ok(hres == S_OK, "PropVariantToGUID failed %x\n", hres);
580 ok(IsEqualGUID(&IID_NULL, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid));
581 PropVariantClear(&propvar);
583 hres = InitPropVariantFromGUIDAsString(&dummy_guid, &propvar);
584 ok(hres == S_OK, "InitPropVariantFromGUIDAsString failed %x\n", hres);
586 hres = PropVariantToGUID(&propvar, &guid);
587 ok(hres == S_OK, "PropVariantToGUID failed %x\n", hres);
588 ok(IsEqualGUID(&dummy_guid, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid));
590 ok(propvar.vt == VT_LPWSTR, "incorrect PROPVARIANT type: %d\n", propvar.vt);
591 propvar.u.pwszVal[1] = 'd';
592 propvar.u.pwszVal[2] = 'E';
593 propvar.u.pwszVal[3] = 'a';
594 hres = PropVariantToGUID(&propvar, &guid);
595 ok(hres == S_OK, "PropVariantToGUID failed %x\n", hres);
596 ok(IsEqualGUID(&dummy_guid, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid));
598 propvar.u.pwszVal[1] = 'z';
599 hres = PropVariantToGUID(&propvar, &guid);
600 ok(hres == E_INVALIDARG, "PropVariantToGUID returned %x\n", hres);
601 PropVariantClear(&propvar);
604 hres = InitVariantFromGUIDAsString(&IID_NULL, &var);
605 ok(hres == S_OK, "InitVariantFromGUIDAsString failed %x\n", hres);
607 hres = VariantToGUID(&var, &guid);
608 ok(hres == S_OK, "VariantToGUID failed %x\n", hres);
609 ok(IsEqualGUID(&IID_NULL, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid));
610 VariantClear(&var);
612 hres = InitVariantFromGUIDAsString(&dummy_guid, &var);
613 ok(hres == S_OK, "InitVariantFromGUIDAsString failed %x\n", hres);
615 hres = VariantToGUID(&var, &guid);
616 ok(hres == S_OK, "VariantToGUID failed %x\n", hres);
617 ok(IsEqualGUID(&dummy_guid, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid));
619 ok(V_VT(&var) == VT_BSTR, "incorrect VARIANT type: %d\n", V_VT(&var));
620 V_BSTR(&var)[1] = 'z';
621 hres = VariantToGUID(&var, &guid);
622 ok(hres == E_FAIL, "VariantToGUID returned %x\n", hres);
624 V_BSTR(&var)[1] = 'd';
625 propvar.vt = V_VT(&var);
626 propvar.u.bstrVal = V_BSTR(&var);
627 V_VT(&var) = VT_EMPTY;
628 hres = PropVariantToGUID(&propvar, &guid);
629 ok(hres == S_OK, "PropVariantToGUID failed %x\n", hres);
630 ok(IsEqualGUID(&dummy_guid, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid));
631 PropVariantClear(&propvar);
633 memset(&guid, 0, sizeof(guid));
634 InitPropVariantFromCLSID(&dummy_guid, &propvar);
635 hres = PropVariantToGUID(&propvar, &guid);
636 ok(hres == S_OK, "PropVariantToGUID failed %x\n", hres);
637 ok(IsEqualGUID(&dummy_guid, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid));
638 PropVariantClear(&propvar);
641 static void test_PropVariantToStringAlloc(void)
643 PROPVARIANT prop;
644 WCHAR *str;
645 HRESULT hres;
647 prop.vt = VT_NULL;
648 hres = PropVariantToStringAlloc(&prop, &str);
649 ok(hres == S_OK, "returned %x\n", hres);
650 ok(!lstrcmpW(str, emptyW), "got %s\n", wine_dbgstr_w(str));
651 CoTaskMemFree(str);
653 prop.vt = VT_LPSTR;
654 prop.u.pszVal = CoTaskMemAlloc(strlen(topic)+1);
655 strcpy(prop.u.pszVal, topic);
656 hres = PropVariantToStringAlloc(&prop, &str);
657 ok(hres == S_OK, "returned %x\n", hres);
658 ok(!lstrcmpW(str, topicW), "got %s\n", wine_dbgstr_w(str));
659 CoTaskMemFree(str);
660 PropVariantClear(&prop);
662 prop.vt = VT_EMPTY;
663 hres = PropVariantToStringAlloc(&prop, &str);
664 ok(hres == S_OK, "returned %x\n", hres);
665 ok(!lstrcmpW(str, emptyW), "got %s\n", wine_dbgstr_w(str));
666 CoTaskMemFree(str);
669 static void test_PropVariantCompare(void)
671 PROPVARIANT empty, null, emptyarray, i2_0, i2_2, i4_large, i4_largeneg, i4_2, str_2, str_02, str_b;
672 PROPVARIANT clsid_null, clsid, clsid2, r4_0, r4_2, r8_0, r8_2;
673 INT res;
674 static const WCHAR str_2W[] = {'2', 0};
675 static const WCHAR str_02W[] = {'0', '2', 0};
676 static const WCHAR str_bW[] = {'b', 0};
677 SAFEARRAY emptysafearray;
679 PropVariantInit(&empty);
680 PropVariantInit(&null);
681 PropVariantInit(&emptyarray);
682 PropVariantInit(&i2_0);
683 PropVariantInit(&i2_2);
684 PropVariantInit(&i4_large);
685 PropVariantInit(&i4_largeneg);
686 PropVariantInit(&i4_2);
687 PropVariantInit(&str_2);
688 PropVariantInit(&str_b);
690 empty.vt = VT_EMPTY;
691 null.vt = VT_NULL;
692 emptyarray.vt = VT_ARRAY | VT_I4;
693 emptyarray.u.parray = &emptysafearray;
694 emptysafearray.cDims = 1;
695 emptysafearray.fFeatures = FADF_FIXEDSIZE;
696 emptysafearray.cbElements = 4;
697 emptysafearray.cLocks = 0;
698 emptysafearray.pvData = NULL;
699 emptysafearray.rgsabound[0].cElements = 0;
700 emptysafearray.rgsabound[0].lLbound = 0;
701 i2_0.vt = VT_I2;
702 i2_0.u.iVal = 0;
703 i2_2.vt = VT_I2;
704 i2_2.u.iVal = 2;
705 i4_large.vt = VT_I4;
706 i4_large.u.lVal = 65536;
707 i4_largeneg.vt = VT_I4;
708 i4_largeneg.u.lVal = -65536;
709 i4_2.vt = VT_I4;
710 i4_2.u.lVal = 2;
711 str_2.vt = VT_BSTR;
712 str_2.u.bstrVal = SysAllocString(str_2W);
713 str_02.vt = VT_BSTR;
714 str_02.u.bstrVal = SysAllocString(str_02W);
715 str_b.vt = VT_BSTR;
716 str_b.u.bstrVal = SysAllocString(str_bW);
717 clsid_null.vt = VT_CLSID;
718 clsid_null.u.puuid = NULL;
719 clsid.vt = VT_CLSID;
720 clsid.u.puuid = (GUID *)&dummy_guid;
721 clsid2.vt = VT_CLSID;
722 clsid2.u.puuid = (GUID *)&GUID_NULL;
723 r4_0.vt = VT_R4;
724 r4_0.u.fltVal = 0.0f;
725 r4_2.vt = VT_R4;
726 r4_2.u.fltVal = 2.0f;
727 r8_0.vt = VT_R8;
728 r8_0.u.dblVal = 0.0;
729 r8_2.vt = VT_R8;
730 r8_2.u.dblVal = 2.0;
732 res = PropVariantCompareEx(&empty, &empty, 0, 0);
733 ok(res == 0, "res=%i\n", res);
735 res = PropVariantCompareEx(&empty, &null, 0, 0);
736 ok(res == 0, "res=%i\n", res);
738 res = PropVariantCompareEx(&null, &emptyarray, 0, 0);
739 ok(res == 0, "res=%i\n", res);
741 res = PropVariantCompareEx(&null, &i2_0, 0, 0);
742 ok(res == -1, "res=%i\n", res);
744 res = PropVariantCompareEx(&i2_0, &null, 0, 0);
745 ok(res == 1, "res=%i\n", res);
747 res = PropVariantCompareEx(&null, &i2_0, 0, PVCF_TREATEMPTYASGREATERTHAN);
748 ok(res == 1, "res=%i\n", res);
750 res = PropVariantCompareEx(&i2_0, &null, 0, PVCF_TREATEMPTYASGREATERTHAN);
751 ok(res == -1, "res=%i\n", res);
753 res = PropVariantCompareEx(&i2_2, &i2_0, 0, 0);
754 ok(res == 1, "res=%i\n", res);
756 res = PropVariantCompareEx(&i2_0, &i2_2, 0, 0);
757 ok(res == -1, "res=%i\n", res);
759 /* Always return -1 if second value cannot be converted to first type */
760 res = PropVariantCompareEx(&i2_0, &i4_large, 0, 0);
761 ok(res == -1, "res=%i\n", res);
763 res = PropVariantCompareEx(&i2_0, &i4_largeneg, 0, 0);
764 ok(res == -1, "res=%i\n", res);
766 res = PropVariantCompareEx(&i4_large, &i2_0, 0, 0);
767 ok(res == 1, "res=%i\n", res);
769 res = PropVariantCompareEx(&i4_largeneg, &i2_0, 0, 0);
770 ok(res == -1, "res=%i\n", res);
772 res = PropVariantCompareEx(&i2_2, &i4_2, 0, 0);
773 ok(res == 0, "res=%i\n", res);
775 res = PropVariantCompareEx(&i2_2, &str_2, 0, 0);
776 ok(res == 0, "res=%i\n", res);
778 res = PropVariantCompareEx(&i2_2, &str_02, 0, 0);
779 ok(res == 0, "res=%i\n", res);
781 res = PropVariantCompareEx(&str_2, &i2_2, 0, 0);
782 todo_wine ok(res == 0, "res=%i\n", res);
784 res = PropVariantCompareEx(&str_02, &i2_2, 0, 0);
785 ok(res == -1, "res=%i\n", res);
787 res = PropVariantCompareEx(&str_02, &str_2, 0, 0);
788 ok(res == -1, "res=%i\n", res);
790 res = PropVariantCompareEx(&str_02, &str_b, 0, 0);
791 ok(res == -1, "res=%i\n", res);
793 res = PropVariantCompareEx(&str_2, &str_02, 0, 0);
794 ok(res == 1, "res=%i\n", res);
796 res = PropVariantCompareEx(&i4_large, &str_b, 0, 0);
797 todo_wine ok(res == -5 /* ??? */, "res=%i\n", res);
799 /* VT_CLSID */
800 res = PropVariantCompareEx(&clsid_null, &clsid_null, 0, 0);
801 ok(res == 0, "res=%i\n", res);
803 res = PropVariantCompareEx(&clsid_null, &clsid_null, 0, PVCF_TREATEMPTYASGREATERTHAN);
804 ok(res == 0, "res=%i\n", res);
806 res = PropVariantCompareEx(&clsid, &clsid, 0, 0);
807 ok(res == 0, "res=%i\n", res);
809 res = PropVariantCompareEx(&clsid, &clsid2, 0, 0);
810 ok(res == 1, "res=%i\n", res);
812 res = PropVariantCompareEx(&clsid2, &clsid, 0, 0);
813 ok(res == -1, "res=%i\n", res);
815 res = PropVariantCompareEx(&clsid_null, &clsid, 0, 0);
816 ok(res == -1, "res=%i\n", res);
818 res = PropVariantCompareEx(&clsid, &clsid_null, 0, 0);
819 ok(res == 1, "res=%i\n", res);
821 res = PropVariantCompareEx(&clsid_null, &clsid, 0, PVCF_TREATEMPTYASGREATERTHAN);
822 ok(res == 1, "res=%i\n", res);
824 res = PropVariantCompareEx(&clsid, &clsid_null, 0, PVCF_TREATEMPTYASGREATERTHAN);
825 ok(res == -1, "res=%i\n", res);
827 /* VT_R4/VT_R8 */
828 res = PropVariantCompareEx(&r4_0, &r8_0, 0, 0);
829 todo_wine
830 ok(res == 0, "res=%i\n", res);
832 res = PropVariantCompareEx(&r4_0, &r4_0, 0, 0);
833 ok(res == 0, "res=%i\n", res);
835 res = PropVariantCompareEx(&r4_0, &r4_2, 0, 0);
836 ok(res == -1, "res=%i\n", res);
838 res = PropVariantCompareEx(&r4_2, &r4_0, 0, 0);
839 ok(res == 1, "res=%i\n", res);
841 res = PropVariantCompareEx(&r8_0, &r8_0, 0, 0);
842 ok(res == 0, "res=%i\n", res);
844 res = PropVariantCompareEx(&r8_0, &r8_2, 0, 0);
845 ok(res == -1, "res=%i\n", res);
847 res = PropVariantCompareEx(&r8_2, &r8_0, 0, 0);
848 ok(res == 1, "res=%i\n", res);
850 SysFreeString(str_2.u.bstrVal);
851 SysFreeString(str_02.u.bstrVal);
852 SysFreeString(str_b.u.bstrVal);
855 static void test_intconversions(void)
857 PROPVARIANT propvar;
858 SHORT sval;
859 USHORT usval;
860 LONG lval;
861 ULONG ulval;
862 LONGLONG llval;
863 ULONGLONG ullval;
864 HRESULT hr;
866 propvar.vt = 0xdead;
867 hr = PropVariantClear(&propvar);
868 ok (FAILED(hr), "PropVariantClear fails on invalid vt.\n");
870 propvar.vt = VT_I8;
871 PropVariantClear(&propvar);
873 propvar.vt = VT_I8;
874 propvar.u.hVal.QuadPart = (ULONGLONG)1 << 63;
876 hr = PropVariantToInt64(&propvar, &llval);
877 ok(hr == S_OK, "hr=%x\n", hr);
878 ok(llval == (ULONGLONG)1 << 63, "got wrong value %s\n", wine_dbgstr_longlong(llval));
880 hr = PropVariantToUInt64(&propvar, &ullval);
881 ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
883 hr = PropVariantToInt32(&propvar, &lval);
884 ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
886 hr = PropVariantToUInt32(&propvar, &ulval);
887 ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
889 hr = PropVariantToInt16(&propvar, &sval);
890 ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
892 hr = PropVariantToUInt16(&propvar, &usval);
893 ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
895 propvar.vt = VT_UI8;
896 propvar.u.uhVal.QuadPart = 5;
898 hr = PropVariantToInt64(&propvar, &llval);
899 ok(hr == S_OK, "hr=%x\n", hr);
900 ok(llval == 5, "got wrong value %s\n", wine_dbgstr_longlong(llval));
902 hr = PropVariantToUInt64(&propvar, &ullval);
903 ok(hr == S_OK, "hr=%x\n", hr);
904 ok(ullval == 5, "got wrong value %s\n", wine_dbgstr_longlong(ullval));
906 hr = PropVariantToInt32(&propvar, &lval);
907 ok(hr == S_OK, "hr=%x\n", hr);
908 ok(lval == 5, "got wrong value %d\n", lval);
910 hr = PropVariantToUInt32(&propvar, &ulval);
911 ok(hr == S_OK, "hr=%x\n", hr);
912 ok(ulval == 5, "got wrong value %d\n", ulval);
914 hr = PropVariantToInt16(&propvar, &sval);
915 ok(hr == S_OK, "hr=%x\n", hr);
916 ok(sval == 5, "got wrong value %d\n", sval);
918 hr = PropVariantToUInt16(&propvar, &usval);
919 ok(hr == S_OK, "hr=%x\n", hr);
920 ok(usval == 5, "got wrong value %d\n", usval);
922 propvar.vt = VT_I8;
923 propvar.u.hVal.QuadPart = -5;
925 hr = PropVariantToInt64(&propvar, &llval);
926 ok(hr == S_OK, "hr=%x\n", hr);
927 ok(llval == -5, "got wrong value %s\n", wine_dbgstr_longlong(llval));
929 hr = PropVariantToUInt64(&propvar, &ullval);
930 ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
932 hr = PropVariantToInt32(&propvar, &lval);
933 ok(hr == S_OK, "hr=%x\n", hr);
934 ok(lval == -5, "got wrong value %d\n", lval);
936 hr = PropVariantToUInt32(&propvar, &ulval);
937 ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
939 hr = PropVariantToInt16(&propvar, &sval);
940 ok(hr == S_OK, "hr=%x\n", hr);
941 ok(sval == -5, "got wrong value %d\n", sval);
943 hr = PropVariantToUInt16(&propvar, &usval);
944 ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
946 propvar.vt = VT_UI4;
947 propvar.u.ulVal = 6;
949 hr = PropVariantToInt64(&propvar, &llval);
950 ok(hr == S_OK, "hr=%x\n", hr);
951 ok(llval == 6, "got wrong value %s\n", wine_dbgstr_longlong(llval));
953 propvar.vt = VT_I4;
954 propvar.u.lVal = -6;
956 hr = PropVariantToInt64(&propvar, &llval);
957 ok(hr == S_OK, "hr=%x\n", hr);
958 ok(llval == -6, "got wrong value %s\n", wine_dbgstr_longlong(llval));
960 propvar.vt = VT_UI2;
961 propvar.u.uiVal = 7;
963 hr = PropVariantToInt64(&propvar, &llval);
964 ok(hr == S_OK, "hr=%x\n", hr);
965 ok(llval == 7, "got wrong value %s\n", wine_dbgstr_longlong(llval));
967 propvar.vt = VT_I2;
968 propvar.u.iVal = -7;
970 hr = PropVariantToInt64(&propvar, &llval);
971 ok(hr == S_OK, "hr=%x\n", hr);
972 ok(llval == -7, "got wrong value %s\n", wine_dbgstr_longlong(llval));
975 static void test_PropVariantToBoolean(void)
977 static WCHAR str_0[] = {'0',0};
978 static WCHAR str_1[] = {'1',0};
979 static WCHAR str_7[] = {'7',0};
980 static WCHAR str_n7[] = {'-','7',0};
981 static WCHAR str_true[] = {'t','r','u','e',0};
982 static WCHAR str_true2[] = {'#','T','R','U','E','#',0};
983 static WCHAR str_true_case[] = {'t','R','U','e',0};
984 static WCHAR str_false[] = {'f','a','l','s','e',0};
985 static WCHAR str_false2[] = {'#','F','A','L','S','E','#',0};
986 static WCHAR str_true_space[] = {'t','r','u','e',' ',0};
987 static WCHAR str_yes[] = {'y','e','s',0};
988 PROPVARIANT propvar;
989 HRESULT hr;
990 BOOL val;
992 /* VT_BOOL */
993 propvar.vt = VT_BOOL;
994 propvar.u.boolVal = VARIANT_FALSE;
995 val = TRUE;
996 hr = PropVariantToBoolean(&propvar, &val);
997 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
998 ok(val == FALSE, "Unexpected value %d\n", val);
1000 propvar.vt = VT_BOOL;
1001 propvar.u.boolVal = 1;
1002 val = TRUE;
1003 hr = PropVariantToBoolean(&propvar, &val);
1004 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1005 ok(val == FALSE, "Unexpected value %d\n", val);
1007 propvar.vt = VT_BOOL;
1008 propvar.u.boolVal = VARIANT_TRUE;
1009 val = FALSE;
1010 hr = PropVariantToBoolean(&propvar, &val);
1011 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1012 ok(val == TRUE, "Unexpected value %d\n", val);
1014 /* VT_EMPTY */
1015 propvar.vt = VT_EMPTY;
1016 propvar.u.boolVal = VARIANT_TRUE;
1017 val = TRUE;
1018 hr = PropVariantToBoolean(&propvar, &val);
1019 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1020 ok(val == FALSE, "Unexpected value %d\n", val);
1022 /* test integer conversion */
1023 propvar.vt = VT_I4;
1024 propvar.u.lVal = 0;
1025 val = TRUE;
1026 hr = PropVariantToBoolean(&propvar, &val);
1027 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1028 ok(val == FALSE, "Unexpected value %d\n", val);
1030 propvar.vt = VT_I4;
1031 propvar.u.lVal = 1;
1032 val = FALSE;
1033 hr = PropVariantToBoolean(&propvar, &val);
1034 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1035 ok(val == TRUE, "Unexpected value %d\n", val);
1037 propvar.vt = VT_I4;
1038 propvar.u.lVal = 67;
1039 val = FALSE;
1040 hr = PropVariantToBoolean(&propvar, &val);
1041 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1042 ok(val == TRUE, "Unexpected value %d\n", val);
1044 propvar.vt = VT_I4;
1045 propvar.u.lVal = -67;
1046 val = FALSE;
1047 hr = PropVariantToBoolean(&propvar, &val);
1048 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1049 ok(val == TRUE, "Unexpected value %d\n", val);
1051 /* test string conversion */
1052 propvar.vt = VT_LPWSTR;
1053 propvar.u.pwszVal = str_0;
1054 val = TRUE;
1055 hr = PropVariantToBoolean(&propvar, &val);
1056 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1057 ok(val == FALSE, "Unexpected value %d\n", val);
1059 propvar.vt = VT_LPWSTR;
1060 propvar.u.pwszVal = str_1;
1061 val = FALSE;
1062 hr = PropVariantToBoolean(&propvar, &val);
1063 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1064 ok(val == TRUE, "Unexpected value %d\n", val);
1066 propvar.vt = VT_LPWSTR;
1067 propvar.u.pwszVal = str_7;
1068 val = FALSE;
1069 hr = PropVariantToBoolean(&propvar, &val);
1070 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1071 ok(val == TRUE, "Unexpected value %d\n", val);
1073 propvar.vt = VT_LPWSTR;
1074 propvar.u.pwszVal = str_n7;
1075 val = FALSE;
1076 hr = PropVariantToBoolean(&propvar, &val);
1077 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1078 ok(val == TRUE, "Unexpected value %d\n", val);
1080 propvar.vt = VT_LPWSTR;
1081 propvar.u.pwszVal = str_true;
1082 val = FALSE;
1083 hr = PropVariantToBoolean(&propvar, &val);
1084 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1085 ok(val == TRUE, "Unexpected value %d\n", val);
1087 propvar.vt = VT_LPWSTR;
1088 propvar.u.pwszVal = str_true_case;
1089 val = FALSE;
1090 hr = PropVariantToBoolean(&propvar, &val);
1091 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1092 ok(val == TRUE, "Unexpected value %d\n", val);
1094 propvar.vt = VT_LPWSTR;
1095 propvar.u.pwszVal = str_true2;
1096 val = FALSE;
1097 hr = PropVariantToBoolean(&propvar, &val);
1098 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1099 ok(val == TRUE, "Unexpected value %d\n", val);
1101 propvar.vt = VT_LPWSTR;
1102 propvar.u.pwszVal = str_false;
1103 val = TRUE;
1104 hr = PropVariantToBoolean(&propvar, &val);
1105 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1106 ok(val == FALSE, "Unexpected value %d\n", val);
1108 propvar.vt = VT_LPWSTR;
1109 propvar.u.pwszVal = str_false2;
1110 val = TRUE;
1111 hr = PropVariantToBoolean(&propvar, &val);
1112 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1113 ok(val == FALSE, "Unexpected value %d\n", val);
1115 propvar.vt = VT_LPWSTR;
1116 propvar.u.pwszVal = str_true_space;
1117 val = TRUE;
1118 hr = PropVariantToBoolean(&propvar, &val);
1119 ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#x.\n", hr);
1120 ok(val == FALSE, "Unexpected value %d\n", val);
1122 propvar.vt = VT_LPWSTR;
1123 propvar.u.pwszVal = str_yes;
1124 val = TRUE;
1125 hr = PropVariantToBoolean(&propvar, &val);
1126 ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#x.\n", hr);
1127 ok(val == FALSE, "Unexpected value %d\n", val);
1129 propvar.vt = VT_LPWSTR;
1130 propvar.u.pwszVal = NULL;
1131 val = TRUE;
1132 hr = PropVariantToBoolean(&propvar, &val);
1133 ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#x.\n", hr);
1134 ok(val == FALSE, "Unexpected value %d\n", val);
1136 /* VT_LPSTR */
1137 propvar.vt = VT_LPSTR;
1138 propvar.u.pszVal = (char *)"#TruE#";
1139 val = TRUE;
1140 hr = PropVariantToBoolean(&propvar, &val);
1141 ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#x.\n", hr);
1142 ok(val == FALSE, "Unexpected value %d\n", val);
1144 propvar.vt = VT_LPSTR;
1145 propvar.u.pszVal = (char *)"#TRUE#";
1146 val = FALSE;
1147 hr = PropVariantToBoolean(&propvar, &val);
1148 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1149 ok(val == TRUE, "Unexpected value %d\n", val);
1151 propvar.vt = VT_LPSTR;
1152 propvar.u.pszVal = (char *)"tRUe";
1153 val = FALSE;
1154 hr = PropVariantToBoolean(&propvar, &val);
1155 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1156 ok(val == TRUE, "Unexpected value %d\n", val);
1158 propvar.vt = VT_LPSTR;
1159 propvar.u.pszVal = (char *)"#FALSE#";
1160 val = TRUE;
1161 hr = PropVariantToBoolean(&propvar, &val);
1162 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1163 ok(val == FALSE, "Unexpected value %d\n", val);
1165 propvar.vt = VT_LPSTR;
1166 propvar.u.pszVal = (char *)"fALSe";
1167 val = TRUE;
1168 hr = PropVariantToBoolean(&propvar, &val);
1169 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1170 ok(val == FALSE, "Unexpected value %d\n", val);
1172 propvar.vt = VT_LPSTR;
1173 propvar.u.pszVal = (char *)"1";
1174 val = FALSE;
1175 hr = PropVariantToBoolean(&propvar, &val);
1176 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1177 ok(val == TRUE, "Unexpected value %d\n", val);
1179 propvar.vt = VT_LPSTR;
1180 propvar.u.pszVal = (char *)"-1";
1181 hr = PropVariantToBoolean(&propvar, &val);
1182 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1183 ok(val == TRUE, "Unexpected value %d\n", val);
1186 static void test_PropVariantToStringWithDefault(void)
1188 PROPVARIANT propvar;
1189 static WCHAR default_value[] = {'t', 'e', 's', 't', 0};
1190 static WCHAR wstr_test2[] = {'t', 'e', 's', 't', '2', 0};
1191 static WCHAR wstr_empty[] = {0};
1192 static WCHAR wstr_space[] = {' ', 0};
1193 static CHAR str_test2[] = "test2";
1194 static CHAR str_empty[] = "";
1195 static CHAR str_space[] = " ";
1196 LPCWSTR result;
1198 propvar.vt = VT_EMPTY;
1199 result = PropVariantToStringWithDefault(&propvar, default_value);
1200 ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result));
1202 propvar.vt = VT_NULL;
1203 result = PropVariantToStringWithDefault(&propvar, default_value);
1204 ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result));
1206 propvar.vt = VT_BOOL;
1207 propvar.u.boolVal = VARIANT_TRUE;
1208 result = PropVariantToStringWithDefault(&propvar, default_value);
1209 ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result));
1211 propvar.vt = VT_I4;
1212 propvar.u.lVal = 15;
1213 result = PropVariantToStringWithDefault(&propvar, default_value);
1214 ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result));
1216 /* VT_LPWSTR */
1218 propvar.vt = VT_LPWSTR;
1219 propvar.u.pwszVal = NULL;
1220 result = PropVariantToStringWithDefault(&propvar, default_value);
1221 ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result));
1223 propvar.vt = VT_LPWSTR;
1224 propvar.u.pwszVal = wstr_empty;
1225 result = PropVariantToStringWithDefault(&propvar, default_value);
1226 ok(result == wstr_empty, "Unexpected value %s\n", wine_dbgstr_w(result));
1228 propvar.vt = VT_LPWSTR;
1229 propvar.u.pwszVal = wstr_space;
1230 result = PropVariantToStringWithDefault(&propvar, default_value);
1231 ok(result == wstr_space, "Unexpected value %s\n", wine_dbgstr_w(result));
1233 propvar.vt = VT_LPWSTR;
1234 propvar.u.pwszVal = wstr_test2;
1235 result = PropVariantToStringWithDefault(&propvar, default_value);
1236 ok(result == wstr_test2, "Unexpected value %s\n", wine_dbgstr_w(result));
1238 /* VT_LPSTR */
1240 propvar.vt = VT_LPSTR;
1241 propvar.u.pszVal = NULL;
1242 result = PropVariantToStringWithDefault(&propvar, default_value);
1243 ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result));
1245 propvar.vt = VT_LPSTR;
1246 propvar.u.pszVal = str_empty;
1247 result = PropVariantToStringWithDefault(&propvar, default_value);
1248 ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result));
1250 propvar.vt = VT_LPSTR;
1251 propvar.u.pszVal = str_space;
1252 result = PropVariantToStringWithDefault(&propvar, default_value);
1253 ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result));
1255 propvar.vt = VT_LPSTR;
1256 propvar.u.pszVal = str_test2;
1257 result = PropVariantToStringWithDefault(&propvar, default_value);
1258 ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result));
1260 /* VT_BSTR */
1262 propvar.vt = VT_BSTR;
1263 propvar.u.bstrVal = NULL;
1264 result = PropVariantToStringWithDefault(&propvar, default_value);
1265 ok(!lstrcmpW(result, wstr_empty), "Unexpected value %s\n", wine_dbgstr_w(result));
1267 propvar.vt = VT_BSTR;
1268 propvar.u.bstrVal = SysAllocString(wstr_empty);
1269 result = PropVariantToStringWithDefault(&propvar, default_value);
1270 ok(!lstrcmpW(result, wstr_empty), "Unexpected value %s\n", wine_dbgstr_w(result));
1271 SysFreeString(propvar.u.bstrVal);
1273 propvar.vt = VT_BSTR;
1274 propvar.u.bstrVal = SysAllocString(wstr_space);
1275 result = PropVariantToStringWithDefault(&propvar, default_value);
1276 ok(!lstrcmpW(result, wstr_space), "Unexpected value %s\n", wine_dbgstr_w(result));
1277 SysFreeString(propvar.u.bstrVal);
1279 propvar.vt = VT_BSTR;
1280 propvar.u.bstrVal = SysAllocString(wstr_test2);
1281 result = PropVariantToStringWithDefault(&propvar, default_value);
1282 ok(!lstrcmpW(result, wstr_test2), "Unexpected value %s\n", wine_dbgstr_w(result));
1283 SysFreeString(propvar.u.bstrVal);
1286 static void test_PropVariantChangeType_LPWSTR(void)
1288 PROPVARIANT dest, src;
1289 HRESULT hr;
1291 PropVariantInit(&dest);
1293 src.vt = VT_NULL;
1294 hr = PropVariantChangeType(&dest, &src, 0, VT_LPWSTR);
1295 ok(hr == S_OK, "hr=%x\n", hr);
1296 ok(dest.vt == VT_LPWSTR, "got %d\n", dest.vt);
1297 ok(!lstrcmpW(dest.u.pwszVal, emptyW), "got %s\n", wine_dbgstr_w(dest.u.pwszVal));
1298 PropVariantClear(&dest);
1299 PropVariantClear(&src);
1301 src.vt = VT_LPSTR;
1302 src.u.pszVal = CoTaskMemAlloc(strlen(topic)+1);
1303 strcpy(src.u.pszVal, topic);
1304 hr = PropVariantChangeType(&dest, &src, 0, VT_LPWSTR);
1305 ok(hr == S_OK, "hr=%x\n", hr);
1306 ok(dest.vt == VT_LPWSTR, "got %d\n", dest.vt);
1307 ok(!lstrcmpW(dest.u.pwszVal, topicW), "got %s\n", wine_dbgstr_w(dest.u.pwszVal));
1308 PropVariantClear(&dest);
1309 PropVariantClear(&src);
1311 src.vt = VT_LPWSTR;
1312 src.u.pwszVal = CoTaskMemAlloc( (lstrlenW(topicW)+1) * sizeof(WCHAR));
1313 lstrcpyW(src.u.pwszVal, topicW);
1314 hr = PropVariantChangeType(&dest, &src, 0, VT_LPWSTR);
1315 ok(hr == S_OK, "hr=%x\n", hr);
1316 ok(dest.vt == VT_LPWSTR, "got %d\n", dest.vt);
1317 ok(!lstrcmpW(dest.u.pwszVal, topicW), "got %s\n", wine_dbgstr_w(dest.u.pwszVal));
1318 PropVariantClear(&dest);
1319 PropVariantClear(&src);
1322 static void test_InitPropVariantFromCLSID(void)
1324 PROPVARIANT propvar;
1325 GUID clsid;
1326 HRESULT hr;
1328 memset(&propvar, 0, sizeof(propvar));
1329 propvar.vt = VT_I4;
1330 propvar.u.lVal = 15;
1332 memset(&clsid, 0xcc, sizeof(clsid));
1333 hr = InitPropVariantFromCLSID(&clsid, &propvar);
1334 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1335 ok(propvar.vt == VT_CLSID, "Unexpected type %d.\n", propvar.vt);
1336 ok(IsEqualGUID(propvar.u.puuid, &clsid), "Unexpected puuid value.\n");
1337 PropVariantClear(&propvar);
1340 static void test_PropVariantToDouble(void)
1342 PROPVARIANT propvar;
1343 double value;
1344 HRESULT hr;
1346 PropVariantInit(&propvar);
1347 propvar.vt = VT_R8;
1348 propvar.u.dblVal = 15.0;
1349 hr = PropVariantToDouble(&propvar, &value);
1350 ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr);
1351 ok(value == 15.0, "Unexpected value: %f.\n", value);
1353 PropVariantClear(&propvar);
1354 propvar.vt = VT_I4;
1355 propvar.u.lVal = 123;
1356 hr = PropVariantToDouble(&propvar, &value);
1357 ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr);
1358 ok(value == 123.0, "Unexpected value: %f.\n", value);
1360 PropVariantClear(&propvar);
1361 propvar.vt = VT_I4;
1362 propvar.u.lVal = -256;
1363 hr = PropVariantToDouble(&propvar, &value);
1364 ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr);
1365 ok(value == -256, "Unexpected value: %f\n", value);
1367 PropVariantClear(&propvar);
1368 propvar.vt = VT_I8;
1369 propvar.u.lVal = 65536;
1370 hr = PropVariantToDouble(&propvar, &value);
1371 ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr);
1372 ok(value == 65536.0, "Unexpected value: %f.\n", value);
1374 PropVariantClear(&propvar);
1375 propvar.vt = VT_I8;
1376 propvar.u.lVal = -321;
1377 hr = PropVariantToDouble(&propvar, &value);
1378 ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr);
1379 ok(value == 4294966975.0, "Unexpected value: %f.\n", value);
1381 PropVariantClear(&propvar);
1382 propvar.vt = VT_UI4;
1383 propvar.u.ulVal = 6;
1384 hr = PropVariantToDouble(&propvar, &value);
1385 ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr);
1386 ok(value == 6.0, "Unexpected value: %f.\n", value);
1388 PropVariantClear(&propvar);
1389 propvar.vt = VT_UI8;
1390 propvar.u.uhVal.QuadPart = 8;
1391 hr = PropVariantToDouble(&propvar, &value);
1392 ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr);
1393 ok(value == 8.0, "Unexpected value: %f.\n", value);
1396 static void test_PropVariantToString(void)
1398 PROPVARIANT propvar;
1399 static CHAR string[] = "Wine";
1400 static WCHAR stringW[] = {'W','i','n','e',0};
1401 WCHAR bufferW[256] = {0};
1402 HRESULT hr;
1404 PropVariantInit(&propvar);
1405 propvar.vt = VT_EMPTY;
1406 U(propvar).pwszVal = stringW;
1407 bufferW[0] = 65;
1408 hr = PropVariantToString(&propvar, bufferW, 0);
1409 ok(hr == E_INVALIDARG, "PropVariantToString should fail: 0x%08x.\n", hr);
1410 ok(!bufferW[0], "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW));
1411 memset(bufferW, 0, sizeof(bufferW));
1412 PropVariantClear(&propvar);
1414 PropVariantInit(&propvar);
1415 propvar.vt = VT_EMPTY;
1416 U(propvar).pwszVal = stringW;
1417 bufferW[0] = 65;
1418 hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW));
1419 ok(hr == S_OK, "PropVariantToString failed: 0x%08x.\n", hr);
1420 ok(!bufferW[0], "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW));
1421 memset(bufferW, 0, sizeof(bufferW));
1422 PropVariantClear(&propvar);
1424 PropVariantInit(&propvar);
1425 propvar.vt = VT_NULL;
1426 U(propvar).pwszVal = stringW;
1427 bufferW[0] = 65;
1428 hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW));
1429 ok(hr == S_OK, "PropVariantToString failed: 0x%08x.\n", hr);
1430 ok(!bufferW[0], "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW));
1431 memset(bufferW, 0, sizeof(bufferW));
1432 PropVariantClear(&propvar);
1434 PropVariantInit(&propvar);
1435 propvar.vt = VT_I4;
1436 U(propvar).lVal = 22;
1437 hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW));
1438 todo_wine ok(hr == S_OK, "PropVariantToString failed: 0x%08x.\n", hr);
1439 todo_wine ok(!lstrcmpW(bufferW, L"22"), "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW));
1440 memset(bufferW, 0, sizeof(bufferW));
1441 PropVariantClear(&propvar);
1443 PropVariantInit(&propvar);
1444 propvar.vt = VT_LPWSTR;
1445 U(propvar).pwszVal = stringW;
1446 hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW));
1447 ok(hr == S_OK, "PropVariantToString failed: 0x%08x.\n", hr);
1448 ok(!lstrcmpW(bufferW, stringW), "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW));
1449 memset(bufferW, 0, sizeof(bufferW));
1451 PropVariantInit(&propvar);
1452 propvar.vt = VT_LPSTR;
1453 U(propvar).pszVal = string;
1454 hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW));
1455 ok(hr == S_OK, "PropVariantToString failed: 0x%08x.\n", hr);
1456 ok(!lstrcmpW(bufferW, stringW), "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW));
1457 memset(bufferW, 0, sizeof(bufferW));
1459 PropVariantInit(&propvar);
1460 propvar.vt = VT_LPWSTR;
1461 U(propvar).pwszVal = stringW;
1462 hr = PropVariantToString(&propvar, bufferW, 4);
1463 ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "PropVariantToString returned: 0x%08x.\n", hr);
1464 ok(!memcmp(bufferW, stringW, 4), "got wrong string.\n");
1465 memset(bufferW, 0, sizeof(bufferW));
1467 PropVariantInit(&propvar);
1468 propvar.vt = VT_LPSTR;
1469 U(propvar).pszVal = string;
1470 hr = PropVariantToString(&propvar, bufferW, 4);
1471 ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "PropVariantToString returned: 0x%08x.\n", hr);
1472 ok(!memcmp(bufferW, stringW, 4), "got wrong string.\n");
1473 memset(bufferW, 0, sizeof(bufferW));
1475 PropVariantInit(&propvar);
1476 propvar.vt = VT_BSTR;
1477 propvar.u.bstrVal = SysAllocString(stringW);
1478 hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW));
1479 ok(hr == S_OK, "PropVariantToString failed: 0x%08x.\n", hr);
1480 ok(!lstrcmpW(bufferW, stringW), "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW));
1481 memset(bufferW, 0, sizeof(bufferW));
1482 SysFreeString(propvar.u.bstrVal);
1485 static void test_PropVariantToBuffer(void)
1487 PROPVARIANT propvar;
1488 HRESULT hr;
1489 UINT8 data[] = {1,2,3,4,5,6,7,8,9,10};
1490 INT8 data_int8[] = {1,2,3,4,5,6,7,8,9,10};
1491 SAFEARRAY *sa;
1492 SAFEARRAYBOUND sabound;
1493 void *pdata;
1494 UINT8 buffer[256];
1496 hr = InitPropVariantFromBuffer(data, 10, &propvar);
1497 ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08x.\n", hr);
1498 hr = PropVariantToBuffer(&propvar, NULL, 0); /* crash when cb isn't zero */
1499 ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08x.\n", hr);
1500 PropVariantClear(&propvar);
1502 hr = InitPropVariantFromBuffer(data, 10, &propvar);
1503 ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08x.\n", hr);
1504 hr = PropVariantToBuffer(&propvar, buffer, 10);
1505 ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08x.\n", hr);
1506 ok(!memcmp(buffer, data, 10) && !buffer[10], "got wrong buffer.\n");
1507 memset(buffer, 0, sizeof(buffer));
1508 PropVariantClear(&propvar);
1510 hr = InitPropVariantFromBuffer(data, 10, &propvar);
1511 ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08x.\n", hr);
1512 buffer[0] = 99;
1513 hr = PropVariantToBuffer(&propvar, buffer, 11);
1514 ok(hr == E_FAIL, "PropVariantToBuffer returned: 0x%08x.\n", hr);
1515 ok(buffer[0] == 99, "got wrong buffer.\n");
1516 memset(buffer, 0, sizeof(buffer));
1517 PropVariantClear(&propvar);
1519 hr = InitPropVariantFromBuffer(data, 10, &propvar);
1520 ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08x.\n", hr);
1521 hr = PropVariantToBuffer(&propvar, buffer, 9);
1522 ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08x.\n", hr);
1523 ok(!memcmp(buffer, data, 9) && !buffer[9], "got wrong buffer.\n");
1524 memset(buffer, 0, sizeof(buffer));
1525 PropVariantClear(&propvar);
1527 PropVariantInit(&propvar);
1528 propvar.vt = VT_ARRAY|VT_UI1;
1529 sabound.lLbound = 0;
1530 sabound.cElements = sizeof(data);
1531 sa = NULL;
1532 sa = SafeArrayCreate(VT_UI1, 1, &sabound);
1533 ok(sa != NULL, "SafeArrayCreate failed.\n");
1534 hr = SafeArrayAccessData(sa, &pdata);
1535 ok(hr == S_OK, "SafeArrayAccessData failed: 0x%08x.\n", hr);
1536 memcpy(pdata, data, sizeof(data));
1537 hr = SafeArrayUnaccessData(sa);
1538 ok(hr == S_OK, "SafeArrayUnaccessData failed: 0x%08x.\n", hr);
1539 U(propvar).parray = sa;
1540 buffer[0] = 99;
1541 hr = PropVariantToBuffer(&propvar, buffer, 11);
1542 todo_wine ok(hr == E_FAIL, "PropVariantToBuffer returned: 0x%08x.\n", hr);
1543 ok(buffer[0] == 99, "got wrong buffer.\n");
1544 memset(buffer, 0, sizeof(buffer));
1545 PropVariantClear(&propvar);
1547 PropVariantInit(&propvar);
1548 propvar.vt = VT_ARRAY|VT_UI1;
1549 sabound.lLbound = 0;
1550 sabound.cElements = sizeof(data);
1551 sa = NULL;
1552 sa = SafeArrayCreate(VT_UI1, 1, &sabound);
1553 ok(sa != NULL, "SafeArrayCreate failed.\n");
1554 hr = SafeArrayAccessData(sa, &pdata);
1555 ok(hr == S_OK, "SafeArrayAccessData failed: 0x%08x.\n", hr);
1556 memcpy(pdata, data, sizeof(data));
1557 hr = SafeArrayUnaccessData(sa);
1558 ok(hr == S_OK, "SafeArrayUnaccessData failed: 0x%08x.\n", hr);
1559 U(propvar).parray = sa;
1560 hr = PropVariantToBuffer(&propvar, buffer, sizeof(data));
1561 todo_wine ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08x.\n", hr);
1562 todo_wine ok(!memcmp(buffer, data, 10) && !buffer[10], "got wrong buffer.\n");
1563 memset(buffer, 0, sizeof(buffer));
1564 PropVariantClear(&propvar);
1566 PropVariantInit(&propvar);
1567 propvar.vt = VT_VECTOR|VT_I1;
1568 U(propvar).caub.pElems = CoTaskMemAlloc(sizeof(data_int8));
1569 U(propvar).caub.cElems = sizeof(data_int8);
1570 memcpy(U(propvar).caub.pElems, data_int8, sizeof(data_int8));
1571 hr = PropVariantToBuffer(&propvar, buffer, sizeof(data_int8));
1572 ok(hr == E_INVALIDARG, "PropVariantToBuffer failed: 0x%08x.\n", hr);
1573 PropVariantClear(&propvar);
1575 PropVariantInit(&propvar);
1576 propvar.vt = VT_ARRAY|VT_I1;
1577 sabound.lLbound = 0;
1578 sabound.cElements = sizeof(data_int8);
1579 sa = NULL;
1580 sa = SafeArrayCreate(VT_I1, 1, &sabound);
1581 ok(sa != NULL, "SafeArrayCreate failed.\n");
1582 hr = SafeArrayAccessData(sa, &pdata);
1583 ok(hr == S_OK, "SafeArrayAccessData failed: 0x%08x.\n", hr);
1584 memcpy(pdata, data_int8, sizeof(data_int8));
1585 hr = SafeArrayUnaccessData(sa);
1586 ok(hr == S_OK, "SafeArrayUnaccessData failed: 0x%08x.\n", hr);
1587 U(propvar).parray = sa;
1588 hr = PropVariantToBuffer(&propvar, buffer, sizeof(data_int8));
1589 ok(hr == E_INVALIDARG, "PropVariantToBuffer failed: 0x%08x.\n", hr);
1590 PropVariantClear(&propvar);
1593 static void test_inmemorystore(void)
1595 IPropertyStoreCache *propcache;
1596 HRESULT hr;
1597 PROPERTYKEY pkey;
1598 PROPVARIANT propvar;
1599 DWORD count;
1600 PSC_STATE state;
1602 CoInitialize(NULL);
1604 hr = CoCreateInstance(&CLSID_InMemoryPropertyStore, NULL, CLSCTX_INPROC_SERVER,
1605 &IID_IPropertyStoreCache, (void**)&propcache);
1606 ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr);
1608 if (FAILED(hr))
1610 win_skip("CLSID_InMemoryPropertyStore not supported\n");
1611 CoUninitialize();
1612 return;
1615 hr = IPropertyStoreCache_GetCount(propcache, NULL);
1616 ok(hr == E_POINTER, "GetCount failed, hr=%x\n", hr);
1618 hr = IPropertyStoreCache_GetCount(propcache, &count);
1619 ok(hr == S_OK, "GetCount failed, hr=%x\n", hr);
1620 ok(count == 0, "GetCount returned %i, expected 0\n", count);
1622 hr = IPropertyStoreCache_Commit(propcache);
1623 ok(hr == S_OK, "Commit failed, hr=%x\n", hr);
1625 hr = IPropertyStoreCache_Commit(propcache);
1626 ok(hr == S_OK, "Commit failed, hr=%x\n", hr);
1628 hr = IPropertyStoreCache_GetAt(propcache, 0, &pkey);
1629 ok(hr == E_INVALIDARG, "GetAt failed, hr=%x\n", hr);
1631 pkey.fmtid = PKEY_WineTest;
1632 pkey.pid = 4;
1634 memset(&propvar, 0, sizeof(propvar));
1635 propvar.vt = VT_I4;
1636 propvar.u.lVal = 12345;
1638 if (0)
1640 /* Crashes on Windows 7 */
1641 hr = IPropertyStoreCache_SetValue(propcache, NULL, &propvar);
1642 ok(hr == E_POINTER, "SetValue failed, hr=%x\n", hr);
1644 hr = IPropertyStoreCache_SetValue(propcache, &pkey, NULL);
1645 ok(hr == E_POINTER, "SetValue failed, hr=%x\n", hr);
1648 hr = IPropertyStoreCache_SetValue(propcache, &pkey, &propvar);
1649 ok(hr == S_OK, "SetValue failed, hr=%x\n", hr);
1651 hr = IPropertyStoreCache_GetCount(propcache, &count);
1652 ok(hr == S_OK, "GetCount failed, hr=%x\n", hr);
1653 ok(count == 1, "GetCount returned %i, expected 0\n", count);
1655 memset(&pkey, 0, sizeof(pkey));
1657 hr = IPropertyStoreCache_GetAt(propcache, 0, &pkey);
1658 ok(hr == S_OK, "GetAt failed, hr=%x\n", hr);
1659 ok(IsEqualGUID(&pkey.fmtid, &PKEY_WineTest), "got wrong pkey\n");
1660 ok(pkey.pid == 4, "got pid of %i, expected 4\n", pkey.pid);
1662 pkey.fmtid = PKEY_WineTest;
1663 pkey.pid = 4;
1665 memset(&propvar, 0, sizeof(propvar));
1667 if (0)
1669 /* Crashes on Windows 7 */
1670 hr = IPropertyStoreCache_GetValue(propcache, NULL, &propvar);
1671 ok(hr == E_POINTER, "GetValue failed, hr=%x\n", hr);
1674 hr = IPropertyStoreCache_GetValue(propcache, &pkey, NULL);
1675 ok(hr == E_POINTER, "GetValue failed, hr=%x\n", hr);
1677 hr = IPropertyStoreCache_GetValue(propcache, &pkey, &propvar);
1678 ok(hr == S_OK, "GetValue failed, hr=%x\n", hr);
1679 ok(propvar.vt == VT_I4, "expected VT_I4, got %d\n", propvar.vt);
1680 ok(propvar.u.lVal == 12345, "expected 12345, got %d\n", propvar.u.lVal);
1682 pkey.fmtid = PKEY_WineTest;
1683 pkey.pid = 10;
1685 /* Get information for field that isn't set yet */
1686 propvar.vt = VT_I2;
1687 hr = IPropertyStoreCache_GetValue(propcache, &pkey, &propvar);
1688 ok(hr == S_OK, "GetValue failed, hr=%x\n", hr);
1689 ok(propvar.vt == VT_EMPTY, "expected VT_EMPTY, got %d\n", propvar.vt);
1691 state = 0xdeadbeef;
1692 hr = IPropertyStoreCache_GetState(propcache, &pkey, &state);
1693 ok(hr == TYPE_E_ELEMENTNOTFOUND, "GetState failed, hr=%x\n", hr);
1694 ok(state == PSC_NORMAL, "expected PSC_NORMAL, got %d\n", state);
1696 propvar.vt = VT_I2;
1697 state = 0xdeadbeef;
1698 hr = IPropertyStoreCache_GetValueAndState(propcache, &pkey, &propvar, &state);
1699 ok(hr == TYPE_E_ELEMENTNOTFOUND, "GetValueAndState failed, hr=%x\n", hr);
1700 ok(propvar.vt == VT_EMPTY, "expected VT_EMPTY, got %d\n", propvar.vt);
1701 ok(state == PSC_NORMAL, "expected PSC_NORMAL, got %d\n", state);
1703 /* Set state on an unset field */
1704 hr = IPropertyStoreCache_SetState(propcache, &pkey, PSC_NORMAL);
1705 ok(hr == TYPE_E_ELEMENTNOTFOUND, "SetState failed, hr=%x\n", hr);
1707 /* Manipulate state on already set field */
1708 pkey.fmtid = PKEY_WineTest;
1709 pkey.pid = 4;
1711 state = 0xdeadbeef;
1712 hr = IPropertyStoreCache_GetState(propcache, &pkey, &state);
1713 ok(hr == S_OK, "GetState failed, hr=%x\n", hr);
1714 ok(state == PSC_NORMAL, "expected PSC_NORMAL, got %d\n", state);
1716 hr = IPropertyStoreCache_SetState(propcache, &pkey, 10);
1717 ok(hr == S_OK, "SetState failed, hr=%x\n", hr);
1719 state = 0xdeadbeef;
1720 hr = IPropertyStoreCache_GetState(propcache, &pkey, &state);
1721 ok(hr == S_OK, "GetState failed, hr=%x\n", hr);
1722 ok(state == 10, "expected 10, got %d\n", state);
1724 propvar.vt = VT_I4;
1725 propvar.u.lVal = 12346;
1726 hr = IPropertyStoreCache_SetValueAndState(propcache, &pkey, &propvar, 5);
1727 ok(hr == S_OK, "SetValueAndState failed, hr=%x\n", hr);
1729 memset(&propvar, 0, sizeof(propvar));
1730 state = 0xdeadbeef;
1731 hr = IPropertyStoreCache_GetValueAndState(propcache, &pkey, &propvar, &state);
1732 ok(hr == S_OK, "GetValueAndState failed, hr=%x\n", hr);
1733 ok(propvar.vt == VT_I4, "expected VT_I4, got %d\n", propvar.vt);
1734 ok(propvar.u.lVal == 12346, "expected 12346, got %d\n", propvar.vt);
1735 ok(state == 5, "expected 5, got %d\n", state);
1737 /* Set new field with state */
1738 pkey.fmtid = PKEY_WineTest;
1739 pkey.pid = 8;
1741 propvar.vt = VT_I4;
1742 propvar.u.lVal = 12347;
1743 hr = IPropertyStoreCache_SetValueAndState(propcache, &pkey, &propvar, PSC_DIRTY);
1744 ok(hr == S_OK, "SetValueAndState failed, hr=%x\n", hr);
1746 memset(&propvar, 0, sizeof(propvar));
1747 state = 0xdeadbeef;
1748 hr = IPropertyStoreCache_GetValueAndState(propcache, &pkey, &propvar, &state);
1749 ok(hr == S_OK, "GetValueAndState failed, hr=%x\n", hr);
1750 ok(propvar.vt == VT_I4, "expected VT_I4, got %d\n", propvar.vt);
1751 ok(propvar.u.lVal == 12347, "expected 12347, got %d\n", propvar.vt);
1752 ok(state == PSC_DIRTY, "expected PSC_DIRTY, got %d\n", state);
1754 IPropertyStoreCache_Release(propcache);
1756 CoUninitialize();
1759 static void test_persistserialized(void)
1761 IPropertyStore *propstore;
1762 IPersistSerializedPropStorage *serialized;
1763 HRESULT hr;
1764 SERIALIZEDPROPSTORAGE *result;
1765 DWORD result_size;
1767 CoInitialize(NULL);
1769 hr = CoCreateInstance(&CLSID_InMemoryPropertyStore, NULL, CLSCTX_INPROC_SERVER,
1770 &IID_IPropertyStore, (void**)&propstore);
1771 ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr);
1773 hr = IPropertyStore_QueryInterface(propstore, &IID_IPersistSerializedPropStorage,
1774 (void**)&serialized);
1775 todo_wine ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr);
1777 if (FAILED(hr))
1779 IPropertyStore_Release(propstore);
1780 skip("IPersistSerializedPropStorage not supported\n");
1781 CoUninitialize();
1782 return;
1785 hr = IPersistSerializedPropStorage_GetPropertyStorage(serialized, NULL, &result_size);
1786 ok(hr == E_POINTER, "GetPropertyStorage failed, hr=%x\n", hr);
1788 hr = IPersistSerializedPropStorage_GetPropertyStorage(serialized, &result, NULL);
1789 ok(hr == E_POINTER, "GetPropertyStorage failed, hr=%x\n", hr);
1791 hr = IPersistSerializedPropStorage_GetPropertyStorage(serialized, &result, &result_size);
1792 ok(hr == S_OK, "GetPropertyStorage failed, hr=%x\n", hr);
1794 if (SUCCEEDED(hr))
1796 ok(result_size == 0, "expected 0 bytes, got %i\n", result_size);
1798 CoTaskMemFree(result);
1801 hr = IPersistSerializedPropStorage_SetPropertyStorage(serialized, NULL, 4);
1802 ok(hr == E_POINTER, "SetPropertyStorage failed, hr=%x\n", hr);
1804 hr = IPersistSerializedPropStorage_SetPropertyStorage(serialized, NULL, 0);
1805 ok(hr == S_OK, "SetPropertyStorage failed, hr=%x\n", hr);
1807 hr = IPropertyStore_GetCount(propstore, &result_size);
1808 ok(hr == S_OK, "GetCount failed, hr=%x\n", hr);
1809 ok(result_size == 0, "expecting 0, got %d\n", result_size);
1811 IPropertyStore_Release(propstore);
1812 IPersistSerializedPropStorage_Release(serialized);
1814 CoUninitialize();
1817 static void test_PSCreateMemoryPropertyStore(void)
1819 IPropertyStore *propstore, *propstore1;
1820 IPersistSerializedPropStorage *serialized;
1821 IPropertyStoreCache *propstorecache;
1822 HRESULT hr;
1824 /* PSCreateMemoryPropertyStore(&IID_IPropertyStore, NULL); crashes */
1826 hr = PSCreateMemoryPropertyStore(&IID_IPropertyStore, (void **)&propstore);
1827 ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08x.\n", hr);
1828 ok(propstore != NULL, "got %p.\n", propstore);
1829 EXPECT_REF(propstore, 1);
1831 hr = PSCreateMemoryPropertyStore(&IID_IPersistSerializedPropStorage, (void **)&serialized);
1832 todo_wine ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08x.\n", hr);
1833 todo_wine ok(serialized != NULL, "got %p.\n", serialized);
1834 EXPECT_REF(propstore, 1);
1835 if(serialized)
1837 EXPECT_REF(serialized, 1);
1838 IPersistSerializedPropStorage_Release(serialized);
1841 hr = PSCreateMemoryPropertyStore(&IID_IPropertyStoreCache, (void **)&propstorecache);
1842 ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08x.\n", hr);
1843 ok(propstorecache != NULL, "got %p.\n", propstore);
1844 ok(propstorecache != (IPropertyStoreCache *)propstore, "pointer are equal: %p, %p.\n", propstorecache, propstore);
1845 EXPECT_REF(propstore, 1);
1846 EXPECT_REF(propstorecache, 1);
1848 hr = PSCreateMemoryPropertyStore(&IID_IPropertyStore, (void **)&propstore1);
1849 ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08x.\n", hr);
1850 ok(propstore1 != NULL, "got %p.\n", propstore);
1851 ok(propstore1 != propstore, "pointer are equal: %p, %p.\n", propstore1, propstore);
1852 EXPECT_REF(propstore, 1);
1853 EXPECT_REF(propstore1, 1);
1854 EXPECT_REF(propstorecache, 1);
1856 IPropertyStore_Release(propstore1);
1857 IPropertyStore_Release(propstore);
1858 IPropertyStoreCache_Release(propstorecache);
1861 static void test_propertystore(void)
1863 IPropertyStore *propstore;
1864 HRESULT hr;
1865 PROPVARIANT propvar, ret_propvar;
1866 PROPERTYKEY propkey;
1867 DWORD count = 0;
1869 hr = PSCreateMemoryPropertyStore(&IID_IPropertyStore, (void **)&propstore);
1870 ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08x.\n", hr);
1871 ok(propstore != NULL, "got %p.\n", propstore);
1873 hr = IPropertyStore_GetCount(propstore, &count);
1874 ok(hr == S_OK, "IPropertyStore_GetCount failed: 0x%08x.\n", hr);
1875 ok(!count, "got wrong property count: %d, expected 0.\n", count);
1877 PropVariantInit(&propvar);
1878 propvar.vt = VT_I4;
1879 U(propvar).lVal = 123;
1880 propkey.fmtid = DUMMY_GUID1;
1881 propkey.pid = PID_FIRST_USABLE;
1882 hr = IPropertyStore_SetValue(propstore, &propkey, &propvar);
1883 ok(hr == S_OK, "IPropertyStore_SetValue failed: 0x%08x.\n", hr);
1884 hr = IPropertyStore_Commit(propstore);
1885 ok(hr == S_OK, "IPropertyStore_Commit failed: 0x%08x.\n", hr);
1886 hr = IPropertyStore_GetCount(propstore, &count);
1887 ok(hr == S_OK, "IPropertyStore_GetCount failed: 0x%08x.\n", hr);
1888 ok(count == 1, "got wrong property count: %d, expected 1.\n", count);
1889 PropVariantInit(&ret_propvar);
1890 ret_propvar.vt = VT_I4;
1891 hr = IPropertyStore_GetValue(propstore, &propkey, &ret_propvar);
1892 ok(hr == S_OK, "IPropertyStore_GetValue failed: 0x%08x.\n", hr);
1893 ok(ret_propvar.vt == VT_I4, "got wrong property type: %x.\n", ret_propvar.vt);
1894 ok(U(ret_propvar).lVal == 123, "got wrong value: %d, expected 123.\n", U(ret_propvar).lVal);
1895 PropVariantClear(&propvar);
1896 PropVariantClear(&ret_propvar);
1898 PropVariantInit(&propvar);
1899 propkey.fmtid = DUMMY_GUID1;
1900 propkey.pid = PID_FIRST_USABLE;
1901 hr = IPropertyStore_SetValue(propstore, &propkey, &propvar);
1902 ok(hr == S_OK, "IPropertyStore_SetValue failed: 0x%08x.\n", hr);
1903 hr = IPropertyStore_Commit(propstore);
1904 ok(hr == S_OK, "IPropertyStore_Commit failed: 0x%08x.\n", hr);
1905 hr = IPropertyStore_GetCount(propstore, &count);
1906 ok(hr == S_OK, "IPropertyStore_GetCount failed: 0x%08x.\n", hr);
1907 ok(count == 1, "got wrong property count: %d, expected 1.\n", count);
1908 PropVariantInit(&ret_propvar);
1909 hr = IPropertyStore_GetValue(propstore, &propkey, &ret_propvar);
1910 ok(hr == S_OK, "IPropertyStore_GetValue failed: 0x%08x.\n", hr);
1911 ok(ret_propvar.vt == VT_EMPTY, "got wrong property type: %x.\n", ret_propvar.vt);
1912 ok(!U(ret_propvar).lVal, "got wrong value: %d, expected 0.\n", U(ret_propvar).lVal);
1913 PropVariantClear(&propvar);
1914 PropVariantClear(&ret_propvar);
1916 IPropertyStore_Release(propstore);
1919 static void test_PSCreatePropertyStoreFromObject(void)
1921 IPropertyStore *propstore;
1922 IUnknown *unk;
1923 HRESULT hr;
1925 hr = PSCreateMemoryPropertyStore(&IID_IPropertyStore, (void **)&propstore);
1926 ok(hr == S_OK, "Failed to create property store, hr %#x.\n", hr);
1928 hr = PSCreatePropertyStoreFromObject(NULL, STGM_READWRITE, &IID_IUnknown, (void **)&unk);
1929 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1931 hr = PSCreatePropertyStoreFromObject((IUnknown *)propstore, STGM_READWRITE, &IID_IUnknown, NULL);
1932 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1934 hr = PSCreatePropertyStoreFromObject((IUnknown *)propstore, STGM_READWRITE, &IID_IUnknown, (void **)&unk);
1935 todo_wine
1936 ok(hr == S_OK, "Failed to create wrapper, hr %#x.\n", hr);
1937 if (SUCCEEDED(hr))
1939 ok(unk != (IUnknown *)propstore, "Unexpected object returned.\n");
1940 IUnknown_Release(unk);
1943 hr = PSCreatePropertyStoreFromObject((IUnknown *)propstore, STGM_READWRITE, &IID_IPropertyStore, (void **)&unk);
1944 ok(hr == S_OK, "Failed to create wrapper, hr %#x.\n", hr);
1945 ok(unk == (IUnknown *)propstore, "Unexpected object returned.\n");
1946 IUnknown_Release(unk);
1948 IPropertyStore_Release(propstore);
1951 START_TEST(propsys)
1953 test_PSStringFromPropertyKey();
1954 test_PSPropertyKeyFromString();
1955 test_PSRefreshPropertySchema();
1956 test_InitPropVariantFromGUIDAsString();
1957 test_InitPropVariantFromBuffer();
1958 test_PropVariantToGUID();
1959 test_PropVariantToStringAlloc();
1960 test_PropVariantCompare();
1961 test_intconversions();
1962 test_PropVariantChangeType_LPWSTR();
1963 test_PropVariantToBoolean();
1964 test_PropVariantToStringWithDefault();
1965 test_InitPropVariantFromCLSID();
1966 test_PropVariantToDouble();
1967 test_PropVariantToString();
1968 test_PropVariantToBuffer();
1969 test_inmemorystore();
1970 test_persistserialized();
1971 test_PSCreateMemoryPropertyStore();
1972 test_propertystore();
1973 test_PSCreatePropertyStoreFromObject();