Recently I faced a problem regarding HLK testing against WDM drivers. When I perform HLK tests against the KMDF driver, every test passes. But when I do the same for the WDM driver some of the PNP tests fail.
At first, I thought there must be something wrong with the code. But while I was debugging the driver with WinDbg I found nothing suspicious.
So I went to https://github.com/microsoft/Windows-driver-samples/tree/main/general/ioctl/wdm and compiled this sample. And I was surprised that this sample also can not pass the same PNP tests on HLK.
For example, the test PNPSurpriseRemoveAndRestartDevice always fails with the error
PNP_VetoLegacyDevice.
Also, I noticed the message
WDTF_PNP : EDT driver is not installed on the Target
right before the failure. Then I thought it might be because of the absent IRP_MJ_PNP handler.
So I slightly modified the code:
#include <ntddk.h>
#include "Driver.h"
IO_REMOVE_LOCK RemoveLock;
NTSTATUS MyWDMDevice_CreateClose(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
UNREFERENCED_PARAMETER(DeviceObject);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS MyWDMDevice_IoControl(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
UNREFERENCED_PARAMETER(DeviceObject);
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
ULONG code = irpStack->Parameters.DeviceIoControl.IoControlCode;
switch (code) {
// Add your specific IOCTL handling here
default:
Irp->IoStatus.Status = STATUS_SUCCESS;
break;
}
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS MyWDMDevice_PnP(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
UNREFERENCED_PARAMETER(DeviceObject);
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status = STATUS_SUCCESS;
switch (irpStack->MinorFunction) {
case IRP_MN_START_DEVICE:
IoInitializeRemoveLock(&deviceExtension->RemoveLock, '1ock', 0, 0);
Irp->IoStatus.Status = STATUS_SUCCESS;
break;
case IRP_MN_REMOVE_DEVICE:
Irp->IoStatus.Status = STATUS_SUCCESS;
IoReleaseRemoveLockAndWait(&deviceExtension->RemoveLock, Irp);
IoDetachDevice(DeviceObject);
IoDeleteDevice(DeviceObject);
break;
case IRP_MN_SURPRISE_REMOVAL:
Irp->IoStatus.Status = STATUS_SUCCESS;
IoReleaseRemoveLockAndWait(&deviceExtension->RemoveLock, Irp);
break;
case IRP_MN_QUERY_LEGACY_BUS_INFORMATION:
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
break;
default:
break;
}
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) {
UNREFERENCED_PARAMETER(RegistryPath);
NTSTATUS status;
UNICODE_STRING DeviceName;
UNICODE_STRING SymLinkName;
RtlInitUnicodeString(&DeviceName, L"\\Device\\TSTDVCE");
RtlInitUnicodeString(&SymLinkName, L"\\DosDevices\\TDVC");
DriverObject->DriverUnload = NULL;
DriverObject->MajorFunction[IRP_MJ_CREATE] = MyWDMDevice_CreateClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = MyWDMDevice_CreateClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MyWDMDevice_IoControl;
DriverObject->MajorFunction[IRP_MJ_PNP] = MyWDMDevice_PnP;
PDEVICE_OBJECT DeviceObject;
status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), &SymLinkName,
FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &DeviceObject);
if (!NT_SUCCESS(status)) {
return status;
}
DeviceObject->Flags |= DO_BUFFERED_IO;
IoCreateSymbolicLink(&SymLinkName, &DeviceName);
PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
RtlZeroMemory(deviceExtension, sizeof(DEVICE_EXTENSION));
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
return STATUS_SUCCESS;
}
Unfortunately, it didn't help. And I still have the same errors. The Static Driver Verifier also found nothing related. No errors while debugging, nor while testing the driver with install/uninstall by devcon or Device Manager
The driver has to be WDM because it has to work with a file system and registry using absolute paths.
Environment/Tools I use for the driver development:
- Win11,
- VS2019 Comunity (16.7),
- HLKStudio (10.0.22621.2428),
- PlayList (HLK Version 22H2 CompatPlaylist x64 ARM64)}
