2

不幸的是,此链接已关闭,但确实有我的实际问题: 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 值实际上是正确的,我最多可以读取此函数报告的扇区数,并且只有在尝试读取超出它时才会出错。那么为什么其他函数不会报告实际的扇区总数/正确大小呢?物理磁盘是否隐藏了某些功能无法访问的某些区域?

4

1 回答 1

0

GetDiskFreeSpace 报告文件系统卷的大小,在 NTFS 的情况下,它不包括包含卷(分区)末尾的备份扇区的集群。

IOCTL_DISK_GET_LENGTH_INFO 报告实际卷(分区)大小(它不指文件系统卷)。

于 2021-03-26T12:52:02.333 回答