xcopy: Add help.
[wine] / dlls / advapi32 / tests / registry.c
1 /*
2  * Unit tests for registry functions
3  *
4  * Copyright (c) 2002 Alexandre Julliard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include <assert.h>
22 #include <stdarg.h>
23 #include "wine/test.h"
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winreg.h"
27 #include "winsvc.h"
28 #include "winerror.h"
29
30 static HKEY hkey_main;
31 static DWORD GLE;
32
33 static const char * sTestpath1 = "%LONGSYSTEMVAR%\\subdir1";
34 static const char * sTestpath2 = "%FOO%\\subdir1";
35
36 static HMODULE hadvapi32;
37 static DWORD (WINAPI *pRegGetValueA)(HKEY,LPCSTR,LPCSTR,DWORD,LPDWORD,PVOID,LPDWORD);
38
39 #define ADVAPI32_GET_PROC(func) \
40     p ## func = (void*)GetProcAddress(hadvapi32, #func); \
41     if(!p ## func) \
42       trace("GetProcAddress(%s) failed\n", #func);
43
44 static void InitFunctionPtrs(void)
45 {
46     hadvapi32 = GetModuleHandleA("advapi32.dll");
47
48     /* This function was introduced with Windows 2003 SP1 */
49     ADVAPI32_GET_PROC(RegGetValueA)
50 }
51
52 /* delete key and all its subkeys */
53 static DWORD delete_key( HKEY hkey )
54 {
55     char name[MAX_PATH];
56     DWORD ret;
57
58     while (!(ret = RegEnumKeyA(hkey, 0, name, sizeof(name))))
59     {
60         HKEY tmp;
61         if (!(ret = RegOpenKeyExA( hkey, name, 0, KEY_ENUMERATE_SUB_KEYS, &tmp )))
62         {
63             ret = delete_key( tmp );
64             RegCloseKey( tmp );
65         }
66         if (ret) break;
67     }
68     if (ret != ERROR_NO_MORE_ITEMS) return ret;
69     RegDeleteKeyA( hkey, "" );
70     return 0;
71 }
72
73 static void setup_main_key(void)
74 {
75     if (RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Test", &hkey_main )) delete_key( hkey_main );
76
77     assert (!RegCreateKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Test", &hkey_main ));
78 }
79
80 static void test_hkey_main_Value_A(LPCSTR name, LPCSTR string)
81 {
82     DWORD ret, type, cbData;
83     DWORD str_byte_len, full_byte_len;
84
85     ret = RegQueryValueExA(hkey_main, name, NULL, &type, NULL, &cbData);
86     GLE = GetLastError();
87     ok(ret == ERROR_SUCCESS, "RegQueryValueExA failed: %d, GLE=%d\n", ret, GLE);
88     if(GLE == ERROR_CALL_NOT_IMPLEMENTED) return;
89
90     str_byte_len = lstrlenA(string) + 1;
91     full_byte_len = sizeof(string);
92     ok(type == REG_SZ, "RegQueryValueExA returned type %d\n", type);
93     ok(cbData == full_byte_len || cbData == str_byte_len,
94         "cbData=%d instead of %d or %d\n", cbData, full_byte_len, str_byte_len);
95 }
96
97 static void test_hkey_main_Value_W(LPCWSTR name, LPCWSTR string)
98 {
99     DWORD ret, type, cbData;
100     DWORD str_byte_len, full_byte_len;
101
102     ret = RegQueryValueExW(hkey_main, name, NULL, &type, NULL, &cbData);
103     GLE = GetLastError();
104     ok(ret == ERROR_SUCCESS, "RegQueryValueExW failed: %d, GLE=%d\n", ret, GLE);
105     if(GLE == ERROR_CALL_NOT_IMPLEMENTED) return;
106
107     str_byte_len = (lstrlenW(string) + 1) * sizeof(WCHAR);
108     full_byte_len = sizeof(string);
109     ok(type == REG_SZ, "RegQueryValueExW returned type %d\n", type);
110     ok(cbData == full_byte_len || cbData == str_byte_len,
111         "cbData=%d instead of %d or %d\n", cbData, full_byte_len, str_byte_len);
112 }
113
114 static void test_set_value(void)
115 {
116     DWORD ret;
117
118     static const WCHAR name1W[] =   {'C','l','e','a','n','S','i','n','g','l','e','S','t','r','i','n','g', 0};
119     static const WCHAR name2W[] =   {'S','o','m','e','I','n','t','r','a','Z','e','r','o','e','d','S','t','r','i','n','g', 0};
120     static const WCHAR string1W[] = {'T','h','i','s','N','e','v','e','r','B','r','e','a','k','s', 0};
121     static const WCHAR string2W[] = {'T','h','i','s', 0 ,'B','r','e','a','k','s', 0 , 0 ,'A', 0 , 0 , 0 , 0 ,'L','o','t', 0 , 0 , 0 , 0};
122
123     static const char name1A[] =   "CleanSingleString";
124     static const char name2A[] =   "SomeIntraZeroedString";
125     static const char string1A[] = "ThisNeverBreaks";
126     static const char string2A[] = "This\0Breaks\0\0A\0\0\0Lot\0\0\0\0";
127
128     /* test RegSetValueExA with normal string */
129     ret = RegSetValueExA(hkey_main, name1A, 0, REG_SZ, (const BYTE *)string1A, sizeof(string1A));
130     ok(ret == ERROR_SUCCESS, "RegSetValueExA failed: %d, GLE=%d\n", ret, GetLastError());
131     test_hkey_main_Value_A(name1A, string1A);
132     test_hkey_main_Value_W(name1W, string1W);
133
134     /* test RegSetValueExA with intrazeroed string */
135     ret = RegSetValueExA(hkey_main, name2A, 0, REG_SZ, (const BYTE *)string2A, sizeof(string2A));
136     ok(ret == ERROR_SUCCESS, "RegSetValueExA failed: %d, GLE=%d\n", ret, GetLastError());
137     test_hkey_main_Value_A(name1A, string1A);
138     test_hkey_main_Value_W(name1W, string1W);
139
140     /* 9x doesn't support W-calls, so don't test them then */
141     if(GLE == ERROR_CALL_NOT_IMPLEMENTED) return; 
142
143     /* test RegSetValueExW with normal string */
144     ret = RegSetValueExW(hkey_main, name1W, 0, REG_SZ, (const BYTE *)string1W, sizeof(string1W));
145     ok(ret == ERROR_SUCCESS, "RegSetValueExW failed: %d, GLE=%d\n", ret, GetLastError());
146     test_hkey_main_Value_A(name1A, string1A);
147     test_hkey_main_Value_W(name1W, string1W);
148
149     /* test RegSetValueExW with intrazeroed string */
150     ret = RegSetValueExW(hkey_main, name2W, 0, REG_SZ, (const BYTE *)string2W, sizeof(string2W));
151     ok(ret == ERROR_SUCCESS, "RegSetValueExW failed: %d, GLE=%d\n", ret, GetLastError());
152     test_hkey_main_Value_A(name1A, string1A);
153     test_hkey_main_Value_W(name1W, string1W);
154 }
155
156 static void create_test_entries(void)
157 {
158     static const DWORD qw[2] = { 0x12345678, 0x87654321 };
159
160     SetEnvironmentVariableA("LONGSYSTEMVAR", "bar");
161     SetEnvironmentVariableA("FOO", "ImARatherLongButIndeedNeededString");
162
163     ok(!RegSetValueExA(hkey_main,"TP1_EXP_SZ",0,REG_EXPAND_SZ, (const BYTE *)sTestpath1, strlen(sTestpath1)+1), 
164         "RegSetValueExA failed\n");
165     ok(!RegSetValueExA(hkey_main,"TP1_SZ",0,REG_SZ, (const BYTE *)sTestpath1, strlen(sTestpath1)+1), 
166         "RegSetValueExA failed\n");
167     ok(!RegSetValueExA(hkey_main,"TP2_EXP_SZ",0,REG_EXPAND_SZ, (const BYTE *)sTestpath2, strlen(sTestpath2)+1), 
168         "RegSetValueExA failed\n");
169     ok(!RegSetValueExA(hkey_main,"DWORD",0,REG_DWORD, (const BYTE *)qw, 4),
170         "RegSetValueExA failed\n");
171     ok(!RegSetValueExA(hkey_main,"BIN32",0,REG_BINARY, (const BYTE *)qw, 4),
172         "RegSetValueExA failed\n");
173     ok(!RegSetValueExA(hkey_main,"BIN64",0,REG_BINARY, (const BYTE *)qw, 8),
174         "RegSetValueExA failed\n");
175 }
176         
177 static void test_enum_value(void)
178 {
179     DWORD res;
180     HKEY test_key;
181     char value[20], data[20];
182     WCHAR valueW[20], dataW[20];
183     DWORD val_count, data_count, type;
184     static const WCHAR foobarW[] = {'f','o','o','b','a','r',0};
185     static const WCHAR testW[] = {'T','e','s','t',0};
186     static const WCHAR xxxW[] = {'x','x','x','x','x','x','x','x',0};
187
188     /* create the working key for new 'Test' value */
189     res = RegCreateKeyA( hkey_main, "TestKey", &test_key );
190     ok( res == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", res);
191
192     /* check NULL data with zero length */
193     res = RegSetValueExA( test_key, "Test", 0, REG_SZ, NULL, 0 );
194     if (GetVersion() & 0x80000000)
195         ok( res == ERROR_INVALID_PARAMETER, "RegSetValueExA returned %d\n", res );
196     else
197         ok( !res, "RegSetValueExA returned %d\n", res );
198     res = RegSetValueExA( test_key, "Test", 0, REG_EXPAND_SZ, NULL, 0 );
199     ok( ERROR_SUCCESS == res || ERROR_INVALID_PARAMETER == res, "RegSetValueExA returned %d\n", res );
200     res = RegSetValueExA( test_key, "Test", 0, REG_BINARY, NULL, 0 );
201     ok( ERROR_SUCCESS == res || ERROR_INVALID_PARAMETER == res, "RegSetValueExA returned %d\n", res );
202
203     res = RegSetValueExA( test_key, "Test", 0, REG_SZ, (const BYTE *)"foobar", 7 );
204     ok( res == 0, "RegSetValueExA failed error %d\n", res );
205
206     /* overflow both name and data */
207     val_count = 2;
208     data_count = 2;
209     type = 1234;
210     strcpy( value, "xxxxxxxxxx" );
211     strcpy( data, "xxxxxxxxxx" );
212     res = RegEnumValueA( test_key, 0, value, &val_count, NULL, &type, (LPBYTE)data, &data_count );
213     ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %d\n", res );
214     ok( val_count == 2, "val_count set to %d\n", val_count );
215     ok( data_count == 7, "data_count set to %d instead of 7\n", data_count );
216     ok( type == REG_SZ, "type %d is not REG_SZ\n", type );
217     ok( !strcmp( value, "xxxxxxxxxx" ), "value set to '%s'\n", value );
218     ok( !strcmp( data, "xxxxxxxxxx" ), "data set to '%s'\n", data );
219
220     /* overflow name */
221     val_count = 3;
222     data_count = 20;
223     type = 1234;
224     strcpy( value, "xxxxxxxxxx" );
225     strcpy( data, "xxxxxxxxxx" );
226     res = RegEnumValueA( test_key, 0, value, &val_count, NULL, &type, (LPBYTE)data, &data_count );
227     ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %d\n", res );
228     /* Win9x returns 2 as specified by MSDN but NT returns 3... */
229     ok( val_count == 2 || val_count == 3, "val_count set to %d\n", val_count );
230     ok( data_count == 7, "data_count set to %d instead of 7\n", data_count );
231     ok( type == REG_SZ, "type %d is not REG_SZ\n", type );
232     /* v5.1.2600.0 (XP Home and Proffesional) does not touch value or data in this case */
233     ok( !strcmp( value, "Te" ) || !strcmp( value, "xxxxxxxxxx" ), 
234         "value set to '%s' instead of 'Te' or 'xxxxxxxxxx'\n", value );
235     ok( !strcmp( data, "foobar" ) || !strcmp( data, "xxxxxxx" ), 
236         "data set to '%s' instead of 'foobar' or 'xxxxxxx'\n", data );
237
238     /* overflow empty name */
239     val_count = 0;
240     data_count = 20;
241     type = 1234;
242     strcpy( value, "xxxxxxxxxx" );
243     strcpy( data, "xxxxxxxxxx" );
244     res = RegEnumValueA( test_key, 0, value, &val_count, NULL, &type, (LPBYTE)data, &data_count );
245     ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %d\n", res );
246     ok( val_count == 0, "val_count set to %d\n", val_count );
247     ok( data_count == 7, "data_count set to %d instead of 7\n", data_count );
248     ok( type == REG_SZ, "type %d is not REG_SZ\n", type );
249     ok( !strcmp( value, "xxxxxxxxxx" ), "value set to '%s'\n", value );
250     /* v5.1.2600.0 (XP Home and Professional) does not touch data in this case */
251     ok( !strcmp( data, "foobar" ) || !strcmp( data, "xxxxxxx" ), 
252         "data set to '%s' instead of 'foobar' or 'xxxxxxx'\n", data );
253
254     /* overflow data */
255     val_count = 20;
256     data_count = 2;
257     type = 1234;
258     strcpy( value, "xxxxxxxxxx" );
259     strcpy( data, "xxxxxxxxxx" );
260     res = RegEnumValueA( test_key, 0, value, &val_count, NULL, &type, (LPBYTE)data, &data_count );
261     ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %d\n", res );
262     ok( val_count == 20, "val_count set to %d\n", val_count );
263     ok( data_count == 7, "data_count set to %d instead of 7\n", data_count );
264     ok( type == REG_SZ, "type %d is not REG_SZ\n", type );
265     ok( !strcmp( value, "xxxxxxxxxx" ), "value set to '%s'\n", value );
266     ok( !strcmp( data, "xxxxxxxxxx" ), "data set to '%s'\n", data );
267
268     /* no overflow */
269     val_count = 20;
270     data_count = 20;
271     type = 1234;
272     strcpy( value, "xxxxxxxxxx" );
273     strcpy( data, "xxxxxxxxxx" );
274     res = RegEnumValueA( test_key, 0, value, &val_count, NULL, &type, (LPBYTE)data, &data_count );
275     ok( res == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", res );
276     ok( val_count == 4, "val_count set to %d instead of 4\n", val_count );
277     ok( data_count == 7, "data_count set to %d instead of 7\n", data_count );
278     ok( type == REG_SZ, "type %d is not REG_SZ\n", type );
279     ok( !strcmp( value, "Test" ), "value is '%s' instead of Test\n", value );
280     ok( !strcmp( data, "foobar" ), "data is '%s' instead of foobar\n", data );
281
282     /* Unicode tests */
283
284     SetLastError(0xdeadbeef);
285     res = RegSetValueExW( test_key, testW, 0, REG_SZ, (const BYTE *)foobarW, 7*sizeof(WCHAR) );
286     if (res==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
287     {
288         skip("RegSetValueExW is not implemented\n");
289         goto cleanup;
290     }
291     ok( res == 0, "RegSetValueExW failed error %d\n", res );
292
293     /* overflow both name and data */
294     val_count = 2;
295     data_count = 2;
296     type = 1234;
297     memcpy( valueW, xxxW, sizeof(xxxW) );
298     memcpy( dataW, xxxW, sizeof(xxxW) );
299     res = RegEnumValueW( test_key, 0, valueW, &val_count, NULL, &type, (BYTE*)dataW, &data_count );
300     ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %d\n", res );
301     ok( val_count == 2, "val_count set to %d\n", val_count );
302     ok( data_count == 7*sizeof(WCHAR), "data_count set to %d instead of 7*sizeof(WCHAR)\n", data_count );
303     ok( type == REG_SZ, "type %d is not REG_SZ\n", type );
304     ok( !memcmp( valueW, xxxW, sizeof(xxxW) ), "value modified\n" );
305     ok( !memcmp( dataW, xxxW, sizeof(xxxW) ), "data modified\n" );
306
307     /* overflow name */
308     val_count = 3;
309     data_count = 20;
310     type = 1234;
311     memcpy( valueW, xxxW, sizeof(xxxW) );
312     memcpy( dataW, xxxW, sizeof(xxxW) );
313     res = RegEnumValueW( test_key, 0, valueW, &val_count, NULL, &type, (BYTE*)dataW, &data_count );
314     ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %d\n", res );
315     ok( val_count == 3, "val_count set to %d\n", val_count );
316     ok( data_count == 7*sizeof(WCHAR), "data_count set to %d instead of 7*sizeof(WCHAR)\n", data_count );
317     ok( type == REG_SZ, "type %d is not REG_SZ\n", type );
318     ok( !memcmp( valueW, xxxW, sizeof(xxxW) ), "value modified\n" );
319     ok( !memcmp( dataW, xxxW, sizeof(xxxW) ), "data modified\n" );
320
321     /* overflow data */
322     val_count = 20;
323     data_count = 2;
324     type = 1234;
325     memcpy( valueW, xxxW, sizeof(xxxW) );
326     memcpy( dataW, xxxW, sizeof(xxxW) );
327     res = RegEnumValueW( test_key, 0, valueW, &val_count, NULL, &type, (BYTE*)dataW, &data_count );
328     ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %d\n", res );
329     ok( val_count == 4, "val_count set to %d instead of 4\n", val_count );
330     ok( data_count == 7*sizeof(WCHAR), "data_count set to %d instead of 7*sizeof(WCHAR)\n", data_count );
331     ok( type == REG_SZ, "type %d is not REG_SZ\n", type );
332     ok( !memcmp( valueW, testW, sizeof(testW) ), "value is not 'Test'\n" );
333     ok( !memcmp( dataW, xxxW, sizeof(xxxW) ), "data modified\n" );
334
335     /* no overflow */
336     val_count = 20;
337     data_count = 20;
338     type = 1234;
339     memcpy( valueW, xxxW, sizeof(xxxW) );
340     memcpy( dataW, xxxW, sizeof(xxxW) );
341     res = RegEnumValueW( test_key, 0, valueW, &val_count, NULL, &type, (BYTE*)dataW, &data_count );
342     ok( res == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", res );
343     ok( val_count == 4, "val_count set to %d instead of 4\n", val_count );
344     ok( data_count == 7*sizeof(WCHAR), "data_count set to %d instead of 7*sizeof(WCHAR)\n", data_count );
345     ok( type == REG_SZ, "type %d is not REG_SZ\n", type );
346     ok( !memcmp( valueW, testW, sizeof(testW) ), "value is not 'Test'\n" );
347     ok( !memcmp( dataW, foobarW, sizeof(foobarW) ), "data is not 'foobar'\n" );
348
349 cleanup:
350     RegDeleteKeyA(test_key, "");
351     RegCloseKey(test_key);
352 }
353
354 static void test_query_value_ex(void)
355 {
356     DWORD ret;
357     DWORD size;
358     DWORD type;
359     BYTE buffer[10];
360     
361     ret = RegQueryValueExA(hkey_main, "TP1_SZ", NULL, &type, NULL, &size);
362     ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret);
363     ok(size == strlen(sTestpath1) + 1, "(%d,%d)\n", (DWORD)strlen(sTestpath1) + 1, size);
364     ok(type == REG_SZ, "type %d is not REG_SZ\n", type);
365
366     type = 0xdeadbeef;
367     size = 0xdeadbeef;
368     ret = RegQueryValueExA(HKEY_CLASSES_ROOT, "Nonexistent Value", NULL, &type, NULL, &size);
369     ok(ret == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %d\n", ret);
370     ok(size == 0, "size should have been set to 0 instead of %d\n", size);
371     /* the type parameter is cleared on Win9x, but is set to a random value on
372      * NT, so don't do this test there */
373     if (GetVersion() & 0x80000000)
374         ok(type == 0, "type should have been set to 0 instead of 0x%x\n", type);
375     else
376         trace("test_query_value_ex: type set to: 0x%08x\n", type);
377
378     size = sizeof(buffer);
379     ret = RegQueryValueExA(HKEY_CLASSES_ROOT, "Nonexistent Value", NULL, &type, buffer, &size);
380     ok(ret == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %d\n", ret);
381     ok(size == sizeof(buffer), "size shouldn't have been changed to %d\n", size);
382 }
383
384 static void test_get_value(void)
385 {
386     DWORD ret;
387     DWORD size;
388     DWORD type;
389     DWORD dw, qw[2];
390     CHAR buf[80];
391     CHAR expanded[] = "bar\\subdir1";
392    
393     if(!pRegGetValueA)
394     {
395         skip("RegGetValue not available on this platform\n");
396         return;
397     }
398
399     /* Query REG_DWORD using RRF_RT_REG_DWORD (ok) */
400     size = type = dw = 0xdeadbeef;
401     ret = pRegGetValueA(hkey_main, NULL, "DWORD", RRF_RT_REG_DWORD, &type, &dw, &size);
402     ok(ret == ERROR_SUCCESS, "ret=%d\n", ret);
403     ok(size == 4, "size=%d\n", size);
404     ok(type == REG_DWORD, "type=%d\n", type);
405     ok(dw == 0x12345678, "dw=%d\n", dw);
406
407     /* Query by subkey-name */
408     ret = pRegGetValueA(HKEY_CURRENT_USER, "Software\\Wine\\Test", "DWORD", RRF_RT_REG_DWORD, NULL, NULL, NULL);
409     ok(ret == ERROR_SUCCESS, "ret=%d\n", ret);
410
411     /* Query REG_DWORD using RRF_RT_REG_BINARY (restricted) */
412     size = type = dw = 0xdeadbeef;
413     ret = pRegGetValueA(hkey_main, NULL, "DWORD", RRF_RT_REG_BINARY, &type, &dw, &size);
414     ok(ret == ERROR_UNSUPPORTED_TYPE, "ret=%d\n", ret);
415     /* Although the function failed all values are retrieved */
416     ok(size == 4, "size=%d\n", size);
417     ok(type == REG_DWORD, "type=%d\n", type);
418     ok(dw == 0x12345678, "dw=%d\n", dw);
419
420     /* Test RRF_ZEROONFAILURE */
421     type = dw = 0xdeadbeef; size = 4;
422     ret = pRegGetValueA(hkey_main, NULL, "DWORD", RRF_RT_REG_SZ|RRF_ZEROONFAILURE, &type, &dw, &size);
423     ok(ret == ERROR_UNSUPPORTED_TYPE, "ret=%d\n", ret);
424     /* Again all values are retrieved ... */
425     ok(size == 4, "size=%d\n", size);
426     ok(type == REG_DWORD, "type=%d\n", type);
427     /* ... except the buffer, which is zeroed out */
428     ok(dw == 0, "dw=%d\n", dw);
429
430     /* Query REG_DWORD using RRF_RT_DWORD (ok) */
431     size = type = dw = 0xdeadbeef;
432     ret = pRegGetValueA(hkey_main, NULL, "DWORD", RRF_RT_DWORD, &type, &dw, &size);
433     ok(ret == ERROR_SUCCESS, "ret=%d\n", ret);
434     ok(size == 4, "size=%d\n", size);
435     ok(type == REG_DWORD, "type=%d\n", type);
436     ok(dw == 0x12345678, "dw=%d\n", dw);
437
438     /* Query 32-bit REG_BINARY using RRF_RT_DWORD (ok) */
439     size = type = dw = 0xdeadbeef;
440     ret = pRegGetValueA(hkey_main, NULL, "BIN32", RRF_RT_DWORD, &type, &dw, &size);
441     ok(ret == ERROR_SUCCESS, "ret=%d\n", ret);
442     ok(size == 4, "size=%d\n", size);
443     ok(type == REG_BINARY, "type=%d\n", type);
444     ok(dw == 0x12345678, "dw=%d\n", dw);
445     
446     /* Query 64-bit REG_BINARY using RRF_RT_DWORD (type mismatch) */
447     qw[0] = qw[1] = size = type = 0xdeadbeef;
448     ret = pRegGetValueA(hkey_main, NULL, "BIN64", RRF_RT_DWORD, &type, qw, &size);
449     ok(ret == ERROR_DATATYPE_MISMATCH, "ret=%d\n", ret);
450     ok(size == 8, "size=%d\n", size);
451     ok(type == REG_BINARY, "type=%d\n", type);
452     ok(qw[0] == 0x12345678 && 
453        qw[1] == 0x87654321, "qw={%d,%d}\n", qw[0], qw[1]);
454     
455     /* Query 64-bit REG_BINARY using 32-bit buffer (buffer too small) */
456     type = dw = 0xdeadbeef; size = 4;
457     ret = pRegGetValueA(hkey_main, NULL, "BIN64", RRF_RT_REG_BINARY, &type, &dw, &size);
458     ok(ret == ERROR_MORE_DATA, "ret=%d\n", ret);
459     ok(dw == 0xdeadbeef, "dw=%d\n", dw);
460     ok(size == 8, "size=%d\n", size);
461
462     /* Query 64-bit REG_BINARY using RRF_RT_QWORD (ok) */
463     qw[0] = qw[1] = size = type = 0xdeadbeef;
464     ret = pRegGetValueA(hkey_main, NULL, "BIN64", RRF_RT_QWORD, &type, qw, &size);
465     ok(ret == ERROR_SUCCESS, "ret=%d\n", ret);
466     ok(size == 8, "size=%d\n", size);
467     ok(type == REG_BINARY, "type=%d\n", type);
468     ok(qw[0] == 0x12345678 &&
469        qw[1] == 0x87654321, "qw={%d,%d}\n", qw[0], qw[1]);
470
471     /* Query REG_SZ using RRF_RT_REG_SZ (ok) */
472     buf[0] = 0; type = 0xdeadbeef; size = sizeof(buf);
473     ret = pRegGetValueA(hkey_main, NULL, "TP1_SZ", RRF_RT_REG_SZ, &type, buf, &size);
474     ok(ret == ERROR_SUCCESS, "ret=%d\n", ret);
475     ok(size == strlen(sTestpath1)+1, "strlen(sTestpath1)=%d size=%d\n", lstrlenA(sTestpath1), size);
476     ok(type == REG_SZ, "type=%d\n", type);
477     ok(!strcmp(sTestpath1, buf), "sTestpath=\"%s\" buf=\"%s\"\n", sTestpath1, buf);
478
479     /* Query REG_SZ using RRF_RT_REG_SZ|RRF_NOEXPAND (ok) */
480     buf[0] = 0; type = 0xdeadbeef; size = sizeof(buf);
481     ret = pRegGetValueA(hkey_main, NULL, "TP1_SZ", RRF_RT_REG_SZ|RRF_NOEXPAND, &type, buf, &size);
482     ok(ret == ERROR_SUCCESS, "ret=%d\n", ret);
483     ok(size == strlen(sTestpath1)+1, "strlen(sTestpath1)=%d size=%d\n", lstrlenA(sTestpath1), size);
484     ok(type == REG_SZ, "type=%d\n", type);
485     ok(!strcmp(sTestpath1, buf), "sTestpath=\"%s\" buf=\"%s\"\n", sTestpath1, buf);
486
487     /* Query REG_EXPAND_SZ using RRF_RT_REG_SZ (ok, expands) */
488     buf[0] = 0; type = 0xdeadbeef; size = sizeof(buf);
489     ret = pRegGetValueA(hkey_main, NULL, "TP1_EXP_SZ", RRF_RT_REG_SZ, &type, buf, &size);
490     ok(ret == ERROR_SUCCESS, "ret=%d\n", ret);
491     /* At least v5.2.3790.1830 (2003 SP1) returns the unexpanded sTestpath1 length + 1 here. */
492     ok((size == strlen(expanded)+1) || (size == strlen(sTestpath1)+1), 
493         "strlen(expanded)=%d, strlen(sTestpath1)=%d, size=%d\n", lstrlenA(expanded), lstrlenA(sTestpath1), size);
494     ok(type == REG_SZ, "type=%d\n", type);
495     ok(!strcmp(expanded, buf), "expanded=\"%s\" buf=\"%s\"\n", expanded, buf);
496     
497     /* Query REG_EXPAND_SZ using RRF_RT_REG_EXPAND_SZ|RRF_NOEXPAND (ok, doesn't expand) */
498     buf[0] = 0; type = 0xdeadbeef; size = sizeof(buf);
499     ret = pRegGetValueA(hkey_main, NULL, "TP1_EXP_SZ", RRF_RT_REG_EXPAND_SZ|RRF_NOEXPAND, &type, buf, &size);
500     ok(ret == ERROR_SUCCESS, "ret=%d\n", ret);
501     ok(size == strlen(sTestpath1)+1, "strlen(sTestpath1)=%d size=%d\n", lstrlenA(sTestpath1), size);
502     ok(type == REG_EXPAND_SZ, "type=%d\n", type);
503     ok(!strcmp(sTestpath1, buf), "sTestpath=\"%s\" buf=\"%s\"\n", sTestpath1, buf);
504     
505     /* Query REG_EXPAND_SZ using RRF_RT_REG_SZ|RRF_NOEXPAND (type mismatch) */
506     ret = pRegGetValueA(hkey_main, NULL, "TP1_EXP_SZ", RRF_RT_REG_SZ|RRF_NOEXPAND, NULL, NULL, NULL);
507     ok(ret == ERROR_UNSUPPORTED_TYPE, "ret=%d\n", ret);
508
509     /* Query REG_EXPAND_SZ using RRF_RT_REG_EXPAND_SZ (not allowed without RRF_NOEXPAND) */
510     ret = pRegGetValueA(hkey_main, NULL, "TP1_EXP_SZ", RRF_RT_REG_EXPAND_SZ, NULL, NULL, NULL);
511     ok(ret == ERROR_INVALID_PARAMETER, "ret=%d\n", ret);
512
513
514 static void test_reg_open_key(void)
515 {
516     DWORD ret = 0;
517     HKEY hkResult = NULL;
518     HKEY hkPreserve = NULL;
519
520     /* successful open */
521     ret = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test", &hkResult);
522     ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret);
523     ok(hkResult != NULL, "expected hkResult != NULL\n");
524     hkPreserve = hkResult;
525
526     /* these tests fail on Win9x, but we want to be compatible with NT, so
527      * run them if we can */
528     if (!(GetVersion() & 0x80000000))
529     {
530         /* open same key twice */
531         ret = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test", &hkResult);
532         ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret);
533         ok(hkResult != hkPreserve, "epxected hkResult != hkPreserve\n");
534         ok(hkResult != NULL, "hkResult != NULL\n");
535         RegCloseKey(hkResult);
536     
537         /* open nonexistent key
538         * check that hkResult is set to NULL
539         */
540         hkResult = hkPreserve;
541         ret = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Nonexistent", &hkResult);
542         ok(ret == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %d\n", ret);
543         ok(hkResult == NULL, "expected hkResult == NULL\n");
544     
545         /* open the same nonexistent key again to make sure the key wasn't created */
546         hkResult = hkPreserve;
547         ret = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Nonexistent", &hkResult);
548         ok(ret == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %d\n", ret);
549         ok(hkResult == NULL, "expected hkResult == NULL\n");
550     
551         /* send in NULL lpSubKey
552         * check that hkResult receives the value of hKey
553         */
554         hkResult = hkPreserve;
555         ret = RegOpenKeyA(HKEY_CURRENT_USER, NULL, &hkResult);
556         ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret);
557         ok(hkResult == HKEY_CURRENT_USER, "expected hkResult == HKEY_CURRENT_USER\n");
558     
559         /* send empty-string in lpSubKey */
560         hkResult = hkPreserve;
561         ret = RegOpenKeyA(HKEY_CURRENT_USER, "", &hkResult);
562         ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret);
563         ok(hkResult == HKEY_CURRENT_USER, "expected hkResult == HKEY_CURRENT_USER\n");
564     
565         /* send in NULL lpSubKey and NULL hKey
566         * hkResult is set to NULL
567         */
568         hkResult = hkPreserve;
569         ret = RegOpenKeyA(NULL, NULL, &hkResult);
570         ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret);
571         ok(hkResult == NULL, "expected hkResult == NULL\n");
572     }
573
574     /* only send NULL hKey
575      * the value of hkResult remains unchanged
576      */
577     hkResult = hkPreserve;
578     ret = RegOpenKeyA(NULL, "Software\\Wine\\Test", &hkResult);
579     ok(ret == ERROR_INVALID_HANDLE || ret == ERROR_BADKEY, /* Windows 95 returns BADKEY */
580        "expected ERROR_INVALID_HANDLE or ERROR_BADKEY, got %d\n", ret);
581     ok(hkResult == hkPreserve, "expected hkResult == hkPreserve\n");
582     RegCloseKey(hkResult);
583
584     /* send in NULL hkResult */
585     ret = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test", NULL);
586     ok(ret == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", ret);
587
588     /*  beginning backslash character */
589     ret = RegOpenKeyA(HKEY_CURRENT_USER, "\\Software\\Wine\\Test", &hkResult);
590        ok(ret == ERROR_BAD_PATHNAME || /* NT/2k/XP */
591            ret == ERROR_FILE_NOT_FOUND /* Win9x,ME */
592            , "expected ERROR_BAD_PATHNAME or ERROR_FILE_NOT_FOUND, got %d\n", ret);
593 }
594
595 static void test_reg_create_key(void)
596 {
597     LONG ret;
598     HKEY hkey1, hkey2;
599     ret = RegCreateKeyExA(hkey_main, "Subkey1", 0, NULL, 0, KEY_NOTIFY, NULL, &hkey1, NULL);
600     ok(!ret, "RegCreateKeyExA failed with error %d\n", ret);
601     /* should succeed: all versions of Windows ignore the access rights
602      * to the parent handle */
603     ret = RegCreateKeyExA(hkey1, "Subkey2", 0, NULL, 0, KEY_SET_VALUE, NULL, &hkey2, NULL);
604     ok(!ret, "RegCreateKeyExA failed with error %d\n", ret);
605
606     /* clean up */
607     RegDeleteKey(hkey2, "");
608     RegDeleteKey(hkey1, "");
609
610     /*  beginning backslash character */
611     ret = RegCreateKeyExA(hkey_main, "\\Subkey3", 0, NULL, 0, KEY_NOTIFY, NULL, &hkey1, NULL);
612     if (!(GetVersion() & 0x80000000))
613         ok(ret == ERROR_BAD_PATHNAME, "expected ERROR_BAD_PATHNAME, got %d\n", ret);
614     else {
615         ok(!ret, "RegCreateKeyExA failed with error %d\n", ret);
616         RegDeleteKey(hkey1, NULL);
617     }
618 }
619
620 static void test_reg_close_key(void)
621 {
622     DWORD ret = 0;
623     HKEY hkHandle;
624
625     /* successfully close key
626      * hkHandle remains changed after call to RegCloseKey
627      */
628     ret = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test", &hkHandle);
629     ret = RegCloseKey(hkHandle);
630     ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret);
631
632     /* try to close the key twice */
633     ret = RegCloseKey(hkHandle); /* Windows 95 doesn't mind. */
634     ok(ret == ERROR_INVALID_HANDLE || ret == ERROR_SUCCESS,
635        "expected ERROR_INVALID_HANDLE or ERROR_SUCCESS, got %d\n", ret);
636     
637     /* try to close a NULL handle */
638     ret = RegCloseKey(NULL);
639     ok(ret == ERROR_INVALID_HANDLE || ret == ERROR_BADKEY, /* Windows 95 returns BADKEY */
640        "expected ERROR_INVALID_HANDLE or ERROR_BADKEY, got %d\n", ret);
641
642     /* Check to see if we didn't potentially close our main handle, which could happen on win98 as
643      * win98 doesn't give a new handle when the same key is opened.
644      * Not re-opening will make some next tests fail.
645      */
646     if (hkey_main == hkHandle)
647     {
648         trace("The main handle is most likely closed, so re-opening\n");
649         RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Test", &hkey_main );
650     }
651 }
652
653 static void test_reg_delete_key(void)
654 {
655     DWORD ret;
656
657     ret = RegDeleteKey(hkey_main, NULL);
658     ok(ret == ERROR_INVALID_PARAMETER ||
659        ret == ERROR_ACCESS_DENIED ||
660        ret == ERROR_BADKEY, /* Win95 */
661        "ret=%d\n", ret);
662 }
663
664 static void test_reg_save_key(void)
665 {
666     DWORD ret;
667
668     ret = RegSaveKey(hkey_main, "saved_key", NULL);
669     ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret);
670 }
671
672 static void test_reg_load_key(void)
673 {
674     DWORD ret;
675     HKEY hkHandle;
676
677     ret = RegLoadKey(HKEY_LOCAL_MACHINE, "Test", "saved_key");
678     ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret);
679
680     ret = RegOpenKey(HKEY_LOCAL_MACHINE, "Test", &hkHandle);
681     ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret);
682
683     RegCloseKey(hkHandle);
684 }
685
686 static void test_reg_unload_key(void)
687 {
688     DWORD ret;
689
690     ret = RegUnLoadKey(HKEY_LOCAL_MACHINE, "Test");
691     ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret);
692
693     DeleteFile("saved_key");
694     DeleteFile("saved_key.LOG");
695 }
696
697 static BOOL set_privileges(LPCSTR privilege, BOOL set)
698 {
699     TOKEN_PRIVILEGES tp;
700     HANDLE hToken;
701     LUID luid;
702
703     if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
704         return FALSE;
705
706     if(!LookupPrivilegeValue(NULL, privilege, &luid))
707     {
708         CloseHandle(hToken);
709         return FALSE;
710     }
711
712     tp.PrivilegeCount = 1;
713     tp.Privileges[0].Luid = luid;
714     
715     if (set)
716         tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
717     else
718         tp.Privileges[0].Attributes = 0;
719
720     AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
721     if (GetLastError() != ERROR_SUCCESS)
722     {
723         CloseHandle(hToken);
724         return FALSE;
725     }
726
727     CloseHandle(hToken);
728     return TRUE;
729 }
730
731 /* tests that show that RegConnectRegistry and 
732    OpenSCManager accept computer names without the
733    \\ prefix (what MSDN says).   */
734 static void test_regconnectregistry( void)
735 {
736     CHAR compName[MAX_COMPUTERNAME_LENGTH + 1];
737     CHAR netwName[MAX_COMPUTERNAME_LENGTH + 3]; /* 2 chars for double backslash */
738     DWORD len = sizeof(compName) ;
739     BOOL ret;
740     LONG retl;
741     HKEY hkey;
742     SC_HANDLE schnd;
743     DWORD GLE;
744
745     ret = GetComputerNameA(compName, &len);
746     ok( ret, "GetComputerName failed err = %d\n", GetLastError());
747     if( !ret) return;
748
749     lstrcpyA(netwName, "\\\\");
750     lstrcpynA(netwName+2, compName, MAX_COMPUTERNAME_LENGTH + 1);
751
752     retl = RegConnectRegistryA( compName, HKEY_LOCAL_MACHINE, &hkey);
753     ok( !retl || retl == ERROR_DLL_INIT_FAILED, "RegConnectRegistryA failed err = %d\n", retl);
754     if( !retl) RegCloseKey( hkey);
755
756     retl = RegConnectRegistryA( netwName, HKEY_LOCAL_MACHINE, &hkey);
757     ok( !retl || retl == ERROR_DLL_INIT_FAILED, "RegConnectRegistryA failed err = %d\n", retl);
758     if( !retl) RegCloseKey( hkey);
759
760     schnd = OpenSCManagerA( compName, NULL, GENERIC_READ); 
761     GLE = GetLastError();
762     ok( schnd != NULL || GLE==ERROR_CALL_NOT_IMPLEMENTED, 
763         "OpenSCManagerA failed err = %d\n", GLE);
764     CloseServiceHandle( schnd);
765
766     schnd = OpenSCManagerA( netwName, NULL, GENERIC_READ); 
767     GLE = GetLastError();
768     ok( schnd != NULL || GLE==ERROR_CALL_NOT_IMPLEMENTED, 
769         "OpenSCManagerA failed err = %d\n", GLE);
770     CloseServiceHandle( schnd);
771
772 }
773
774 static void test_reg_query_value(void)
775 {
776     HKEY subkey;
777     CHAR val[MAX_PATH];
778     WCHAR valW[5];
779     LONG size, ret;
780
781     static const WCHAR expected[] = {'d','a','t','a',0};
782
783     ret = RegCreateKeyA(hkey_main, "subkey", &subkey);
784     ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
785
786     ret = RegSetValueA(subkey, NULL, REG_SZ, "data", 4);
787     ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
788
789     /* try an invalid hkey */
790     SetLastError(0xdeadbeef);
791     size = MAX_PATH;
792     ret = RegQueryValueA((HKEY)0xcafebabe, "subkey", val, &size);
793     ok(ret == ERROR_INVALID_HANDLE || ret == ERROR_BADKEY, /* Windows 98 returns BADKEY */
794        "Expected ERROR_INVALID_HANDLE or ERROR_BADKEY, got %d\n", ret);
795     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
796
797     /* try a NULL hkey */
798     SetLastError(0xdeadbeef);
799     size = MAX_PATH;
800     ret = RegQueryValueA(NULL, "subkey", val, &size);
801     ok(ret == ERROR_INVALID_HANDLE || ret == ERROR_BADKEY, /* Windows 98 returns BADKEY */
802        "Expected ERROR_INVALID_HANDLE or ERROR_BADKEY, got %d\n", ret);
803     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
804
805     /* try a NULL value */
806     size = MAX_PATH;
807     ret = RegQueryValueA(hkey_main, "subkey", NULL, &size);
808     ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
809     ok(size == 5, "Expected 5, got %d\n", size);
810
811     /* try a NULL size */
812     SetLastError(0xdeadbeef);
813     val[0] = '\0';
814     ret = RegQueryValueA(hkey_main, "subkey", val, NULL);
815     ok(ret == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", ret);
816     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
817     ok(lstrlenA(val) == 0, "Expected val to be untouched, got %s\n", val);
818
819     /* try a NULL value and size */
820     ret = RegQueryValueA(hkey_main, "subkey", NULL, NULL);
821     ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
822
823     /* try a size too small */
824     SetLastError(0xdeadbeef);
825     val[0] = '\0';
826     size = 1;
827     ret = RegQueryValueA(hkey_main, "subkey", val, &size);
828     ok(ret == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", ret);
829     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
830     ok(lstrlenA(val) == 0, "Expected val to be untouched, got %s\n", val);
831     ok(size == 5, "Expected 5, got %d\n", size);
832
833     /* successfully read the value using 'subkey' */
834     size = MAX_PATH;
835     ret = RegQueryValueA(hkey_main, "subkey", val, &size);
836     ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
837     ok(!lstrcmpA(val, "data"), "Expected 'data', got '%s'\n", val);
838     ok(size == 5, "Expected 5, got %d\n", size);
839
840     /* successfully read the value using the subkey key */
841     size = MAX_PATH;
842     ret = RegQueryValueA(subkey, NULL, val, &size);
843     ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
844     ok(!lstrcmpA(val, "data"), "Expected 'data', got '%s'\n", val);
845     ok(size == 5, "Expected 5, got %d\n", size);
846
847     /* unicode - try size too small */
848     SetLastError(0xdeadbeef);
849     valW[0] = '\0';
850     size = 0;
851     ret = RegQueryValueW(subkey, NULL, valW, &size);
852     if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
853     {
854         skip("RegQueryValueW is not implemented\n");
855         goto cleanup;
856     }
857     ok(ret == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", ret);
858     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
859     ok(lstrlenW(valW) == 0, "Expected valW to be untouched\n");
860     ok(size == sizeof(expected), "Got wrong size: %d\n", size);
861
862     /* unicode - try size in WCHARS */
863     SetLastError(0xdeadbeef);
864     size = sizeof(valW) / sizeof(WCHAR);
865     ret = RegQueryValueW(subkey, NULL, valW, &size);
866     ok(ret == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", ret);
867     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
868     ok(lstrlenW(valW) == 0, "Expected valW to be untouched\n");
869     ok(size == sizeof(expected), "Got wrong size: %d\n", size);
870
871     /* unicode - successfully read the value */
872     size = sizeof(valW);
873     ret = RegQueryValueW(subkey, NULL, valW, &size);
874     ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
875     ok(!lstrcmpW(valW, expected), "Got wrong value\n");
876     ok(size == sizeof(expected), "Got wrong size: %d\n", size);
877
878     /* unicode - set the value without a NULL terminator */
879     ret = RegSetValueW(subkey, NULL, REG_SZ, expected, sizeof(expected)-sizeof(WCHAR));
880     ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
881
882     /* unicode - read the unterminated value, value is terminated for us */
883     memset(valW, 'a', sizeof(valW));
884     size = sizeof(valW);
885     ret = RegQueryValueW(subkey, NULL, valW, &size);
886     ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
887     ok(!lstrcmpW(valW, expected), "Got wrong value\n");
888     ok(size == sizeof(expected), "Got wrong size: %d\n", size);
889
890 cleanup:
891     RegDeleteKeyA(subkey, "");
892     RegCloseKey(subkey);
893 }
894
895 START_TEST(registry)
896 {
897     /* Load pointers for functions that are not available in all Windows versions */
898     InitFunctionPtrs();
899
900     setup_main_key();
901     test_set_value();
902     create_test_entries();
903     test_enum_value();
904     test_query_value_ex();
905     test_get_value();
906     test_reg_open_key();
907     test_reg_create_key();
908     test_reg_close_key();
909     test_reg_delete_key();
910     test_reg_query_value();
911
912     /* SaveKey/LoadKey require the SE_BACKUP_NAME privilege to be set */
913     if (set_privileges(SE_BACKUP_NAME, TRUE) &&
914         set_privileges(SE_RESTORE_NAME, TRUE))
915     {
916         test_reg_save_key();
917         test_reg_load_key();
918         test_reg_unload_key();
919
920         set_privileges(SE_BACKUP_NAME, FALSE);
921         set_privileges(SE_RESTORE_NAME, FALSE);
922     }
923
924     /* cleanup */
925     delete_key( hkey_main );
926     
927     test_regconnectregistry();
928 }