C# Win32\u卷容量4096字节小于Win32 API设备控制IOCTL\u磁盘\u获取长度\u信息

C# Win32\u卷容量4096字节小于Win32 API设备控制IOCTL\u磁盘\u获取长度\u信息,c#,winapi,wmi,volume,deviceiocontrol,C#,Winapi,Wmi,Volume,Deviceiocontrol,不幸的是,这个链接被关闭了,但它确实有我的实际问题: 当我在Windows中使用WMI获取卷的容量时,通过Win32_volume和我的c:\驱动器的capacity属性,我得到以下值: 499513290752 然而,当我使用 bool Success = DeviceIoControl( Handle, IoControl.IOCTL_DISK_GET_LENGTH_INFO, IntPtr.Zero, //InBuf

不幸的是,这个链接被关闭了,但它确实有我的实际问题:

当我在Windows中使用WMI获取卷的容量时,通过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。我发现硬盘上的每个卷都是一样的。(此句柄是通过调用文件名为“\\?\Volume{93b1858d-033d-4719-a42a-870d8eb3fe0d}\”的CreateFile()获得的SafeFileHandle)

另外,使用以下命令查询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\U DiskPartition时,它确实报告了与DeviceIoControl相同的容量值,这很奇怪(例如,这里的文件名是“\\?\GLOBALROOT\Device\Harddisk0\Partition1”)

当比较从Win32\U DiskDrive和DeviceIoControl函数获得的值时,我得到的数字也大不相同,物理磁盘由“\\.\PhysicalDrive0”给出:

Win32_磁盘驱动器:500105249280

IoControl:500107862016(我认为相差约2.5兆)

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

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

更新:
更多信息/澄清。我还尝试读取物理扇区,可以读取超过DiskGeometry和Win32_DiskDrive报告的磁盘大小的数据。在这种情况下,IOCTL\u DISK\u GET\u LENGTH\u INFO值实际上是正确的,我最多可以读取此函数报告的扇区数,并且只有在尝试读取超出它的扇区数时才会收到错误。那么,为什么其他职能部门不报告实际的扇区总数/正确的大小?物理磁盘是否隐藏某些功能无法访问的区域?

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


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

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


IOCTL\u DISK\u GET\u LENGTH\u INFO报告实际卷(分区)大小(它不指文件系统卷)。

没有答案,但我刚刚投票重新打开了@BenVoigt的问题,您链接了这个问题。对于
winapi
标记,它的主题听起来非常贴切,并且它包含了所有相关信息。不知道为什么它一开始就关闭了。那些没有真正阅读问题并关闭它的人,可能是因为它似乎不符合应用于它的其他标记的期望,或者没有代码示例。我发誓这种情况在这里发生得太频繁了,但还不足以让我在Meta上提起(就像我在几个月前问了几个关于如何使用IWebBrowser2和/或WebKitGTK+的问题时,网络程序员因为不关心编写HTML而关闭了这些问题)。更荒谬的是,它在被问到两年后就被关闭了。还有一个问题,如果我猜的话,WMI方法只是告诉你关于C:分区的信息,
DeviceIoControl()
调用告诉你关于整个物理驱动器的信息?假设C:分区是驱动器上唯一的分区并占用驱动器的全部空间,我的猜测是WMI方法告诉您文件系统上的可用空间,即不包括为启动代码保留的第一个群集。我对物理驱动器不太确定,但我认为整个第一轨道只包含MBR。太好了。现在我们有两个相同的问题。没有答案,但我刚刚投票重新打开了你链接的@BenVoigt的问题。对于
winapi
标记,它的主题听起来非常贴切,并且它包含了所有相关信息。不知道为什么它一开始就关闭了。那些没有真正阅读问题并关闭它的人,可能是因为它似乎不符合应用于它的其他标记的期望,或者没有代码示例。我发誓这种情况在这里发生得太频繁了,但还不足以让我在Meta上提起(就像我在几个月前问了几个关于如何使用IWebBrowser2和/或WebKitGTK+的问题时,网络程序员因为不关心编写HTML而关闭了这些问题)。更荒谬的是,它在被问到两年后就被关闭了。还有一个问题,如果我猜的话,WMI方法只是告诉你关于C:分区的信息,
DeviceIoControl()
调用告诉你关于整个物理驱动器的信息?假设C:分区是驱动器上唯一的分区并占用驱动器的全部空间,我的猜测是WMI方法告诉您文件系统上的可用空间,即不包括为启动代码保留的第一个群集。我对物理驱动器不太确定,但我认为整个第一轨道只包含MBR。太好了。现在我们有两个相同的问题。