这是这个问题的后续行动。 我想知道你是否可以在写入模式下访问原始设备(即\\.\PhysicalDriveN
),如果是这样的话,怎么样。
使用Linux,写入访问可以通过使用例如open("/dev/sdd", "w+")
(只要脚本以root权限运行)来实现。 我假设Mac OS的行为类似(使用/dev/diskN
作为input文件)。
在Windows下(使用相应的path)尝试相同的命令时,会失败,并显示以下错误:
IOError: [Errno 22] invalid mode ('w+') or filename: '\\\\.\\PhysicalDrive3'
但是,尝试从PhysicalDrive 读取时,它确实有效 (即使读取了正确的数据)。 在Windows 7下,shell正在以pipe理员权限运行。
有没有其他的方式来使用python来完成这个任务,同时仍然保持脚本尽可能平台无关?
我进一步了解了python提供的用于文件处理的方法,并在os.open中偶然发现了这些方法 。 使用os.open(drive_string, os.O_WRONLY|os.O_BINARY)
打开PhysicalDrive不会返回错误。 到现在为止还挺好。 现在我可以select使用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
在第二种情况下,我可以创build一个具有写入权限的文件对象,但是写入本身失败(当然,使用.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
正如eryksun和agf在评论中指出的那样(但我一开始并没有真正了解),解决方案相当简单:您必须在rb+
模式下打开设备,然后打开设备进行更新 (正如我找到的那样现在出来..),而不是试图用一个新的文件(这是行不通的,因为该文件实际上是一个物理驱动器)取代它。
写入时,必须一次写入整个扇区(即512字节的倍数),否则将失败。
另外, .seek()
命令也可以只跳转扇区。 如果你试图在一个扇区内寻找一个位置(例如位置621
),文件对象将跳转到你要求位置的扇区的开始处(即到第二个扇区的开始,字节512
)。
可能在Win 7中,你必须做一些更极端的事情,例如事先用DeviceIoControl(hVol,FSCTL_LOCK_VOLUME,…)来锁定磁盘的卷。
在赢7,你不必这样做; 用“rb +”模式打开和书写工作正常。