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 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