Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

System Information Utility

, 17 Apr 2001
Utility to extract system information
computerinfo_demo.zip
ComputerInformation
Bin
Debug
Inc
Lib
md
SocketUtil
SocketUtil.dsp
SystemApplication
hlp
AfxDlg.rtf
SystemApplication.cnt
SYSTEMAPPLICATION.HLP
SystemApplication.hpj
SystemApplication.ph
md
res
SysApp.ico
SystemApplication.ico
SystemApplication.dep
SystemApplication.dsp
SystemApplication.dsw
SystemApplication.odl
SystemApplication.suo
SystemCPU
CPUInformation.rgs
SystemCPU.def
SystemCPU.dsp
SystemCPU.dsw
SystemCPUps.def
SystemDevices
HWDevices.rgs
SystemDevices.def
SystemDevices.rgs
SystemDevicesps.def
SystemHDisk
HDiskInformation.rgs
SystemHDisk.def
SystemHDisk.dsp
SystemHDisk.dsw
SystemHDiskps.def
SystemInfo
SystemInfo.def
SystemInfo.dsp
SystemInfo.dsw
SystemInfops.def
SystemInformation.rgs
SystemKeyboard
PSKeyboardInformation.rgs
SystemKeyboard.def
SystemKeyboard.dsp
SystemKeyboard.vspscc
SystemKeyboardps.def
SystemLocale
LocaleInformation.rgs
SystemLocale.def
SystemLocale.dsp
SystemLocaleps.def
SystemMemory
MemoryInformation.rgs
SystemMemory.def
SystemMemory.dsp
SystemMemory.dsw
SystemMemoryps.def
SystemMisc
MiscInfomation2.rgs
MiscInformation.rgs
MiscInformation2.rgs
SystemMisc.def
SystemMisc.dsp
SystemMisc.dsw
SystemMiscps.def
SystemModem
ModemInformation.rgs
SystemModem.def
SystemModem.dsp
SystemModemps.def
SystemMouse
MouseInformation.rgs
SystemMouse.def
SystemMouse.dsp
SystemMouse.dsw
SystemMouseps.def
SystemMultiMedia
MultiMediaDevice.rgs
MultiMediaDeviceList.rgs
MultiMediaInformation.rgs
SystemMultiMedia.def
SystemMultiMedia.dsp
SystemMultiMedia.dsw
SystemMultiMediaps.def
SystemNetwork
NetworkInformation.rgs
SystemNetwork.def
SystemNetwork.dsp
SystemNetworkps.def
SystemOS
OSInformation.rgs
SystemOS.def
SystemOS.dsp
SystemOS.dsw
SystemOSps.def
SystemPnPDevices
PnPDevice.rgs
PnPDeviceDriver.rgs
PnPDeviceDrivers.rgs
PnPDevices.rgs
PnPDevicesInfo.rgs
SystemPnPDevices.def
SystemPnPDevices.dsp
SystemPnPDevicesps.def
SystemProtectFiles
ProtectedFilesInfo.rgs
SystemProtectFiles.def
SystemProtectFiles.dep
SystemProtectFiles.dsp
SystemProtectFilesps.def
SystemStorage
StorageMediaInformation.rgs
SystemStorage.def
SystemStorage.dsp
SystemStorage.dsw
SystemStorageps.def
TestConsole
// Disclaimer and Copyright Information
// HDiskInformation.cpp : Implementation of CHDiskInformation
//
// All rights reserved.
//
// Written by Naveen K Kohli (naveenkohli@netzero.net)
// Version 1.0
//
// Distribute freely, except: don't remove my name from the source or
// documentation (don't take credit for my work), mark your changes (don't
// get me blamed for your possible bugs), don't alter or remove this
// notice.
// No warrantee of any kind, express or implied, is included with this
// software; use at your own risk, responsibility for damages (if any) to
// anyone resulting from the use of this software rests entirely with the
// user.
//
// Send bug reports, bug fixes, enhancements, requests, flames, etc. to
// naveenkohli@netzero.net
///////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include <stdio.h>
#include "SystemHDisk.h"
#include "HDiskInformation.h"

/////////////////////////////////////////////////////////////////////////////
// CHDiskInformation

STDMETHODIMP CHDiskInformation::InterfaceSupportsErrorInfo(REFIID riid)
{
	static const IID* arr[] = 
	{
		&IID_IHDiskInformation
	};
	for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		if (::InlineIsEqualGUID(*arr[i],riid))
			return S_OK;
	}
	return S_FALSE;
}

STDMETHODIMP CHDiskInformation::get_NumberOfPartitions(long *pVal)
{
	HRESULT hRes = E_FAIL;

	if ((hRes = GetInformation ()) != S_OK)
	{
		return hRes;
	}

	*pVal = m_NumberOfPartitions;

	return hRes;
}

STDMETHODIMP CHDiskInformation::get_Bootable(VARIANT *pVal)
{
	HRESULT hRes = E_FAIL;

	if ((hRes = GetInformation ()) != S_OK)
	{
		return hRes;
	}

	VariantInit (pVal);

	V_VT (pVal) = VT_ARRAY | VT_BOOL;
	V_ARRAY (pVal) = m_pBootable;

	return hRes;
}

STDMETHODIMP CHDiskInformation::get_Letter(VARIANT *pVal)
{
	HRESULT hRes = E_FAIL;

	if ((hRes = GetInformation ()) != S_OK)
	{
		return hRes;
	}

	::VariantInit (pVal);

	V_VT (pVal) = VT_ARRAY | VT_BSTR;
	V_ARRAY (pVal) = m_pPartitionLetter;
	return hRes;
}

STDMETHODIMP CHDiskInformation::get_PartitionType(VARIANT *pVal)
{
	HRESULT hRes = E_FAIL;

	if ((hRes = GetInformation ()) != S_OK)
	{
		return hRes;
	}

	::VariantInit (pVal);

	V_VT (pVal) = VT_ARRAY | VT_BSTR;
	V_ARRAY (pVal) = m_pPartitionType;
	return hRes;
}

STDMETHODIMP CHDiskInformation::get_PartitionNumber(VARIANT *pVal)
{
	HRESULT hRes = E_FAIL;

	if ((hRes = GetInformation ()) != S_OK)
	{
		return hRes;
	}

	VariantInit (pVal);

	V_VT (pVal) = VT_ARRAY | VT_I4;
	V_ARRAY (pVal) = m_pPartitionNumber;
	return hRes;
}

STDMETHODIMP CHDiskInformation::get_PartitionLength(VARIANT *pVal)
{
	HRESULT hRes = E_FAIL;

	if ((hRes = GetInformation ()) != S_OK)
	{
		return hRes;
	}

	::VariantInit (pVal);

	V_VT (pVal) = VT_ARRAY | VT_I4;
	V_ARRAY (pVal) = m_pPartitionLength;
	return hRes;
}

STDMETHODIMP CHDiskInformation::get_HiddenSectors(VARIANT *pVal)
{
	HRESULT hRes = E_FAIL;

	if ((hRes = GetInformation ()) != S_OK)
	{
		return hRes;
	}

	::VariantInit (pVal);

	V_VT (pVal) = VT_ARRAY | VT_I4;
	V_ARRAY (pVal) = m_pHiddenSectors;
	return hRes;
}

STDMETHODIMP CHDiskInformation::GetHDiskInformation(long *plNumberOfPartitions,
													VARIANT *pbstrDriveLetterArr,
													VARIANT *pbBootableArr,
													VARIANT *pbstrTypeArr,
													VARIANT *plPartitionNumberArr,
													VARIANT *plLengthArr,
													VARIANT *plHiddenSectorsArr)
{
	HRESULT hRes = E_FAIL;

	if ((hRes = GetInformation ()) != S_OK) {
		return hRes;
	}

	*plNumberOfPartitions = m_NumberOfPartitions;

	::VariantInit (pbstrDriveLetterArr);
	::VariantInit (pbBootableArr);
	::VariantInit (pbstrTypeArr);
	::VariantInit (plPartitionNumberArr);
	::VariantInit (plLengthArr);
	::VariantInit (plHiddenSectorsArr);

	V_VT (pbstrDriveLetterArr) = VT_ARRAY | VT_BSTR;
	V_ARRAY (pbstrDriveLetterArr) = m_pPartitionLetter;

	V_VT (pbBootableArr) = VT_ARRAY | VT_BOOL;
	V_ARRAY (pbBootableArr) = m_pBootable;

	V_VT (pbstrTypeArr) = VT_ARRAY | VT_BSTR;
	V_ARRAY (pbstrTypeArr) = m_pPartitionType;

	V_VT (plPartitionNumberArr) = VT_ARRAY | VT_I4;
	V_ARRAY (plPartitionNumberArr) = m_pPartitionNumber;

	V_VT (plLengthArr) = VT_ARRAY | VT_R8;
	V_ARRAY (plLengthArr) = m_pPartitionLength;

	V_VT (plHiddenSectorsArr) = VT_ARRAY | VT_I4;
	V_ARRAY (plHiddenSectorsArr) = m_pHiddenSectors;
	return S_OK;
}

HRESULT CHDiskInformation::GetInformation ()
{
	UINT i, nIndex;
	UINT nDrives, nDriveType;
	HRESULT hRes = S_OK;
	HANDLE hDevice = NULL;
	BOOL fResult;
	DWORD dwBytes, dwError;
	double tmpNum = 0.;
	char szCurrentDrive[MAX_PATH];
	char szName[80];
	char lpMultiByteStr[128];
	DWORD dwLogicalDrives;
	PARTITION_INFORMATION  *pPartitionInfo = NULL;

	if (m_bInformationObtained)
	{
		return S_OK;
	}

	CComBSTR bstrDriveLetter;
	SAFEARRAY *pSafeArray = NULL;
	SAFEARRAYBOUND arrayBound[1];

	arrayBound[0].lLbound = 0;
	arrayBound[0].cElements = 32;

	pSafeArray = ::SafeArrayCreate (VT_BSTR, 1, arrayBound);

	// Get the all the logical drives. Function will return a bit mask of the logical
	// drives. Bits are set if the corresponding drives are available. Bit 0 represents
	// drive A, bit 2 is drive B and so on.
	dwLogicalDrives = ::GetLogicalDrives ();

	m_NumberOfPartitions = nIndex = 0;

	for (nDrives = 0; nDrives < 32; nDrives ++)
	{
		if (dwLogicalDrives && (1 << nDrives))
		{
			wsprintf (szCurrentDrive, "%c", nDrives + 'A');
			strcpy (szName, szCurrentDrive);
			strcat (szCurrentDrive, _T (":\\"));
			
			// Get the drive type.
			nDriveType = ::GetDriveType (szCurrentDrive);

			// If its a hard drive type of drive, then get the partition information.
			if (nDriveType == DRIVE_FIXED)
			{
				bstrDriveLetter = szName;
				::SafeArrayPutElement (pSafeArray, (long *) &nIndex, bstrDriveLetter.Copy ());
				m_NumberOfPartitions++;
				nIndex++;
			}
		}
	}

	// Create the SafeArrays.

	if (FAILED (this->InitializeSafeArrays ()))
	{
		return E_FAIL;
	}

	// Get information for each drive and stuff into arrays.
	for (i = 0; i < nIndex; i++)
	{
		::SafeArrayGetElement (pSafeArray, (long *) &i, &bstrDriveLetter);

		::WideCharToMultiByte (CP_ACP, 0, bstrDriveLetter, -1, lpMultiByteStr,
							   sizeof (lpMultiByteStr), NULL, NULL);

		strcat (lpMultiByteStr, _T (":"));
		sprintf(szName,"\\\\.\\%s", lpMultiByteStr);

		hDevice = CreateFile (szName, GENERIC_READ | GENERIC_WRITE,
							  FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
							  OPEN_EXISTING, 0, NULL);
		if (hDevice == INVALID_HANDLE_VALUE)
		{
			dwError = ::GetLastError ();
			continue;
		}

		// Get the partition information.
		pPartitionInfo = new PARTITION_INFORMATION ;
		fResult = ::DeviceIoControl (hDevice, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0,
									 pPartitionInfo, sizeof (*pPartitionInfo),
									 &dwBytes, (LPOVERLAPPED) NULL);
		
		if (!fResult) {
			dwError = GetLastError ();
			continue;
		}

		::SafeArrayPutElement (m_pPartitionLetter, (long *) &i, bstrDriveLetter.Copy ());
		::SafeArrayPutElement (m_pBootable, (long *) &i, &pPartitionInfo->BootIndicator);
		tmpNum = (double)pPartitionInfo->PartitionLength.QuadPart;
		::SafeArrayPutElement (m_pPartitionLength, (long *) &i, &tmpNum);
		::SafeArrayPutElement (m_pHiddenSectors, (long *) &i, &pPartitionInfo->HiddenSectors);
		::SafeArrayPutElement (m_pPartitionNumber, (long *) &i, &pPartitionInfo->PartitionNumber);
		::SafeArrayPutElement (m_pPartitionType, (long *) &i,
							   GetPartitionType ((DWORD)pPartitionInfo->PartitionType).Copy ());

		::CloseHandle (hDevice);

		if (pPartitionInfo != NULL)
		{
			delete pPartitionInfo;
			pPartitionInfo = NULL;
		}
	}

	m_bInformationObtained = true;
	return S_OK;
}

HRESULT CHDiskInformation::InitializeSafeArrays ()
{
	SAFEARRAYBOUND arrayBound[1];

	if (m_NumberOfPartitions <= 0)
	{
		return E_FAIL;
	}

	arrayBound[0].lLbound = 0;
	arrayBound[0].cElements = m_NumberOfPartitions;

	m_pBootable = ::SafeArrayCreate (VT_BOOL, 1, arrayBound);
	m_pPartitionLetter = ::SafeArrayCreate (VT_BSTR, 1, arrayBound);
	m_pPartitionType = ::SafeArrayCreate (VT_BSTR, 1, arrayBound);
	m_pPartitionNumber = ::SafeArrayCreate (VT_I4, 1, arrayBound);
	m_pPartitionLength = ::SafeArrayCreate (VT_R8, 1, arrayBound);
	m_pHiddenSectors = ::SafeArrayCreate (VT_I4, 1, arrayBound);

	return S_OK;
}

CComBSTR CHDiskInformation::GetPartitionType (DWORD dwType) const
{
	CComBSTR bstrType;

	switch (dwType)
	{
		case PARTITION_ENTRY_UNUSED:
			bstrType = _T ("Unknown");
			break;
		case PARTITION_FAT_12:
			bstrType = _T ("12-bit FAT");
			break;
		case PARTITION_XENIX_1:
			bstrType = _T ("Xenix type 1");
			break;
		case PARTITION_XENIX_2:
			bstrType = _T ("Xenix type 2");
			break;
		case PARTITION_FAT_16:
			bstrType = _T ("FAT16");
			break;
		case PARTITION_EXTENDED:
			bstrType = _T ("Extended"); 
			break;
		case PARTITION_FAT32:
			bstrType = _T ("FAT32");
			break;
		case PARTITION_HUGE:
			bstrType = _T ("MS-DOS V4 Huge");
			break;
		case PARTITION_IFS:
			bstrType = _T ("IFS");
			break;
		case PARTITION_PREP:
			bstrType = _T ("PowerPC Reference Platform");
			break;
		case PARTITION_UNIX:
			bstrType = _T ("UNIX");
			break;
		case VALID_NTFT:
			bstrType = _T ("NTFT");
			break;
		case PARTITION_LDM:
			bstrType = _T ("Logical Disk Manager");
			break;
		case PARTITION_XINT13:
			bstrType = _T ("Partition with Extened int13 Services");
			break;
		case PARTITION_XINT13_EXTENDED:
			bstrType = _T ("Exteneded Partition with Extended int13 Services");
			break;
		case PARTITION_FAT32_XINT13 :
			bstrType = _T ("FAT32 with Extended int13 Services");
			break;
	}

	return bstrType;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Naveen K Kohli

United States United States
No Biography provided

| Advertise | Privacy | Mobile
Web01 | 2.8.140721.1 | Last Updated 18 Apr 2001
Article Copyright 2001 by Naveen K Kohli
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid