I am trying to figure out how to get a mouse filter driver to work correctly while using an INF file. The issue is by default INF files add your driver to the RegEdit bellow mouclass
inside of UpperFilter. There also seems to be no way to invert this. This however, is an issue since my driver only works when I manually move my driver above mouclass
. Since there does not seem to be a way to get the INF file to prepend instead of appending I am hoping to find a different solution to my problem. The following will document my issue in detail…
Firstly, I installed the INF file and then started up the driver first by disabling my mouse then renabling it again and secondly by rebooting my machine just to check every edge case. Just to clarify this trial was with the original ordering of appending my driver to mouclass. This resulted in the following output captured by my network debugger.
Starting KMDF
Adding MouFilter Device
KMDF Dispatch Pass Through
Adding MouFilter Device
Adding MouFilter Device
These statements corelate to the function they originated in as depicted in Microsoft Example. Next I manually inverted their order meaning KMDF came before mouclass and then rebooted my VM here is the what got printed to my debugger.
Starting KMDF
Adding MouFilter Device
KMDF Connected Mouse
KMDF Dispatch Pass Through
KMDF Dispatch Pass Through
KMDF Dispatch Pass Through
Adding MouFilter Device
KMDF Connected Mouse
KMDF Dispatch Pass Through
Adding MouFilter Device
KMDF Connected Mouse
KMDF Dispatch Pass Through
KMDF Dispatch Pass Through
KMDF Dispatch Pass Through
KMDF Dispatch Pass Through
I then repeated this process multiple times to make sure it was not a fluke. Based on my very limited knowledge I concluded that moufilter is obfuscating some of the information which is why I receive a lot less info with the appended approach. However, when I prepended it my filter was able to intercept calls before it reaches moufilter. I don’t understand exactly what is going on behind the scenes so maybe someone could elaborate what moufilter does. I assume it is responsible handling my numerous amount of connected mice in order to make a clean exit point of filtered mouse data. If you look at the moufilter example you can see that the MouseHook is registered inside of the Connect Mouse case inside of the AddDevice function. This is a problem because that never gets called in the appended method (I am just talking about USB here and I removed all instances of I8042).
Anyways I tried to rectify this by moving the code that assigns MouFilter_ServiceCallback
to outside of the switch statement because I know the MouFilter_EvtIoInternalDeviceControl
function still gets called with the appended method. This did not create any errors but the MouFilter_ServiceCallback
still never gets called. So far the only way I have been able to get this function to be called is by using the prepended technique. Does anyone happen to know how I can rectify this?
Lastly, here is the code from where I think the issue originates (just so you don’t have to search through the Microsoft Example). Just to restate the issue with the appended approach no “Mouse Connection” is sent which is where I register the call back hence why the call back is never called. That is what needs fixing because the Microsoft Example simply won’t work in its current state.
VOID MouFilter_EvtIoInternalDeviceControl(
IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t OutputBufferLength,
IN size_t InputBufferLength,
IN ULONG IoControlCode
)
{
PDEVICE_EXTENSION devExt;
PCONNECT_DATA connectData;
NTSTATUS status = STATUS_SUCCESS;
WDFDEVICE hDevice;
size_t length;
UNREFERENCED_PARAMETER(OutputBufferLength);
UNREFERENCED_PARAMETER(InputBufferLength);~~~~
PAGED_CODE();
hDevice = WdfIoQueueGetDevice(Queue);
devExt = FilterGetData(hDevice);
switch (IoControlCode) {
// Connect a mouse class device driver to the port driver.
case IOCTL_INTERNAL_MOUSE_CONNECT:
// Only allow one connection.
if (devExt->UpperConnectData.ClassService != NULL) {
status = STATUS_SHARING_VIOLATION;
break;
}
DebugMessage("KMDF Connected Mouse \n");
// Copy the connection parameters to the device extension.
status = WdfRequestRetrieveInputBuffer(Request, sizeof(CONNECT_DATA), (PVOID *) (&connectData), &length);
if (!NT_SUCCESS(status)) {
DebugPrint(("WdfRequestRetrieveInputBuffer failed %x\n", status));
DebugMessage("WdfRequestRetrieveInputBuffer failed %x\n", status);
break;
}
devExt->UpperConnectData = *connectData;
// Hook into the report chain. Everytime a mouse packet is reported to the system, MouFilter_ServiceCallback will be called
connectData->ClassDeviceObject = WdfDeviceWdmGetDeviceObject(hDevice);
connectData->ClassService = MouFilter_ServiceCallback;
break;
case IOCTL_INTERNAL_MOUSE_DISCONNECT:
DebugMessage("KMDF Disconnected Mouse \n");
status = STATUS_NOT_IMPLEMENTED;
break;
case IOCTL_MOUSE_QUERY_ATTRIBUTES:
default:
break;
}
if (!NT_SUCCESS(status)) {
WdfRequestComplete(Request, status);
return;
}
MouFilter_DispatchPassThrough(Request, WdfDeviceGetIoTarget(hDevice));
}