www.pudn.com > ComputerInformation.zip > HDiskInformation.cpp
// 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#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; }