Autor Beitrag
Frühlingsrolle
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2279
Erhaltene Danke: 419

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Mo 17.10.16 13:23 
Hallo Forum

Problemstellung:
Ich habe mir von diesen Beitrag (eject-usb-device-via-c-sharp) den Code nach Delphi übersetzt. Er scheint bei USB Sticks jeglicher Art zu funktionieren, jedoch nicht bei allen externen HDD Festplatten. Am gegebenen Dateisystem (NFTS, FAT32, ...) liegt es schonmal nicht, und ob er am USB 2.0/3.0 Slot hängt, scheinbar auch nicht. Vielleicht ist es eine Frage des Treibers, jedoch wurde jede der Festplatten anhand des Betriebssystems XP und 7 erkannt und ohne externe Quellen, konfiguriert, also ohne Treibersuche aus'n Netz. Wieso funktioniert der Code nun nur wahlweise bei gewissen externen Festplatten? :suspect:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
{
  [*] Note:
    Minimum support: Windows XP / Windows Server 2003

  [*] Declare Functions if needed:

  Name: DeviceIoControl
  DLL: Kernel32.dll
  ------------------------------------------
  BOOL WINAPI DeviceIoControl(
  _In_        HANDLE       hDevice,
  _In_        DWORD        dwIoControlCode,
  _In_opt_    LPVOID       lpInBuffer,
  _In_        DWORD        nInBufferSize,
  _Out_opt_   LPVOID       lpOutBuffer,
  _In_        DWORD        nOutBufferSize,
  _Out_opt_   LPDWORD      lpBytesReturned,
  _Inout_opt_ LPOVERLAPPED lpOverlapped

  Name: CreateFileW (Unicode) and CreateFileA (ANSI)
  DLL: Kernel32.dll
  ------------------------------------------
  HANDLE WINAPI CreateFile(
  _In_     LPCTSTR               lpFileName,
  _In_     DWORD                 dwDesiredAccess,
  _In_     DWORD                 dwShareMode,
  _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  _In_     DWORD                 dwCreationDisposition,
  _In_     DWORD                 dwFlagsAndAttributes,
  _In_opt_ HANDLE                hTemplateFile

  Name: CloseHandle
  DLL: Kernel32.dll
  ------------------------------------------
  BOOL WINAPI CloseHandle(
  _In_ HANDLE hObject
}


unit ufrDrive;

interface

uses
  Classes, Windows;

type
  _PREVENT_MEDIA_REMOVAL = record
    PreventMediaRemoval: Boolean;
  end;
  {$EXTERNALSYM _PREVENT_MEDIA_REMOVAL}
  TPreventMediaRemoval = _PREVENT_MEDIA_REMOVAL;
  PREVENT_MEDIA_REMOVAL = _PREVENT_MEDIA_REMOVAL;
  {$EXTERNALSYM PREVENT_MEDIA_REMOVAL}

  TfrDrive = class
  private
    function LockVolume(Handle: THandle): Boolean;
    function DismountVolume(Handle: THandle): Boolean;
    function AutoEjectVolume(Handle: THandle): Boolean;
    function PreventRemovalOfVolume(Handle: THandle; Prevent: Boolean): Boolean;
  public
    function OpenVolume(DriveLetter: AnsiChar): THandle;
    function CloseVolume(Handle: THandle): Boolean;
    function UnlockVolume(Handle: THandle): Boolean;
    function Eject(Handle: THandle): Boolean;
  end;

implementation

const
  //GENERIC_READ                = $80000000;
  //GENERIC_WRITE               = $40000000;
  //FILE_SHARE_READ             = $00000001;
  //FILE_SHARE_WRITE            = $00000002;
  OPEN_EXISTING               = $00000003;
  FSCTL_LOCK_VOLUME           = $00090018;
  FSCTL_UNLOCK_VOLUME         = $0009001C;
  FSCTL_DISMOUNT_VOLUME       = $00090020;
  IOCTL_STORAGE_EJECT_MEDIA   = $002D4808;
  IOCTL_STORAGE_MEDIA_REMOVAL = $002D4804;

function TfrDrive.LockVolume(Handle: THandle): Boolean;
var
  byteReturned: UInt;
begin
  result := DeviceIoControl(Handle,
                            FSCTL_LOCK_VOLUME,
                            nil,
                            0,
                            nil,
                            0,
                            byteReturned,
                            nil);
end;

function TfrDrive.DismountVolume(Handle: THandle): Boolean;
var
  byteReturned: UInt;
begin
  result := DeviceIoControl(Handle,
                            FSCTL_DISMOUNT_VOLUME,
                            nil,
                            0,
                            nil,
                            0,
                            byteReturned,
                            nil);
end;

function TfrDrive.AutoEjectVolume(Handle: THandle): Boolean;
var
  byteReturned: UInt;
begin
  result := DeviceIoControl(Handle,
                            IOCTL_STORAGE_EJECT_MEDIA,
                            nil,
                            0,
                            nil,
                            0,
                            byteReturned,
                            nil);
end;

function TfrDrive.PreventRemovalOfVolume(Handle: THandle;
  Prevent: Boolean): Boolean;
var
  byteReturned: UInt;
  pmrLock: TPreventMediaRemoval;
begin
  pmrLock.PreventMediaRemoval := Prevent;
  result := DeviceIoControl(Handle,
                            IOCTL_STORAGE_MEDIA_REMOVAL,
                            @pmrLock,
                            SizeOf(pmrLock),
                            nil,
                            0,
                            byteReturned,
                            nil);
end;

function TfrDrive.OpenVolume(DriveLetter: AnsiChar): THandle;
var
  Path: string;
begin
  Path := '\\.\' + DriveLetter + ':';
  result := CreateFile(PAnsiChar(Path),
                       GENERIC_READ or GENERIC_WRITE,
                       FILE_SHARE_READ or FILE_SHARE_WRITE,
                       nil,
                       OPEN_EXISTING,
                       0,
                       0);
end;

function TfrDrive.CloseVolume(Handle: THandle): Boolean;
begin
  result := CloseHandle(Handle);
end;

function TfrDrive.UnlockVolume(Handle: THandle): Boolean;
var
  byteReturned: UInt;
begin
  result := DeviceIoControl(Handle,
                            FSCTL_UNLOCK_VOLUME,
                            nil,
                            0,
                            nil,
                            0,
                            byteReturned,
                            nil);
end;

function TfrDrive.Eject(Handle: THandle): Boolean;
var
  b: Boolean;
begin
  b := false;
  if LockVolume(Handle) and DismountVolume(Handle) then
  begin
    PreventRemovalOfVolume(Handle, false);
    b := AutoEjectVolume(Handle);
  end;
  result := b;
end;

end.


// Aufruf
begin
  h := frDrive.OpenVolume('I');
  frDrive.Eject(h);
  sleep(5000);
  //frDrive.UnlockVolume(h);
  frDrive.CloseVolume(h);
end;

_________________
„Politicians are put there to give you the idea that you have freedom of choice. You don’t. You have no choice. You have owners. They own you. They own everything." (George Denis Patrick Carlin)


Zuletzt bearbeitet von Frühlingsrolle am Do 20.10.16 09:32, insgesamt 1-mal bearbeitet
Frühlingsrolle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2279
Erhaltene Danke: 419

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Mi 19.10.16 12:21 
Zu FSCTL_LOCK_VOLUME steht:

- If the specified volume is a system volume or contains a page file, the operation fails.
- If there are any open files on the volume, this operation will fail. Conversely, success of this operation indicates there are no open files.

Das zum besagten Zeitpunkt weder eine Datei noch ein Ordner aus einem der Laufwerke geöffnet wird, bleibt nur noch eine Möglichkeit:

Zitat:
or contains a page file, the operation fails.

Was ist mit page file gemeint?

_________________
„Politicians are put there to give you the idea that you have freedom of choice. You don’t. You have no choice. You have owners. They own you. They own everything." (George Denis Patrick Carlin)
t.roller
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 118
Erhaltene Danke: 34



BeitragVerfasst: Mi 19.10.16 12:56 
Page File = Auslagerungsdatei = pagefile.sys.
Einloggen, um Attachments anzusehen!


Zuletzt bearbeitet von t.roller am Mi 19.10.16 14:19, insgesamt 1-mal bearbeitet

Für diesen Beitrag haben gedankt: Frühlingsrolle
Frühlingsrolle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2279
Erhaltene Danke: 419

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Mi 19.10.16 13:08 
Besten Dank. Wenn du mir noch sagen könntest, welche Dateiendung, eventuell Dateinamen diese haben könnte, wäre ich zufrieden.

_________________
„Politicians are put there to give you the idea that you have freedom of choice. You don’t. You have no choice. You have owners. They own you. They own everything." (George Denis Patrick Carlin)
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4416
Erhaltene Danke: 901


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 19.10.16 14:15 
Pagefile.sys

Ich bezweifle aber das es daran liegt. Du wüßtest es wenn du die Windowseinstellungen so geändert hättest um das Pagefile da abzulegen.
Kannst du auschließen das irgendwas auf diesem Laufwerk noch offene Files hat (Anti Viren Tools, Dropbox-artige Cloudtools)

Für diesen Beitrag haben gedankt: Frühlingsrolle
t.roller
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 118
Erhaltene Danke: 34



BeitragVerfasst: Mi 19.10.16 14:20 
Die Voreinstellung ist automatisch und unsichtbar.
Frühlingsrolle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2279
Erhaltene Danke: 419

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Mi 19.10.16 23:39 
Du sagst es, ich "wüsste" was davon. Nachdem alle relevanten Anwendungen inkl. der Anti Viren Anwendung geschlossen wurden, habe ich mir die Prozesse mit einer Spy Anwendung näher angesehen. Da war leider nichts.
Also habe ich es an einem anderen PC gestestet und da hat es funktioniert. Im Anschluss wieder am vorherigen PC angeschlossen, da gings doch auf einmal, bis auf einen einzigen USB 3.0 Slot. Entweder fehlen dem neue Treiber oder er ist im gewissen Maße defekt. Dennoch kann er die externe Festplatte sowie ihre Inhalte lesen und schreiben.
Ist es doch ein Treiber Problem (seitens des Slots)?

_________________
„Politicians are put there to give you the idea that you have freedom of choice. You don’t. You have no choice. You have owners. They own you. They own everything." (George Denis Patrick Carlin)
t.roller
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 118
Erhaltene Danke: 34



BeitragVerfasst: Do 20.10.16 07:14 
Wie gross ist die Geschwindigkeit der USB3.0-HDD?
Hardware-mäßig sind USB3.0 und USB2.0 hintereinander geschaltet:
Ist kein USB3.0-Gerät angeschlossen übernimmt USB2.0.
Das Gleiche geschieht bei fehlendem xHCL-Treiber.

Man kann auch einstellen: schnelles Entfernen oder Cache.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 18694
Erhaltene Danke: 1620

W10 x64 (Chrome, IE11)
Delphi 10.2 Ent, Oxygene, C# (VS 2015), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 20.10.16 07:53 
Ich erinnere mich noch wie ich unter Windows XP, Vista und 7 manchmal genau deshalb geflucht habe. Das Antivirenprogramm hat noch gescannt, der Papierkorb wurde von Windows zugegriffen, usw. und deshalb Stick oder Platte nicht getrennt. Und dabei meine ich aus der Tray über die Standardfunktion von Windows.

Erst ab Windows 8 funktioniert das sauber. Seitdem hatte ich damit noch nie Probleme. Ich konnte immer beim ersten Versuch entladen. Bis Windows 7 musste ich es immer wieder mal mehrfach wiederholen bis es ging.

Deshalb halte ich das Verhalten für normal bis Windows 7.
Frühlingsrolle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2279
Erhaltene Danke: 419

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Do 20.10.16 09:23 
Damit liegst du wohl richtig. Es verhält sich doch recht launisch. Für das eigentliche Vorhaben wird ein zuästzlicher Workaround nötig sein. Aber ansonsten erfüllt die Klasse ihren Zweck. Den Quelltext werde ich ich noch ein wenig formatieren.

Das Thema hat sich erledigt !!!

_________________
„Politicians are put there to give you the idea that you have freedom of choice. You don’t. You have no choice. You have owners. They own you. They own everything." (George Denis Patrick Carlin)