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
Antwort Antwort
Seite 2 von 3     12 3      
TurboMartin

Registriert seit: 13. Feb 2006
Ort: Bad Honnef
765 Beiträge
 
Turbo Delphi für Win32
 
#11

Re: USB Stick sicher entfernen unter Vista

  Alt 5. Nov 2009, 14:49
Probier mal Folgendes:

Delphi-Quellcode:
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;
Aufruf mit z.B. EjectVolume('J');
Tomorrow will be cancelled due to lack of interest.

  Mit Zitat antworten Zitat
worker.db

Registriert seit: 5. Nov 2009
8 Beiträge
 
#12

Re: USB Stick sicher entfernen unter Vista

  Alt 6. Nov 2009, 11:59
Vielen Dank für Ihre Antworten.
  Mit Zitat antworten Zitat
worker.db

Registriert seit: 5. Nov 2009
8 Beiträge
 
#13

Re: USB Stick sicher entfernen unter Vista

  Alt 6. Nov 2009, 13:53
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.
  Mit Zitat antworten Zitat
Alter Mann

Registriert seit: 15. Nov 2003
Ort: Berlin
934 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#14

Re: USB Stick sicher entfernen unter Vista

  Alt 6. Nov 2009, 14:33
Hallo TurboMartin,

unter Win 7 und als Admin geht es, unter Vista nicht.

Keine Meldung, nix.

Gruß
  Mit Zitat antworten Zitat
Benutzerbild von Pichel
Pichel

Registriert seit: 25. Feb 2005
Ort: Kassel
65 Beiträge
 
Delphi 7 Professional
 
#15

Re: USB Stick sicher entfernen unter Vista

  Alt 6. Nov 2009, 20:33
Zitat von TurboMartin:
Probier mal Folgendes:
Delphi-Quellcode:
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);
Habs jetzt mal getestet und es kracht genau bei obigem Aufruf in der "kernel32".
Grüße aus Kassel.

Konfuzius sprach: Etwas lernen und sich immer wieder darin üben - schafft das nicht auch Befriedigung?
  Mit Zitat antworten Zitat
worker.db

Registriert seit: 5. Nov 2009
8 Beiträge
 
#16

Re: USB Stick sicher entfernen unter Vista

  Alt 8. Nov 2009, 16:51
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?
  Mit Zitat antworten Zitat
Uwe Sieber

Registriert seit: 21. Jan 2009
4 Beiträge
 
#17

Re: USB Stick sicher entfernen unter Vista

  Alt 8. Nov 2009, 23:00
Zitat von worker.db:
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?

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:
http://www.codeproject.com/KB/system...eByLetter.aspx


Gruß Uwe
  Mit Zitat antworten Zitat
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
Uwe Sieber

Registriert seit: 21. Jan 2009
4 Beiträge
 
#19

Re: USB Stick sicher entfernen unter Vista

  Alt 13. Nov 2009, 12:47
Zitat von Bomberbb:
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?
IOCTL_STORAGE_EJECT_MEDIA meldet nicht das Laufwerk ab, es wirft das Medium aus - daher der Name.
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
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#20

Re: USB Stick sicher entfernen unter Vista

  Alt 13. Nov 2009, 15:31
Zitat von Uwe Sieber:

IOCTL_STORAGE_EJECT_MEDIA meldet nicht das Laufwerk ab, es wirft das Medium aus - daher der Name.
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.
Was ist mit "Anschließen" gemeint?

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
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


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 01:16 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