Thefree OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.
I'm trying to protect a file from modification by certain processes using a filesystem mini filter driver. To do this I'm relying on being able to determine the process name and a normalized local file path of the form \Device\HarddiskVolumeN\path\to\file
Currently there is a workaround for the protection that allows access to a protected file using a UNC path like \localhost\c$\protected.txt
Let's say, for example, I want to prevent notepad.exe on the local system from opening that file (I'm not trying to prevent notepad on a remote system from opening the file...I understand I won't be able to get the process name from a remote system).
When notepad opens the file normally I can see the file path normalized with FltGetFileNameInformation and I can get the process name as well since the IRP happens in the context of notepad.
If notepad opens the file by UNC path like \localhost\c$\protected.txt I get an IRP_MJ_NETWORK_QUERY_OPEN in the context of notepad but the file path is the UNC path and I need the \Device\HardiskVolumeN version. If I return FLT_PREOP_DISALLOW_FASTIO the IRP comes back down as an IRP_MJ_CREATE also from notepad.exe but still with the UNC path which I don't need and don't know how to convert.
Eventually I do see an IRP_MJ_CREATE happen on the local file with the path I need but at this point the request is in the context of the SYSTEM process and I can't figure out how to get the original process.
My current thought is I can cache the PID and filename when I see the IRP_MJ_CREATE or IRP_MJ_NETWORK_QUERY_OPEN that happen in the context of notepad. Then, when the IRP_MJ_CREATE happens in the context of SYSTEM, I can lookup in the cache based on filename/share name/etc. since the IRP_MJ_CREATE that happens as system also comes with a PSRV_OPEN_ECP_CONTEXT I have the share name and the socket address in the context of SYSTEM. This has some drawbacks however: I will have to expire entries in this cache, I'll have to ignore the IP/hostname in the path since I can't rely on it being "localhost" (it could be 127.0.0.1, the IP of the machine itself, or anything if the hosts file is modified).
Overall I feel like my idea above is to hacky. There must be a way to: A) make some function call to convert \Device\Mup\localhost\c$\protected.txt to \Device\HarddiskVolumeN\protected.txt myself if it truly is a file on the local system or B) Store the PID with the file in a way where I can query for it in the IRP_MJ_CREATE that happens as SYSTEM after the path has been converted to \Device\HarddiskVolumeN\protected.txt for me.
I'd rather just store the original PID with the file object but I tried that and the file object is different once I'm in the IRP_MJ_CREATE that runs in the context of SYSTEM.