2013-03-13 8 views
7

物理ドライブの合計サイズ(未割り当て+プライマリパーティション+拡張パーティションサイズ)を取得しようとしています。C++のウィンドウでハードディスクの合計サイズを取得

Iは\\.\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; 

私はIOCTL_DISK_GET_DRIVE_LAYOUT_EX を使用してのDeviceIoControlを使用してパーティション情報を取得することができますが、私は、拡張パーティションのサイズについて混乱取得しています。

Windows上のC++でハードディスクの合計サイズを正確に取得できる方法はありますか?

答えて

7

物理ディスクとパーティションではないので、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); 
} 
+0

おかげルディが、今それは私の作品私は、論理ドライブであるドライブを知っていますか1つの以上の質問があります。私はebrを読んだり、DeviceIoControlから行うことができますか? – singh

+1

'DeviceIoControl'は、パーティション情報を必要とするならば、パーティションではなくディスクで直接動作します。別のSO質問の候補です。 –

+1

IOCTL_DISK_GET_DRIVE_GEOMETRYは、合計サイズをバイト単位(実際のディスクサイズよりもわずか数K)小さくする方法が不正です。代わりにIOCTL_DISK_GET_LENGTH_INFOを使用することをお勧めします。 – Calmarius

関連する問題