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: https://www.osr.com/osr-learning-library/
I am trying to obtain the FILE_FS_SECTOR_SIZE_INFORMATION for a disk device using NtQueryVolumeInformationFile in a C# application and I have run into a problem that I can't seem to figure out.
First, some background:
Microsoft introduced FILE_FS_SECTOR_SIZE_INFORMATION to make it easier for developers to query the physical and logical sector sizes. This was introduced in Windows 8, but backported to Windows 7 via hotfix.
Now, the problem:
In short, NtQueryVolumeInformationFile returns STATUS_INVALID_PARAMETER (0xC000000D).
After investigating using Process Monitor, the error comes from FltRequestOperationStatusCallback. The MS Docs page has information about the error, but the information isn't particularly helpful in understanding this particular issue.
Testing and reversing
I wanted to verify that Windows 7 still supported the FileFsSectorSizeInformation (0xB) value for the FsInformationClass parameter in NtQueryVolumeInformationFile. I booted up a Windows 7 VM, fully updated it, and opened up ntkrnlpa.exe in IDA to look at NtQueryVolumeInformationFile:
0xB will indeed pass the parameter check, and looking at the indexed Length value check, the value defined in that array is the same as the result of C#'s Marshal.SizeOf on my FILE_FS_SECTOR_SIZE_INFORMATION structure. So, it appears the Length and FsInformationClass parameters are correct. Otherwise, I would get one of those other status codes.
All development is being done on Windows 10. This works just fine there. No errors. Even after intentionally sabotaging the parameters, I could not reproduce STATUS_INVALID_PARAMETER. The exact same code, when run on Windows 7, returns STATUS_INVALID_PARAMETER. 64bit, 32bit - doesn't matter. I was initially testing in a Hyper-V VM, but also tested on a laptop just to make sure the virtual disk wasn't the issue. Finally, to make sure it wasn't the way I set this up in C#, I tried another FsInformationClass, and it worked! This is clearly a problem with FileFsSectorSizeInformation working differently on Windows 7.
Maybe I'm missing a flag with CreateFile? A permission/token adjustment? (the app already runs as administrator) I've attempted to dig deeper, but things get hard to reverse past IofCallDriver.
I created a small Visual Studio console project with all the necessary pieces of code. If you compile it and run it on Windows 7, it should error. Running on anything newer should yield a "Success!" message. Hopefully someone more experienced in driver development can help pinpoint what's causing this to fail on Windows 7. I'm sure this would fail in a C or C++ project as well.
|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!|
|Developing Minifilters||24 May 2021||Live, Online|
|Writing WDF Drivers||14 June 2021||Live, Online|
|Internals & Software Drivers||27 September 2021||Live, Online|
|Kernel Debugging||15 November 2021||Live, Online|