WMI:Win32_DiskDrive获取物理磁盘dri上的总扇区

2024-09-28 22:21:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我曾尝试使用Win32_DiskDrive来获取磁盘的最大总扇区,但它们都返回了不正确的值。我使用HxD,这个程序返回准确的值。我试着用fdisk得到Linux中的总扇区,它也能准确地返回。在

我注意到在Win32_DiskDrive MSDN 中有一个注释,如下所示:

the value for this property is obtained through extended functions of BIOS interrupt 13h. The value may be inaccurate if the drive uses a translation scheme to support high-capacity disk sizes. Consult the manufacturer for accurate drive specifications.

但我不明白这是什么意思?如何解决这个问题呢?在

更新1:

这是我的python脚本的剪贴代码。在

必需:PythonPyWin32WMI

import wmi

c = wmi.WMI()
for diskDrive in c.query("SELECT * FROM Win32_DiskDrive"):
    print diskDrive.Name, "\nTotal Sector: ", diskDrive.TotalSectors

更新2:

根据要求,以下是检测到HxD总扇区的WMI片段。在

  • WMI:625137345(顶部)
  • HxD:625142448(底部)

Sector Difference Screenshot

更新3:

如果有人感兴趣,您也可以在自己的计算机上尝试,看看Win32磁盘驱动器是否报告准确的结果。我在其他许多计算机上尝试过这个方法,但结果都不准确。在

若要尝试,请安装PythonPyWin32WMI

非常感谢


Tags: the程序forvalue计算机drivewmi磁盘
2条回答

你说这个片段不适合某个硬盘?你能告诉我们这个硬盘的详细情况吗?你怎么知道它是不正确的。在

但是,请尝试使用纯winapi方法。可以使用DeviceIoControl轻松地完成这项工作。参见cpp中的complete code listing。在

我知道有一种用python编写c++的方法,祝你好运:)

WMI报告驱动器比实际大小小几MB。我认为这与Windows如何处理汽缸/磁头/扇区有关。在

我的解决方案是读取超过报告的驱动器大小的末尾,直到出现错误:

import wmi
disks = wmi.WMI().Win32_DiskDrive(MediaType="Removable Media")
for disk in disks:
    disk_size = int(disk.size)
    sector_size = disk.BytesPerSector
    print(disk.name, "reported size:", disk_size)
    with open(disk.name, "rb") as f:
        f.seek(disk_size)
        while True:
            try:
                f.read(sector_size)
                disk_size += sector_size
            except PermissionError:
                break
    print(disk.name, "readable size:", disk_size)

对于两个不同的32GB SD卡,我得到以下结果:

^{pr2}$

但是,实际的驱动器实际上还有1024到2048个字节,我们仍然无法读取,我不确定如何获取它们。但是,这比我们之前丢失的几个MB要好。在

编辑:似乎是buffering导致了读取最后几个字节的问题。如果我这样做,我可以读取剩余的字节open(disk.name, "rb", buffering=0)。但是,这是非常慢的(大约1MB/秒,相当于其中一个驱动器大约7秒)。可能有一种很好的混合方法,只使用buffering=0读取最后几个字节,其余时间使用默认缓冲。在

\\.\PHYSICALDRIVE2 reported size: 31683778560
\\.\PHYSICALDRIVE2 readable size: 31691112448 (with buffering=0)
\\.\PHYSICALDRIVE14 reported size: 31437020160
\\.\PHYSICALDRIVE14 readable size: 31439454208 (with buffering=0)

编辑2:您可以使用read1获得最后几个字节,而不需要用buffering=0打开文件。因此,要获得实际磁盘大小,可以执行以下操作:

reported_size = disk.size
f.seek(reported_size)
while True:
    try:  # Read beyond the reported size
        f.read(sector_size)
    except PermissionError:
        easily_readable_size = f.tell()
        try:  # Get the last few bytes using read1 (unbuffered)
            for i in range(128):  # Test up to this many additional sectors
                f.read1(self.sector_size)
        except PermissionError:
            actual_size = f.tell()
            break

注意,我认为您可能不总是能够f.read直到easily_readable_size,因为内部缓冲区的对齐方式可能并不总是相同的(?)。我把这个值减少了io.DEFAULT_BUFFER_SIZE,这样更安全一些。然后我用我自己的函数重写f.read,该函数将上述内容组合起来,从而在整个磁盘上透明地{}。这样一来,f.read就和你期望的一样工作。在

相关问题 更多 >