Hello,
I’ve posted a question on this list some time ago regarding this and received good advice that helped me put together a first working version of the driver I needed.
Here’s my progress:
I’ve implemented this as an “Image” class upper level filter driver. I started off with the MSFT supplied toaster sample’s generic filter driver and then in FilterEvtIoDeviceControl() I do the following:
pIRP = WdfRequestWdmGetIrp(Request);
pSIRP = IoGetCurrentIrpStackLocation(pIRP);
pIRP->UserBuffer;
__try
{
if (KeGetCurrentIrql() == PASSIVE_LEVEL)
{
// Here we get the thread pointer
pEThread = pIRP->Tail.Overlay.Thread;
// Get the process that owns this thread.
pEProcess = IoThreadToProcess(pEThread);
if( NULL != gGetProcessImageFileName )
{
// Get image name
pImageName = gGetProcessImageFileName( PsGetCurrentProcess() );
}
//process and get rid of filter driver control IOCTLs we have sent
if (strstr(“DrvController.exe”, pImageName))
{
pInputBuffer = (PCHAR) pIRP->AssociatedIrp.SystemBuffer;
setUpWhiteList(pInputBuffer);
WdfRequestComplete(Request, STATUS_CANCELLED);
return;
}
if ( Cancel_All || !isInWhiteList(pImageName) )
{
WdfRequestComplete(Request, STATUS_CANCELLED);
KdPrint((“Request from %s cancelled!\n”, pImageName));
return;
}
}
else
KdPrint((“IRQL is not PASSIVE_LEVEL!\n”));
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
//Something went wrong!
status2 = GetExceptionCode();
KdPrint((“Exception: %lx\n”, status2));
}
As you may notice we use DeviceIoControl() on the user mode side to relay special IOCTLs to the filter - these IOCTLs bear as payload a comma delimited string (whitelist) of process names that are allowed to access imaging devices.
This works great for us but I would very much appreciate any comments you have regarding errors or oversights you find.
Also, we are now thinking of adding an “on-the-fly” whitelisting feature whereby when the driver encounters IRPs coming in from a process with an unknown name it somehow communicates that to our user mode app and that prompts the user for input (i.e. either whitelist or block).
I’ve been thinking that the communication from kernel mode to user mode needed could be implemented as a shared event (as explained in your article here: http://www.osronline.com/article.cfm?id=108) although I am still unsure as to how I would pass the name of the process in question back to user mode (perhaps like this: http://www.osronline.com/article.cfm?article=39).
Still, the biggest problem, I think, is what the driver should do with the IRPs in question in the meantime. I currently tend to think that I should keep them queued until the user responds or a timeout (that defaults to block) occurs, although I am kinda unsure right now as to how exactly this could be done - perhaps like this? http://msdn.microsoft.com/en-us/library/windows/hardware/ff563772(v=vs.85).aspx
Thank you very much in advance for any help and suggestions.
Merry Xmas all!
Alex