1 /*
2  * PROJECT:         ReactOS api tests
3  * LICENSE:         GPLv2+ - See COPYING in the top level directory
4  * PURPOSE:         Test for the RegQueryValueW API
5  * PROGRAMMER:      Victor Martinez Calvo <victor.martinez@reactos.org>
6  */
7 
8 #include "precomp.h"
9 
delete_key(HKEY hkey)10 static DWORD delete_key(HKEY hkey)
11 {
12     WCHAR name[MAX_PATH];
13     DWORD ret;
14 
15     while (!(ret = RegEnumKeyW(hkey, 0, name, _countof(name))))
16     {
17         HKEY tmp;
18         if (!(ret = RegOpenKeyExW(hkey, name, 0, KEY_ENUMERATE_SUB_KEYS, &tmp)))
19         {
20             ret = delete_key(tmp);
21         }
22         if (ret)
23             break;
24     }
25     if (ret == ERROR_NO_MORE_ITEMS)
26     {
27         RegDeleteKeyW(hkey, L"");
28         ret = 0;
29     }
30     RegCloseKey(hkey);
31     return ret;
32 }
33 
START_TEST(RegQueryValueExW)34 START_TEST(RegQueryValueExW)
35 {
36     HKEY hkey_main;
37     HKEY subkey;
38     DWORD type, size, ret, reserved;
39     const WCHAR string1W[] = L"1";
40     const WCHAR string22W[] = L"Thisstringhas22letters";
41     WCHAR data22[22];
42     WCHAR data23[23];
43     WCHAR data24[24];
44 
45 
46     /* If the tree key already exist, delete it to ensure proper testing*/
47     if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\ReactOS\\advapi32_apitest", 0, KEY_ALL_ACCESS, &hkey_main) == ERROR_SUCCESS)
48         delete_key(hkey_main);
49 
50     /* Ready to recreate it */
51     SetLastError(0xdeadbeef);
52     ret = RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\ReactOS\\advapi32_apitest", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey_main, NULL);
53     ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", ret);
54     ok(GetLastError(), "RegCreateKeyExW failed: %lx\n", GetLastError());
55     if(ret != ERROR_SUCCESS)
56     {
57         trace("Unable to create test key, aborting!\n");
58         return;
59     }
60 
61     SetLastError(0xdeadbeef);
62     ret = RegCreateKeyExW(hkey_main, L"subkey", 0, L"subkey class", 0, KEY_ALL_ACCESS, NULL, &subkey, NULL);
63     ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", ret);
64     ok(GetLastError(), "RegCreateKeyExW failed: %lx\n", GetLastError());
65 
66     /* All NULL */
67     SetLastError(0xdeadbeef);
68     ret = RegQueryValueExW(NULL, NULL, NULL, NULL, NULL, NULL);
69     ok(ret == ERROR_INVALID_HANDLE, "RegQueryValueExW returned: %lx\n", ret);
70     ok(GetLastError() == 0xdeadbeef, "RegQueryValueExW returned: %lx\n", GetLastError());
71 
72     /* All NULL. Reserved not NULL */
73     type = 666;
74     size = 666;
75     reserved = 3;
76     SetLastError(0xdeadbeef);
77     ret = RegQueryValueExW(NULL, NULL, &reserved, NULL, NULL, NULL);
78     ok(ret == ERROR_INVALID_PARAMETER, "RegQueryValueExW returned: %lx\n", ret);
79     ok(GetLastError() == 0xdeadbeef, "RegQueryValueExW returned: %lx\n", GetLastError());
80     ok(reserved == 3, "Expected reserved=3, reserved is: %ld\n", reserved);
81 
82     /* NULL handle. NULL value. Reserved not NULL */
83     type = 666;
84     size = 666;
85     reserved = 3;
86     SetLastError(0xdeadbeef);
87     ret = RegQueryValueExW(NULL, NULL, &reserved, &type, NULL, &size);
88     ok(ret == ERROR_INVALID_PARAMETER, "RegQueryValueExW returned: %lx\n", ret);
89     ok(GetLastError() == 0xdeadbeef, "RegQueryValueExW returned: %lx\n", GetLastError());
90     ok(type == 666, "Expected untouched, Type was set with: %ld\n", type);
91     ok(size == 666, "Expected untouched, Size was set with: %ld\n", size);
92     ok(reserved == 3, "Expected reserved = 3, reserved is: %ld\n", reserved);
93 
94     /* NULL handle. NULL value */
95     type = 666;
96     size = 666;
97     SetLastError(0xdeadbeef);
98     ret = RegQueryValueExW(NULL, NULL, NULL, &type, NULL, &size);
99     ok(ret == ERROR_INVALID_HANDLE, "RegQueryValueExW returned: %lx\n", ret);
100     ok(GetLastError() == 0xdeadbeef, "RegQueryValueExW returned: %lx\n", GetLastError());
101     ok(type == 666, "Expected untouched, Type was set with: %ld\n", type);
102     ok(size == 666, "Expected untouched, Size was set with: %ld\n", size);
103 
104     /* NULL handle . Inexistent value. Reserved not NULL */
105     type = 666;
106     size = 666;
107     reserved = 3;
108     SetLastError(0xdeadbeef);
109     ret = RegQueryValueExW(NULL, L"MSITESTVAR11", &reserved, &type, NULL, &size);
110     ok(ret == ERROR_INVALID_PARAMETER, "RegQueryValueExW returned: %lx\n", ret);
111     ok(GetLastError() == 0xdeadbeef, "RegQueryValueExW returned: %lx\n", GetLastError());
112     ok(type == 666, "Expected untouched, Type was set with: %ld\n", type);
113     ok(size == 666, "Expected untouched, Size was set with: %ld\n", size);
114     ok(reserved == 3, "Expected reserved = 3, reserved is: %ld\n", reserved);
115 
116     /* NULL handle . Inexistent value. */
117     type = 666;
118     size = 666;
119     SetLastError(0xdeadbeef);
120     ret = RegQueryValueExW(NULL, L"MSITESTVAR11", NULL, &type, NULL, &size);
121     ok(ret == ERROR_INVALID_HANDLE, "RegQueryValueExW returned: %lx\n", ret);
122     ok(GetLastError() == 0xdeadbeef, "RegQueryValueExW returned: %lx\n", GetLastError());
123     ok(type == 666, "Expected untouched, Type was set with: %ld\n", type);
124     ok(size == 666, "Expected untouched, Size was set with: %ld\n", size);
125 
126     /* NULL handle */
127     type = 666;
128     size = 666;
129     SetLastError(0xdeadbeef);
130     ret = RegQueryValueExW(NULL, L"MSITESTVAR11", NULL, &type, NULL, &size);
131     ok(ret == ERROR_INVALID_HANDLE, "RegQueryValueExW returned: %lx\n", ret);
132     ok(GetLastError() == 0xdeadbeef, "RegQueryValueExW returned: %lx\n", GetLastError());
133     ok(type == 666, "Expected untouched, Type was set with: %ld\n", type);
134     ok(size == 666, "Expected untouched, Size was set with: %ld\n", size);
135 
136     /* INVALID handle. NULL value. Reserved not NULL */
137     type = 666;
138     size = 666;
139     reserved = 3;
140     SetLastError(0xdeadbeef);
141     ret = RegQueryValueExW((HKEY)-4, NULL, &reserved, &type, NULL, &size);
142     ok(ret == ERROR_INVALID_PARAMETER, "RegQueryValueExW returned: %lx\n", ret);
143     ok(GetLastError() == 0xdeadbeef, "RegQueryValueExW returned: %lx\n", GetLastError());
144     ok(type == 666, "Expected untouched, Type was set with: %ld\n", type);
145     ok(size == 666, "Expected untouched, Size was set with: %ld\n", size);
146     ok(reserved == 3, "Expected reserved = 3, reserved is: %ld\n", reserved);
147 
148     /* INVALID handle. NULL value.*/
149     type = 666;
150     size = 666;
151     SetLastError(0xdeadbeef);
152     ret = RegQueryValueExW((HKEY)-4, NULL, NULL, &type, NULL, &size);
153     ok(ret == ERROR_INVALID_HANDLE, "RegQueryValueExW returned: %lx\n", ret);
154     ok(GetLastError() == 0xdeadbeef, "RegQueryValueExW returned: %lx\n", GetLastError());
155     ok(type == REG_NONE, "Expected REG_NONE, Type is: %ld\n", type);
156     ok(size == 0, "Expected size = 0, size is: %ld\n", size);
157     ok(reserved == 3, "Expected reserved = 3, reserved is: %ld\n", reserved);
158 
159     /* INVALID handle. Non-existent value. Reserved not NULL*/
160     type = 666;
161     size = 666;
162     reserved = 3;
163     SetLastError(0xdeadbeef);
164     ret = RegQueryValueExW((HKEY)-4, L"MSITESTVAR11", &reserved, &type, NULL, &size);
165     ok(ret == ERROR_INVALID_PARAMETER, "RegQueryValueExW returned: %lx\n", ret);
166     ok(GetLastError() == 0xdeadbeef, "RegQueryValueExW returned: %lx\n", GetLastError());
167     ok(type == 666, "Expected untouched, Type was set with: %ld\n", type);
168     ok(size == 666, "Expected untouched, Size was set with: %ld\n", size);
169     ok(reserved == 3, "Expected reserved = 3, reserved is: %ld\n", reserved);
170 
171     /* INVALID handle. Non-existent value. */
172     type = 666;
173     size = 666;
174     SetLastError(0xdeadbeef);
175     ret = RegQueryValueExW((HKEY)-4, L"MSITESTVAR11", NULL, &type, NULL, &size);
176     ok(ret == ERROR_INVALID_HANDLE, "RegQueryValueExW returned: %lx\n", ret);
177     ok(GetLastError() == 0xdeadbeef, "RegQueryValueExW returned: %lx\n", GetLastError());
178     ok(type == REG_NONE, "Expected REG_NONE, Type is: %ld\n", type);
179     ok(size == 0, "Expected size = 0, size is: %ld\n", size);
180 
181     /* VALID handle, Non-existent value, Reserved not NULL */
182     type = 666;
183     size = 666;
184     reserved = 3;
185     SetLastError(0xdeadbeef);
186     ret = RegQueryValueExW(hkey_main, L"MSITESTVAR11", &reserved, &type, NULL, &size);
187     ok(ret == ERROR_INVALID_PARAMETER, "RegQueryValueExW returned: %lx\n", ret);
188     ok(GetLastError() == 0xdeadbeef, "RegQueryValueExW returned: %lx\n", GetLastError());
189     ok(type == 666, "Expected untouched, Type was set with: %ld\n", type);
190     ok(size == 666, "Expected untouched, Size was set with: %ld\n", size);
191     ok(reserved == 3, "Expected reserved = 3, reserved is: %ld\n", reserved);
192 
193     /* VALID handle, Non-existent value */
194     type = 666;
195     size = 666;
196     SetLastError(0xdeadbeef);
197     ret = RegQueryValueExW(hkey_main, L"MSITESTVAR11", NULL, &type, NULL, &size);
198     ok(ret == ERROR_FILE_NOT_FOUND, "RegQueryValueExW returned: %lx\n", ret);
199     ok(GetLastError() == 0xdeadbeef, "RegQueryValueExW returned: %lx\n", GetLastError());
200     ok(type == REG_NONE, "Expected REG_NONE, Type is: %ld\n", type);
201     ok(size == 0, "Expected size = 0, size is: %ld\n", size);
202 
203     /* VALID handle, NULL value */
204     type = 666;
205     size = 666;
206     SetLastError(0xdeadbeef);
207     ret = RegQueryValueExW(hkey_main, NULL, NULL, &type, NULL, &size);
208     ok(ret == ERROR_FILE_NOT_FOUND, "RegQueryValueExW returned: %lx\n", ret);
209     ok(GetLastError() == 0xdeadbeef, "RegQueryValueExW returned: %lx\n", GetLastError());
210     ok(type == REG_NONE, "Expected REG_NONE, Type is: %ld\n", type);
211     ok(size == 0, "Expected size = 0, size is: %ld\n", size);
212 
213     /* Create the value */
214     SetLastError(0xdeadbeef);
215     if ((ret = RegSetValueExW(hkey_main, L"MSITESTVAR11", 0, REG_NONE, (const BYTE *)string1W, 4)) != ERROR_SUCCESS)
216     {
217         ok(1, "RegSetValueExW failed: %lx, %lx\n", ret, GetLastError());
218     }
219     if ((ret = RegSetValueExW(hkey_main, L"LONGSTRING", 0, REG_SZ, (const BYTE *)string22W, (lstrlenW(string22W)+1) * sizeof(WCHAR))) != ERROR_SUCCESS)
220     {
221         ok(1, "RegSetValueExW failed: %lx, %lx\n", ret, GetLastError());
222     }
223 
224     /* Existent value. Reserved not NULL */
225     SetLastError(0xdeadbeef);
226     size = 666;
227     type = 666;
228     reserved = 3;
229     ret = RegQueryValueExW(hkey_main, L"MSITESTVAR11", &reserved, &type, NULL, &size);
230     ok(ret == ERROR_INVALID_PARAMETER, "RegQueryValueExW returned: %lx\n", ret);
231     ok(GetLastError() == 0xdeadbeef, "RegQueryValueExW returned: %lx\n", GetLastError());
232     ok(type == 666, "Expected untouched, Type was set with: %ld\n", type);
233     ok(size == 666, "Expected untouched, Size was set with: %ld\n", size);
234     ok(reserved == 3, "Expected reserved = 3, reserved is: %ld\n", reserved);
235 
236     /* Existent value */
237     SetLastError(0xdeadbeef);
238     size = 666;
239     type = 666;
240     ret = RegQueryValueExW(hkey_main, L"MSITESTVAR11", NULL, &type, NULL, &size);
241     ok(ret == ERROR_SUCCESS, "RegQueryValueExW returned: %lx\n", ret);
242     ok(GetLastError() == 0xdeadbeef, "RegQueryValueExW returned: %lx\n", GetLastError());
243     ok(type == REG_NONE, "Expected REG_NONE, Type is: %ld\n", type);
244     ok(size == 4, "Expected size = 4, size is: %ld\n", size);
245 
246     /* Data tests */
247     /* Buffer one wchar smaller than needed */
248     SetLastError(0xdeadbeef);
249     size = sizeof(data22);
250     type = 666;
251     ret = RegQueryValueExW(hkey_main, L"LONGSTRING", NULL, &type, (LPBYTE)data22, &size);
252     ok(ret == ERROR_MORE_DATA, "RegQueryValueExW returned: %lx\n", ret);
253     ok(GetLastError() == 0xdeadbeef, "RegQueryValueExW returned: %lx\n", GetLastError());
254     ok(type == REG_SZ, "Expected REG_SZ, Type is: %ld\n", type);
255     ok(size == 46, "Expected size = 46, size is: %ld\n", size);
256     ok(wcscmp(data22, string22W), "Expected being different!");
257 
258     /* Buffer has perfect size */
259     SetLastError(0xdeadbeef);
260     size = sizeof(data23);
261     type = 666;
262     ret = RegQueryValueExW(hkey_main, L"LONGSTRING", NULL, &type, (LPBYTE)data23, &size);
263     ok(ret == ERROR_SUCCESS, "RegQueryValueExW returned: %lx\n", ret);
264     ok(GetLastError() == 0xdeadbeef, "RegQueryValueExW returned: %lx\n", GetLastError());
265     ok(type == REG_SZ, "Expected REG_SZ, Type is: %ld\n", type);
266     ok(size == 46, "Expected size = 46, size is: %ld", size);
267     ok(!wcscmp(data23,string22W), "Expected same string! data23: %S, string22W: %S", data23, string22W);
268 
269     /* Buffer one wchar bigger than needed */
270     SetLastError(0xdeadbeef);
271     size = sizeof(data24);
272     type = 666;
273     ret = RegQueryValueExW(hkey_main, L"LONGSTRING", NULL, &type, (LPBYTE)data24, &size);
274     ok(ret == ERROR_SUCCESS, "RegQueryValueExW returned: %lx\n", ret);
275     ok(GetLastError() == 0xdeadbeef, "RegQueryValueExW returned: %lx\n", GetLastError());
276     ok(type == REG_SZ, "Expected REG_SZ, Type is: %ld\n", type);
277     ok(size == 46, "Expected size = 46, size is: %ld\n", size);
278     ok(!wcscmp(data24, string22W), "Expected same string! data24: %S, string22W: %S\n", data24, string22W);
279 
280     /* Buffer has perfect size. Size wrong: 1 WCHAR less */
281     SetLastError(0xdeadbeef);
282     memset(data23, 0, sizeof(data23));
283     size = sizeof(data23) - 2;
284     type = 666;
285     ret = RegQueryValueExW(hkey_main, L"LONGSTRING", NULL, &type, (LPBYTE)data23, &size);
286     ok(ret == ERROR_MORE_DATA, "RegQueryValueExW returned: %lx\n", ret);
287     ok(GetLastError() == 0xdeadbeef, "RegQueryValueExW returned: %lx\n", GetLastError());
288     ok(type == REG_SZ, "Expected REG_SZ, Type is: %ld\n", type);
289     ok(size == 46, "Expected size = 46, size is: %ld", size);
290     ok(wcscmp(data23, string22W), "Expected different string!\n");
291 
292     /* Buffer has perfect size. Size wrong: 1 WCHAR more */
293     SetLastError(0xdeadbeef);
294     memset(data23, 0, sizeof(data23));
295     size = sizeof(data23) + 2;
296     type = 666;
297     ret = RegQueryValueExW(hkey_main, L"LONGSTRING", NULL, &type, (LPBYTE)data23, &size);
298     ok(ret == ERROR_SUCCESS, "RegQueryValueExW returned: %lx\n", ret);
299     ok(GetLastError() == 0xdeadbeef, "RegQueryValueExW returned: %lx\n", GetLastError());
300     ok(type == REG_SZ, "Expected REG_SZ, Type is: %ld\n", type);
301     ok(size == 46, "Expected size = 46, size is: %ld", size);
302     ok(!wcscmp(data23, string22W), "Expected same string! data23: %S, string22W: %S", data23, string22W);
303 
304     /* Ask for a var that doesnt exist. */
305     SetLastError(0xdeadbeef);
306     size = sizeof(data23);
307     memset(data23, 0, sizeof(data23));
308     type = 666;
309     ret = RegQueryValueExW(hkey_main, L"XXXXXYYYYYZZZZZZ", NULL, &type, (LPBYTE)data23, &size);
310     ok(ret == ERROR_FILE_NOT_FOUND, "RegQueryValueExW returned: %lx\n", ret);
311     ok(GetLastError() == 0xdeadbeef, "RegQueryValueExW returned: %lx\n", GetLastError());
312     /* 2k3 leaves garbage */
313     ok(type == REG_NONE || broken(type != REG_NONE && type != 666), "Expected REG_NONE, Type is: %ld\n", type);
314     ok(size == 46, "Expected size = 46, size is: %ld", size);
315     ok(!wcscmp(data23,L""), "Expected same string! data23: %S, ''", data23);
316 
317 
318     RegCloseKey(hkey_main);
319     RegCloseKey(subkey);
320 
321     /* Delete the whole test key */
322     RegOpenKeyW(HKEY_CURRENT_USER, L"Software\\ReactOS\\advapi32_apitest", &hkey_main);
323     delete_key(hkey_main);
324 }
325