CHSなど物理ドライブ情報を取得する

DeviceIoControlにIOCTL_DISK_GET_DRIVE_GEOMETRY_EXを指定して実行するとシリンダー数などのディスク情報を取得できる。ただしデバイスによってはIOCTL_DISK_GET_DRIVE_GEOMETRY_EXをサポートしていないので失敗した場合は従来から備わるIOCTL_DISK_GET_DRIVE_GEOMETRYで取得する。

対応OS:Windows NT 4.0以降 依存環境:ATL
#include "atlstr.h"

#include "winioctl.h"


//
//	ディスク情報の取得
//
//nDriveNoは0~の数値で指定
//
//IOCTL_DISK_GET_DRIVE_GEOMETRY_EX、IOCTL_DISK_GET_DRIVE_GEOMETRYにより
//ディスク情報を取得する
//
bool	GetDiskGeometry(int nDriveNo,DISK_GEOMETRY_EX* psDiskGeometryEx)
{
	DWORD	dwWritten;
	BOOL	ret;
	HANDLE	hDevice;
	TCHAR	pszDevice[256];

	if(psDiskGeometryEx == NULL)
		return	false;
	::_stprintf_s (pszDevice,256,_T("\\\\.\\PHYSICALDRIVE%d"),nDriveNo);
	::ZeroMemory(psDiskGeometryEx,sizeof(DISK_GEOMETRY_EX));
	hDevice = ::CreateFile(pszDevice,GENERIC_READ,FILE_SHARE_WRITE,NULL,OPEN_EXISTING,NULL,NULL);
	if(hDevice == INVALID_HANDLE_VALUE)
		return	false;

	ret = ::DeviceIoControl(hDevice,IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,NULL,0,psDiskGeometryEx,sizeof(DISK_GEOMETRY_EX),&dwWritten,NULL);
	if(ret == FALSE || dwWritten != sizeof(DISK_GEOMETRY_EX))
	{
		ret = ::DeviceIoControl(hDevice,IOCTL_DISK_GET_DRIVE_GEOMETRY,NULL,0,&psDiskGeometryEx->Geometry,sizeof(DISK_GEOMETRY),&dwWritten,NULL);
		if(ret == FALSE || dwWritten != sizeof(DISK_GEOMETRY))
		{
			::ZeroMemory(psDiskGeometryEx,sizeof(DISK_GEOMETRY_EX));
			ret = FALSE;
		}
		else
		{
			psDiskGeometryEx->DiskSize.QuadPart = psDiskGeometryEx->Geometry.Cylinders.QuadPart;
			psDiskGeometryEx->DiskSize.QuadPart *= psDiskGeometryEx->Geometry.TracksPerCylinder;
			psDiskGeometryEx->DiskSize.QuadPart *= psDiskGeometryEx->Geometry.SectorsPerTrack;
			psDiskGeometryEx->DiskSize.QuadPart *= psDiskGeometryEx->Geometry.BytesPerSector;
		}
	}
	::CloseHandle(hDevice);

	return	(ret) ? true : false;
}



void	Test(void)
{
	bool				ret;
	DISK_GEOMETRY_EX	sDiskGeometryEx;

	ret = GetDiskGeometry(0,&sDiskGeometryEx);

	if(ret)
	{
		CAtlString	strMessage;

		strMessage.Format(_T("シリンダー数:%d %d\nトラック/シリンダー:%d\nセクター/トラック:%d\nバイト/セクター:%d\nディスク容量:%ld")
			,sDiskGeometryEx.Geometry.Cylinders.HighPart,sDiskGeometryEx.Geometry.Cylinders.LowPart,sDiskGeometryEx.Geometry.TracksPerCylinder,sDiskGeometryEx.Geometry.SectorsPerTrack,sDiskGeometryEx.Geometry.BytesPerSector,sDiskGeometryEx.DiskSize);
		::MessageBox(NULL,strMessage,_T(""),MB_OK);
	}
	else
		::MessageBox(NULL,_T("取得に失敗しました"),_T(""),MB_OK);
}

プロジェクトファイルをダウンロード


カテゴリー「システム情報」 のエントリー