不幸的是,此链接已关闭,但确实有我的实际问题: Get size of volume on Windows
当我使用 WMI 在 Windows 中通过 Win32_Volume 和我的 c:\ 驱动器的容量属性获取卷的容量时,我得到这个值:499513290752
但是,当我使用
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
);
我得到: 499513294848 比 WMI 报告的大 4096。我发现这对于硬盘驱动器上的每个卷都是一样的。(此句柄是通过调用 CreateFile() 获得的 SafeFileHandle,文件名为“\\?\Volume{93b1858d-033d-4719-a42a-870d8eb3fe0d}\”)。
此外,使用以下查询 c:\ 驱动器
uint SectorsPerCluster = 0;
uint BytesPerSector = 0;
uint NumberOfFreeClusters = 0;
uint TotalNumberOfClusters = 0;
GetDiskFreeSpace(
Drive,
out SectorsPerCluster,
out BytesPerSector,
out NumberOfFreeClusters,
out TotalNumberOfClusters
);
报告总共有 121951487 个簇,每个簇 8 个扇区,每个扇区 512 字节,即 499513290752 字节,与 WMI 相同。
当我使用 Win32_DiskPartition 时,它确实报告了与 DeviceIoControl 相同的容量值,这很奇怪(这里的文件名是“\\?\GLOBALROOT\Device\Harddisk0\Partition1”作为一个例子)。
在比较“\\.\PhysicalDrive0”给出的物理磁盘的 Win32_DiskDrive 和 DeviceIoControl 函数获得的值时,我也得到了一个完全不同的数字:
Win32_DiskDrive: 500105249280
IoControl:500107862016(我认为差异约为 2.5 MiB)
Win32_DiskDrive 大小与 WMI 类中报告的每扇区字节数 * 总扇区数相匹配:每扇区 512 字节 * 总扇区数 976768065 = 500105249280。如果 IoControl 值正确,这意味着实际上总扇区数为 976773168。Disk Geometry 中的值也支持 500105249280 磁盘大小。
那么,我应该信任哪个值/来源,为什么它们对于卷总是 4096 字节不同?IOCTL_DISK_GET_LENGTH_INFO 是否仅对分区有效,对物理磁盘或卷无效?
更新:更多信息/说明。我还尝试读取物理扇区,并且可以读取超出 DiskGeometry 和 Win32_DiskDrive 报告的磁盘大小。在这种情况下,IOCTL_DISK_GET_LENGTH_INFO 值实际上是正确的,我最多可以读取此函数报告的扇区数,并且只有在尝试读取超出它时才会出错。那么为什么其他函数不会报告实际的扇区总数/正确大小呢?物理磁盘是否隐藏了某些功能无法访问的某些区域?