Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Before Posting...
Please check out the Community Guidelines in the Announcements and Administration Category.

More Info on Driver Writing and Debugging

The free 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.

Check out The OSR Learning Library at:

Uniformity of file paths in kernel-mode

KeternaKeterna Member Posts: 18

Dear board writers !

I'm using PsSetCreateProcessNotifyRoutineEx and a minifilter to restrict access to certain kind of files/pcoesses. When my callback of process creation is triggered, the file path received in parameter has the form of something like \??\C:\Users\root\Desktop\Service.exe. When one of the callbacks of the minifilter is triggered, I use the function FltGetFileNameInformation to retrieve the path of the file, which has the form of \Device\HarddiskVolume4\Users\root\Desktop\Service.exe.

Is there an idiomatic way to represent file paths kernel-side ? How can I unify those two data sources to have a same kind of path formatting ?

Thanks for your help !


  • rod_widdowsonrod_widdowson Member - All Emails Posts: 1,132

    \??\c: is a symbolic link. There used to be (and may still be) a program called ObjDir to help you understand all that stuff.

    Pragmatically the easiest way is to open the file, normalize the name and take what the filter manager gives you.

    You might also want to worry about volume guids which are persistent.

  • Bill_WandelBill_Wandel Member - All Emails Posts: 236

    One way is to open and query the symbolic link with ZwOpenSymbolicLinkObject/ZwQuerySymbolicLinkObject. Another way is to get a handle to the new process and call ZwQueryInformationProcess to get the physical path.

    Bill Wandel

  • KeternaKeterna Member Posts: 18
    edited November 2019

    Hey, many thanks for your answers!

    I need the physical path when the callback of PsSetCreateProcessNotifyRoutineEx is triggered, so I can add the process in a collection. As this callback occurs before the finalization of the process creation, ZwQueryInformationProcess does not work unfortunately.

    After your suggestion I tried the program WinObj and effectively, it provides a nice GUI to visualize those paths! I tried to convert the symbolic link into its physical path using ZwOpenSymbolicLinkObject/ZwQuerySymbolicLinkObject, but I cannot make it work for a path with the format **\??**. Here is the code:

            OBJECT_ATTRIBUTES  objAttr;
            HANDLE f;
            InitializeObjectAttributes(&objAttr, (PUNICODE_STRING)CreateInfo->ImageFileName,
            NTSTATUS status = ZwOpenSymbolicLinkObject(&f, GENERIC_READ, &objAttr);

    Unfortunately, ZwOpenSymbolicLinkObject returns STATUS_OBJECT_TYPE_MISMATCH. The image file name is equal to \??\C:\Windows\system32\notepad.exe. I tried to use a static string like \SystemRoot and it works. I guess it is something related with my symbolic path ?

    @Rod: Do you mean I should rather rely on a volume GUID than storing the first part of the path (\Device\HarddiskVolume4 for example) ?

    Thanks for your help !

    Post edited by Keterna on
  • Bill_WandelBill_Wandel Member - All Emails Posts: 236

    Actually ZwQueryInformationProcess does work.
    Use ObOpenObjectByPointer with the supplied EPROCESS. Use the resulting handle in ZwQueryInrormationProcess.

    Bill Wandel

  • rod_widdowsonrod_widdowson Member - All Emails Posts: 1,132

    Do you mean I should rather rely on a volume GUID than storing the first part of the path (\Device\HarddiskVolume4 for example) ?

    I mean that you might want to think about it, depending on your precise requirements....

  • KeternaKeterna Member Posts: 18

    Mr Wandel,

    You ended hours of headaches with a single function, THANK YOU !

    My error is that I was passing the process id as an argument to ZwQueryInformationProcess instead of a real handle of the proces (!!).

    Thanks again and enjoy your weekend <3

  • Scott_Noone_(OSR)Scott_Noone_(OSR) Administrator Posts: 3,302

    You can also call FltGetFileNameInformationUnsafe on CreateInfo->FileObject. This gives you the ability to normalize the path using standard FltMgr options.


Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Kernel Debugging 30 Mar 2020 OSR Seminar Space
Developing Minifilters 15 Jun 2020 LIVE ONLINE
Writing WDF Drivers 22 June 2020 LIVE ONLINE
Internals & Software Drivers 28 Sept 2020 Dulles, VA