From b2cf64094cc0980f7d16e4cd089b3e9a9dd34773 Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Sat, 31 Oct 2020 13:08:06 +0100 Subject: [PATCH] [NTDLL_APITEST] Add a test for KeyValuePartialInformationAlign64. CORE-17358 --- .../rostests/apitests/ntdll/CMakeLists.txt | 1 + .../rostests/apitests/ntdll/NtQueryValueKey.c | 115 ++++++++++++++++++ modules/rostests/apitests/ntdll/testlist.c | 2 + 3 files changed, 118 insertions(+) create mode 100644 modules/rostests/apitests/ntdll/NtQueryValueKey.c diff --git a/modules/rostests/apitests/ntdll/CMakeLists.txt b/modules/rostests/apitests/ntdll/CMakeLists.txt index bb2a8cad1f6..1c5be3bad1e 100644 --- a/modules/rostests/apitests/ntdll/CMakeLists.txt +++ b/modules/rostests/apitests/ntdll/CMakeLists.txt @@ -30,6 +30,7 @@ list(APPEND SOURCE NtQueryKey.c NtQuerySystemEnvironmentValue.c NtQuerySystemInformation.c + NtQueryValueKey.c NtQueryVolumeInformationFile.c NtReadFile.c NtSaveKey.c diff --git a/modules/rostests/apitests/ntdll/NtQueryValueKey.c b/modules/rostests/apitests/ntdll/NtQueryValueKey.c new file mode 100644 index 00000000000..b2b75948289 --- /dev/null +++ b/modules/rostests/apitests/ntdll/NtQueryValueKey.c @@ -0,0 +1,115 @@ +/* + * PROJECT: ReactOS API Tests + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Test for NtQueryValueKey + * COPYRIGHT: Copyright 2020 Thomas Faber (thomas.faber@reactos.org) + */ + +#include "precomp.h" +#include + +START_TEST(NtQueryValueKey) +{ + NTSTATUS Status; + HANDLE KeyHandle; + UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"); + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"SystemRoot"); + PKEY_VALUE_PARTIAL_INFORMATION_ALIGN64 Info; + PKEY_VALUE_PARTIAL_INFORMATION_ALIGN64 InfoUnaligned; + ULONG InfoLength; + ULONG ResultLength; + const WCHAR *StringData; + ULONG StringLength; + + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenKey(&KeyHandle, + KEY_QUERY_VALUE, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + skip("Test key unavailable\n"); + return; + } + + /* Specify zero-size buffer, get the length */ + ResultLength = 0x55555555; + Status = NtQueryValueKey(KeyHandle, + &ValueName, + KeyValuePartialInformationAlign64, + NULL, + 0, + &ResultLength); + ok_hex(Status, STATUS_BUFFER_TOO_SMALL); + ok(ResultLength > FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION_ALIGN64, Data) && ResultLength < 0x10000, + "Invalid result length %lu\n", ResultLength); + if (ResultLength < FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION_ALIGN64, Data)) + { + skip("Result length %lu too small\n", ResultLength); + goto Exit; + } + InfoLength = ResultLength; + Info = RtlAllocateHeap(RtlGetProcessHeap(), + 0, + InfoLength + 4); + if (Info == NULL) + { + skip("Could not alloc %lu bytes\n", InfoLength); + goto Exit; + } + + /* Successful call */ + Status = NtQueryValueKey(KeyHandle, + &ValueName, + KeyValuePartialInformationAlign64, + Info, + InfoLength, + &ResultLength); + ok_hex(Status, STATUS_SUCCESS); + ok_int(ResultLength, InfoLength); + + ok_int(Info->Type, REG_SZ); + StringLength = InfoLength - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION_ALIGN64, Data); + ok_int(Info->DataLength, StringLength); + + StringData = (PWCHAR)Info->Data; + ok(Info->DataLength >= 5 * sizeof(WCHAR), "DataLength %lu is too small for path\n", Info->DataLength); + if (Info->DataLength >= 5 * sizeof(WCHAR)) + { + trace("SystemRoot: %.*ls\n", (int)(Info->DataLength / sizeof(WCHAR) - 1), StringData); + ok(StringData[0] >= 'A' && StringData[0] <= 'Z', "Data[0] = %x\n", StringData[0]); + ok(StringData[1] == ':', "Data[1] = %x\n", StringData[1]); + ok(StringData[2] == '\\', "Data[2] = %x\n", StringData[2]); + ok(iswalnum(StringData[3]), "Data[3] = %x\n", StringData[3]); + ok(StringData[Info->DataLength / sizeof(WCHAR) - 1] == UNICODE_NULL, + "Data[%lu] = %x\n", Info->DataLength / sizeof(WCHAR) - 1, StringData[Info->DataLength / sizeof(WCHAR) - 1]); + } + + /* If the buffer isn't 64 bit aligned, the data won't be, either */ + InfoUnaligned = (PVOID)((PUCHAR)Info + 4); + Status = NtQueryValueKey(KeyHandle, + &ValueName, + KeyValuePartialInformationAlign64, + InfoUnaligned, + InfoLength, + &ResultLength); + ok_hex(Status, STATUS_SUCCESS); + ok_int(ResultLength, InfoLength); + ok_int(InfoUnaligned->Type, REG_SZ); + StringData = (PWCHAR)InfoUnaligned->Data; + ok(InfoUnaligned->DataLength >= 2 * sizeof(WCHAR), "DataLength %lu is too small for path\n", InfoUnaligned->DataLength); + if (InfoUnaligned->DataLength >= 2 * sizeof(WCHAR)) + { + ok(StringData[1] == ':', "Data[1] = %x\n", StringData[1]); + } + + RtlFreeHeap(RtlGetProcessHeap(), 0, Info); + +Exit: + Status = NtClose(KeyHandle); + ok_hex(Status, STATUS_SUCCESS); +} diff --git a/modules/rostests/apitests/ntdll/testlist.c b/modules/rostests/apitests/ntdll/testlist.c index 40a0d686c8b..fa8282ea5f4 100644 --- a/modules/rostests/apitests/ntdll/testlist.c +++ b/modules/rostests/apitests/ntdll/testlist.c @@ -28,6 +28,7 @@ extern void func_NtQueryInformationThread(void); extern void func_NtQueryKey(void); extern void func_NtQuerySystemEnvironmentValue(void); extern void func_NtQuerySystemInformation(void); +extern void func_NtQueryValueKey(void); extern void func_NtQueryVolumeInformationFile(void); extern void func_NtReadFile(void); extern void func_NtSaveKey(void); @@ -102,6 +103,7 @@ const struct test winetest_testlist[] = { "NtQueryKey", func_NtQueryKey }, { "NtQuerySystemEnvironmentValue", func_NtQuerySystemEnvironmentValue }, { "NtQuerySystemInformation", func_NtQuerySystemInformation }, + { "NtQueryValueKey", func_NtQueryValueKey }, { "NtQueryVolumeInformationFile", func_NtQueryVolumeInformationFile }, { "NtReadFile", func_NtReadFile }, { "NtSaveKey", func_NtSaveKey},