mirror of
https://github.com/reactos/reactos.git
synced 2025-02-28 19:32:59 +00:00
[NTDLL_APITEST][KMTESTS] Add tests for NtQueryObject(ObjectNameInformation) (#7592)
CORE-13525
This commit is contained in:
parent
dac991c056
commit
02a394ea57
4 changed files with 215 additions and 0 deletions
|
@ -41,6 +41,7 @@ list(APPEND SOURCE
|
|||
NtQueryInformationThread.c
|
||||
NtQueryInformationToken.c
|
||||
NtQueryKey.c
|
||||
NtQueryObject.c
|
||||
NtQueryOpenSubKeys.c
|
||||
NtQuerySystemEnvironmentValue.c
|
||||
NtQuerySystemInformation.c
|
||||
|
|
107
modules/rostests/apitests/ntdll/NtQueryObject.c
Normal file
107
modules/rostests/apitests/ntdll/NtQueryObject.c
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* PROJECT: ReactOS API Tests
|
||||
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
||||
* PURPOSE: Test for NtQueryObject
|
||||
* COPYRIGHT: Copyright 2024 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
/* Flags combination allowing all the read, write and delete share modes.
|
||||
* Currently similar to FILE_SHARE_VALID_FLAGS. */
|
||||
#define FILE_SHARE_ALL \
|
||||
(FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE)
|
||||
|
||||
/* Adapted from kmtests/ntos_ob/ObQuery.c!ObjectNameInformationTests().
|
||||
* Please sync both tests in case you add or remove new features. */
|
||||
START_TEST(NtQueryObject)
|
||||
{
|
||||
ULONG g_OsVersion =
|
||||
SharedUserData->NtMajorVersion << 8 | SharedUserData->NtMinorVersion;
|
||||
|
||||
NTSTATUS Status;
|
||||
HANDLE DeviceHandle;
|
||||
UNICODE_STRING DeviceName;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
|
||||
ULONG BufferSize1, BufferSize2, BufferSize3;
|
||||
struct { OBJECT_NAME_INFORMATION; WCHAR Buffer[MAX_PATH]; } ObjectNameBuffer;
|
||||
PUNICODE_STRING ObjectName = &ObjectNameBuffer.Name;
|
||||
|
||||
/* Test the drive containing SystemRoot */
|
||||
WCHAR NtDeviceName[] = L"\\DosDevices\\?:";
|
||||
NtDeviceName[sizeof("\\DosDevices\\")-1] = SharedUserData->NtSystemRoot[0];
|
||||
|
||||
/* Open a handle to the device */
|
||||
RtlInitUnicodeString(&DeviceName, NtDeviceName);
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&DeviceName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
Status = NtOpenFile(&DeviceHandle,
|
||||
FILE_READ_ATTRIBUTES | SYNCHRONIZE,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
FILE_SHARE_ALL,
|
||||
FILE_SYNCHRONOUS_IO_NONALERT);
|
||||
ok_ntstatus(Status, STATUS_SUCCESS);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
skip("Device '%S': Opening failed\n", NtDeviceName);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Invoke ObjectNameInformation that retrieves the canonical device name */
|
||||
Status = NtQueryObject(DeviceHandle,
|
||||
ObjectNameInformation,
|
||||
&ObjectNameBuffer,
|
||||
0,
|
||||
&BufferSize1);
|
||||
ok_ntstatus(Status, STATUS_INFO_LENGTH_MISMATCH);
|
||||
|
||||
Status = NtQueryObject(DeviceHandle,
|
||||
ObjectNameInformation,
|
||||
&ObjectNameBuffer,
|
||||
sizeof(OBJECT_NAME_INFORMATION),
|
||||
&BufferSize2);
|
||||
ok_ntstatus(Status, STATUS_BUFFER_OVERFLOW);
|
||||
|
||||
Status = NtQueryObject(DeviceHandle,
|
||||
ObjectNameInformation,
|
||||
&ObjectNameBuffer,
|
||||
sizeof(ObjectNameBuffer),
|
||||
&BufferSize3);
|
||||
ok_ntstatus(Status, STATUS_SUCCESS);
|
||||
|
||||
NtClose(DeviceHandle);
|
||||
|
||||
/* Compare the returned buffer sizes */
|
||||
|
||||
/* The returned size behaviour changed (when NtQueryObject()'s
|
||||
* input Length is zero) between Windows <= 2003 and Vista+ */
|
||||
if (g_OsVersion < _WIN32_WINNT_VISTA)
|
||||
ok_eq_ulong(BufferSize1, (ULONG)sizeof(OBJECT_NAME_INFORMATION));
|
||||
else
|
||||
ok_eq_ulong(BufferSize1, (ULONG)sizeof(OBJECT_NAME_INFORMATION) + ObjectName->MaximumLength);
|
||||
|
||||
ok_eq_ulong(BufferSize2, BufferSize3);
|
||||
ok_eq_ulong(BufferSize3, (ULONG)sizeof(OBJECT_NAME_INFORMATION) + ObjectName->MaximumLength);
|
||||
|
||||
/* Test the name buffer */
|
||||
ok(ObjectName->Length > 0, "ObjectName->Length == %hu, expected > 0\n", ObjectName->Length);
|
||||
ok_eq_uint(ObjectName->MaximumLength, ObjectName->Length + sizeof(WCHAR));
|
||||
ok(ObjectName->Buffer[ObjectName->Length / sizeof(WCHAR)] == UNICODE_NULL,
|
||||
"UNICODE_NULL not found at end of ObjectName->Buffer\n");
|
||||
if (ObjectName->Buffer[ObjectName->Length / sizeof(WCHAR)] != UNICODE_NULL)
|
||||
{
|
||||
skip("ObjectName->Buffer string length check skipped\n");
|
||||
return;
|
||||
}
|
||||
/* Verify that ObjectName->Length doesn't count extra NUL-terminators */
|
||||
{
|
||||
SIZE_T strLen = wcslen(ObjectName->Buffer) * sizeof(WCHAR);
|
||||
ok_eq_size(strLen, (SIZE_T)ObjectName->Length);
|
||||
}
|
||||
}
|
|
@ -37,6 +37,7 @@ extern void func_NtQueryInformationProcess(void);
|
|||
extern void func_NtQueryInformationThread(void);
|
||||
extern void func_NtQueryInformationToken(void);
|
||||
extern void func_NtQueryKey(void);
|
||||
extern void func_NtQueryObject(void);
|
||||
extern void func_NtQueryOpenSubKeys(void);
|
||||
extern void func_NtQuerySystemEnvironmentValue(void);
|
||||
extern void func_NtQuerySystemInformation(void);
|
||||
|
@ -140,6 +141,7 @@ const struct test winetest_testlist[] =
|
|||
{ "NtQueryInformationThread", func_NtQueryInformationThread },
|
||||
{ "NtQueryInformationToken", func_NtQueryInformationToken },
|
||||
{ "NtQueryKey", func_NtQueryKey },
|
||||
{ "NtQueryObject", func_NtQueryObject },
|
||||
{ "NtQueryOpenSubKeys", func_NtQueryOpenSubKeys },
|
||||
{ "NtQuerySystemEnvironmentValue", func_NtQuerySystemEnvironmentValue },
|
||||
{ "NtQuerySystemInformation", func_NtQuerySystemInformation },
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: Kernel mode tests for object information querying
|
||||
* COPYRIGHT: Copyright 2023 George Bișoc <george.bisoc@reactos.org>
|
||||
* Copyright 2024 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
|
||||
*/
|
||||
|
||||
#include <kmt_test.h>
|
||||
|
@ -65,7 +66,111 @@ ObjectBasicInformationTests(VOID)
|
|||
ZwClose(WinStaDirHandle);
|
||||
}
|
||||
|
||||
/* Flags combination allowing all the read, write and delete share modes.
|
||||
* Currently similar to FILE_SHARE_VALID_FLAGS. */
|
||||
#define FILE_SHARE_ALL \
|
||||
(FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE)
|
||||
|
||||
#define ok_ntstatus ok_eq_hex
|
||||
|
||||
/* Adapted from apitests/ntdll/NtQueryObject.c!START_TEST(NtQueryObject).
|
||||
* Please sync both tests in case you add or remove new features. */
|
||||
static
|
||||
VOID
|
||||
ObjectNameInformationTests(VOID)
|
||||
{
|
||||
ULONG g_OsVersion =
|
||||
SharedUserData->NtMajorVersion << 8 | SharedUserData->NtMinorVersion;
|
||||
|
||||
NTSTATUS Status;
|
||||
HANDLE DeviceHandle;
|
||||
UNICODE_STRING DeviceName;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
|
||||
ULONG BufferSize1, BufferSize2, BufferSize3;
|
||||
struct { OBJECT_NAME_INFORMATION; WCHAR Buffer[MAX_PATH]; } ObjectNameBuffer;
|
||||
PUNICODE_STRING ObjectName = &ObjectNameBuffer.Name;
|
||||
|
||||
/* Test the drive containing SystemRoot */
|
||||
WCHAR NtDeviceName[] = L"\\DosDevices\\?:";
|
||||
NtDeviceName[sizeof("\\DosDevices\\")-1] = SharedUserData->NtSystemRoot[0];
|
||||
|
||||
/* We must be in PASSIVE_LEVEL to do all of this stuff */
|
||||
ok_irql(PASSIVE_LEVEL);
|
||||
|
||||
/* Open a handle to the device */
|
||||
RtlInitUnicodeString(&DeviceName, NtDeviceName);
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&DeviceName,
|
||||
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
|
||||
NULL,
|
||||
NULL);
|
||||
Status = ZwOpenFile(&DeviceHandle,
|
||||
FILE_READ_ATTRIBUTES | SYNCHRONIZE,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
FILE_SHARE_ALL,
|
||||
FILE_SYNCHRONOUS_IO_NONALERT);
|
||||
ok_ntstatus(Status, STATUS_SUCCESS);
|
||||
if (skip(NT_SUCCESS(Status), "Device '%wZ': Opening failed\n", &DeviceName))
|
||||
return;
|
||||
|
||||
/* Invoke ObjectNameInformation that retrieves the canonical device name */
|
||||
Status = ZwQueryObject(DeviceHandle,
|
||||
ObjectNameInformation,
|
||||
&ObjectNameBuffer,
|
||||
0,
|
||||
&BufferSize1);
|
||||
ok_ntstatus(Status, STATUS_INFO_LENGTH_MISMATCH);
|
||||
|
||||
Status = ZwQueryObject(DeviceHandle,
|
||||
ObjectNameInformation,
|
||||
&ObjectNameBuffer,
|
||||
sizeof(OBJECT_NAME_INFORMATION),
|
||||
&BufferSize2);
|
||||
ok_ntstatus(Status, STATUS_BUFFER_OVERFLOW);
|
||||
|
||||
Status = ZwQueryObject(DeviceHandle,
|
||||
ObjectNameInformation,
|
||||
&ObjectNameBuffer,
|
||||
sizeof(ObjectNameBuffer),
|
||||
&BufferSize3);
|
||||
ok_ntstatus(Status, STATUS_SUCCESS);
|
||||
|
||||
ZwClose(DeviceHandle);
|
||||
|
||||
/* Compare the returned buffer sizes */
|
||||
|
||||
/* The returned size behaviour changed (when ZwQueryObject()'s
|
||||
* input Length is zero) between Windows <= 2003 and Vista+ */
|
||||
if (g_OsVersion < _WIN32_WINNT_VISTA)
|
||||
ok_eq_ulong(BufferSize1, sizeof(OBJECT_NAME_INFORMATION));
|
||||
else
|
||||
ok_eq_ulong(BufferSize1, sizeof(OBJECT_NAME_INFORMATION) + ObjectName->MaximumLength);
|
||||
|
||||
ok_eq_ulong(BufferSize2, BufferSize3);
|
||||
ok_eq_ulong(BufferSize3, sizeof(OBJECT_NAME_INFORMATION) + ObjectName->MaximumLength);
|
||||
|
||||
/* Test the name buffer */
|
||||
ok(ObjectName->Length > 0, "ObjectName->Length == %hu, expected > 0\n", ObjectName->Length);
|
||||
ok_eq_uint(ObjectName->MaximumLength, ObjectName->Length + sizeof(WCHAR));
|
||||
ok(ObjectName->Buffer[ObjectName->Length / sizeof(WCHAR)] == UNICODE_NULL,
|
||||
"UNICODE_NULL not found at end of ObjectName->Buffer\n");
|
||||
if (skip(ObjectName->Buffer[ObjectName->Length / sizeof(WCHAR)] == UNICODE_NULL,
|
||||
"ObjectName->Buffer string length check skipped\n"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
/* Verify that ObjectName->Length doesn't count extra NUL-terminators */
|
||||
{
|
||||
SIZE_T strLen = wcslen(ObjectName->Buffer) * sizeof(WCHAR);
|
||||
ok_eq_size(strLen, (SIZE_T)ObjectName->Length);
|
||||
}
|
||||
}
|
||||
|
||||
START_TEST(ObQuery)
|
||||
{
|
||||
ObjectBasicInformationTests();
|
||||
ObjectNameInformationTests();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue