Files
Carl J. Bialorucki d992cf0ba2 [KMTEST] Skip tests that bugcheck on Vista (#8406)
- [kmtest_drv] Increase timeout period from 10 seconds to 30 seconds. This was needed on my machine because of log spam in the kmtest:IoDeviceInterface test. I also reduced the log spam in that test, making this not necessary. However, I left it in as I figured if I ran into this issue, others may too in the future with other tests.
- [kmtest:ExFastMutex] Skip concurrent fast mutex tests on Vista+. It appears that this was also causing hangs on WS03 x64 so I moved the skip logic there and combined it with the vista+ skip.
- [kmtest:IoDeviceInterface] Change some traces to DPRINTs since it was creating excessive log spam that slowed down the test enough to trigger the previous timeout.
- [kmtest:KeEvent] Skip concurrent event tests on Vista+.
- [kmtest:KeGuardedMutex] Skip on Vista+.
- [kmtest:ObType] Disable making custom object types as this is invalid on Vista+.
- [kmtest:PoIrp] Skip on Vista+ (already skipped on WS03 x64).
- [kmtest:SeInheritance] Skip on Vista+.
2025-10-07 12:17:13 -05:00

263 lines
9.5 KiB
C

/*
* PROJECT: ReactOS kernel-mode tests
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
* PURPOSE: Test for Device Interface functions
* COPYRIGHT: Copyright 2011 Filip Navara <[email protected]>
* Copyright 2011-2015 Thomas Faber <[email protected]>
* Copyright 2021 Mark Jansen <[email protected]>
* Copyright 2021-2024 Oleg Dubinskiy <[email protected]>
*/
/* TODO: Add IoRegisterDeviceInterface testcase */
#include <kmt_test.h>
#include <poclass.h>
#define NDEBUG
#include <debug.h>
/* Predefined GUIDs are required for IoGetDeviceInterfaceAlias and IoOpenDeviceInterfaceRegistryKey.
* Only they can provide the aliases and the needed subkeys, unlike manually declared test GUIDs.
* Since IoRegisterDeviceInterface testcase is missing, it is not possible to register the new device interface
* and get an alias/key handle of it using this test. */
/* Invalid GUID */
static const GUID GUID_NULL = {0x00000000L, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
/* From our ks.h */
static const GUID KSCATEGORY_BRIDGE = {0x085AFF00L, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
static const GUID KSCATEGORY_CAPTURE = {0x65E8773DL, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
static const GUID KSCATEGORY_COMMUNICATIONSTRANSFORM = {0xCF1DDA2CL, 0x9743, 0x11D0, {0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
static const GUID KSCATEGORY_DATACOMPRESSOR = {0x1E84C900L, 0x7E70, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
static const GUID KSCATEGORY_DATADECOMPRESSOR = {0x2721AE20L, 0x7E70, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
static const GUID KSCATEGORY_DATATRANSFORM = {0x2EB07EA0L, 0x7E70, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
static const GUID KSCATEGORY_FILESYSTEM = {0x760FED5EL, 0x9357, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
static const GUID KSCATEGORY_INTERFACETRANSFORM = {0xCF1DDA2DL, 0x9743, 0x11D0, {0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
static const GUID KSCATEGORY_MEDIUMTRANSFORM = {0xCF1DDA2EL, 0x9743, 0x11D0, {0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
static const GUID KSCATEGORY_MIXER = {0xAD809C00L, 0x7B88, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
static const GUID KSCATEGORY_RENDER = {0x65E8773EL, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
static const GUID KSCATEGORY_SPLITTER = {0x0A4252A0L, 0x7E70, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
static const GUID* Types[] =
{
&GUID_NULL,
&KSCATEGORY_BRIDGE,
&KSCATEGORY_CAPTURE,
&KSCATEGORY_COMMUNICATIONSTRANSFORM,
&KSCATEGORY_DATACOMPRESSOR,
&KSCATEGORY_DATADECOMPRESSOR,
&KSCATEGORY_DATATRANSFORM,
&KSCATEGORY_FILESYSTEM,
&KSCATEGORY_INTERFACETRANSFORM,
&KSCATEGORY_MEDIUMTRANSFORM,
&KSCATEGORY_MIXER,
&KSCATEGORY_RENDER,
&KSCATEGORY_SPLITTER,
};
static
VOID
Test_IoOpenDeviceInterfaceRegistryKey(
_In_opt_ PCWSTR SymbolicLink)
{
UNICODE_STRING KeyName, SymbolicLinkName;
HANDLE DeviceInterfaceKey;
NTSTATUS Status;
size_t n;
RtlInitUnicodeString(&SymbolicLinkName, SymbolicLink);
RtlInitUnicodeString(&KeyName, L"ReactOS_kmtest");
/* It's okay to call this from a user process's thread */
Status = IoOpenDeviceInterfaceRegistryKey(&SymbolicLinkName, KEY_CREATE_SUB_KEY, &DeviceInterfaceKey);
if (skip(NT_SUCCESS(Status), "IoOpenDeviceInterfaceRegistryKey() failed: 0x%lx\n", Status))
return;
DPRINT("IoOpenDeviceInterfaceRegistryKey() success: 0x%p\n", DeviceInterfaceKey);
for (n = 0; n < RTL_NUMBER_OF(Types); ++n)
{
HANDLE DeviceInterfaceSubKey;
OBJECT_ATTRIBUTES ObjectAttributes;
/* Try to create the non-volatile subkey to check whether the parent key is volatile */
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
DeviceInterfaceKey,
NULL);
Status = ZwCreateKey(&DeviceInterfaceSubKey,
KEY_WRITE,
&ObjectAttributes,
0,
NULL,
REG_OPTION_NON_VOLATILE,
NULL);
if (skip(NT_SUCCESS(Status), "ZwCreateKey() failed to create a subkey: %d 0x%lx\n", n, Status))
continue;
DPRINT("ZwCreateKey(): successfully created subkey: %d 0x%p\n", n, DeviceInterfaceSubKey);
ZwDeleteKey(DeviceInterfaceSubKey);
ZwClose(DeviceInterfaceSubKey);
}
ZwClose(DeviceInterfaceKey);
}
static
VOID
Test_IoGetDeviceInterfaceAlias(
_In_opt_ PCWSTR SymbolicLink)
{
UNICODE_STRING SymbolicLinkName;
size_t n;
RtlInitUnicodeString(&SymbolicLinkName, SymbolicLink);
for (n = 0; n < RTL_NUMBER_OF(Types); ++n)
{
UNICODE_STRING AliasSymbolicLinkName;
NTSTATUS Status = IoGetDeviceInterfaceAlias(&SymbolicLinkName, Types[n], &AliasSymbolicLinkName);
if (skip(NT_SUCCESS(Status), "IoGetDeviceInterfaceAlias(): fail: %d 0x%x\n", n, Status))
continue;
DPRINT("IoGetDeviceInterfaceAlias(): success: %d %wZ\n", n, &AliasSymbolicLinkName);
/* Test IoOpenDeviceInterfaceRegistryKey with alias symbolic link too */
Test_IoOpenDeviceInterfaceRegistryKey(AliasSymbolicLinkName.Buffer);
RtlFreeUnicodeString(&AliasSymbolicLinkName);
}
}
static
VOID
Test_IoSetDeviceInterfaceState(
_In_opt_ PCWSTR SymbolicLink)
{
UNICODE_STRING SymbolicLinkName;
size_t n;
RtlInitUnicodeString(&SymbolicLinkName, SymbolicLink);
for (n = 0; n < RTL_NUMBER_OF(Types); ++n)
{
NTSTATUS Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
if (skip(NT_SUCCESS(Status), "IoSetDeviceInterfaceState(): failed to enable interface: %d 0x%x\n", n, Status))
continue;
DPRINT("IoSetDeviceInterfaceState(): successfully enabled interface: %d %wZ\n", n, &SymbolicLinkName);
}
}
static
VOID
Test_IoGetDeviceInterfaces(
_In_ const GUID* Guid)
{
NTSTATUS Status;
PZZWSTR SymbolicLinkList;
PWSTR SymbolicLink;
UNICODE_STRING GuidString;
Status = IoGetDeviceInterfaces(Guid, NULL, DEVICE_INTERFACE_INCLUDE_NONACTIVE, &SymbolicLinkList);
RtlStringFromGUID(Guid, &GuidString);
if (skip(NT_SUCCESS(Status), "IoGetDeviceInterfaces failed with status 0x%x for '%wZ'\n", Status, &GuidString))
{
RtlFreeUnicodeString(&GuidString);
return;
}
DPRINT("IoGetDeviceInterfaces '%wZ' results:\n", &GuidString);
RtlFreeUnicodeString(&GuidString);
for (SymbolicLink = SymbolicLinkList;
SymbolicLink[0] != UNICODE_NULL;
SymbolicLink += wcslen(SymbolicLink) + 1)
{
DPRINT("Symbolic Link: %S\n", SymbolicLink);
Test_IoGetDeviceInterfaceAlias(SymbolicLink);
Test_IoOpenDeviceInterfaceRegistryKey(SymbolicLink);
Test_IoSetDeviceInterfaceState(SymbolicLink);
}
ExFreePool(SymbolicLinkList);
}
static UCHAR NotificationContext;
static DRIVER_NOTIFICATION_CALLBACK_ROUTINE NotificationCallback;
static
NTSTATUS
NTAPI
NotificationCallback(
_In_ PVOID NotificationStructure,
_Inout_opt_ PVOID Context)
{
PDEVICE_INTERFACE_CHANGE_NOTIFICATION Notification = NotificationStructure;
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE Handle;
ok_irql(PASSIVE_LEVEL);
ok_eq_pointer(Context, &NotificationContext);
ok_eq_uint(Notification->Version, 1);
ok_eq_uint(Notification->Size, sizeof(*Notification));
/* symbolic link must exist */
DPRINT("Interface change: %wZ\n", Notification->SymbolicLinkName);
InitializeObjectAttributes(&ObjectAttributes,
Notification->SymbolicLinkName,
OBJ_KERNEL_HANDLE,
NULL,
NULL);
Status = ZwOpenSymbolicLinkObject(&Handle, GENERIC_READ, &ObjectAttributes);
ok_eq_hex(Status, STATUS_SUCCESS);
if (!skip(NT_SUCCESS(Status), "No symbolic link\n"))
{
Status = ObCloseHandle(Handle, KernelMode);
ok_eq_hex(Status, STATUS_SUCCESS);
}
return STATUS_SUCCESS;
}
static
VOID
Test_IoRegisterPlugPlayNotification(VOID)
{
NTSTATUS Status;
PVOID NotificationEntry;
Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
(PVOID)&GUID_DEVICE_SYS_BUTTON,
KmtDriverObject,
NotificationCallback,
&NotificationContext,
&NotificationEntry);
ok_eq_hex(Status, STATUS_SUCCESS);
if (!skip(NT_SUCCESS(Status), "PlugPlayNotification not registered\n"))
{
Status = IoUnregisterPlugPlayNotification(NotificationEntry);
ok_eq_hex(Status, STATUS_SUCCESS);
}
}
START_TEST(IoDeviceInterface)
{
size_t n;
for (n = 0; n < RTL_NUMBER_OF(Types); ++n)
{
Test_IoGetDeviceInterfaces(Types[n]);
}
/* Test the invalid case behaviour */
Test_IoGetDeviceInterfaceAlias(NULL);
Test_IoOpenDeviceInterfaceRegistryKey(NULL);
Test_IoSetDeviceInterfaceState(NULL);
Test_IoRegisterPlugPlayNotification();
}