![]() |
Re: USB Stick sicher entfernen unter Vista
Probier mal Folgendes:
Delphi-Quellcode:
Aufruf mit z.B. EjectVolume('J');
function OpenVolume(ADrive: char): THandle;
var RootName, VolumeName: string; AccessFlags: DWORD; DriveType:Cardinal; begin RootName := ADrive + ':\'; DriveType := GetDriveType(PChar(RootName)); case DriveType of DRIVE_REMOVABLE: AccessFlags := GENERIC_READ or GENERIC_WRITE; DRIVE_CDROM: AccessFlags := GENERIC_READ; // DRIVE_FIXED: // AccessFlags := GENERIC_READ or GENERIC_WRITE; else Result := INVALID_HANDLE_VALUE; exit; end; VolumeName := Format('\\.\%s:', [ADrive]); Result := CreateFile(PChar(VolumeName), AccessFlags, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0); if Result = INVALID_HANDLE_VALUE then RaiseLastWin32Error; end; function LockVolume(AVolumeHandle: THandle): boolean; const LOCK_TIMEOUT = 10 * 1000; // 10 Seconds LOCK_RETRIES = 20; LOCK_SLEEP = LOCK_TIMEOUT div LOCK_RETRIES; FSCTL_LOCK_VOLUME = (9 shl 16) or (0 shl 14) or (6 shl 2) or 0; var Retries: integer; BytesReturned: Cardinal; begin for Retries := 1 to LOCK_RETRIES do begin Result := DeviceIoControl(AVolumeHandle, FSCTL_LOCK_VOLUME, nil, 0, nil, 0, BytesReturned, nil); if Result then break; Sleep(LOCK_SLEEP); end; end; function DismountVolume(AVolumeHandle: THandle): boolean; const FSCTL_DISMOUNT_VOLUME = (9 shl 16) or (0 shl 14) or (8 shl 2) or 0; var BytesReturned: Cardinal; begin Result := DeviceIoControl(AVolumeHandle, FSCTL_DISMOUNT_VOLUME, nil, 0, nil, 0, BytesReturned, nil); if not Result then RaiseLastWin32Error; end; function PreventRemovalOfVolume(AVolumeHandle: THandle; APreventRemoval: boolean): boolean; const IOCTL_STORAGE_MEDIA_REMOVAL = ($2d shl 16) or (1 shl 14) or ($201 shl 2) or 0; type TPreventMediaRemoval = record PreventMediaRemoval: BOOL; end; var BytesReturned: Cardinal; PMRBuffer: TPreventMediaRemoval; begin PMRBuffer.PreventMediaRemoval := APreventRemoval; Result := DeviceIoControl(AVolumeHandle, IOCTL_STORAGE_MEDIA_REMOVAL, @PMRBuffer, SizeOf(TPreventMediaRemoval), nil, 0, BytesReturned, nil); if not Result then RaiseLastWin32Error; end; function AutoEjectVolume(AVolumeHandle: THandle): boolean; const IOCTL_STORAGE_EJECT_MEDIA = ($2d shl 16) or (1 shl 14) or ($202 shl 2) or 0; var BytesReturned: Cardinal; begin Result := DeviceIoControl(AVolumeHandle, IOCTL_STORAGE_EJECT_MEDIA, nil, 0, nil, 0, BytesReturned, nil); if not Result then RaiseLastWin32Error; end; function EjectVolume(ADrive: char): boolean; var VolumeHandle: THandle; begin Result := FALSE; // Open the volume VolumeHandle := OpenVolume(ADrive); if VolumeHandle = INVALID_HANDLE_VALUE then exit; try // Lock and dismount the volume if LockVolume(VolumeHandle) and DismountVolume(VolumeHandle) then begin // Set prevent removal to false and eject the volume if PreventRemovalOfVolume(VolumeHandle, FALSE) then AutoEjectVolume(VolumeHandle); end; finally // Close the volume so other processes can use the dr CloseHandle(VolumeHandle); end; end; |
Re: USB Stick sicher entfernen unter Vista
Vielen Dank für Ihre Antworten.
|
Re: USB Stick sicher entfernen unter Vista
Wie bekomme ich 'angeschlossenen USB-Info "(Geräte-Instanz-ID, Fahrerairbag, Schlüsselnamen ..) aus der Registry in Vista oder Windows 7 mit Delphi?
Wo ist diese Information in Windows Registry? Ich habe einen Code es funktioniert unter XP, aber nicht in Vista. Warum wird der Code funktioniert nicht auf Vista? Ich bin Stack wirklich darüber. Bitte helfen Sie. |
Re: USB Stick sicher entfernen unter Vista
Hallo TurboMartin,
unter Win 7 und als Admin geht es, unter Vista nicht. Keine Meldung, nix. Gruß |
Re: USB Stick sicher entfernen unter Vista
Zitat:
|
Re: USB Stick sicher entfernen unter Vista
Für Vista und Win7:
GetDriveInstanceID () except alles korrekt funktioniert. So GetDriveInstanceID(DriveMountPoints[I], Inst) returned from 'Inst' ist falsch. Ergebnisse für den gleichen USB: ----------------XP-----------Win7 ----------------------------------- Inst--------2788----------3908 Key---------1924-----------0 Was hat sich in Vista Registry geändert? |
Re: USB Stick sicher entfernen unter Vista
Zitat:
Nochmal: Die Funktion setzt eine Parent/Child-Beziehung zwischen Volume und Disk voraus. Das war schon unter XP nur für Wechseldatenträger und CDROMs ok, aber nicht für Festplatten. Ab Vista ist das nur noch für CDROMs und USB-Floppys der Fall, sonst ist der Volume-Manager im Spiel. Hier habe ich in C++ gezeigt, wie es geht: ![]() Gruß Uwe |
Re: USB Stick sicher entfernen unter Vista
Ich hänge mich hier mal an mit meinem Problem:
Ich nutze folgenden Quelltext:
Delphi-Quellcode:
Der USB-Stick wird ausgehängt, aber irgendwie scheint ShChangeNotify zu scheitern. Das Symbol in der Taskleiste bleibt erhalten, ebendso wird im Explorer noch das Laufwerk angezeigt. Wie sag ich Windows nun, dass ich den Stick ausgehängt habe?
Function EjectVolume(ADrive: char): Boolean;
Function OpenVolume(ADrive: char): THandle; Var RootName, VolumeName : String; AccessFlags : DWORD; DriveType : Cardinal; Begin RootName := ADrive + ':\'; DriveType := GetDriveType(pChar(RootName)); Case DriveType Of DRIVE_REMOVABLE: AccessFlags := GENERIC_READ Or GENERIC_WRITE; DRIVE_CDROM: AccessFlags := GENERIC_READ; // DRIVE_FIXED: // AccessFlags := GENERIC_READ or GENERIC_WRITE; Else Result := INVALID_HANDLE_VALUE; Exit; End; VolumeName := Format('\\.\%s:', [ADrive]); Result := CreateFile(pChar(VolumeName), AccessFlags, FILE_SHARE_READ Or FILE_SHARE_WRITE, Nil, OPEN_EXISTING, 0, 0); If Result = INVALID_HANDLE_VALUE Then RaiseLastWin32Error; End; Function LockVolume(AVolumeHandle: THandle): Boolean; Const LOCK_TIMEOUT = 10 * 1000; // 10 Seconds LOCK_RETRIES = 20; LOCK_SLEEP = LOCK_TIMEOUT Div LOCK_RETRIES; FSCTL_LOCK_VOLUME = (9 Shl 16) Or (0 Shl 14) Or (6 Shl 2) Or 0; Var Retries : Integer; BytesReturned : Cardinal; Begin For Retries := 1 To LOCK_RETRIES Do Begin Result := DeviceIoControl(AVolumeHandle, FSCTL_LOCK_VOLUME, Nil, 0, Nil, 0, BytesReturned, Nil); If Result Then Break; Sleep(LOCK_SLEEP); End; End; Function DismountVolume(AVolumeHandle: THandle): Boolean; Const FSCTL_DISMOUNT_VOLUME = (9 Shl 16) Or (0 Shl 14) Or (8 Shl 2) Or 0; Var BytesReturned : Cardinal; Begin Result := DeviceIoControl(AVolumeHandle, FSCTL_DISMOUNT_VOLUME, Nil, 0, Nil, 0, BytesReturned, Nil); If Not Result Then RaiseLastWin32Error; End; Function PreventRemovalOfVolume(AVolumeHandle: THandle; APreventRemoval: Boolean): Boolean; Const IOCTL_STORAGE_MEDIA_REMOVAL = ($2D Shl 16) Or (1 Shl 14) Or ($201 Shl 2) Or 0; Type TPreventMediaRemoval = Record PreventMediaRemoval: BOOL; End; Var BytesReturned : Cardinal; PMRBuffer : TPreventMediaRemoval; Begin PMRBuffer.PreventMediaRemoval := APreventRemoval; Result := DeviceIoControl(AVolumeHandle, IOCTL_STORAGE_MEDIA_REMOVAL, @PMRBuffer, SizeOf(TPreventMediaRemoval), Nil, 0, BytesReturned, Nil); If Not Result Then RaiseLastWin32Error; End; Function AutoEjectVolume(AVolumeHandle: THandle): Boolean; Const IOCTL_STORAGE_EJECT_MEDIA = ($2D Shl 16) Or (1 Shl 14) Or ($202 Shl 2) Or 0; Var BytesReturned : Cardinal; Begin Result := DeviceIoControl(AVolumeHandle, IOCTL_STORAGE_EJECT_MEDIA, Nil, 0, Nil, 0, BytesReturned, Nil); If Not Result Then RaiseLastWin32Error; End; Var VolumeHandle : THandle; str : String; Begin Result := False; // Open the volume VolumeHandle := OpenVolume(ADrive); If VolumeHandle = INVALID_HANDLE_VALUE Then Exit; Try // Lock and dismount the volume If LockVolume(VolumeHandle) And DismountVolume(VolumeHandle) Then Begin // Set prevent removal to false and eject the volume If PreventRemovalOfVolume(VolumeHandle, False) Then Result := AutoEjectVolume(VolumeHandle); End; Finally // Close the volume so other processes can use the dr CloseHandle(VolumeHandle); End; If Result Then Begin str := ADrive + '\'; ShChangeNotify( SHCNE_MEDIAREMOVED, SHCNF_PATH, pChar(str), Nil); End; End; Gruß Sascha |
Re: USB Stick sicher entfernen unter Vista
Zitat:
Bei einem CD-Laufwerk ginge Schublade auf, mehr nicht. Bei einem Kartenleser könnte man die Karte entnehmen und wieder einlegen -> geht wieder. Einem USB-Stick kann man nach dem Auswerfen beruhigt abziehen, Wiederbeleben geht nur durch erneutes Anschließen. Gruß Uwe |
Re: USB Stick sicher entfernen unter Vista
Zitat:
Ein IOCTL_STORAGE_LOAD_MEDIA nach IOCTL_STORAGE_EJECT_MEDIA scheint Windows (Unter Vista auf jeden Fall! unter XP geht's nicht!) ein erneutes Einstecken des Sticks vorzugaukeln. Ob das Entfernen "sicher" ist kann ich nicht beurteilen. Gruß K-H |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:41 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