Reactos
at master 140 lines 5.5 kB view raw
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 NtQueryObject 5 * COPYRIGHT: Copyright 2024 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org> 6 */ 7 8#include "precomp.h" 9 10/* Flags combination allowing all the read, write and delete share modes. 11 * Currently similar to FILE_SHARE_VALID_FLAGS. */ 12#define FILE_SHARE_ALL \ 13 (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE) 14 15/* Adapted from kmtests/ntos_ob/ObQuery.c!ObjectNameInformationTests(). 16 * Please sync both tests in case you add or remove new features. */ 17START_TEST(NtQueryObject) 18{ 19 ULONG g_OsVersion = 20 SharedUserData->NtMajorVersion << 8 | SharedUserData->NtMinorVersion; 21 22 NTSTATUS Status; 23 HANDLE DeviceHandle; 24 UNICODE_STRING DeviceName; 25 OBJECT_ATTRIBUTES ObjectAttributes; 26 IO_STATUS_BLOCK IoStatusBlock; 27 28 ULONG BufferSize1, BufferSize2, BufferSize3; 29 struct { OBJECT_NAME_INFORMATION; WCHAR Buffer[MAX_PATH]; } ObjectNameBuffer; 30 PUNICODE_STRING ObjectName = &ObjectNameBuffer.Name; 31 32 /* Test the drive containing SystemRoot */ 33 WCHAR NtDeviceName[] = L"\\DosDevices\\?:"; 34 NtDeviceName[sizeof("\\DosDevices\\")-1] = SharedUserData->NtSystemRoot[0]; 35 36 /* Open a handle to the device */ 37 RtlInitUnicodeString(&DeviceName, NtDeviceName); 38 InitializeObjectAttributes(&ObjectAttributes, 39 &DeviceName, 40 OBJ_CASE_INSENSITIVE, 41 NULL, 42 NULL); 43 Status = NtOpenFile(&DeviceHandle, 44 FILE_READ_ATTRIBUTES | SYNCHRONIZE, 45 &ObjectAttributes, 46 &IoStatusBlock, 47 FILE_SHARE_ALL, 48 FILE_SYNCHRONOUS_IO_NONALERT); 49 ok_ntstatus(Status, STATUS_SUCCESS); 50 if (!NT_SUCCESS(Status)) 51 { 52 skip("Device '%S': Opening failed\n", NtDeviceName); 53 return; 54 } 55 56 /* Invoke ObjectNameInformation that retrieves the canonical device name */ 57 Status = NtQueryObject(DeviceHandle, 58 ObjectNameInformation, 59 &ObjectNameBuffer, 60 0, 61 &BufferSize1); 62 ok_ntstatus(Status, STATUS_INFO_LENGTH_MISMATCH); 63 64 Status = NtQueryObject(DeviceHandle, 65 ObjectNameInformation, 66 &ObjectNameBuffer, 67 sizeof(OBJECT_NAME_INFORMATION), 68 &BufferSize2); 69 ok_ntstatus(Status, STATUS_BUFFER_OVERFLOW); 70 71 Status = NtQueryObject(DeviceHandle, 72 ObjectNameInformation, 73 &ObjectNameBuffer, 74 sizeof(ObjectNameBuffer), 75 &BufferSize3); 76 ok_ntstatus(Status, STATUS_SUCCESS); 77 78 NtClose(DeviceHandle); 79 80 /* Compare the returned buffer sizes */ 81 82 /* The returned size behaviour changed (when NtQueryObject()'s 83 * input Length is zero) between Windows <= 2003 and Vista+ */ 84 if (g_OsVersion < _WIN32_WINNT_VISTA) 85 ok_eq_ulong(BufferSize1, (ULONG)sizeof(OBJECT_NAME_INFORMATION)); 86 else 87 ok_eq_ulong(BufferSize1, (ULONG)sizeof(OBJECT_NAME_INFORMATION) + ObjectName->MaximumLength); 88 89 ok_eq_ulong(BufferSize2, BufferSize3); 90 ok_eq_ulong(BufferSize3, (ULONG)sizeof(OBJECT_NAME_INFORMATION) + ObjectName->MaximumLength); 91 92 /* Test the name buffer */ 93 ok(ObjectName->Length > 0, "ObjectName->Length == %hu, expected > 0\n", ObjectName->Length); 94 ok_eq_uint(ObjectName->MaximumLength, ObjectName->Length + sizeof(WCHAR)); 95 ok(ObjectName->Buffer[ObjectName->Length / sizeof(WCHAR)] == UNICODE_NULL, 96 "UNICODE_NULL not found at end of ObjectName->Buffer\n"); 97 if (ObjectName->Buffer[ObjectName->Length / sizeof(WCHAR)] != UNICODE_NULL) 98 { 99 skip("ObjectName->Buffer string length check skipped\n"); 100 return; 101 } 102 103 /* Verify that ObjectName->Length doesn't count extra NUL-terminators */ 104 SIZE_T strLen = wcslen(ObjectName->Buffer) * sizeof(WCHAR); 105 ok_eq_size(strLen, (SIZE_T)ObjectName->Length); 106 107 /* Get the full path name of the current executable */ 108 WCHAR ExecutablePath[MAX_PATH]; 109 GetModuleFileNameW(NULL, ExecutablePath, MAX_PATH); 110 111 /* Open the executable file */ 112 HANDLE FileHandle; 113 FileHandle = CreateFileW(ExecutablePath, 114 GENERIC_READ, 115 FILE_SHARE_READ | FILE_SHARE_WRITE, 116 NULL, 117 OPEN_EXISTING, 118 FILE_ATTRIBUTE_NORMAL, 119 NULL); 120 ok(FileHandle != INVALID_HANDLE_VALUE, 121 "File '%S': Opening failed\n", ExecutablePath); 122 if (FileHandle == INVALID_HANDLE_VALUE) 123 { 124 skip("File '%S': Opening failed\n", ExecutablePath); 125 return; 126 } 127 128 /* Query the name of the file */ 129 Status = NtQueryObject(FileHandle, 130 ObjectNameInformation, 131 &ObjectNameBuffer, 132 sizeof(ObjectNameBuffer), 133 &BufferSize3); 134 ok_ntstatus(Status, STATUS_SUCCESS); 135 136 /* Validate that the name starts with "\\Device" */ 137 ok(wcsncmp(ObjectName->Buffer, L"\\Device", 7) == 0, 138 "ObjectName->Buffer: '%S' does not start with '\\Device'\n", 139 ObjectName->Buffer); 140}