ディスク容量取得

解説


 Windows95 OSR2以降の場合はGetDiskFreeSpaceExを利用して情報を取得する。それ以前 の場合はGetDiskFreeSpaceを利用する。GetDiskFreeSpaceは大容量ハードディスクや「パス」 には対応していないためWindows95では取得に失敗することもある。そのため公開しておいて 何だがこのソースの使用はあまりお勧めできない。


ソースコード


#include "atlstr.h"

bool	Test()
{
	DWORDLONG	dlAvail;
	DWORDLONG	dlTotal;
	CAtlString	str;

	GetDiskInfo(_T("c:\\"),dlAvail,dlTotal);
	str.Format(_T("%I64d bytes\n%I64d bytes"),dlAvail,dlTotal);
	MessageBox(0,str,_T(""),0);

	return	true;
}


//
//	ディスク空き容量情報取得
//
//Windows95OSR2よりも前のOSではGetDiskFreeSpaceExが使えないため、パスを指定すると
//正しい情報を取得できない
//
bool	GetDiskInfo(LPCTSTR pszPath,DWORDLONG& dlAvail,DWORDLONG& dlTotal)
{
	BOOL			fRet;
	OSVERSIONINFO	info;

	dlAvail = 0;
	dlTotal = 0;

	::ZeroMemory(&info,sizeof(OSVERSIONINFO));
	info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	fRet = ::GetVersionEx(&info);

	if(info.dwPlatformId == VER_PLATFORM_WIN32_NT || (info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS && LOWORD(info.dwBuildNumber) > 1000))
	{
		//GetDiskFreeSpaceExを使う

		BOOL (WINAPI* pfnGetDiskFreeSpaceEx)(LPCTSTR lpDirectoryName,PULARGE_INTEGER lpFreeBytesAvailable,PULARGE_INTEGER lpTotalNumberOfBytes,PULARGE_INTEGER lpTotalNumberOfFreeBytes);

		HMODULE			hDLL;
		ULARGE_INTEGER	uliFreeBytesAvailable;
		ULARGE_INTEGER	uliTotalNumberOfBytes;
		ULARGE_INTEGER	uliTotalNumberOfFreeBytes;

		hDLL = ::LoadLibrary(_T("Kernel32.dll"));
		if(hDLL == NULL)
			return	false;

		(FARPROC&)pfnGetDiskFreeSpaceEx = ::GetProcAddress(hDLL,"GetDiskFreeSpaceExA");
		if(pfnGetDiskFreeSpaceEx)
			fRet = pfnGetDiskFreeSpaceEx(pszPath,&uliFreeBytesAvailable,&uliTotalNumberOfBytes,&uliTotalNumberOfFreeBytes);
		else
			fRet = FALSE;

		::FreeLibrary(hDLL);

		if(fRet)
		{
			dlAvail = uliFreeBytesAvailable.QuadPart;
			dlTotal = uliTotalNumberOfBytes.QuadPart;
		}
	}
	else
	{
		//GetDiskFreeSpaceを使う

		DWORD	dwSectorsPerCluster;
		DWORD	dwBytesPerSector;
		DWORD	dwNumberOfFreeClusters;
		DWORD	dwTotalNumberOfClusters;

		CAtlString	strPath;

		strPath = pszPath;
		if(strPath.Right(1) == _T("\\"))
		{
			//パスは使えない
			ATLASSERT(0);
			strPath = strPath.Left(strPath.GetLength() - 1);
		}

		fRet = GetDiskFreeSpace(strPath,&dwSectorsPerCluster,&dwBytesPerSector,&dwNumberOfFreeClusters,&dwTotalNumberOfClusters);
		if(fRet)
		{
			dlAvail = dwNumberOfFreeClusters * dwSectorsPerCluster * dwBytesPerSector;
			dlTotal = dwTotalNumberOfClusters * dwSectorsPerCluster * dwBytesPerSector;
		}
	}

	return	fRet ? true : false;
}



カテゴリー「VC++ TIPS」 のエントリー