ntdll: Set the DataLength field of the information field in NtQueryValueKey to how...
[wine/testsucceed.git] / dlls / ntdll / tests / reg.c
blob4a559a5c5b85489be14c04b31973de902884ff7e
1 /* Unit test suite for Rtl* Registry API functions
3 * Copyright 2003 Thomas Mertes
4 * Copyright 2005 Brad DeMorrow
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
20 * NOTE: I don't test every RelativeTo value because it would be redundant, all calls go through
21 * helper function RTL_GetKeyHandle().--Brad DeMorrow
25 #include "ntdll_test.h"
26 #include "winternl.h"
27 #include "stdio.h"
28 #include "winnt.h"
29 #include "winnls.h"
30 #include "stdlib.h"
32 #ifndef __WINE_WINTERNL_H
34 /* RtlQueryRegistryValues structs and defines */
35 #define RTL_REGISTRY_ABSOLUTE 0
36 #define RTL_REGISTRY_SERVICES 1
37 #define RTL_REGISTRY_CONTROL 2
38 #define RTL_REGISTRY_WINDOWS_NT 3
39 #define RTL_REGISTRY_DEVICEMAP 4
40 #define RTL_REGISTRY_USER 5
42 #define RTL_REGISTRY_HANDLE 0x40000000
43 #define RTL_REGISTRY_OPTIONAL 0x80000000
45 #define RTL_QUERY_REGISTRY_SUBKEY 0x00000001
46 #define RTL_QUERY_REGISTRY_TOPKEY 0x00000002
47 #define RTL_QUERY_REGISTRY_REQUIRED 0x00000004
48 #define RTL_QUERY_REGISTRY_NOVALUE 0x00000008
49 #define RTL_QUERY_REGISTRY_NOEXPAND 0x00000010
50 #define RTL_QUERY_REGISTRY_DIRECT 0x00000020
51 #define RTL_QUERY_REGISTRY_DELETE 0x00000040
53 typedef NTSTATUS (WINAPI *PRTL_QUERY_REGISTRY_ROUTINE)( PCWSTR ValueName,
54 ULONG ValueType,
55 PVOID ValueData,
56 ULONG ValueLength,
57 PVOID Context,
58 PVOID EntryContext);
60 typedef struct _RTL_QUERY_REGISTRY_TABLE {
61 PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine;
62 ULONG Flags;
63 PWSTR Name;
64 PVOID EntryContext;
65 ULONG DefaultType;
66 PVOID DefaultData;
67 ULONG DefaultLength;
68 } RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE;
70 typedef struct _KEY_VALUE_PARTIAL_INFORMATION {
71 ULONG TitleIndex;
72 ULONG Type;
73 ULONG DataLength;
74 UCHAR Data[1];
75 } KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION;
77 typedef struct _KEY_VALUE_FULL_INFORMATION {
78 ULONG TitleIndex;
79 ULONG Type;
80 ULONG DataOffset;
81 ULONG DataLength;
82 ULONG NameLength;
83 WCHAR Name[1];
84 } KEY_VALUE_FULL_INFORMATION, *PKEY_VALUE_FULL_INFORMATION;
86 typedef enum _KEY_VALUE_INFORMATION_CLASS {
87 KeyValueBasicInformation,
88 KeyValueFullInformation,
89 KeyValuePartialInformation,
90 KeyValueFullInformationAlign64,
91 KeyValuePartialInformationAlign64
92 } KEY_VALUE_INFORMATION_CLASS;
94 #define InitializeObjectAttributes(p,n,a,r,s) \
95 do { \
96 (p)->Length = sizeof(OBJECT_ATTRIBUTES); \
97 (p)->RootDirectory = r; \
98 (p)->Attributes = a; \
99 (p)->ObjectName = n; \
100 (p)->SecurityDescriptor = s; \
101 (p)->SecurityQualityOfService = NULL; \
102 } while (0)
104 #endif
106 static NTSTATUS (WINAPI * pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING, LPCSTR);
107 static NTSTATUS (WINAPI * pRtlFreeUnicodeString)(PUNICODE_STRING);
108 static NTSTATUS (WINAPI * pNtDeleteValueKey)(IN HANDLE, IN PUNICODE_STRING);
109 static NTSTATUS (WINAPI * pRtlQueryRegistryValues)(IN ULONG, IN PCWSTR,IN PRTL_QUERY_REGISTRY_TABLE, IN PVOID,IN PVOID);
110 static NTSTATUS (WINAPI * pRtlCheckRegistryKey)(IN ULONG,IN PWSTR);
111 static NTSTATUS (WINAPI * pRtlOpenCurrentUser)(IN ACCESS_MASK, OUT PHKEY);
112 static NTSTATUS (WINAPI * pNtOpenKey)(PHANDLE, IN ACCESS_MASK, IN POBJECT_ATTRIBUTES);
113 static NTSTATUS (WINAPI * pNtClose)(IN HANDLE);
114 static NTSTATUS (WINAPI * pNtDeleteValueKey)(IN HANDLE, IN PUNICODE_STRING);
115 static NTSTATUS (WINAPI * pNtFlushKey)(HKEY);
116 static NTSTATUS (WINAPI * pNtDeleteKey)(HKEY);
117 static NTSTATUS (WINAPI * pNtCreateKey)( PHKEY retkey, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr,
118 ULONG TitleIndex, const UNICODE_STRING *class, ULONG options,
119 PULONG dispos );
120 static NTSTATUS (WINAPI * pNtQueryValueKey)(HANDLE,const UNICODE_STRING *,KEY_VALUE_INFORMATION_CLASS,void *,DWORD,DWORD *);
121 static NTSTATUS (WINAPI * pNtSetValueKey)( PHKEY, const PUNICODE_STRING, ULONG,
122 ULONG, const PVOID, ULONG );
123 static NTSTATUS (WINAPI * pRtlFormatCurrentUserKeyPath)(PUNICODE_STRING);
124 static NTSTATUS (WINAPI * pRtlCreateUnicodeString)( PUNICODE_STRING, LPCWSTR);
125 static NTSTATUS (WINAPI * pRtlReAllocateHeap)(IN PVOID, IN ULONG, IN PVOID, IN ULONG);
126 static NTSTATUS (WINAPI * pRtlAppendUnicodeToString)(PUNICODE_STRING, PCWSTR);
127 static NTSTATUS (WINAPI * pRtlUnicodeStringToAnsiString)(PSTRING, PUNICODE_STRING, BOOL);
128 static NTSTATUS (WINAPI * pRtlFreeHeap)(PVOID, ULONG, PVOID);
129 static NTSTATUS (WINAPI * pRtlAllocateHeap)(PVOID,ULONG,ULONG);
130 static NTSTATUS (WINAPI * pRtlZeroMemory)(PVOID, ULONG);
131 static NTSTATUS (WINAPI * pRtlpNtQueryValueKey)(HANDLE,ULONG*,PBYTE,DWORD*);
133 static HMODULE hntdll = 0;
134 static int CurrentTest = 0;
135 static UNICODE_STRING winetestpath;
137 #define NTDLL_GET_PROC(func) \
138 p ## func = (void*)GetProcAddress(hntdll, #func); \
139 if(!p ## func) { \
140 trace("GetProcAddress(%s) failed\n", #func); \
141 FreeLibrary(hntdll); \
142 return FALSE; \
145 static BOOL InitFunctionPtrs(void)
147 hntdll = LoadLibraryA("ntdll.dll");
148 if(!hntdll) {
149 trace("Could not load ntdll.dll\n");
150 return FALSE;
152 if (hntdll)
154 NTDLL_GET_PROC(RtlCreateUnicodeStringFromAsciiz)
155 NTDLL_GET_PROC(RtlCreateUnicodeString)
156 NTDLL_GET_PROC(RtlFreeUnicodeString)
157 NTDLL_GET_PROC(NtDeleteValueKey)
158 NTDLL_GET_PROC(RtlQueryRegistryValues)
159 NTDLL_GET_PROC(RtlCheckRegistryKey)
160 NTDLL_GET_PROC(RtlOpenCurrentUser)
161 NTDLL_GET_PROC(NtClose)
162 NTDLL_GET_PROC(NtDeleteValueKey)
163 NTDLL_GET_PROC(NtCreateKey)
164 NTDLL_GET_PROC(NtFlushKey)
165 NTDLL_GET_PROC(NtDeleteKey)
166 NTDLL_GET_PROC(NtQueryValueKey)
167 NTDLL_GET_PROC(NtSetValueKey)
168 NTDLL_GET_PROC(NtOpenKey)
169 NTDLL_GET_PROC(RtlFormatCurrentUserKeyPath)
170 NTDLL_GET_PROC(RtlReAllocateHeap)
171 NTDLL_GET_PROC(RtlAppendUnicodeToString)
172 NTDLL_GET_PROC(RtlUnicodeStringToAnsiString)
173 NTDLL_GET_PROC(RtlFreeHeap)
174 NTDLL_GET_PROC(RtlAllocateHeap)
175 NTDLL_GET_PROC(RtlZeroMemory)
176 NTDLL_GET_PROC(RtlpNtQueryValueKey)
178 return TRUE;
180 #undef NTDLL_GET_PROC
182 static NTSTATUS WINAPI QueryRoutine (IN PCWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData,
183 IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
185 NTSTATUS ret = STATUS_SUCCESS;
186 int ValueNameLength = 0;
187 LPSTR ValName = 0;
188 trace("**Test %d**\n", CurrentTest);
190 if(ValueName)
192 ValueNameLength = lstrlenW(ValueName);
194 ValName = (LPSTR)pRtlAllocateHeap(GetProcessHeap(), 0, ValueNameLength);
196 WideCharToMultiByte(0, 0, ValueName, ValueNameLength+1,ValName, ValueNameLength, 0, 0);
198 trace("ValueName: %s\n", ValName);
200 else
201 trace("ValueName: (null)\n");
203 switch(ValueType)
205 case REG_NONE:
206 trace("ValueType: REG_NONE\n");
207 trace("ValueData: %d\n", (int)ValueData);
208 break;
210 case REG_BINARY:
211 trace("ValueType: REG_BINARY\n");
212 trace("ValueData: %d\n", (int)ValueData);
213 break;
215 case REG_SZ:
216 trace("ValueType: REG_SZ\n");
217 trace("ValueData: %s\n", (char*)ValueData);
218 break;
220 case REG_MULTI_SZ:
221 trace("ValueType: REG_MULTI_SZ\n");
222 trace("ValueData: %s\n", (char*)ValueData);
223 break;
225 case REG_EXPAND_SZ:
226 trace("ValueType: REG_EXPAND_SZ\n");
227 trace("ValueData: %s\n", (char*)ValueData);
228 break;
230 case REG_DWORD:
231 trace("ValueType: REG_DWORD\n");
232 trace("ValueData: %d\n", (int)ValueData);
233 break;
235 trace("ValueLength: %d\n", (int)ValueLength);
237 if(CurrentTest == 0)
238 ok(1, "\n"); /*checks that QueryRoutine is called*/
239 if(CurrentTest > 7)
240 ok(!1, "Invalid Test Specified!\n");
242 CurrentTest++;
244 if(ValName)
245 pRtlFreeHeap(GetProcessHeap(), 0, ValName);
247 return ret;
250 static void test_RtlQueryRegistryValues(void)
254 ******************************
255 * QueryTable Flags *
256 ******************************
257 *RTL_QUERY_REGISTRY_SUBKEY * Name is the name of a subkey relative to Path
258 *RTL_QUERY_REGISTRY_TOPKEY * Resets location to original RelativeTo and Path
259 *RTL_QUERY_REGISTRY_REQUIRED * Key required. returns STATUS_OBJECT_NAME_NOT_FOUND if not present
260 *RTL_QUERY_REGISTRY_NOVALUE * We just want a call-back
261 *RTL_QUERY_REGISTRY_NOEXPAND * Don't expand the variables!
262 *RTL_QUERY_REGISTRY_DIRECT * Results of query will be stored in EntryContext(QueryRoutine ignored)
263 *RTL_QUERY_REGISTRY_DELETE * Delete value key after query
264 ******************************
267 **Test layout(numbered according to CurrentTest value)**
268 0)NOVALUE Just make sure call-back works
269 1)Null Name See if QueryRoutine is called for every value in current key
270 2)SUBKEY See if we can use SUBKEY to change the current path on the fly
271 3)REQUIRED Test for value that's not there
272 4)NOEXPAND See if it will return multiple strings(no expand should split strings up)
273 5)DIRECT Make it store data directly in EntryContext and not call QueryRoutine
274 6)DefaultType Test return values when key isn't present
275 7)DefaultValue Test Default Value returned with key isn't present(and no REQUIRED flag set)
276 8)DefaultLength Test Default Length with DefaultType = REG_SZ
277 9)DefaultLength Test Default Length with DefaultType = REG_MULTI_SZ
278 10)DefaultLength Test Default Length with DefaultType = REG_EXPAND_SZ
279 11)DefaultData Test whether DefaultData is used while DefaltType = REG_NONE(shouldn't be)
280 12)Delete Try to delete value key
283 NTSTATUS status;
284 ULONG RelativeTo;
286 PRTL_QUERY_REGISTRY_TABLE QueryTable = NULL;
287 RelativeTo = RTL_REGISTRY_ABSOLUTE;/*Only using absolute - no need to test all relativeto variables*/
289 QueryTable = (PRTL_QUERY_REGISTRY_TABLE)pRtlAllocateHeap(GetProcessHeap(), 0, sizeof(RTL_QUERY_REGISTRY_TABLE)*26);
291 pRtlZeroMemory( QueryTable, sizeof(RTL_QUERY_REGISTRY_TABLE) * 26);
293 QueryTable[0].QueryRoutine = QueryRoutine;
294 QueryTable[0].Flags = RTL_QUERY_REGISTRY_NOVALUE;
295 QueryTable[0].Name = NULL;
296 QueryTable[0].EntryContext = NULL;
297 QueryTable[0].DefaultType = REG_BINARY;
298 QueryTable[0].DefaultData = NULL;
299 QueryTable[0].DefaultLength = 100;
301 QueryTable[1].QueryRoutine = QueryRoutine;
302 QueryTable[1].Flags = 0;
303 QueryTable[1].Name = NULL;
304 QueryTable[1].EntryContext = 0;
305 QueryTable[1].DefaultType = REG_NONE;
306 QueryTable[1].DefaultData = NULL;
307 QueryTable[1].DefaultLength = 0;
309 QueryTable[2].QueryRoutine = NULL;
310 QueryTable[2].Flags = 0;
311 QueryTable[2].Name = NULL;
312 QueryTable[2].EntryContext = 0;
313 QueryTable[2].DefaultType = REG_NONE;
314 QueryTable[2].DefaultData = NULL;
315 QueryTable[2].DefaultLength = 0;
317 status = pRtlQueryRegistryValues(RelativeTo, winetestpath.Buffer, QueryTable, 0, 0);
318 ok(status == STATUS_SUCCESS, "RtlQueryRegistryValues return: 0x%08x\n", status);
320 pRtlFreeHeap(GetProcessHeap(), 0, QueryTable);
323 static void test_NtOpenKey(void)
325 HANDLE key;
326 NTSTATUS status;
327 OBJECT_ATTRIBUTES attr;
328 ACCESS_MASK am = KEY_READ;
330 if (0)
332 /* Crashes Wine */
333 /* All NULL */
334 status = pNtOpenKey(NULL, 0, NULL);
335 ok(status == STATUS_ACCESS_VIOLATION, "Expected STATUS_ACCESS_VIOLATION, got: 0x%08x\n", status);
337 /* NULL attributes */
338 status = pNtOpenKey(&key, 0, NULL);
339 ok(status == STATUS_ACCESS_VIOLATION /* W2K3/XP/W2K */ || status == STATUS_INVALID_PARAMETER /* NT4 */,
340 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_PARAMETER(NT4), got: 0x%08x\n", status);
343 InitializeObjectAttributes(&attr, &winetestpath, 0, 0, 0);
345 /* NULL key */
346 status = pNtOpenKey(NULL, 0, &attr);
347 todo_wine
348 ok(status == STATUS_ACCESS_VIOLATION, "Expected STATUS_ACCESS_VIOLATION, got: 0x%08x\n", status);
350 /* Length > sizeof(OBJECT_ATTRIBUTES) */
351 attr.Length *= 2;
352 status = pNtOpenKey(&key, am, &attr);
353 todo_wine
354 ok(status == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got: 0x%08x\n", status);
357 static void test_NtCreateKey(void)
359 /*Create WineTest*/
360 OBJECT_ATTRIBUTES attr;
361 HKEY key;
362 ACCESS_MASK am = GENERIC_ALL;
363 NTSTATUS status;
365 /* All NULL */
366 status = pNtCreateKey(NULL, 0, NULL, 0, 0, 0, 0);
367 ok(status == STATUS_ACCESS_VIOLATION, "Expected STATUS_ACCESS_VIOLATION, got: 0x%08x\n", status);
369 /* Only the key */
370 status = pNtCreateKey(&key, 0, NULL, 0, 0, 0, 0);
371 ok(status == STATUS_ACCESS_VIOLATION /* W2K3/XP/W2K */ || status == STATUS_INVALID_PARAMETER /* NT4 */,
372 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_PARAMETER(NT4), got: 0x%08x\n", status);
374 /* Only accessmask */
375 status = pNtCreateKey(NULL, am, NULL, 0, 0, 0, 0);
376 ok(status == STATUS_ACCESS_VIOLATION, "Expected STATUS_ACCESS_VIOLATION, got: 0x%08x\n", status);
378 /* Key and accessmask */
379 status = pNtCreateKey(&key, am, NULL, 0, 0, 0, 0);
380 ok(status == STATUS_ACCESS_VIOLATION /* W2K3/XP/W2K */ || status == STATUS_INVALID_PARAMETER /* NT4 */,
381 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_PARAMETER(NT4), got: 0x%08x\n", status);
383 InitializeObjectAttributes(&attr, &winetestpath, 0, 0, 0);
385 /* Only attributes */
386 status = pNtCreateKey(NULL, 0, &attr, 0, 0, 0, 0);
387 ok(status == STATUS_ACCESS_VIOLATION, "Expected STATUS_ACCESS_VIOLATION, got: 0x%08x\n", status);
389 status = pNtCreateKey(&key, am, &attr, 0, 0, 0, 0);
390 ok(status == STATUS_SUCCESS, "NtCreateKey Failed: 0x%08x\n", status);
392 /* Length > sizeof(OBJECT_ATTRIBUTES) */
393 attr.Length *= 2;
394 status = pNtCreateKey(&key, am, &attr, 0, 0, 0, 0);
395 ok(status == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got: 0x%08x\n", status);
397 pNtClose(key);
400 static void test_NtSetValueKey(void)
402 HANDLE key;
403 NTSTATUS status;
404 OBJECT_ATTRIBUTES attr;
405 ACCESS_MASK am = KEY_WRITE;
406 UNICODE_STRING ValName;
407 DWORD data = 711;
409 pRtlCreateUnicodeStringFromAsciiz(&ValName, "deletetest");
411 InitializeObjectAttributes(&attr, &winetestpath, 0, 0, 0);
412 status = pNtOpenKey(&key, am, &attr);
413 ok(status == STATUS_SUCCESS, "NtOpenKey Failed: 0x%08x\n", status);
415 status = pNtSetValueKey(key, &ValName, 0, REG_DWORD, &data, sizeof(data));
416 ok(status == STATUS_SUCCESS, "NtSetValueKey Failed: 0x%08x\n", status);
418 pRtlFreeUnicodeString(&ValName);
419 pNtClose(key);
422 static void test_RtlOpenCurrentUser(void)
424 NTSTATUS status;
425 HKEY handle;
426 status=pRtlOpenCurrentUser(KEY_READ, &handle);
427 ok(status == STATUS_SUCCESS, "RtlOpenCurrentUser Failed: 0x%08x\n", status);
428 pNtClose(handle);
431 static void test_RtlCheckRegistryKey(void)
433 NTSTATUS status;
435 status = pRtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, winetestpath.Buffer);
436 ok(status == STATUS_SUCCESS, "RtlCheckRegistryKey with RTL_REGISTRY_ABSOLUTE: 0x%08x\n", status);
438 status = pRtlCheckRegistryKey((RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL), winetestpath.Buffer);
439 ok(status == STATUS_SUCCESS, "RtlCheckRegistryKey with RTL_REGISTRY_ABSOLUTE and RTL_REGISTRY_OPTIONAL: 0x%08x\n", status);
442 static void test_NtFlushKey(void)
444 NTSTATUS status;
445 HANDLE hkey;
446 OBJECT_ATTRIBUTES attr;
447 ACCESS_MASK am = KEY_ALL_ACCESS;
449 status = pNtFlushKey(NULL);
450 ok(status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got: 0x%08x\n", status);
452 InitializeObjectAttributes(&attr, &winetestpath, 0, 0, 0);
453 pNtOpenKey(&hkey, am, &attr);
455 status = pNtFlushKey(hkey);
456 ok(status == STATUS_SUCCESS, "NtDeleteKey Failed: 0x%08x\n", status);
458 pNtClose(hkey);
461 static void test_NtQueryValueKey(void)
463 HANDLE key;
464 NTSTATUS status;
465 OBJECT_ATTRIBUTES attr;
466 UNICODE_STRING ValName;
467 KEY_VALUE_PARTIAL_INFORMATION *partial_info;
468 KEY_VALUE_FULL_INFORMATION *full_info;
469 DWORD len;
471 pRtlCreateUnicodeStringFromAsciiz(&ValName, "deletetest");
473 InitializeObjectAttributes(&attr, &winetestpath, 0, 0, 0);
474 status = pNtOpenKey(&key, KEY_READ, &attr);
475 ok(status == STATUS_SUCCESS, "NtOpenKey Failed: 0x%08x\n", status);
477 len = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]);
478 partial_info = HeapAlloc(GetProcessHeap(), 0, len);
479 status = pNtQueryValueKey(key, &ValName, KeyValuePartialInformation, partial_info, len, &len);
480 ok(status == STATUS_BUFFER_OVERFLOW, "NtQueryValueKey should have returned STATUS_BUFFER_OVERFLOW instead of 0x%08x\n", status);
481 ok(partial_info->TitleIndex == 0, "NtQueryValueKey returned wrong TitleIndex %d\n", partial_info->Type);
482 ok(partial_info->Type == REG_DWORD, "NtQueryValueKey returned wrong Type %d\n", partial_info->Type);
483 ok(partial_info->DataLength == 4, "NtQueryValueKey returned wrong DataLength %d\n", partial_info->DataLength);
484 ok(len == FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[partial_info->DataLength]), "NtQueryValueKey returned wrong len %d\n", len);
485 HeapFree(GetProcessHeap(), 0, partial_info);
487 len = FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name[0]);
488 full_info = HeapAlloc(GetProcessHeap(), 0, len);
489 status = pNtQueryValueKey(key, &ValName, KeyValueFullInformation, full_info, len, &len);
490 ok(status == STATUS_BUFFER_OVERFLOW, "NtQueryValueKey should have returned STATUS_BUFFER_OVERFLOW instead of 0x%08x\n", status);
491 ok(full_info->TitleIndex == 0, "NtQueryValueKey returned wrong TitleIndex %d\n", full_info->Type);
492 ok(full_info->Type == REG_DWORD, "NtQueryValueKey returned wrong Type %d\n", full_info->Type);
493 ok(full_info->DataLength == 4, "NtQueryValueKey returned wrong DataLength %d\n", full_info->DataLength);
494 ok(full_info->NameLength == 20, "NtQueryValueKey returned wrong NameLength %d\n", full_info->NameLength);
495 todo_wine
496 ok(len == FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name[0]) + full_info->DataLength + full_info->NameLength,
497 "NtQueryValueKey returned wrong len %d\n", len);
498 HeapFree(GetProcessHeap(), 0, full_info);
500 pRtlFreeUnicodeString(&ValName);
501 pNtClose(key);
504 static void test_NtDeleteKey(void)
506 NTSTATUS status;
507 HANDLE hkey;
508 OBJECT_ATTRIBUTES attr;
509 ACCESS_MASK am = KEY_ALL_ACCESS;
511 status = pNtDeleteKey(NULL);
512 ok(status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got: 0x%08x\n", status);
514 InitializeObjectAttributes(&attr, &winetestpath, 0, 0, 0);
515 status = pNtOpenKey(&hkey, am, &attr);
517 status = pNtDeleteKey(hkey);
518 ok(status == STATUS_SUCCESS, "NtDeleteKey Failed: 0x%08x\n", status);
521 static void test_RtlpNtQueryValueKey(void)
523 NTSTATUS status;
525 status = pRtlpNtQueryValueKey(NULL, NULL, NULL, NULL);
526 ok(status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got: 0x%08x\n", status);
529 START_TEST(reg)
531 static const WCHAR winetest[] = {'\\','W','i','n','e','T','e','s','t','\\',0};
532 if(!InitFunctionPtrs())
533 return;
534 pRtlFormatCurrentUserKeyPath(&winetestpath);
535 winetestpath.Buffer = (PWSTR)pRtlReAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, winetestpath.Buffer,
536 winetestpath.MaximumLength + sizeof(winetest)*sizeof(WCHAR));
537 winetestpath.MaximumLength = winetestpath.MaximumLength + sizeof(winetest)*sizeof(WCHAR);
539 pRtlAppendUnicodeToString(&winetestpath, winetest);
541 test_NtOpenKey();
542 test_NtCreateKey();
543 test_NtSetValueKey();
544 test_RtlCheckRegistryKey();
545 test_RtlOpenCurrentUser();
546 test_RtlQueryRegistryValues();
547 test_RtlpNtQueryValueKey();
548 test_NtFlushKey();
549 test_NtQueryValueKey();
550 test_NtDeleteKey();
552 pRtlFreeUnicodeString(&winetestpath);
554 FreeLibrary(hntdll);