AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi USB Stick sicher entfernen unter Vista
Thema durchsuchen
Ansicht
Themen-Optionen

USB Stick sicher entfernen unter Vista

Ein Thema von Pichel · begonnen am 15. Sep 2008 · letzter Beitrag vom 24. Apr 2014
 
Bomberbb

Registriert seit: 23. Sep 2003
227 Beiträge
 
#18

Re: USB Stick sicher entfernen unter Vista

  Alt 13. Nov 2009, 12:30
Ich hänge mich hier mal an mit meinem Problem:

Ich nutze folgenden Quelltext:
Delphi-Quellcode:
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;
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?

Gruß

Sascha
  Mit Zitat antworten Zitat
 


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 11:31 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-2025 by Thomas Breitkreuz