Registriert seit: 21. Apr 2004
Ort: Tuningen
367 Beiträge
Delphi XE2 Enterprise
|
Re: Mit DeviceIoControl Laufwerk sperren und auslesen
22. Nov 2005, 14: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;
|
|
Zitat
|