可以在Windows中使用Python获取对原始设备的写入访问权限吗?

17 投票
2 回答
15476 浏览
提问于 2025-04-17 00:01

这是对这个问题的进一步讨论。我想知道是否可以以写入模式访问原始设备(也就是 \\.\PhysicalDriveN),如果可以的话,应该怎么做。

在Linux系统中,写入权限可以通过使用例如 open("/dev/sdd", "w+") 来轻松实现(前提是脚本以root权限运行)。我猜Mac OS的行为也差不多(输入文件是 /dev/diskN)。

但是在Windows下尝试同样的命令(用相应的路径)时,会出现以下错误:

IOError: [Errno 22] invalid mode ('w+') or filename: '\\\\.\\PhysicalDrive3'

不过,当尝试从PhysicalDrive读取数据时,它是可以工作的(而且读取的数据也是正确的)。在Windows 7下,命令行是以管理员权限运行的。

有没有其他方法可以用Python完成这个任务,同时尽量保持脚本的跨平台兼容性?

编辑:

我进一步研究了一下Python提供的文件处理方法,发现了os.open。使用 os.open(drive_string, os.O_WRONLY|os.O_BINARY) 打开PhysicalDrive时没有返回错误。到目前为止,一切正常。现在我可以选择直接使用os.write向这个文件描述符写入,或者使用os.fdopen来获取一个文件对象,然后以常规方式写入。

可惜,这些方法都不奏效。在第一种情况下(os.write()),我得到了这个错误:

>>> os.write(os.open("\\\\.\\PhysicalDrive3", os.O_WRONLY|os.O_BINARY), "test")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 22] Invalid argument

在第二种情况下,我可以创建一个具有写入权限的文件对象,但写入操作本身失败了(即使在强制执行 .flush() 后):

>>> g = os.fdopen(os.open("\\\\.\\PhysicalDrive3", os.O_WRONLY|os.O_BINARY), "wb")
>>> g.write("test")
>>> g.flush()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 22] Invalid argument

2 个回答

-1

在Windows 7中,你可能需要做一些更极端的操作,比如事先用DeviceIoControl(hVol, FSCTL_LOCK_VOLUME, ...)来锁定磁盘的卷。

但在Windows 7中,其实你不需要这样做;用'rb+'模式打开和写入就可以正常工作。

19

正如eryksunagf在评论中提到的(我一开始没太明白),解决办法其实很简单:你需要以rb+模式打开设备,这样可以对设备进行更新(我现在才明白这一点..),而不是试图用一个新文件去替代它(这样做是行不通的,因为这个文件实际上是一个物理驱动器)。

在写入数据时,你必须一次写入一个完整的扇区(也就是512字节的倍数),否则就会失败。

另外,.seek()命令也只能按扇区跳转。如果你试图在一个扇区内部寻找某个位置(比如位置621),文件对象会跳到你请求位置所在的扇区的开始位置(也就是第二个扇区的开始,字节512)。

撰写回答