ReactOS 0.4.15-dev-7934-g1dc8d80
NtQueryKey.c File Reference
#include "precomp.h"
Include dependency graph for NtQueryKey.c:

Go to the source code of this file.

Functions

static void Test_KeyFullInformation (void)
 
static void Test_KeyNameInformation (void)
 
 START_TEST (NtQueryKey)
 

Function Documentation

◆ START_TEST()

START_TEST ( NtQueryKey  )

Definition at line 272 of file NtQueryKey.c.

273{
276}
static void Test_KeyFullInformation(void)
Definition: NtQueryKey.c:13
static void Test_KeyNameInformation(void)
Definition: NtQueryKey.c:188

◆ Test_KeyFullInformation()

static void Test_KeyFullInformation ( void  )
static

Definition at line 13 of file NtQueryKey.c.

14{
15 UNICODE_STRING HKLM_Name = RTL_CONSTANT_STRING(L"\\Registry\\Machine");
16 UNICODE_STRING Software_Name = RTL_CONSTANT_STRING(L"Software");
17 UNICODE_STRING Test_Name = RTL_CONSTANT_STRING(L"NtQueryKey_apitest");
18 UNICODE_STRING MyClass = RTL_CONSTANT_STRING(L"MyClass");
19 HANDLE HKLM_Key, HKLM_Software_Key, Test_Key;
20 ULONG FullInformationLength;
21 PKEY_FULL_INFORMATION FullInformation;
22 ULONG InfoLength;
25
26 FullInformationLength = FIELD_OFFSET(KEY_FULL_INFORMATION, Class[100]);
27 FullInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, FullInformationLength);
28 if (!FullInformation)
29 {
30 skip("Out of memory\n");
31 return;
32 }
33
35 &HKLM_Name,
37 NULL,
38 NULL);
41
42 InfoLength = 0x55555555;
43 Status = NtQueryKey(HKLM_Key, KeyFullInformation, NULL, 0, &InfoLength);
44 ok(Status == STATUS_BUFFER_TOO_SMALL, "Status = 0x%lx\n", Status);
45 ok(InfoLength == FIELD_OFFSET(KEY_FULL_INFORMATION, Class), "InfoLength = %lu\n", InfoLength);
46
47 RtlFillMemory(FullInformation, FullInformationLength, 0x55);
48 InfoLength = 0x55555555;
49 Status = NtQueryKey(HKLM_Key, KeyFullInformation, FullInformation, FIELD_OFFSET(KEY_FULL_INFORMATION, Class), &InfoLength);
50 ok(Status == STATUS_SUCCESS, "Status = 0x%lx\n", Status);
51 ok(InfoLength == FIELD_OFFSET(KEY_FULL_INFORMATION, Class), "InfoLength = %lu\n", InfoLength);
52 ok(FullInformation->LastWriteTime.QuadPart != 0x5555555555555555, "LastWriteTime unchanged\n");
53 ok(FullInformation->TitleIndex == 0, "TitleIndex = %lu\n", FullInformation->TitleIndex);
54 ok(FullInformation->ClassOffset == 0xffffffff, "ClassOffset = %lu\n", FullInformation->ClassOffset);
55 ok(FullInformation->ClassLength == 0, "ClassLength = %lu\n", FullInformation->ClassLength);
56 ok(FullInformation->SubKeys >= 5 && FullInformation->SubKeys < 20, "SubKeys = %lu\n", FullInformation->SubKeys);
57 ok(FullInformation->MaxNameLen >= 8 * sizeof(WCHAR) && FullInformation->MaxNameLen < 100 * sizeof(WCHAR), "MaxNameLen = %lu\n", FullInformation->MaxNameLen);
58 ok(FullInformation->MaxClassLen != 0x55555555 && FullInformation->MaxClassLen % sizeof(WCHAR) == 0, "MaxClassLen = %lu\n", FullInformation->MaxClassLen);
59 ok(FullInformation->Values != 0x55555555, "Values = %lu\n", FullInformation->Values);
60 ok(FullInformation->MaxValueNameLen != 0x55555555 && FullInformation->MaxValueNameLen % sizeof(WCHAR) == 0, "MaxValueNameLen = %lu\n", FullInformation->MaxValueNameLen);
61 ok(FullInformation->MaxValueDataLen != 0x55555555, "MaxValueDataLen = %lu\n", FullInformation->MaxValueDataLen);
62 ok(FullInformation->Class[0] == 0x5555, "Class[0] = %u\n", FullInformation->Class[0]);
63
64 RtlFillMemory(FullInformation, FullInformationLength, 0x55);
65 InfoLength = 0x55555555;
66 Status = NtQueryKey(HKLM_Key, KeyFullInformation, FullInformation, FIELD_OFFSET(KEY_FULL_INFORMATION, Class) - 1, &InfoLength);
67 ok(Status == STATUS_BUFFER_TOO_SMALL, "Status = 0x%lx\n", Status);
68 ok(InfoLength == FIELD_OFFSET(KEY_FULL_INFORMATION, Class), "InfoLength = %lu\n", InfoLength);
69 ok(FullInformation->LastWriteTime.QuadPart == 0x5555555555555555, "LastWriteTime changed: %I64d\n", FullInformation->LastWriteTime.QuadPart);
70
72 &Software_Name,
74 HKLM_Key,
75 NULL);
76 Status = NtOpenKey(&HKLM_Software_Key, KEY_READ, &ObjectAttributes);
78
79 RtlFillMemory(FullInformation, FullInformationLength, 0x55);
80 InfoLength = 0x55555555;
81 Status = NtQueryKey(HKLM_Software_Key, KeyFullInformation, FullInformation, FIELD_OFFSET(KEY_FULL_INFORMATION, Class), &InfoLength);
82 ok(Status == STATUS_SUCCESS, "Status = 0x%lx\n", Status);
83 ok(InfoLength == FIELD_OFFSET(KEY_FULL_INFORMATION, Class), "InfoLength = %lu\n", InfoLength);
84 ok(FullInformation->LastWriteTime.QuadPart != 0x5555555555555555, "LastWriteTime unchanged\n");
85 ok(FullInformation->TitleIndex == 0, "TitleIndex = %lu\n", FullInformation->TitleIndex);
86 ok(FullInformation->ClassOffset == 0xffffffff, "ClassOffset = %lu\n", FullInformation->ClassOffset);
87 ok(FullInformation->ClassLength == 0, "ClassLength = %lu\n", FullInformation->ClassLength);
88 ok(FullInformation->SubKeys >= 5 && FullInformation->SubKeys < 1000, "SubKeys = %lu\n", FullInformation->SubKeys);
89 ok(FullInformation->MaxNameLen >= 8 * sizeof(WCHAR), "MaxNameLen = %lu\n", FullInformation->MaxNameLen);
90 ok(FullInformation->MaxClassLen != 0x55555555 && FullInformation->MaxClassLen % sizeof(WCHAR) == 0, "MaxClassLen = %lu\n", FullInformation->MaxClassLen);
91 ok(FullInformation->Values != 0x55555555, "Values = %lu\n", FullInformation->Values);
92 ok(FullInformation->MaxValueNameLen != 0x55555555 && FullInformation->MaxValueNameLen % sizeof(WCHAR) == 0, "MaxValueNameLen = %lu\n", FullInformation->MaxValueNameLen);
93 ok(FullInformation->MaxValueDataLen != 0x55555555, "MaxValueDataLen = %lu\n", FullInformation->MaxValueDataLen);
94 ok(FullInformation->Class[0] == 0x5555, "Class[0] = %u\n", FullInformation->Class[0]);
95
97 &Test_Name,
99 HKLM_Software_Key,
100 NULL);
103
104 InfoLength = 0x55555555;
105 Status = NtQueryKey(Test_Key, KeyFullInformation, NULL, 0, &InfoLength);
106 ok(Status == STATUS_BUFFER_TOO_SMALL, "Status = 0x%lx\n", Status);
107 ok(InfoLength == FIELD_OFFSET(KEY_FULL_INFORMATION, Class) + MyClass.Length, "InfoLength = %lu\n", InfoLength);
108
109 RtlFillMemory(FullInformation, FullInformationLength, 0x55);
110 InfoLength = 0x55555555;
111 Status = NtQueryKey(Test_Key, KeyFullInformation, FullInformation, FIELD_OFFSET(KEY_FULL_INFORMATION, Class), &InfoLength);
112 ok(Status == STATUS_BUFFER_OVERFLOW, "Status = 0x%lx\n", Status);
113 ok(InfoLength == FIELD_OFFSET(KEY_FULL_INFORMATION, Class) + MyClass.Length, "InfoLength = %lu\n", InfoLength);
114 ok(FullInformation->LastWriteTime.QuadPart != 0x5555555555555555, "LastWriteTime unchanged\n");
115 ok(FullInformation->TitleIndex == 0, "TitleIndex = %lu\n", FullInformation->TitleIndex);
116 ok(FullInformation->ClassOffset == FIELD_OFFSET(KEY_FULL_INFORMATION, Class), "ClassOffset = %lu\n", FullInformation->ClassOffset);
117 ok(FullInformation->ClassLength == MyClass.Length, "ClassLength = %lu\n", FullInformation->ClassLength);
118 ok(FullInformation->SubKeys == 0, "SubKeys = %lu\n", FullInformation->SubKeys);
119 ok(FullInformation->MaxNameLen == 0, "MaxNameLen = %lu\n", FullInformation->MaxNameLen);
120 ok(FullInformation->MaxClassLen == 0, "MaxClassLen = %lu\n", FullInformation->MaxClassLen);
121 ok(FullInformation->Values == 0, "Values = %lu\n", FullInformation->Values);
122 ok(FullInformation->MaxValueNameLen == 0, "MaxValueNameLen = %lu\n", FullInformation->MaxValueNameLen);
123 ok(FullInformation->MaxValueDataLen == 0, "MaxValueDataLen = %lu\n", FullInformation->MaxValueDataLen);
124 ok(FullInformation->Class[0] == 0x5555, "Class[0] = %u\n", FullInformation->Class[0]);
125
126 RtlFillMemory(FullInformation, FullInformationLength, 0x55);
127 InfoLength = 0x55555555;
128 Status = NtQueryKey(Test_Key, KeyFullInformation, FullInformation, FIELD_OFFSET(KEY_FULL_INFORMATION, Class[1]), &InfoLength);
129 ok(Status == STATUS_BUFFER_OVERFLOW, "Status = 0x%lx\n", Status);
130 ok(InfoLength == FIELD_OFFSET(KEY_FULL_INFORMATION, Class) + MyClass.Length, "InfoLength = %lu\n", InfoLength);
131 ok(FullInformation->LastWriteTime.QuadPart != 0x5555555555555555, "LastWriteTime unchanged\n");
132 ok(FullInformation->ClassOffset == FIELD_OFFSET(KEY_FULL_INFORMATION, Class), "ClassOffset = %lu\n", FullInformation->ClassOffset);
133 ok(FullInformation->ClassLength == MyClass.Length, "ClassLength = %lu\n", FullInformation->ClassLength);
134 ok(FullInformation->Class[0] == L'M', "Class[0] = %u\n", FullInformation->Class[0]);
135 ok(FullInformation->Class[1] == 0x5555, "Class[1] = %u\n", FullInformation->Class[1]);
136
137 RtlFillMemory(FullInformation, FullInformationLength, 0x55);
138 InfoLength = 0x55555555;
139 Status = NtQueryKey(Test_Key, KeyFullInformation, FullInformation, FIELD_OFFSET(KEY_FULL_INFORMATION, Class) + MyClass.Length - 1, &InfoLength);
140 ok(Status == STATUS_BUFFER_OVERFLOW, "Status = 0x%lx\n", Status);
141 ok(InfoLength == FIELD_OFFSET(KEY_FULL_INFORMATION, Class) + MyClass.Length, "InfoLength = %lu\n", InfoLength);
142 ok(FullInformation->LastWriteTime.QuadPart != 0x5555555555555555, "LastWriteTime unchanged\n");
143 ok(FullInformation->ClassOffset == FIELD_OFFSET(KEY_FULL_INFORMATION, Class), "ClassOffset = %lu\n", FullInformation->ClassOffset);
144 ok(FullInformation->ClassLength == MyClass.Length, "ClassLength = %lu\n", FullInformation->ClassLength);
145 ok(FullInformation->Class[0] == L'M', "Class[0] = %u\n", FullInformation->Class[0]);
146 ok(FullInformation->Class[1] == L'y', "Class[1] = %u\n", FullInformation->Class[1]);
147 ok(FullInformation->Class[6] == (L's' | 0x5500), "Class[6] = %u\n", FullInformation->Class[6]);
148 ok(FullInformation->Class[7] == 0x5555, "Class[7] = %u\n", FullInformation->Class[7]);
149
150 RtlFillMemory(FullInformation, FullInformationLength, 0x55);
151 InfoLength = 0x55555555;
152 Status = NtQueryKey(Test_Key, KeyFullInformation, FullInformation, FIELD_OFFSET(KEY_FULL_INFORMATION, Class) + MyClass.Length, &InfoLength);
153 ok(Status == STATUS_SUCCESS, "Status = 0x%lx\n", Status);
154 ok(InfoLength == FIELD_OFFSET(KEY_FULL_INFORMATION, Class) + MyClass.Length, "InfoLength = %lu\n", InfoLength);
155 ok(FullInformation->LastWriteTime.QuadPart != 0x5555555555555555, "LastWriteTime unchanged\n");
156 ok(FullInformation->ClassOffset == FIELD_OFFSET(KEY_FULL_INFORMATION, Class), "ClassOffset = %lu\n", FullInformation->ClassOffset);
157 ok(FullInformation->ClassLength == MyClass.Length, "ClassLength = %lu\n", FullInformation->ClassLength);
158 ok(FullInformation->Class[0] == L'M', "Class[0] = %u\n", FullInformation->Class[0]);
159 ok(FullInformation->Class[1] == L'y', "Class[1] = %u\n", FullInformation->Class[1]);
160 ok(FullInformation->Class[6] == L's', "Class[6] = %u\n", FullInformation->Class[6]);
161 ok(FullInformation->Class[7] == 0x5555, "Class[7] = %u\n", FullInformation->Class[7]);
162
163 RtlFillMemory(FullInformation, FullInformationLength, 0x55);
164 InfoLength = 0x55555555;
165 Status = NtQueryKey(Test_Key, KeyFullInformation, FullInformation, FIELD_OFFSET(KEY_FULL_INFORMATION, Class) + MyClass.Length + sizeof(UNICODE_NULL), &InfoLength);
166 ok(Status == STATUS_SUCCESS, "Status = 0x%lx\n", Status);
167 ok(InfoLength == FIELD_OFFSET(KEY_FULL_INFORMATION, Class) + MyClass.Length, "InfoLength = %lu\n", InfoLength);
168 ok(FullInformation->LastWriteTime.QuadPart != 0x5555555555555555, "LastWriteTime unchanged\n");
169 ok(FullInformation->ClassOffset == FIELD_OFFSET(KEY_FULL_INFORMATION, Class), "ClassOffset = %lu\n", FullInformation->ClassOffset);
170 ok(FullInformation->ClassLength == MyClass.Length, "ClassLength = %lu\n", FullInformation->ClassLength);
171 ok(FullInformation->Class[0] == L'M', "Class[0] = %u\n", FullInformation->Class[0]);
172 ok(FullInformation->Class[1] == L'y', "Class[1] = %u\n", FullInformation->Class[1]);
173 ok(FullInformation->Class[6] == L's', "Class[6] = %u\n", FullInformation->Class[6]);
174 ok(FullInformation->Class[7] == 0x5555, "Class[7] = %u\n", FullInformation->Class[7]);
175
176 RtlFreeHeap(RtlGetProcessHeap(), 0, FullInformation);
177
178 Status = NtDeleteKey(Test_Key);
180
181 NtClose(Test_Key);
182 NtClose(HKLM_Software_Key);
183 NtClose(HKLM_Key);
184}
#define ok_ntstatus(status, expected)
Definition: atltest.h:135
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
LONG NTSTATUS
Definition: precomp.h:26
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
Status
Definition: gdiplustypes.h:25
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:599
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
@ KeyFullInformation
Definition: nt_native.h:1133
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define KEY_READ
Definition: nt_native.h:1023
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
NTSTATUS NTAPI NtDeleteKey(IN HANDLE KeyHandle)
Definition: ntapi.c:408
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 NtQueryKey(IN HANDLE KeyHandle, IN KEY_INFORMATION_CLASS KeyInformationClass, OUT PVOID KeyInformation, IN ULONG Length, OUT PULONG ResultLength)
Definition: ntapi.c:632
#define UNICODE_NULL
#define L(x)
Definition: ntvdm.h:50
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
LARGE_INTEGER LastWriteTime
Definition: nt_native.h:1117
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
uint32_t ULONG
Definition: typedefs.h:59
LONGLONG QuadPart
Definition: typedefs.h:114
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by START_TEST().

◆ Test_KeyNameInformation()

static void Test_KeyNameInformation ( void  )
static

Definition at line 188 of file NtQueryKey.c.

189{
190 UNICODE_STRING HKLM_Name = RTL_CONSTANT_STRING(L"\\Registry\\Machine");
191 UNICODE_STRING HKLM_Software_Name = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software");
192 UNICODE_STRING Software_Name = RTL_CONSTANT_STRING(L"Software");
193 UNICODE_STRING InfoName;
194 HANDLE HKLM_Key, HKLM_Software_Key;
195 PKEY_NAME_INFORMATION NameInformation;
196 ULONG InfoLength;
199
200 /* Open the HKCU key */
202 &HKLM_Name,
204 NULL,
205 NULL);
208
209 /* Get the name info length */
210 InfoLength = 0;
211 Status = NtQueryKey(HKLM_Key, KeyNameInformation, NULL, 0, &InfoLength);
213 ok_size_t(InfoLength, FIELD_OFFSET(KEY_NAME_INFORMATION, Name[HKLM_Name.Length/sizeof(WCHAR)]));
214
215 /* Get it for real */
216 NameInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, InfoLength);
217 if (!NameInformation)
218 {
219 skip("Out of memory\n");
220 return;
221 }
222
223 Status = NtQueryKey(HKLM_Key, KeyNameInformation, NameInformation, InfoLength, &InfoLength);
225 ok_size_t(InfoLength, FIELD_OFFSET(KEY_NAME_INFORMATION, Name[HKLM_Name.Length/sizeof(WCHAR)]));
226 ok_size_t(NameInformation->NameLength, HKLM_Name.Length);
227
228 InfoName.Buffer = NameInformation->Name;
229 InfoName.Length = NameInformation->NameLength;
230 InfoName.MaximumLength = NameInformation->NameLength;
231 ok(RtlCompareUnicodeString(&InfoName, &HKLM_Name, TRUE) == 0, "%.*S\n",
232 InfoName.Length, InfoName.Buffer);
233
234 RtlFreeHeap(RtlGetProcessHeap(), 0, NameInformation);
235
236 /* Open one subkey */
238 &Software_Name,
240 HKLM_Key,
241 NULL);
242 Status = NtOpenKey(&HKLM_Software_Key, KEY_READ, &ObjectAttributes);
244
245 /* Get the name info length */
246 InfoLength = 0;
247 Status = NtQueryKey(HKLM_Software_Key, KeyNameInformation, NULL, 0, &InfoLength);
249 ok_size_t(InfoLength, FIELD_OFFSET(KEY_NAME_INFORMATION, Name[HKLM_Software_Name.Length/sizeof(WCHAR)]));
250
251 /* Get it for real */
252 NameInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, InfoLength);
253 ok(NameInformation != NULL, "\n");
254
255 Status = NtQueryKey(HKLM_Software_Key, KeyNameInformation, NameInformation, InfoLength, &InfoLength);
257 ok_size_t(InfoLength, FIELD_OFFSET(KEY_NAME_INFORMATION, Name[HKLM_Software_Name.Length/sizeof(WCHAR)]));
258 ok_size_t(NameInformation->NameLength, HKLM_Software_Name.Length);
259
260 InfoName.Buffer = NameInformation->Name;
261 InfoName.Length = NameInformation->NameLength;
262 InfoName.MaximumLength = NameInformation->NameLength;
263 ok(RtlCompareUnicodeString(&InfoName, &HKLM_Software_Name, TRUE) == 0, "%.*S\n",
264 InfoName.Length, InfoName.Buffer);
265
266 RtlFreeHeap(RtlGetProcessHeap(), 0, NameInformation);
267
268 NtClose(HKLM_Software_Key);
269 NtClose(HKLM_Key);
270}
#define ok_size_t(expression, result)
Definition: atltest.h:115
#define TRUE
Definition: types.h:120
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
@ KeyNameInformation
Definition: winternl.h:831
USHORT MaximumLength
Definition: env_spec_w32.h:370

Referenced by START_TEST().