Unfortunately this link was closed, but it does have my actual question: Get size of volume on Windows
When I use WMI to get the capacity of a volume in Windows, via Win32_Volume and the Capacity property for my c:\ drive, I get this value: 499513290752
However, when I use
bool Success = DeviceIoControl(
Handle,
IoControl.IOCTL_DISK_GET_LENGTH_INFO,
IntPtr.Zero, //InBuffer
0, //InBuffer Size
OutputBuffer,
(uint)Marshal.SizeOf(OutputLengthInfo),
out BytesReturned,
IntPtr.Zero
);
I get: 499513294848 which is exactly 4096 larger than what WMI reports. I find this is the same for every volume on the hard drive. (This Handle is a SafeFileHandle that is obtained from a call to CreateFile() with a file name of "\\?\Volume{93b1858d-033d-4719-a42a-870d8eb3fe0d}\").
Also, using the following to query the c:\ drive
uint SectorsPerCluster = 0;
uint BytesPerSector = 0;
uint NumberOfFreeClusters = 0;
uint TotalNumberOfClusters = 0;
GetDiskFreeSpace(
Drive,
out SectorsPerCluster,
out BytesPerSector,
out NumberOfFreeClusters,
out TotalNumberOfClusters
);
Reports that there are 121951487 total clusters, 8 sectors per cluster, and 512 bytes per sector, which gives 499513290752 bytes, the same as WMI.
When I use Win32_DiskPartition, it does report the same value as DeviceIoControl for capacity, which is weird (the filename here is "\\?\GLOBALROOT\Device\Harddisk0\Partition1" as one example).
I also get a wildly different number when comparing the value obtained from Win32_DiskDrive and DeviceIoControl function for a physical disk given by "\\.\PhysicalDrive0":
Win32_DiskDrive: 500105249280
IoControl: 500107862016 (a difference of around 2.5 MiB I think)
The Win32_DiskDrive size matches the math of Bytes Per Sector * TotalSectors as reported in the WMI class: 512 bytes per sector * 976768065 total sectors = 500105249280. If the IoControl value is correct, this would mean there are actually 976773168 total sectors. The value from Disk Geometry also supports the 500105249280 disk size.
So, which value/source should I trust, and why are they always 4096 bytes different for volumes? Is the IOCTL_DISK_GET_LENGTH_INFO only valid for partitions and not for physical disks or volumes?
UPDATE: Some more information/clarification. I have also tried to read the physical sectors, and can read beyond the disk size reported by DiskGeometry and Win32_DiskDrive. In this case the IOCTL_DISK_GET_LENGTH_INFO value is actually correct, I can read up to the number of sectors reported by this function, and only get an error when I try to read beyond it. So why would the other functions not report the actual total number of sectors/correct size? Is the physical disk hiding certain areas that some functions can't access?