1 /*
2 * PROJECT: ReactOS API Tests
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: Test for NtQueryValueKey
5 * COPYRIGHT: Copyright 2020 Thomas Faber (thomas.faber@reactos.org)
6 */
7
8 #include "precomp.h"
9 #include <winreg.h>
10
START_TEST(NtQueryValueKey)11 START_TEST(NtQueryValueKey)
12 {
13 NTSTATUS Status;
14 HANDLE KeyHandle;
15 UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion");
16 OBJECT_ATTRIBUTES ObjectAttributes;
17 UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"SystemRoot");
18 PKEY_VALUE_PARTIAL_INFORMATION_ALIGN64 Info;
19 PKEY_VALUE_PARTIAL_INFORMATION_ALIGN64 InfoUnaligned;
20 ULONG InfoLength;
21 ULONG ResultLength;
22 const WCHAR *StringData;
23 ULONG StringLength;
24
25 InitializeObjectAttributes(&ObjectAttributes,
26 &KeyName,
27 OBJ_CASE_INSENSITIVE,
28 NULL,
29 NULL);
30 Status = NtOpenKey(&KeyHandle,
31 KEY_QUERY_VALUE,
32 &ObjectAttributes);
33 if (!NT_SUCCESS(Status))
34 {
35 skip("Test key unavailable\n");
36 return;
37 }
38
39 /* Specify zero-size buffer, get the length */
40 ResultLength = 0x55555555;
41 Status = NtQueryValueKey(KeyHandle,
42 &ValueName,
43 KeyValuePartialInformationAlign64,
44 NULL,
45 0,
46 &ResultLength);
47 ok_hex(Status, STATUS_BUFFER_TOO_SMALL);
48 ok(ResultLength > FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION_ALIGN64, Data) && ResultLength < 0x10000,
49 "Invalid result length %lu\n", ResultLength);
50 if (ResultLength < FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION_ALIGN64, Data))
51 {
52 skip("Result length %lu too small\n", ResultLength);
53 goto Exit;
54 }
55 InfoLength = ResultLength;
56 Info = RtlAllocateHeap(RtlGetProcessHeap(),
57 0,
58 InfoLength + 4);
59 if (Info == NULL)
60 {
61 skip("Could not alloc %lu bytes\n", InfoLength);
62 goto Exit;
63 }
64
65 /* Successful call */
66 Status = NtQueryValueKey(KeyHandle,
67 &ValueName,
68 KeyValuePartialInformationAlign64,
69 Info,
70 InfoLength,
71 &ResultLength);
72 ok_hex(Status, STATUS_SUCCESS);
73 ok_int(ResultLength, InfoLength);
74
75 ok_int(Info->Type, REG_SZ);
76 StringLength = InfoLength - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION_ALIGN64, Data);
77 ok_int(Info->DataLength, StringLength);
78
79 StringData = (PWCHAR)Info->Data;
80 ok(Info->DataLength >= 5 * sizeof(WCHAR), "DataLength %lu is too small for path\n", Info->DataLength);
81 if (Info->DataLength >= 5 * sizeof(WCHAR))
82 {
83 trace("SystemRoot: %.*ls\n", (int)(Info->DataLength / sizeof(WCHAR) - 1), StringData);
84 ok(StringData[0] >= 'A' && StringData[0] <= 'Z', "Data[0] = %x\n", StringData[0]);
85 ok(StringData[1] == ':', "Data[1] = %x\n", StringData[1]);
86 ok(StringData[2] == '\\', "Data[2] = %x\n", StringData[2]);
87 ok(iswalnum(StringData[3]), "Data[3] = %x\n", StringData[3]);
88 ok(StringData[Info->DataLength / sizeof(WCHAR) - 1] == UNICODE_NULL,
89 "Data[%lu] = %x\n", Info->DataLength / sizeof(WCHAR) - 1, StringData[Info->DataLength / sizeof(WCHAR) - 1]);
90 }
91
92 /* If the buffer isn't 64 bit aligned, the data won't be, either */
93 InfoUnaligned = (PVOID)((PUCHAR)Info + 4);
94 Status = NtQueryValueKey(KeyHandle,
95 &ValueName,
96 KeyValuePartialInformationAlign64,
97 InfoUnaligned,
98 InfoLength,
99 &ResultLength);
100 ok_hex(Status, STATUS_SUCCESS);
101 ok_int(ResultLength, InfoLength);
102 ok_int(InfoUnaligned->Type, REG_SZ);
103 StringData = (PWCHAR)InfoUnaligned->Data;
104 ok(InfoUnaligned->DataLength >= 2 * sizeof(WCHAR), "DataLength %lu is too small for path\n", InfoUnaligned->DataLength);
105 if (InfoUnaligned->DataLength >= 2 * sizeof(WCHAR))
106 {
107 ok(StringData[1] == ':', "Data[1] = %x\n", StringData[1]);
108 }
109
110 RtlFreeHeap(RtlGetProcessHeap(), 0, Info);
111
112 Exit:
113 Status = NtClose(KeyHandle);
114 ok_hex(Status, STATUS_SUCCESS);
115 }
116