Можно ли получить доступ к необработанным устройствам с помощью python с окнами?

Это продолжение следующего этого вопроса. Я хочу знать, можете ли вы получить доступ к необработанным устройствам (т.е. \\.\PhysicalDriveN) в режиме записи, и если это так, как.

Используя Linux, доступ к записи может быть просто достигнут, используя, например, open("/dev/sdd", "w+") (при условии, что script работает с правами root). Я предполагаю, что Mac OS ведет себя аналогично (с /dev/diskN в качестве входного файла).

При попытке выполнить ту же команду под Windows (с соответствующим путем), она не работает со следующей ошибкой:

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

Однако при попытке прочитать из PhysicalDrive он работает (даже правильные данные считываются). Оболочка работает с правами администратора в Windows 7.

Есть ли другой способ выполнить эту задачу с помощью python, сохраняя при этом script как можно более независимую от платформы?

Изменить:

Я немного посмотрел на то, какие методы python предоставляет для обработки файлов и наткнулся на os.open. Открытие PhysicalDrive с помощью os.open(drive_string, os.O_WRONLY|os.O_BINARY) не возвращает ошибки. Все идет нормально. Теперь у меня есть выбор, чтобы написать прямо в этот файловый дескриптор, используя 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

Ответ 1

Как eryksun и agf указано в комментариях (но я не сделал на самом деле получить его сначала), решение довольно просто: вам нужно открыть устройство в режиме rb+, который открывает устройство для обновления (как я выяснил сейчас..), не пытаясь заменить его новым файлом (который не будет работать, потому что файл на самом деле является физическим диском).

При записи вы должны всегда писать целый сектор (т.е. умножить на 512 байт), иначе он терпит неудачу.

Кроме того, команда .seek() также может переходить только по сектору. Если вы попытаетесь найти позицию внутри сектора (например, позиция 621), файл-объект перейдет в начало сектора, в котором находится запрошенная позиция (т.е. к началу второго сектора, байт 512).

Ответ 2

Возможно, в Win 7 вам нужно сделать что-то более экстремальное, например, заранее заблокировать том для диска с помощью DeviceIoControl (hVol, FSCTL_LOCK_VOLUME,...)

В Win 7 вам не обязательно это делать; открытие и запись с режимом "rb +" отлично работают.