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 #define NTDLL_GET_PROC(func) \
103 p ## func = (void*)GetProcAddress(hntdll, #func); \
105 trace("GetProcAddress(%s) failed\n", #func); \
106 FreeLibrary(hntdll); \
110 static BOOL InitFunctionPtrs(void)
112 hntdll = LoadLibraryA("ntdll.dll");
114 trace("Could not load ntdll.dll\n");
119 NTDLL_GET_PROC(RtlCreateUnicodeStringFromAsciiz)
120 NTDLL_GET_PROC(RtlCreateUnicodeString)
121 NTDLL_GET_PROC(RtlFreeUnicodeString)
122 NTDLL_GET_PROC(NtDeleteValueKey)
123 NTDLL_GET_PROC(RtlQueryRegistryValues)
124 NTDLL_GET_PROC(RtlCheckRegistryKey)
125 NTDLL_GET_PROC(RtlOpenCurrentUser)
126 NTDLL_GET_PROC(NtClose)
127 NTDLL_GET_PROC(NtDeleteValueKey)
128 NTDLL_GET_PROC(NtCreateKey)
129 NTDLL_GET_PROC(NtDeleteKey)
130 NTDLL_GET_PROC(NtSetValueKey)
131 NTDLL_GET_PROC(NtOpenKey)
132 NTDLL_GET_PROC(RtlFormatCurrentUserKeyPath)
133 NTDLL_GET_PROC(RtlReAllocateHeap)
134 NTDLL_GET_PROC(RtlAppendUnicodeToString)
135 NTDLL_GET_PROC(RtlUnicodeStringToAnsiString)
136 NTDLL_GET_PROC(RtlFreeHeap)
137 NTDLL_GET_PROC(RtlAllocateHeap)
138 NTDLL_GET_PROC(RtlZeroMemory)
142 #undef NTDLL_GET_PROC
144 static NTSTATUS WINAPI QueryRoutine (IN PCWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData,
145 IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
147 NTSTATUS ret = STATUS_SUCCESS;
148 int ValueNameLength = 0;
150 trace("**Test %d**\n", CurrentTest);
154 ValueNameLength = strlenW(ValueName);
156 ValName = (LPSTR)pRtlAllocateHeap(GetProcessHeap(), 0, ValueNameLength);
158 WideCharToMultiByte(0, 0, ValueName, ValueNameLength+1,ValName, ValueNameLength, 0, 0);
160 trace("ValueName: %s\n", ValName);
163 trace("ValueName: (null)\n");
168 trace("ValueType: REG_NONE\n");
169 trace("ValueData: %d\n", (int)ValueData);
173 trace("ValueType: REG_BINARY\n");
174 trace("ValueData: %d\n", (int)ValueData);
178 trace("ValueType: REG_SZ\n");
179 trace("ValueData: %s\n", (char*)ValueData);
183 trace("ValueType: REG_MULTI_SZ\n");
184 trace("ValueData: %s\n", (char*)ValueData);
188 trace("ValueType: REG_EXPAND_SZ\n");
189 trace("ValueData: %s\n", (char*)ValueData);
193 trace("ValueType: REG_DWORD\n");
194 trace("ValueData: %d\n", (int)ValueData);
197 trace("ValueLength: %d\n", (int)ValueLength);
200 ok(1, "\n"); /*checks that QueryRoutine is called*/
202 ok(!1, "Invalid Test Specified!\n");
207 pRtlFreeHeap(GetProcessHeap(), 0, ValName);
212 static void test_RtlQueryRegistryValues(void)
216 ******************************
218 ******************************
219 *RTL_QUERY_REGISTRY_SUBKEY * Name is the name of a subkey relative to Path
220 *RTL_QUERY_REGISTRY_TOPKEY * Resets location to original RelativeTo and Path
221 *RTL_QUERY_REGISTRY_REQUIRED * Key required. returns STATUS_OBJECT_NAME_NOT_FOUND if not present
222 *RTL_QUERY_REGISTRY_NOVALUE * We just want a call-back
223 *RTL_QUERY_REGISTRY_NOEXPAND * Don't expand the variables!
224 *RTL_QUERY_REGISTRY_DIRECT * Results of query will be stored in EntryContext(QueryRoutine ignored)
225 *RTL_QUERY_REGISTRY_DELETE * Delete value key after query
226 ******************************
229 **Test layout(numbered according to CurrentTest value)**
230 0)NOVALUE Just make sure call-back works
231 1)Null Name See if QueryRoutine is called for every value in current key
232 2)SUBKEY See if we can use SUBKEY to change the current path on the fly
233 3)REQUIRED Test for value that's not there
234 4)NOEXPAND See if it will return multiple strings(no expand should split strings up)
235 5)DIRECT Make it store data directly in EntryContext and not call QueryRoutine
236 6)DefaultType Test return values when key isn't present
237 7)DefaultValue Test Default Value returned with key isn't present(and no REQUIRED flag set)
238 8)DefaultLength Test Default Length with DefaultType = REG_SZ
239 9)DefaultLength Test Default Length with DefaultType = REG_MULTI_SZ
240 10)DefaultLength Test Default Length with DefaultType = REG_EXPAND_SZ
241 11)DefaultData Test whether DefaultData is used while DefaltType = REG_NONE(shouldn't be)
242 12)Delete Try to delete value key
248 PRTL_QUERY_REGISTRY_TABLE QueryTable = NULL;
249 RelativeTo = RTL_REGISTRY_ABSOLUTE;/*Only using absolute - no need to test all relativeto variables*/
251 QueryTable = (PRTL_QUERY_REGISTRY_TABLE)pRtlAllocateHeap(GetProcessHeap(), 0, sizeof(RTL_QUERY_REGISTRY_TABLE)*26);
253 pRtlZeroMemory( QueryTable, sizeof(RTL_QUERY_REGISTRY_TABLE) * 26);
255 QueryTable[0].QueryRoutine = QueryRoutine;
256 QueryTable[0].Flags = RTL_QUERY_REGISTRY_NOVALUE;
257 QueryTable[0].Name = NULL;
258 QueryTable[0].EntryContext = NULL;
259 QueryTable[0].DefaultType = REG_BINARY;
260 QueryTable[0].DefaultData = NULL;
261 QueryTable[0].DefaultLength = 100;
263 QueryTable[1].QueryRoutine = QueryRoutine;
264 QueryTable[1].Flags = 0;
265 QueryTable[1].Name = NULL;
266 QueryTable[1].EntryContext = 0;
267 QueryTable[1].DefaultType = REG_NONE;
268 QueryTable[1].DefaultData = NULL;
269 QueryTable[1].DefaultLength = 0;
271 QueryTable[2].QueryRoutine = NULL;
272 QueryTable[2].Flags = 0;
273 QueryTable[2].Name = NULL;
274 QueryTable[2].EntryContext = 0;
275 QueryTable[2].DefaultType = REG_NONE;
276 QueryTable[2].DefaultData = NULL;
277 QueryTable[2].DefaultLength = 0;
279 status = pRtlQueryRegistryValues(RelativeTo, winetestpath.Buffer, QueryTable, 0, 0);
280 ok(status == STATUS_SUCCESS, "RtlQueryRegistryValues return: 0x%08lx\n", status);
282 pRtlFreeHeap(GetProcessHeap(), 0, QueryTable);
285 static void test_NtCreateKey(void)
288 OBJECT_ATTRIBUTES attr;
289 UNICODE_STRING ValName;
291 ACCESS_MASK am = GENERIC_ALL;
294 InitializeObjectAttributes(&attr, &winetestpath, 0, 0, 0);
295 status = pNtCreateKey(&key, am, &attr, 0, 0, 0, 0);
296 ok(status == STATUS_SUCCESS, "NtCreateKey Failed: 0x%08lx\n", status);
298 pRtlFreeUnicodeString(&ValName);
302 static void test_NtSetValueKey(void)
306 OBJECT_ATTRIBUTES attr;
307 ACCESS_MASK am = KEY_WRITE;
308 UNICODE_STRING ValName;
311 pRtlCreateUnicodeStringFromAsciiz(&ValName, "deletetest");
313 InitializeObjectAttributes(&attr, &winetestpath, 0, 0, 0);
314 status = pNtOpenKey(&key, am, &attr);
315 ok(status == STATUS_SUCCESS, "NtOpenKey Failed: 0x%08lx\n", status);
317 status = pNtSetValueKey(key, &ValName, 0, REG_DWORD, &data, sizeof(data));
318 ok(status == STATUS_SUCCESS, "NtSetValueKey Failed: 0x%08lx\n", status);
320 pRtlFreeUnicodeString(&ValName);
324 static void test_RtlOpenCurrentUser(void)
328 status=pRtlOpenCurrentUser(KEY_READ, &handle);
329 ok(status == STATUS_SUCCESS, "RtlOpenCurrentUser Failed: 0x%08lx\n", status);
333 static void test_RtlCheckRegistryKey(void)
337 status = pRtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, winetestpath.Buffer);
338 ok(status == STATUS_SUCCESS, "RtlCheckRegistryKey with RTL_REGISTRY_ABSOLUTE: 0x%08lx\n", status);
340 status = pRtlCheckRegistryKey((RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL), winetestpath.Buffer);
341 ok(status == STATUS_SUCCESS, "RtlCheckRegistryKey with RTL_REGISTRY_ABSOLUTE and RTL_REGISTRY_OPTIONAL: 0x%08lx\n", status);
344 static void test_NtDeleteKey()
348 OBJECT_ATTRIBUTES attr;
349 ACCESS_MASK am = KEY_ALL_ACCESS;
351 InitializeObjectAttributes(&attr, &winetestpath, 0, 0, 0);
352 status = pNtOpenKey(&hkey, am, &attr);
354 status = pNtDeleteKey(hkey);
355 ok(status == STATUS_SUCCESS, "NtDeleteKey Failed: 0x%08lx\n", status);
360 static const WCHAR winetest[] = {'\\','W','i','n','e','T','e','s','t','\\',0};
361 if(!InitFunctionPtrs())
363 pRtlFormatCurrentUserKeyPath(&winetestpath);
364 winetestpath.Buffer = (PWSTR)pRtlReAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, winetestpath.Buffer,
365 winetestpath.MaximumLength + sizeof(winetest)*sizeof(WCHAR));
366 winetestpath.MaximumLength = winetestpath.MaximumLength + sizeof(winetest)*sizeof(WCHAR);
368 pRtlAppendUnicodeToString(&winetestpath, winetest);
371 test_NtSetValueKey();
372 test_RtlCheckRegistryKey();
373 test_RtlOpenCurrentUser();
374 test_RtlQueryRegistryValues();
377 pRtlFreeUnicodeString(&winetestpath);