Wie liste ich physische Festplatten auf?

76

Wie liste ich physische Festplatten in Windows auf? Um eine Liste der "\\\\.\PhysicalDrive0"verfügbaren zu erhalten.

CiNN
quelle

Antworten:

70

WMIC

wmic ist ein sehr vollständiges Werkzeug

wmic diskdrive list

Geben Sie zum Beispiel eine (zu viele) detaillierte Liste an

für weniger info

wmic diskdrive list brief 

C.

Sebastian Godelet erwähnt in den Kommentaren :

In C:

system("wmic diskdrive list");

Wie kommentiert, können Sie auch die WinAPI aufrufen, aber ... wie unter " So erhalten Sie Daten von WMI mit einer C-Anwendung? " Gezeigt , ist dies recht komplex (und wird im Allgemeinen mit C ++ und nicht mit C ausgeführt).

Power Shell

Oder mit PowerShell:

Get-WmiObject Win32_DiskDrive
VonC
quelle
9
-1 Beantwortet nicht die Frage, die fragt, wie es in C. zu tun ist
unixman83
11
+1 Beantwortet die Frage nicht, aber es ist eine sehr nützliche Information :-)
Grodriguez
8
Sie könnten eine system("wmic diskdrive list");in C
Sebastian
Sie können WMI auch über WinApi verwenden und nicht nur die wmic-App aufrufen.
Alex P.
Win32_DiskDrive listet keine physische Festplatte auf, wenn Software-RAID oder StorageSpaces aktiviert sind. Ursprüngliche physische Festplatten wurden herausgefiltert. Einfach mit PowerShell Get-PhysicalDisk zu vergleichen
Dmitry Gusarov
46

Ein Weg, es zu tun:

  1. Zählen Sie logische Laufwerke mit auf GetLogicalDrives

  2. Öffnen Sie für jedes logische Laufwerk eine Datei mit dem Namen "\\.\X:"(ohne Anführungszeichen), wobei X der Buchstabe des logischen Laufwerks ist.

  3. Rufen Sie auf, DeviceIoControlindem Sie das Handle an die im vorherigen Schritt geöffnete Datei übergeben und den dwIoControlCodeParameter auf Folgendes setzen IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS:

    HANDLE hHandle;
    VOLUME_DISK_EXTENTS diskExtents;
    DWORD dwSize;
    [...]
    
    iRes = DeviceIoControl(
        hHandle,
        IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
        NULL,
        0,
        (LPVOID) &diskExtents,
        (DWORD) sizeof(diskExtents),
        (LPDWORD) &dwSize,
        NULL);
    

Dies gibt Informationen über den physischen Speicherort eines logischen Volumes als VOLUME_DISK_EXTENTSStruktur zurück.

In dem einfachen Fall, in dem sich das Volume auf einem einzelnen physischen Laufwerk befindet, ist die Nummer des physischen Laufwerks in verfügbar diskExtents.Extents[0].DiskNumber

Grodriguez
quelle
8
Was ist, wenn eine leere Festplatte ohne (gemountete) Volumes vorhanden ist?
j_kubik
2
Beachten Sie, dass seine vorgeschlagene Implementierung des DeviceIoControl(IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS)Aufrufs fehlschlägt, wenn sich ein Volume über mehrere Festplatten erstreckt. Mit anderen Worten, Sie müssen zuerst nach DeviceIoControlder Größe der VOLUME_DISK_EXTENTSStruktur fragen , dann so viel Speicher zuweisen und erst dann mit dem zugewiesenen Puffer erneut aufrufen. Dies funktioniert wie oben gezeigt, da sich die meisten Volumes auf nur einer Festplatte befinden.
ahmd0
Entschuldigung, ich kann das "\\. \ C:" nicht erfolgreich öffnen, indem ich CreateFile ((_ T ("\\. \ C:"), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIB) verwende / * FILE_FLAG_WRITE_THROUGH | * / FILE_FLAG_NO_BUFFERING, NULL); Könnten Sie mein Problem herausfinden?
Bowman Han
@ ahmd0 VOLUME_DISK_EXTENTSenthält genügend Speicher für eine Ausdehnung, sodass Sie es so aufrufen können, wie es Grodriguez vorschlägt, und dann nachsehen können, success || ERROR_MORE_DATA == GetLastError()da wir uns sowieso nur um die erste Ausdehnung kümmern.
Millie Smith
1
Verwenden Sie 0 anstelle von GENERIC_READ. Dadurch können Sie die Festplatte auch ohne Administratorrechte öffnen. Sie können jedoch Metainformationen wie Festplattenbereiche lesen.
ivan.ukr
32

Dies könnte 5 Jahre zu spät sein :). Aber da ich noch keine Antwort darauf sehe, füge ich dies hinzu.

Wir können Setup-APIs verwenden , um die Liste der Festplatten abzurufen, dh der Geräte im System, die implementiert werden GUID_DEVINTERFACE_DISK.

Sobald wir ihre Gerätepfade haben, können wir ausgeben IOCTL_STORAGE_GET_DEVICE_NUMBERzu konstruieren , "\\.\PHYSICALDRIVE%d"mitSTORAGE_DEVICE_NUMBER.DeviceNumber

Siehe auch SetupDiGetClassDevsFunktion

#include <Windows.h>
#include <Setupapi.h>
#include <Ntddstor.h>

#pragma comment( lib, "setupapi.lib" )

#include <iostream>
#include <string>
using namespace std;

#define START_ERROR_CHK()           \
    DWORD error = ERROR_SUCCESS;    \
    DWORD failedLine;               \
    string failedApi;

#define CHK( expr, api )            \
    if ( !( expr ) ) {              \
        error = GetLastError( );    \
        failedLine = __LINE__;      \
        failedApi = ( api );        \
        goto Error_Exit;            \
    }

#define END_ERROR_CHK()             \
    error = ERROR_SUCCESS;          \
    Error_Exit:                     \
    if ( ERROR_SUCCESS != error ) { \
        cout << failedApi << " failed at " << failedLine << " : Error Code - " << error << endl;    \
    }

int main( int argc, char **argv ) {

    HDEVINFO diskClassDevices;
    GUID diskClassDeviceInterfaceGuid = GUID_DEVINTERFACE_DISK;
    SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
    PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData;
    DWORD requiredSize;
    DWORD deviceIndex;

    HANDLE disk = INVALID_HANDLE_VALUE;
    STORAGE_DEVICE_NUMBER diskNumber;
    DWORD bytesReturned;

    START_ERROR_CHK();

    //
    // Get the handle to the device information set for installed
    // disk class devices. Returns only devices that are currently
    // present in the system and have an enabled disk device
    // interface.
    //
    diskClassDevices = SetupDiGetClassDevs( &diskClassDeviceInterfaceGuid,
                                            NULL,
                                            NULL,
                                            DIGCF_PRESENT |
                                            DIGCF_DEVICEINTERFACE );
    CHK( INVALID_HANDLE_VALUE != diskClassDevices,
         "SetupDiGetClassDevs" );

    ZeroMemory( &deviceInterfaceData, sizeof( SP_DEVICE_INTERFACE_DATA ) );
    deviceInterfaceData.cbSize = sizeof( SP_DEVICE_INTERFACE_DATA );
    deviceIndex = 0;

    while ( SetupDiEnumDeviceInterfaces( diskClassDevices,
                                         NULL,
                                         &diskClassDeviceInterfaceGuid,
                                         deviceIndex,
                                         &deviceInterfaceData ) ) {

        ++deviceIndex;

        SetupDiGetDeviceInterfaceDetail( diskClassDevices,
                                         &deviceInterfaceData,
                                         NULL,
                                         0,
                                         &requiredSize,
                                         NULL );
        CHK( ERROR_INSUFFICIENT_BUFFER == GetLastError( ),
             "SetupDiGetDeviceInterfaceDetail - 1" );

        deviceInterfaceDetailData = ( PSP_DEVICE_INTERFACE_DETAIL_DATA ) malloc( requiredSize );
        CHK( NULL != deviceInterfaceDetailData,
             "malloc" );

        ZeroMemory( deviceInterfaceDetailData, requiredSize );
        deviceInterfaceDetailData->cbSize = sizeof( SP_DEVICE_INTERFACE_DETAIL_DATA );

        CHK( SetupDiGetDeviceInterfaceDetail( diskClassDevices,
                                              &deviceInterfaceData,
                                              deviceInterfaceDetailData,
                                              requiredSize,
                                              NULL,
                                              NULL ),
             "SetupDiGetDeviceInterfaceDetail - 2" );

        disk = CreateFile( deviceInterfaceDetailData->DevicePath,
                           GENERIC_READ,
                           FILE_SHARE_READ | FILE_SHARE_WRITE,
                           NULL,
                           OPEN_EXISTING,
                           FILE_ATTRIBUTE_NORMAL,
                           NULL );
        CHK( INVALID_HANDLE_VALUE != disk,
             "CreateFile" );

        CHK( DeviceIoControl( disk,
                              IOCTL_STORAGE_GET_DEVICE_NUMBER,
                              NULL,
                              0,
                              &diskNumber,
                              sizeof( STORAGE_DEVICE_NUMBER ),
                              &bytesReturned,
                              NULL ),
             "IOCTL_STORAGE_GET_DEVICE_NUMBER" );

        CloseHandle( disk );
        disk = INVALID_HANDLE_VALUE;

        cout << deviceInterfaceDetailData->DevicePath << endl;
        cout << "\\\\?\\PhysicalDrive" << diskNumber.DeviceNumber << endl;
        cout << endl;
    }
    CHK( ERROR_NO_MORE_ITEMS == GetLastError( ),
         "SetupDiEnumDeviceInterfaces" );

    END_ERROR_CHK();

Exit:

    if ( INVALID_HANDLE_VALUE != diskClassDevices ) {
        SetupDiDestroyDeviceInfoList( diskClassDevices );
    }

    if ( INVALID_HANDLE_VALUE != disk ) {
        CloseHandle( disk );
    }

    return error;
}
arun
quelle
Hinzufügen eines weiteren Links (ich hatte nicht genügend Mitarbeiter, um in der Antwort zu posten) Setup-API-Funktionen
Arun
1
Klingt interessant. Vollständiger als meine Antwort oben. +1
VonC
Beachten Sie, dass diese SetupAPI Funktionen werden nicht alle nur Liste physischen Laufwerke , sondern virtuelle diejenigen, auch - in der Tat jeder registrierte Plattenlaufwerk - Schnittstelle aufgeführt werden, methinks dies kann Lösung für die Frage sein , aber es wird auch eine Menge „Rauschdaten“ erzeugen, Die Verwendung von SetupAPI ist viel komplexer als in dieser Antwort vorgeschlagen
spezialisiert auf den
Ich habe eine kleine Bibliothek namens libwindevblk geschrieben, basierend auf der obigen Antwort, die Laufwerke auflistet , Datenträgernamen abruft, wenn möglich, und eine API bereitstellt, die das einfache Lesen / Schreiben auf Partitionen ermöglicht
Vincent Rich
19

Die Antwort ist viel einfacher als alle oben genannten Antworten. Die Liste der physischen Laufwerke wird tatsächlich in einem Registrierungsschlüssel gespeichert, der auch die Gerätezuordnung enthält.

HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ disk \ Enum

Count ist die Anzahl der PhysicalDrive # und jeder nummerierte Registrierungswert ist das entsprechende physische Laufwerk.

Der Registrierungswert "0" ist beispielsweise PhysicalDrive0. Der Wert ist das tatsächliche Gerät, dem PhysicalDrive0 zugeordnet ist. Der hier enthaltene Wert kann in geben wird CM_Locate_DevNode innerhalb Parameter pDeviceID die Plug - and - Play - Dienste zu nutzen. Auf diese Weise können Sie eine Fülle von Informationen auf dem Gerät sammeln. B. die Eigenschaften des Geräte-Managers wie "Benutzerfreundlicher Anzeigename", wenn Sie einen Namen für das Laufwerk, Seriennummern und mehr benötigen.

Es sind keine WMI-Dienste erforderlich, die möglicherweise nicht auf dem System oder einem anderen Hacker ausgeführt werden. Diese Funktionalität ist in Windows seit mindestens 2000 vorhanden und ist in Windows 10 weiterhin der Fall.

HooliganCoder
quelle
Interessante Alternative, wahrscheinlich relevanter als meine 7+ Jahre alte Antwort. +1
VonC
Die beste Option meiner Meinung nach, da sie einfach, zuverlässig und die Verwendung der Registrierung wahrscheinlich das ist, was Entwickler von Windows beim Entwerfen von Windows wollten.
Felknight
Weitaus bessere Option als meine Antwort, +1. Die letzte Frage ist, warum es tatsächliche Informationen enthalten muss. Ist es dokumentiert? In welchem ​​Moment schreibt Windows dort Daten? Verwendet die Managementkonsole es?
polkovnikov.ph
Ausgezeichnete Methode, hat aber einen kleinen Nachteil: Es kann nicht jede physische Laufwerksgröße auflisten, da diese nicht in der Registrierung gespeichert sind (WMI-Dienste bieten sie jedoch an). Für Dinge wie den Hersteller und das Modell jedes Laufwerks ist es immer noch viel besser und weniger ressourcenintensiv, also +1 von mir. Ich muss die Größe jedes Laufwerks ermitteln und verwende dies nicht in C, daher muss ich den WMI-Weg gehen. Es ist mehr oder weniger die gleiche Geschichte wie mit dem physischen Speicher, dessen detaillierte Daten auch nicht in der Registrierung gespeichert sind ...
Yin Cognyto
"seit mindestens 2000 in Windows vorhanden": Kann nicht bestätigt werden. Der Registrierungsschlüssel fehlt in Windows XP und Windows 7.
Thomas
12

Ich habe ein Open-Source-Programm namens "dskwipe" geändert, um diese Festplatteninformationen daraus zu ziehen. Dskwipe ist in C geschrieben, und Sie können diese Funktion daraus ziehen. Die Binärdatei und die Quelle sind hier verfügbar: dskwipe 0.3 wurde veröffentlicht

Die zurückgegebenen Informationen sehen ungefähr so ​​aus:

Device Name                         Size Type      Partition Type
------------------------------ --------- --------- --------------------
\\.\PhysicalDrive0               40.0 GB Fixed
\\.\PhysicalDrive1               80.0 GB Fixed
\Device\Harddisk0\Partition0     40.0 GB Fixed
\Device\Harddisk0\Partition1     40.0 GB Fixed     NTFS
\Device\Harddisk1\Partition0     80.0 GB Fixed
\Device\Harddisk1\Partition1     80.0 GB Fixed     NTFS
\\.\C:                           80.0 GB Fixed     NTFS
\\.\D:                            2.1 GB Fixed     FAT32
\\.\E:                           40.0 GB Fixed     NTFS
Mick
quelle
1
Ich dachte, es wäre es, aber es erzwingt eine brutale Suche nach den Laufwerken. Gibt es nicht eine API, die nur die Geräte zurückmeldet?
CiNN
2
Ja. SetupApi in Win32, Funktionsnamen beginnen mit SetupDi
Warren P
10

Der einzig sichere Weg, dies zu tun, ist anzurufen CreateFile() alle bei \\.\Physicaldiskxdenen x zwischen 0 und 15 liegt (16 ist die maximal zulässige Anzahl von Festplatten). Überprüfen Sie den zurückgegebenen Handle-Wert. Wenn ungültig, GetLastError()auf ERROR_FILE_NOT_FOUND prüfen . Wenn etwas anderes zurückgegeben wird, ist die Festplatte vorhanden, Sie können jedoch aus irgendeinem Grund nicht darauf zugreifen.

anni
quelle
7
Woher hast du diese Nummer?
Schwachstellen
1
Warum auf beschränken 15? Zählen Sie weiter, bis Sie versagen. Ich bin nicht sicher, ob eine Gerätenummer vom Betriebssystem übersprungen wird.
Ajay
1
@ Ajay meine beste Vermutung ist für den Fall, dass Sie Gerät A, Gerät B anschließen, dann Gerät A
Howl
10

Die einzig richtige Antwort ist die von @Grodriguez, und hier ist ein Code, den er zu faul war, um ihn zu schreiben:

#include <windows.h>
#include <iostream>
#include <bitset>
#include <vector>
using namespace std;

typedef struct _DISK_EXTENT {
    DWORD         DiskNumber;
    LARGE_INTEGER StartingOffset;
    LARGE_INTEGER ExtentLength;
} DISK_EXTENT, *PDISK_EXTENT;

typedef struct _VOLUME_DISK_EXTENTS {
    DWORD       NumberOfDiskExtents;
    DISK_EXTENT Extents[ANYSIZE_ARRAY];
} VOLUME_DISK_EXTENTS, *PVOLUME_DISK_EXTENTS;

#define CTL_CODE(DeviceType, Function, Method, Access) \
    (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
#define IOCTL_VOLUME_BASE ((DWORD)'V')
#define METHOD_BUFFERED 0
#define FILE_ANY_ACCESS 0x00000000
#define IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS CTL_CODE(IOCTL_VOLUME_BASE, 0, METHOD_BUFFERED, FILE_ANY_ACCESS)

int main() {
    bitset<32> drives(GetLogicalDrives());
    vector<char> goodDrives;
    for (char c = 'A'; c <= 'Z'; ++c) {
        if (drives[c - 'A']) {
            if (GetDriveType((c + string(":\\")).c_str()) == DRIVE_FIXED) {
                goodDrives.push_back(c);
            }
        }
    }
    for (auto & drive : goodDrives) {
        string s = string("\\\\.\\") + drive + ":";
        HANDLE h = CreateFileA(
            s.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
            OPEN_EXISTING, FILE_FLAG_NO_BUFFERING | FILE_FLAG_RANDOM_ACCESS, NULL
        );
        if (h == INVALID_HANDLE_VALUE) {
            cerr << "Drive " << drive << ":\\ cannot be opened";
            continue;
        }
        DWORD bytesReturned;
        VOLUME_DISK_EXTENTS vde;
        if (!DeviceIoControl(
            h, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
            NULL, 0, &vde, sizeof(vde), &bytesReturned, NULL
        )) {
            cerr << "Drive " << drive << ":\\ cannot be mapped into physical drive";
            continue;
        }
        cout << "Drive " << drive << ":\\ is on the following physical drives: ";
        for (int i = 0; i < vde.NumberOfDiskExtents; ++i) {
            cout << vde.Extents[i].DiskNumber << ' ';
        }
        cout << endl;
    }
}

Ich denke, dass die Installation des Windows Driver Development Kit ein ziemlich langwieriger Prozess ist, daher habe ich die Deklarationen beigefügt, die DeviceIoControlfür diese Aufgabe verwendet werden müssen.

polkovnikov.ph
quelle
1
Außerdem: Die Neudefinition von Windows-Makros ist möglicherweise die schlechteste Idee aller Zeiten. Eine solche Anwendung wird kaputt gehen und bald nicht mehr funktionieren.
Spezialisiert
2
Wie ich in meinem Kommentar zu dieser Antwort gezeigt habe, rufen Sie DeviceIoControlfalsch an. Sie können nicht davon ausgehen, dass es nur einen Umfang gibt. Sie müssen nach DeviceIoControlder Größe des benötigten VOLUME_DISK_EXTENTSPuffers fragen .
ahmd0
@ ahmd0 Ich würde es gerne beheben. Könnten Sie bitte auf die msdn-Seite verweisen, die ein solches Verhalten beschreibt? (Obwohl die Möglichkeit, eine Festplatte zu erstellen, die sich in zwei Bereichen befindet, ebenfalls in Ordnung wäre, da ich gerade keine Möglichkeit gefunden habe, sie zu testen.)
polkovnikov.ph
@ polkovnikov.ph: msdn.microsoft.com/en-us/library/windows/desktop/aa365727.aspx Sie rufen DeviceIoControlim Grunde den Speicher für eine Single auf, VOLUME_DISK_EXTENTSwie Sie es getan haben, prüfen dann aber, ob sie fehlgeschlagen ist, und prüfen, ob sie zurückgegeben wurde Weisen Sie ERROR_MORE_DATAin GetLastErrorund wenn ja, einen neuen Puffer für die NumberOfDiskExtentsAnzahl der zurückgegebenen DISK_EXTENTStrukturen zu, rufen Sie ihn DeviceIoControlerneut auf und stellen Sie sicher, dass er erfolgreich ist. Sie tun dies offensichtlich nicht, wenn der erste Anruf DeviceIoControlerfolgreich ist.
ahmd0
1
Nicht jedem physischen Laufwerk wird ein logisches Laufwerk zugeordnet, und selbst dann wird nicht jedem logischen Laufwerk ein Laufwerksbuchstabe zugewiesen.
Anni
9

GetLogicalDrives () listet alle gemounteten Festplattenpartitionen auf, keine physischen Laufwerke.

Sie können die Laufwerksbuchstaben mit (oder ohne) GetLogicalDrives auflisten und dann QueryDosDevice () aufrufen, um herauszufinden, welchem ​​physischen Laufwerk der Buchstabe zugeordnet ist.

Alternativ können Sie die Informationen in der Registrierung unter HKEY_LOCAL_MACHINE \ SYSTEM \ MountedDevices dekodieren. Die dortigen binären Datencodierungen sind jedoch nicht offensichtlich. Wenn Sie eine Kopie von Russinovichs und Solomons Buch Microsoft Windows Internals haben, wird diese Registrierungsstruktur in Kapitel 10 erläutert.

Stirb in Sente
quelle
1
QueryDosDevice retuens Partition, nicht die Festplatte selbst. Einzelne Festplatte wird in C: und D:, Win7 x64 aufgeteilt. Also: c => "\ Device \ HarddiskVolume2"; d => "\ Device \ HarddiskVolume3 '"
Arioch' Der
4

Diese WMIC-Befehlskombination funktioniert einwandfrei:

wmic volume list brief
user2506992
quelle
Volumes! = physische Festplatten. Dieser Befehl listet keine physischen Datenträger auf, die keine Volumes enthalten, z. B. nicht initialisierte Datenträger. (Auch wenn es sich nicht um ein schwerwiegendes Problem wie das vorherige handelt, muss die Ausgabe dieses Befehls weiter verarbeitet werden, um die IDs physischer Festplatten mit mehreren Volumes
Keith Russell
2

Vielleicht möchten Sie die alten A: - und B: -Laufwerke einbeziehen, da Sie nie wissen, wer sie möglicherweise verwendet! Ich habe es satt, dass USB-Laufwerke meine beiden SDHC-Laufwerke, die nur für Readyboost bestimmt sind, anstoßen. Ich habe sie hohen Buchstaben Z: Y: mit einem Dienstprogramm zugewiesen, das Geräten Laufwerksbuchstaben nach Ihren Wünschen zuweist. Ich habe mich gefragt ... Kann ich einen Readyboost-Laufwerksbuchstaben A: erstellen? JA! Kann ich meinen zweiten SDHC-Laufwerksbuchstaben als B: eingeben? JA!

Ich habe früher Floppy Drives verwendet und hätte nie gedacht, dass A: oder B: für Readyboost nützlich sein würden.

Mein Punkt ist, nehmen Sie nicht an, dass A: & B: von niemandem für irgendetwas verwendet wird. Vielleicht finden Sie sogar den alten SUBST-Befehl, der verwendet wird!

Leberblümchen
quelle
1

Ich bin heute in meinem RSS-Reader darauf gestoßen. Ich habe eine sauberere Lösung für Sie. Dieses Beispiel befindet sich in Delphi, kann jedoch sehr einfach in C / C ++ konvertiert werden (es ist alles Win32).

Fragen Sie alle Wertnamen vom folgenden Registrierungsspeicherort ab: HKLM \ SYSTEM \ MountedDevices

Übergeben Sie sie nacheinander an die folgende Funktion, und Sie erhalten den Gerätenamen zurück. Ziemlich sauber und einfach! Ich habe diesen Code in einem Blog hier gefunden.

function VolumeNameToDeviceName(const VolName: String): String;
var
  s: String;
  TargetPath: Array[0..MAX_PATH] of WideChar;
  bSucceeded: Boolean;
begin
  Result := ”;
  // VolumeName has a format like this: \\?\Volume{c4ee0265-bada-11dd-9cd5-806e6f6e6963}\
  // We need to strip this to Volume{c4ee0265-bada-11dd-9cd5-806e6f6e6963}
  s :=  Copy(VolName, 5, Length(VolName) - 5);

  bSucceeded := QueryDosDeviceW(PWideChar(WideString(s)), TargetPath, MAX_PATH) <> 0;
  if bSucceeded then
  begin
    Result := TargetPath;
  end
  else begin
    // raise exception
  end;

end;
Mick
quelle
2
Ich möchte den physischen Namen haben, damit ich mit nicht zugewiesenem Speicherplatz spielen kann. Ich vermute also, dass dieser nicht zugewiesene Speicherplatz keine angehängte Volume-Anleitung hat ...
CiNN
1
'Fraid, das ist nicht das, wonach wir suchen, und es ähnelt der Antwort von @ Alnitak.
Matt Joiner
1
Sie sollten SetupApi in Windows XP und höher verwenden und nicht mehr die Registrierung verwenden, wie dies in Win98 der Fall war, aber nicht mehr.
Warren P
1

Wenn Sie "physischen" Zugriff wünschen, entwickeln wir diese API, mit der Sie eventuell mit Speichergeräten kommunizieren können. Es ist Open Source und Sie können den aktuellen Code für einige Informationen sehen. Weitere Funktionen finden Sie unter: https://github.com/virtium/vtStor

Phandinhlan
quelle
1

Hier ist eine neue Lösung für WMI-Aufrufe.
Dann müssen Sie nur noch anrufen:

queryAndPrintResult(L"SELECT * FROM Win32_DiskDrive", L"Name");
Nur Schatten
quelle
-3

Erstellen Sie eine Liste aller Buchstaben im englischen US-Alphabet und überspringen Sie a & b. "CDEFGHIJKLMNOPQRSTUVWXYZ". Öffnen Sie jedes dieser Laufwerke mit CreateFilez CreateFile("\\.\C:"). Wenn es nicht zurückkehrt, haben INVALID_HANDLE_VALUESie ein "gutes" Laufwerk. Nehmen Sie als nächstes dieses Handle und führen Sie es durch DeviceIoControl, um die Disk # zu erhalten. Siehe meine verwandte Antwort für weitere Details .

unixman83
quelle