C # WriteFile () beendet das Schreiben in Sektor 242 auf USB-Laufwerken

8

Ich habe den folgenden Code geschrieben, um 0xFF in alle Bytes auf meinem USB-Speichergerät zu schreiben. Aus irgendeinem Grund beginnen die WriteFile () - Aufrufe bei Sektor 242 zu einem Fehler. Ich habe dies auf zwei getrennten USB-Speichergeräten gemacht und dann die Geräte in einem Hex-Editor untersucht. Der Sektor 242 scheint der Anfang der Dateizuordnungstabelle auf einem FAT16-formatierten Gerät und der Start des Bootbereichs auf einem NTFS-Gerät zu sein. Ich bin mir sicher, dass es kein Zufall ist, dass es genau an diesen Stellen ausgeht, aber ich weiß nicht, wie ich dieses Verhalten ändern soll. Das HRESULT, das ich empfange, wenn das WriteFile fehlschlägt, ist -2147024891, das E_ACCESSDENIED ist. Weiß jemand, was das Problem verursachen könnte?

HINWEIS: Wenn Sie diesen Code auf Ihrem lokalen System ausführen, seien Sie SEHR VORSICHTIG, da ich die physische Geräte-ID für mein USB-Gerät fest codiert habe. Stellen Sie sicher, dass Sie die Variable deviceId mit dem Gerät aktualisieren, auf das Sie schreiben möchten. Sie möchten Ihre Festplatte nicht zerstören.

%Vor%

BEARBEITEN / AKTUALISIEREN

Ich konnte das erfolgreich durchführen, nachdem ich das USB-Gerät mit einem Tool eines Drittanbieters gelöscht hatte. Nachdem das Laufwerk vollständig gelöscht wurde, konnte ich erfolgreich auf das Gerät schreiben. Es sieht so aus, als würde Windows das Gerät sperren, sobald es ein gültiges fat- oder ntfs-Dateisystem und die Verwendung von

erkennt %Vor%

gepaart mit DeviceIoControl scheint die Sperrfenster auf dem Gerät nicht zu überschreiben.

Kann jemand erfolgreich ein entfernbares USB-Gerät in Windows mit DeviceIoControl auf einem Laufwerk mit einem gültigen Dateisystem sperren?

Ich habe mehrere Tools von Drittanbietern verwendet, die das ausführen, was ich versuche, und sie arbeiten erfolgreich. Ich weiß, dass es möglich ist, aber alle MSDN-Dokumentation, die ich gelesen habe, hat nicht geholfen, das Problem zu lösen.

BEARBEITEN / AKTUALISIEREN 2

Dies stammt aus Ссылка

"Die Anwendung muss das Volume sperren, das Volume aufheben oder beides, bevor DASD-E / A ausgegeben werden kann. Dies ist neu in Windows Vista und wurde durchgeführt, um potenziell bösartige Techniken zu beheben.

  1. Das Dateisystem blockiert alle Schreibvorgänge auf reservierte Bereiche der Festplatte. In diesem Fall umfassen diese reservierten Abschnitte den MBR- und die zwei FAT-Bereiche. Um diese Bereiche zu blockieren, müssen Sie das Volume sperren, indem Sie FSCTL_LOCK_VOLUME senden. Sie müssen diese Struktur auf demselben Volume-Handle ausgeben, das die eigentlichen Schreiboperationen ausführt. Diese Anforderung kann fehlschlagen, wenn offene Dateihandles vorhanden sind. In diesem Fall kann die Anwendung das Abmelden des Dateisystems erzwingen, indem sie FSCTL_DISMOUNT_VOLUME absetzt. Das Volume wird jedoch tatsächlich nicht aufgehoben, bis das Dateihandle geschlossen wird. Bis dahin kann die Anwendung DASD-E / A weiterhin mit demselben Datei-Handle ausgeben, das derzeit geöffnet ist.

  2. Es gibt einen erweiterten Bereich, der über den Volumenbereich hinausgeht, der dem Dateisystem bekannt ist, in dem Schreibvorgänge blockiert werden. Um Schreibvorgänge für diese Region zuzulassen, müssen Sie FSCTL_ALLOW_EXTENDED_DASD_IO auf dem Datenträger-Handle ausgeben.

Sie können die Win32-API-Routine DeviceIoControl verwenden, um alle vorherigen FSCTS auszustellen. "

Ich glaube, das ist genau das, was wir im obigen Code implementieren, aber es scheint nicht richtig zu funktionieren. Wir bekommen einen Griff und sperren und demontieren das Gerät, so dass wir in der Lage sein sollten, in den geschützten Bereich richtig zu schreiben?

BEARBEITEN / AKTUALISIEREN 3

Ok, das ist die aktuelle Reihenfolge beim Öffnen von Festplatten und Volumes. Die Methoden zum Sperren, Demontieren usw. funktionieren nur in der Reihenfolge, die wir für falsch halten.

%Vor%

Ich bekomme immer noch die gleichen Ergebnisse, es funktioniert nur, wenn die Festplatte zerstört wird.

    
Brandon Stout 22.08.2012, 21:00
quelle

3 Antworten

5

Es besteht eine Verwechslung zwischen Festplatte und Laufwerk .

Wenn Sie vollen Zugriff auf eine Festplatte haben möchten (dies ist der Fall, wenn Sie \.\PHYSICALDRIVE verwenden), müssen Sie alle bereitgestellten Volumes sperren alle Partitionen (dh Laufwerke ) Ihrer physischen Festplatte .

Anstatt FSCTL_LOCK_VOLUME für das Handle zu verwenden, das von CreateFile("\.\PHYSICALDRIVE"...) zurückgegeben wird, erhalten Sie mit dem Muster string.Replace("\\.\{0}:", DriveLetter) ein Handle für jedes bereitgestellte Volume (ein Laufwerk, keine physische Festplatte).

Sie können die Liste der gemounteten Volumes (letztlich eine Liste von Buchstaben) für eine bestimmte physische Festplatte mit IOCTL_DISK_GET_DRIVE_LAYOUT erhalten.

BEARBEITEN:

Von MSDN :

  

Ein Schreibvorgang auf einem Datenträgerhandle ist erfolgreich, wenn einer der folgenden Schritte ausgeführt wird   Bedingungen ist wahr:

     

Die zu beschreibenden Sektoren fallen nicht in a   Volumen Extents.

     

Die zu schreibenden Sektoren fallen in ein eingehängtes Feld   Volume, aber Sie haben das Volume explizit gesperrt oder aufgehoben   mit FSCTL_LOCK_VOLUME oder FSCTL_DISMOUNT_VOLUME.

     

Die Sektoren zu sein   geschrieben, um in einen Datenträger zu fallen, der kein angehängtes Dateisystem hat   als RAW.

Was Sie im Grunde tun sollten, ist:

  • erhält einen Handle für jedes Volume
  • Verwenden Sie FSCTL_LOCK_VOLUME oder FSCTL_DISMOUNT_VOLUME auf jedem Volume. Wenn keine Datei im Volume verwendet wird (d. H. Kein geöffnetes Handle von einem Prozess in einer Datei), ist FSCTL_LOCK_VOLUME genug
  • Erhalte ein Handle für den physischen Datenträger
  • schreibe auf den physischen Datenträger
  • schließe beide Griffe. Durch Schließen des Lautstärkereglers wird die Sperre aufgehoben.

Stellen Sie außerdem sicher, dass Sie Ihre Anwendung mit Administratorrechten ausführen (erhöhter Prozess).

    
ken2k 24.08.2012, 17:14
quelle
1

Ich nehme an, dass Sie Windows Vista oder später verwenden. Das Betriebssystem blockiert alle Versuche, das Schreiben in diese Sektoren zu leiten. Daher müssen Sie zuerst eine Sperre ausführen. Mehr dazu hier:

Ссылка

Auch das Einchecken in SO brachte diesen Post hoch:

CreateFile: direkte Schreiboperation auf Raw-Platte "Zugriff verweigert" - Vista, Win7

Die investigativen Informationen könnten hilfreich sein, HTH ...

    
code4life 24.08.2012 15:21
quelle
1

BEARBEITEN

Ich habe diese Antwort bearbeitet, um die Vorschläge von ken2k widerzuspiegeln.

ken2ks Vorschlag hat das Problem gelöst, das ich hatte. Ich bin mir nicht sicher, warum meine früheren Versuche, diesen Ansatz zu verwenden, nicht erfolgreich waren, aber ich habe meinen Code gerade überarbeitet / optimiert und dieser Ansatz scheint korrekt zu funktionieren.

Hier sind die Schritte, die ich verwendet habe, um dieses Problem zu lösen:

  • Erhalte ein Handle für den physischen Datenträger
  • Erhalte einen Handle für jedes logische Laufwerk auf dem physischen Datenträger
  • Sperren Sie jedes Laufwerk auf der physischen Festplatte
  • Demontieren Sie jedes Laufwerk auf der physischen Festplatte
  • Sperren Sie die physische Festplatte (Optional)
  • Demontieren Sie die physische Festplatte (Optional)
  • Verwenden Sie die physische Datenträgerkennung, um die gesamte physische Festplatte auf Null zu setzen
  • Entsperren Sie jedes logische Laufwerk
  • Entsperren Sie die physische Festplatte (Nur wenn Sie die Festplatte sperren)
  • Schließen Sie die logischen Laufwerksgriffe
  • Schließen Sie den physischen Datenträgergriff

ANMERKUNG: Wenn Sie Datenträgeroperationen nacheinander durchführen möchten, ohne das Programm zu beenden, und Sie die FSCTL_DISMOUNT_VOLUME-Funktionalität verwendet haben, müssen Sie die Festplatte mit folgendem Befehl neu mounten:

%Vor%

oder

%Vor%

Um die IDs des logischen Laufwerks der ID des physischen Laufwerks zuzuordnen, wenn Sie versuchen, jedes einzelne logische Laufwerk zu sperren, verwenden Sie den folgenden Codeabschnitt, um die Beschriftungen des logischen Laufwerks mit den Beschriftungen des physischen Laufwerks zu verknüpfen:

%Vor%

Wenn also beispielsweise das physische Laufwerkslabel \. \ PHYSICALDRIVE1 heißt und es ein logisches Laufwerk mit dem Laufwerksbuchstaben "E" enthält, wird der obige Code \. \ E: \. \ PHYSICALDRIVE1.

zuordnen

Gemäß ken2ks Vorschlag kann diese Zuordnung auch mithilfe der IOCTL_DISK_GET_DRIVE_LAYOUT-Funktionalität erfolgen.

Hoffentlich ist das nützlich für jemand anderen!

Danke euch allen für die Hilfe, mir in die richtige Richtung zu zeigen!

    
Brandon Stout 27.08.2012 16:27
quelle

Tags und Links