2016-10-25 5 views
2

Ich versuche, direkte Daten lesen und schreiben auf ein USB-Flash-Laufwerk als ein physikalisches Laufwerk auf Windows (10, wenn es darauf ankommt). Ich benutze Python, um das zu tun.Schreiben von Rohdaten auf physischen Datenträger (Flash-Laufwerk) schlägt mit "Bad Dateideskriptor" auf Windows - Python

Ich habe die folgende Diskussion an:

get writing access to raw devices using python with windows

ich in das gleiche Problem lief kcstrom in dieser Frage hatte. Ich bekomme eine

Traceback (most recent call last): 
    File "C:\script.py", line 49, in <module> 
    disk.write(data) 
    IOError: [Errno 9] Bad file descriptor 

Lesen und suchen funktionieren, wie sie sollten, und die gelesenen Daten sind korrekt.

Was ich weiß, bisher:

  1. Das Fahrverhalten sollte so bemessen, in Sektor erfolgen liest/schreibt/sucht.
  2. Die Festplatte muss mit dem Modus 'rb +' geöffnet werden.
  3. Die Verwendung von \\. \ L: und \\. \ PhysicalDriveN führt zu denselben Ergebnissen.
  4. Das Skript muss unter Administratorrechten ausgeführt werden.
  5. Unmounten des Laufwerks und versuchen, auf die Datei \\. \ PhysicalDriveN zuzugreifen - "Permission Denied", auch wenn es als Administrator ausgeführt wird.

den Fehler zu reproduzieren: (ACHTUNG: DIESER CODE CORRUPT -Festplatten nur dann laufen, wenn Sie wissen, was Sie tun)

SOME_OFFSET = 123123 
SOME_SIZE = 100 
# replace L with the drive letter 
disk = open('\\\\.\\L:','r+b') 
# or use: (replace N with the drive number) 
# disk = open('\\\\.\\PhysicalDriveN','r+b') 
disk.seek(SOME_OFFSET*512) 
data = disk.read(SOME_SIZE*512) 
#modify data... 
disk.seek(SOME_OFFSET*512) 
disk.write(data) 

ich kann nicht herausfinden, ob dies ein Berechtigungsproblem ist oder ein Problem mit dem Öffnen des Laufwerks.

+1

Das zugrunde liegende 'WriteFile' schlägt mit 'ERROR_ACCESS_DENIED' fehl. Das direkte Schreiben auf ein bereitgestelltes Volume ist nicht zulässig. Sie müssen mehr darüber nachdenken, um das Volume zu sperren und zu entfernen, bevor Sie es oder das physische Laufwerk schreiben. – eryksun

+0

@eryksun Könnten Sie mir bitte auf die Informationen hinweisen, die ich brauche? Vielen Dank! – MiaoHatola

+1

Sie rufen ['DeviceIoControl'] (https://msdn.microsoft.com/en-us/library/aa363216) auf einem Volume-Handle auf, das mit [' CreateFile'] geöffnet wurde (https://msdn.microsoft. com/de-de/library/aa363858). Hier sind die [Lautstärkeregelcodes] (https://msdn.microsoft.com/en-us/library/aa365729) zum Sperren, Aufheben und Entsperren des Volumes. In Python können Sie ctypes oder PyWin32s ['win32file'] (http://docs.activestate.com/activepython/2.7/pywin32/win32file.html) Modul verwenden. – eryksun

Antwort

1

Nach dem MSDN technischen Hinweis "Blocking Direct Write Operations to Volumes and Disks":

Write operations on a DASD volume handle will succeed if the file system is not mounted, or if:

  • The sectors being written to are the boot sectors.
  • The sectors being written to reside outside file system space.
  • The file system has been locked implicitly by requesting exclusive write access.
  • The file system has been locked explicitly by sending down a lock/dismount request.

....

Write operations on a disk handle will succeed if:

  • The sectors being written to do not fall within a file system.
  • The sectors being written to fall within a mounted file system that is locked explicitly.
  • The sectors being written to fall within a file system that is not mounted or the volume has no file system.

Hier ist ein einfacher Kontextmanager ein Volumen zu sperren. Es verwendet die Module win32file und winoctlcon von PyWin32.

import msvcrt 
import win32file 
import winioctlcon 
import contextlib 

@contextlib.contextmanager 
def lock_volume(vol): 
    hVol = msvcrt.get_osfhandle(vol.fileno()) 
    win32file.DeviceIoControl(hVol, winioctlcon.FSCTL_LOCK_VOLUME, 
           None, None) 
    try: 
     yield vol 
    finally: 
     try: 
      vol.flush() 
     finally: 
      win32file.DeviceIoControl(hVol, winioctlcon.FSCTL_UNLOCK_VOLUME, 
             None, None) 

if __name__ == '__main__': 
    VOLUME_PATH = r'\\.\E:' 
    OFFSET = 123123 
    SIZE = 100 

    with open(VOLUME_PATH, 'r+b') as disk: 
     with lock_volume(disk): 
      disk.seek(OFFSET * 512) 
      data = disk.read(SIZE * 512) 
      disk.seek(OFFSET * 512) 
      disk.write(data) 
      input('press enter to unlock the volume') 
Verwandte Themen