ReactOS 0.4.17-dev-116-ga4b6fe9
reg.c
Go to the documentation of this file.
1/* Unit test suite for Rtl* Registry API functions
2 *
3 * Copyright 2003 Thomas Mertes
4 * Copyright 2005 Brad DeMorrow
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 * NOTE: I don't test every RelativeTo value because it would be redundant, all calls go through
21 * helper function RTL_GetKeyHandle().--Brad DeMorrow
22 *
23 */
24
25#include <stdarg.h>
26#include <stdio.h>
27#include <stdlib.h>
28
29#include "ntstatus.h"
30#define WIN32_NO_STATUS
31#include "windef.h"
32#include "winbase.h"
33#include "winreg.h"
34#include "winnls.h"
35#include "winternl.h"
36#include "wine/test.h"
37#ifdef __REACTOS__
38#define REG_APP_HIVE 0x10
39#endif
40
41/* A test string */
42static const WCHAR stringW[] = {'s', 't', 'r', 'i', 'n', 'g', 'W', 0};
43/* A size, in bytes, short enough to cause truncation of the above */
44#define STR_TRUNC_SIZE (sizeof(stringW)-2*sizeof(*stringW))
45
46#ifndef __WINE_WINTERNL_H
47
48/* RtlQueryRegistryValues structs and defines */
49#define RTL_REGISTRY_ABSOLUTE 0
50#define RTL_REGISTRY_SERVICES 1
51#define RTL_REGISTRY_CONTROL 2
52#define RTL_REGISTRY_WINDOWS_NT 3
53#define RTL_REGISTRY_DEVICEMAP 4
54#define RTL_REGISTRY_USER 5
55
56#define RTL_REGISTRY_HANDLE 0x40000000
57#define RTL_REGISTRY_OPTIONAL 0x80000000
58
59#define RTL_QUERY_REGISTRY_SUBKEY 0x00000001
60#define RTL_QUERY_REGISTRY_TOPKEY 0x00000002
61#define RTL_QUERY_REGISTRY_REQUIRED 0x00000004
62#define RTL_QUERY_REGISTRY_NOVALUE 0x00000008
63#define RTL_QUERY_REGISTRY_NOEXPAND 0x00000010
64#define RTL_QUERY_REGISTRY_DIRECT 0x00000020
65#define RTL_QUERY_REGISTRY_DELETE 0x00000040
66
73
74typedef struct _RTL_QUERY_REGISTRY_TABLE {
77 PWSTR Name;
83
84typedef struct _KEY_VALUE_BASIC_INFORMATION {
86 ULONG Type;
88 WCHAR Name[1];
90
91typedef struct _KEY_VALUE_PARTIAL_INFORMATION {
93 ULONG Type;
95 UCHAR Data[1];
97
98typedef struct _KEY_VALUE_FULL_INFORMATION {
100 ULONG Type;
104 WCHAR Name[1];
106
114
115#define InitializeObjectAttributes(p,n,a,r,s) \
116 do { \
117 (p)->Length = sizeof(OBJECT_ATTRIBUTES); \
118 (p)->RootDirectory = r; \
119 (p)->Attributes = a; \
120 (p)->ObjectName = n; \
121 (p)->SecurityDescriptor = s; \
122 (p)->SecurityQualityOfService = NULL; \
123 } while (0)
124
125#endif
126
127static BOOLEAN (WINAPI * pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING, LPCSTR);
128static void (WINAPI * pRtlInitUnicodeString)(PUNICODE_STRING,PCWSTR);
129static NTSTATUS (WINAPI * pRtlFreeUnicodeString)(PUNICODE_STRING);
130static NTSTATUS (WINAPI * pNtDeleteValueKey)(IN HANDLE, IN PUNICODE_STRING);
131static NTSTATUS (WINAPI * pRtlQueryRegistryValues)(IN ULONG, IN PCWSTR,IN PRTL_QUERY_REGISTRY_TABLE, IN PVOID,IN PVOID);
132static NTSTATUS (WINAPI * pRtlCheckRegistryKey)(IN ULONG,IN PWSTR);
133static NTSTATUS (WINAPI * pRtlOpenCurrentUser)(IN ACCESS_MASK, PHANDLE);
136static NTSTATUS (WINAPI * pNtClose)(IN HANDLE);
137static NTSTATUS (WINAPI * pNtEnumerateKey)(HANDLE, ULONG, KEY_INFORMATION_CLASS, void *, DWORD, DWORD *);
138static NTSTATUS (WINAPI * pNtEnumerateValueKey)(HANDLE, ULONG, KEY_VALUE_INFORMATION_CLASS, void *, DWORD, DWORD *);
139static NTSTATUS (WINAPI * pNtFlushKey)(HANDLE);
140static NTSTATUS (WINAPI * pNtDeleteKey)(HANDLE);
141static NTSTATUS (WINAPI * pNtCreateKey)( PHANDLE retkey, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr,
145static NTSTATUS (WINAPI * pNtQueryLicenseValue)(const UNICODE_STRING *,ULONG *,PVOID,ULONG,ULONG *);
146static NTSTATUS (WINAPI * pNtQueryObject)(HANDLE, OBJECT_INFORMATION_CLASS, void *, ULONG, ULONG *);
147static NTSTATUS (WINAPI * pNtQueryValueKey)(HANDLE,const UNICODE_STRING *,KEY_VALUE_INFORMATION_CLASS,void *,DWORD,DWORD *);
148static NTSTATUS (WINAPI * pNtSetValueKey)(HANDLE, const PUNICODE_STRING, ULONG,
149 ULONG, const void*, ULONG );
150static NTSTATUS (WINAPI * pRtlFormatCurrentUserKeyPath)(PUNICODE_STRING);
151static LONG (WINAPI * pRtlCompareUnicodeString)(const PUNICODE_STRING,const PUNICODE_STRING,BOOLEAN);
152static BOOLEAN (WINAPI * pRtlCreateUnicodeString)(PUNICODE_STRING, LPCWSTR);
153static LPVOID (WINAPI * pRtlReAllocateHeap)(IN PVOID, IN ULONG, IN PVOID, IN ULONG);
154static NTSTATUS (WINAPI * pRtlAppendUnicodeToString)(PUNICODE_STRING, PCWSTR);
155static NTSTATUS (WINAPI * pRtlUnicodeStringToAnsiString)(PSTRING, PUNICODE_STRING, BOOL);
156static NTSTATUS (WINAPI * pRtlFreeHeap)(PVOID, ULONG, PVOID);
157static LPVOID (WINAPI * pRtlAllocateHeap)(PVOID,ULONG,ULONG);
158static NTSTATUS (WINAPI * pRtlZeroMemory)(PVOID, ULONG);
159static NTSTATUS (WINAPI * pRtlCreateRegistryKey)(ULONG, PWSTR);
160static NTSTATUS (WINAPI * pRtlpNtQueryValueKey)(HANDLE,ULONG*,PBYTE,DWORD*,void *);
162static NTSTATUS (WINAPI * pNtNotifyChangeMultipleKeys)(HANDLE,ULONG,OBJECT_ATTRIBUTES*,HANDLE,PIO_APC_ROUTINE,
164static NTSTATUS (WINAPI * pNtWaitForSingleObject)(HANDLE,BOOLEAN,const LARGE_INTEGER*);
166
167static HMODULE hntdll = 0;
169
170#define NTDLL_GET_PROC(func) \
171 p ## func = (void*)GetProcAddress(hntdll, #func); \
172 if(!p ## func) { \
173 trace("GetProcAddress(%s) failed\n", #func); \
174 FreeLibrary(hntdll); \
175 return FALSE; \
176 }
177
179{
180 hntdll = LoadLibraryA("ntdll.dll");
181 if(!hntdll) {
182 trace("Could not load ntdll.dll\n");
183 return FALSE;
184 }
218
219 /* optional functions */
220 pNtQueryLicenseValue = (void *)GetProcAddress(hntdll, "NtQueryLicenseValue");
221 pNtOpenKeyEx = (void *)GetProcAddress(hntdll, "NtOpenKeyEx");
222 pNtNotifyChangeMultipleKeys = (void *)GetProcAddress(hntdll, "NtNotifyChangeMultipleKeys");
223
224 return TRUE;
225}
226#undef NTDLL_GET_PROC
227
228static void test_NtOpenKey(void)
229{
230 HANDLE key, subkey;
235
236 /* All NULL */
237 status = pNtOpenKey(NULL, 0, NULL);
238 ok(status == STATUS_ACCESS_VIOLATION, "Expected STATUS_ACCESS_VIOLATION, got: 0x%08lx\n", status);
239
240 /* NULL attributes */
241 status = pNtOpenKey(&key, 0, NULL);
242 ok(status == STATUS_ACCESS_VIOLATION, "Expected STATUS_ACCESS_VIOLATION, got: 0x%08lx\n", status);
243
245
246 /* NULL key */
247 status = pNtOpenKey(NULL, am, &attr);
248 ok(status == STATUS_ACCESS_VIOLATION, "Expected STATUS_ACCESS_VIOLATION, got: 0x%08lx\n", status);
249
250 /* Length > sizeof(OBJECT_ATTRIBUTES) */
251 attr.Length *= 2;
252 status = pNtOpenKey(&key, am, &attr);
253 ok(status == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got: 0x%08lx\n", status);
254
255 /* Zero accessmask */
256 attr.Length = sizeof(attr);
257 key = (HANDLE)0xdeadbeef;
258 status = pNtOpenKey(&key, 0, &attr);
260 ok(status == STATUS_ACCESS_DENIED, "Expected STATUS_ACCESS_DENIED, got: 0x%08lx\n", status);
262 ok(!key, "key = %p\n", key);
264
265 /* Calling without parent key requires full registry path. */
266 pRtlCreateUnicodeStringFromAsciiz( &str, "Machine" );
268 key = (HANDLE)0xdeadbeef;
269 status = pNtOpenKey(&key, KEY_READ, &attr);
270 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtOpenKey Failed: 0x%08lx\n", status);
271 ok(!key, "key = %p\n", key);
272 pRtlFreeUnicodeString( &str );
273
274 /* Open is case sensitive unless OBJ_CASE_INSENSITIVE is specified. */
275 pRtlCreateUnicodeStringFromAsciiz( &str, "\\Registry\\Machine" );
276 status = pNtOpenKey(&key, KEY_READ, &attr);
278 "NtOpenKey Failed: 0x%08lx\n", status);
279 if (!status) pNtClose( key );
280
281 attr.Attributes = OBJ_CASE_INSENSITIVE;
282 status = pNtOpenKey(&key, KEY_READ, &attr);
283 ok(status == STATUS_SUCCESS, "NtOpenKey Failed: 0x%08lx\n", status);
284 pNtClose(key);
285 pRtlFreeUnicodeString( &str );
286
287 pRtlCreateUnicodeStringFromAsciiz( &str, "" );
288 status = pNtOpenKey(&key, KEY_READ, &attr);
289 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtOpenKey failed: 0x%08lx\n", status );
290 pRtlFreeUnicodeString( &str );
291
292 pRtlCreateUnicodeStringFromAsciiz( &str, "\\" );
293 status = pNtOpenKey(&key, KEY_READ, &attr);
294 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtOpenKey failed: 0x%08lx\n", status );
295 pRtlFreeUnicodeString( &str );
296
297 pRtlCreateUnicodeStringFromAsciiz( &str, "\\\\\\" );
298 status = pNtOpenKey(&key, KEY_READ, &attr);
299 ok( status == STATUS_OBJECT_NAME_INVALID, "NtOpenKey failed: 0x%08lx\n", status );
300 pRtlFreeUnicodeString( &str );
301
302 pRtlCreateUnicodeStringFromAsciiz( &str, "\\Registry" );
303 status = pNtOpenKey(&key, KEY_READ, &attr);
304 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
305 pNtClose( key );
306 pRtlFreeUnicodeString( &str );
307
308 pRtlCreateUnicodeStringFromAsciiz( &str, "\\Registry\\" );
309 status = pNtOpenKey(&key, KEY_READ, &attr);
310 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
311 pNtClose( key );
312 pRtlFreeUnicodeString( &str );
313
314 pRtlCreateUnicodeStringFromAsciiz( &str, "\\Registry\\\\" );
315 status = pNtOpenKey(&key, KEY_READ, &attr);
316 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
317 pNtClose( key );
318 pRtlFreeUnicodeString( &str );
319
320 pRtlCreateUnicodeStringFromAsciiz( &str, "\\Foobar" );
321 status = pNtOpenKey(&key, KEY_READ, &attr);
322 ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtOpenKey failed: 0x%08lx\n", status );
323 pRtlFreeUnicodeString( &str );
324
325 pRtlCreateUnicodeStringFromAsciiz( &str, "\\Foobar\\Machine" );
326 status = pNtOpenKey(&key, KEY_READ, &attr);
327 ok( status == STATUS_OBJECT_PATH_NOT_FOUND, "NtOpenKey failed: 0x%08lx\n", status );
328 pRtlFreeUnicodeString( &str );
329
330 pRtlCreateUnicodeStringFromAsciiz( &str, "\\Machine\\Software\\Classes" );
331 status = pNtOpenKey(&key, KEY_READ, &attr);
332 ok( status == STATUS_OBJECT_PATH_NOT_FOUND, "NtOpenKey failed: 0x%08lx\n", status );
333 pRtlFreeUnicodeString( &str );
334
335 pRtlCreateUnicodeStringFromAsciiz( &str, "Machine\\Software\\Classes" );
336 status = pNtOpenKey(&key, KEY_READ, &attr);
337 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtOpenKey failed: 0x%08lx\n", status );
338 pRtlFreeUnicodeString( &str );
339
340 pRtlCreateUnicodeStringFromAsciiz( &str, "\\Device\\Null" );
341 status = pNtOpenKey(&key, KEY_READ, &attr);
342 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtOpenKey failed: 0x%08lx\n", status );
343 pRtlFreeUnicodeString( &str );
344
346 status = pNtOpenKey(&key, KEY_WRITE|KEY_READ, &attr);
347 ok(status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status);
348
349 /* keys are case insensitive even without OBJ_CASE_INSENSITIVE */
351 pRtlInitUnicodeString( &str, L"\xf6\xf3\x14d\x371\xd801\xdc00" );
352 status = pNtCreateKey( &subkey, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0);
353 ok(status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status);
354 pNtClose( subkey );
355#ifdef __REACTOS__
356 if (pNtOpenKeyEx == NULL)
357 {
358 pNtClose(key);
359 win_skip("NtOpenKeyEx not available\n");
360 return;
361 }
362#endif
363 pRtlInitUnicodeString( &str, L"\xd6\xd3\x14c\x370\xd801\xdc28" ); /* surrogates not supported */
364 status = pNtOpenKeyEx(&subkey, KEY_ALL_ACCESS, &attr, 0);
365 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "NtOpenKeyEx failed: 0x%08lx\n", status);
366 pRtlInitUnicodeString( &str, L"\xd6\xd3\x14c\x370\xd801\xdc00" );
367 status = pNtOpenKeyEx(&subkey, KEY_ALL_ACCESS, &attr, 0);
368 ok(status == STATUS_SUCCESS, "NtOpenKeyEx failed: 0x%08lx\n", status);
369
370 pNtDeleteKey( subkey );
371 pNtClose( subkey );
372 pNtClose( key );
373
374 if (!pNtOpenKeyEx)
375 {
376 win_skip("NtOpenKeyEx not available\n");
377 return;
378 }
379
381 status = pNtOpenKeyEx(&key, KEY_WRITE|KEY_READ, &attr, 0);
382 ok(status == STATUS_SUCCESS, "NtOpenKeyEx Failed: 0x%08lx\n", status);
383
384 pNtClose(key);
385}
386
387static void test_NtCreateKey(void)
388{
389 /*Create WineTest*/
391 HANDLE key, subkey, subkey2;
395
396 /* All NULL */
397 status = pNtCreateKey(NULL, 0, NULL, 0, 0, 0, 0);
399 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_PARAMETER, got: 0x%08lx\n", status);
400
401 /* Only the key */
402 status = pNtCreateKey(&key, 0, NULL, 0, 0, 0, 0);
403 ok(status == STATUS_ACCESS_VIOLATION, "Expected STATUS_ACCESS_VIOLATION, got: 0x%08lx\n", status);
404
405 /* Only accessmask */
406 status = pNtCreateKey(NULL, am, NULL, 0, 0, 0, 0);
408 "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_PARAMETER, got: 0x%08lx\n", status);
409
410 /* Key and accessmask */
411 status = pNtCreateKey(&key, am, NULL, 0, 0, 0, 0);
412 ok(status == STATUS_ACCESS_VIOLATION, "Expected STATUS_ACCESS_VIOLATION, got: 0x%08lx\n", status);
413
415
416 /* Only attributes */
417 status = pNtCreateKey(NULL, 0, &attr, 0, 0, 0, 0);
419 "Expected STATUS_ACCESS_VIOLATION or STATUS_ACCESS_DENIED, got: 0x%08lx\n", status);
420
421 /* Length > sizeof(OBJECT_ATTRIBUTES) */
422 attr.Length *= 2;
423 status = pNtCreateKey(&key, am, &attr, 0, 0, 0, 0);
424 ok(status == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got: 0x%08lx\n", status);
425
426 attr.Length = sizeof(attr);
427 status = pNtCreateKey(&key, am, &attr, 0, 0, 0, 0);
428 ok(status == STATUS_SUCCESS, "NtCreateKey Failed: 0x%08lx\n", status);
429
430 attr.RootDirectory = key;
431 attr.ObjectName = &str;
432
433 pRtlCreateUnicodeStringFromAsciiz( &str, "test\\sub\\key" );
434 status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 );
435 ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtCreateKey failed: 0x%08lx\n", status );
436 pRtlFreeUnicodeString( &str );
437
438 pRtlCreateUnicodeStringFromAsciiz( &str, "test\\subkey" );
439 status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 );
440 ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtCreateKey failed: 0x%08lx\n", status );
441 pRtlFreeUnicodeString( &str );
442
443 pRtlCreateUnicodeStringFromAsciiz( &str, "test\\\\subkey" );
444 status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 );
445 ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtCreateKey failed: 0x%08lx\n", status );
446 pRtlFreeUnicodeString( &str );
447
448 pRtlCreateUnicodeStringFromAsciiz( &str, "test\\subkey\\" );
449 status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 );
450 ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtCreateKey failed: 0x%08lx\n", status );
451 pRtlFreeUnicodeString( &str );
452
453 pRtlCreateUnicodeStringFromAsciiz( &str, "test_subkey\\" );
454 status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 );
455 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
456
457 pRtlCreateUnicodeStringFromAsciiz( &str, "test_subkey\\" );
458 status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 );
459 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
460 pNtDeleteKey( subkey );
461 pNtClose( subkey );
462 pRtlFreeUnicodeString( &str );
463
464 pRtlCreateUnicodeStringFromAsciiz( &str, "test_subkey2\\\\" );
465 status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 );
466 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
467 pRtlCreateUnicodeStringFromAsciiz( &str, "test_subkey2\\\\test\\\\" );
468 status = pNtCreateKey( &subkey2, am, &attr, 0, 0, 0, 0 );
469 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
470 pRtlFreeUnicodeString( &str );
471 pNtDeleteKey( subkey2 );
472 pNtClose( subkey2 );
473 pNtDeleteKey( subkey );
474 pNtClose( subkey );
475
476 pRtlCreateUnicodeStringFromAsciiz( &str, "test_subkey" );
477 status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 );
478 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
479 pRtlFreeUnicodeString( &str );
480 pNtDeleteKey( subkey );
481 pNtClose( subkey );
482
483 attr.RootDirectory = 0;
484 attr.Attributes = OBJ_CASE_INSENSITIVE;
485
486 pRtlCreateUnicodeStringFromAsciiz( &str, "" );
487 status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 );
488 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtCreateKey failed: 0x%08lx\n", status );
489 pRtlFreeUnicodeString( &str );
490
491 pRtlCreateUnicodeStringFromAsciiz( &str, "\\" );
492 status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 );
493 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtCreateKey failed: 0x%08lx\n", status );
494 pRtlFreeUnicodeString( &str );
495
496 pRtlCreateUnicodeStringFromAsciiz( &str, "\\Registry" );
497 status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 );
499 "NtCreateKey failed: 0x%08lx\n", status );
500 if (!status) pNtClose( subkey );
501 pRtlFreeUnicodeString( &str );
502
503 pRtlCreateUnicodeStringFromAsciiz( &str, "\\Registry\\" );
504 status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 );
506 "NtCreateKey failed: 0x%08lx\n", status );
507 if (!status) pNtClose( subkey );
508 pRtlFreeUnicodeString( &str );
509
510 pRtlCreateUnicodeStringFromAsciiz( &str, "\\Registry\\\\" );
511 status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 );
513 "NtCreateKey failed: 0x%08lx\n", status );
514 if (!status) pNtClose( subkey );
515 pRtlFreeUnicodeString( &str );
516
517 pRtlCreateUnicodeStringFromAsciiz( &str, "\\Foobar" );
518 status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 );
519 ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtCreateKey failed: 0x%08lx\n", status );
520 pRtlFreeUnicodeString( &str );
521
522 pRtlCreateUnicodeStringFromAsciiz( &str, "\\Foobar\\Machine" );
523 status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 );
524 ok( status == STATUS_OBJECT_PATH_NOT_FOUND, "NtCreateKey failed: 0x%08lx\n", status );
525 pRtlFreeUnicodeString( &str );
526
527 pRtlCreateUnicodeStringFromAsciiz( &str, "\\Machine\\Software\\Classes" );
528 status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 );
529 ok( status == STATUS_OBJECT_PATH_NOT_FOUND, "NtCreateKey failed: 0x%08lx\n", status );
530 pRtlFreeUnicodeString( &str );
531
532 pRtlCreateUnicodeStringFromAsciiz( &str, "Machine\\Software\\Classes" );
533 status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 );
534 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtCreateKey failed: 0x%08lx\n", status );
535 pRtlFreeUnicodeString( &str );
536
537 pRtlCreateUnicodeStringFromAsciiz( &str, "\\Device\\Null" );
538 status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 );
539 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtCreateKey failed: 0x%08lx\n", status );
540 pRtlFreeUnicodeString( &str );
541
542 pRtlCreateUnicodeStringFromAsciiz( &str, "\\Registry\\Machine\\Software\\Classes" );
543 status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 );
545 "NtCreateKey failed: 0x%08lx\n", status );
546 if (!status) pNtClose( subkey );
547 pRtlFreeUnicodeString( &str );
548
549 /* the REGISTRY part is case-sensitive unless OBJ_CASE_INSENSITIVE is specified */
550 am = GENERIC_READ;
551 attr.Attributes = 0;
552 pRtlCreateUnicodeStringFromAsciiz( &str, "\\Registry\\Machine\\Software\\Classes" );
553 status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 );
555 "NtCreateKey failed: 0x%08lx\n", status );
556 if (!status) pNtClose( subkey );
557 pRtlFreeUnicodeString( &str );
558
559 pRtlCreateUnicodeStringFromAsciiz( &str, "\\REGISTRY\\Machine\\Software\\Classes" );
560 status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 );
562 "NtCreateKey failed: 0x%08lx\n", status );
563 if (!status) pNtClose( subkey );
564 pRtlFreeUnicodeString( &str );
565
566 pRtlCreateUnicodeStringFromAsciiz( &str, "\\REGISTRY\\MACHINE\\SOFTWARE\\CLASSES" );
567 status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 );
569 "NtCreateKey failed: 0x%08lx\n", status );
570 if (!status) pNtClose( subkey );
571 pRtlFreeUnicodeString( &str );
572
573 pNtClose(key);
574}
575
576static void test_NtSetValueKey(void)
577{
578 HANDLE key;
582 UNICODE_STRING ValName;
583 DWORD data = 711;
584
586 status = pNtOpenKey(&key, am, &attr);
587 ok(status == STATUS_SUCCESS, "NtOpenKey Failed: 0x%08lx\n", status);
588
589 pRtlCreateUnicodeStringFromAsciiz(&ValName, "deletetest");
590 status = pNtSetValueKey(key, &ValName, 0, REG_DWORD, &data, sizeof(data));
591 ok(status == STATUS_SUCCESS, "NtSetValueKey Failed: 0x%08lx\n", status);
592 pRtlFreeUnicodeString(&ValName);
593
594 pRtlCreateUnicodeStringFromAsciiz(&ValName, "stringtest");
595 status = pNtSetValueKey(key, &ValName, 0, REG_SZ, (VOID*)stringW, STR_TRUNC_SIZE);
596 ok(status == STATUS_SUCCESS, "NtSetValueKey Failed: 0x%08lx\n", status);
597 pRtlFreeUnicodeString(&ValName);
598
599 pNtClose(key);
600}
601
602static void test_RtlOpenCurrentUser(void)
603{
606 status=pRtlOpenCurrentUser(KEY_READ, &handle);
607 ok(status == STATUS_SUCCESS, "RtlOpenCurrentUser Failed: 0x%08lx\n", status);
608 pNtClose(handle);
609}
610
612{
613 static WCHAR empty[] = {0};
615
616 status = pRtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, winetestpath.Buffer);
617 ok(status == STATUS_SUCCESS, "RtlCheckRegistryKey with RTL_REGISTRY_ABSOLUTE: 0x%08lx\n", status);
618
620 ok(status == STATUS_SUCCESS, "RtlCheckRegistryKey with RTL_REGISTRY_ABSOLUTE and RTL_REGISTRY_OPTIONAL: 0x%08lx\n", status);
621
622 status = pRtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, NULL);
623 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD, "RtlCheckRegistryKey with RTL_REGISTRY_ABSOLUTE and Path being NULL: 0x%08lx\n", status);
624
625 status = pRtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, empty);
626 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD, "RtlCheckRegistryKey with RTL_REGISTRY_ABSOLUTE and Path being empty: 0x%08lx\n", status);
627
628 status = pRtlCheckRegistryKey(RTL_REGISTRY_USER, NULL);
629 ok(status == STATUS_SUCCESS, "RtlCheckRegistryKey with RTL_REGISTRY_USER and Path being NULL: 0x%08lx\n", status);
630
631 status = pRtlCheckRegistryKey(RTL_REGISTRY_USER, empty);
632 ok(status == STATUS_SUCCESS, "RtlCheckRegistryKey with RTL_REGISTRY_USER and Path being empty: 0x%08lx\n", status);
633}
634
635static void test_NtFlushKey(void)
636{
638 HANDLE hkey;
641
642 status = pNtFlushKey(NULL);
643 ok(status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got: 0x%08lx\n", status);
644
646 pNtOpenKey(&hkey, am, &attr);
647
648 status = pNtFlushKey(hkey);
649 ok(status == STATUS_SUCCESS, "NtDeleteKey Failed: 0x%08lx\n", status);
650
651 pNtClose(hkey);
652}
653
654static void test_NtQueryValueKey(void)
655{
656 HANDLE key;
659 UNICODE_STRING ValName;
660 KEY_VALUE_BASIC_INFORMATION *basic_info;
661 KEY_VALUE_PARTIAL_INFORMATION *partial_info, pi;
665
666 pRtlCreateUnicodeStringFromAsciiz(&ValName, "deletetest");
667
669 status = pNtOpenKey(&key, KEY_READ|KEY_SET_VALUE, &attr);
670 ok(status == STATUS_SUCCESS, "NtOpenKey Failed: 0x%08lx\n", status);
671
673 basic_info = HeapAlloc(GetProcessHeap(), 0, sizeof(*basic_info));
674 status = pNtQueryValueKey(key, &ValName, KeyValueBasicInformation, basic_info, len, &len);
675 ok(status == STATUS_BUFFER_OVERFLOW, "NtQueryValueKey should have returned STATUS_BUFFER_OVERFLOW instead of 0x%08lx\n", status);
676 ok(basic_info->TitleIndex == 0, "NtQueryValueKey returned wrong TitleIndex %ld\n", basic_info->TitleIndex);
677 ok(basic_info->Type == REG_DWORD, "NtQueryValueKey returned wrong Type %ld\n", basic_info->Type);
678 ok(basic_info->NameLength == 20, "NtQueryValueKey returned wrong NameLength %ld\n", basic_info->NameLength);
679 ok(len == FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name[basic_info->NameLength/sizeof(WCHAR)]), "NtQueryValueKey returned wrong len %ld\n", len);
680
681 basic_info = HeapReAlloc(GetProcessHeap(), 0, basic_info, len);
682 status = pNtQueryValueKey(key, &ValName, KeyValueBasicInformation, basic_info, len, &len);
683 ok(status == STATUS_SUCCESS, "NtQueryValueKey should have returned STATUS_SUCCESS instead of 0x%08lx\n", status);
684 ok(basic_info->TitleIndex == 0, "NtQueryValueKey returned wrong TitleIndex %ld\n", basic_info->TitleIndex);
685 ok(basic_info->Type == REG_DWORD, "NtQueryValueKey returned wrong Type %ld\n", basic_info->Type);
686 ok(basic_info->NameLength == 20, "NtQueryValueKey returned wrong NameLength %ld\n", basic_info->NameLength);
687 ok(len == FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name[basic_info->NameLength/sizeof(WCHAR)]), "NtQueryValueKey returned wrong len %ld\n", len);
688 ok(!memcmp(basic_info->Name, ValName.Buffer, ValName.Length), "incorrect Name returned\n");
689 HeapFree(GetProcessHeap(), 0, basic_info);
690
692 partial_info = HeapAlloc(GetProcessHeap(), 0, sizeof(*partial_info));
693 status = pNtQueryValueKey(key, &ValName, KeyValuePartialInformation, partial_info, len, &len);
694 ok(status == STATUS_BUFFER_OVERFLOW, "NtQueryValueKey should have returned STATUS_BUFFER_OVERFLOW instead of 0x%08lx\n", status);
695 ok(partial_info->TitleIndex == 0, "NtQueryValueKey returned wrong TitleIndex %ld\n", partial_info->TitleIndex);
696 ok(partial_info->Type == REG_DWORD, "NtQueryValueKey returned wrong Type %ld\n", partial_info->Type);
697 ok(partial_info->DataLength == 4, "NtQueryValueKey returned wrong DataLength %ld\n", partial_info->DataLength);
698 ok(len == FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[partial_info->DataLength]), "NtQueryValueKey returned wrong len %ld\n", len);
699
700 partial_info = HeapReAlloc(GetProcessHeap(), 0, partial_info, len);
701 status = pNtQueryValueKey(key, &ValName, KeyValuePartialInformation, partial_info, len, &len);
702 ok(status == STATUS_SUCCESS, "NtQueryValueKey should have returned STATUS_SUCCESS instead of 0x%08lx\n", status);
703 ok(partial_info->TitleIndex == 0, "NtQueryValueKey returned wrong TitleIndex %ld\n", partial_info->TitleIndex);
704 ok(partial_info->Type == REG_DWORD, "NtQueryValueKey returned wrong Type %ld\n", partial_info->Type);
705 ok(partial_info->DataLength == 4, "NtQueryValueKey returned wrong DataLength %ld\n", partial_info->DataLength);
706 ok(len == FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[partial_info->DataLength]), "NtQueryValueKey returned wrong len %ld\n", len);
707 ok(*(DWORD *)partial_info->Data == 711, "incorrect Data returned: 0x%lx\n", *(DWORD *)partial_info->Data);
708 HeapFree(GetProcessHeap(), 0, partial_info);
709
711 aligned_info = HeapAlloc(GetProcessHeap(), 0, sizeof(*aligned_info) + 4);
712
713 aligned_info = (KEY_VALUE_PARTIAL_INFORMATION_ALIGN64 *)((char *)aligned_info + 4);
714 status = pNtQueryValueKey(key, &ValName, KeyValuePartialInformationAlign64, aligned_info, len, &len);
715 ok(status == STATUS_BUFFER_OVERFLOW, "NtQueryValueKey should have returned STATUS_BUFFER_OVERFLOW instead of 0x%08lx\n", status);
716 ok(aligned_info->Type == REG_DWORD, "NtQueryValueKey returned wrong Type %ld\n", aligned_info->Type);
717 ok(aligned_info->DataLength == 4, "NtQueryValueKey returned wrong DataLength %ld\n", aligned_info->DataLength);
718 ok(len == FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION_ALIGN64, Data[aligned_info->DataLength]), "NtQueryValueKey returned wrong len %ld\n", len);
719
721 aligned_info = (KEY_VALUE_PARTIAL_INFORMATION_ALIGN64 *)((char *)aligned_info - 4);
722 status = pNtQueryValueKey(key, &ValName, KeyValuePartialInformationAlign64, aligned_info, len, &len);
723 ok(status == STATUS_BUFFER_OVERFLOW, "NtQueryValueKey should have returned STATUS_BUFFER_OVERFLOW instead of 0x%08lx\n", status);
724 ok(aligned_info->Type == REG_DWORD, "NtQueryValueKey returned wrong Type %ld\n", aligned_info->Type);
725 ok(aligned_info->DataLength == 4, "NtQueryValueKey returned wrong DataLength %ld\n", aligned_info->DataLength);
726 ok(len == FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION_ALIGN64, Data[aligned_info->DataLength]), "NtQueryValueKey returned wrong len %ld\n", len);
727
728 aligned_info = HeapReAlloc(GetProcessHeap(), 0, aligned_info, len + 4);
729 aligned_info = (KEY_VALUE_PARTIAL_INFORMATION_ALIGN64 *)((char *)aligned_info + 4);
730 status = pNtQueryValueKey(key, &ValName, KeyValuePartialInformationAlign64, aligned_info, len, &len);
731 ok(status == STATUS_SUCCESS, "NtQueryValueKey should have returned STATUS_SUCCESS instead of 0x%08lx\n", status);
732 ok(aligned_info->Type == REG_DWORD, "NtQueryValueKey returned wrong Type %ld\n", aligned_info->Type);
733 ok(aligned_info->DataLength == 4, "NtQueryValueKey returned wrong DataLength %ld\n", aligned_info->DataLength);
734 ok(len == FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION_ALIGN64, Data[aligned_info->DataLength]), "NtQueryValueKey returned wrong len %ld\n", len);
735 ok(*(DWORD *)aligned_info->Data == 711, "incorrect Data returned: 0x%lx\n", *(DWORD *)aligned_info->Data);
736
737 aligned_info = (KEY_VALUE_PARTIAL_INFORMATION_ALIGN64 *)((char *)aligned_info - 4);
738 status = pNtQueryValueKey(key, &ValName, KeyValuePartialInformationAlign64, aligned_info, len, &len);
739 ok(status == STATUS_SUCCESS, "NtQueryValueKey should have returned STATUS_SUCCESS instead of 0x%08lx\n", status);
740 ok(aligned_info->Type == REG_DWORD, "NtQueryValueKey returned wrong Type %ld\n", aligned_info->Type);
741 ok(aligned_info->DataLength == 4, "NtQueryValueKey returned wrong DataLength %ld\n", aligned_info->DataLength);
742 ok(len == FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION_ALIGN64, Data[aligned_info->DataLength]), "NtQueryValueKey returned wrong len %ld\n", len);
743 ok(*(DWORD *)aligned_info->Data == 711, "incorrect Data returned: 0x%lx\n", *(DWORD *)aligned_info->Data);
744 HeapFree(GetProcessHeap(), 0, aligned_info);
745
747 full_info = HeapAlloc(GetProcessHeap(), 0, sizeof(*full_info));
748 status = pNtQueryValueKey(key, &ValName, KeyValueFullInformation, full_info, len, &len);
749 ok(status == STATUS_BUFFER_OVERFLOW, "NtQueryValueKey should have returned STATUS_BUFFER_OVERFLOW instead of 0x%08lx\n", status);
750 ok(full_info->TitleIndex == 0, "NtQueryValueKey returned wrong TitleIndex %ld\n", full_info->TitleIndex);
751 ok(full_info->Type == REG_DWORD, "NtQueryValueKey returned wrong Type %ld\n", full_info->Type);
752 ok(full_info->DataLength == 4, "NtQueryValueKey returned wrong DataLength %ld\n", full_info->DataLength);
753 ok(full_info->NameLength == 20, "NtQueryValueKey returned wrong NameLength %ld\n", full_info->NameLength);
754 ok(len == FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name[0]) + full_info->DataLength + full_info->NameLength,
755 "NtQueryValueKey returned wrong len %ld\n", len);
756 len = FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name[0]) + full_info->DataLength + full_info->NameLength;
757
758 full_info = HeapReAlloc(GetProcessHeap(), 0, full_info, len);
759 status = pNtQueryValueKey(key, &ValName, KeyValueFullInformation, full_info, len, &len);
760 ok(status == STATUS_SUCCESS, "NtQueryValueKey should have returned STATUS_SUCCESS instead of 0x%08lx\n", status);
761 ok(full_info->TitleIndex == 0, "NtQueryValueKey returned wrong TitleIndex %ld\n", full_info->TitleIndex);
762 ok(full_info->Type == REG_DWORD, "NtQueryValueKey returned wrong Type %ld\n", full_info->Type);
763 ok(full_info->DataLength == 4, "NtQueryValueKey returned wrong DataLength %ld\n", full_info->DataLength);
764 ok(full_info->NameLength == 20, "NtQueryValueKey returned wrong NameLength %ld\n", full_info->NameLength);
765 ok(!memcmp(full_info->Name, ValName.Buffer, ValName.Length), "incorrect Name returned\n");
766 ok(*(DWORD *)((char *)full_info + full_info->DataOffset) == 711, "incorrect Data returned: 0x%lx\n",
767 *(DWORD *)((char *)full_info + full_info->DataOffset));
768 HeapFree(GetProcessHeap(), 0, full_info);
769
770 pRtlFreeUnicodeString(&ValName);
771 pRtlCreateUnicodeStringFromAsciiz(&ValName, "stringtest");
772
773 status = pNtQueryValueKey(key, &ValName, KeyValuePartialInformation, NULL, 0, &len);
774 ok(status == STATUS_BUFFER_TOO_SMALL, "NtQueryValueKey should have returned STATUS_BUFFER_TOO_SMALL instead of 0x%08lx\n", status);
775 partial_info = HeapAlloc(GetProcessHeap(), 0, len+1);
776 memset(partial_info, 0xbd, len+1);
777 status = pNtQueryValueKey(key, &ValName, KeyValuePartialInformation, partial_info, len, &len);
778 ok(status == STATUS_SUCCESS, "NtQueryValueKey should have returned STATUS_SUCCESS instead of 0x%08lx\n", status);
779 ok(partial_info->TitleIndex == 0, "NtQueryValueKey returned wrong TitleIndex %ld\n", partial_info->TitleIndex);
780 ok(partial_info->Type == REG_SZ, "NtQueryValueKey returned wrong Type %ld\n", partial_info->Type);
781 ok(partial_info->DataLength == STR_TRUNC_SIZE, "NtQueryValueKey returned wrong DataLength %ld\n", partial_info->DataLength);
782 ok(!memcmp(partial_info->Data, stringW, STR_TRUNC_SIZE), "incorrect Data returned\n");
783 ok(*(partial_info->Data+STR_TRUNC_SIZE) == 0xbd, "string overflowed %02x\n", *(partial_info->Data+STR_TRUNC_SIZE));
784
785 expected = len;
786 status = pNtQueryValueKey(key, &ValName, KeyValuePartialInformation, partial_info, 0, &len);
787 ok(status == STATUS_BUFFER_TOO_SMALL, "NtQueryValueKey wrong status 0x%08lx\n", status);
788 ok(len == expected, "NtQueryValueKey wrong len %lu\n", len);
789 status = pNtQueryValueKey(key, &ValName, KeyValuePartialInformation, partial_info, 1, &len);
790 ok(status == STATUS_BUFFER_TOO_SMALL, "NtQueryValueKey wrong status 0x%08lx\n", status);
791 ok(len == expected, "NtQueryValueKey wrong len %lu\n", len);
792 status = pNtQueryValueKey(key, &ValName, KeyValuePartialInformation, partial_info, FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) - 1, &len);
793 ok(status == STATUS_BUFFER_TOO_SMALL, "NtQueryValueKey wrong status 0x%08lx\n", status);
794 ok(len == expected, "NtQueryValueKey wrong len %lu\n", len);
795 status = pNtQueryValueKey(key, &ValName, KeyValuePartialInformation, partial_info, FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data), &len);
796 ok(status == STATUS_BUFFER_OVERFLOW, "NtQueryValueKey wrong status 0x%08lx\n", status);
797 ok(len == expected, "NtQueryValueKey wrong len %lu\n", len);
798
799 HeapFree(GetProcessHeap(), 0, partial_info);
800 pRtlFreeUnicodeString(&ValName);
801
802 pRtlCreateUnicodeStringFromAsciiz(&ValName, "custtest");
803 status = pNtSetValueKey(key, &ValName, 0, 0xff00ff00, NULL, 0);
804 ok(status == STATUS_SUCCESS, "NtSetValueKey Failed: 0x%08lx\n", status);
805
806 status = pNtQueryValueKey(key, &ValName, KeyValuePartialInformation, &pi, sizeof(pi), &len);
807 ok(status == STATUS_SUCCESS, "NtQueryValueKey should have returned STATUS_SUCCESS instead of 0x%08lx\n", status);
808 ok(pi.Type == 0xff00ff00, "Type=%lx\n", pi.Type);
809 ok(pi.DataLength == 0, "DataLength=%lu\n", pi.DataLength);
810 pRtlFreeUnicodeString(&ValName);
811
812 pNtClose(key);
813}
814
815#ifdef __REACTOS__
816static void delete_subkeys_and_values(HKEY hkey)
817{
819 DWORD size;
820 char buffer[200];
823 while ((status = NtEnumerateKey(hkey, 0, KeyBasicInformation, keyInfo, sizeof(buffer), &size)) >= 0)
824 {
825 string = (UNICODE_STRING){ keyInfo->NameLength, keyInfo->NameLength, keyInfo->Name };
826 printf("got subkey %wZ\n", &string);
827 HANDLE hsubkey;
829 status = NtOpenKey(&hsubkey, KEY_ALL_ACCESS, &attr);
830 ok(status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status);
831 delete_subkeys_and_values(hsubkey);
832 status = pNtDeleteKey(hsubkey);
833 NtClose(hsubkey);
834 ok(status == STATUS_SUCCESS, "NtDeleteKey failed: 0x%08lx\n", status);
835 if (status != STATUS_SUCCESS) break;
836 }
837 ok(status == STATUS_NO_MORE_ENTRIES, "NtEnumerateKey unexpected status: 0x%08lx\n", status);
839 while ((status = NtEnumerateValueKey(hkey, 0, KeyValueBasicInformation, valInfo, sizeof(buffer), &size)) >= 0)
840 {
841 string = (UNICODE_STRING){ valInfo->NameLength, valInfo->NameLength, valInfo->Name };
842 printf("Deleting value %wZ\n", &string);
843 status = NtDeleteValueKey(hkey, &string);
844 ok(status == STATUS_SUCCESS, "NtDeleteValueKey failed: 0x%08lx\n", status);
845 if (status != STATUS_SUCCESS) break;
846 }
847 ok(status == STATUS_NO_MORE_ENTRIES, "NtEnumerateValueKey unexpected status: 0x%08lx\n", status);
848}
849#endif
850
851static void test_NtDeleteKey(void)
852{
854 char buffer[200];
856 HANDLE hkey, hkey2;
858 DWORD size;
859
860 status = pNtDeleteKey(NULL);
861 ok(status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got: 0x%08lx\n", status);
862
864 status = pNtOpenKey(&hkey, KEY_ALL_ACCESS, &attr);
865 ok(status == STATUS_SUCCESS, "NtOpenKey Failed: 0x%08lx\n", status);
866
867 status = pNtDeleteKey(hkey);
868#ifdef __REACTOS__
870 {
871 /* On older Windows versions the key cannot be deleted, if it still has keys/values in it */
872 ok(status == STATUS_CANNOT_DELETE, "NtDeleteKey unexpected status: 0x%08lx\n", status);
873 delete_subkeys_and_values(hkey); // RegDeleteTreeW is Vista+
874 status = pNtDeleteKey(hkey);
875 }
876#endif
877 ok(status == STATUS_SUCCESS, "NtDeleteKey Failed: 0x%08lx\n", status);
878
879 status = pNtQueryKey(hkey, KeyNameInformation, buffer, sizeof(buffer), &size);
880 ok(status == STATUS_KEY_DELETED, "got %#lx\n", status);
881
882 status = pNtEnumerateKey(hkey, 0, KeyFullInformation, buffer, sizeof(buffer), &size);
883 ok(status == STATUS_KEY_DELETED, "got %#lx\n", status);
884
885 pRtlInitUnicodeString(&string, L"value");
886 status = pNtQueryValueKey(hkey, &string, KeyValueBasicInformation, buffer, sizeof(buffer), &size);
887 ok(status == STATUS_KEY_DELETED, "got %#lx\n", status);
888
889 status = pNtEnumerateValueKey(hkey, 0, KeyValuePartialInformation, buffer, sizeof(buffer), &size);
890 ok(status == STATUS_KEY_DELETED, "got %#lx\n", status);
891
892 status = pNtSetValueKey(hkey, &string, 0, REG_SZ, "test", 5);
893 ok(status == STATUS_KEY_DELETED, "got %#lx\n", status);
894
895 status = pNtDeleteValueKey(hkey, &string);
896 ok(status == STATUS_KEY_DELETED, "got %#lx\n", status);
897
898 status = pNtDeleteKey(hkey);
899 ok(!status, "got %#lx\n", status);
900
901 RtlInitUnicodeString(&string, L"subkey");
903 status = pNtOpenKey(&hkey2, KEY_READ, &attr);
904 ok(status == STATUS_KEY_DELETED, "got %#lx\n", status);
905
906 status = pNtCreateKey(&hkey2, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL);
907 ok(status == STATUS_KEY_DELETED, "got %#lx\n", status);
908
909 status = pNtQueryObject(hkey, ObjectNameInformation, buffer, sizeof(buffer), &size);
910 ok(status == STATUS_KEY_DELETED, "got %#lx\n", status);
911
912 status = pNtQueryObject(hkey, ObjectBasicInformation, buffer, sizeof(OBJECT_BASIC_INFORMATION), &size);
913 ok(!status, "got %#lx\n", status);
914
915 status = pNtClose(hkey);
916 ok(status == STATUS_SUCCESS, "got %#lx\n", status);
917}
918
919static void test_NtQueryLicenseKey(void)
920{
921 static const WCHAR emptyW[] = {'E','M','P','T','Y',0};
923 WORD buffer[32];
925 ULONG type, len;
926 DWORD value;
927
928 if (!pNtQueryLicenseValue)
929 {
930 win_skip("NtQueryLicenseValue not found, skipping tests\n");
931 return;
932 }
933
934 type = 0xdead;
935 len = 0xbeef;
936 memset(&name, 0, sizeof(name));
937 status = pNtQueryLicenseValue(&name, &type, buffer, sizeof(buffer), &len);
938 ok(status == STATUS_INVALID_PARAMETER, "NtQueryLicenseValue returned %08lx, expected STATUS_INVALID_PARAMETER\n", status);
939 ok(type == 0xdead, "expected unmodified value for type, got %lu\n", type);
940 ok(len == 0xbeef, "expected unmodified value for len, got %lu\n", len);
941
942 /* test with empty key */
943 pRtlCreateUnicodeStringFromAsciiz(&name, "");
944
945 type = 0xdead;
946 len = 0xbeef;
947 status = pNtQueryLicenseValue(NULL, &type, buffer, sizeof(buffer), &len);
948 ok(status == STATUS_INVALID_PARAMETER, "NtQueryLicenseValue returned %08lx, expected STATUS_INVALID_PARAMETER\n", status);
949 ok(type == 0xdead, "expected unmodified value for type, got %lu\n", type);
950 ok(len == 0xbeef, "expected unmodified value for len, got %lu\n", len);
951
952 type = 0xdead;
953 status = pNtQueryLicenseValue(&name, &type, buffer, sizeof(buffer), NULL);
954 ok(status == STATUS_INVALID_PARAMETER, "NtQueryLicenseValue returned %08lx, expected STATUS_INVALID_PARAMETER\n", status);
955 ok(type == 0xdead, "expected unmodified value for type, got %lu\n", type);
956
957 len = 0xbeef;
958 status = pNtQueryLicenseValue(&name, NULL, buffer, sizeof(buffer), &len);
959 ok(status == STATUS_INVALID_PARAMETER, "NtQueryLicenseValue returned %08lx, expected STATUS_INVALID_PARAMETER\n", status);
960 ok(len == 0xbeef, "expected unmodified value for len, got %lu\n", len);
961
962 type = 0xdead;
963 len = 0xbeef;
964 status = pNtQueryLicenseValue(&name, &type, buffer, sizeof(buffer), &len);
965 ok(status == STATUS_INVALID_PARAMETER, "NtQueryLicenseValue returned %08lx, expected STATUS_INVALID_PARAMETER\n", status);
966 ok(type == 0xdead, "expected unmodified value for type, got %lu\n", type);
967 ok(len == 0xbeef, "expected unmodified value for len, got %lu\n", len);
968
969 pRtlFreeUnicodeString(&name);
970
971 /* test with nonexistent licence key */
972 pRtlCreateUnicodeStringFromAsciiz(&name, "Nonexistent-License-Value");
973
974 type = 0xdead;
975 len = 0xbeef;
976 status = pNtQueryLicenseValue(NULL, &type, buffer, sizeof(buffer), &len);
977 ok(status == STATUS_INVALID_PARAMETER, "NtQueryLicenseValue returned %08lx, expected STATUS_INVALID_PARAMETER\n", status);
978 ok(type == 0xdead, "expected unmodified value for type, got %lu\n", type);
979 ok(len == 0xbeef, "expected unmodified value for len, got %lu\n", len);
980
981 type = 0xdead;
982 status = pNtQueryLicenseValue(&name, &type, buffer, sizeof(buffer), NULL);
983 ok(status == STATUS_INVALID_PARAMETER, "NtQueryLicenseValue returned %08lx, expected STATUS_INVALID_PARAMETER\n", status);
984 ok(type == 0xdead, "expected unmodified value for type, got %lu\n", type);
985
986 len = 0xbeef;
987 status = pNtQueryLicenseValue(&name, NULL, buffer, sizeof(buffer), &len);
988 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "NtQueryLicenseValue returned %08lx, expected STATUS_OBJECT_NAME_NOT_FOUND\n", status);
989 ok(len == 0xbeef || broken(!len) /* Win10 1607 */, "expected unmodified value for len, got %lu\n", len);
990
991 type = 0xdead;
992 len = 0xbeef;
993 status = pNtQueryLicenseValue(&name, &type, buffer, sizeof(buffer), &len);
994 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "NtQueryLicenseValue unexpected succeeded\n");
995 ok(type == 0xdead, "expected unmodified value for type, got %lu\n", type);
996 ok(len == 0xbeef || broken(!len) /* Win10 1607 */, "expected unmodified value for len, got %lu\n", len);
997
998 pRtlFreeUnicodeString(&name);
999
1000 /* test with REG_SZ license key */
1001 pRtlCreateUnicodeStringFromAsciiz(&name, "Kernel-MUI-Language-Allowed");
1002
1003 type = 0xdead;
1004 len = 0xbeef;
1005 status = pNtQueryLicenseValue(NULL, &type, buffer, sizeof(buffer), &len);
1006 ok(status == STATUS_INVALID_PARAMETER, "NtQueryLicenseValue returned %08lx, expected STATUS_INVALID_PARAMETER\n", status);
1007 ok(type == 0xdead, "expected unmodified value for type, got %lu\n", type);
1008 ok(len == 0xbeef, "expected unmodified value for len, got %lu\n", len);
1009
1010 type = 0xdead;
1011 status = pNtQueryLicenseValue(&name, &type, buffer, sizeof(buffer), NULL);
1012 ok(status == STATUS_INVALID_PARAMETER, "NtQueryLicenseValue returned %08lx, expected STATUS_INVALID_PARAMETER\n", status);
1013 ok(type == 0xdead, "expected unmodified value for type, got %lu\n", type);
1014
1015 type = 0xdead;
1016 len = 0;
1017 status = pNtQueryLicenseValue(&name, &type, buffer, 0, &len);
1018 ok(status == STATUS_BUFFER_TOO_SMALL, "NtQueryLicenseValue returned %08lx, expected STATUS_BUFFER_TOO_SMALL\n", status);
1019 ok(type == REG_SZ, "expected type = REG_SZ, got %lu\n", type);
1020 ok(len == sizeof(emptyW), "expected len = %lu, got %lu\n", (DWORD)sizeof(emptyW), len);
1021
1022 len = 0;
1023 status = pNtQueryLicenseValue(&name, NULL, buffer, 0, &len);
1024 ok(status == STATUS_BUFFER_TOO_SMALL, "NtQueryLicenseValue returned %08lx, expected STATUS_BUFFER_TOO_SMALL\n", status);
1025 ok(len == sizeof(emptyW), "expected len = %lu, got %lu\n", (DWORD)sizeof(emptyW), len);
1026
1027 type = 0xdead;
1028 len = 0;
1029 memset(buffer, 0x11, sizeof(buffer));
1030 status = pNtQueryLicenseValue(&name, &type, buffer, sizeof(buffer), &len);
1031 ok(status == STATUS_SUCCESS, "NtQueryLicenseValue returned %08lx, expected STATUS_SUCCESS\n", status);
1032 ok(type == REG_SZ, "expected type = REG_SZ, got %lu\n", type);
1033 ok(len == sizeof(emptyW), "expected len = %lu, got %lu\n", (DWORD)sizeof(emptyW), len);
1034 ok(!memcmp(buffer, emptyW, sizeof(emptyW)), "unexpected buffer content\n");
1035
1036 type = 0xdead;
1037 len = 0;
1038 memset(buffer, 0x11, sizeof(buffer));
1039 status = pNtQueryLicenseValue(&name, &type, buffer, 2, &len);
1040 ok(status == STATUS_BUFFER_TOO_SMALL, "NtQueryLicenseValue returned %08lx, expected STATUS_BUFFER_TOO_SMALL\n", status);
1041 ok(type == REG_SZ, "expected type REG_SZ, got %lu\n", type);
1042 ok(len == sizeof(emptyW), "expected len = %lu, got %lu\n", (DWORD)sizeof(emptyW), len);
1043 ok(buffer[0] == 0x1111, "expected buffer[0] = 0x1111, got %u\n", buffer[0]);
1044
1045 pRtlFreeUnicodeString(&name);
1046
1047 /* test with REG_DWORD license key */
1048 pRtlCreateUnicodeStringFromAsciiz(&name, "Kernel-MUI-Number-Allowed");
1049
1050 type = 0xdead;
1051 len = 0xbeef;
1052 status = pNtQueryLicenseValue(NULL, &type, &value, sizeof(value), &len);
1053 ok(status == STATUS_INVALID_PARAMETER, "NtQueryLicenseValue returned %08lx, expected STATUS_INVALID_PARAMETER\n", status);
1054 ok(type == 0xdead, "expected unmodified value for type, got %lu\n", type);
1055 ok(len == 0xbeef, "expected unmodified value for len, got %lu\n", len);
1056
1057 type = 0xdead;
1058 status = pNtQueryLicenseValue(&name, &type, &value, sizeof(value), NULL);
1059 ok(status == STATUS_INVALID_PARAMETER, "NtQueryLicenseValue returned %08lx, expected STATUS_INVALID_PARAMETER\n", status);
1060 ok(type == 0xdead, "expected unmodified value for type, got %lu\n", type);
1061
1062 type = 0xdead;
1063 len = 0;
1064 status = pNtQueryLicenseValue(&name, &type, &value, 0, &len);
1065 ok(status == STATUS_BUFFER_TOO_SMALL, "NtQueryLicenseValue returned %08lx, expected STATUS_BUFFER_TOO_SMALL\n", status);
1066 ok(type == REG_DWORD, "expected type = REG_DWORD, got %lu\n", type);
1067 ok(len == sizeof(value), "expected len = %lu, got %lu\n", (DWORD)sizeof(value), len);
1068
1069 len = 0;
1070 status = pNtQueryLicenseValue(&name, NULL, &value, 0, &len);
1071 ok(status == STATUS_BUFFER_TOO_SMALL, "NtQueryLicenseValue returned %08lx, expected STATUS_BUFFER_TOO_SMALL\n", status);
1072 ok(len == sizeof(value), "expected len = %lu, got %lu\n", (DWORD)sizeof(value), len);
1073
1074 type = 0xdead;
1075 len = 0;
1076 value = 0xdeadbeef;
1077 status = pNtQueryLicenseValue(&name, &type, &value, sizeof(value), &len);
1078 ok(status == STATUS_SUCCESS, "NtQueryLicenseValue returned %08lx, expected STATUS_SUCCESS\n", status);
1079 ok(type == REG_DWORD, "expected type = REG_DWORD, got %lu\n", type);
1080 ok(len == sizeof(value), "expected len = %lu, got %lu\n", (DWORD)sizeof(value), len);
1081 ok(value != 0xdeadbeef, "expected value != 0xdeadbeef\n");
1082
1083 type = 0xdead;
1084 len = 0;
1085 status = pNtQueryLicenseValue(&name, &type, &value, 2, &len);
1086 ok(status == STATUS_BUFFER_TOO_SMALL, "NtQueryLicenseValue returned %08lx, expected STATUS_BUFFER_TOO_SMALL\n", status);
1087 ok(type == REG_DWORD, "expected type REG_DWORD, got %lu\n", type);
1088 ok(len == sizeof(value), "expected len = %lu, got %lu\n", (DWORD)sizeof(value), len);
1089
1090 pRtlFreeUnicodeString(&name);
1091}
1092
1094{
1096
1097 status = pRtlpNtQueryValueKey(NULL, NULL, NULL, NULL, NULL);
1098 ok(status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got: 0x%08lx\n", status);
1099}
1100
1101static void test_symlinks(void)
1102{
1103 static const WCHAR linkW[] = {'l','i','n','k',0};
1104 static const WCHAR valueW[] = {'v','a','l','u','e',0};
1105 static const WCHAR symlinkW[] = {'S','y','m','b','o','l','i','c','L','i','n','k','V','a','l','u','e',0};
1106 static const WCHAR targetW[] = {'\\','t','a','r','g','e','t',0};
1107 static UNICODE_STRING null_str;
1108 char buffer[1024];
1110 WCHAR *target;
1111 UNICODE_STRING symlink_str, link_str, target_str, value_str;
1112 HANDLE root, key, link;
1115 DWORD target_len, len, dw;
1116
1117 pRtlInitUnicodeString( &link_str, linkW );
1118 pRtlInitUnicodeString( &symlink_str, symlinkW );
1119 pRtlInitUnicodeString( &target_str, targetW + 1 );
1120 pRtlInitUnicodeString( &value_str, valueW );
1121
1122 target_len = winetestpath.Length + sizeof(targetW);
1123 target = pRtlAllocateHeap( GetProcessHeap(), 0, target_len + sizeof(targetW) /*for loop test*/ );
1125 memcpy( target + winetestpath.Length/sizeof(WCHAR), targetW, sizeof(targetW) );
1126
1127 attr.Length = sizeof(attr);
1128 attr.RootDirectory = 0;
1129 attr.Attributes = 0;
1130 attr.ObjectName = &winetestpath;
1131 attr.SecurityDescriptor = NULL;
1132 attr.SecurityQualityOfService = NULL;
1133
1134 status = pNtCreateKey( &root, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1135 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1136
1137 attr.RootDirectory = root;
1138 attr.ObjectName = &link_str;
1139 status = pNtCreateKey( &link, KEY_ALL_ACCESS, &attr, 0, 0, REG_OPTION_CREATE_LINK, 0 );
1140 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1141
1142 /* REG_SZ is not allowed */
1143 status = pNtSetValueKey( link, &symlink_str, 0, REG_SZ, target, target_len );
1144 ok( status == STATUS_ACCESS_DENIED, "NtSetValueKey wrong status 0x%08lx\n", status );
1145 status = pNtSetValueKey( link, &symlink_str, 0, REG_LINK, target, target_len - sizeof(WCHAR) );
1146 ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status );
1147 /* other values are not allowed */
1148 status = pNtSetValueKey( link, &link_str, 0, REG_LINK, target, target_len - sizeof(WCHAR) );
1149 ok( status == STATUS_ACCESS_DENIED, "NtSetValueKey wrong status 0x%08lx\n", status );
1150
1151 /* try opening the target through the link */
1152
1153 attr.ObjectName = &link_str;
1154 key = (HANDLE)0xdeadbeef;
1155 status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr );
1156 ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtOpenKey wrong status 0x%08lx\n", status );
1157 ok( !key, "key = %p\n", key );
1158
1159 attr.ObjectName = &target_str;
1160 status = pNtCreateKey( &key, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1161 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1162
1163 dw = 0xbeef;
1164 status = pNtSetValueKey( key, &value_str, 0, REG_DWORD, &dw, sizeof(dw) );
1165 ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status );
1166 pNtClose( key );
1167
1168 attr.ObjectName = &link_str;
1169 status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr );
1170 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
1171
1172 len = sizeof(buffer);
1173 status = pNtQueryValueKey( key, &value_str, KeyValuePartialInformation, info, len, &len );
1174 ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status );
1175 ok( len == FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION,Data) + sizeof(DWORD), "wrong len %lu\n", len );
1176
1177 status = pNtQueryValueKey( key, &symlink_str, KeyValuePartialInformation, info, len, &len );
1178 ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtQueryValueKey failed: 0x%08lx\n", status );
1179
1180 /* REG_LINK can be created in non-link keys */
1181 status = pNtSetValueKey( key, &symlink_str, 0, REG_LINK, target, target_len - sizeof(WCHAR) );
1182 ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status );
1183 len = sizeof(buffer);
1184 status = pNtQueryValueKey( key, &symlink_str, KeyValuePartialInformation, info, len, &len );
1185 ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status );
1186 ok( len == FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION,Data) + target_len - sizeof(WCHAR),
1187 "wrong len %lu\n", len );
1188 status = pNtDeleteValueKey( key, &symlink_str );
1189 ok( status == STATUS_SUCCESS, "NtDeleteValueKey failed: 0x%08lx\n", status );
1190
1191 pNtClose( key );
1192
1193 attr.Attributes = 0;
1194 status = pNtCreateKey( &key, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1195 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1196
1197 len = sizeof(buffer);
1198 status = pNtQueryValueKey( key, &value_str, KeyValuePartialInformation, info, len, &len );
1199 ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status );
1200 ok( len == FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION,Data) + sizeof(DWORD), "wrong len %lu\n", len );
1201
1202 status = pNtQueryValueKey( key, &symlink_str, KeyValuePartialInformation, info, len, &len );
1203 ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtQueryValueKey failed: 0x%08lx\n", status );
1204 pNtClose( key );
1205
1206 /* now open the symlink itself */
1207
1208 attr.RootDirectory = root;
1209 attr.Attributes = OBJ_OPENLINK;
1210 attr.ObjectName = &link_str;
1211 status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr );
1212 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
1213
1214 len = sizeof(buffer);
1215 status = pNtQueryValueKey( key, &symlink_str, KeyValuePartialInformation, info, len, &len );
1216 ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status );
1217 ok( len == FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION,Data) + target_len - sizeof(WCHAR),
1218 "wrong len %lu\n", len );
1219 pNtClose( key );
1220
1221 if (pNtOpenKeyEx)
1222 {
1223 /* REG_OPTION_OPEN_LINK flag doesn't matter */
1224 status = pNtOpenKeyEx( &key, KEY_ALL_ACCESS, &attr, REG_OPTION_OPEN_LINK );
1225 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
1226
1227 len = sizeof(buffer);
1228 status = pNtQueryValueKey( key, &symlink_str, KeyValuePartialInformation, info, len, &len );
1229 ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status );
1230 ok( len == FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION,Data) + target_len - sizeof(WCHAR),
1231 "wrong len %lu\n", len );
1232 pNtClose( key );
1233
1234 status = pNtOpenKeyEx( &key, KEY_ALL_ACCESS, &attr, 0 );
1235 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
1236
1237 len = sizeof(buffer);
1238 status = pNtQueryValueKey( key, &symlink_str, KeyValuePartialInformation, info, len, &len );
1239 ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status );
1240 ok( len == FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION,Data) + target_len - sizeof(WCHAR),
1241 "wrong len %lu\n", len );
1242 pNtClose( key );
1243
1244 attr.Attributes = 0;
1245 status = pNtOpenKeyEx( &key, KEY_ALL_ACCESS, &attr, REG_OPTION_OPEN_LINK );
1246 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
1247
1248 len = sizeof(buffer);
1249 status = pNtQueryValueKey( key, &symlink_str, KeyValuePartialInformation, info, len, &len );
1250 ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtQueryValueKey failed: 0x%08lx\n", status );
1251 pNtClose( key );
1252 }
1253
1254 attr.Attributes = OBJ_OPENLINK;
1255 status = pNtCreateKey( &key, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1256 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1257 len = sizeof(buffer);
1258 status = pNtQueryValueKey( key, &symlink_str, KeyValuePartialInformation, info, len, &len );
1259 ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status );
1260 ok( len == FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION,Data) + target_len - sizeof(WCHAR),
1261 "wrong len %lu\n", len );
1262 pNtClose( key );
1263
1264 /* delete target and create by NtCreateKey on link */
1265 attr.ObjectName = &target_str;
1266 status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr );
1267 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
1268 status = pNtDeleteKey( key );
1269 ok( status == STATUS_SUCCESS, "NtDeleteKey failed: 0x%08lx\n", status );
1270 pNtClose( key );
1271
1272 attr.ObjectName = &link_str;
1273 attr.Attributes = 0;
1274 status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr );
1275 ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtOpenKey wrong status 0x%08lx\n", status );
1276
1277 status = pNtCreateKey( &key, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1278 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1279 pNtClose( key );
1280
1281 attr.ObjectName = &target_str;
1282 attr.Attributes = OBJ_OPENLINK;
1283 status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr );
1284 ok( status == STATUS_SUCCESS, "NtOpenKey wrong status 0x%08lx\n", status );
1285
1286 if (0) /* crashes the Windows kernel on some Vista systems */
1287 {
1288 /* reopen the link from itself */
1289
1290 attr.RootDirectory = link;
1291 attr.Attributes = OBJ_OPENLINK;
1292 attr.ObjectName = &null_str;
1293 status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr );
1294 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
1295 len = sizeof(buffer);
1296 status = pNtQueryValueKey( key, &symlink_str, KeyValuePartialInformation, info, len, &len );
1297 ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status );
1298 ok( len == FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION,Data) + target_len - sizeof(WCHAR),
1299 "wrong len %lu\n", len );
1300 pNtClose( key );
1301
1302 status = pNtCreateKey( &key, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1303 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1304 len = sizeof(buffer);
1305 status = pNtQueryValueKey( key, &symlink_str, KeyValuePartialInformation, info, len, &len );
1306 ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status );
1307 ok( len == FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION,Data) + target_len - sizeof(WCHAR),
1308 "wrong len %lu\n", len );
1309 pNtClose( key );
1310 }
1311
1312 if (0) /* crashes the Windows kernel in most versions */
1313 {
1314 attr.RootDirectory = link;
1315 attr.Attributes = 0;
1316 attr.ObjectName = &null_str;
1317 status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr );
1318 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
1319 len = sizeof(buffer);
1320 status = pNtQueryValueKey( key, &symlink_str, KeyValuePartialInformation, info, len, &len );
1321 ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtQueryValueKey failed: 0x%08lx\n", status );
1322 pNtClose( key );
1323
1324 status = pNtCreateKey( &key, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1325 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1326 len = sizeof(buffer);
1327 status = pNtQueryValueKey( key, &symlink_str, KeyValuePartialInformation, info, len, &len );
1328 ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtQueryValueKey failed: 0x%08lx\n", status );
1329 pNtClose( key );
1330 }
1331
1332 /* target with terminating null doesn't work */
1333 status = pNtSetValueKey( link, &symlink_str, 0, REG_LINK, target, target_len );
1334 ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status );
1335 attr.RootDirectory = root;
1336 attr.Attributes = 0;
1337 attr.ObjectName = &link_str;
1338 status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr );
1339 ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtOpenKey wrong status 0x%08lx\n", status );
1340
1341 /* relative symlink, works only on win2k */
1342 status = pNtSetValueKey( link, &symlink_str, 0, REG_LINK, targetW+1, sizeof(targetW)-2*sizeof(WCHAR) );
1343 ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status );
1344 attr.ObjectName = &link_str;
1345 status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr );
1347 "NtOpenKey wrong status 0x%08lx\n", status );
1348
1349 key = (HKEY)0xdeadbeef;
1350 status = pNtCreateKey( &key, KEY_ALL_ACCESS, &attr, 0, 0, REG_OPTION_CREATE_LINK, NULL );
1351 ok( status == STATUS_OBJECT_NAME_COLLISION, "NtCreateKey failed: 0x%08lx\n", status );
1352 ok( !key, "key = %p\n", key );
1353
1354 status = pNtDeleteKey( link );
1355 ok( status == STATUS_SUCCESS, "NtDeleteKey failed: 0x%08lx\n", status );
1356 pNtClose( link );
1357
1358 attr.ObjectName = &target_str;
1359 status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr );
1360 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
1361 status = pNtDeleteKey( key );
1362 ok( status == STATUS_SUCCESS, "NtDeleteKey failed: 0x%08lx\n", status );
1363 pNtClose( key );
1364
1365 /* symlink loop */
1366
1367 status = pNtCreateKey( &link, KEY_ALL_ACCESS, &attr, 0, 0, REG_OPTION_CREATE_LINK, 0 );
1368 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1369 memcpy( target + target_len/sizeof(WCHAR) - 1, targetW, sizeof(targetW) );
1370 status = pNtSetValueKey( link, &symlink_str, 0, REG_LINK,
1371 target, target_len + sizeof(targetW) - sizeof(WCHAR) );
1372 ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status );
1373
1374 status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr );
1375 ok( status == STATUS_NAME_TOO_LONG || status == STATUS_INVALID_PARAMETER /* Win10 1607+ */,
1376 "NtOpenKey failed: 0x%08lx\n", status );
1377
1378 attr.Attributes = OBJ_OPENLINK;
1379 status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr );
1380 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
1381 pNtClose( key );
1382
1383 status = pNtDeleteKey( link );
1384 ok( status == STATUS_SUCCESS, "NtDeleteKey failed: 0x%08lx\n", status );
1385 pNtClose( link );
1386
1387 status = pNtDeleteKey( root );
1388 ok( status == STATUS_SUCCESS, "NtDeleteKey failed: 0x%08lx\n", status );
1389 pNtClose( root );
1390
1391 pRtlFreeHeap(GetProcessHeap(), 0, target);
1392}
1393
1394static WCHAR valueW[] = {'v','a','l','u','e'};
1395static UNICODE_STRING value_str = { sizeof(valueW), sizeof(valueW), valueW };
1396static const DWORD ptr_size = 8 * sizeof(void*);
1397
1399{
1400 char tmp[32];
1404 HANDLE key;
1406 DWORD dw, len = sizeof(tmp);
1407
1408 attr.Length = sizeof(attr);
1409 attr.RootDirectory = root;
1410 attr.Attributes = OBJ_CASE_INSENSITIVE;
1411 attr.ObjectName = &str;
1412 attr.SecurityDescriptor = NULL;
1413 attr.SecurityQualityOfService = NULL;
1414 pRtlCreateUnicodeStringFromAsciiz( &str, name );
1415
1416 status = pNtOpenKey( &key, flags | KEY_ALL_ACCESS, &attr );
1417 if (status == STATUS_OBJECT_NAME_NOT_FOUND) return 0;
1418 ok( status == STATUS_SUCCESS, "%08lx: NtCreateKey failed: 0x%08lx\n", flags, status );
1419
1420 status = pNtQueryValueKey( key, &value_str, KeyValuePartialInformation, info, len, &len );
1422 dw = 0;
1423 else
1424 {
1425 ok( status == STATUS_SUCCESS, "%08lx: NtQueryValueKey failed: 0x%08lx\n", flags, status );
1426 dw = *(DWORD *)info->Data;
1427 }
1428 pNtClose( key );
1429 pRtlFreeUnicodeString( &str );
1430 return dw;
1431}
1432
1433static void _check_key_value( int line, HANDLE root, const char *name, DWORD flags, DWORD expect )
1434{
1436 ok_(__FILE__,line)( dw == expect, "%08lx: wrong value %lu/%lu\n", flags, dw, expect );
1437}
1438#define check_key_value(root,name,flags,expect) _check_key_value( __LINE__, root, name, flags, expect )
1439
1440static void _check_enum_value( int line, const WCHAR *name, DWORD flags, int subkeys, BOOL present)
1441{
1442 static const WCHAR wineW[] = {'W','i','n','e'};
1443 char buffer[1024];
1449 BOOL found;
1450 HANDLE key;
1451 DWORD len;
1452 int i;
1453
1454 attr.Length = sizeof(attr);
1455 attr.RootDirectory = 0;
1456 attr.Attributes = OBJ_CASE_INSENSITIVE;
1457 attr.ObjectName = &str;
1458 attr.SecurityDescriptor = NULL;
1459 attr.SecurityQualityOfService = NULL;
1460
1461 pRtlInitUnicodeString( &str, name );
1462 status = pNtOpenKey( &key, flags, &attr );
1463 ok_( __FILE__, line )( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
1464#ifdef __REACTOS__
1465 if (status != STATUS_SUCCESS)
1466 return;
1467#endif
1468
1469 status = pNtQueryKey( key, KeyFullInformation, full_info, sizeof(buffer), &len );
1470 ok_( __FILE__, line )( status == STATUS_SUCCESS, "NtQueryKey failed: 0x%08lx\n", status );
1471 ok_( __FILE__, line )( full_info->SubKeys == subkeys, "wrong number of subkeys: %lu\n", full_info->SubKeys );
1472 subkeys = full_info->SubKeys;
1473
1474 found = FALSE;
1475 for (i = 0; i < subkeys; i++)
1476 {
1477 status = pNtEnumerateKey( key, i, KeyBasicInformation, basic_info, sizeof(buffer), &len );
1478 ok_( __FILE__, line )( status == STATUS_SUCCESS, "NtEnumerateKey failed: 0x%08lx\n", status );
1479
1480 if (basic_info->NameLength == sizeof(wineW) && !memcmp(basic_info->Name, wineW, sizeof(wineW) ))
1481 found = TRUE;
1482 }
1483 ok_( __FILE__, line )( found == present, "found equals %d\n", found );
1484 pNtClose( key );
1485
1486 status = pNtCreateKey( &key, flags, &attr, 0, 0, 0, 0 );
1487 ok_( __FILE__, line )( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1488
1489 status = pNtQueryKey( key, KeyFullInformation, full_info, sizeof(buffer), &len );
1490 ok_( __FILE__, line )( status == STATUS_SUCCESS, "NtQueryKey failed: 0x%08lx\n", status );
1491 ok_( __FILE__, line )( full_info->SubKeys == subkeys, "wrong number of subkeys: %lu\n", full_info->SubKeys );
1492 subkeys = full_info->SubKeys;
1493
1494 found = FALSE;
1495 for (i = 0; i < subkeys; i++)
1496 {
1497 status = pNtEnumerateKey( key, i, KeyBasicInformation, basic_info, sizeof(buffer), &len );
1498 ok_( __FILE__, line )( status == STATUS_SUCCESS, "NtEnumerateKey failed: 0x%08lx\n", status );
1499
1500 if (basic_info->NameLength == sizeof(wineW) && !memcmp(basic_info->Name, wineW, sizeof(wineW) ))
1501 found = TRUE;
1502 }
1503 ok_( __FILE__, line )( found == present, "found equals %d\n", found );
1504 pNtClose( key );
1505}
1506#define check_enum_value(name, flags, subkeys, present) _check_enum_value( __LINE__, name, flags, subkeys, present )
1507
1508static void test_redirection(void)
1509{
1513 char buffer[1024];
1516 DWORD dw, len;
1517 HANDLE key, key32, key64, root, root32, root64;
1518 int subkeys64, subkeys32;
1519
1520 if (ptr_size != 64)
1521 {
1524 &is_wow64, sizeof(is_wow64), &len ) ||
1525 !is_wow64)
1526 {
1527 trace( "Not on Wow64, no redirection\n" );
1528 return;
1529 }
1530 }
1531
1532 attr.Length = sizeof(attr);
1533 attr.RootDirectory = 0;
1534 attr.Attributes = OBJ_CASE_INSENSITIVE;
1535 attr.ObjectName = &str;
1536 attr.SecurityDescriptor = NULL;
1537 attr.SecurityQualityOfService = NULL;
1538
1539 pRtlInitUnicodeString( &str, L"\\Registry\\Machine\\Software\\Wine" );
1540 status = pNtCreateKey( &root64, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1542 {
1543 skip("Not authorized to modify KEY_WOW64_64KEY, no redirection\n");
1544 return;
1545 }
1546 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1547
1548 pRtlInitUnicodeString( &str, L"\\Registry\\Machine\\Software\\Wow6432Node\\Wine" );
1549 status = pNtCreateKey( &root32, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1550 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1551
1552 pRtlInitUnicodeString( &str, L"\\Registry\\Machine\\Software\\Wine\\Winetest" );
1553 status = pNtCreateKey( &key64, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1554 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1555
1556 pRtlInitUnicodeString( &str, L"\\Registry\\Machine\\Software\\Wow6432Node\\Wine\\Winetest" );
1557 status = pNtCreateKey( &key32, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1558 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1559
1560 dw = 64;
1561 status = pNtSetValueKey( key64, &value_str, 0, REG_DWORD, &dw, sizeof(dw) );
1562 ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status );
1563
1564 dw = 32;
1565 status = pNtSetValueKey( key32, &value_str, 0, REG_DWORD, &dw, sizeof(dw) );
1566 ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status );
1567
1568 len = sizeof(buffer);
1569 status = pNtQueryValueKey( key32, &value_str, KeyValuePartialInformation, info, len, &len );
1570 ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status );
1571 dw = *(DWORD *)info->Data;
1572 ok( dw == 32, "wrong value %lu\n", dw );
1573
1574 len = sizeof(buffer);
1575 status = pNtQueryValueKey( key64, &value_str, KeyValuePartialInformation, info, len, &len );
1576 ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08lx\n", status );
1577 dw = *(DWORD *)info->Data;
1578 ok( dw == 64, "wrong value %lu\n", dw );
1579
1580 pRtlInitUnicodeString( &str, L"\\Registry\\Machine\\Software" );
1581 status = pNtCreateKey( &key, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1582 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1583
1584 check_key_value( key, "Wine\\Winetest", 0, ptr_size );
1585 check_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY, ptr_size );
1586 check_key_value( key, "Wine\\Winetest", KEY_WOW64_32KEY, ptr_size );
1587 check_key_value( key, "Wow6432Node\\Wine\\Winetest", 0, ptr_size == 32 ? 0 : 32 );
1588 check_key_value( key, "Wow6432Node\\Wine\\Winetest", KEY_WOW64_64KEY, ptr_size == 32 ? 0 : 32 );
1589 check_key_value( key, "Wow6432Node\\Wine\\Winetest", KEY_WOW64_32KEY, ptr_size == 32 ? 0 : 32 );
1590 pNtClose( key );
1591
1592 status = pNtCreateKey( &key, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1593 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1594 dw = get_key_value( key, "Wine\\Winetest", 0 );
1595 ok( dw == 64 || broken(dw == 32) /* win7 */, "wrong value %lu\n", dw );
1596 check_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY, 64 );
1597 check_key_value( key, "Wine\\Winetest", KEY_WOW64_32KEY, ptr_size );
1598 check_key_value( key, "Wow6432Node\\Wine\\Winetest", 0, 32 );
1599 check_key_value( key, "Wow6432Node\\Wine\\Winetest", KEY_WOW64_64KEY, 32 );
1600 check_key_value( key, "Wow6432Node\\Wine\\Winetest", KEY_WOW64_32KEY, 32 );
1601 pNtClose( key );
1602
1603 status = pNtCreateKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1604 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1605 check_key_value( key, "Wine\\Winetest", 0, ptr_size );
1606 check_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY, ptr_size );
1607 check_key_value( key, "Wine\\Winetest", KEY_WOW64_32KEY, ptr_size );
1608 check_key_value( key, "Wow6432Node\\Wine\\Winetest", 0, ptr_size == 32 ? 0 : 32 );
1609 check_key_value( key, "Wow6432Node\\Wine\\Winetest", KEY_WOW64_64KEY, ptr_size == 32 ? 0 : 32 );
1610 check_key_value( key, "Wow6432Node\\Wine\\Winetest", KEY_WOW64_32KEY, ptr_size == 32 ? 0 : 32 );
1611 pNtClose( key );
1612
1613 check_key_value( 0, "\\Registry\\Machine\\Software\\Wine\\Winetest", 0, ptr_size );
1614 check_key_value( 0, "\\Registry\\Machine\\Software\\Wow6432Node\\Wine\\Winetest", 0, 32 );
1615 check_key_value( 0, "\\Registry\\Machine\\Software\\Wine\\Winetest", KEY_WOW64_64KEY, 64 );
1616 check_key_value( 0, "\\Registry\\Machine\\Software\\Wine\\Winetest", KEY_WOW64_32KEY, ptr_size );
1617 check_key_value( 0, "\\Registry\\Machine\\Software\\Wow6432Node\\Wine\\Winetest", KEY_WOW64_64KEY, 32 );
1618 check_key_value( 0, "\\Registry\\Machine\\Software\\Wow6432Node\\Wine\\Winetest", KEY_WOW64_32KEY, 32 );
1619
1620 pRtlInitUnicodeString( &str, L"\\Registry\\Machine\\Software\\Wow6432Node" );
1621 status = pNtCreateKey( &key, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1622 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1623 check_key_value( key, "Wine\\Winetest", 0, 32 );
1624 check_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY, 32 );
1625 check_key_value( key, "Wine\\Winetest", KEY_WOW64_32KEY, 32 );
1626 pNtClose( key );
1627
1628 status = pNtCreateKey( &key, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1629 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1630 check_key_value( key, "Wine\\Winetest", 0, 32 );
1631 check_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY, 32 );
1632 check_key_value( key, "Wine\\Winetest", KEY_WOW64_32KEY, 32 );
1633 pNtClose( key );
1634
1635 status = pNtCreateKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1636 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1637 check_key_value( key, "Wine\\Winetest", 0, 32 );
1638 check_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY, 32 );
1639 check_key_value( key, "Wine\\Winetest", KEY_WOW64_32KEY, 32 );
1640 pNtClose( key );
1641
1642 pRtlInitUnicodeString( &str, L"\\Registry\\Machine\\Software\\Wow6432Node\\Wine" );
1643 status = pNtCreateKey( &key, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1644 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1645 check_key_value( key, "Winetest", 0, 32 );
1646 check_key_value( key, "Winetest", KEY_WOW64_64KEY, 32 );
1647 check_key_value( key, "Winetest", KEY_WOW64_32KEY, 32 );
1648 pNtClose( key );
1649
1650 status = pNtCreateKey( &key, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1651 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1652 check_key_value( key, "Winetest", 0, 32 );
1653 check_key_value( key, "Winetest", KEY_WOW64_64KEY, 32 );
1654 check_key_value( key, "Winetest", KEY_WOW64_32KEY, 32 );
1655 pNtClose( key );
1656
1657 status = pNtCreateKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1658 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1659 check_key_value( key, "Winetest", 0, 32 );
1660 check_key_value( key, "Winetest", KEY_WOW64_64KEY, 32 );
1661 check_key_value( key, "Winetest", KEY_WOW64_32KEY, 32 );
1662 pNtClose( key );
1663
1664 pRtlInitUnicodeString( &str, L"\\Registry\\Machine\\Software\\Wine" );
1665 status = pNtCreateKey( &key, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1666 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1667 check_key_value( key, "Winetest", 0, ptr_size );
1670 pNtClose( key );
1671
1672 status = pNtCreateKey( &key, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1673 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1674 check_key_value( key, "Winetest", 0, 64 );
1675 check_key_value( key, "Winetest", KEY_WOW64_64KEY, 64 );
1677 pNtClose( key );
1678
1679 status = pNtCreateKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1680 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1681 check_key_value( key, "Winetest", 0, ptr_size );
1684 pNtClose( key );
1685
1686 status = pNtDeleteKey( key32 );
1687 ok( status == STATUS_SUCCESS, "NtDeleteKey failed: 0x%08lx\n", status );
1688 pNtClose( key32 );
1689
1690 status = pNtDeleteKey( key64 );
1691 ok( status == STATUS_SUCCESS, "NtDeleteKey failed: 0x%08lx\n", status );
1692 pNtClose( key64 );
1693
1694 pRtlInitUnicodeString( &str, L"Winetest" );
1695 attr.RootDirectory = root64;
1696 status = pNtCreateKey( &key32, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1697 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1698
1699 pRtlInitUnicodeString( &str, L"\\Registry\\Machine\\Software\\Wow6432Node\\Wine\\Winetest" );
1700 attr.RootDirectory = 0;
1701 status = pNtOpenKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr );
1703 "NtOpenKey failed: 0x%08lx\n", status );
1704 pNtClose( key );
1705
1706 status = pNtDeleteKey( key32 );
1707 ok( status == STATUS_SUCCESS, "NtDeleteKey failed: 0x%08lx\n", status );
1708 pNtClose( key32 );
1709
1710 pNtDeleteKey( root32 );
1711 pNtClose( root32 );
1712 pNtDeleteKey( root64 );
1713 pNtClose( root64 );
1714
1715 /* Software\Classes is shared/reflected so behavior is different */
1716
1717 pRtlInitUnicodeString( &str, L"\\Registry\\Machine\\Software\\Classes\\Wine" );
1718 status = pNtCreateKey( &key64, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1720 {
1721 skip("Not authorized to modify the Classes key\n");
1722 return;
1723 }
1724 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1725
1726 pRtlInitUnicodeString( &str, L"\\Registry\\Machine\\Software\\Classes\\Wow6432Node\\Wine" );
1727 status = pNtOpenKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr );
1729 "NtOpenKey failed: 0x%08lx\n", status );
1730 if (!status) pNtClose( key );
1731
1732 status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr );
1734 "NtOpenKey failed: 0x%08lx\n", status );
1735 if (!status) pNtClose( key );
1736
1737 status = pNtCreateKey( &key32, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1738 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1739
1740 dw = 32;
1741 status = pNtSetValueKey( key32, &value_str, 0, REG_DWORD, &dw, sizeof(dw) );
1742 ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status );
1743
1744 dw = 64;
1745 status = pNtSetValueKey( key64, &value_str, 0, REG_DWORD, &dw, sizeof(dw) );
1746 ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status );
1747
1748 check_key_value( 0, "\\Registry\\Machine\\Software\\Classes\\Wine", 0, 64 );
1749 check_key_value( 0, "\\Registry\\Machine\\Software\\Classes\\Wine", KEY_WOW64_64KEY, 64 );
1750 check_key_value( 0, "\\Registry\\Machine\\Software\\Classes\\Wine", KEY_WOW64_32KEY, 64 );
1751 check_key_value( 0, "\\Registry\\Machine\\Software\\Classes\\Wow6432Node\\Wine", 0, ptr_size == 64 ? 32 : 64 );
1752 check_key_value( 0, "\\Registry\\Machine\\Software\\Classes\\Wow6432Node\\Wine", KEY_WOW64_64KEY, ptr_size == 64 ? 32 : 0 );
1753 check_key_value( 0, "\\Registry\\Machine\\Software\\Classes\\Wow6432Node\\Wine", KEY_WOW64_32KEY, ptr_size == 64 ? 32 : 64 );
1754
1755 pNtDeleteKey( key32 );
1756 pNtClose( key32 );
1757
1758 check_key_value( 0, "\\Registry\\Machine\\Software\\Classes\\Wine", 0, ptr_size == 32 ? 0 : 64 );
1759 check_key_value( 0, "\\Registry\\Machine\\Software\\Classes\\Wine", KEY_WOW64_64KEY, ptr_size == 32 ? 0 : 64 );
1760 check_key_value( 0, "\\Registry\\Machine\\Software\\Classes\\Wine", KEY_WOW64_32KEY, ptr_size == 32 ? 0 : 64 );
1761 check_key_value( 0, "\\Registry\\Machine\\Software\\Classes\\Wow6432Node\\Wine", 0, 0 );
1762 check_key_value( 0, "\\Registry\\Machine\\Software\\Classes\\Wow6432Node\\Wine", KEY_WOW64_64KEY, 0 );
1763 check_key_value( 0, "\\Registry\\Machine\\Software\\Classes\\Wow6432Node\\Wine", KEY_WOW64_32KEY, 0 );
1764
1765 pNtDeleteKey( key64 );
1766 pNtClose( key64 );
1767
1768 pRtlInitUnicodeString( &str, L"\\Registry\\Machine\\Software\\Classes" );
1769 status = pNtOpenKey( &root64, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr );
1770 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
1771
1772 status = pNtOpenKey( &root32, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr );
1773 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
1774
1775 pRtlInitUnicodeString( &str, L"Wine" );
1776 attr.RootDirectory = root64;
1777 status = pNtCreateKey( &key64, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1778 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1779
1780 attr.RootDirectory = key64;
1781 status = pNtCreateKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1782 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1783 pNtDeleteKey( key );
1784 pNtClose( key );
1785
1786 attr.RootDirectory = root32;
1787 status = pNtOpenKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr );
1788 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
1789 pNtClose( key );
1790
1791 status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr );
1792 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
1793 pNtClose( key );
1794
1795 status = pNtCreateKey( &key32, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1796 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1797
1798 dw = 32;
1799 status = pNtSetValueKey( key32, &value_str, 0, REG_DWORD, &dw, sizeof(dw) );
1800 ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status );
1801
1802 dw = 64;
1803 status = pNtSetValueKey( key64, &value_str, 0, REG_DWORD, &dw, sizeof(dw) );
1804 ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status );
1805
1806 check_key_value( root64, "Wine", 0, 64 );
1807 check_key_value( root64, "Wine", KEY_WOW64_64KEY, 64 );
1808 check_key_value( root64, "Wine", KEY_WOW64_32KEY, 64 );
1809 check_key_value( root32, "Wine", 0, 64 );
1810 check_key_value( root32, "Wine", KEY_WOW64_64KEY, 64 );
1811 check_key_value( root32, "Wine", KEY_WOW64_32KEY, 64 );
1812
1813 pNtDeleteKey( key32 );
1814 pNtClose( key32 );
1815
1816 check_key_value( root64, "Wine", 0, 0 );
1817 check_key_value( root64, "Wine", KEY_WOW64_64KEY, 0 );
1818 check_key_value( root64, "Wine", KEY_WOW64_32KEY, 0 );
1819 check_key_value( root32, "Wine", 0, 0 );
1820 check_key_value( root32, "Wine", KEY_WOW64_64KEY, 0 );
1821 check_key_value( root32, "Wine", KEY_WOW64_32KEY, 0 );
1822
1823 pNtDeleteKey( key64 );
1824 pNtClose( key64 );
1825
1826 attr.RootDirectory = root32;
1827 status = pNtCreateKey( &key32, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1828 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1829
1830 dw = 32;
1831 status = pNtSetValueKey( key32, &value_str, 0, REG_DWORD, &dw, sizeof(dw) );
1832 ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status );
1833
1834 check_key_value( root64, "Wine", 0, 32 );
1835 check_key_value( root64, "Wine", KEY_WOW64_64KEY, 32 );
1836 check_key_value( root64, "Wine", KEY_WOW64_32KEY, 32 );
1837 check_key_value( root32, "Wine", 0, 32 );
1838 check_key_value( root32, "Wine", KEY_WOW64_64KEY, 32 );
1839 check_key_value( root32, "Wine", KEY_WOW64_32KEY, 32 );
1840
1841 pNtDeleteKey( key32 );
1842 pNtClose( key32 );
1843
1844 pNtClose( root64 );
1845 pNtClose( root32 );
1846
1847 pRtlInitUnicodeString( &str, L"\\Registry\\Machine\\Software\\Classes" );
1848 attr.RootDirectory = 0;
1849 status = pNtOpenKey( &root64, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr );
1850 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
1851
1852 status = pNtOpenKey( &root32, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr );
1853 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
1854
1855 status = pNtOpenKey( &root, KEY_ALL_ACCESS, &attr );
1856 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
1857
1858 pRtlInitUnicodeString( &str, L"Interface" );
1859 attr.RootDirectory = root64;
1860 status = pNtOpenKey( &key64, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr );
1861 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
1862
1863 attr.RootDirectory = root32;
1864 status = pNtOpenKey( &key32, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr );
1865 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
1866
1867 attr.RootDirectory = root;
1868 status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr );
1869 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
1870
1871 pNtClose( root64 );
1872 pNtClose( root32 );
1873 pNtClose( root );
1874
1875 root64 = key64;
1876 root32 = key32;
1877 root = key;
1878
1879 pRtlInitUnicodeString( &str, L"Wine" );
1880 attr.RootDirectory = root32;
1881 status = pNtCreateKey( &key32, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1882 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1883
1884 attr.RootDirectory = root;
1885 status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr );
1886 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
1887 pNtClose( key );
1888
1889 pNtDeleteKey( key32 );
1890 pNtClose( key32 );
1891
1892 attr.RootDirectory = root64;
1893 status = pNtCreateKey( &key64, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1894 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1895
1896 attr.RootDirectory = root;
1897 status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr );
1899 "NtOpenKey failed: 0x%08lx\n", status );
1900 if (!status) pNtClose( key );
1901
1902 pNtDeleteKey( key64 );
1903 pNtClose( key64 );
1904
1905 pNtDeleteKey( root );
1906 pNtClose( root );
1907
1908 attr.RootDirectory = root64;
1909 status = pNtCreateKey( &key64, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1910 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1911
1912 attr.RootDirectory = root32;
1913 status = pNtOpenKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr );
1915 "NtOpenKey failed: 0x%08lx\n", status );
1916 if (!status) pNtClose( key );
1917
1918 status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr );
1920 "NtOpenKey failed: 0x%08lx\n", status );
1921 if (!status) pNtClose( key );
1922
1923 status = pNtCreateKey( &key32, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1924 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1925
1926 dw = 32;
1927 status = pNtSetValueKey( key32, &value_str, 0, REG_DWORD, &dw, sizeof(dw) );
1928 ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status );
1929
1930 dw = 64;
1931 status = pNtSetValueKey( key64, &value_str, 0, REG_DWORD, &dw, sizeof(dw) );
1932 ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status );
1933
1934 check_key_value( root64, "Wine", 0, 64 );
1935 check_key_value( root64, "Wine", KEY_WOW64_64KEY, 64 );
1936 check_key_value( root64, "Wine", KEY_WOW64_32KEY, ptr_size );
1937 check_key_value( root32, "Wine", 0, ptr_size );
1938 check_key_value( root32, "Wine", KEY_WOW64_64KEY, ptr_size );
1939 check_key_value( root32, "Wine", KEY_WOW64_32KEY, ptr_size );
1940
1941 pRtlInitUnicodeString( &str, L"\\Registry\\Machine\\Software\\Classes\\Interface" );
1942 attr.RootDirectory = 0;
1943 status = pNtOpenKey( &key, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr );
1944 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
1945 check_key_value( key, "Wine", 0, 64 );
1946 check_key_value( key, "Wine", KEY_WOW64_64KEY, 64 );
1948 pNtClose( key );
1949
1950 status = pNtOpenKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr );
1951 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
1952 check_key_value( key, "Wine", 0, ptr_size );
1955 pNtClose( key );
1956
1957 check_key_value( 0, "\\Registry\\Machine\\Software\\Classes\\Interface\\Wine", 0, ptr_size );
1958 check_key_value( 0, "\\Registry\\Machine\\Software\\Classes\\Interface\\Wine", KEY_WOW64_64KEY, 64 );
1959 check_key_value( 0, "\\Registry\\Machine\\Software\\Classes\\Interface\\Wine", KEY_WOW64_32KEY, ptr_size );
1960
1961 pNtDeleteKey( key32 );
1962 pNtClose( key32 );
1963
1964 check_key_value( root64, "Wine", 0, ptr_size == 64 ? 0 : 64 );
1965 check_key_value( root64, "Wine", KEY_WOW64_64KEY, ptr_size == 64 ? 0 : 64 );
1966 check_key_value( root64, "Wine", KEY_WOW64_32KEY, 0 );
1967 check_key_value( root32, "Wine", 0, 0 );
1968 check_key_value( root32, "Wine", KEY_WOW64_64KEY, 0 );
1969 check_key_value( root32, "Wine", KEY_WOW64_32KEY, 0 );
1970
1971 check_key_value( 0, "\\Registry\\Machine\\Software\\Classes\\Interface\\Wine", 0, 0 );
1972 check_key_value( 0, "\\Registry\\Machine\\Software\\Classes\\Interface\\Wine", KEY_WOW64_64KEY, ptr_size == 64 ? 0 : 64 );
1973 check_key_value( 0, "\\Registry\\Machine\\Software\\Classes\\Interface\\Wine", KEY_WOW64_32KEY, 0 );
1974
1975 pNtDeleteKey( key64 );
1976 pNtClose( key64 );
1977
1978 pRtlInitUnicodeString( &str, L"Wine" );
1979 attr.RootDirectory = root32;
1980 status = pNtCreateKey( &key32, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1981 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
1982
1983 dw = 32;
1984 status = pNtSetValueKey( key32, &value_str, 0, REG_DWORD, &dw, sizeof(dw) );
1985 ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status );
1986
1987 check_key_value( root64, "Wine", 0, ptr_size == 64 ? 32 : 0 );
1988 check_key_value( root64, "Wine", KEY_WOW64_64KEY, ptr_size == 64 ? 32 : 0 );
1989 check_key_value( root64, "Wine", KEY_WOW64_32KEY, 32 );
1990 check_key_value( root32, "Wine", 0, 32 );
1991 check_key_value( root32, "Wine", KEY_WOW64_64KEY, 32 );
1992 check_key_value( root32, "Wine", KEY_WOW64_32KEY, 32 );
1993
1994 pNtDeleteKey( key32 );
1995 pNtClose( key32 );
1996
1997 pNtClose( root64 );
1998 pNtClose( root32 );
1999
2000 pRtlInitUnicodeString( &str, L"\\Registry\\Machine\\Software\\Classes\\Wow6432Node\\Wine" );
2001 attr.RootDirectory = 0;
2002 status = pNtCreateKey( &key32, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
2003 ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status );
2004
2005 status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr );
2006 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
2007 pNtClose( key );
2008
2009 status = pNtOpenKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr );
2010 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
2011 pNtClose( key );
2012
2013 status = pNtOpenKey( &key, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr );
2015 "NtOpenKey failed: 0x%08lx\n", status );
2016 if (!status) pNtClose( key );
2017
2018 pRtlInitUnicodeString( &str, L"\\Registry\\Machine\\Software\\Classes\\Wine" );
2019 status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr );
2021 "NtOpenKey failed: 0x%08lx\n", status );
2022 if (!status) pNtClose( key );
2023
2024 status = pNtOpenKey( &key, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr );
2026 "NtOpenKey failed: 0x%08lx\n", status );
2027 if (!status) pNtClose( key );
2028
2029 status = pNtOpenKey( &key, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr );
2031 "NtOpenKey failed: 0x%08lx\n", status );
2032 if (!status) pNtClose( key );
2033
2034 pRtlInitUnicodeString( &str, L"\\Registry\\Machine\\Software\\Classes\\Wow6432Node" );
2035 status = pNtOpenKey( &root32, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &attr );
2036 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
2037
2038 status = pNtQueryKey( root32, KeyFullInformation, full_info, sizeof(buffer), &len );
2039 ok( status == STATUS_SUCCESS, "NtQueryKey failed: 0x%08lx\n", status );
2040 ok( full_info->SubKeys > 0, "wrong number of subkeys: %lu\n", full_info->SubKeys );
2041 subkeys32 = full_info->SubKeys;
2042 pNtClose( root32 );
2043
2044 pRtlInitUnicodeString( &str, L"\\Registry\\Machine\\Software\\Classes" );
2045 status = pNtOpenKey( &root64, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr );
2046 ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status );
2047
2048 status = pNtQueryKey( root64, KeyFullInformation, full_info, sizeof(buffer), &len );
2049 ok( status == STATUS_SUCCESS, "NtQueryKey failed: 0x%08lx\n", status );
2050 ok( full_info->SubKeys > subkeys32, "wrong number of subkeys: %lu\n", full_info->SubKeys );
2051 subkeys64 = full_info->SubKeys;
2052 pNtClose( root64 );
2053
2054 check_enum_value( L"\\Registry\\Machine\\Software\\Classes",
2055 KEY_WOW64_32KEY | KEY_ALL_ACCESS, subkeys64, ptr_size == 32 );
2056 check_enum_value( L"\\Registry\\Machine\\Software\\Classes",
2057 KEY_WOW64_64KEY | KEY_ALL_ACCESS, subkeys64, ptr_size == 32 );
2058 check_enum_value( L"\\Registry\\Machine\\Software\\Classes",
2059 KEY_ALL_ACCESS, subkeys64, ptr_size == 32 );
2060 check_enum_value( L"\\Registry\\Machine\\Software\\Classes\\Wow6432Node",
2061 KEY_WOW64_32KEY | KEY_ALL_ACCESS, subkeys32, ptr_size == 64 );
2062 check_enum_value( L"\\Registry\\Machine\\Software\\Classes\\Wow6432Node",
2063 KEY_WOW64_64KEY | KEY_ALL_ACCESS, subkeys32, ptr_size == 64 );
2064 check_enum_value( L"\\Registry\\Machine\\Software\\Classes\\Wow6432Node",
2065 KEY_ALL_ACCESS, subkeys32, ptr_size == 64 );
2066 check_enum_value( L"\\Registry\\Machine\\Software\\Wow6432Node\\Classes",
2067 KEY_WOW64_32KEY | KEY_ALL_ACCESS, ptr_size == 32 ? subkeys64 : subkeys32, TRUE );
2068 check_enum_value( L"\\Registry\\Machine\\Software\\Wow6432Node\\Classes",
2069 KEY_WOW64_64KEY | KEY_ALL_ACCESS, subkeys32, ptr_size == 64 );
2070 check_enum_value( L"\\Registry\\Machine\\Software\\Wow6432Node\\Classes",
2071 KEY_ALL_ACCESS, ptr_size == 32 ? subkeys64 : subkeys32, TRUE );
2072
2073 pNtDeleteKey( key32 );
2074 pNtClose( key32 );
2075}
2076
2077static void test_long_value_name(void)
2078{
2079 HANDLE key;
2082 UNICODE_STRING ValName;
2083 DWORD i;
2084
2086 status = pNtOpenKey(&key, KEY_WRITE|KEY_READ, &attr);
2087 ok(status == STATUS_SUCCESS, "NtOpenKey Failed: 0x%08lx\n", status);
2088
2089 ValName.MaximumLength = 0xfffc;
2090 ValName.Length = ValName.MaximumLength - sizeof(WCHAR);
2091 ValName.Buffer = HeapAlloc(GetProcessHeap(), 0, ValName.MaximumLength);
2092 for (i = 0; i < ValName.Length / sizeof(WCHAR); i++)
2093 ValName.Buffer[i] = 'a';
2094 ValName.Buffer[i] = 0;
2095
2096 status = pNtDeleteValueKey(key, &ValName);
2097 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "NtDeleteValueKey with nonexistent long value name returned 0x%08lx\n", status);
2098 status = pNtSetValueKey(key, &ValName, 0, REG_DWORD, &i, sizeof(i));
2099 ok(status == STATUS_INVALID_PARAMETER, "NtSetValueKey with long value name returned 0x%08lx\n", status);
2100
2101 status = pNtQueryValueKey(key, &ValName, KeyValueBasicInformation, NULL, 0, &i);
2102 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "NtQueryValueKey with nonexistent long value name returned 0x%08lx\n", status);
2103
2104 pRtlFreeUnicodeString(&ValName);
2105 pNtClose(key);
2106}
2107
2108static void test_NtQueryKey(void)
2109{
2110 HANDLE key, subkey, subkey2;
2113 ULONG length, len;
2115 KEY_CACHED_INFORMATION cached_info;
2117 DWORD dw;
2118
2120 status = pNtOpenKey(&key, KEY_READ, &attr);
2121 ok(status == STATUS_SUCCESS, "NtOpenKey Failed: 0x%08lx\n", status);
2122
2123 status = pNtQueryKey(key, KeyNameInformation, NULL, 0, &length);
2125 win_skip("KeyNameInformation is not supported\n");
2126 pNtClose(key);
2127 return;
2128 }
2129 ok(status == STATUS_BUFFER_TOO_SMALL, "NtQueryKey Failed: 0x%08lx\n", status);
2131
2132 /* non-zero buffer size, but insufficient */
2133 len = 0;
2134 status = pNtQueryKey(key, KeyNameInformation, info, 1, &len);
2135 ok(status == STATUS_BUFFER_TOO_SMALL, "NtQueryKey Failed: 0x%08lx\n", status);
2136 ok(length == len, "got %ld, expected %ld\n", len, length);
2137 len = 0;
2139 ok(status == STATUS_BUFFER_TOO_SMALL, "NtQueryKey Failed: 0x%08lx\n", status);
2140 ok(length == len, "got %ld, expected %ld\n", len, length);
2141 len = 0;
2143 ok(status == STATUS_BUFFER_OVERFLOW, "NtQueryKey Failed: 0x%08lx\n", status);
2144 ok(length == len, "got %ld, expected %ld\n", len, length);
2145 len = 0;
2146 status = pNtQueryKey(key, KeyNameInformation, info, sizeof(*info), &len);
2147 ok(status == STATUS_BUFFER_OVERFLOW, "NtQueryKey Failed: 0x%08lx\n", status);
2148 ok(length == len, "got %ld, expected %ld\n", len, length);
2149 ok(info->NameLength == winetestpath.Length, "got %ld, expected %d\n",
2150 info->NameLength, winetestpath.Length);
2151
2152 /* correct buffer size */
2153 len = 0;
2154 status = pNtQueryKey(key, KeyNameInformation, info, length, &len);
2155 ok(status == STATUS_SUCCESS, "NtQueryKey Failed: 0x%08lx\n", status);
2156 ok(length == len, "got %ld, expected %ld\n", len, length);
2157
2158 str.Buffer = info->Name;
2159 str.Length = info->NameLength;
2160 ok(pRtlCompareUnicodeString(&winetestpath, &str, TRUE) == 0,
2161 "got %s, expected %s\n",
2162 wine_dbgstr_wn(str.Buffer, str.Length/sizeof(WCHAR)),
2164
2166
2167 attr.RootDirectory = key;
2168 attr.ObjectName = &str;
2169 pRtlCreateUnicodeStringFromAsciiz(&str, "test_subkey");
2170 status = pNtCreateKey(&subkey, GENERIC_ALL, &attr, 0, 0, 0, 0);
2171 ok(status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status);
2172 pRtlFreeUnicodeString(&str);
2173
2174 status = pNtQueryKey(subkey, KeyCachedInformation, &cached_info, sizeof(cached_info), &len);
2175 ok(status == STATUS_SUCCESS, "NtQueryKey Failed: 0x%08lx\n", status);
2176
2177 if (status == STATUS_SUCCESS)
2178 {
2179 ok(len == sizeof(cached_info), "got unexpected length %ld\n", len);
2180 ok(cached_info.SubKeys == 0, "cached_info.SubKeys = %lu\n", cached_info.SubKeys);
2181 ok(cached_info.MaxNameLen == 0, "cached_info.MaxNameLen = %lu\n", cached_info.MaxNameLen);
2182 ok(cached_info.Values == 0, "cached_info.Values = %lu\n", cached_info.Values);
2183 ok(cached_info.MaxValueNameLen == 0, "cached_info.MaxValueNameLen = %lu\n", cached_info.MaxValueNameLen);
2184 ok(cached_info.MaxValueDataLen == 0, "cached_info.MaxValueDataLen = %lu\n", cached_info.MaxValueDataLen);
2185 ok(cached_info.NameLength == 22, "cached_info.NameLength = %lu\n", cached_info.NameLength);
2186 }
2187
2188 attr.RootDirectory = subkey;
2189 attr.ObjectName = &str;
2190 pRtlCreateUnicodeStringFromAsciiz(&str, "test_subkey2");
2191 status = pNtCreateKey(&subkey2, GENERIC_ALL, &attr, 0, 0, 0, 0);
2192 ok(status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status);
2193 pRtlFreeUnicodeString(&str);
2194
2195 pRtlCreateUnicodeStringFromAsciiz(&str, "val");
2196 dw = 64;
2197 status = pNtSetValueKey( subkey, &str, 0, REG_DWORD, &dw, sizeof(dw) );
2198 ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08lx\n", status );
2199 pRtlFreeUnicodeString(&str);
2200
2201 status = pNtQueryKey(subkey, KeyCachedInformation, &cached_info, sizeof(cached_info), &len);
2202 ok(status == STATUS_SUCCESS, "NtQueryKey Failed: 0x%08lx\n", status);
2203
2204 if (status == STATUS_SUCCESS)
2205 {
2206 ok(len == sizeof(cached_info), "got unexpected length %ld\n", len);
2207 ok(cached_info.SubKeys == 1, "cached_info.SubKeys = %lu\n", cached_info.SubKeys);
2208 ok(cached_info.MaxNameLen == 24, "cached_info.MaxNameLen = %lu\n", cached_info.MaxNameLen);
2209 ok(cached_info.Values == 1, "cached_info.Values = %lu\n", cached_info.Values);
2210 ok(cached_info.MaxValueNameLen == 6, "cached_info.MaxValueNameLen = %lu\n", cached_info.MaxValueNameLen);
2211 ok(cached_info.MaxValueDataLen == 4, "cached_info.MaxValueDataLen = %lu\n", cached_info.MaxValueDataLen);
2212 ok(cached_info.NameLength == 22, "cached_info.NameLength = %lu\n", cached_info.NameLength);
2213 }
2214
2215 status = pNtDeleteKey(subkey2);
2216 ok(status == STATUS_SUCCESS, "NtDeleteSubkey failed: %lx\n", status);
2217 status = pNtDeleteKey(subkey);
2218 ok(status == STATUS_SUCCESS, "NtDeleteSubkey failed: %lx\n", status);
2219
2220 pNtClose(subkey2);
2221 pNtClose(subkey);
2222 pNtClose(key);
2223}
2224
2225static void test_notify(void)
2226{
2228 static const LARGE_INTEGER timeout;
2231 HANDLE key, key2, events[4], subkey;
2233 unsigned int i;
2234
2236 status = pNtOpenKey(&key, KEY_ALL_ACCESS, &attr);
2237 ok(status == STATUS_SUCCESS, "NtOpenKey Failed: 0x%08lx\n", status);
2238 status = pNtOpenKey(&key2, KEY_ALL_ACCESS, &attr);
2239 ok(status == STATUS_SUCCESS, "NtOpenKey Failed: 0x%08lx\n", status);
2240
2241 for (i = 0; i < ARRAY_SIZE(events); ++i)
2243
2244 status = pNtNotifyChangeKey(key, events[0], NULL, NULL, &iosb, REG_NOTIFY_CHANGE_NAME, FALSE, NULL, 0, TRUE);
2245 ok(status == STATUS_PENDING, "NtNotifyChangeKey returned %lx\n", status);
2246 status = pNtNotifyChangeKey(key, events[1], NULL, NULL, &iosb, 0, FALSE, NULL, 0, TRUE);
2247 ok(status == STATUS_PENDING, "NtNotifyChangeKey returned %lx\n", status);
2248 status = pNtNotifyChangeKey(key2, events[2], NULL, NULL, &iosb, 0, FALSE, NULL, 0, TRUE);
2249 ok(status == STATUS_PENDING, "NtNotifyChangeKey returned %lx\n", status);
2250 status = pNtNotifyChangeKey(key2, events[3], NULL, NULL, &iosb, REG_NOTIFY_CHANGE_NAME, FALSE, NULL, 0, TRUE);
2251 ok(status == STATUS_PENDING, "NtNotifyChangeKey returned %lx\n", status);
2252
2254 ok(status == WAIT_TIMEOUT, "got %ld\n", status);
2255
2256 attr.RootDirectory = key;
2257 attr.ObjectName = &str;
2258
2259 pRtlCreateUnicodeStringFromAsciiz(&str, "test_subkey");
2260 status = pNtCreateKey(&subkey, GENERIC_ALL, &attr, 0, 0, 0, 0);
2261 ok(status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status);
2262 pRtlFreeUnicodeString(&str);
2263
2264 status = pNtWaitForSingleObject(events[0], FALSE, &timeout);
2265 ok(!status, "got %#lx\n", status);
2266 status = pNtWaitForSingleObject(events[1], FALSE, &timeout);
2267 ok(!status, "got %#lx\n", status);
2268 status = pNtWaitForSingleObject(events[2], FALSE, &timeout);
2269 ok(status == STATUS_TIMEOUT, "got %#lx\n", status);
2270 status = pNtWaitForSingleObject(events[3], FALSE, &timeout);
2271 ok(status == STATUS_TIMEOUT, "got %#lx\n", status);
2272
2273 status = pNtNotifyChangeKey(key, events[0], NULL, NULL, &iosb, 0, FALSE, NULL, 0, TRUE);
2274 ok(status == STATUS_PENDING, "NtNotifyChangeKey returned %lx\n", status);
2275
2276 status = pNtWaitForSingleObject(events[0], FALSE, &timeout);
2277 ok(status == STATUS_TIMEOUT, "got %#lx\n", status);
2278 status = pNtWaitForSingleObject(events[1], FALSE, &timeout);
2279 ok(!status, "got %#lx\n", status);
2280 status = pNtWaitForSingleObject(events[2], FALSE, &timeout);
2281 ok(status == STATUS_TIMEOUT, "got %#lx\n", status);
2282 status = pNtWaitForSingleObject(events[3], FALSE, &timeout);
2283 ok(status == STATUS_TIMEOUT, "got %#lx\n", status);
2284
2285 status = pNtNotifyChangeKey(key, events[1], NULL, NULL, &iosb, 0, FALSE, NULL, 0, TRUE);
2286 ok(status == STATUS_PENDING, "NtNotifyChangeKey returned %lx\n", status);
2287
2289 ok(status == WAIT_TIMEOUT, "got %ld\n", status);
2290
2291 status = pNtDeleteKey(subkey);
2292 ok(status == STATUS_SUCCESS, "NtDeleteSubkey failed: %lx\n", status);
2293
2294 status = pNtWaitForSingleObject(events[0], FALSE, &timeout);
2295 ok(!status, "got %#lx\n", status);
2296 status = pNtWaitForSingleObject(events[1], FALSE, &timeout);
2297 ok(!status, "got %#lx\n", status);
2298 status = pNtWaitForSingleObject(events[2], FALSE, &timeout);
2299 ok(status == STATUS_TIMEOUT, "got %#lx\n", status);
2300 status = pNtWaitForSingleObject(events[3], FALSE, &timeout);
2301 ok(status == STATUS_TIMEOUT, "got %#lx\n", status);
2302
2303 pNtClose(subkey);
2304
2305 status = pNtNotifyChangeKey(key, events[0], NULL, NULL, &iosb, 0, FALSE, NULL, 0, TRUE);
2306 ok(status == STATUS_PENDING, "NtNotifyChangeKey returned %lx\n", status);
2307 status = pNtNotifyChangeKey(key, events[1], NULL, NULL, &iosb, 0, FALSE, NULL, 0, TRUE);
2308 ok(status == STATUS_PENDING, "NtNotifyChangeKey returned %lx\n", status);
2309
2310 pNtClose(key);
2311
2312 status = pNtWaitForSingleObject(events[0], FALSE, &timeout);
2313 ok(!status, "got %#lx\n", status);
2314 status = pNtWaitForSingleObject(events[1], FALSE, &timeout);
2315 ok(!status, "got %#lx\n", status);
2316 status = pNtWaitForSingleObject(events[2], FALSE, &timeout);
2317 ok(status == STATUS_TIMEOUT, "got %#lx\n", status);
2318 status = pNtWaitForSingleObject(events[3], FALSE, &timeout);
2319 ok(status == STATUS_TIMEOUT, "got %#lx\n", status);
2320
2321 if (pNtNotifyChangeMultipleKeys)
2322 {
2324 status = pNtOpenKey(&key, KEY_ALL_ACCESS, &attr);
2325 ok(status == STATUS_SUCCESS, "NtOpenKey Failed: 0x%08lx\n", status);
2326
2327 status = pNtNotifyChangeMultipleKeys(key, 0, NULL, events[0], NULL, NULL, &iosb, REG_NOTIFY_CHANGE_NAME, FALSE, NULL, 0, TRUE);
2328 ok(status == STATUS_PENDING, "NtNotifyChangeKey returned %lx\n", status);
2329
2330 status = pNtWaitForSingleObject(events[0], FALSE, &timeout);
2331 ok(status == STATUS_TIMEOUT, "NtWaitForSingleObject returned %lx\n", status);
2332
2333 attr.RootDirectory = key;
2334 attr.ObjectName = &str;
2335 pRtlCreateUnicodeStringFromAsciiz(&str, "test_subkey");
2336 status = pNtCreateKey(&subkey, GENERIC_ALL, &attr, 0, 0, 0, 0);
2337 ok(status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08lx\n", status);
2338 pRtlFreeUnicodeString(&str);
2339
2340 status = pNtWaitForSingleObject(events[0], FALSE, &timeout);
2341 ok(status == STATUS_SUCCESS, "NtWaitForSingleObject returned %lx\n", status);
2342
2343 status = pNtDeleteKey(subkey);
2344 ok(status == STATUS_SUCCESS, "NtDeleteSubkey failed: %lx\n", status);
2345 pNtClose(subkey);
2346 pNtClose(key);
2347 }
2348 else
2349 {
2350 win_skip("NtNotifyChangeMultipleKeys not available\n");
2351 }
2352
2353 pNtClose(events[0]);
2354 pNtClose(events[1]);
2355}
2356
2358{
2359 static WCHAR empty[] = {0};
2360 static const WCHAR key1[] = {'\\','R','t','l','C','r','e','a','t','e','R','e','g','i','s','t','r','y','K','e','y',0};
2362 SIZE_T size;
2364
2366 size = str.MaximumLength + sizeof(key1)* sizeof(WCHAR) * 2;
2367 str.Buffer = pRtlReAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, str.Buffer, size);
2368 str.MaximumLength = size;
2369 pRtlAppendUnicodeToString(&str, key1);
2370 pRtlAppendUnicodeToString(&str, key1);
2371
2372 /* should work */
2373 status = pRtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE, winetestpath.Buffer);
2374 ok(status == STATUS_SUCCESS, "RtlCreateRegistryKey failed: %08lx\n", status);
2375
2377 ok(status == STATUS_SUCCESS, "RtlCreateRegistryKey failed: %08lx\n", status);
2378
2379 status = pRtlCreateRegistryKey(RTL_REGISTRY_USER, NULL);
2380 ok(status == STATUS_SUCCESS, "RtlCreateRegistryKey failed: %08lx\n", status);
2381
2382 status = pRtlCreateRegistryKey(RTL_REGISTRY_USER | RTL_REGISTRY_OPTIONAL, NULL);
2383 ok(status == STATUS_SUCCESS, "RtlCreateRegistryKey failed: %08lx\n", status);
2384
2385 status = pRtlCreateRegistryKey(RTL_REGISTRY_USER, empty);
2386 ok(status == STATUS_SUCCESS, "RtlCreateRegistryKey failed: %08lx\n", status);
2387
2388 status = pRtlCreateRegistryKey(RTL_REGISTRY_USER | RTL_REGISTRY_OPTIONAL, empty);
2389 ok(status == STATUS_SUCCESS, "RtlCreateRegistryKey failed: %08lx\n", status);
2390
2391 /* invalid first parameter */
2392 status = pRtlCreateRegistryKey(RTL_REGISTRY_USER+1, winetestpath.Buffer);
2393 ok(status == STATUS_INVALID_PARAMETER, "RtlCreateRegistryKey unexpected return value: %08lx, expected %08lx\n", status, STATUS_INVALID_PARAMETER);
2394
2395 status = pRtlCreateRegistryKey((RTL_REGISTRY_USER+1) | RTL_REGISTRY_OPTIONAL, winetestpath.Buffer);
2396 ok(status == STATUS_INVALID_PARAMETER, "RtlCreateRegistryKey unexpected return value: %08lx, expected %08lx\n", status, STATUS_INVALID_PARAMETER);
2397
2398 /* invalid second parameter */
2399 status = pRtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE, NULL);
2400 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD, "RtlCreateRegistryKey unexpected return value: %08lx, expected %08lx\n", status, STATUS_OBJECT_PATH_SYNTAX_BAD);
2401
2402 status = pRtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, NULL);
2403 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD, "RtlCreateRegistryKey unexpected return value: %08lx, expected %08lx\n", status, STATUS_OBJECT_PATH_SYNTAX_BAD);
2404
2405 status = pRtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE, empty);
2406 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD, "RtlCreateRegistryKey unexpected return value: %08lx, expected %08lx\n", status, STATUS_OBJECT_PATH_SYNTAX_BAD);
2407
2408 status = pRtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, empty);
2409 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD, "RtlCreateRegistryKey unexpected return value: %08lx, expected %08lx\n", status, STATUS_OBJECT_PATH_SYNTAX_BAD);
2410
2411 status = pRtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE, str.Buffer);
2412 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "RtlCreateRegistryKey unexpected return value: %08lx, expected %08lx\n", status, STATUS_OBJECT_NAME_NOT_FOUND);
2413
2414 status = pRtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, str.Buffer);
2415 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "RtlCreateRegistryKey unexpected return value: %08lx, expected %08lx\n", status, STATUS_OBJECT_NAME_NOT_FOUND);
2416
2417 /* both parameters invalid */
2418 status = pRtlCreateRegistryKey(RTL_REGISTRY_USER+1, NULL);
2419 ok(status == STATUS_INVALID_PARAMETER, "RtlCreateRegistryKey unexpected return value: %08lx, expected %08lx\n", status, STATUS_INVALID_PARAMETER);
2420
2421 status = pRtlCreateRegistryKey((RTL_REGISTRY_USER+1) | RTL_REGISTRY_OPTIONAL, NULL);
2422 ok(status == STATUS_INVALID_PARAMETER, "RtlCreateRegistryKey unexpected return value: %08lx, expected %08lx\n", status, STATUS_INVALID_PARAMETER);
2423
2424 pRtlFreeUnicodeString(&str);
2425}
2426
2427static void test_NtRenameKey(void)
2428{
2432 HANDLE key, subkey;
2433 char buffer[200];
2435 DWORD size;
2436
2438 ok(status == STATUS_ACCESS_VIOLATION, "Unexpected status %#lx.\n", status);
2439
2441 status = pNtCreateKey(&key, KEY_READ|DELETE, &attr, 0, 0, 0, 0);
2442 ok(!status, "Unexpected status %#lx.\n", status);
2443
2444 attr.RootDirectory = key;
2445 attr.ObjectName = &str;
2446
2447 pRtlCreateUnicodeStringFromAsciiz(&str, "rename_subkey");
2448 status = pNtCreateKey(&subkey, KEY_READ|DELETE, &attr, 0, 0, 0, 0);
2449 ok(!status, "Unexpected status %#lx.\n", status);
2450
2451 memset(&str2, 0, sizeof(str2));
2452 status = NtRenameKey(subkey, &str2);
2453 ok(status == STATUS_INVALID_PARAMETER, "Unexpected status %#lx.\n", status);
2454
2455 pRtlCreateUnicodeStringFromAsciiz(&str2, "renamed_subkey");
2456
2457 status = NtRenameKey(subkey, NULL);
2458 ok(status == STATUS_ACCESS_VIOLATION, "Unexpected status %#lx.\n", status);
2460 ok(status == STATUS_INVALID_HANDLE, "Unexpected status %#lx.\n", status);
2461
2462 status = NtRenameKey(subkey, &str2);
2463 ok(status == STATUS_ACCESS_DENIED, "Unexpected status %#lx.\n", status);
2464 pNtClose(subkey);
2465
2466 status = pNtCreateKey(&subkey, KEY_WRITE|DELETE, &attr, 0, 0, 0, 0);
2467 ok(!status, "Unexpected status %#lx.\n", status);
2468 /* Rename to itself. */
2469 status = NtRenameKey(subkey, &str);
2470 ok(status == STATUS_CANNOT_DELETE, "Unexpected status %#lx.\n", status);
2471 status = NtRenameKey(subkey, &str2);
2472 ok(!status, "Unexpected status %#lx.\n", status);
2473
2474 pRtlFreeUnicodeString(&str2);
2475 pRtlFreeUnicodeString(&str);
2476
2478 status = pNtQueryKey(subkey, KeyNameInformation, info, sizeof(buffer), &size);
2479 ok(!status, "Unexpected status %#lx.\n", status);
2480 if (status == STATUS_SUCCESS)
2481 {
2482 info->Name[info->NameLength/sizeof(WCHAR)] = 0;
2483 ok(!!wcsstr(info->Name, L"renamed_subkey"), "Unexpected subkey name %s.\n", wine_dbgstr_w(info->Name));
2484 }
2485
2486 pNtDeleteKey(subkey);
2487 pNtDeleteKey(key);
2488 pNtClose(subkey);
2489 pNtClose(key);
2490}
2491
2493{
2495 HANDLE hToken;
2496 LUID luid;
2497
2499 return FALSE;
2500
2501 if(!LookupPrivilegeValueA(NULL, privilege, &luid))
2502 {
2503 CloseHandle(hToken);
2504 return FALSE;
2505 }
2506
2507 tp.PrivilegeCount = 1;
2508 tp.Privileges[0].Luid = luid;
2509
2510 if (set)
2511 tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
2512 else
2513 tp.Privileges[0].Attributes = 0;
2514
2516 if (GetLastError() != ERROR_SUCCESS)
2517 {
2518 CloseHandle(hToken);
2519 return FALSE;
2520 }
2521
2522 CloseHandle(hToken);
2523 return TRUE;
2524}
2525
2526static void test_NtRegLoadKeyEx(void)
2527{
2529 OBJECT_ATTRIBUTES file_attr, key_attr;
2530 WCHAR temp_path[MAX_PATH], hivefile_path[MAX_PATH];
2531 UNICODE_STRING hivefile_pathW, key_pathW;
2532 HANDLE key = 0;
2533
2534#ifdef __REACTOS__
2536 {
2537 win_skip("Skipping tests for NtLoadKeyEx on pre-NT6\n");
2538 return;
2539 }
2540#endif
2541
2543 GetTempFileNameW(temp_path, L"key", 0, hivefile_path);
2544 DeleteFileW(hivefile_path);
2545 RtlDosPathNameToNtPathName_U(hivefile_path, &hivefile_pathW, NULL, NULL);
2546
2549 {
2550 win_skip("Failed to set SE_RESTORE_NAME and SE_BACKUP_NAME privileges, skipping tests\n");
2551 RtlFreeUnicodeString(&hivefile_pathW);
2552 return;
2553 }
2554
2555 /* Generate hive file */
2557 status = pNtCreateKey(&key, KEY_ALL_ACCESS, &key_attr, 0, 0, 0, 0);
2558 ok(status == ERROR_SUCCESS, "couldn't create key 0x%lx\n", status);
2559 status = RegSaveKeyW(key, hivefile_path, NULL);
2560 ok(status == ERROR_SUCCESS, "couldn't save key %ld\n", status);
2561 status = pNtDeleteKey(key);
2562 ok(status == ERROR_SUCCESS, "couldn't delete key 0x%lx\n", status);
2563 key = 0;
2564
2565 /* Test for roothandle parameter with no flags */
2566 pRtlFormatCurrentUserKeyPath(&key_pathW);
2567 key_pathW.Buffer = pRtlReAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, key_pathW.Buffer,
2568 key_pathW.MaximumLength + sizeof(key_pathW)*sizeof(WCHAR));
2569 key_pathW.MaximumLength = key_pathW.MaximumLength + sizeof(key_pathW)*sizeof(WCHAR);
2570 pRtlAppendUnicodeToString(&key_pathW, L"TestKey");
2571
2572 InitializeObjectAttributes(&file_attr, &hivefile_pathW, 0, NULL, NULL);
2573 key_attr.ObjectName = &key_pathW;
2574 status = pNtLoadKeyEx(&key_attr, &file_attr, 0, NULL, NULL, KEY_READ, &key, NULL);
2577 {
2578 win_skip("NtLoadKeyEx has a different order of parameters in this windows version\n");
2579 RtlFreeUnicodeString(&hivefile_pathW);
2580 RtlFreeUnicodeString(&key_pathW);
2581 DeleteFileW(hivefile_path);
2582 return;
2583 }
2584 ok(!key, "key is expected to be null\n");
2585 if (key) pNtClose(key);
2586 RtlFreeUnicodeString(&key_pathW);
2587
2588 /* Test for roothandle parameter with REG_APP_HIVE */
2589 RtlCreateUnicodeString(&key_pathW, L"\\REGISTRY\\A\\TestKey");
2590 status = pNtLoadKeyEx(&key_attr, &file_attr, REG_APP_HIVE, NULL, NULL, KEY_READ, &key, NULL);
2591 todo_wine ok(status == STATUS_SUCCESS, "got 0x%lx\n", status);
2592 todo_wine ok(key != NULL, "key is null\n");
2593 if (key) pNtClose(key);
2594 RtlFreeUnicodeString(&key_pathW);
2595
2598 RtlFreeUnicodeString(&hivefile_pathW);
2599 DeleteFileW(hivefile_path);
2600}
2601
2603{
2606 unsigned int expected_calls;
2607 enum
2608 {
2618 }
2624};
2625
2626#if !defined(__REACTOS__) || (DLL_EXPORT_VERSION >= _WIN32_WINNT_WIN7)
2627static unsigned int query_routine_calls;
2628
2629static NTSTATUS WINAPI query_routine(const WCHAR *value_name, ULONG value_type, void *value_data, ULONG value_data_size,
2630 void *context, void *entry_context)
2631{
2633 RTL_QUERY_REGISTRY_TABLE *query = entry_context;
2634 const WCHAR *expected_data;
2635 ULONG expected_size;
2637
2638 trace("Value name: %s\n", debugstr_w(value_name));
2639 trace("Value data: %s\n", debugstr_w(value_data));
2640
2641 if (!(test->flags & SKIP_NAME_CHECK))
2642 {
2644 if (query->Name)
2645 ok(!wcscmp(value_name, query->Name), "Expected name %s, got %s\n", debugstr_w(query->Name), debugstr_w(value_name));
2646 else
2647 ok(!value_name, "Expected null name\n");
2648 }
2649
2650 if (!(test->flags & SKIP_DATA_CHECK) && query_routine_calls < test->expected_calls)
2651 {
2652 if (test->flags & EXPECT_DEFAULT_DATA)
2653 {
2654 expected_type = query->DefaultType;
2655 expected_data = query->DefaultData;
2656 expected_size = query->DefaultLength;
2657 }
2658 else
2659 {
2660 expected_type = test->expected_type;
2661 expected_data = test->expected_data;
2662 expected_size = test->expected_data_size;
2663 }
2664
2665 if (test->flags & SPLIT_MULTI)
2666 {
2668 for (int i = 0; i < query_routine_calls; i++)
2669 expected_data = wcschr(expected_data, '\0') + 1;
2670 expected_size = 0;
2671 }
2672
2673 if (!expected_size && expected_data && (expected_type == REG_SZ || expected_type == REG_EXPAND_SZ))
2674 expected_size = (wcslen(expected_data) + 1) * sizeof(WCHAR);
2675
2677 ok(value_type == expected_type, "Expected type %lu, got %lu\n", expected_type, value_type);
2678
2680 ok(value_data_size == expected_size, "Expected size %lu, got %lu\n", expected_size, value_data_size);
2681
2682 if (expected_data == query->DefaultData || expected_data == NULL)
2683 ok(value_data == expected_data, "Expected data %p, got %p\n", expected_data, value_data);
2684 else
2685 ok(!memcmp(value_data, expected_data, value_data_size),
2686 "Expected data %s, got %s\n", debugstr_w(expected_data), debugstr_w(value_data));
2687 }
2688
2690
2691 return STATUS_SUCCESS;
2692}
2693
2696
2698
2699static union
2700{
2702 char data[32];
2703}
2705
2706static struct
2707{
2708 ULONG size;
2710 char data[32];
2711}
2713
2715{
2716 /* Empty table */
2717 {
2718 {{ NULL }},
2720 },
2721 /* Name without query routine or DIRECT */
2722 {
2723 {{ NULL, 0, (WCHAR*)L"WindowsDrive" }},
2725 },
2726 {
2727 {{ NULL, 0, (WCHAR*)L"I don't exist", NULL, REG_SZ, (WCHAR*)L"Some default" }},
2729 },
2730 /* The query routine is called for every value in current key */
2731 {
2732 {{ query_routine }},
2734 },
2735 /* NOVALUE is ignored when the name is not null */
2736 {
2737 {{ query_routine, RTL_QUERY_REGISTRY_NOVALUE, (WCHAR*)L"WindowsDrive" }},
2739 },
2740 /* NOVALUE calls the callback without enumerating any values */
2741 {
2742 {
2745 },
2747 },
2748 /* DIRECT doesn't call the query routine and reads directly into a buffer */
2749 {
2752 },
2753 {
2754 {{ query_routine, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
2755 &query_reg_values_direct_str, REG_SZ, (WCHAR*)L"Some default" }},
2757 },
2758 {
2760 STATUS_SUCCESS, 0, 0, REG_NONE, L"C:"
2761 },
2762 {
2764 STATUS_SUCCESS, 0, 0, REG_NONE, L"\x2323", 0, 2 * sizeof(WCHAR)
2765 },
2766 {
2769 STATUS_SUCCESS, 0, 0, REG_NONE, L"%SYSTEMDRIVE%"
2770 },
2771 {
2774 STATUS_SUCCESS, 0, 0, REG_NONE, L"\x2323", 0, 2 * sizeof(WCHAR)
2775 },
2776 {
2778 STATUS_SUCCESS, 0, 0, REG_NONE, L"\x2a"
2779 },
2780 {
2782 STATUS_SUCCESS, 0, 0, REG_NONE, L"\x2a\0\0", sizeof(UINT64)
2783 },
2784 {
2786 STATUS_SUCCESS, 0, 0, REG_NONE, L"\xff", 1, 1
2787 },
2788 {
2790 STATUS_SUCCESS, 0, 0, REG_QWORD, L"\x2a\0\0", sizeof(UINT64)
2791 },
2792 {
2794 STATUS_SUCCESS, 0, 0, 0x23, L"\x23", 1, 1
2795 },
2796 /* DIRECT on a multi-string crashes on Windows without NOEXPAND */
2797 /* {
2798 {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"CapitalsOfEurope", &query_reg_values_direct_str }},
2799 STATUS_SUCCESS, 0, WINE_TODO_RET
2800 }, */
2801 {
2804 STATUS_SUCCESS, 0, 0, REG_NONE, L"Brussels\0Paris\0%PATH%\0", sizeof(L"Brussels\0Paris\0%PATH%\0")
2805 },
2806 {
2809 STATUS_SUCCESS, 0, 0, REG_NONE, L"\x2323", 0, 2 * sizeof(WCHAR)
2810 },
2811 /* DIRECT with a null buffer crashes on Windows */
2812 /* {
2813 {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"WindowsDrive", NULL }},
2814 STATUS_INVALID_PARAMETER
2815 }, */
2816 /* SUBKEY changes the current path on the fly */
2817 {
2820 },
2821 {
2822 {
2823 { NULL, RTL_QUERY_REGISTRY_SUBKEY, (WCHAR*)L"subkey" },
2824 { query_routine, 0, (WCHAR*)L"Color" },
2825 },
2827 },
2828 /* NOEXPAND disables variable expansion */
2829 {
2830 {{ query_routine, RTL_QUERY_REGISTRY_NOEXPAND, (WCHAR*)L"WindowsDrive" }},
2831 STATUS_SUCCESS, 1, 0, REG_EXPAND_SZ, L"%SYSTEMDRIVE%"
2832 },
2833 /* NOEXPAND calls the query routine only once instead of once for each string in a multi-string */
2834 {
2835 {{ query_routine, 0, (WCHAR*)L"CapitalsOfEurope" }},
2836 STATUS_SUCCESS, 3, SPLIT_MULTI, REG_SZ, L"Brussels\0Paris\0%PATH%\0"
2837 },
2838 {
2839 {{ query_routine, RTL_QUERY_REGISTRY_NOEXPAND, (WCHAR*)L"CapitalsOfEurope" }},
2840 STATUS_SUCCESS, 1, 0, REG_MULTI_SZ, L"Brussels\0Paris\0%PATH%\0", sizeof(L"Brussels\0Paris\0%PATH%\0")
2841 },
2842 /* The default value is used if the registry value does not exist */
2843 {
2844 {{ query_routine, 0, (WCHAR*)L"I don't exist", NULL, REG_SZ, (WCHAR*)L"Some default", 4 * sizeof (WCHAR) }},
2845 STATUS_SUCCESS, 1, 0, REG_SZ, L"Some", 4 * sizeof(WCHAR)
2846 },
2847 {
2848 {{ query_routine, 0, (WCHAR*)L"I don't exist", NULL, REG_SZ, (WCHAR*)L"%SYSTEMDRIVE%" }},
2850 },
2851 {
2852 {{ query_routine, 0, (WCHAR*)L"I don't exist", NULL, REG_EXPAND_SZ, (WCHAR*)L"%SYSTEMDRIVE%" }},
2853 STATUS_SUCCESS, 1, 0, REG_SZ, L"C:"
2854 },
2855 {
2856 {{ query_routine, 0, (WCHAR*)L"I don't exist", NULL, REG_MULTI_SZ, (WCHAR*)L"Brussels\0Paris\0%PATH%\0" }},
2858 },
2859 {
2860 {{ query_routine, 0, (WCHAR*)L"I don't exist",
2861 NULL, REG_MULTI_SZ, (WCHAR*)L"A\0B\0C", sizeof(L"A\0B\0C") }},
2863 },
2864 {
2865 {{ query_routine, 0, (WCHAR*)L"I don't exist",
2866 NULL, REG_MULTI_SZ, (WCHAR*)L"A\0B\0C", sizeof(L"A\0B\0C") - sizeof(L'\0') }},
2868 },
2869 {
2870 {{ query_routine, 0, (WCHAR*)L"I don't exist", NULL, REG_DWORD, (WCHAR*)0xdeadbeef }},
2872 },
2873 {
2874 {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
2875 &query_reg_values_direct_str, REG_SZ, (WCHAR*)L"Some default", 4 * sizeof(WCHAR) }},
2877 },
2878 {
2879 {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
2880 &query_reg_values_direct_str, REG_SZ, (WCHAR*)L"%SYSTEMDRIVE%" }},
2882 },
2883 {
2884 {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
2885 &query_reg_values_direct_str, REG_SZ, (WCHAR*)L"%SYSTEMDRIVE%" }},
2886 STATUS_SUCCESS, 0, 0, REG_NONE, L"\x2323", 0, 2 * sizeof(WCHAR)
2887 },
2888 {
2889 {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
2890 &query_reg_values_direct_str, REG_EXPAND_SZ, (WCHAR*)L"%SYSTEMDRIVE%" }},
2891 STATUS_SUCCESS, 0, 0, REG_NONE, L"C:"
2892 },
2893 {
2894 {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
2895 &query_reg_values_direct_str, REG_EXPAND_SZ, (WCHAR*)L"%SYSTEMDRIVE%" }},
2896 STATUS_SUCCESS, 0, 0, REG_NONE, L"\x2323", 0, 2 * sizeof(WCHAR)
2897 },
2898 {
2899 {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
2900 &query_reg_values_direct_int, REG_DWORD, (WCHAR*)0xdeadbeef }},
2902 },
2903 {
2904 {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
2905 &query_reg_values_direct_int, REG_DWORD, (WCHAR*)L"\x2a", sizeof(DWORD) }},
2907 },
2908 {
2909 {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
2910 &query_reg_values_direct_sized, REG_DWORD, (WCHAR*)L"Some default", sizeof(L"Some default") }},
2912 },
2913 {
2914 {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
2915 &query_reg_values_direct_sized, REG_DWORD, (WCHAR*)L"Some default", sizeof(L"Some default") }},
2916 STATUS_SUCCESS, 0, 0, REG_NONE, L"\xff", 1, 1
2917 },
2918 {
2919 {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
2920 &query_reg_values_direct_typed, REG_NONE, (WCHAR*)L"Some default", sizeof(L"Some default") }},
2922 },
2923 {
2924 {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
2925 &query_reg_values_direct_typed, REG_QWORD, (WCHAR*)L"Some default", sizeof(L"Some default") }},
2927 },
2928 {
2929 {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
2930 &query_reg_values_direct_typed, REG_QWORD, (WCHAR*)L"\x2a\0\0", sizeof(UINT64) }},
2932 },
2933 {
2934 {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
2935 &query_reg_values_direct_typed, REG_QWORD, (WCHAR*)L"\x2a\0\0", sizeof(UINT64) }},
2936 STATUS_SUCCESS, 0, 0, 0x23, L"\x23", 1, 1
2937 },
2938 /* DIRECT with a multi-string default value crashes on Windows without NOEXPAND */
2939 /* {
2940 {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
2941 &query_reg_values_direct_str, REG_MULTI_SZ, (WCHAR*)L"A\0B\0C\0", sizeof(L"A\0B\0C\0") }},
2942 STATUS_SUCCESS, 0, EXPECT_DEFAULT_DATA
2943 }, */
2944 {
2946 &query_reg_values_direct_str, REG_MULTI_SZ, (WCHAR*)L"A\0B\0C", sizeof(L"A\0B\0C") - sizeof(L'\0') }},
2948 },
2949 /* The default value is not used if it is not valid */
2950 {
2951 {{ query_routine, 0, (WCHAR*)L"I don't exist", NULL, REG_SZ }},
2953 },
2954 {
2955 {{ query_routine, 0, (WCHAR*)L"I don't exist", NULL, REG_NONE, (WCHAR*)L"Some default" }},
2957 },
2958 {
2959 {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
2962 },
2963 {
2964 {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist",
2965 &query_reg_values_direct_str, REG_NONE, (WCHAR*)L"Some default" }},
2966 STATUS_SUCCESS, 0, 0, REG_NONE, NULL, -1
2967 },
2968 /* REQUIRED fails if the value doesn't exist and there is no default */
2969 {
2970 {{ query_routine, RTL_QUERY_REGISTRY_REQUIRED, (WCHAR*)L"I don't exist",
2971 NULL, REG_SZ, (WCHAR*)L"Some default" }},
2973 },
2974 {
2975 {{ query_routine, RTL_QUERY_REGISTRY_REQUIRED, (WCHAR*)L"I don't exist",
2976 NULL, REG_NONE, (WCHAR*)L"Some default" }},
2978 },
2979 /* DELETE deletes the value after reading it */
2980 {
2981 {{ query_routine, RTL_QUERY_REGISTRY_DELETE, (WCHAR*)L"WindowsDrive" }},
2982 STATUS_SUCCESS, 1, 0, REG_SZ, L"C:"
2983 },
2984 {
2985 {{ query_routine, 0, (WCHAR*)L"I don't exist", NULL, REG_SZ, (WCHAR*)L"Some default" }},
2987 },
2988};
2989
2991{
2993 unsigned int i;
2994
2995 status = RegSetKeyValueW(HKEY_CURRENT_USER, L"WineTest", L"WindowsDrive", REG_EXPAND_SZ,
2996 L"%SYSTEMDRIVE%", sizeof(L"%SYSTEMDRIVE%"));
2997 ok(status == ERROR_SUCCESS, "Failed to create registry value WindowsDrive: %lu\n", status);
2998
2999 status = RegSetKeyValueW(HKEY_CURRENT_USER, L"WineTest", L"CapitalsOfEurope", REG_MULTI_SZ,
3000 L"Brussels\0Paris\0%PATH%", sizeof(L"Brussels\0Paris\0%PATH%") - sizeof(L'\0'));
3001 ok(status == ERROR_SUCCESS, "Failed to create registry value CapitalsOfEurope: %lu\n", status);
3002
3003 status = RegSetKeyValueW(HKEY_CURRENT_USER, L"WineTest", L"MeaningOfLife32", REG_DWORD,
3004 L"\x2a", sizeof(DWORD));
3005 ok(status == ERROR_SUCCESS, "Failed to create registry value MeaningOfLife32: %lu\n", status);
3006
3007 status = RegSetKeyValueW(HKEY_CURRENT_USER, L"WineTest", L"MeaningOfLife64", REG_QWORD,
3008 L"\x2a\0\0", sizeof(UINT64));
3009 ok(status == ERROR_SUCCESS, "Failed to create registry value MeaningOfLife64: %lu\n", status);
3010
3011 status = RegSetKeyValueW(HKEY_CURRENT_USER, L"WineTest\\subkey", L"Color", REG_SZ,
3012 L"Yellow", sizeof(L"Yellow"));
3013 ok(status == ERROR_SUCCESS, "Failed to create registry value Color: %lu\n", status);
3014
3015 for (i = 0; i < ARRAY_SIZE(query_reg_values_tests); i++)
3016 {
3019 const WCHAR *expected_data;
3020 ULONG expected_size;
3022
3024
3025 for (query = test->query_table; query->QueryRoutine || query->Name; query++)
3026 {
3027 if (!(query->Flags & RTL_QUERY_REGISTRY_DIRECT))
3028 query->EntryContext = query;
3029 }
3030
3032
3033 query_reg_values_direct_str.MaximumLength = test->size_limit ? test->size_limit
3037 else
3041
3043
3045 query_reg_values_direct_sized.size = test->size_limit ? -test->size_limit
3047
3048 query_reg_values_direct_typed.size = test->size_limit ? test->size_limit
3049 : sizeof(query_reg_values_direct_typed.data);
3052
3053 status = pRtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, winetestpath.Buffer, test->query_table, test, NULL);
3054
3056 ok(status == test->expected_ret, "Expected RtlQueryRegistryValues to return 0x%08lx, got 0x%08lx\n",
3057 test->expected_ret, status);
3058
3060 ok(query_routine_calls == test->expected_calls, "Expected %u calls to QueryRoutine, got %u\n",
3061 test->expected_calls, query_routine_calls);
3062
3063 for (query = test->query_table; query->QueryRoutine || query->Name; query++)
3064 {
3065 if ((query->Flags & RTL_QUERY_REGISTRY_DIRECT) && query->EntryContext)
3066 {
3067 if (test->flags & EXPECT_DEFAULT_DATA)
3068 {
3069 expected_type = query->DefaultType;
3070 expected_data = query->DefaultData;
3071 expected_size = query->DefaultLength;
3072 }
3073 else
3074 {
3075 expected_type = test->expected_type;
3076 expected_data = test->expected_data;
3077 expected_size = test->expected_data_size;
3078 }
3079
3080 if (query->EntryContext == &query_reg_values_direct_str)
3081 {
3082 if (!expected_size && expected_data)
3083 expected_size = (wcslen(expected_data) + 1) * sizeof(WCHAR);
3084 else if (expected_size == -1)
3086
3088 ok(query_reg_values_direct_str.Length + sizeof(WCHAR) == expected_size,
3089 "Expected size %lu, got %Iu\n", expected_size,
3091
3092 if (expected_data)
3093 {
3095 "Expected data %s, got %s\n", debugstr_w(expected_data),
3097 }
3098 }
3099 else if (query->EntryContext == &query_reg_values_direct_int)
3100 {
3101 if (expected_data)
3102 {
3104 "Data does not match\n");
3105 }
3106 else
3107 {
3109 "Expected data to not change, got %lu\n", query_reg_values_direct_int);
3110 }
3111 }
3112 else if (query->EntryContext == &query_reg_values_direct_sized)
3113 {
3115 "Data does not match\n");
3116 }
3117 else if (query->EntryContext == &query_reg_values_direct_typed)
3118 {
3119 if (expected_size == -1)
3120 expected_size = sizeof(query_reg_values_direct_typed.data);
3121
3123 ok(query_reg_values_direct_typed.size == expected_size,
3124 "Expected size %lu, got %lu\n", expected_size, query_reg_values_direct_typed.size);
3125
3128 "Expected type %lu, got %lu\n", expected_type, query_reg_values_direct_typed.type);
3129
3130 if (expected_data)
3131 {
3133 "Data does not match\n");
3134 }
3135 }
3136 }
3137 }
3138
3140 }
3141
3142 status = RegDeleteKeyValueW(HKEY_CURRENT_USER, L"WineTest", L"WindowsDrive");
3143 ok(status == ERROR_FILE_NOT_FOUND, "Registry value WindowsDrive should have been deleted already\n");
3144}
3145#endif
3146
3148{
3149#if !defined(__REACTOS__) || (DLL_EXPORT_VERSION >= _WIN32_WINNT_WIN7)
3151#endif
3152
3153 if(!InitFunctionPtrs())
3154 return;
3155
3156 pRtlFormatCurrentUserKeyPath(&winetestpath);
3157 winetestpath.MaximumLength = winetestpath.MaximumLength + sizeof(L"\\WineTest");
3160 pRtlAppendUnicodeToString(&winetestpath, L"\\WineTest");
3161
3173 test_notify();
3176 test_symlinks();
3180#if !defined(__REACTOS__) || (DLL_EXPORT_VERSION >= _WIN32_WINNT_WIN7)
3182
3184 ok(status == ERROR_SUCCESS, "Failed to delete the WineTest registry key: %lu\n", status);
3185#endif
3186
3187 pRtlFreeUnicodeString(&winetestpath);
3188
3190}
@ ObjectBasicInformation
Definition: DriverTester.h:54
@ ObjectNameInformation
Definition: DriverTester.h:55
#define SE_BACKUP_NAME
#define SE_RESTORE_NAME
#define expect(EXPECTED, GOT)
Definition: SystemMenu.c:483
COMPILER_DEPENDENT_UINT64 UINT64
Definition: actypes.h:131
#define GetNTVersion()
Definition: apitest.h:17
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
HKEY key
Definition: reg.c:28
LONG NTSTATUS
Definition: precomp.h:26
EXTERN_C NTSTATUS WINAPI NtQueryObject(HANDLE, OBJECT_INFORMATION_CLASS, PVOID, ULONG, PULONG)
#define ARRAY_SIZE(A)
Definition: main.h:20
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:616
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
HANDLE HKEY
Definition: registry.h:26
struct _root root
@ ProcessWow64Information
Definition: cicbase.cpp:65
Definition: _set.h:50
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define STATUS_TIMEOUT
Definition: d3dkmdt.h:49
#define STATUS_INVALID_HANDLE
Definition: d3dkmdt.h:40
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: d3dkmdt.h:46
const WCHAR * link
Definition: db.cpp:998
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define ERROR_SUCCESS
Definition: deptool.c:10
LPWSTR Name
Definition: desk.c:124
static LSTATUS(WINAPI *pRegDeleteTreeW)(HKEY
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NTSTATUS
Definition: precomp.h:19
LSTATUS WINAPI RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey)
Definition: reg.c:1711
LONG WINAPI RegSaveKeyW(HKEY hKey, LPCWSTR lpFile, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: reg.c:4617
LONG WINAPI RegDeleteKeyValueW(IN HKEY hKey, IN LPCWSTR lpSubKey OPTIONAL, IN LPCWSTR lpValueName OPTIONAL)
Definition: reg.c:1361
LONG WINAPI RegSetKeyValueW(IN HKEY hKey, IN LPCWSTR lpSubKey OPTIONAL, IN LPCWSTR lpValueName OPTIONAL, IN DWORD dwType, IN LPCVOID lpData OPTIONAL, IN DWORD cbData)
Definition: reg.c:2139
BOOL WINAPI LookupPrivilegeValueA(LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid)
Definition: misc.c:732
BOOL WINAPI AdjustTokenPrivileges(HANDLE TokenHandle, BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength)
Definition: security.c:374
BOOL WINAPI OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle)
Definition: security.c:294
static const WCHAR empty[1]
Definition: string.c:47
#define CloseHandle
Definition: compat.h:739
#define wcschr
Definition: compat.h:17
#define GetProcessHeap()
Definition: compat.h:736
#define GetProcAddress(x, y)
Definition: compat.h:753
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define FreeLibrary(x)
Definition: compat.h:748
#define GetCurrentProcess()
Definition: compat.h:759
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static const WCHAR valueW[]
Definition: object.c:48
static const WCHAR linkW[]
Definition: string.c:50
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
Definition: path.c:1999
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2983
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1972
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
_ACRTIMP wchar_t *__cdecl wcsstr(const wchar_t *, const wchar_t *)
Definition: wcs.c:2993
unsigned int _winver
#define L(x)
Definition: resources.c:13
_In_ uint64_t _In_ uint64_t _In_ uint64_t _In_opt_ traverse_ptr * tp
Definition: btrfs.c:2996
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
struct _UNICODE_STRING UNICODE_STRING
UINT WINAPI GetTempFileNameW(IN LPCWSTR lpPathName, IN LPCWSTR lpPrefixString, IN UINT uUnique, OUT LPWSTR lpTempFileName)
Definition: filename.c:84
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define STATUS_ACCESS_VIOLATION
#define printf
Definition: freeldr.h:103
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLuint64EXT GLuint GLuint GLenum GLenum GLuint GLuint GLenum GLuint GLuint key1
Definition: glext.h:10608
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:312
static int reg
Definition: i386-dis.c:1290
static const WCHAR emptyW[]
Definition: navigate.c:40
REFIID LPVOID DWORD_PTR dw
Definition: atlbase.h:40
#define debugstr_w
Definition: kernel32.h:32
#define wine_dbgstr_w
Definition: kernel32.h:34
BOOL is_wow64
Definition: main.c:38
#define REG_SZ
Definition: layer.c:22
static WCHAR wineW[]
Definition: localmon.c:128
#define win_skip
Definition: minitest.h:67
#define todo_wine_if(is_todo)
Definition: minitest.h:81
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl void winetest_pop_context(void)
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl winetest_push_context(const char *fmt,...) __WINE_PRINTF_ATTR(1
Definition: test.h:537
#define todo_wine
Definition: minitest.h:80
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
char string[160]
Definition: util.h:11
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
HANDLE events[2]
Definition: event.c:4
BOOL expected
Definition: store.c:2000
static PROCESS_INFORMATION pi
Definition: debugger.c:2303
static PIO_STATUS_BLOCK iosb
Definition: file.c:70
struct _KEY_VALUE_BASIC_INFORMATION KEY_VALUE_BASIC_INFORMATION
static ULONG PBYTE
Definition: reg.c:160
static UNICODE_STRING value_str
Definition: reg.c:1395
static IN IN POBJECT_ATTRIBUTES
Definition: reg.c:134
#define check_enum_value(name, flags, subkeys, present)
Definition: reg.c:1506
static unsigned int query_routine_calls
Definition: reg.c:2627
#define NTDLL_GET_PROC(func)
Definition: reg.c:170
static PCWSTR
Definition: reg.c:128
static BOOL set_privileges(LPCSTR privilege, BOOL set)
Definition: reg.c:2492
struct _KEY_VALUE_FULL_INFORMATION KEY_VALUE_FULL_INFORMATION
static void _check_enum_value(int line, const WCHAR *name, DWORD flags, int subkeys, BOOL present)
Definition: reg.c:1440
static ACCESS_MASK access
Definition: reg.c:141
#define RTL_QUERY_REGISTRY_SUBKEY
Definition: reg.c:59
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
static WCHAR query_reg_values_direct_str_buf[32]
Definition: reg.c:2694
static union @1827 query_reg_values_direct_sized
static ACCESS_MASK const OBJECT_ATTRIBUTES * attr
Definition: reg.c:141
static const LARGE_INTEGER *static OBJECT_ATTRIBUTES HANDLE IO_STATUS_BLOCK *static HMODULE hntdll
Definition: reg.c:167
static void test_long_value_name(void)
Definition: reg.c:2077
@ KeyValuePartialInformationAlign64
Definition: reg.c:112
@ KeyValueBasicInformation
Definition: reg.c:108
@ KeyValueFullInformationAlign64
Definition: reg.c:111
static void test_redirection(void)
Definition: reg.c:1508
static BOOL
Definition: reg.c:155
static void test_symlinks(void)
Definition: reg.c:1101
static struct @1828 query_reg_values_direct_typed
enum _KEY_VALUE_INFORMATION_CLASS KEY_VALUE_INFORMATION_CLASS
Definition: reg.c:138
static void test_NtQueryKey(void)
Definition: reg.c:2108
static ULONG DWORD void *static PIO_STATUS_BLOCK
Definition: reg.c:161
static ACCESS_MASK const OBJECT_ATTRIBUTES ULONG const UNICODE_STRING ULONG PULONG dispos
Definition: reg.c:143
static void test_NtRenameKey(void)
Definition: reg.c:2427
#define RTL_QUERY_REGISTRY_NOEXPAND
Definition: reg.c:63
static void test_RtlCheckRegistryKey(void)
Definition: reg.c:611
static UNICODE_STRING winetestpath
Definition: reg.c:168
static ACCESS_MASK const OBJECT_ATTRIBUTES ULONG const UNICODE_STRING ULONG options
Definition: reg.c:142
static void test_NtOpenKey(void)
Definition: reg.c:228
static void test_NtSetValueKey(void)
Definition: reg.c:576
static PHANDLE
Definition: reg.c:133
#define RTL_REGISTRY_ABSOLUTE
Definition: reg.c:49
static void test_NtRegLoadKeyEx(void)
Definition: reg.c:2526
static ACCESS_MASK const OBJECT_ATTRIBUTES ULONG TitleIndex
Definition: reg.c:142
static ULONG ULONG *static OBJECT_INFORMATION_CLASS
Definition: reg.c:146
static const DWORD ptr_size
Definition: reg.c:1396
struct _RTL_QUERY_REGISTRY_TABLE * PRTL_QUERY_REGISTRY_TABLE
Definition: reg.c:131
static void test_RtlpNtQueryValueKey(void)
Definition: reg.c:1093
static void test_notify(void)
Definition: reg.c:2225
#define check_key_value(root, name, flags, expect)
Definition: reg.c:1438
static UNICODE_STRING query_reg_values_direct_str
Definition: reg.c:2695
#define RTL_QUERY_REGISTRY_REQUIRED
Definition: reg.c:61
static void test_NtDeleteKey(void)
Definition: reg.c:851
#define RTL_QUERY_REGISTRY_DIRECT
Definition: reg.c:64
#define RTL_REGISTRY_USER
Definition: reg.c:54
struct _KEY_VALUE_PARTIAL_INFORMATION KEY_VALUE_PARTIAL_INFORMATION
static ULONG DWORD void *static PIO_APC_ROUTINE
Definition: reg.c:161
static KEY_INFORMATION_CLASS
Definition: reg.c:137
static ULONG
Definition: reg.c:135
static void test_RtlCreateRegistryKey(void)
Definition: reg.c:2357
static void _check_key_value(int line, HANDLE root, const char *name, DWORD flags, DWORD expect)
Definition: reg.c:1433
static LPCWSTR
Definition: reg.c:152
static IN PUNICODE_STRING
Definition: reg.c:130
struct _KEY_VALUE_PARTIAL_INFORMATION * PKEY_VALUE_PARTIAL_INFORMATION
struct _KEY_VALUE_BASIC_INFORMATION * PKEY_VALUE_BASIC_INFORMATION
static const WCHAR stringW[]
Definition: reg.c:42
static NTSTATUS WINAPI query_routine(const WCHAR *value_name, ULONG value_type, void *value_data, ULONG value_data_size, void *context, void *entry_context)
Definition: reg.c:2629
#define STR_TRUNC_SIZE
Definition: reg.c:44
static void test_RtlOpenCurrentUser(void)
Definition: reg.c:602
struct _RTL_QUERY_REGISTRY_TABLE RTL_QUERY_REGISTRY_TABLE
static DWORD get_key_value(HANDLE root, const char *name, DWORD flags)
Definition: reg.c:1398
static void test_RtlQueryRegistryValues(void)
Definition: reg.c:2990
#define RTL_QUERY_REGISTRY_DELETE
Definition: reg.c:65
static BOOL InitFunctionPtrs(void)
Definition: reg.c:178
static LPCSTR
Definition: reg.c:127
#define RTL_QUERY_REGISTRY_NOVALUE
Definition: reg.c:62
#define RTL_REGISTRY_OPTIONAL
Definition: reg.c:57
static IN ACCESS_MASK
Definition: reg.c:134
static void test_NtFlushKey(void)
Definition: reg.c:635
static struct query_reg_values_test query_reg_values_tests[]
Definition: reg.c:2714
static ULONG query_reg_values_direct_int
Definition: reg.c:2697
static const BOOLEAN
Definition: reg.c:151
struct _KEY_VALUE_FULL_INFORMATION * PKEY_VALUE_FULL_INFORMATION
static PULONG
Definition: reg.c:144
static void test_NtQueryLicenseKey(void)
Definition: reg.c:919
static void test_NtCreateKey(void)
Definition: reg.c:387
static void test_NtQueryValueKey(void)
Definition: reg.c:654
char temp_path[MAX_PATH]
Definition: mspatcha.c:123
NTSYSAPI NTSTATUS NTAPI RtlCreateRegistryKey(_In_ ULONG RelativeTo, _In_ PWSTR Path)
NTSYSAPI NTSTATUS NTAPI RtlOpenCurrentUser(_In_ ACCESS_MASK DesiredAccess, _Out_ PHANDLE KeyHandle)
_In_ PCWSTR _Inout_ _At_ QueryTable EntryContext
Definition: rtlfuncs.h:4210
NTSYSAPI NTSTATUS NTAPI RtlFormatCurrentUserKeyPath(_Out_ _At_(KeyPath->Buffer, __drv_allocatesMem(Mem) _Post_bytecap_(KeyPath->MaximumLength) _Post_bytecount_(KeyPath->Length)) PUNICODE_STRING KeyPath)
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
NTSYSAPI BOOLEAN NTAPI RtlDosPathNameToNtPathName_U(_In_opt_z_ PCWSTR DosPathName, _Out_ PUNICODE_STRING NtPathName, _Out_opt_ PCWSTR *NtFileNamePart, _Out_opt_ PRTL_RELATIVE_NAME_U DirectoryInfo)
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
NTSYSAPI NTSTATUS NTAPI NtSetValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN ULONG TitleIndex OPTIONAL, IN ULONG Type, IN PVOID Data, IN ULONG DataSize)
Definition: ntapi.c:859
@ KeyBasicInformation
Definition: nt_native.h:1134
@ KeyFullInformation
Definition: nt_native.h:1136
#define REG_OPTION_OPEN_LINK
Definition: nt_native.h:1073
_KEY_VALUE_INFORMATION_CLASS
Definition: nt_native.h:1182
@ KeyValuePartialInformation
Definition: nt_native.h:1185
@ KeyValueFullInformation
Definition: nt_native.h:1184
#define KEY_ALL_ACCESS
Definition: nt_native.h:1044
#define KEY_READ
Definition: nt_native.h:1026
NTSYSAPI NTSTATUS NTAPI NtDeleteValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName)
Definition: ntapi.c:1014
#define REG_OPTION_CREATE_LINK
Definition: nt_native.h:1066
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
ULONG ACCESS_MASK
Definition: nt_native.h:40
struct _KEY_BASIC_INFORMATION * PKEY_BASIC_INFORMATION
#define LPVOID
Definition: nt_native.h:45
NTSYSAPI NTSTATUS NTAPI NtQueryValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, IN PVOID KeyValueInformation, IN ULONG Length, IN PULONG ResultLength)
#define REG_MULTI_SZ
Definition: nt_native.h:1504
NTSYSAPI NTSTATUS NTAPI NtEnumerateKey(IN HANDLE KeyHandle, IN ULONG Index, IN KEY_INFORMATION_CLASS KeyInformationClass, IN PVOID KeyInformation, IN ULONG Length, IN PULONG ResultLength)
#define GENERIC_ALL
Definition: nt_native.h:92
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define DELETE
Definition: nt_native.h:57
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define KEY_WRITE
Definition: nt_native.h:1034
#define REG_LINK
Definition: nt_native.h:1503
#define DWORD
Definition: nt_native.h:44
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)
#define REG_NONE
Definition: nt_native.h:1495
#define REG_EXPAND_SZ
Definition: nt_native.h:1497
#define KEY_SET_VALUE
Definition: nt_native.h:1020
NTSTATUS NTAPI NtLoadKeyEx(IN POBJECT_ATTRIBUTES TargetKey, IN POBJECT_ATTRIBUTES SourceFile, IN ULONG Flags, IN HANDLE TrustClassKey)
Definition: ntapi.c:1148
NTSTATUS NTAPI NtDeleteKey(IN HANDLE KeyHandle)
Definition: ntapi.c:408
NTSTATUS NTAPI NtNotifyChangeKey(IN HANDLE KeyHandle, IN HANDLE Event, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG CompletionFilter, IN BOOLEAN WatchTree, OUT PVOID Buffer, IN ULONG Length, IN BOOLEAN Asynchronous)
Definition: ntapi.c:1290
NTSTATUS NTAPI NtCreateKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG TitleIndex, IN PUNICODE_STRING Class OPTIONAL, IN ULONG CreateOptions, OUT PULONG Disposition OPTIONAL)
Definition: ntapi.c:240
NTSTATUS NTAPI NtFlushKey(IN HANDLE KeyHandle)
Definition: ntapi.c:1085
NTSTATUS NTAPI NtEnumerateValueKey(IN HANDLE KeyHandle, IN ULONG Index, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, OUT PVOID KeyValueInformation, IN ULONG Length, OUT PULONG ResultLength)
Definition: ntapi.c:542
NTSTATUS NTAPI NtRenameKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ReplacementName)
Definition: ntapi.c:1605
NTSTATUS NTAPI NtQueryKey(IN HANDLE KeyHandle, IN KEY_INFORMATION_CLASS KeyInformationClass, OUT PVOID KeyInformation, IN ULONG Length, OUT PULONG ResultLength)
Definition: ntapi.c:632
NTSTATUS NTAPI NtQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_writes_bytes_to_opt_(ProcessInformationLength, *ReturnLength) PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:211
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_OBJECT_PATH_SYNTAX_BAD
Definition: ntstatus.h:389
#define STATUS_KEY_DELETED
Definition: ntstatus.h:707
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:285
#define STATUS_INVALID_PARAMETER_7
Definition: ntstatus.h:575
#define STATUS_INVALID_PARAMETER_6
Definition: ntstatus.h:574
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:592
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_OPENLINK
Definition: winternl.h:230
#define test
Definition: rosglue.h:37
#define wine_dbgstr_wn
Definition: testlist.c:2
const WCHAR * str
#define REG_QWORD
Definition: sdbapi.c:616
#define REG_DWORD
Definition: sdbapi.c:615
#define offsetof(TYPE, MEMBER)
XML_HIDDEN void xmlParserErrors const char const xmlChar const xmlChar * str2
Definition: parser.h:35
#define memset(x, y, z)
Definition: compat.h:39
NTSTATUS NTAPI RtlpNtQueryValueKey(IN HANDLE KeyHandle, OUT PULONG Type OPTIONAL, OUT PVOID Data OPTIONAL, IN OUT PULONG DataLength OPTIONAL, IN ULONG Unused)
Definition: registry.c:936
#define _WIN32_WINNT_WIN7
Definition: sdkddkver.h:28
#define _WIN32_WINNT_VISTA
Definition: sdkddkver.h:25
#define STATUS_CANNOT_DELETE
Definition: shellext.h:71
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
_In_ PVOID Context
Definition: storport.h:2269
PUNICODE_STRING ObjectName
Definition: umtypes.h:187
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: cookie.c:202
Definition: http.c:7252
Definition: copy.c:22
Definition: parser.c:49
Definition: name.c:39
enum query_reg_values_test::@1829 flags
unsigned int expected_calls
Definition: reg.c:2606
ULONG expected_data_size
Definition: reg.c:2622
RTL_QUERY_REGISTRY_TABLE query_table[3]
Definition: reg.c:2604
ULONG expected_type
Definition: reg.c:2620
NTSTATUS expected_ret
Definition: reg.c:2605
const WCHAR * expected_data
Definition: reg.c:2621
Definition: ps.c:97
Definition: tools.h:99
Definition: dhcpd.h:248
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:587
#define STATUS_PENDING
Definition: telnetd.h:14
uint16_t * PWSTR
Definition: typedefs.h:56
const char * LPCSTR
Definition: typedefs.h:52
uint32_t * PULONG
Definition: typedefs.h:59
const uint16_t * PCWSTR
Definition: typedefs.h:57
unsigned char UCHAR
Definition: typedefs.h:53
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
void * PVOID
Definition: typedefs.h:50
PVOID HANDLE
Definition: typedefs.h:73
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_DATA_OVERRUN
Definition: udferr_usr.h:152
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
struct _STRING * PSTRING
struct _OBJECT_ATTRIBUTES OBJECT_ATTRIBUTES
Definition: pdh_main.c:96
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG _Out_opt_ PULONG _Out_opt_ PULONG ValueType
Definition: wdfregistry.h:282
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG ValueLength
Definition: wdfregistry.h:275
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define WINAPI
Definition: msvc.h:6
@ KeyCachedInformation
Definition: winternl.h:1853
@ KeyNameInformation
Definition: winternl.h:1852
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T) __WINE_ALLOC_SIZE(4) __WINE_DEALLOC(RtlFreeHeap
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
NTSYSAPI NTSTATUS WINAPI RtlDuplicateUnicodeString(int, const UNICODE_STRING *, UNICODE_STRING *)
NTSYSAPI NTSTATUS WINAPI RtlCheckRegistryKey(ULONG, PWSTR)
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define REG_NOTIFY_CHANGE_NAME
Definition: winreg.h:38
#define KEY_WOW64_32KEY
Definition: cmtypes.h:45
#define REG_APP_HIVE
Definition: cmtypes.h:110
#define KEY_WOW64_64KEY
Definition: cmtypes.h:46
RTL_QUERY_REGISTRY_ROUTINE * PRTL_QUERY_REGISTRY_ROUTINE
Definition: rtltypes.h:53
#define TOKEN_ADJUST_PRIVILEGES
Definition: setypes.h:942
#define SE_PRIVILEGE_ENABLED
Definition: setypes.h:63