AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Mit DeviceIoControl Laufwerk sperren und auslesen
Thema durchsuchen
Ansicht
Themen-Optionen

Mit DeviceIoControl Laufwerk sperren und auslesen

Ein Thema von Kasoft · begonnen am 26. Mai 2004 · letzter Beitrag vom 22. Nov 2005
Antwort Antwort
Kasoft

Registriert seit: 5. Mai 2004
Ort: Filderstadt
111 Beiträge
 
Delphi 7 Professional
 
#1

Mit DeviceIoControl Laufwerk sperren und auslesen

  Alt 26. Mai 2004, 14:42
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:
  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);
Jedoch hab ich trotzdem ein Problem damit. Wenn ein Zugriff auf dieses Laufwerk
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
  Mit Zitat antworten Zitat
Kasoft

Registriert seit: 5. Mai 2004
Ort: Filderstadt
111 Beiträge
 
Delphi 7 Professional
 
#2

Re: Mit DeviceIoControl Laufwerk sperren und auslesen

  Alt 26. Mai 2004, 17:21
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:

   Result := DeviceIoControl(Handle, FSCTL_DISMOUNT_VOLUME, nil, 0, nil, 0,
      BytesReturned, nil);
Also eine DeviceIoControl Funktion. FSCTL_DISMOUNT_VOLUME ist eine Konstante.
In der winioctl.h wird sie so beschrieben:
Code:
#define FSCTL_DISMOUNT_VOLUME
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 8, METHOD_BUFFERED, FILE_ANY_ACCESS)
Das müsste für FSCTL_DISMOUNT_VOLUME den Wert $90020 ergeben.
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
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#3

Re: Mit DeviceIoControl Laufwerk sperren und auslesen

  Alt 26. Mai 2004, 17:26
Vielleicht hilft dir mein DiskImageNT von meiner Seite. Ist mit Code. Kuck es dir einfach mal an.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Kasoft

Registriert seit: 5. Mai 2004
Ort: Filderstadt
111 Beiträge
 
Delphi 7 Professional
 
#4

Re: Mit DeviceIoControl Laufwerk sperren und auslesen

  Alt 26. Mai 2004, 17:47
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
  Mit Zitat antworten Zitat
Kasoft

Registriert seit: 5. Mai 2004
Ort: Filderstadt
111 Beiträge
 
Delphi 7 Professional
 
#5

Re: Mit DeviceIoControl Laufwerk sperren und auslesen

  Alt 27. Mai 2004, 10:31
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"?

MfG
Kasoft
  Mit Zitat antworten Zitat
Kasoft

Registriert seit: 5. Mai 2004
Ort: Filderstadt
111 Beiträge
 
Delphi 7 Professional
 
#6

Re: Mit DeviceIoControl Laufwerk sperren und auslesen

  Alt 2. Jun 2004, 06:06
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
  Mit Zitat antworten Zitat
Nils_25

Registriert seit: 15. Nov 2005
3 Beiträge
 
Delphi 7 Enterprise
 
#7

Re: Mit DeviceIoControl Laufwerk sperren und auslesen

  Alt 15. Nov 2005, 13:52
Hallo zusammen,

ich hätte da mal eine Frage, wie komme ich von dem Inhalt aus der Klammer
Zitat:
(FILE_DEVICE_FILE_SYSTEM, 8, METHOD_BUFFERED, FILE_ANY_ACCESS)
auf

den Wert
Zitat:
$90020
?

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
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#8

Re: Mit DeviceIoControl Laufwerk sperren und auslesen

  Alt 22. Nov 2005, 12:36
@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:
#define CTL_CODE( DeviceType, Function, Method, Access ) (                 \
    ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
)
Im GPD aus dem DDK haben wir:
Code:
#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
Beispiel:
Code:
_  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
Ich hoffe mal, daß ich richtig gerechnet habe. Hab's im Kopf gerechnet.
  Mit Zitat antworten Zitat
Benutzerbild von TKC
TKC

Registriert seit: 21. Apr 2004
Ort: Tuningen
367 Beiträge
 
Delphi XE2 Enterprise
 
#9

Re: Mit DeviceIoControl Laufwerk sperren und auslesen

  Alt 22. Nov 2005, 13:03
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;
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:20 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz