是否可以在windows中使用python获得对原始设备的写入权限?
这是一种后续行动。我想知道您是否可以在写入模式下访问原始设备(即是否可以在windows中使用python获得对原始设备的写入权限?,python,windows,file-io,Python,Windows,File Io,这是一种后续行动。我想知道您是否可以在写入模式下访问原始设备(即\\.\PhysicalDriveN),如果是这种情况,如何访问 使用Linux,只需使用open(“/dev/sdd”,“w+”)(假设脚本以root权限运行)即可实现写访问。我假设Mac OS的行为类似(输入文件为/dev/diskN) 在Windows下尝试相同的命令(使用相应的路径)时,失败并出现以下错误: IOError: [Errno 22] invalid mode ('w+') or filename: '\\\\.
\\.\PhysicalDriveN
),如果是这种情况,如何访问
使用Linux,只需使用open(“/dev/sdd”,“w+”)
(假设脚本以root权限运行)即可实现写访问。我假设Mac OS的行为类似(输入文件为/dev/diskN
)
在Windows下尝试相同的命令(使用相应的路径)时,失败并出现以下错误:
IOError: [Errno 22] invalid mode ('w+') or filename: '\\\\.\\PhysicalDrive3'
但是,当尝试从PhysicalDrive中读取时,它确实起作用(即使读取了正确的数据)。shell在Windows 7下以管理员权限运行
是否有其他方法可以使用python完成此任务,同时尽可能保持脚本的平台独立性
编辑:
我进一步研究了python为文件处理提供的方法,并偶然发现了这些方法。使用os.open(drive_string,os.O_WRONLY | os.O_BINARY)打开PhysicalDrive
不会返回任何错误。到目前为止,一切顺利。现在,我可以选择使用直接写入此文件描述符,或者使用获取文件对象并以常规方式写入。
不幸的是,这些可能性都不起作用。在第一种情况下(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
正如和在评论中指出的(但我一开始并没有真正理解),解决方案相当简单:您必须以rb+
模式打开设备,这将为(正如我现在发现的那样…)打开设备,而不尝试用新文件替换它(因为该文件实际上是一个物理驱动器,所以无法工作)
写入时,您必须始终一次写入整个扇区(即512字节的倍数),否则将失败
此外,.seek()
命令也只能按扇区跳转。如果您尝试在扇区内查找位置(例如,位置621
),文件对象将跳转到您请求的位置所在的扇区的开头(即,跳转到第二个扇区的开头,字节512
)
可能在Win 7中,您必须执行一些更极端的操作,例如预先使用DeviceIoControl(hVol、FSCTL_LOCK_volume…)锁定磁盘的卷
在Win7中,你不必这样做;使用“rb+”模式打开和写入很好。您是否尝试过在
rb+
或wb
或ab+
中写入它,甚至只是rb
(我读到它需要二进制模式才能在Windows上正常工作)?嗯。听起来您需要写入权限才能从驱动器读取,所以我不认为这是一个许可问题。这可能是我的一个问题。我想自己知道答案。@agf是的,我也试过wb和w+b,但也不起作用。然而,如前所述,阅读(即rb)确实有效!这个问题主要是关于写作模式。啊!非常感谢你。我不知道你实际上可以在rb+
模式下写作(我的意思是,r
代表阅读,不是吗?)。嗯,我现在已经试过了,它确实可以正常工作。再次感谢!谢谢你在这个问题上提供的好信息!我可以按建议使用“rb+”模式打开SD卡的原始访问权限,但我无法写入-我得到“OSError:[Errno 9]错误的文件描述符”。我已经确定我写的是512的倍数。看来我可以成功地从设备读取数据。我正在运行Windows7。你们中有没有其他的信息,这些信息是用来工作的?
>>> 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