Получить общий размер жесткого диска в windows c++

Я пытаюсь получить общий размер физического диска (нераспределенные + первичные разделы + расширенный размер разделов).

у меня есть имя диска, как .PhysicalDriveX

Я попытался с помощью GetDiskFreeSpaceEx но он не дает правильного результата, когда раздел является расширенным разделом, в этом случае он возвращает общий размер раздела.

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

Я могу получить информацию о разделе с помощью DeviceIoControl с помощью IOCTL_DISK_GET_DRIVE_LAYOUT_EX но я начинаю путаться. размер дополнительного раздела.

есть ли способ, которым я могу точно получить общий размер жесткого диска в C++ на windows ??

1 ответов


поскольку вы говорите о физическом диске, а не о разделах, взгляните на DeviceIoControl.

пример оттуда, который включает в себя расчет общего размера диска в 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);
}