Sign in to follow this  
  • entries
    72
  • comments
    104
  • views
    45401

Citizen: Local system information.

Sign in to follow this  

178 views

Citizen: Local system information.

For debugging purposes I wanted to add some intormation on the running system to the log file during program startup. This information would be OS version, processor name and speed, physical memory installed and graphics adapter. Basing the program entirely on the Windows platforms I went to MSDN for clues. I've said this before and I will say it again. The Windows API is a mess, an absolute jungle. How anyone ever found it a productive way to do things is beyond me *grumble*. Anyway, here's what I concluded:

  • OS version - Getting the numeric Windows version on the local machine is not hard. The GetVersionEx( ) function gives you exactly this by filling a OSVERSIONINFOEX structure. The tricky part is that different editions of Windows can have the same version number. For example Windows XP Professional x64 Edition, Windows Server 2003, Windows Home Server, Windows Server 2003 R2 all have version number 5.2 while Windows Vista and Windows Server 2008 both have version 6.0 and so on. Determining the exact product involves getting information from all over the place and a set of conditions that makes me as an OOP philosopher die a little inside. The full list of test conditions can be found near the end of this page.
  • Processor name and speed - There are several ways to get this information. The one most appealing to me is using the registry. Windows keeps track of installed CPUs in the "HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0" registry key. The fields ProcessorNameString and ~MHz contains the name and speed of the given CPU core. If the system has multiple installed processors or one with multiple cores they are listed under the same key path except the 0 is replaced with a 1, 2, 3, etc. The information can be obtained using the functions RegOpenKeyEx( ), RegQueryValueEx( ) and RegCloseKey( ).
  • Physical memory - This is amazingly straightforward. Using GlobalMemoryStatusEx( ) to fill a MEMORYSTATUSEX structure the total physical memory installed can be found in the structure's ullTotalPhys field. I mean wow! Note that If you use the non-extended versions of the function and structure you will only get results accurate up to 4 GiB (32 bit value).
  • Graphics adapter name - Luckily the DX9 API is much simpler to work with than the Windows API. To get the adapter name you only need an adapter ordinal to differentiate between multiple adapters, and a call to IDirect3D9::GetAdapterIdentifier( ), filling out a D3DADAPTER_IDENTIFIER9 structure. The adapter name is found in the struct's Description field. Done.

To conclude this, here is the complete testing code.

std::string Application::getSystemDesc( ) {
std::ostringstream ss;
ss << "Retrieving system information." << std::endl;

ss << "OS: " << getOSDesc( ) << std::endl;

HKEY key;
char prName[256] = "";
unsigned long prNameSize = sizeof( prName );
unsigned long prSpeed = 0;
unsigned long prSpeedSize = sizeof( prSpeed );
if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0,
KEY_QUERY_VALUE, &key ) != ERROR_SUCCESS ||
RegQueryValueEx( key, "ProcessorNameString", 0, 0, ( unsigned char * )prName, &prNameSize )
!= ERROR_SUCCESS ||
RegQueryValueEx( key, "~MHz", 0, 0, ( unsigned char * )&prSpeed, &prSpeedSize )
!= ERROR_SUCCESS )
{
throw Exception( "Error: Unable to locate processor information in registry." );
}
RegCloseKey( key );
ss << "Processor name: " << prName << std::endl;
ss << "Processor speed: " << prSpeed << " MHz." << std::endl;

MEMORYSTATUSEX mem;
mem.dwLength = sizeof( mem );
if ( !GlobalMemoryStatusEx( &mem )) throw Exception( "Error: Unable to get physical memory status." );
ss << "Physical memory: " << ( float )mem.ullTotalPhys / 1073741824 << " GiB." << std::endl;

return ss.str( );
}

std::string Application::getOSDesc( ) {
OSVERSIONINFOEX osver;
osver.dwOSVersionInfoSize = sizeof( osver );
if ( !GetVersionEx(( OSVERSIONINFO * )&osver )) {
throw Exception( "Error: Unable to get OS version." );
}
if ( osver.dwMajorVersion == 5 ) {
if ( osver.dwMinorVersion == 0 ) {
return "Windows 2000";
} else if ( osver.dwMinorVersion == 1 ) {
return "Windows XP";
} else if ( osver.dwMinorVersion == 2 ) {
SYSTEM_INFO si;
GetNativeSystemInfo( &si );
if ( osver.wProductType == VER_NT_WORKSTATION &&
si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 )
{
return "Windows XP Professional x64 Edition";
} else if ( osver.wSuiteMask == VER_SUITE_WH_SERVER ) {
return "Windows Home Server";
} else if ( GetSystemMetrics( SM_SERVERR2 ) == 0 ) {
return "Windows Server 2003";
} else {
return "Windows Server 2003 R2";
}
}
} else if ( osver.dwMajorVersion == 6 ) {
if ( osver.dwMinorVersion == 0 ) {
if ( osver.wProductType == VER_NT_WORKSTATION ) {
return "Windows Vista";
} else {
return "Windows Server 2008";
}
} else if ( osver.dwMinorVersion == 1 ) {
if ( osver.wProductType == VER_NT_WORKSTATION ) {
return "Windows 7";
} else {
return "Windows Server 2008 R2";
}
}
}
throw Exception( "Error: Unknown OS version." );
}

std::string D3D9Device::getAdapterDesc( ) {
if ( !d3d ) throw Exception( "Error: Unable to get graphics adapter description." );
std::ostringstream ss;
D3DADAPTER_IDENTIFIER9 id;
d3d->GetAdapterIdentifier( D3DADAPTER_DEFAULT, 0, &id );
ss << "Graphics adapter: " << id.Description << std::endl;
return ss.str( );
}

Sign in to follow this  


0 Comments


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now