37#include <wx/msw/registry.h>
51 std::string ConvertWCSToMBS(
const wchar_t* pstr,
long wslen )
53 int len = ::WideCharToMultiByte( CP_ACP, 0, pstr, wslen, NULL, 0, NULL, NULL );
55 std::string dblstr( len,
'\0' );
56 len = ::WideCharToMultiByte( CP_ACP, 0 , pstr,
57 wslen , &dblstr[0], len, NULL,
64 std::string ConvertBSTRToMBS( BSTR bstr )
66 int wslen = ::SysStringLen( bstr );
67 return ConvertWCSToMBS( (
wchar_t*) bstr, wslen );
71 BSTR ConvertMBSToBSTR(
const std::string& str )
73 int wsLen = ::MultiByteToWideChar( CP_ACP, 0 , str.data(), str.length(), NULL,
76 BSTR wsData = ::SysAllocStringLen( NULL, wsLen );
77 if( ::MultiByteToWideChar( CP_ACP, 0 ,
84 ::SysFreeString( wsData );
110 hres = CoCreateInstance( CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator,
115 throw std::runtime_error(
"Failed to create IWbemLocator object." );
122 hres =
m_pLoc->ConnectServer( ConvertMBSToBSTR(
"ROOT\\CIMV2" ),
135 throw std::runtime_error(
"Could not connect to root\\cimv2." );
139 hres = CoSetProxyBlanket(
m_pSvc,
143 RPC_C_AUTHN_LEVEL_CALL,
144 RPC_C_IMP_LEVEL_IMPERSONATE,
153 throw std::runtime_error(
"Could not set proxy blanket." );
185 const std::string& aVersion )
187 if( aManufacturer.find(
"NVIDIA" ) != std::string::npos
188 || aManufacturer.find(
"Nvidia" ) != std::string::npos )
190 std::istringstream versionStream( aVersion );
192 std::vector<std::string> versionBits;
193 while( getline( versionStream, s,
'.' ) )
195 versionBits.push_back( s );
198 if( versionBits.size() == 4 )
200 unsigned int numChars2 = versionBits[2].length();
201 unsigned int numChars3 = versionBits[2].length();
202 if( numChars2 >= 1 && numChars3 >= 2 )
206 versionBits[3].insert( 0, ( 4 - versionBits[3].size() ),
'0' );
211 std::string major1 = versionBits[2].substr( numChars2 - 1, numChars2 - 1 );
212 std::string major2 = versionBits[3].substr( 0, 1 );
213 std::string major = major1 + major2;
214 std::string minor = versionBits[3].substr( 2, numChars3 - 1 );
217 return major +
"." + minor;
227 MEMORYSTATUSEX statex;
229 statex.dwLength =
sizeof( statex );
231 if( GlobalMemoryStatusEx( &statex ) != 0 )
233 aMemoryInfo.
Usage = statex.dwMemoryLoad;
237 aMemoryInfo.
FreePaging = statex.ullAvailPageFile;
253 IWbemClassObject* processors[2];
255 ConvertMBSToBSTR(
"WQL" ), ConvertMBSToBSTR(
"SELECT * FROM Win32_Processor" ),
256 WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 0, &
m_pEnumerator );
258 if( SUCCEEDED( hres ) )
260 hres =
m_pEnumerator->Next( WBEM_INFINITE, 2, processors, &returned );
261 if( FAILED( hres ) || returned == 0 )
270 std::string chRetValue =
"";
271 for( UINT ctrlIndex = 0; ctrlIndex < returned; ctrlIndex++ )
273 IWbemClassObject* processor = processors[ctrlIndex];
276 hres = processor->Get( ConvertMBSToBSTR(
"Name" ), 0, &var, NULL, NULL );
277 if( SUCCEEDED( hres ) )
280 cpuInfo.Name = chRetValue;
282 VariantClear( &var );
283 processor->Get( ConvertMBSToBSTR(
"Manufacturer" ), 0, &var, NULL, NULL );
285 cpuInfo.Manufacturer = chRetValue;
287 VariantClear( &var );
288 processor->Get( ConvertMBSToBSTR(
"NumberOfCores" ), 0, &var, NULL, NULL );
290 long long cores = atoll( chRetValue.c_str() );
291 cpuInfo.NumberCores = cores;
293 VariantClear( &var );
294 processor->Get( ConvertMBSToBSTR(
"NumberOfLogicalProcessors" ), 0, &var, NULL, NULL );
296 long long logical = atoll( chRetValue.c_str() );
297 cpuInfo.NumberLogical = logical;
300 aCpuInfos.push_back( cpuInfo );
303 VariantClear( &var );
313 wxString baseKeyName =
"SOFTWARE\\Microsoft\\DirectX";
314 wxRegKey key( wxRegKey::HKLM, baseKeyName );
317 if( key.HasSubkeys() )
319 wxString adapterGuid;
321 for(
bool cont = key.GetFirstKey( adapterGuid,
index ); cont;
322 cont = key.GetNextKey( adapterGuid,
index ) )
324 wxString subKeyName = baseKeyName +
"\\" + adapterGuid;
327 status = ::RegOpenKeyEx(
328 (HKEY) HKEY_LOCAL_MACHINE, subKeyName.t_str(), 0, KEY_READ, &tmpKey );
330 ULONGLONG adapterLuid;
331 DWORD dwType, dwSize =
sizeof(ULONGLONG);
332 status = ::RegQueryValueEx((HKEY)tmpKey,
L"AdapterLuid",
334 &dwType, (LPBYTE)&adapterLuid, &dwSize);
336 if (status != ERROR_SUCCESS)
338 ::RegCloseKey(tmpKey);
343 if ( dwType != REG_QWORD_LITTLE_ENDIAN && dwType != REG_QWORD ) {
344 ::RegCloseKey(tmpKey);
348 if (adapterLuid != aAdapterLuid)
350 ::RegCloseKey(tmpKey);
354 ULONGLONG driverVersion;
355 status = ::RegQueryValueEx((HKEY)tmpKey,
L"DriverVersion",
357 &dwType, (LPBYTE)&driverVersion, &dwSize);
359 if (status != ERROR_SUCCESS)
361 ::RegCloseKey(tmpKey);
366 if ( dwType != REG_QWORD_LITTLE_ENDIAN && dwType != REG_QWORD ) {
367 ::RegCloseKey(tmpKey);
371 std::stringstream fmt;
372 fmt << ( ( driverVersion >> 48 ) & 0xFFFF ) <<
"."
373 << ( ( driverVersion >> 32 ) & 0xFFFF ) <<
"."
374 << std::to_string( ( driverVersion >> 16 ) & 0xFFFF ) <<
"."
375 << std::to_string( driverVersion & 0xFFFF );
376 aDriverVersion = fmt.str();
378 ::RegCloseKey(tmpKey);
389 typedef HRESULT( WINAPI * LPCREATEDXGIFACTORY )( REFIID,
void** );
390 LPCREATEDXGIFACTORY pCreateDXGIFactory = NULL;
391 HMODULE hDXGI = NULL;
393 hDXGI = LoadLibrary(
L"dxgi.dll" );
400 IID iid_IDXGIFactory;
403 IIDFromString(
L"{7b7166ec-21c7-44ae-b21a-c9ae321ae369}", &iid_IDXGIFactory );
405 IDXGIAdapter* pAdapter = NULL;
406 pCreateDXGIFactory = (LPCREATEDXGIFACTORY) GetProcAddress( hDXGI,
"CreateDXGIFactory" );
407 if( pCreateDXGIFactory )
409 IDXGIFactory* pDXGIFactory;
410 HRESULT hr = pCreateDXGIFactory( iid_IDXGIFactory, (
void**) &pDXGIFactory );
411 if( SUCCEEDED( hr ) )
414 while( pDXGIFactory->EnumAdapters( adapter, &pAdapter ) != DXGI_ERROR_NOT_FOUND )
416 DXGI_ADAPTER_DESC desc;
417 hr = pAdapter->GetDesc( &desc );
418 if( SUCCEEDED( hr ) )
421 if( desc.VendorId == 5140 && desc.DeviceId == 140 )
428 char descriptionBuffer[260];
429 char defaultChar =
' ';
430 WideCharToMultiByte( CP_ACP, 0, desc.Description, -1, descriptionBuffer,
431 sizeof( descriptionBuffer ), &defaultChar, NULL );
433 gpuInfo.
Name = descriptionBuffer;
437 gpuInfo.
MemorySize = desc.DedicatedVideoMemory;
439 int64_t luid = ( ( (int64_t) desc.AdapterLuid.HighPart ) << 32 )
440 | desc.AdapterLuid.LowPart;
447 aGpuInfos.push_back( gpuInfo );
453 pDXGIFactory->Release();
457 FreeLibrary( hDXGI );
477 char returnBuffer[256];
483 aReturnString = ConvertBSTRToMBS( aVar->bstrVal );
488 if( VARIANT_TRUE == aVar->boolVal )
489 aReturnString =
"true";
491 aReturnString =
"false";
496 sprintf_s( returnBuffer,
sizeof( returnBuffer ) - 1,
"%u", aVar->uintVal );
498 aReturnString = returnBuffer;
503 sprintf_s( returnBuffer,
sizeof( returnBuffer ) - 1,
"%u", aVar->uintVal );
504 aReturnString = returnBuffer;
509 sprintf_s( returnBuffer,
sizeof( returnBuffer ) - 1,
"%u", aVar->uintVal );
510 aReturnString = returnBuffer;
513 case VT_BSTR | VT_ARRAY:
516 hr = SafeArrayAccessData( aVar->parray, (
void**) &raw );
518 const _bstr_t bstr( raw[0] );
519 hr = SafeArrayUnaccessData( aVar->parray );
521 aReturnString = ConvertBSTRToMBS( bstr );
524 case VT_I4 | VT_ARRAY:
528 SafeArrayGetLBound( aVar->parray, 1, &low );
529 SafeArrayGetUBound( aVar->parray, 1, &high );
531 hr = SafeArrayAccessData( aVar->parray, (
void HUGEP**) &pBuf );
532 hr = SafeArrayUnaccessData( aVar->parray );
534 high = std::min( high, (
long) MAX_PATH * 2 - 1 );
535 for( LONG i = low; i <= high; ++i )
537 sprintf_s( returnBuffer,
sizeof( returnBuffer ) - 1,
"%02X", pBuf[i] );
538 aReturnString += returnBuffer;
Object to store and handle common variant information.