NtQueryVolumeInformationFile and FileFsSectorSizeInformation on Windows 7

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.

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

Peter

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.

@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.

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

@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.

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.?