Einzelnen Beitrag anzeigen

Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: Zu Mountpoints Festplatte/Parition bzw. Laufwerksbuchstabe auslesen

  Alt 7. Okt 2015, 08:48
Oder man wirft einen Blick in die Doku https://msdn.microsoft.com/en-us/lib...25(VS.85).aspx und schaut sich das Beispiel an. Schon weiß man, wohin der Gaul laufen muss.
Mit der Funktion FindFirstVolume und etc. hole ich mir ja bereit die VolumeNames. Mir geht es ja darum, daraus jetzt
a) die HDD's zu Nummerieren (Quasi entsprechend ihrem Anschluss am SATA. SATA1=HDD1, SATA2=HDD2 usw).
b) Festzustellen, welche der Partitionsnamen zu welcher HDD gehörte und in der richtigen Reihenfolge
c) Dazu möglich noch den LW-Buchstaben zu erfahren
d) Den Mediatyp auszulesen (Wobei das bei vorhandenem LW-Buchstabe sicherlich nicht das Problem wäre. Aber auch bei Partitionen ohne LW-Buchstaben von Interesse)

Dazu habe ich im MSDN ja was über PARTITION_INFORMATION_EX bzw. IOCTL_DISK_GET_PARTITION_INFO_EX gelesen, komme aber mit der Umsetzung der deklaration nach Delphi nicht wirklich klar. Liegt sicherlich an mir, weil ich mich dabei immer etwas schwer tue.
Auf der Seite (vom Link) finden wir
Zitat:
Examples

For an example, see Displaying Volume Paths.
Und wenn wir dem Link folgen finden wir
Code:
#include <windows.h>
#include <stdio.h>

void DisplayVolumePaths(
        __in PWCHAR VolumeName
        )
{
    DWORD CharCount = MAX_PATH + 1;
    PWCHAR Names    = NULL;
    PWCHAR NameIdx  = NULL;
    BOOL  Success  = FALSE;

    for (;;)
    {
        //
        //  Allocate a buffer to hold the paths.
        Names = (PWCHAR) new BYTE [CharCount * sizeof(WCHAR)];

        if ( !Names )
        {
            //
            //  If memory can't be allocated, return.
            return;
        }

        //
        //  Obtain all of the paths
        //  for this volume.
        Success = GetVolumePathNamesForVolumeNameW(
            VolumeName, Names, CharCount, &CharCount
            );

        if ( Success )
        {
            break;
        }

        if ( GetLastError() != ERROR_MORE_DATA )
        {
            break;
        }

        //
        //  Try again with the
        //  new suggested size.
        delete [] Names;
        Names = NULL;
    }

    if ( Success )
    {
        //
        //  Display the various paths.
        for ( NameIdx = Names;
              NameIdx[0] != L'\0';
              NameIdx += wcslen(NameIdx) + 1 )
        {
            wprintf(L" %s", NameIdx);
        }
        wprintf(L"\n");
    }

    if ( Names != NULL )
    {
        delete [] Names;
        Names = NULL;
    }

    return;
}

void __cdecl wmain(void)
{
    DWORD CharCount           = 0;
    WCHAR DeviceName[MAX_PATH] = L"";
    DWORD Error               = ERROR_SUCCESS;
    HANDLE FindHandle          = INVALID_HANDLE_VALUE;
    BOOL  Found               = FALSE;
    size_t Index               = 0;
    BOOL  Success             = FALSE;
    WCHAR VolumeName[MAX_PATH] = L"";

    //
    //  Enumerate all volumes in the system.
    FindHandle = FindFirstVolumeW(VolumeName, ARRAYSIZE(VolumeName));

    if (FindHandle == INVALID_HANDLE_VALUE)
    {
        Error = GetLastError();
        wprintf(L"FindFirstVolumeW failed with error code %d\n", Error);
        return;
    }

    for (;;)
    {
        //
        //  Skip the \\?\ prefix and remove the trailing backslash.
        Index = wcslen(VolumeName) - 1;

        if (VolumeName[0]    != L'\\' ||
            VolumeName[1]    != L'\\' ||
            VolumeName[2]    != L'?' ||
            VolumeName[3]    != L'\\' ||
            VolumeName[Index] != L'\\')
        {
            Error = ERROR_BAD_PATHNAME;
            wprintf(L"FindFirstVolumeW/FindNextVolumeW returned a bad path: %s\n", VolumeName);
            break;
        }

        //
        //  QueryDosDeviceW does not allow a trailing backslash,
        //  so temporarily remove it.
        VolumeName[Index] = L'\0';

        CharCount = QueryDosDeviceW(&VolumeName[4], DeviceName, ARRAYSIZE(DeviceName));

        VolumeName[Index] = L'\\';

        if ( CharCount == 0 )
        {
            Error = GetLastError();
            wprintf(L"QueryDosDeviceW failed with error code %d\n", Error);
            break;
        }

        wprintf(L"\nFound a device:\n %s", DeviceName);
        wprintf(L"\nVolume name: %s", VolumeName);
        wprintf(L"\nPaths:");
        DisplayVolumePaths(VolumeName);

        //
        //  Move on to the next volume.
        Success = FindNextVolumeW(FindHandle, VolumeName, ARRAYSIZE(VolumeName));

        if ( !Success )
        {
            Error = GetLastError();

            if (Error != ERROR_NO_MORE_FILES)
            {
                wprintf(L"FindNextVolumeW failed with error code %d\n", Error);
                break;
            }

            //
            //  Finished iterating
            //  through all the volumes.
            Error = ERROR_SUCCESS;
            break;
        }
    }

    FindVolumeClose(FindHandle);
    FindHandle = INVALID_HANDLE_VALUE;

    return;
}
der folgende Ausgabe produziert
Code:
Found a device:
 \Device\HarddiskVolume2
Volume name: \\?\Volume{4c1b02c1-d990-11dc-99ae-806e6f6e6963}\
Paths: C:\

Found a device:
 \Device\CdRom0
Volume name: \\?\Volume{4c1b02c4-d990-11dc-99ae-806e6f6e6963}\
Paths: D:\
Das hast du doch gesucht ... oder etwa nicht ...

Ja, das ist kein Delphi, aber man erkennt die Richtung, wohin man laufen muss ...
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat