Einzelnen Beitrag anzeigen

Bomberbb

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

Re: USB Stick sicher entfernen unter Vista

  Alt 13. Nov 2009, 13: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