ドライブのジオメトリ情報(物理的なサイズ情報)の取得(IOCTL_DISK_GET_DRIVE_GEOMETRY)
DeviceIoControl関数を用いてドライブの物理ディスクジオメトリ情報(物理的なサイズ情報)を取得するサンプルコードです。この投稿ではIOCTL_DISK_GET_DRIVE_GEOMETRYを用いた場合を紹介します。詳細な説明はいつか。
シンプルなコード
#define STRICT #include <Windows.h> #include <strsafe.h> int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { HANDLE volumeHandle = CreateFile( TEXT("\\\\.\\C:"), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); if (volumeHandle == INVALID_HANDLE_VALUE) { return 0; } DISK_GEOMETRY diskGeometry; DWORD returnedBytes = 0; BOOL succeeded = DeviceIoControl( volumeHandle, IOCTL_DISK_GET_DRIVE_GEOMETRY, nullptr, 0, &diskGeometry, sizeof diskGeometry, &returnedBytes, nullptr); TCHAR buffer[1024]; succeeded = SUCCEEDED(StringCbPrintf(buffer, sizeof buffer, TEXT("シリンダ数: %lld\n") TEXT("メディアの種類: %ld\n") TEXT("シリンダ当たりのトラック数: %ld\n") TEXT("トラック当たりのセクタ数: %ld\n") TEXT("セクタ当たりのバイト数: %ld"), diskGeometry.Cylinders, diskGeometry.MediaType, diskGeometry.TracksPerCylinder, diskGeometry.SectorsPerTrack, diskGeometry.BytesPerSector)); MessageBox(HWND_DESKTOP, buffer, TEXT("Cドライブのジオメトリ情報"), MB_ICONINFORMATION); CloseHandle(volumeHandle); return 0; }
ヘルパー関数を追加したコード
#define STRICT #include <Windows.h> #include <StrSafe.h> inline DWORD BytesPerTrack(const DISK_GEOMETRY& diskGeometry) { return diskGeometry.BytesPerSector * diskGeometry.SectorsPerTrack; } inline DWORD BytesPerClinder(const DISK_GEOMETRY& diskGeometry) { return BytesPerTrack(diskGeometry) * diskGeometry.TracksPerCylinder; } inline LARGE_INTEGER BytesPerDisk(const DISK_GEOMETRY& diskGeometry) { LARGE_INTEGER ret; ret.QuadPart = BytesPerClinder(diskGeometry) * diskGeometry.Cylinders.QuadPart; return ret; } // DISK_GEOMETRY構造体のMediaTypeの値からMEDIA_TYPE列挙体での名前を返します。 // MicrosoftのWinIoCtl.h BUILD Version: 0016から引用しています。 inline LPCTSTR MediaTypeValueName(const DISK_GEOMETRY& diskGeometry) { switch (diskGeometry.MediaType) { case Unknown: return TEXT("Unknown"); case F5_1Pt2_512: return TEXT("F5_1Pt2_512"); case F3_1Pt44_512: return TEXT("F3_1Pt44_512"); case F3_2Pt88_512: return TEXT("F3_2Pt88_512"); case F3_20Pt8_512: return TEXT("F3_20Pt8_512"); case F3_720_512: return TEXT("F3_720_512"); case F5_360_512: return TEXT("F5_360_512"); case F5_320_512: return TEXT("F5_320_512"); case F5_320_1024: return TEXT("F5_320_1024"); case F5_180_512: return TEXT("F5_180_512"); case F5_160_512: return TEXT("F5_160_512"); case RemovableMedia: return TEXT("RemovableMedia"); case FixedMedia: return TEXT("FixedMedia"); case F3_120M_512: return TEXT("F3_120M_512"); case F3_640_512: return TEXT("F3_640_512"); case F5_640_512: return TEXT("F5_640_512"); case F5_720_512: return TEXT("F5_720_512"); case F3_1Pt2_512: return TEXT("F3_1Pt2_512"); case F3_1Pt23_1024: return TEXT("F3_1Pt23_1024"); case F5_1Pt23_1024: return TEXT("F5_1Pt23_1024"); case F3_128Mb_512: return TEXT("F3_128Mb_512"); case F3_230Mb_512: return TEXT("F3_230Mb_512"); case F8_256_128: return TEXT("F8_256_128"); case F3_200Mb_512: return TEXT("F3_200Mb_512"); case F3_240M_512: return TEXT("F3_240M_512"); case F3_32M_512: return TEXT("F3_32M_512"); default: return nullptr; } } // DISK_GEOMETRY構造体のMediaTypeの値からMEDIA_TYPE列挙体での説明を返します。 // MicrosoftのWinIoCtl.h BUILD Version: 0016から引用しています。 inline LPCTSTR MediaTypeDescription(const DISK_GEOMETRY& diskGeometry) { switch (diskGeometry.MediaType) { case Unknown: return TEXT("Format is unknown"); case F5_1Pt2_512: return TEXT("5.25\", 1.2MB, 512 bytes / sector"); case F3_1Pt44_512: return TEXT("3.5\", 1.44MB, 512 bytes / sector"); case F3_2Pt88_512: return TEXT("3.5\", 2.88MB, 512 bytes / sector"); case F3_20Pt8_512: return TEXT("3.5\", 20.8MB, 512 bytes / sector"); case F3_720_512: return TEXT("3.5\", 720KB, 512 bytes / sector"); case F5_360_512: return TEXT("5.25\", 360KB, 512 bytes / sector"); case F5_320_512: return TEXT("5.25\", 320KB, 512 bytes / sector"); case F5_320_1024: return TEXT("5.25\", 320KB, 1024 bytes / sector"); case F5_180_512: return TEXT("5.25\", 180KB, 512 bytes / sector"); case F5_160_512: return TEXT("5.25\", 160KB, 512 bytes / sector"); case RemovableMedia: return TEXT("Removable media other than floppy"); case FixedMedia: return TEXT("Fixed hard disk media"); case F3_120M_512: return TEXT("3.5\", 120M Floppy"); case F3_640_512: return TEXT("3.5\", 640KB, 512 bytes / sector"); case F5_640_512: return TEXT("5.25\", 640KB, 512 bytes / sector"); case F5_720_512: return TEXT("5.25\", 720KB, 512 bytes / sector"); case F3_1Pt2_512: return TEXT("3.5\", 1.2Mb, 512 bytes / sector"); case F3_1Pt23_1024: return TEXT("3.5\", 1.23Mb, 1024 bytes / sector"); case F5_1Pt23_1024: return TEXT("5.25\", 1.23MB, 1024 bytes / sector"); case F3_128Mb_512: return TEXT("3.5\" MO 128Mb 512 bytes / sector"); case F3_230Mb_512: return TEXT("3.5\" MO 230Mb 512 bytes / sector"); case F8_256_128: return TEXT("8\", 256KB, 128 bytes / sector"); case F3_200Mb_512: return TEXT("3.5\", 200M Floppy(HiFD)"); case F3_240M_512: return TEXT("3.5\", 240Mb Floppy(HiFD)"); case F3_32M_512: return TEXT("3.5\", 32Mb Floppy"); default: return nullptr; } } int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { HANDLE volumeHandle = CreateFile( TEXT("\\\\.\\C:"), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); if (volumeHandle == INVALID_HANDLE_VALUE) { return 0; } DISK_GEOMETRY diskGeometry; DWORD returnedBytes = 0; BOOL succeeded = DeviceIoControl( volumeHandle, IOCTL_DISK_GET_DRIVE_GEOMETRY, nullptr, 0, &diskGeometry, sizeof diskGeometry, &returnedBytes, nullptr); TCHAR buffer[1024]; succeeded = SUCCEEDED(StringCbPrintf(buffer, sizeof buffer, TEXT("シリンダ数: %llu\n") TEXT("メディアの種類: %ld (%s) - \"%s\"\n") TEXT("シリンダ当たりのトラック数: %lu\n") TEXT("トラック当たりのセクタ数: %lu\n") TEXT("セクタ当たりのバイト数: %lu\n") TEXT("-----\n") TEXT("トラック当たりのバイト数: %lu\n") TEXT("シリンダ当たりのバイト数: %lu\n") TEXT("ディスク当たりのバイト数: %lu"), diskGeometry.Cylinders, diskGeometry.MediaType, MediaTypeValueName(diskGeometry), MediaTypeDescription(diskGeometry), diskGeometry.TracksPerCylinder, diskGeometry.SectorsPerTrack, diskGeometry.BytesPerSector, // -----, BytesPerTrack(diskGeometry), BytesPerClinder(diskGeometry), BytesPerDisk(diskGeometry))); MessageBox(HWND_DESKTOP, buffer, TEXT("Cドライブのジオメトリ情報"), MB_ICONINFORMATION); CloseHandle(volumeHandle); return 0; }