2013-03-13 18 views
7

Próbuję uzyskać całkowity rozmiar dysku fizycznego (nieprzydzielone + partycje podstawowe + rozmiar rozszerzonych partycji).Uzyskaj całkowity rozmiar dysku twardego w systemie C++ Windows

mam nazwę dysku jako \\.\PhysicalDriveX

Próbowałem za pomocą GetDiskFreeSpaceEx ale nie daje poprawny wynik, gdy partycja jest partycja rozszerzona, w tym przypadku zwraca całkowity rozmiar partycji.

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

mogę uzyskać informacje o partycji przy użyciu DeviceIoControl użyciu IOCTL_DISK_GET_DRIVE_LAYOUT_EX ale otrzymuję mylić o przedłużonym rozmiaru partycji.

Czy istnieje sposób, że mogę dokładnie uzyskać całkowity rozmiar dysku twardego w C++ w oknach?

Odpowiedz

7

Ponieważ mówimy o dysku fizycznym, a nie partycjach, spójrz na DeviceIoControl.

Przykład stamtąd, który zawiera wyliczenie całkowitego rozmiaru dysku w wmain:

#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

Dzięki Rudi, teraz pracuje dla mnie jeszcze jedno pytanie skąd mam wiedzieć, który dysk jest dysk logiczny. Mam na myśli, czy powinienem przeczytać ebr, czy może to zrobić z DeviceIoControl? – singh

+1

'DeviceIoControl' działa z dyskami bezpośrednio, a nie partycjami, jeśli chcesz uzyskać informacje o partycji, to jest kandydatem na inne pytanie SO :) –

+1

IOCTL_DISK_GET_DRIVE_GEOMETRY jest niedokładnym sposobem na uzyskanie całkowitego rozmiaru w bajtach (kilka K mniej niż faktyczny rozmiar dysku). Sugeruję zamiast tego użycie IOCTL_DISK_GET_LENGTH_INFO. – Calmarius

Powiązane problemy