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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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"
27 #include "wine/library.h"
32 #include "wine/unicode.h"
34 #ifndef __WINE_WINTERNL_H
36 /* RtlQueryRegistryValues structs and defines */
37 #define RTL_REGISTRY_ABSOLUTE 0
38 #define RTL_REGISTRY_SERVICES 1
39 #define RTL_REGISTRY_CONTROL 2
40 #define RTL_REGISTRY_WINDOWS_NT 3
41 #define RTL_REGISTRY_DEVICEMAP 4
42 #define RTL_REGISTRY_USER 5
44 #define RTL_REGISTRY_HANDLE 0x40000000
45 #define RTL_REGISTRY_OPTIONAL 0x80000000
47 #define RTL_QUERY_REGISTRY_SUBKEY 0x00000001
48 #define RTL_QUERY_REGISTRY_TOPKEY 0x00000002
49 #define RTL_QUERY_REGISTRY_REQUIRED 0x00000004
50 #define RTL_QUERY_REGISTRY_NOVALUE 0x00000008
51 #define RTL_QUERY_REGISTRY_NOEXPAND 0x00000010
52 #define RTL_QUERY_REGISTRY_DIRECT 0x00000020
53 #define RTL_QUERY_REGISTRY_DELETE 0x00000040
55 typedef NTSTATUS (WINAPI *PRTL_QUERY_REGISTRY_ROUTINE)( PCWSTR ValueName,
62 typedef struct _RTL_QUERY_REGISTRY_TABLE {
63 PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine;
70 } RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE;
74 static NTSTATUS (WINAPI * pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING, LPCSTR);
75 static NTSTATUS (WINAPI * pRtlFreeUnicodeString)(PUNICODE_STRING);
76 static NTSTATUS (WINAPI * pNtDeleteValueKey)(IN HANDLE, IN PUNICODE_STRING);
77 static NTSTATUS (WINAPI * pRtlQueryRegistryValues)(IN ULONG, IN PCWSTR,IN PRTL_QUERY_REGISTRY_TABLE, IN PVOID,IN PVOID);
78 static NTSTATUS (WINAPI * pRtlCheckRegistryKey)(IN ULONG,IN PWSTR);
79 static NTSTATUS (WINAPI * pRtlOpenCurrentUser)(IN ACCESS_MASK, OUT PHKEY);
80 static NTSTATUS (WINAPI * pNtOpenKey)(PHANDLE, IN ACCESS_MASK, IN POBJECT_ATTRIBUTES);
81 static NTSTATUS (WINAPI * pNtClose)(IN HANDLE);
82 static NTSTATUS (WINAPI * pNtDeleteValueKey)(IN HANDLE, IN PUNICODE_STRING);
83 static NTSTATUS (WINAPI * pNtDeleteKey)(HKEY);
84 static NTSTATUS (WINAPI * pNtCreateKey)( PHKEY retkey, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr,
85 ULONG TitleIndex, const UNICODE_STRING *class, ULONG options,
87 static NTSTATUS (WINAPI * pNtSetValueKey)( PHKEY, const PUNICODE_STRING, ULONG,
88 ULONG, const PVOID, ULONG );
89 static NTSTATUS (WINAPI * pRtlFormatCurrentUserKeyPath)(PUNICODE_STRING);
90 static NTSTATUS (WINAPI * pRtlCreateUnicodeString)( PUNICODE_STRING, LPCWSTR);
91 static NTSTATUS (WINAPI * pRtlReAllocateHeap)(IN PVOID, IN ULONG, IN PVOID, IN ULONG);
92 static NTSTATUS (WINAPI * pRtlAppendUnicodeToString)(PUNICODE_STRING, PCWSTR);
93 static NTSTATUS (WINAPI * pRtlUnicodeStringToAnsiString)(PSTRING, PUNICODE_STRING, BOOL);
94 static NTSTATUS (WINAPI * pRtlFreeHeap)(PVOID, ULONG, PVOID);
95 static NTSTATUS (WINAPI * pRtlAllocateHeap)(PVOID,ULONG,ULONG);
96 static NTSTATUS (WINAPI * pRtlZeroMemory)(PVOID, ULONG);
98 static HMODULE hntdll = 0;
99 static int CurrentTest = 0;
100 static UNICODE_STRING winetestpath;
102 static void InitFunctionPtrs(void)
104 hntdll = LoadLibraryA("ntdll.dll");
105 ok(hntdll != 0, "LoadLibrary failed\n");
108 pRtlCreateUnicodeStringFromAsciiz = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeStringFromAsciiz");
109 pRtlCreateUnicodeString = (void*)GetProcAddress(hntdll, "RtlCreateUnicodeString");
110 pRtlFreeUnicodeString = (void*)GetProcAddress(hntdll, "RtlFreeUnicodeString");
111 pNtDeleteValueKey = (void*)GetProcAddress(hntdll, "NtDeleteValueKey");
112 pRtlQueryRegistryValues = (void*)GetProcAddress(hntdll, "RtlQueryRegistryValues");
113 pRtlCheckRegistryKey = (void*)GetProcAddress(hntdll, "RtlCheckRegistryKey");
114 pRtlOpenCurrentUser = (void*)GetProcAddress(hntdll, "RtlOpenCurrentUser");
115 pNtClose = (void*)GetProcAddress(hntdll, "NtClose");
116 pNtDeleteValueKey = (void*)GetProcAddress(hntdll, "NtDeleteValueKey");
117 pNtCreateKey = (void*)GetProcAddress(hntdll, "NtCreateKey");
118 pNtDeleteKey = (void*)GetProcAddress(hntdll, "NtDeleteKey");
119 pNtSetValueKey = (void*)GetProcAddress(hntdll, "NtSetValueKey");
120 pNtOpenKey = (void*)GetProcAddress(hntdll, "NtOpenKey");
121 pRtlFormatCurrentUserKeyPath = (void*)GetProcAddress(hntdll, "RtlFormatCurrentUserKeyPath");
122 pRtlReAllocateHeap = (void*)GetProcAddress(hntdll, "RtlReAllocateHeap");
123 pRtlAppendUnicodeToString = (void*)GetProcAddress(hntdll, "RtlAppendUnicodeToString");
124 pRtlUnicodeStringToAnsiString = (void*)GetProcAddress(hntdll, "RtlUnicodeStringToAnsiString");
125 pRtlFreeHeap = (void*)GetProcAddress(hntdll, "RtlFreeHeap");
126 pRtlAllocateHeap = (void*)GetProcAddress(hntdll, "RtlAllocateHeap");
127 pRtlZeroMemory = (void*)GetProcAddress(hntdll, "RtlZeroMemory");
133 static NTSTATUS WINAPI QueryRoutine (IN PCWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData,
134 IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
136 NTSTATUS ret = STATUS_SUCCESS;
137 int ValueNameLength = 0;
139 trace("**Test %d**\n", CurrentTest);
143 ValueNameLength = strlenW(ValueName);
145 ValName = (LPSTR)pRtlAllocateHeap(GetProcessHeap(), 0, ValueNameLength);
147 WideCharToMultiByte(0, 0, ValueName, ValueNameLength+1,ValName, ValueNameLength, 0, 0);
149 trace("ValueName: %s\n", ValName);
152 trace("ValueName: (null)\n");
157 trace("ValueType: REG_NONE\n");
158 trace("ValueData: %d\n", (int)ValueData);
162 trace("ValueType: REG_BINARY\n");
163 trace("ValueData: %d\n", (int)ValueData);
167 trace("ValueType: REG_SZ\n");
168 trace("ValueData: %s\n", (char*)ValueData);
172 trace("ValueType: REG_MULTI_SZ\n");
173 trace("ValueData: %s\n", (char*)ValueData);
177 trace("ValueType: REG_EXPAND_SZ\n");
178 trace("ValueData: %s\n", (char*)ValueData);
182 trace("ValueType: REG_DWORD\n");
183 trace("ValueData: %d\n", (int)ValueData);
186 trace("ValueLength: %d\n", (int)ValueLength);
189 ok(1, "\n"); /*checks that QueryRoutine is called*/
191 ok(!1, "Invalid Test Specified!\n");
196 pRtlFreeHeap(GetProcessHeap(), 0, ValName);
201 static void test_RtlQueryRegistryValues(void)
205 ******************************
207 ******************************
208 *RTL_QUERY_REGISTRY_SUBKEY * Name is the name of a subkey relative to Path
209 *RTL_QUERY_REGISTRY_TOPKEY * Resets location to original RelativeTo and Path
210 *RTL_QUERY_REGISTRY_REQUIRED * Key required. returns STATUS_OBJECT_NAME_NOT_FOUND if not present
211 *RTL_QUERY_REGISTRY_NOVALUE * We just want a call-back
212 *RTL_QUERY_REGISTRY_NOEXPAND * Don't expand the variables!
213 *RTL_QUERY_REGISTRY_DIRECT * Results of query will be stored in EntryContext(QueryRoutine ignored)
214 *RTL_QUERY_REGISTRY_DELETE * Delete value key after query
215 ******************************
218 **Test layout(numbered according to CurrentTest value)**
219 0)NOVALUE Just make sure call-back works
220 1)Null Name See if QueryRoutine is called for every value in current key
221 2)SUBKEY See if we can use SUBKEY to change the current path on the fly
222 3)REQUIRED Test for value that's not there
223 4)NOEXPAND See if it will return multiple strings(no expand should split strings up)
224 5)DIRECT Make it store data directly in EntryContext and not call QueryRoutine
225 6)DefaultType Test return values when key isn't present
226 7)DefaultValue Test Default Value returned with key isn't present(and no REQUIRED flag set)
227 8)DefaultLength Test Default Length with DefaultType = REG_SZ
228 9)DefaultLength Test Default Length with DefaultType = REG_MULTI_SZ
229 10)DefaultLength Test Default Length with DefaultType = REG_EXPAND_SZ
230 11)DefaultData Test whether DefaultData is used while DefaltType = REG_NONE(shouldn't be)
231 12)Delete Try to delete value key
237 PRTL_QUERY_REGISTRY_TABLE QueryTable = NULL;
238 RelativeTo = RTL_REGISTRY_ABSOLUTE;/*Only using absolute - no need to test all relativeto variables*/
240 QueryTable = (PRTL_QUERY_REGISTRY_TABLE)pRtlAllocateHeap(GetProcessHeap(), 0, sizeof(RTL_QUERY_REGISTRY_TABLE)*26);
242 pRtlZeroMemory( QueryTable, sizeof(RTL_QUERY_REGISTRY_TABLE) * 26);
244 QueryTable[0].QueryRoutine = QueryRoutine;
245 QueryTable[0].Flags = RTL_QUERY_REGISTRY_NOVALUE;
246 QueryTable[0].Name = NULL;
247 QueryTable[0].EntryContext = NULL;
248 QueryTable[0].DefaultType = REG_BINARY;
249 QueryTable[0].DefaultData = NULL;
250 QueryTable[0].DefaultLength = 100;
252 QueryTable[1].QueryRoutine = QueryRoutine;
253 QueryTable[1].Flags = 0;
254 QueryTable[1].Name = NULL;
255 QueryTable[1].EntryContext = 0;
256 QueryTable[1].DefaultType = REG_NONE;
257 QueryTable[1].DefaultData = NULL;
258 QueryTable[1].DefaultLength = 0;
260 QueryTable[2].QueryRoutine = NULL;
261 QueryTable[2].Flags = 0;
262 QueryTable[2].Name = NULL;
263 QueryTable[2].EntryContext = 0;
264 QueryTable[2].DefaultType = REG_NONE;
265 QueryTable[2].DefaultData = NULL;
266 QueryTable[2].DefaultLength = 0;
268 status = pRtlQueryRegistryValues(RelativeTo, winetestpath.Buffer, QueryTable, 0, 0);
269 ok(status == STATUS_SUCCESS, "RtlQueryRegistryValues return: 0x%08lx\n", status);
271 pRtlFreeHeap(GetProcessHeap(), 0, QueryTable);
274 static void test_NtCreateKey(void)
277 OBJECT_ATTRIBUTES attr;
278 UNICODE_STRING ValName;
280 ACCESS_MASK am = GENERIC_ALL;
283 InitializeObjectAttributes(&attr, &winetestpath, 0, 0, 0);
284 status = pNtCreateKey(&key, am, &attr, 0, 0, 0, 0);
285 ok(status == STATUS_SUCCESS, "NtCreateKey Failed: 0x%08lx\n", status);
287 pRtlFreeUnicodeString(&ValName);
291 static void test_NtSetValueKey(void)
295 OBJECT_ATTRIBUTES attr;
296 ACCESS_MASK am = KEY_WRITE;
297 UNICODE_STRING ValName;
300 pRtlCreateUnicodeStringFromAsciiz(&ValName, "deletetest");
302 InitializeObjectAttributes(&attr, &winetestpath, 0, 0, 0);
303 status = pNtOpenKey(&key, am, &attr);
304 ok(status == STATUS_SUCCESS, "NtOpenKey Failed: 0x%08lx\n", status);
306 status = pNtSetValueKey(key, &ValName, 0, REG_DWORD, &data, sizeof(data));
307 ok(status == STATUS_SUCCESS, "NtSetValueKey Failed: 0x%08lx\n", status);
309 pRtlFreeUnicodeString(&ValName);
313 static void test_RtlOpenCurrentUser(void)
317 status=pRtlOpenCurrentUser(KEY_READ, &handle);
318 ok(status == STATUS_SUCCESS, "RtlOpenCurrentUser Failed: 0x%08lx\n", status);
322 static void test_RtlCheckRegistryKey(void)
326 status = pRtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, winetestpath.Buffer);
327 ok(status == STATUS_SUCCESS, "RtlCheckRegistryKey with RTL_REGISTRY_ABSOLUTE: 0x%08lx\n", status);
329 status = pRtlCheckRegistryKey((RTL_REGISTRY_ABSOLUTE & RTL_REGISTRY_OPTIONAL), winetestpath.Buffer);
330 ok(status == STATUS_SUCCESS, "RtlCheckRegistryKey with RTL_REGISTRY_ABSOLUTE & RTL_REGISTRY_OPTIONAL: 0x%08lx\n", status);
333 static void test_NtDeleteKey()
337 OBJECT_ATTRIBUTES attr;
338 ACCESS_MASK am = KEY_ALL_ACCESS;
340 InitializeObjectAttributes(&attr, &winetestpath, 0, 0, 0);
341 status = pNtOpenKey(&hkey, am, &attr);
343 status = pNtDeleteKey(hkey);
344 ok(status == STATUS_SUCCESS, "NtDeleteKey Failed: 0x%08lx\n", status);
349 static const WCHAR winetest[] = {'\\','W','i','n','e','T','e','s','t','\\',0};
351 pRtlFormatCurrentUserKeyPath(&winetestpath);
352 winetestpath.Buffer = (PWSTR)pRtlReAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, winetestpath.Buffer,
353 winetestpath.MaximumLength + sizeof(winetest)*sizeof(WCHAR));
354 winetestpath.MaximumLength = winetestpath.MaximumLength + sizeof(winetest)*sizeof(WCHAR);
356 pRtlAppendUnicodeToString(&winetestpath, winetest);
359 test_NtSetValueKey();
360 test_RtlCheckRegistryKey();
361 test_RtlOpenCurrentUser();
362 test_RtlQueryRegistryValues();
365 pRtlFreeUnicodeString(&winetestpath);