I am trying to create an upper filter driver for a usb mouse. To do this I used the KMDF template in Visual Studio and I am testing the driver on a Windows 10 Vm (VmWare). Then on the Vm after turning on test signing mode I would install the inf file which adds my driver to %windir%\system32\drivers it also creates a service directory and adds the drivers name to the mouse’s upperfilter regedit. One issue with this is that it adds my driver bellow mouclass
when it needs to add it above it any ideas on how I can invert this? For now I just manually move it above so that I can continue on testing
Anyways at this point I do sc query kmdf
and I can see my driver is installed and that its disabled. I can manually start it from console but that does not actually make the filter driver work (I know this because I only receive debug messages originating from the DriverEntry function). I assume that my driver requires a reboot for it to actually be injected into the mouse software stack. However, this is where my main issues occur. Rebooting bricks the whole OS with a BSOD and I receive a Kernel_Security_Check_Failure
. I have been looing this up for a while now and I have not found any resources describing possible causes or solutions. I have had this happen to me multiple times one time with basically the same code as MouseFilter and the second time with a bare bones driver that just contained the the DriverEntry function. From what I read excluding functions in your filter driver means the kernel will just pass it on down the line. I also know that sometimes not returning success in a function (for example in AddDevice) can cause the kernel to not pass it down the line which in my case would be to mouclass. But having said that I don’t know what is wrong in this particular situation because in the past I had an issue where my mouse would just not work but breaking my whole OS is so much worse.
I have looked at countless mouse filter drivers but I have not found a single one that uses INF files that actually works. If you have any links to ones that I can use as a template please let me know. Anyways here is my INF file, DriverEntry function, and AddDevice function in case you were curious.
[Version]
Signature="$WINDOWS NT$"
Class=Mouse
ClassGuid= %ClassGUIDToFilter%
Provider=%Provider%
CatalogFile=KMDF.cat
DriverVer=03/15/2023, 1.0.0.0
PnpLockdown=1
[DestinationDirs]
DefaultDestDir = 12 ; DIRID_DRIVERS
[DefaultInstall.NT]
CopyFiles = KMDF.CopyFiles
Addreg = KMDF.AddReg
[KMDF.AddReg]
"HKLM", System\CurrentControlSet\Control\Class\%ClassGUIDToFilter%, "UpperFilters", 0x00010008, %DriverName%
[KMDF.CopyFiles]
KMDF.sys
[DefaultInstall.NT.Services]
Include = MSMOUSE.INF
Needs = HID_Mouse_Inst.NT.Hw
AddService = KMDF, , KMDF.Service.Install
;[ControlFlags]
; We don't want our device to be installable via the non-PnP hardware dialogs
;ExcludeFromSelect = *
; ================= Class section =====================
[SourceDisksNames]
1 = %DiskName%
[SourceDisksFiles]
KMDF.sys = 1
; -------------- KMDF driver install sections https://learn.microsoft.com/en-us/windows-hardware/drivers/install/inf-addservice-directive
[KMDF.Service.install]
DisplayName = %KMDF.SvcDesc%
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
StartType = 3 ; SERVICE_DEMAND_START
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
ServiceBinary = %12%\KMDF.sys
; -------------- String definitions
[Strings]
Provider = "u/IgnoreException"
; Mfg names
IgnoreException = "IgnoreException"
; Service names
KMDF.SvcDesc = "KMDF Service"
; Media names
DiskName = "KMDF Driver Disk"
ClassGUIDToFilter = "{4d36e96f-e325-11ce-bfc1-08002be10318}"
ServiceDescription = "Generic Upper Filter"
moufiltr.DeviceDesc = "Mouse Filter Sample Device"
ServiceName = "KMDF"
DriverName = "KMDF"
DiskId1 = "Genric Upper Filter Installation Disk"
; Standard defs
SPSVCINST_TAGTOFRONT = 0x00000001
SPSVCINST_ASSOCSERVICE= 0x00000002
SERVICE_KERNEL_DRIVER = 1
SERVICE_BOOT_START = 0
SERVICE_SYSTEM_START = 1
SERVICE_AUTO_START = 2
SERVICE_ERROR_NORMAL = 1
SERVICE_ERROR_IGNORE = 0
REG_EXPAND_SZ = 0x00020000
REG_DWORD = 0x00010001
REG_SZ = 0x00000000
#ifdef ALLOC_PRAGMA
#pragma alloc_text (INIT, DriverEntry)
#pragma alloc_text (PAGE, MouFilter_EvtDeviceAdd)
#endif;
NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
{
WDF_DRIVER_CONFIG config;
NTSTATUS status;
WDFDRIVER driver;
// Initialize WPP Tracing
DebugMessage(" ");
DebugMessage("Starting KMDF");
DebugMessage(" ");
DebugPrint("Mouse Filter Driver Sample - Driver Framework Edition.\n");
DebugPrint(("Built %s %s\n", __DATE__, __TIME__));
WDF_DRIVER_CONFIG_INIT(&config, MouFilter_EvtDeviceAdd);
status = WdfDriverCreate(DriverObject, RegistryPath, WDF_NO_OBJECT_ATTRIBUTES, &config, &driver);
if (!NT_SUCCESS(status)) {
return status;
}
return status;
}
#ifdef ALLOC_PRAGMA
#pragma alloc_text (PAGE, MouFilter_EvtDeviceAdd)
#pragma alloc_text (PAGE, MouFilter_EvtIoInternalDeviceControl)
#endif
#pragma warning(push)
#pragma warning(disable:4055) // type case from PVOID to PSERVICE_CALLBACK_ROUTINE
#pragma warning(disable:4152) // function/data pointer conversion in expression
NTSTATUS MouFilter_EvtDeviceAdd(IN WDFDRIVER Driver, IN PWDFDEVICE_INIT DeviceInit)
{
WDF_OBJECT_ATTRIBUTES deviceAttributes;
NTSTATUS status;
WDFDEVICE hDevice;
WDF_IO_QUEUE_CONFIG ioQueueConfig;
UNREFERENCED_PARAMETER(Driver);
PAGED_CODE();
DebugMessage(" ");
DebugMessage("Adding MouFilter Device");
DebugMessage(" ");
DebugPrint(("Enter FilterEvtDeviceAdd \n"));
// Tell the framework that you are filter driver. Framework takes care of inherting all the device flags & characterstics from the lower device you are attaching to.
WdfFdoInitSetFilter(DeviceInit);
WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_MOUSE);
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_EXTENSION);
// Create a framework device object. This call will in turn create a WDM deviceobject, attach to the lower stack and set the appropriate flags and attributes.
status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &hDevice);
if (!NT_SUCCESS(status)) {
DebugPrint(("WdfDeviceCreate failed with status code 0x%x\n", status));
return status;
}
WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig, WdfIoQueueDispatchParallel);
// Framework by default creates non-power managed queues for filter drivers.
ioQueueConfig.EvtIoInternalDeviceControl = MouFilter_EvtIoInternalDeviceControl;
status = WdfIoQueueCreate(hDevice, &ioQueueConfig, WDF_NO_OBJECT_ATTRIBUTES, WDF_NO_HANDLE // pointer to default queue
);
if (!NT_SUCCESS(status)) {
DebugPrint(("WdfIoQueueCreate failed 0x%x\n", status));
return status;
}
return status;
}