2013-03-13 14 views
7

Ich versuche, die Gesamtgröße eines physischen Laufwerks (nicht zugewiesene + primäre Partitionen + erweiterte Partitionen Größe) zu erhalten.Get Gesamtgröße einer Festplatte in C++ Windows

Ich habe Plattennamen als \\.\PhysicalDriveX

ich mit GetDiskFreeSpaceEx versucht, aber es nicht korrektem Ergebnis nicht geben, wenn die Partition eine erweiterte Partition ist, in diesem Fall ist es die Gesamtgröße der Partition zurück.

BOOL ret = FALSE; 
ULARGE_INTEGER ulFreeSpace; 
ULARGE_INTEGER ulTotalSpace; 
ULARGE_INTEGER ulTotalFreeSpace; 
__int64 ulTotalUsedSpace = 0; 
GetDiskFreeSpaceEx(szBuffer, &ulFreeSpace, &ulTotalSpace, &ulTotalFreeSpace); 
*diskSize = ulTotalSpace.QuadPart; 

kann ich die Partition Informationen erhalten DeviceIoControl mit mit IOCTL_DISK_GET_DRIVE_LAYOUT_EX aber ich bin immer verwirrt über erweiterte Partition Größe.

Gibt es eine Möglichkeit, dass ich die Gesamtgröße einer Festplatte in C++ auf Windows genau erhalten kann ??

Antwort

7

Da Sie über die physische Festplatte und nicht über Partitionen sprechen, werfen Sie einen Blick auf DeviceIoControl.

Beispiel von dort, die die Berechnung der Gesamtplattengröße in wmain umfasst:

#include <windows.h> 
#include <winioctl.h> 
#include <stdio.h> 

BOOL GetDriveGeometry(LPWSTR wszPath, DISK_GEOMETRY *pdg) 
{ 
    HANDLE hDevice = INVALID_HANDLE_VALUE; // handle to the drive to be examined 
    BOOL bResult = FALSE;     // results flag 
    DWORD junk  = 0;      // discard results 

    hDevice = CreateFileW(wszPath,   // drive to open 
         0,    // no access to the drive 
         FILE_SHARE_READ | // share mode 
         FILE_SHARE_WRITE, 
         NULL,    // default security attributes 
         OPEN_EXISTING, // disposition 
         0,    // file attributes 
         NULL);   // do not copy file attributes 

    if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive 
    { 
    return (FALSE); 
    } 

    bResult = DeviceIoControl(hDevice,      // device to be queried 
          IOCTL_DISK_GET_DRIVE_GEOMETRY, // operation to perform 
          NULL, 0,      // no input buffer 
          pdg, sizeof(*pdg),   // output buffer 
          &junk,       // # bytes returned 
          (LPOVERLAPPED) NULL);   // synchronous I/O 

    CloseHandle(hDevice); 

    return (bResult); 
} 

int wmain(int argc, wchar_t *argv[]) 
{ 
    DISK_GEOMETRY pdg = { 0 }; // disk drive geometry structure 
    BOOL bResult = FALSE;  // generic results flag 
    ULONGLONG DiskSize = 0; // size of the drive, in bytes 

    bResult = GetDriveGeometry (wszDrive, &pdg); 

    if (bResult) 
    { 
    wprintf(L"Drive path  = %ws\n", wszDrive); 
    wprintf(L"Cylinders  = %I64d\n", pdg.Cylinders); 
    wprintf(L"Tracks/cylinder = %ld\n", (ULONG) pdg.TracksPerCylinder); 
    wprintf(L"Sectors/track = %ld\n", (ULONG) pdg.SectorsPerTrack); 
    wprintf(L"Bytes/sector = %ld\n", (ULONG) pdg.BytesPerSector); 

    DiskSize = pdg.Cylinders.QuadPart * (ULONG)pdg.TracksPerCylinder * 
       (ULONG)pdg.SectorsPerTrack * (ULONG)pdg.BytesPerSector; 
    wprintf(L"Disk size  = %I64d (Bytes)\n" 
      L"    = %.2f (Gb)\n", 
      DiskSize, (double) DiskSize/(1024 * 1024 * 1024)); 
    } 
    else 
    { 
    wprintf (L"GetDriveGeometry failed. Error %ld.\n", GetLastError()); 
    } 

    return ((int)bResult); 
} 
+0

Dank Rudi, jetzt funktioniert es für mich, ich habe eine Frage, wie kann ich wissen, welches Laufwerk ein logisches Laufwerk ist. Ich meine, sollte ich das EBR lesen oder es kann von DeviceIoControl getan werden ??? – singh

+1

'DeviceIoControl' arbeitet mit Festplatten direkt anstatt Partitionen, wenn Sie Partitionsinformationen wollen, ist das ein Kandidat für eine andere SO-Frage :) –

+1

IOCTL_DISK_GET_DRIVE_GEOMETRY ist ungenaue Möglichkeit, die Gesamtgröße in Bytes zu erhalten (einige K kleiner als die tatsächliche Festplattengröße). Ich empfehle stattdessen, IOCTL_DISK_GET_LENGTH_INFO zu verwenden. – Calmarius

Verwandte Themen