![]() |
Mit DeviceIoControl Laufwerk sperren und auslesen
Hallo,
Ich versuche mich gerade in DeviceIoControl einzuleben. Was mir sehr gut gefallen hat das man durch DeviceIOControl sehr schön Datenträger sperren kann:
Code:
Jedoch hab ich trotzdem ein Problem damit. Wenn ein Zugriff auf dieses Laufwerk
Handle := CreateFile(PChar('\\.\' + Volume), GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, 0); . . . DeviceIoControl(Handle, FSCTL_LOCK_VOLUME, nil, 0, nil, 0, BytesReturned, nil); vorhanden ist kann ich das nicht sperren. Für meinen gebrauch ist das aber notwendig das ich das Laufwerk sperren kann auch wenn darauf gearbeitet ist (es ist keine System- partition). Weiterhin probiere ich mit dem handle das ich ja durch CreateFile erhalte auf dem Datenträger eine Datei auszulesen. Aber ich hab keinen Ansatzpunkt gefunden wie ich das bewerkstellige. Habt ihr mir da einen Tipp? Danke für eure Antworten schon im Voraus. MfG Kasoft |
Re: Mit DeviceIoControl Laufwerk sperren und auslesen
Die Google-Suche ergab das einige Leute auf das Problem gestoßen sind.
Gleichzeitig ergab sie auch dass man die Festplatte nur durch "dismounten" von den Handles befreien kann. Natürlich habe ich nun versucht diese Möglich- keit zu nutzen aber das führte zu keinem Erfolg. Der Code den ich benutzt hab lautet:
Code:
Also eine DeviceIoControl Funktion. FSCTL_DISMOUNT_VOLUME ist eine Konstante. Result := DeviceIoControl(Handle, FSCTL_DISMOUNT_VOLUME, nil, 0, nil, 0, BytesReturned, nil); In der winioctl.h wird sie so beschrieben:
Code:
Das müsste für FSCTL_DISMOUNT_VOLUME den Wert $90020 ergeben.
#define FSCTL_DISMOUNT_VOLUME
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 8, METHOD_BUFFERED, FILE_ANY_ACCESS) Wenn ich diese Funktion aber so ausführe meldet sie mir TRUE. ansich wäre es ja dann perfekt. Aber leider stimmt das nicht. Wenn ich versuche nun die Platte zu locken dann meldet er mir wieder false. Danach hab ich ein Workaround mit Chkdsk gelesen. Chkdsk kontrolliert zuerst ob irgendwelche Handles auf das Laufwerk zugreifen. Eigentlich sollte man dann mit einem geeigneten Parameter die Handles ungültig machen können. Ich glaube das war der Parameter /X Aber auch diese Möglichkeit klappt nicht da mir chkdsk sofort meldet das Handles auf das Laufwerk geöffnet sind und er nicht weiterarbeiten kann. Die Google suche ergab hier rein gar nichts. Oder eher das es bei anderen klappt. Ich hoffe das ich gerade nur nen Blackout habe und deswegen nicht vorwärts komme. MfG Kasoft |
Re: Mit DeviceIoControl Laufwerk sperren und auslesen
Vielleicht hilft dir mein DiskImageNT von meiner Seite. Ist mit Code. Kuck es dir einfach mal an.
|
Re: Mit DeviceIoControl Laufwerk sperren und auslesen
Salût Lucky,
danke für die Antwort aber leider hab ich nichts gefunden was mir da helfen könnte. Locken kann ich ja nicht da ein Handle darauf ist (egal ob es ein Programm ist oder nur der Explorer der den Inhalt auf die Daten der Platte anzeigt) und dismounten hilft auch nicht. MfG Kasoft |
Re: Mit DeviceIoControl Laufwerk sperren und auslesen
Sodelle nachdem fast die ganze Nacht draufgegangen ist um irgendwelche Informationen
über das Locken von Datenträgern zu suchen ist, hab ich gerade was ganz merkwürdiges gesehen. Wenn ich meine Funktion (CM_REQUEST_DEVICE_EJECT) zum Auswerfen von USB-Geräten benutze funktioniert das merkwürdigerweise. Gestern hat es nicht getan... Das macht ganz perplex...Naja ich sehe das als eher die unschöne Methode. Deswegen bin ich immernoch auf der suche zum Locken eines Datenträgers. Oder ich hätte da noch eine Idee: Gibt es eine Möglichkeit um alle Handles die auf einen Datenträger zeigen aufzulisten und sie dann zu ,ich mag zwar dieses Wort nicht aber anders kann ichs nicht umformulieren, "eliminieren"? :gruebel: MfG Kasoft |
Re: Mit DeviceIoControl Laufwerk sperren und auslesen
Ich legs als beendet ab da keiner helfen könnten. Soll ja nicht unnötig
geöffnet bleiben. MfG Kasoft P.S.: Häh warum kann ich den Thread nicht closen? <--- war eine rhetorische Frage |
Re: Mit DeviceIoControl Laufwerk sperren und auslesen
Hallo zusammen,
ich hätte da mal eine Frage, wie komme ich von dem Inhalt aus der Klammer Zitat:
den Wert Zitat:
ich bräuchte den Wert für 1.: (GPD_TYPE, $443, METHOD_BUFFERED,FILE_WRITE_ACCESS) 2.: (GPD_TYPE, $443, METHOD_BUFFERED,FILE_READ_ACCESS) 3.: (GPD_TYPE, $043, METHOD_BUFFERED,FILE_WRITE_ACCESS) kann mir jemand helfen? Danke schon mal. Ciao Nils |
Re: Mit DeviceIoControl Laufwerk sperren und auslesen
@Nils_25: das ist eine andere Frage, gehört also in einen neuen Thread. Aber du kannst dir ja mal das Makro anschauen, dessen Parameter du uns oben angegeben hast, dann wirst du feststellen, wie man die IOCTLs selber berechnet. Der Name des Makros ist: CTL_CODE
Ich würde dir übrigens nicht empfehlen den generischen Porttreiber ("GPD") aus dem DDK zu nehmen - auch nicht irgendwelche Derivate, die du u.U. noch nichtmal verstehst. Habe ich hier schon oft genug begründet, also suche einfach mal mithilfe der Forumssuche. Das Makro:
Code:
Im GPD aus dem DDK haben wir:
#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \ )
Code:
Beispiel:
#define GPD_TYPE 40000
// ntddk.h #define METHOD_BUFFERED 0 #define METHOD_IN_DIRECT 1 #define METHOD_OUT_DIRECT 2 #define METHOD_NEITHER 3 // ... ntddk.h #define FILE_ANY_ACCESS 0 #define FILE_SPECIAL_ACCESS (FILE_ANY_ACCESS) #define FILE_READ_ACCESS ( 0x0001 ) // file & pipe #define FILE_WRITE_ACCESS ( 0x0002 ) // file & pipe
Code:
Ich hoffe mal, daß ich richtig gerechnet habe. Hab's im Kopf gerechnet.
_ CTL_CODE(GPD_TYPE, 0x443, METHOD_BUFFERED, FILE_WRITE_ACCESS)
== CTL_CODE(40000, 0x443, 0, 2) == (40000 << 16) | (2 << 14) | (0x443 << 2) | 0 // C-Syntax == (40000 shl 16) or (2 shl 14) or ($443 shl 2) or 0 // Delphi-Syntax == ($9C40 shl 16) or ($2 shl 14) or ($443 shl 2) or 0 // Delphi-Syntax == ($9C400000) or ($8000) or ($110C) or 0 // Delphi-Syntax == ($9C400000) or ($8000) or ($110C) or 0 // Delphi-Syntax == $9C40910C |
Re: Mit DeviceIoControl Laufwerk sperren und auslesen
ich hab das mal vor einiger Zeit für meine TDriveCheck Kompo gebraucht ...
den Code kann man bestimmt noch verbessern ... stammt noch aus meiner Anfangszeit mit Delphi ;)
Delphi-Quellcode:
const
//Konstanten für Volume Funktionen METHOD_BUFFERED = 0; {$EXTERNALSYM METHOD_BUFFERED} FILE_ANY_ACCESS = 0; {$EXTERNALSYM FILE_ANY_ACCESS} FILE_DEVICE_FILE_SYSTEM = $00000009; {$EXTERNALSYM FILE_DEVICE_FILE_SYSTEM} FSCTL_LOCK_VOLUME = (FILE_DEVICE_FILE_SYSTEM shl 16) or (FILE_ANY_ACCESS shl 14) or (6 shl 2) or METHOD_BUFFERED; {$EXTERNALSYM FSCTL_LOCK_VOLUME} FSCTL_UNLOCK_VOLUME = ((FILE_DEVICE_FILE_SYSTEM shl 16) or (FILE_ANY_ACCESS shl 14) or (7 shl 2) or METHOD_BUFFERED); {$EXTERNALSYM FSCTL_UNLOCK_VOLUME} FSCTL_DISMOUNT_VOLUME = ((FILE_DEVICE_FILE_SYSTEM shl 16) or (FILE_ANY_ACCESS shl 14) or (8 shl 2) or METHOD_BUFFERED); {$EXTERNALSYM FSCTL_DISMOUNT_VOLUME} {----------------------------------------------------------------------------- Funcktion: DismountVolume Date: 21-Aug-2005 Arguments: sDrive: string Result: Boolean Description: Schreibzugriff auf Volume herstellen -----------------------------------------------------------------------------} function TDriveCheck.DismountVolume(sDrive: string): Boolean; const LOCK_TIMEOUT = 3000; LOCK_RETRIES = 3; var iWaitTimeout : Integer; iTryCount : Integer; bLocked : Boolean; sVolumeName : string; bIOResult : Boolean; cBytesReturned : Cardinal; hVolumeHandle : THandle; begin bLocked := False; iWaitTimeout := LOCK_TIMEOUT div LOCK_RETRIES; sVolumeName := '\\.\' + sDrive; //Generischen Schreibzugriff prüfen hVolumeHandle := CreateFile(PChar(sVolumeName), GENERIC_WRITE, 0, nil, OPEN_EXISTING, 0, 0); if hVolumeHandle <> INVALID_HANDLE_VALUE then begin Result := true; CloseHandle(hVolumeHandle); LogToMemo('Schreibzugriff hergestellt ...'#13#10); Exit; end; //Volumehandle für DeviceIO - Lock/Dismount holen hVolumeHandle := CreateFile(PChar(sVolumeName), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0); if hVolumeHandle = INVALID_HANDLE_VALUE then begin Result := False; CloseHandle(hVolumeHandle); LogToMemo('Fehler beim Volume zugriff !!'#13#10); Exit; end; //Versuch das Laufwerk zu sperren LogToMemo('Versuche Laufwerk zu sperren ...'#13#10); for iTryCount := 0 to LOCK_RETRIES do begin bIOResult := DeviceIoControl(hVolumeHandle, FSCTL_LOCK_VOLUME, nil, 0, nil, 0, cBytesReturned, nil); if bIOResult then begin bLocked := true; LogToMemo('Laufwerk erfolgreich gesperrt ...'#13#10#13#10); break; end; Sleep(iWaitTimeout); end; //Laufwerk konnte nicht gesperrt werden - Versuch die Handles zu schließen if not bLocked then begin LogToMemo('Schließe alle offenen Handles auf das Volume ...'#13#10); for iTryCount := 0 to LOCK_RETRIES do begin bIOResult := DeviceIoControl(hVolumeHandle, FSCTL_DISMOUNT_VOLUME, nil, 0, nil, 0, cBytesReturned, nil); if bIOResult then begin bLocked := true; LogToMemo('Alle Handles erfolgreich geschlossen.'#13#10#13#10); break; end; Sleep(iWaitTimeout); end; end; //Volume wieder freigeben CloseHandle(hVolumeHandle); Sleep(LOCK_TIMEOUT); //Ergebnis setzen if bLocked then Result := true else begin LogToMemo('Handles konnten nicht geschlossen werden !'); if (MessageBox(0, 'Es konnte kein exclusiver Zugriff auf das Laufwerk hergestellt werden.' + #13#10#13#10 + 'Soll das Laufwerk beim nächsten Systemstart geprüft werden ?', 'Laufwerksprüfung', MB_ICONQUESTION or MB_YESNO or MB_DEFBUTTON1) = idYes) then SetBootAutochk() else LogToMemo(#13#10'Scan vom Benutzer abgebrochen !!'#13#10); Result := False; end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:52 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz