Win32_Volume容量比Win32 API小4096字节DeviceIOControl

本文关键字:Win32 4096字节 DeviceIOControl API Volume 容量 | 更新日期: 2023-09-27 18:01:27

不幸的是这个链接是关闭的,但它确实有我的实际问题:获取Windows上的卷大小

当我使用WMI在Windows中获取卷的容量时,通过Win32_Volume和我的c:'驱动器的capacity属性,我得到这个值: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。我发现这对硬盘上的每个卷都是一样的。(这个句柄是一个SafeFileHandle,通过调用文件名为"''?'Volume{93b1858d-033d-4719-a42a-870d8eb3fe0d}'"的CreateFile()获得)

同样,使用以下命令查询c:' drive

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"作为一个例子)。

当比较从Win32_DiskDrive和DeviceIoControl函数为"''.'PhysicalDrive0"给出的物理磁盘获得的值时,我也得到了一个完全不同的数字:

Win32_DiskDrive: 500105249280

IoControl: 500107862016(我认为差异约2.5 MiB)

Win32_DiskDrive大小匹配WMI类中报告的每扇区字节数*总扇区:每扇区512字节* 976768065总扇区= 500105249280。如果IoControl值是正确的,这意味着实际上有976773168个扇区。磁盘几何的值也支持500105249280磁盘大小。

那么,我应该信任哪个值/源,为什么它们总是4096字节不同的卷?IOCTL_DISK_GET_LENGTH_INFO是否只对分区有效,而对物理磁盘或卷无效?

更新:更多的信息/澄清。我还尝试读取物理扇区,并且可以读取超出DiskGeometry和Win32_DiskDrive报告的磁盘大小。在这种情况下,IOCTL_DISK_GET_LENGTH_INFO值实际上是正确的,我可以读取这个函数报告的扇区数量,只有当我试图读取超出它时才会得到一个错误。那么,为什么其他函数不报告扇区的实际总数/正确大小呢?物理磁盘是否隐藏了某些功能无法访问的某些区域?

Win32_Volume容量比Win32 API小4096字节DeviceIOControl

GetDiskFreeSpace报告文件系统卷大小,对于NTFS,不包括卷(分区)末端包含备份扇区的集群。

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