USB Devices auflisten
-
Moin,
ich habe momentan ein sehr spezielles Problem. Ich möchte eine Liste aller angeschlossenen USB-Sticks (!) erstellen und zwar mit Namen und Laufwerkbuchstaben. Ich muss gestehen, dass ich bisher nicht mit der WinAPI gearbeitet habe und mich deshalb absolut nicht auskenne. Ich kenne mich nur mit reinem C++ und ein bisschen Qt aus. Wäre nett, wenn jemand Rat weiß.
Gruß,
Mark
-
Also zunächst gibt es da:
DWORD drivetest; drivetest = GetLogicalDrives();Dabei ist der Rückgabewert simpel zu interpretieren:
1.Bit gesetzt: Laufwerk A:
2. Bit: Laufwerk B:
usw.Dann haste schonmal alle logischen Laufwerksnamen die das derzeit System hat.
Mußt nur anhand der gesetzten Bits die Laufwerksnamen als string speichern.Anschließend fütterst du:
UINT GetDriveType(logicaldrive);mit dem string und erhältst den Typ des Laufwerks als Zahl.
DRIVE_UNKNOWN
0 The drive type cannot be determined.DRIVE_NO_ROOT_DIR
1 The root path is invalid; for example, there is no volume mounted at the specified path.DRIVE_REMOVABLE
2 The drive has removable media; for example, a floppy drive, thumb drive, or flash card reader.DRIVE_FIXED
3 The drive has fixed media; for example, a hard drive or flash drive.DRIVE_REMOTE
4 The drive is a remote (network) drive.DRIVE_CDROM
5 The drive is a CD-ROM drive.DRIVE_RAMDISK
6 The drive is a RAM disk.Und um dann die Namen auszulesen ist das vielleicht hilfreich:
http://www.c-plusplus.net/forum/258111
Habe alles mal in einen total grottenschlechten ineffezienten Code gepackt.
Kann man wesentlich eleganter lösen, aber wollte eh nur testen ob es überhaupt klappt.DWORD drivetest; char driveletter[5][12]; drivetest = GetLogicalDrives(); if ((drivetest&1) == 1) strcpy(driveletter[0],"A:"); if ((drivetest&2) == 2) strcpy(driveletter[1],"B:"); if ((drivetest&4) == 4) strcpy(driveletter[2],"C:"); if ((drivetest&8) == 8) strcpy(driveletter[3],"D:"); if ((drivetest&16) == 16) strcpy(driveletter[4],"E:"); if ((drivetest&32) == 32) strcpy(driveletter[5],"F:"); if ((drivetest&64) == 64) strcpy(driveletter[6],"G:"); if ((drivetest&128) ==128) strcpy(driveletter[7],"H:"); if ((drivetest&256) == 256) strcpy(driveletter[8],"I:"); if ((drivetest&512) == 512) strcpy(driveletter[9],"J:"); if ((drivetest&1024) == 1024) strcpy(driveletter[10],"K:"); if ((drivetest&2048) == 2048) strcpy(driveletter[11],"L:"); // usw. usw. DWORD VolumeSerialNumber={0}; DWORD dwMaxNameLength={0}; DWORD dwFileSystemFlags={0}; TCHAR FileSysName[128]; TCHAR VolumeName[128]; for(i=0;i<12;i++) { if (GetDriveType(driveletter[i])==2) { GetVolumeInformation( driveletter[i], VolumeName, sizeof( VolumeName ), &VolumeSerialNumber, &dwMaxNameLength, &dwFileSystemFlags, FileSysName, sizeof( FileSysName ) ); cout << driveletter[i] << "\n"; cout << VolumeName << "\n"; cout << FileSysName << "\n"; cout << VolumeSerialNumber << "\n"; cout <<"\n"; } strcpy(VolumeName,""); }Es werden die logischen und system Namen aller DRIVE_REMOVABLE ausgegeben.
Gruß,
DC
-
Vielen Dank für deine Mühe, werde es direkt mal testen.

-
Hier nochmal ein überarbeiteter Code.
Der Erste gefiel mir garnicht.#include <windows.h> #include <iostream> using namespace std; int main() { DWORD VolumeSerialNumber={0}; DWORD dwMaxNameLength={0}; DWORD dwFileSystemFlags={0}; TCHAR FileSysName[128]; TCHAR VolumeName[128]; DWORD drivetest; char driveletter[]={"A:"}; driveletter[0]--; drivetest = GetLogicalDrives(); for (DWORD aa=1;aa<drivetest+1;aa=aa*2) { driveletter[0]++; if ((drivetest&aa)&&(GetDriveType(driveletter)==2)) // ==2 prüft auf DRIVE_REMOVABLE { GetVolumeInformation( driveletter, VolumeName, sizeof( VolumeName ), &VolumeSerialNumber, &dwMaxNameLength, &dwFileSystemFlags, FileSysName, sizeof( FileSysName ) ); if (dwMaxNameLength!=0) { cout << driveletter << "\n"; cout << VolumeName << "\n"; cout << FileSysName << "\n"; cout << VolumeSerialNumber << "\n"; cout <<"\n"; } strcpy(VolumeName,""); } } system("pause"); }Vielleicht können einige C++ Cracks mir Tips geben, wie man Einiges eleganter löst.
Gruß,
DC
-
Ja danke, kann ich wenigstens erfolgreich einsetzen :). Musste ein paar kleine Änderung wegen Unicode vornehmen, aber konntest du ja nicht wissen.
Ich frage mich nur, warum stürtzt das Programm ab, wenn ich die Funktion setupDevices , die wiederum nur deinem Code ausführt, aufrufe?
Gruß, Mark
-
Keine Ahnung, ich kenne die Funktion noch nicht einmal.
-
void FormatUSB::setupDevices() { liste.clear(); comboBox->clear(); DWORD VolumeSerialNumber={0}; DWORD dwMaxNameLength={0}; DWORD dwFileSystemFlags={0}; TCHAR FileSysName[128]; TCHAR VolumeName[128]; DWORD drivetest; char driveletter[]={"A:"}; driveletter[0]--; drivetest = GetLogicalDrives(); Widen<wchar_t> to_wstring; for (int aa=1;aa<65537;aa=aa*2) { driveletter[0]++; if ((drivetest&aa)&&(GetDriveTypeA(driveletter)==2)) // ==2 prüft auf DRIVE_REMOVABLE { GetVolumeInformation( to_wstring(driveletter).c_str(), VolumeName, sizeof( VolumeName ), &VolumeSerialNumber, &dwMaxNameLength, &dwFileSystemFlags, FileSysName, sizeof( FileSysName ) ); if (dwMaxNameLength!=0) { comboBox->addItem(QString(driveletter)+QString::fromWCharArray(VolumeName)); liste.push_back(QString(driveletter).at(0).toAscii()); } } strcpy(const_cast<char*>(QString::fromWCharArray(VolumeName).toStdString().c_str()),""); } }Das ist sie. Einmaliges aufrufen ist gar kein Problem. Doch wenn ich nun nochmal die Funktion aufrufe um geänderte Volumennamen oder andere Wechseldatenträger zu erkennen, dann stürzt er dabei ab, ohne eine Ausnahme zu werfen.
Gruß, Mark
-
Hab keinen Schimmer.
Da mußte mal an verschiedenen Stellen kleine Ausgaben einbauen und dich langsam an die Stelle des Fehlers vortasten wenn der Debugger nicht mehr hilft.
-
Herzlichen Glückwunsch, umständlicher, fehleranfälliger und gefährlicher als
MarkAPI schrieb:
strcpy(const_cast<char*>QString::fromWCharArray(VolumeName).toStdString().c_str()),"");kann man
VolumeName[0]=0;imho gar nicht schreiben
.Edit:
VolumeName[0]=0;wird so natürlich noch nicht einmal durchgeführt.
-
Ja du sagst es. Ich habe den Fehler gestern noch gefunden und es war natürlich die Stelle, ist mittlerweile aber voll funktionstüchtig. Danke nochmal.
-
Vielleicht noch, um variabel in der Anzahl der Laufwerke zu bleiben, diese Zeile:
for (int aa=1;aa<65537;aa=aa*2)durch diese:
for (DWORD aa=1;aa<drivetest+1;aa=aa*2)ersetzen.