reactos/modules/rostests/apitests/ntdll/NtQueryValueKey.c

116 lines
4.4 KiB
C

/*
* 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 <winreg.h>
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);
}