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

Home NTFSD
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: https://www.osr.com/osr-learning-library/


NtQueryVolumeInformationFile and FileFsSectorSizeInformation on Windows 7

EatonEaton Member Posts: 6

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.

Comments

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 7,900

    (As this is related to file systems and file system filtering, I've moved this post from NTDEV to NTFSD)

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • Gabriel_BerceaGabriel_Bercea Member - All Emails Posts: 482

    Looking at the fastfat code it implements this using FsRtlGetSectorSizeInformation ( check FatQueryFsSectorSizeInfo), which I assumed it would do, but this routine is not available in Windows 7. So I am guessing the "official" Windows 7 build does the FsRtlGetSectorSizeInformation inline in the handling of this information class.
    Unfortunately my build of Windows 7 that I have running on my VM returns STATUS_INVALID_INFO_CLASS which means I don't have the hotfix.
    My guess is that the hotfix simply implements FsRtlGetSectorSizeInformation and calls this. If so, you could try this yourself from a test driver.

    You could also try and mount different volumes with different FSes on your VM and see if it fails on all of them.

    Alternatively you could try using IOCTL_STORAGE_QUERY_PROPERTY with the StorageAccessAlignmentProperty property ID and look at the STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR which is returned in the output buffer. You should have the BytesPerLogicalSector and BytesPerPhysicalSector which you could use for your convenience.
    There is not much you have to change in your C# code as well. Replace the NtQueryVolumeInformationFile with DeviceIoControl having the control code as IOCTL_STORAGE_QUERY_PROPERTY and the proper input buffer and output buffer. I think you will find plenty of samples online about this.

    Hope this helps,
    Gabriel.

    Cheers,
    Gabriel

  • EatonEaton Member Posts: 6

    @Gabriel_Bercea said:
    Looking at the fastfat code it implements this using FsRtlGetSectorSizeInformation ( check FatQueryFsSectorSizeInfo), which I assumed it would do, but this routine is not available in Windows 7. So I am guessing the "official" Windows 7 build does the FsRtlGetSectorSizeInformation inline in the handling of this information class.
    Unfortunately my build of Windows 7 that I have running on my VM returns STATUS_INVALID_INFO_CLASS which means I don't have the hotfix.
    My guess is that the hotfix simply implements FsRtlGetSectorSizeInformation and calls this. If so, you could try this yourself from a test driver.

    You could also try and mount different volumes with different FSes on your VM and see if it fails on all of them.

    Alternatively you could try using IOCTL_STORAGE_QUERY_PROPERTY with the StorageAccessAlignmentProperty property ID and look at the STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR which is returned in the output buffer. You should have the BytesPerLogicalSector and BytesPerPhysicalSector which you could use for your convenience.
    There is not much you have to change in your C# code as well. Replace the NtQueryVolumeInformationFile with DeviceIoControl having the control code as IOCTL_STORAGE_QUERY_PROPERTY and the proper input buffer and output buffer. I think you will find plenty of samples online about this.

    Hope this helps,
    Gabriel.

    Thanks for the response!


    For my use-case, how the file system drivers implement this should not matter. I will be using this on blank disks without any file systems on them, which is why I didn't initially post this in the file systems forum.


    I have tested blank disks without any file systems on Windows 7 and the error code is the same.


    IOCTL_STORAGE_QUERY_PROPERTY - yes, I know about this. FsRtlGetSectorSizeInformation actually does this internally to put the sector sizes into FILE_FS_SECTOR_SIZE_INFORMATION. However, I wanted to use NtQueryVolumeInformationFile and FileFsSectorSizeInformation because is returns more information that may be useful, and all in one, convenient function. I'm just trying to figure out why it doesn't work here on Windows 7, where it clearly should.


    Also, I did try a checked/debug Windows 7 build. Unfortunately, the hotfix cannot be applied to it, so it was a dead end.

  • Gabriel_BerceaGabriel_Bercea Member - All Emails Posts: 482

    Also, the hotfix is not longer available, or at least I was not able to find it from the link and download it.

    Cheers,
    Gabriel

  • EatonEaton Member Posts: 6

    @Gabriel_Bercea said:
    Also, the hotfix is not longer available, or at least I was not able to find it from the link and download it.

    Visit Windows Update and it'll download it. That's what I did since it did indeed say it wasn't available to download individually anymore. Probably just wrapped into one of their newer updates.

  • EatonEaton Member Posts: 6

    Ultimately, I just decided to scrap this and use IOCTL_STORAGE_QUERY_PROPERTY to get STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR. As expected, that works fine on Windows 7.

    I would still be interested in hearing other peoples' thoughts on why my approach for getting FILE_FS_SECTOR_SIZE_INFORMATION isn't working.😬

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