I looked up the mouse filter driver projects on github, there is a global variable call pendingKey
in every one of them.
- The variable is increased in
DispatchRead
function - and is decreased in
ReadComplete
function
The devices created can be safely detached and deleted if pendingKey
equals 0
when Unload function is called.
NTSTATUS DispatchRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PDEVICE_EXTENSION devExt;
PIO_STACK_LOCATION currentIrpStack;
PIO_STACK_LOCATION nextIrpStack;
currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
nextIrpStack = IoGetNextIrpStackLocation(Irp);
*nextIrpStack = *currentIrpStack;
pendingKey++;
IoSetCompletionRoutine(Irp, ReadComplete, NULL, TRUE, TRUE, TRUE);
return IoCallDriver(((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice, Irp);
}
NTSTATUS ReadComplete(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
{
PMOUSE_INPUT_DATA input = (PMOUSE_INPUT_DATA)Irp->AssociatedIrp.SystemBuffer;
int structnum = Irp->IoStatus.Information / sizeof(MOUSE_INPUT_DATA);
if (Irp->PendingReturned)
{
IoMarkIrpPending(Irp);
}
pendingKey--;
return Irp->IoStatus.Status;
}
VOID Unload(IN PDRIVER_OBJECT DriverObject)
{
LARGE_INTEGER interval = { 0 };
PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject;
interval.QuadPart = -10 * 1000 * 1000;
int count = 0;
while (DeviceObject)
{
IoDetachDevice(((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice);
DeviceObject = DeviceObject->NextDevice;
}
while (pendingKey)
{
KeDelayExecutionThread(KernelMode, FALSE, &interval);
}
DeviceObject = DriverObject->DeviceObject;
while (DeviceObject)
{
IoDeleteDevice(DeviceObject);
DeviceObject = DeviceObject->NextDevice;
}
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "Unloaded\r\n");
}
The Extra Mouse Click Problem
The problem is, after Unload function is called, I have to click the mouse once more or it stucks in the waiting loop,which means pendingkey is bigger than 0.
while (pendingKey)
{
KeDelayExecutionThread(KernelMode, FALSE, &interval);
}
So someone please tell me how can I unload the driver without having to click the mouse.