Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get total size of a hard disk in c++ windows

I am trying to get total size of a physical drive (unallocated + primary partitions + extended partitions size).

I have disk name as \\.\PhysicalDriveX

I tried using GetDiskFreeSpaceEx but it doesn't give correct result when the partition is an extended partition, in this case it returns the total size of the partition.

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

I can get the partition info using DeviceIoControl using IOCTL_DISK_GET_DRIVE_LAYOUT_EX but i am getting confused about extended partition size.

Is there a way that I can accurately get total size of a hard disk in C++ on windows ??

like image 684
singh Avatar asked Mar 13 '13 12:03

singh


People also ask

How do I find out the capacity of my C drive?

To check the total disk space left on your Windows 10 device, select File Explorer from the taskbar, and then select This PC on the left. The available space on your drive will appear under Devices and drives.

How do I see disk size in CMD?

Search command prompt in Windows 10, and right-click on the result and choose Run as administrator. Step 2. Type wmic diskdrive get size and press Enter. Finally, the total size of hard disk space (in pure number) is displayed in the figure below.

What is the Storage capacity of C?

Space for C drive: Space for System Files — Recommend 30GB – 50GB. Space for Program Files — About 30 GB. Space for Hibernation File — Recommend 8GB – 32GB. Space for Virtual Memory — Recommend 12GB – 40GB.


1 Answers

Since you're talking about the physical disk and not partitions, take a look at DeviceIoControl.

Example from there, which includes the calculation of the total disk size in 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);
}
like image 157
Rudi Visser Avatar answered Sep 21 '22 08:09

Rudi Visser