www.pudn.com > ComputerInformation.zip > CPUInformation.cpp
// Disclaimer and Copyright Information // CPUInformation.cpp : Implementation of CCPUInformation // // All rights reserved. // // Written by Naveen K Kohli (naveenkohli@att.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@att.net /////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "SystemCPU.h" #include "CPUInformation.h" #include///////////////////////////////////////////////////////////////////////////// // CCPUInformation HRESULT CCPUInformation::FinalConstruct () { HRESULT hr; hr = CoCreateInstance (CLSID_OSInformation, 0, CLSCTX_INPROC_SERVER, IID_IOSInformation, (void **) &m_pOSInfo); if (FAILED (hr)) { return E_NOINTERFACE; } return S_OK; } void CCPUInformation::FinalRelease () { if (m_pOSInfo != NULL) { m_pOSInfo->Release (); } } STDMETHODIMP CCPUInformation::InterfaceSupportsErrorInfo(REFIID riid) { static const IID* arr[] = { &IID_ICPUInformation }; for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++) { if (::InlineIsEqualGUID(*arr[i],riid)) return S_OK; } return S_FALSE; } STDMETHODIMP CCPUInformation::get_NumberOfProcessors(long *pVal) { HRESULT hRes = S_OK; if ((hRes = GetInformation ()) != S_OK) { return hRes; } *pVal = m_lNumberOfProcessors; return S_OK; } STDMETHODIMP CCPUInformation::get_CPUSpeed(long *pVal) { HRESULT hRes = S_OK; if ((hRes = GetInformation ()) != S_OK) { return hRes; } *pVal = m_lCPUSpeed; return S_OK; } STDMETHODIMP CCPUInformation::get_PageSize(long *pVal) { HRESULT hRes = S_OK; if ((hRes = GetInformation ()) != S_OK) { return hRes; } *pVal = m_lPageSize; return S_OK; } STDMETHODIMP CCPUInformation::get_ActiveProcessorMask(long *pVal) { HRESULT hRes = S_OK; if ((hRes = GetInformation ()) != S_OK) { return hRes; } *pVal = m_lActiveMask; return S_OK; } STDMETHODIMP CCPUInformation::get_Vendor(BSTR *pVal) { HRESULT hRes = S_OK; if ((hRes = GetInformation ()) != S_OK) { return hRes; } *pVal = m_bstrVendor.Copy (); return S_OK; } STDMETHODIMP CCPUInformation::get_ProcessorType(BSTR *pVal) { HRESULT hRes = S_OK; if ((hRes = GetInformation ()) != S_OK) { return hRes; } *pVal = m_bstrCPUType.Copy (); return S_OK; } STDMETHODIMP CCPUInformation::get_Architecture(BSTR *pVal) { HRESULT hRes = S_OK; if ((hRes = GetInformation ()) != S_OK) { return hRes; } *pVal = m_bstrArchitecture.Copy (); return S_OK; } STDMETHODIMP CCPUInformation::get_CPULevel(BSTR *pVal) { HRESULT hRes = S_OK; if ((hRes = GetInformation ()) != S_OK) { return hRes; } *pVal = m_CPULevel.Copy (); return S_OK; } STDMETHODIMP CCPUInformation::get_CPURevision(BSTR *pVal) { HRESULT hRes = S_OK; if ((hRes = GetInformation ()) != S_OK) { return hRes; } *pVal = m_CPURevision.Copy (); return S_OK; } STDMETHODIMP CCPUInformation::GetCPUInformation(BSTR *pbstrVendor, BSTR *pbstrType, BSTR *pbstrArchitecture, BSTR *pbstrLevel, BSTR *pbstrRevision, long *plNumberOfProcessors, long *plSpeed, long *plPageSize, long *plMask) { HRESULT hRes = S_OK; if ((hRes = GetInformation ()) != S_OK) { return hRes; } *pbstrVendor = m_bstrVendor.Copy (); *pbstrType = m_bstrCPUType.Copy (); *pbstrLevel = m_CPULevel.Copy (); *pbstrArchitecture = m_bstrArchitecture.Copy (); *pbstrRevision = m_CPURevision.Copy (); *plMask = m_lActiveMask; *plPageSize = m_lPageSize; *plSpeed = m_lCPUSpeed; *plNumberOfProcessors = m_lNumberOfProcessors; return S_OK; } HRESULT CCPUInformation::GetInformation () { HRESULT hRes = S_OK; long bIsWin95 = FALSE; SYSTEM_INFO sysInfo; char str [MAX_PATH]; CComBSTR tmpStr; LONG result; HKEY hKey; TCHAR vendorData [64]; DWORD data, dataSize; LPTSTR lpErrDesc = NULL; // Get the processor speed info. result = ::RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Hardware\\Description\\System\\CentralProcessor\\0", 0, KEY_QUERY_VALUE, &hKey); // Check if the function has succeeded. if (result == ERROR_SUCCESS) { dataSize = MAX_PATH; result = ::RegQueryValueEx (hKey, _T("~MHz"), NULL, NULL, (LPBYTE)&data, &dataSize); if (result != ERROR_SUCCESS) { ATLTRACE (_T ("Failed to get CPU Speed information!\n")); return MakeAPIErrorDesc (); } m_lCPUSpeed = data; dataSize = sizeof (vendorData); result = ::RegQueryValueEx (hKey, _T("VendorIdentifier"), NULL, NULL, (LPBYTE)vendorData, &dataSize); if (result != ERROR_SUCCESS) { ATLTRACE (_T ("Failed to get vendor information!\n")); return MakeAPIErrorDesc (); } m_bstrVendor = vendorData; } else { return MakeAPIErrorDesc (); } // Make sure to close the reg key RegCloseKey (hKey); // Get the hardware information ::GetSystemInfo (&sysInfo); // Lets check the processor type first if (sysInfo.dwProcessorType == PROCESSOR_INTEL_386) { m_bstrCPUType = _T ("Intel 386"); } else if (sysInfo.dwProcessorType == PROCESSOR_INTEL_486) { m_bstrCPUType = _T ("Intel 486"); } else if (sysInfo.dwProcessorType == PROCESSOR_INTEL_PENTIUM) { m_bstrCPUType = _T ("Intel Pentium"); } else if (sysInfo.dwProcessorType == PROCESSOR_MIPS_R4000) { // only for NT m_bstrCPUType = _T ("MIPS"); } else if (sysInfo.dwProcessorType == PROCESSOR_ALPHA_21064) { // only for NT m_bstrCPUType = _T ("Alpha"); } else { m_bstrCPUType = _T ("Unknown"); } // check number of processors m_lNumberOfProcessors = sysInfo.dwNumberOfProcessors; // Get the information if we have Win95 OS. hRes = m_pOSInfo->get_IsWin95 (&bIsWin95); if (FAILED (hRes)) { ATLTRACE (_T ("Failed to OS information!\n")); return hRes; } // Check the architecture type and processor level // Windows 95 doesn't use processor level m_CPURevision = _T ("Unknown"); if (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) { m_bstrArchitecture = _T ("Pentium"); switch (sysInfo.wProcessorLevel) { case 3: m_CPULevel = _T ("Intel 80386"); if (!bIsWin95) { m_CPURevision = HIBYTE (sysInfo.wProcessorRevision); m_CPURevision += _T ("A"); tmpStr = LOBYTE (sysInfo.wProcessorRevision); m_CPURevision += tmpStr; } break; case 4: m_CPULevel = _T ("Intel 80486"); if (!bIsWin95) { m_CPURevision = HIBYTE (sysInfo.wProcessorRevision); m_CPURevision += _T ("A"); tmpStr = LOBYTE (sysInfo.wProcessorRevision); m_CPURevision += tmpStr; } break; case 5: m_CPULevel = _T ("Pentium"); // Check if the MMX instruction set is availbale or not. if (IsProcessorFeaturePresent (PF_MMX_INSTRUCTIONS_AVAILABLE)) { m_CPULevel += _T (" MMX"); } if (!bIsWin95) { m_CPURevision = _T ("Model "); sprintf (str, "%d", HIBYTE (sysInfo.wProcessorRevision)); tmpStr = str; m_CPURevision.Append (tmpStr); m_CPURevision.Append (_T (", Stepping ")); sprintf (str, "%d", LOBYTE (sysInfo.wProcessorRevision)); tmpStr = str; m_CPURevision += tmpStr; } break; case 6: m_CPULevel = _T ("Pentium (II/Pro)"); break; } } else if (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_MIPS) { m_bstrArchitecture = _T ("MIPS"); if (sysInfo.wProcessorLevel == 0004) { m_CPULevel = _T ("MIPS R4000"); } else { m_CPULevel = _T ("Unknown"); } } else if (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ALPHA) { m_bstrArchitecture = _T ("Alpha"); itoa (sysInfo.wProcessorLevel , str, 10); tmpStr = m_bstrArchitecture; tmpStr.Append (str); m_CPULevel.Append (tmpStr); } else if (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_PPC) { m_bstrArchitecture = _T ("PPC"); switch (sysInfo.wProcessorLevel) { case 1: m_CPULevel = _T ("PPC 601"); break; case 3: m_CPULevel = _T ("PPC 603"); break; case 4: m_CPULevel = _T ("PPC 604"); break; case 6: m_CPULevel = _T ("PPC 603+"); break; case 9: m_CPULevel = _T ("PPC 604+"); break; case 20: m_CPULevel = _T ("PPC 620"); break; } } else if (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_UNKNOWN) { m_bstrArchitecture = _T ("Unknown"); } ::SysFreeString (tmpStr); // Check page size m_lPageSize = sysInfo.dwPageSize; // Get active processor mask // It represent how many processors are active (?? I am not sure) m_lActiveMask = sysInfo.dwActiveProcessorMask; return hRes; } HRESULT CCPUInformation::MakeAPIErrorDesc () { LPTSTR lpErrDesc = NULL; DWORD dwError = ::GetLastError (); FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), lpErrDesc, 0, NULL); if (NULL != lpErrDesc) { return Error (lpErrDesc, IID_IOSInformation, E_FAIL); } else { return Error (_T ("Unknown Error"), IID_IOSInformation, E_FAIL); } }