是否可以在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