2 * Unit tests for registry functions
4 * Copyright (c) 2002 Alexandre Julliard
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.
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.
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
23 #include "wine/test.h"
30 static HKEY hkey_main
;
33 static const char * sTestpath1
= "%LONGSYSTEMVAR%\\subdir1";
34 static const char * sTestpath2
= "%FOO%\\subdir1";
36 static HMODULE hadvapi32
;
37 static DWORD (WINAPI
*pRegGetValueA
)(HKEY
,LPCSTR
,LPCSTR
,DWORD
,LPDWORD
,PVOID
,LPDWORD
);
38 static DWORD (WINAPI
*pRegDeleteTreeA
)(HKEY
,LPCSTR
);
40 #define ADVAPI32_GET_PROC(func) \
41 p ## func = (void*)GetProcAddress(hadvapi32, #func); \
43 trace("GetProcAddress(%s) failed\n", #func);
45 static void InitFunctionPtrs(void)
47 hadvapi32
= GetModuleHandleA("advapi32.dll");
49 /* This function was introduced with Windows 2003 SP1 */
50 ADVAPI32_GET_PROC(RegGetValueA
)
51 ADVAPI32_GET_PROC(RegDeleteTreeA
)
54 /* delete key and all its subkeys */
55 static DWORD
delete_key( HKEY hkey
)
60 while (!(ret
= RegEnumKeyA(hkey
, 0, name
, sizeof(name
))))
63 if (!(ret
= RegOpenKeyExA( hkey
, name
, 0, KEY_ENUMERATE_SUB_KEYS
, &tmp
)))
65 ret
= delete_key( tmp
);
70 if (ret
!= ERROR_NO_MORE_ITEMS
) return ret
;
71 RegDeleteKeyA( hkey
, "" );
75 static void setup_main_key(void)
77 if (RegOpenKeyA( HKEY_CURRENT_USER
, "Software\\Wine\\Test", &hkey_main
)) delete_key( hkey_main
);
79 assert (!RegCreateKeyA( HKEY_CURRENT_USER
, "Software\\Wine\\Test", &hkey_main
));
82 static void test_hkey_main_Value_A(LPCSTR name
, LPCSTR string
)
84 DWORD ret
, type
, cbData
;
85 DWORD str_byte_len
, full_byte_len
;
87 ret
= RegQueryValueExA(hkey_main
, name
, NULL
, &type
, NULL
, &cbData
);
89 ok(ret
== ERROR_SUCCESS
, "RegQueryValueExA failed: %d, GLE=%d\n", ret
, GLE
);
90 if(GLE
== ERROR_CALL_NOT_IMPLEMENTED
) return;
92 str_byte_len
= lstrlenA(string
) + 1;
93 full_byte_len
= sizeof(string
);
94 ok(type
== REG_SZ
, "RegQueryValueExA returned type %d\n", type
);
95 ok(cbData
== full_byte_len
|| cbData
== str_byte_len
,
96 "cbData=%d instead of %d or %d\n", cbData
, full_byte_len
, str_byte_len
);
99 static void test_hkey_main_Value_W(LPCWSTR name
, LPCWSTR string
)
101 DWORD ret
, type
, cbData
;
102 DWORD str_byte_len
, full_byte_len
;
104 ret
= RegQueryValueExW(hkey_main
, name
, NULL
, &type
, NULL
, &cbData
);
105 GLE
= GetLastError();
106 ok(ret
== ERROR_SUCCESS
, "RegQueryValueExW failed: %d, GLE=%d\n", ret
, GLE
);
107 if(GLE
== ERROR_CALL_NOT_IMPLEMENTED
) return;
109 str_byte_len
= (lstrlenW(string
) + 1) * sizeof(WCHAR
);
110 full_byte_len
= sizeof(string
);
111 ok(type
== REG_SZ
, "RegQueryValueExW returned type %d\n", type
);
112 ok(cbData
== full_byte_len
|| cbData
== str_byte_len
,
113 "cbData=%d instead of %d or %d\n", cbData
, full_byte_len
, str_byte_len
);
116 static void test_set_value(void)
120 static const WCHAR name1W
[] = {'C','l','e','a','n','S','i','n','g','l','e','S','t','r','i','n','g', 0};
121 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};
122 static const WCHAR string1W
[] = {'T','h','i','s','N','e','v','e','r','B','r','e','a','k','s', 0};
123 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};
125 static const char name1A
[] = "CleanSingleString";
126 static const char name2A
[] = "SomeIntraZeroedString";
127 static const char string1A
[] = "ThisNeverBreaks";
128 static const char string2A
[] = "This\0Breaks\0\0A\0\0\0Lot\0\0\0\0";
130 /* test RegSetValueExA with normal string */
131 ret
= RegSetValueExA(hkey_main
, name1A
, 0, REG_SZ
, (const BYTE
*)string1A
, sizeof(string1A
));
132 ok(ret
== ERROR_SUCCESS
, "RegSetValueExA failed: %d, GLE=%d\n", ret
, GetLastError());
133 test_hkey_main_Value_A(name1A
, string1A
);
134 test_hkey_main_Value_W(name1W
, string1W
);
136 /* test RegSetValueExA with intrazeroed string */
137 ret
= RegSetValueExA(hkey_main
, name2A
, 0, REG_SZ
, (const BYTE
*)string2A
, sizeof(string2A
));
138 ok(ret
== ERROR_SUCCESS
, "RegSetValueExA failed: %d, GLE=%d\n", ret
, GetLastError());
139 test_hkey_main_Value_A(name1A
, string1A
);
140 test_hkey_main_Value_W(name1W
, string1W
);
142 /* 9x doesn't support W-calls, so don't test them then */
143 if(GLE
== ERROR_CALL_NOT_IMPLEMENTED
) return;
145 /* test RegSetValueExW with normal string */
146 ret
= RegSetValueExW(hkey_main
, name1W
, 0, REG_SZ
, (const BYTE
*)string1W
, sizeof(string1W
));
147 ok(ret
== ERROR_SUCCESS
, "RegSetValueExW failed: %d, GLE=%d\n", ret
, GetLastError());
148 test_hkey_main_Value_A(name1A
, string1A
);
149 test_hkey_main_Value_W(name1W
, string1W
);
151 /* test RegSetValueExW with intrazeroed string */
152 ret
= RegSetValueExW(hkey_main
, name2W
, 0, REG_SZ
, (const BYTE
*)string2W
, sizeof(string2W
));
153 ok(ret
== ERROR_SUCCESS
, "RegSetValueExW failed: %d, GLE=%d\n", ret
, GetLastError());
154 test_hkey_main_Value_A(name1A
, string1A
);
155 test_hkey_main_Value_W(name1W
, string1W
);
158 static void create_test_entries(void)
160 static const DWORD qw
[2] = { 0x12345678, 0x87654321 };
162 SetEnvironmentVariableA("LONGSYSTEMVAR", "bar");
163 SetEnvironmentVariableA("FOO", "ImARatherLongButIndeedNeededString");
165 ok(!RegSetValueExA(hkey_main
,"TP1_EXP_SZ",0,REG_EXPAND_SZ
, (const BYTE
*)sTestpath1
, strlen(sTestpath1
)+1),
166 "RegSetValueExA failed\n");
167 ok(!RegSetValueExA(hkey_main
,"TP1_SZ",0,REG_SZ
, (const BYTE
*)sTestpath1
, strlen(sTestpath1
)+1),
168 "RegSetValueExA failed\n");
169 ok(!RegSetValueExA(hkey_main
,"TP2_EXP_SZ",0,REG_EXPAND_SZ
, (const BYTE
*)sTestpath2
, strlen(sTestpath2
)+1),
170 "RegSetValueExA failed\n");
171 ok(!RegSetValueExA(hkey_main
,"DWORD",0,REG_DWORD
, (const BYTE
*)qw
, 4),
172 "RegSetValueExA failed\n");
173 ok(!RegSetValueExA(hkey_main
,"BIN32",0,REG_BINARY
, (const BYTE
*)qw
, 4),
174 "RegSetValueExA failed\n");
175 ok(!RegSetValueExA(hkey_main
,"BIN64",0,REG_BINARY
, (const BYTE
*)qw
, 8),
176 "RegSetValueExA failed\n");
179 static void test_enum_value(void)
183 char value
[20], data
[20];
184 WCHAR valueW
[20], dataW
[20];
185 DWORD val_count
, data_count
, type
;
186 static const WCHAR foobarW
[] = {'f','o','o','b','a','r',0};
187 static const WCHAR testW
[] = {'T','e','s','t',0};
188 static const WCHAR xxxW
[] = {'x','x','x','x','x','x','x','x',0};
190 /* create the working key for new 'Test' value */
191 res
= RegCreateKeyA( hkey_main
, "TestKey", &test_key
);
192 ok( res
== ERROR_SUCCESS
, "expected ERROR_SUCCESS, got %d\n", res
);
194 /* check NULL data with zero length */
195 res
= RegSetValueExA( test_key
, "Test", 0, REG_SZ
, NULL
, 0 );
196 if (GetVersion() & 0x80000000)
197 ok( res
== ERROR_INVALID_PARAMETER
, "RegSetValueExA returned %d\n", res
);
199 ok( !res
, "RegSetValueExA returned %d\n", res
);
200 res
= RegSetValueExA( test_key
, "Test", 0, REG_EXPAND_SZ
, NULL
, 0 );
201 ok( ERROR_SUCCESS
== res
|| ERROR_INVALID_PARAMETER
== res
, "RegSetValueExA returned %d\n", res
);
202 res
= RegSetValueExA( test_key
, "Test", 0, REG_BINARY
, NULL
, 0 );
203 ok( ERROR_SUCCESS
== res
|| ERROR_INVALID_PARAMETER
== res
, "RegSetValueExA returned %d\n", res
);
205 res
= RegSetValueExA( test_key
, "Test", 0, REG_SZ
, (const BYTE
*)"foobar", 7 );
206 ok( res
== 0, "RegSetValueExA failed error %d\n", res
);
208 /* overflow both name and data */
212 strcpy( value
, "xxxxxxxxxx" );
213 strcpy( data
, "xxxxxxxxxx" );
214 res
= RegEnumValueA( test_key
, 0, value
, &val_count
, NULL
, &type
, (LPBYTE
)data
, &data_count
);
215 ok( res
== ERROR_MORE_DATA
, "expected ERROR_MORE_DATA, got %d\n", res
);
216 ok( val_count
== 2, "val_count set to %d\n", val_count
);
217 ok( data_count
== 7, "data_count set to %d instead of 7\n", data_count
);
218 ok( type
== REG_SZ
, "type %d is not REG_SZ\n", type
);
219 ok( !strcmp( value
, "xxxxxxxxxx" ), "value set to '%s'\n", value
);
220 ok( !strcmp( data
, "xxxxxxxxxx" ), "data set to '%s'\n", data
);
226 strcpy( value
, "xxxxxxxxxx" );
227 strcpy( data
, "xxxxxxxxxx" );
228 res
= RegEnumValueA( test_key
, 0, value
, &val_count
, NULL
, &type
, (LPBYTE
)data
, &data_count
);
229 ok( res
== ERROR_MORE_DATA
, "expected ERROR_MORE_DATA, got %d\n", res
);
230 /* Win9x returns 2 as specified by MSDN but NT returns 3... */
231 ok( val_count
== 2 || val_count
== 3, "val_count set to %d\n", val_count
);
232 ok( data_count
== 7, "data_count set to %d instead of 7\n", data_count
);
233 ok( type
== REG_SZ
, "type %d is not REG_SZ\n", type
);
234 /* v5.1.2600.0 (XP Home and Proffesional) does not touch value or data in this case */
235 ok( !strcmp( value
, "Te" ) || !strcmp( value
, "xxxxxxxxxx" ),
236 "value set to '%s' instead of 'Te' or 'xxxxxxxxxx'\n", value
);
237 ok( !strcmp( data
, "foobar" ) || !strcmp( data
, "xxxxxxx" ),
238 "data set to '%s' instead of 'foobar' or 'xxxxxxx'\n", data
);
240 /* overflow empty name */
244 strcpy( value
, "xxxxxxxxxx" );
245 strcpy( data
, "xxxxxxxxxx" );
246 res
= RegEnumValueA( test_key
, 0, value
, &val_count
, NULL
, &type
, (LPBYTE
)data
, &data_count
);
247 ok( res
== ERROR_MORE_DATA
, "expected ERROR_MORE_DATA, got %d\n", res
);
248 ok( val_count
== 0, "val_count set to %d\n", val_count
);
249 ok( data_count
== 7, "data_count set to %d instead of 7\n", data_count
);
250 ok( type
== REG_SZ
, "type %d is not REG_SZ\n", type
);
251 ok( !strcmp( value
, "xxxxxxxxxx" ), "value set to '%s'\n", value
);
252 /* v5.1.2600.0 (XP Home and Professional) does not touch data in this case */
253 ok( !strcmp( data
, "foobar" ) || !strcmp( data
, "xxxxxxx" ),
254 "data set to '%s' instead of 'foobar' or 'xxxxxxx'\n", data
);
260 strcpy( value
, "xxxxxxxxxx" );
261 strcpy( data
, "xxxxxxxxxx" );
262 res
= RegEnumValueA( test_key
, 0, value
, &val_count
, NULL
, &type
, (LPBYTE
)data
, &data_count
);
263 ok( res
== ERROR_MORE_DATA
, "expected ERROR_MORE_DATA, got %d\n", res
);
264 ok( val_count
== 20, "val_count set to %d\n", val_count
);
265 ok( data_count
== 7, "data_count set to %d instead of 7\n", data_count
);
266 ok( type
== REG_SZ
, "type %d is not REG_SZ\n", type
);
267 ok( !strcmp( value
, "xxxxxxxxxx" ), "value set to '%s'\n", value
);
268 ok( !strcmp( data
, "xxxxxxxxxx" ), "data set to '%s'\n", data
);
274 strcpy( value
, "xxxxxxxxxx" );
275 strcpy( data
, "xxxxxxxxxx" );
276 res
= RegEnumValueA( test_key
, 0, value
, &val_count
, NULL
, &type
, (LPBYTE
)data
, &data_count
);
277 ok( res
== ERROR_SUCCESS
, "expected ERROR_SUCCESS, got %d\n", res
);
278 ok( val_count
== 4, "val_count set to %d instead of 4\n", val_count
);
279 ok( data_count
== 7, "data_count set to %d instead of 7\n", data_count
);
280 ok( type
== REG_SZ
, "type %d is not REG_SZ\n", type
);
281 ok( !strcmp( value
, "Test" ), "value is '%s' instead of Test\n", value
);
282 ok( !strcmp( data
, "foobar" ), "data is '%s' instead of foobar\n", data
);
286 SetLastError(0xdeadbeef);
287 res
= RegSetValueExW( test_key
, testW
, 0, REG_SZ
, (const BYTE
*)foobarW
, 7*sizeof(WCHAR
) );
288 if (res
==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED
)
290 skip("RegSetValueExW is not implemented\n");
293 ok( res
== 0, "RegSetValueExW failed error %d\n", res
);
295 /* overflow both name and data */
299 memcpy( valueW
, xxxW
, sizeof(xxxW
) );
300 memcpy( dataW
, xxxW
, sizeof(xxxW
) );
301 res
= RegEnumValueW( test_key
, 0, valueW
, &val_count
, NULL
, &type
, (BYTE
*)dataW
, &data_count
);
302 ok( res
== ERROR_MORE_DATA
, "expected ERROR_MORE_DATA, got %d\n", res
);
303 ok( val_count
== 2, "val_count set to %d\n", val_count
);
304 ok( data_count
== 7*sizeof(WCHAR
), "data_count set to %d instead of 7*sizeof(WCHAR)\n", data_count
);
305 ok( type
== REG_SZ
, "type %d is not REG_SZ\n", type
);
306 ok( !memcmp( valueW
, xxxW
, sizeof(xxxW
) ), "value modified\n" );
307 ok( !memcmp( dataW
, xxxW
, sizeof(xxxW
) ), "data modified\n" );
313 memcpy( valueW
, xxxW
, sizeof(xxxW
) );
314 memcpy( dataW
, xxxW
, sizeof(xxxW
) );
315 res
= RegEnumValueW( test_key
, 0, valueW
, &val_count
, NULL
, &type
, (BYTE
*)dataW
, &data_count
);
316 ok( res
== ERROR_MORE_DATA
, "expected ERROR_MORE_DATA, got %d\n", res
);
317 ok( val_count
== 3, "val_count set to %d\n", val_count
);
318 ok( data_count
== 7*sizeof(WCHAR
), "data_count set to %d instead of 7*sizeof(WCHAR)\n", data_count
);
319 ok( type
== REG_SZ
, "type %d is not REG_SZ\n", type
);
320 ok( !memcmp( valueW
, xxxW
, sizeof(xxxW
) ), "value modified\n" );
321 ok( !memcmp( dataW
, xxxW
, sizeof(xxxW
) ), "data modified\n" );
327 memcpy( valueW
, xxxW
, sizeof(xxxW
) );
328 memcpy( dataW
, xxxW
, sizeof(xxxW
) );
329 res
= RegEnumValueW( test_key
, 0, valueW
, &val_count
, NULL
, &type
, (BYTE
*)dataW
, &data_count
);
330 ok( res
== ERROR_MORE_DATA
, "expected ERROR_MORE_DATA, got %d\n", res
);
331 ok( val_count
== 4, "val_count set to %d instead of 4\n", val_count
);
332 ok( data_count
== 7*sizeof(WCHAR
), "data_count set to %d instead of 7*sizeof(WCHAR)\n", data_count
);
333 ok( type
== REG_SZ
, "type %d is not REG_SZ\n", type
);
334 ok( !memcmp( valueW
, testW
, sizeof(testW
) ), "value is not 'Test'\n" );
335 ok( !memcmp( dataW
, xxxW
, sizeof(xxxW
) ), "data modified\n" );
341 memcpy( valueW
, xxxW
, sizeof(xxxW
) );
342 memcpy( dataW
, xxxW
, sizeof(xxxW
) );
343 res
= RegEnumValueW( test_key
, 0, valueW
, &val_count
, NULL
, &type
, (BYTE
*)dataW
, &data_count
);
344 ok( res
== ERROR_SUCCESS
, "expected ERROR_SUCCESS, got %d\n", res
);
345 ok( val_count
== 4, "val_count set to %d instead of 4\n", val_count
);
346 ok( data_count
== 7*sizeof(WCHAR
), "data_count set to %d instead of 7*sizeof(WCHAR)\n", data_count
);
347 ok( type
== REG_SZ
, "type %d is not REG_SZ\n", type
);
348 ok( !memcmp( valueW
, testW
, sizeof(testW
) ), "value is not 'Test'\n" );
349 ok( !memcmp( dataW
, foobarW
, sizeof(foobarW
) ), "data is not 'foobar'\n" );
352 RegDeleteKeyA(test_key
, "");
353 RegCloseKey(test_key
);
356 static void test_query_value_ex(void)
363 ret
= RegQueryValueExA(hkey_main
, "TP1_SZ", NULL
, &type
, NULL
, &size
);
364 ok(ret
== ERROR_SUCCESS
, "expected ERROR_SUCCESS, got %d\n", ret
);
365 ok(size
== strlen(sTestpath1
) + 1, "(%d,%d)\n", (DWORD
)strlen(sTestpath1
) + 1, size
);
366 ok(type
== REG_SZ
, "type %d is not REG_SZ\n", type
);
370 ret
= RegQueryValueExA(HKEY_CLASSES_ROOT
, "Nonexistent Value", NULL
, &type
, NULL
, &size
);
371 ok(ret
== ERROR_FILE_NOT_FOUND
, "expected ERROR_FILE_NOT_FOUND, got %d\n", ret
);
372 ok(size
== 0, "size should have been set to 0 instead of %d\n", size
);
373 /* the type parameter is cleared on Win9x, but is set to a random value on
374 * NT, so don't do this test there */
375 if (GetVersion() & 0x80000000)
376 ok(type
== 0, "type should have been set to 0 instead of 0x%x\n", type
);
378 trace("test_query_value_ex: type set to: 0x%08x\n", type
);
380 size
= sizeof(buffer
);
381 ret
= RegQueryValueExA(HKEY_CLASSES_ROOT
, "Nonexistent Value", NULL
, &type
, buffer
, &size
);
382 ok(ret
== ERROR_FILE_NOT_FOUND
, "expected ERROR_FILE_NOT_FOUND, got %d\n", ret
);
383 ok(size
== sizeof(buffer
), "size shouldn't have been changed to %d\n", size
);
386 static void test_get_value(void)
393 CHAR expanded
[] = "bar\\subdir1";
397 skip("RegGetValue not available on this platform\n");
401 /* Query REG_DWORD using RRF_RT_REG_DWORD (ok) */
402 size
= type
= dw
= 0xdeadbeef;
403 ret
= pRegGetValueA(hkey_main
, NULL
, "DWORD", RRF_RT_REG_DWORD
, &type
, &dw
, &size
);
404 ok(ret
== ERROR_SUCCESS
, "ret=%d\n", ret
);
405 ok(size
== 4, "size=%d\n", size
);
406 ok(type
== REG_DWORD
, "type=%d\n", type
);
407 ok(dw
== 0x12345678, "dw=%d\n", dw
);
409 /* Query by subkey-name */
410 ret
= pRegGetValueA(HKEY_CURRENT_USER
, "Software\\Wine\\Test", "DWORD", RRF_RT_REG_DWORD
, NULL
, NULL
, NULL
);
411 ok(ret
== ERROR_SUCCESS
, "ret=%d\n", ret
);
413 /* Query REG_DWORD using RRF_RT_REG_BINARY (restricted) */
414 size
= type
= dw
= 0xdeadbeef;
415 ret
= pRegGetValueA(hkey_main
, NULL
, "DWORD", RRF_RT_REG_BINARY
, &type
, &dw
, &size
);
416 ok(ret
== ERROR_UNSUPPORTED_TYPE
, "ret=%d\n", ret
);
417 /* Although the function failed all values are retrieved */
418 ok(size
== 4, "size=%d\n", size
);
419 ok(type
== REG_DWORD
, "type=%d\n", type
);
420 ok(dw
== 0x12345678, "dw=%d\n", dw
);
422 /* Test RRF_ZEROONFAILURE */
423 type
= dw
= 0xdeadbeef; size
= 4;
424 ret
= pRegGetValueA(hkey_main
, NULL
, "DWORD", RRF_RT_REG_SZ
|RRF_ZEROONFAILURE
, &type
, &dw
, &size
);
425 ok(ret
== ERROR_UNSUPPORTED_TYPE
, "ret=%d\n", ret
);
426 /* Again all values are retrieved ... */
427 ok(size
== 4, "size=%d\n", size
);
428 ok(type
== REG_DWORD
, "type=%d\n", type
);
429 /* ... except the buffer, which is zeroed out */
430 ok(dw
== 0, "dw=%d\n", dw
);
432 /* Query REG_DWORD using RRF_RT_DWORD (ok) */
433 size
= type
= dw
= 0xdeadbeef;
434 ret
= pRegGetValueA(hkey_main
, NULL
, "DWORD", RRF_RT_DWORD
, &type
, &dw
, &size
);
435 ok(ret
== ERROR_SUCCESS
, "ret=%d\n", ret
);
436 ok(size
== 4, "size=%d\n", size
);
437 ok(type
== REG_DWORD
, "type=%d\n", type
);
438 ok(dw
== 0x12345678, "dw=%d\n", dw
);
440 /* Query 32-bit REG_BINARY using RRF_RT_DWORD (ok) */
441 size
= type
= dw
= 0xdeadbeef;
442 ret
= pRegGetValueA(hkey_main
, NULL
, "BIN32", RRF_RT_DWORD
, &type
, &dw
, &size
);
443 ok(ret
== ERROR_SUCCESS
, "ret=%d\n", ret
);
444 ok(size
== 4, "size=%d\n", size
);
445 ok(type
== REG_BINARY
, "type=%d\n", type
);
446 ok(dw
== 0x12345678, "dw=%d\n", dw
);
448 /* Query 64-bit REG_BINARY using RRF_RT_DWORD (type mismatch) */
449 qw
[0] = qw
[1] = size
= type
= 0xdeadbeef;
450 ret
= pRegGetValueA(hkey_main
, NULL
, "BIN64", RRF_RT_DWORD
, &type
, qw
, &size
);
451 ok(ret
== ERROR_DATATYPE_MISMATCH
, "ret=%d\n", ret
);
452 ok(size
== 8, "size=%d\n", size
);
453 ok(type
== REG_BINARY
, "type=%d\n", type
);
454 ok(qw
[0] == 0x12345678 &&
455 qw
[1] == 0x87654321, "qw={%d,%d}\n", qw
[0], qw
[1]);
457 /* Query 64-bit REG_BINARY using 32-bit buffer (buffer too small) */
458 type
= dw
= 0xdeadbeef; size
= 4;
459 ret
= pRegGetValueA(hkey_main
, NULL
, "BIN64", RRF_RT_REG_BINARY
, &type
, &dw
, &size
);
460 ok(ret
== ERROR_MORE_DATA
, "ret=%d\n", ret
);
461 ok(dw
== 0xdeadbeef, "dw=%d\n", dw
);
462 ok(size
== 8, "size=%d\n", size
);
464 /* Query 64-bit REG_BINARY using RRF_RT_QWORD (ok) */
465 qw
[0] = qw
[1] = size
= type
= 0xdeadbeef;
466 ret
= pRegGetValueA(hkey_main
, NULL
, "BIN64", RRF_RT_QWORD
, &type
, qw
, &size
);
467 ok(ret
== ERROR_SUCCESS
, "ret=%d\n", ret
);
468 ok(size
== 8, "size=%d\n", size
);
469 ok(type
== REG_BINARY
, "type=%d\n", type
);
470 ok(qw
[0] == 0x12345678 &&
471 qw
[1] == 0x87654321, "qw={%d,%d}\n", qw
[0], qw
[1]);
473 /* Query REG_SZ using RRF_RT_REG_SZ (ok) */
474 buf
[0] = 0; type
= 0xdeadbeef; size
= sizeof(buf
);
475 ret
= pRegGetValueA(hkey_main
, NULL
, "TP1_SZ", RRF_RT_REG_SZ
, &type
, buf
, &size
);
476 ok(ret
== ERROR_SUCCESS
, "ret=%d\n", ret
);
477 ok(size
== strlen(sTestpath1
)+1, "strlen(sTestpath1)=%d size=%d\n", lstrlenA(sTestpath1
), size
);
478 ok(type
== REG_SZ
, "type=%d\n", type
);
479 ok(!strcmp(sTestpath1
, buf
), "sTestpath=\"%s\" buf=\"%s\"\n", sTestpath1
, buf
);
481 /* Query REG_SZ using RRF_RT_REG_SZ|RRF_NOEXPAND (ok) */
482 buf
[0] = 0; type
= 0xdeadbeef; size
= sizeof(buf
);
483 ret
= pRegGetValueA(hkey_main
, NULL
, "TP1_SZ", RRF_RT_REG_SZ
|RRF_NOEXPAND
, &type
, buf
, &size
);
484 ok(ret
== ERROR_SUCCESS
, "ret=%d\n", ret
);
485 ok(size
== strlen(sTestpath1
)+1, "strlen(sTestpath1)=%d size=%d\n", lstrlenA(sTestpath1
), size
);
486 ok(type
== REG_SZ
, "type=%d\n", type
);
487 ok(!strcmp(sTestpath1
, buf
), "sTestpath=\"%s\" buf=\"%s\"\n", sTestpath1
, buf
);
489 /* Query REG_EXPAND_SZ using RRF_RT_REG_SZ (ok, expands) */
490 buf
[0] = 0; type
= 0xdeadbeef; size
= sizeof(buf
);
491 ret
= pRegGetValueA(hkey_main
, NULL
, "TP1_EXP_SZ", RRF_RT_REG_SZ
, &type
, buf
, &size
);
492 ok(ret
== ERROR_SUCCESS
, "ret=%d\n", ret
);
493 /* At least v5.2.3790.1830 (2003 SP1) returns the unexpanded sTestpath1 length + 1 here. */
494 ok((size
== strlen(expanded
)+1) || (size
== strlen(sTestpath1
)+1),
495 "strlen(expanded)=%d, strlen(sTestpath1)=%d, size=%d\n", lstrlenA(expanded
), lstrlenA(sTestpath1
), size
);
496 ok(type
== REG_SZ
, "type=%d\n", type
);
497 ok(!strcmp(expanded
, buf
), "expanded=\"%s\" buf=\"%s\"\n", expanded
, buf
);
499 /* Query REG_EXPAND_SZ using RRF_RT_REG_EXPAND_SZ|RRF_NOEXPAND (ok, doesn't expand) */
500 buf
[0] = 0; type
= 0xdeadbeef; size
= sizeof(buf
);
501 ret
= pRegGetValueA(hkey_main
, NULL
, "TP1_EXP_SZ", RRF_RT_REG_EXPAND_SZ
|RRF_NOEXPAND
, &type
, buf
, &size
);
502 ok(ret
== ERROR_SUCCESS
, "ret=%d\n", ret
);
503 ok(size
== strlen(sTestpath1
)+1, "strlen(sTestpath1)=%d size=%d\n", lstrlenA(sTestpath1
), size
);
504 ok(type
== REG_EXPAND_SZ
, "type=%d\n", type
);
505 ok(!strcmp(sTestpath1
, buf
), "sTestpath=\"%s\" buf=\"%s\"\n", sTestpath1
, buf
);
507 /* Query REG_EXPAND_SZ using RRF_RT_REG_SZ|RRF_NOEXPAND (type mismatch) */
508 ret
= pRegGetValueA(hkey_main
, NULL
, "TP1_EXP_SZ", RRF_RT_REG_SZ
|RRF_NOEXPAND
, NULL
, NULL
, NULL
);
509 ok(ret
== ERROR_UNSUPPORTED_TYPE
, "ret=%d\n", ret
);
511 /* Query REG_EXPAND_SZ using RRF_RT_REG_EXPAND_SZ (not allowed without RRF_NOEXPAND) */
512 ret
= pRegGetValueA(hkey_main
, NULL
, "TP1_EXP_SZ", RRF_RT_REG_EXPAND_SZ
, NULL
, NULL
, NULL
);
513 ok(ret
== ERROR_INVALID_PARAMETER
, "ret=%d\n", ret
);
516 static void test_reg_open_key(void)
519 HKEY hkResult
= NULL
;
520 HKEY hkPreserve
= NULL
;
522 /* successful open */
523 ret
= RegOpenKeyA(HKEY_CURRENT_USER
, "Software\\Wine\\Test", &hkResult
);
524 ok(ret
== ERROR_SUCCESS
, "expected ERROR_SUCCESS, got %d\n", ret
);
525 ok(hkResult
!= NULL
, "expected hkResult != NULL\n");
526 hkPreserve
= hkResult
;
528 /* these tests fail on Win9x, but we want to be compatible with NT, so
529 * run them if we can */
530 if (!(GetVersion() & 0x80000000))
532 /* open same key twice */
533 ret
= RegOpenKeyA(HKEY_CURRENT_USER
, "Software\\Wine\\Test", &hkResult
);
534 ok(ret
== ERROR_SUCCESS
, "expected ERROR_SUCCESS, got %d\n", ret
);
535 ok(hkResult
!= hkPreserve
, "epxected hkResult != hkPreserve\n");
536 ok(hkResult
!= NULL
, "hkResult != NULL\n");
537 RegCloseKey(hkResult
);
539 /* open nonexistent key
540 * check that hkResult is set to NULL
542 hkResult
= hkPreserve
;
543 ret
= RegOpenKeyA(HKEY_CURRENT_USER
, "Software\\Wine\\Nonexistent", &hkResult
);
544 ok(ret
== ERROR_FILE_NOT_FOUND
, "expected ERROR_FILE_NOT_FOUND, got %d\n", ret
);
545 ok(hkResult
== NULL
, "expected hkResult == NULL\n");
547 /* open the same nonexistent key again to make sure the key wasn't created */
548 hkResult
= hkPreserve
;
549 ret
= RegOpenKeyA(HKEY_CURRENT_USER
, "Software\\Wine\\Nonexistent", &hkResult
);
550 ok(ret
== ERROR_FILE_NOT_FOUND
, "expected ERROR_FILE_NOT_FOUND, got %d\n", ret
);
551 ok(hkResult
== NULL
, "expected hkResult == NULL\n");
553 /* send in NULL lpSubKey
554 * check that hkResult receives the value of hKey
556 hkResult
= hkPreserve
;
557 ret
= RegOpenKeyA(HKEY_CURRENT_USER
, NULL
, &hkResult
);
558 ok(ret
== ERROR_SUCCESS
, "expected ERROR_SUCCESS, got %d\n", ret
);
559 ok(hkResult
== HKEY_CURRENT_USER
, "expected hkResult == HKEY_CURRENT_USER\n");
561 /* send empty-string in lpSubKey */
562 hkResult
= hkPreserve
;
563 ret
= RegOpenKeyA(HKEY_CURRENT_USER
, "", &hkResult
);
564 ok(ret
== ERROR_SUCCESS
, "expected ERROR_SUCCESS, got %d\n", ret
);
565 ok(hkResult
== HKEY_CURRENT_USER
, "expected hkResult == HKEY_CURRENT_USER\n");
567 /* send in NULL lpSubKey and NULL hKey
568 * hkResult is set to NULL
570 hkResult
= hkPreserve
;
571 ret
= RegOpenKeyA(NULL
, NULL
, &hkResult
);
572 ok(ret
== ERROR_SUCCESS
, "expected ERROR_SUCCESS, got %d\n", ret
);
573 ok(hkResult
== NULL
, "expected hkResult == NULL\n");
576 /* only send NULL hKey
577 * the value of hkResult remains unchanged
579 hkResult
= hkPreserve
;
580 ret
= RegOpenKeyA(NULL
, "Software\\Wine\\Test", &hkResult
);
581 ok(ret
== ERROR_INVALID_HANDLE
|| ret
== ERROR_BADKEY
, /* Windows 95 returns BADKEY */
582 "expected ERROR_INVALID_HANDLE or ERROR_BADKEY, got %d\n", ret
);
583 ok(hkResult
== hkPreserve
, "expected hkResult == hkPreserve\n");
584 RegCloseKey(hkResult
);
586 /* send in NULL hkResult */
587 ret
= RegOpenKeyA(HKEY_CURRENT_USER
, "Software\\Wine\\Test", NULL
);
588 ok(ret
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", ret
);
590 /* beginning backslash character */
591 ret
= RegOpenKeyA(HKEY_CURRENT_USER
, "\\Software\\Wine\\Test", &hkResult
);
592 ok(ret
== ERROR_BAD_PATHNAME
|| /* NT/2k/XP */
593 ret
== ERROR_FILE_NOT_FOUND
/* Win9x,ME */
594 , "expected ERROR_BAD_PATHNAME or ERROR_FILE_NOT_FOUND, got %d\n", ret
);
597 static void test_reg_create_key(void)
601 ret
= RegCreateKeyExA(hkey_main
, "Subkey1", 0, NULL
, 0, KEY_NOTIFY
, NULL
, &hkey1
, NULL
);
602 ok(!ret
, "RegCreateKeyExA failed with error %d\n", ret
);
603 /* should succeed: all versions of Windows ignore the access rights
604 * to the parent handle */
605 ret
= RegCreateKeyExA(hkey1
, "Subkey2", 0, NULL
, 0, KEY_SET_VALUE
, NULL
, &hkey2
, NULL
);
606 ok(!ret
, "RegCreateKeyExA failed with error %d\n", ret
);
609 RegDeleteKey(hkey2
, "");
610 RegDeleteKey(hkey1
, "");
612 /* beginning backslash character */
613 ret
= RegCreateKeyExA(hkey_main
, "\\Subkey3", 0, NULL
, 0, KEY_NOTIFY
, NULL
, &hkey1
, NULL
);
614 if (!(GetVersion() & 0x80000000))
615 ok(ret
== ERROR_BAD_PATHNAME
, "expected ERROR_BAD_PATHNAME, got %d\n", ret
);
617 ok(!ret
, "RegCreateKeyExA failed with error %d\n", ret
);
618 RegDeleteKey(hkey1
, NULL
);
622 static void test_reg_close_key(void)
627 /* successfully close key
628 * hkHandle remains changed after call to RegCloseKey
630 ret
= RegOpenKeyA(HKEY_CURRENT_USER
, "Software\\Wine\\Test", &hkHandle
);
631 ret
= RegCloseKey(hkHandle
);
632 ok(ret
== ERROR_SUCCESS
, "expected ERROR_SUCCESS, got %d\n", ret
);
634 /* try to close the key twice */
635 ret
= RegCloseKey(hkHandle
); /* Windows 95 doesn't mind. */
636 ok(ret
== ERROR_INVALID_HANDLE
|| ret
== ERROR_SUCCESS
,
637 "expected ERROR_INVALID_HANDLE or ERROR_SUCCESS, got %d\n", ret
);
639 /* try to close a NULL handle */
640 ret
= RegCloseKey(NULL
);
641 ok(ret
== ERROR_INVALID_HANDLE
|| ret
== ERROR_BADKEY
, /* Windows 95 returns BADKEY */
642 "expected ERROR_INVALID_HANDLE or ERROR_BADKEY, got %d\n", ret
);
644 /* Check to see if we didn't potentially close our main handle, which could happen on win98 as
645 * win98 doesn't give a new handle when the same key is opened.
646 * Not re-opening will make some next tests fail.
648 if (hkey_main
== hkHandle
)
650 trace("The main handle is most likely closed, so re-opening\n");
651 RegOpenKeyA( HKEY_CURRENT_USER
, "Software\\Wine\\Test", &hkey_main
);
655 static void test_reg_delete_key(void)
659 ret
= RegDeleteKey(hkey_main
, NULL
);
660 ok(ret
== ERROR_INVALID_PARAMETER
||
661 ret
== ERROR_ACCESS_DENIED
||
662 ret
== ERROR_BADKEY
, /* Win95 */
666 static void test_reg_save_key(void)
670 ret
= RegSaveKey(hkey_main
, "saved_key", NULL
);
671 ok(ret
== ERROR_SUCCESS
, "expected ERROR_SUCCESS, got %d\n", ret
);
674 static void test_reg_load_key(void)
679 ret
= RegLoadKey(HKEY_LOCAL_MACHINE
, "Test", "saved_key");
680 ok(ret
== ERROR_SUCCESS
, "expected ERROR_SUCCESS, got %d\n", ret
);
682 ret
= RegOpenKey(HKEY_LOCAL_MACHINE
, "Test", &hkHandle
);
683 ok(ret
== ERROR_SUCCESS
, "expected ERROR_SUCCESS, got %d\n", ret
);
685 RegCloseKey(hkHandle
);
688 static void test_reg_unload_key(void)
692 ret
= RegUnLoadKey(HKEY_LOCAL_MACHINE
, "Test");
693 ok(ret
== ERROR_SUCCESS
, "expected ERROR_SUCCESS, got %d\n", ret
);
695 DeleteFile("saved_key");
696 DeleteFile("saved_key.LOG");
699 static BOOL
set_privileges(LPCSTR privilege
, BOOL set
)
705 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES
, &hToken
))
708 if(!LookupPrivilegeValue(NULL
, privilege
, &luid
))
714 tp
.PrivilegeCount
= 1;
715 tp
.Privileges
[0].Luid
= luid
;
718 tp
.Privileges
[0].Attributes
= SE_PRIVILEGE_ENABLED
;
720 tp
.Privileges
[0].Attributes
= 0;
722 AdjustTokenPrivileges(hToken
, FALSE
, &tp
, sizeof(TOKEN_PRIVILEGES
), NULL
, NULL
);
723 if (GetLastError() != ERROR_SUCCESS
)
733 /* tests that show that RegConnectRegistry and
734 OpenSCManager accept computer names without the
735 \\ prefix (what MSDN says). */
736 static void test_regconnectregistry( void)
738 CHAR compName
[MAX_COMPUTERNAME_LENGTH
+ 1];
739 CHAR netwName
[MAX_COMPUTERNAME_LENGTH
+ 3]; /* 2 chars for double backslash */
740 DWORD len
= sizeof(compName
) ;
747 ret
= GetComputerNameA(compName
, &len
);
748 ok( ret
, "GetComputerName failed err = %d\n", GetLastError());
751 lstrcpyA(netwName
, "\\\\");
752 lstrcpynA(netwName
+2, compName
, MAX_COMPUTERNAME_LENGTH
+ 1);
754 retl
= RegConnectRegistryA( compName
, HKEY_LOCAL_MACHINE
, &hkey
);
755 ok( !retl
|| retl
== ERROR_DLL_INIT_FAILED
, "RegConnectRegistryA failed err = %d\n", retl
);
756 if( !retl
) RegCloseKey( hkey
);
758 retl
= RegConnectRegistryA( netwName
, HKEY_LOCAL_MACHINE
, &hkey
);
759 ok( !retl
|| retl
== ERROR_DLL_INIT_FAILED
, "RegConnectRegistryA failed err = %d\n", retl
);
760 if( !retl
) RegCloseKey( hkey
);
762 schnd
= OpenSCManagerA( compName
, NULL
, GENERIC_READ
);
763 GLE
= GetLastError();
764 ok( schnd
!= NULL
|| GLE
==ERROR_CALL_NOT_IMPLEMENTED
,
765 "OpenSCManagerA failed err = %d\n", GLE
);
766 CloseServiceHandle( schnd
);
768 schnd
= OpenSCManagerA( netwName
, NULL
, GENERIC_READ
);
769 GLE
= GetLastError();
770 ok( schnd
!= NULL
|| GLE
==ERROR_CALL_NOT_IMPLEMENTED
,
771 "OpenSCManagerA failed err = %d\n", GLE
);
772 CloseServiceHandle( schnd
);
776 static void test_reg_query_value(void)
783 static const WCHAR expected
[] = {'d','a','t','a',0};
785 ret
= RegCreateKeyA(hkey_main
, "subkey", &subkey
);
786 ok(ret
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", ret
);
788 ret
= RegSetValueA(subkey
, NULL
, REG_SZ
, "data", 4);
789 ok(ret
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", ret
);
791 /* try an invalid hkey */
792 SetLastError(0xdeadbeef);
794 ret
= RegQueryValueA((HKEY
)0xcafebabe, "subkey", val
, &size
);
795 ok(ret
== ERROR_INVALID_HANDLE
|| ret
== ERROR_BADKEY
, /* Windows 98 returns BADKEY */
796 "Expected ERROR_INVALID_HANDLE or ERROR_BADKEY, got %d\n", ret
);
797 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
799 /* try a NULL hkey */
800 SetLastError(0xdeadbeef);
802 ret
= RegQueryValueA(NULL
, "subkey", val
, &size
);
803 ok(ret
== ERROR_INVALID_HANDLE
|| ret
== ERROR_BADKEY
, /* Windows 98 returns BADKEY */
804 "Expected ERROR_INVALID_HANDLE or ERROR_BADKEY, got %d\n", ret
);
805 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
807 /* try a NULL value */
809 ret
= RegQueryValueA(hkey_main
, "subkey", NULL
, &size
);
810 ok(ret
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", ret
);
811 ok(size
== 5, "Expected 5, got %d\n", size
);
813 /* try a NULL size */
814 SetLastError(0xdeadbeef);
816 ret
= RegQueryValueA(hkey_main
, "subkey", val
, NULL
);
817 ok(ret
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", ret
);
818 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
819 ok(lstrlenA(val
) == 0, "Expected val to be untouched, got %s\n", val
);
821 /* try a NULL value and size */
822 ret
= RegQueryValueA(hkey_main
, "subkey", NULL
, NULL
);
823 ok(ret
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", ret
);
825 /* try a size too small */
826 SetLastError(0xdeadbeef);
829 ret
= RegQueryValueA(hkey_main
, "subkey", val
, &size
);
830 ok(ret
== ERROR_MORE_DATA
, "Expected ERROR_MORE_DATA, got %d\n", ret
);
831 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
832 ok(lstrlenA(val
) == 0, "Expected val to be untouched, got %s\n", val
);
833 ok(size
== 5, "Expected 5, got %d\n", size
);
835 /* successfully read the value using 'subkey' */
837 ret
= RegQueryValueA(hkey_main
, "subkey", val
, &size
);
838 ok(ret
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", ret
);
839 ok(!lstrcmpA(val
, "data"), "Expected 'data', got '%s'\n", val
);
840 ok(size
== 5, "Expected 5, got %d\n", size
);
842 /* successfully read the value using the subkey key */
844 ret
= RegQueryValueA(subkey
, NULL
, val
, &size
);
845 ok(ret
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", ret
);
846 ok(!lstrcmpA(val
, "data"), "Expected 'data', got '%s'\n", val
);
847 ok(size
== 5, "Expected 5, got %d\n", size
);
849 /* unicode - try size too small */
850 SetLastError(0xdeadbeef);
853 ret
= RegQueryValueW(subkey
, NULL
, valW
, &size
);
854 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
856 skip("RegQueryValueW is not implemented\n");
859 ok(ret
== ERROR_MORE_DATA
, "Expected ERROR_MORE_DATA, got %d\n", ret
);
860 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
861 ok(lstrlenW(valW
) == 0, "Expected valW to be untouched\n");
862 ok(size
== sizeof(expected
), "Got wrong size: %d\n", size
);
864 /* unicode - try size in WCHARS */
865 SetLastError(0xdeadbeef);
866 size
= sizeof(valW
) / sizeof(WCHAR
);
867 ret
= RegQueryValueW(subkey
, NULL
, valW
, &size
);
868 ok(ret
== ERROR_MORE_DATA
, "Expected ERROR_MORE_DATA, got %d\n", ret
);
869 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
870 ok(lstrlenW(valW
) == 0, "Expected valW to be untouched\n");
871 ok(size
== sizeof(expected
), "Got wrong size: %d\n", size
);
873 /* unicode - successfully read the value */
875 ret
= RegQueryValueW(subkey
, NULL
, valW
, &size
);
876 ok(ret
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", ret
);
877 ok(!lstrcmpW(valW
, expected
), "Got wrong value\n");
878 ok(size
== sizeof(expected
), "Got wrong size: %d\n", size
);
880 /* unicode - set the value without a NULL terminator */
881 ret
= RegSetValueW(subkey
, NULL
, REG_SZ
, expected
, sizeof(expected
)-sizeof(WCHAR
));
882 ok(ret
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", ret
);
884 /* unicode - read the unterminated value, value is terminated for us */
885 memset(valW
, 'a', sizeof(valW
));
887 ret
= RegQueryValueW(subkey
, NULL
, valW
, &size
);
888 ok(ret
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", ret
);
889 ok(!lstrcmpW(valW
, expected
), "Got wrong value\n");
890 ok(size
== sizeof(expected
), "Got wrong size: %d\n", size
);
893 RegDeleteKeyA(subkey
, "");
897 static void test_reg_delete_tree(void)
899 CHAR buffer
[MAX_PATH
];
900 HKEY subkey
, subkey2
;
903 if(!pRegDeleteTreeA
) {
904 skip("Skipping RegDeleteTreeA tests, function not present\n");
908 ret
= RegCreateKeyA(hkey_main
, "subkey", &subkey
);
909 ok(ret
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", ret
);
910 ret
= RegCreateKeyA(subkey
, "subkey2", &subkey2
);
911 ok(ret
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", ret
);
912 ret
= RegSetValueA(subkey
, NULL
, REG_SZ
, "data", 4);
913 ok(ret
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", ret
);
914 ret
= RegSetValueA(subkey2
, NULL
, REG_SZ
, "data2", 5);
915 ok(ret
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", ret
);
916 ret
= RegCloseKey(subkey2
);
917 ok(ret
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", ret
);
919 ret
= pRegDeleteTreeA(subkey
, "subkey2");
920 ok(ret
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", ret
);
921 ok(RegOpenKeyA(subkey
, "subkey2", &subkey2
),
922 "subkey2 was not deleted\n");
924 ok(!RegQueryValueA(subkey
, NULL
, buffer
, &size
),
925 "Default value of subkey not longer present\n");
927 ret
= RegCreateKeyA(subkey
, "subkey2", &subkey2
);
928 ok(ret
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", ret
);
929 ret
= RegCloseKey(subkey2
);
930 ok(ret
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", ret
);
931 ret
= pRegDeleteTreeA(hkey_main
, "subkey\\subkey2");
932 ok(ret
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", ret
);
933 ok(RegOpenKeyA(subkey
, "subkey2", &subkey2
),
934 "subkey2 was not deleted\n");
935 ok(!RegQueryValueA(subkey
, NULL
, buffer
, &size
),
936 "Default value of subkey not longer present\n");
938 ret
= pRegDeleteTreeA(subkey
, NULL
);
939 ok(ret
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", ret
);
940 ok(!RegOpenKeyA(hkey_main
, "subkey", &subkey
),
941 "subkey was deleted\n");
942 ret
= RegQueryValueA(subkey
, NULL
, buffer
, &size
);
943 ok(ret
== ERROR_SUCCESS
,
944 "Default value of subkey is not present\n");
945 ok(!lstrlenA(buffer
),
946 "Expected length 0 got length %u(%s)\n", lstrlenA(buffer
), buffer
);
948 ret
= pRegDeleteTreeA(hkey_main
, "not-here");
949 ok(ret
== ERROR_FILE_NOT_FOUND
,
950 "Expected ERROR_FILE_NOT_FOUND, got %d\n", ret
);
955 /* Load pointers for functions that are not available in all Windows versions */
960 create_test_entries();
962 test_query_value_ex();
965 test_reg_create_key();
966 test_reg_close_key();
967 test_reg_delete_key();
968 test_reg_query_value();
970 /* SaveKey/LoadKey require the SE_BACKUP_NAME privilege to be set */
971 if (set_privileges(SE_BACKUP_NAME
, TRUE
) &&
972 set_privileges(SE_RESTORE_NAME
, TRUE
))
976 test_reg_unload_key();
978 set_privileges(SE_BACKUP_NAME
, FALSE
);
979 set_privileges(SE_RESTORE_NAME
, FALSE
);
982 test_reg_delete_tree();
985 delete_key( hkey_main
);
987 test_regconnectregistry();