Можно ли получить доступ для записи к необработанным устройствам, использующим python с windows? - PullRequest
11 голосов
/ 21 августа 2011

Это своего рода продолжение этого вопроса .Я хочу знать, можете ли вы получить доступ к необработанным устройствам (например, \\.\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 .Открытие 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

Ответы [ 2 ]

14 голосов
/ 22 августа 2011

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

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

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

0 голосов
/ 24 марта 2013

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

В Win 7 вам не нужно этого делать;открытие и запись в режиме 'rb +' работает нормально.

...