Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi USB-Laufwerk ermitteln (https://www.delphipraxis.net/124713-usb-laufwerk-ermitteln.html)

Carsten1234 24. Nov 2008 06:56


USB-Laufwerk ermitteln
 
Hallo,

via dem hier geposteten und leicht modifizierten Code lasse ich mir alle (angeschlossenen) USB-Geräte (HID; USB-Stick) auflisten. Das klappt auch ganz gut, nur möchte ich den Code dahingehend erweitern, dass ich auch den dazugehörigen Laufwerksbuchstaben bekomme, der dem USB-Gerät von Windows zugeordnet wurde (also der Buchstabe, den man im Explodierer sieht).
Frage: Wie ermittle ich den Laufwerksbuchstaben?

Dank vorab für Tipps und Gruß, Carsten

Nachtrag: Ein "nice-to-have" wäre noch, wenn ich auch die VID und PID darüber ermitteln könnte...

Carsten1234 25. Nov 2008 07:57

Re: USB-Laufwerk ermitteln
 
Hallo,

ich bin zwar inzwischen hier fündig geworden, wie ich bei einem Gerätewechsel an den Laufwerksbuchstaben komme, doch wenn, wie in meinem Fall, der USB-Stick bereits vor dem Programmstart gesteckt ist, kommt dieser Event ja nicht vorbei.
Ferner suche ich noch immer nach einer Möglichkeit, zum Laufwerksbuchstaben die VID und PID ermitteln zu können.
Hat denn niemand eine Idee?

Gruß, Carsten

nicodex 25. Nov 2008 08:07

Re: USB-Laufwerk ermitteln
 
Zitat:

Zitat von Carsten1234
Wie ermittle ich den Laufwerksbuchstaben?

Ein Volume kann mehrere Laufwerksbuchstaben haben, oder gar keinen und/oder ein oder mehreren Pfaden (Mount Points) eines anderen Volumes zugeordnet sein. Den Laufwerksbuchstaben gibt es also nicht.

Vielleicht helfen dir die folgenden API-Funktionen als Stichpunkte weiter: FindFirstVolume/FindNextVolume, GetVolumePathNamesForVolumeName, DeviceIoControl(IOCTL_STORAGE_QUERY_PROPERTY/IOCTL_STORAGE_GET_DEVICE_NUMBER/IOCTL_DISK_GET_PARTITION_INFO(_EX)/...).

Edit: GetVolumePathNamesForVolumeName ist recht aufwändig zu emulieren (für Windows 2000) und die API-Funktion liefert bei zirkulären Referenzen auch die erste Rekursion als Ergebnis (A ist in B:\Mount eingebunden und B in A:\Mount, dann ist im Ergebnis neben A:\ auch A:\Mount\Mount enthalten).

Edit: oh, ich vergaß die API QueryDosDevice zu erwähnen :)

Carsten1234 25. Nov 2008 08:51

Re: USB-Laufwerk ermitteln
 
Zitat:

Zitat von nicodex
Ein Volume kann mehrere Laufwerksbuchstaben haben, oder gar keinen und/oder ein oder mehreren Pfaden (Mount Points) eines anderen Volumes zugeordnet sein. Den Laufwerksbuchstaben gibt es also nicht.

Jepp, schon klar. Jedes jemals mit dem PC verbundene USB-Gerät wird in die Registry eingetragen, wobei natürlich die Geräte nicht (mehr) existent sein müssen und somit natürlich auch keinen Laufwerksbuchstaben mehr besitzen.
Ich wollte eigentlich nur (beim Programmstart oder bei einem erkannten Gerätewechsel via wm_DeviceChange) alle Laufwerke/Laufwerksbuchstaben nach Removable-Geräten durchsuchen (sind ja nur max. 26) und dann, wenn es sich um ein USB-Gerät handelt, deren VID und PID auslesen. Mit der unter#2 genannten Routine finde ich ja schon mal den entsprechenden (neuen) Gerätebuchstaben und bekomme via GetVolumeInformation den im Windows Explorer angezeigten Name.
Und irgendwer (Plug&Play Manager?) muss ja den Zusammenhang zw. dem Laufwerksbuchstaben und VID/PID kennen... :wall:

Zitat:

Zitat von nicodex
Vielleicht helfen dir die folgenden API-Funktionen als Stichpunkte weiter:
(...)
Edit: oh, ich vergaß die API QueryDosDevice zu erwähnen :)

Danke für die Hinweise, werde ich mir mal anschauen.

OregonGhost 25. Nov 2008 14:18

Re: USB-Laufwerk ermitteln
 
Zitat:

Zitat von Carsten1234
Zitat:

Zitat von nicodex
Ein Volume kann mehrere Laufwerksbuchstaben haben, oder gar keinen und/oder ein oder mehreren Pfaden (Mount Points) eines anderen Volumes zugeordnet sein. Den Laufwerksbuchstaben gibt es also nicht.

Jepp, schon klar. Jedes jemals mit dem PC verbundene USB-Gerät wird in die Registry eingetragen, wobei natürlich die Geräte nicht (mehr) existent sein müssen und somit natürlich auch keinen Laufwerksbuchstaben mehr besitzen.

Das meinte nicodex wohl nicht. Geh mal in die Datenträgerverwaltung. Dort kannst du für jede Partition, auch für die Partition(en) auf einem USB-Stick, ein oder mehrere Laufwerksbuchstaben zuweisen oder auch alle entfernen. Konsequenterweise findest du nicht alle USB-Sticks, indem du die Laufwerksbuchstaben durchsuchst. Meine Kartenleser-Laufwerke zum Beispiel finden sich alle unter C:\Kartenleser und keiner davon hat einen eigenen Laufwerksbuchstaben :)

Carsten1234 26. Nov 2008 08:47

Re: USB-Laufwerk ermitteln
 
Zitat:

Zitat von OregonGhost
Das meinte nicodex wohl nicht. Geh mal in die Datenträgerverwaltung. Dort kannst du für jede Partition, auch für die Partition(en) auf einem USB-Stick, ein oder mehrere Laufwerksbuchstaben zuweisen oder auch alle entfernen. Konsequenterweise findest du nicht alle USB-Sticks, indem du die Laufwerksbuchstaben durchsuchst.

Auch klar. Nur wird ja dann trotzdem (normalerweise) die Ansicht im Windows Explorer nachgepflegt, ergo muss es dort irgendwo eine Verküpfung zw. dem USB-Gerät selbst und dessen Partition(en) geben. Und wenn eine Partition nicht sichtbar ist, so findet sie GetDriveType auch nicht.
Ich versuche mir gerade an

Delphi-Quellcode:
var HidHandle : THandle;

HidHandle:= CreateFile(PChar('\\.\'+DriveLetter+':'),
                       GENERIC_READ OR GENERIC_WRITE,
                       FILE_SHARE_READ OR FILE_SHARE_WRITE,
                       nil, OPEN_EXISTING, 0, 0);
wobei DriveLetter der über GetDriveType ermittelte Typ 'DRIVE_REMOVABLE' ist.
Im weiteren wollte ich gerne auf die exportierten Funktionen von HID.DLL zugreifen, doch die dortige Funktion HidD_GetAttributes will noch nicht so recht. :gruebel:
In der Online-Hilfe ist dazu zu lesen:
---schnipp---
Comment:
Only user-mode applications can call HidD_GetAttributes. Kernel-mode drivers can use IOCTL_HID_GET_COLLECTION_INFORMATION.
---schnapp---

Und die Sache mit dem IOCTL_HID_GET_COLLECTION_INFORMATION verstehe ich noch nicht so recht...

Gruß, Carsten


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:44 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