diff options
Diffstat (limited to 'indra/llwindow/lldxhardware.cpp')
-rwxr-xr-x | indra/llwindow/lldxhardware.cpp | 210 |
1 files changed, 189 insertions, 21 deletions
diff --git a/indra/llwindow/lldxhardware.cpp b/indra/llwindow/lldxhardware.cpp index b0f4bc5503..e7afef63f8 100755 --- a/indra/llwindow/lldxhardware.cpp +++ b/indra/llwindow/lldxhardware.cpp @@ -34,9 +34,12 @@ #include <dxdiag.h> #undef INITGUID +#include <wbemidl.h> + #include <boost/tokenizer.hpp> #include "lldxhardware.h" + #include "llerror.h" #include "llstring.h" @@ -53,11 +56,160 @@ LLDXHardware gDXHardware; #define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } } #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } } -std::string get_string(IDxDiagContainer *containerp, WCHAR *wszPropName) +typedef BOOL ( WINAPI* PfnCoSetProxyBlanket )( IUnknown* pProxy, DWORD dwAuthnSvc, DWORD dwAuthzSvc, + OLECHAR* pServerPrincName, DWORD dwAuthnLevel, DWORD dwImpLevel, + RPC_AUTH_IDENTITY_HANDLE pAuthInfo, DWORD dwCapabilities ); + +HRESULT GetVideoMemoryViaWMI( WCHAR* strInputDeviceID, DWORD* pdwAdapterRam ) { HRESULT hr; + bool bGotMemory = false; + HRESULT hrCoInitialize = S_OK; + IWbemLocator* pIWbemLocator = nullptr; + IWbemServices* pIWbemServices = nullptr; + BSTR pNamespace = nullptr; + + *pdwAdapterRam = 0; + hrCoInitialize = CoInitialize( 0 ); + + hr = CoCreateInstance( CLSID_WbemLocator, + nullptr, + CLSCTX_INPROC_SERVER, + IID_IWbemLocator, + ( LPVOID* )&pIWbemLocator ); +#ifdef PRINTF_DEBUGGING + if( FAILED( hr ) ) wprintf( L"WMI: CoCreateInstance failed: 0x%0.8x\n", hr ); +#endif + + if( SUCCEEDED( hr ) && pIWbemLocator ) + { + // Using the locator, connect to WMI in the given namespace. + pNamespace = SysAllocString( L"\\\\.\\root\\cimv2" ); + + hr = pIWbemLocator->ConnectServer( pNamespace, nullptr, nullptr, 0L, + 0L, nullptr, nullptr, &pIWbemServices ); +#ifdef PRINTF_DEBUGGING + if( FAILED( hr ) ) wprintf( L"WMI: pIWbemLocator->ConnectServer failed: 0x%0.8x\n", hr ); +#endif + if( SUCCEEDED( hr ) && pIWbemServices != 0 ) + { + HINSTANCE hinstOle32 = nullptr; + + hinstOle32 = LoadLibraryW( L"ole32.dll" ); + if( hinstOle32 ) + { + PfnCoSetProxyBlanket pfnCoSetProxyBlanket = nullptr; + + pfnCoSetProxyBlanket = ( PfnCoSetProxyBlanket )GetProcAddress( hinstOle32, "CoSetProxyBlanket" ); + if( pfnCoSetProxyBlanket != 0 ) + { + // Switch security level to IMPERSONATE. + pfnCoSetProxyBlanket( pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr, + RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, 0 ); + } + + FreeLibrary( hinstOle32 ); + } + + IEnumWbemClassObject* pEnumVideoControllers = nullptr; + BSTR pClassName = nullptr; + + pClassName = SysAllocString( L"Win32_VideoController" ); + + hr = pIWbemServices->CreateInstanceEnum( pClassName, 0, + nullptr, &pEnumVideoControllers ); +#ifdef PRINTF_DEBUGGING + if( FAILED( hr ) ) wprintf( L"WMI: pIWbemServices->CreateInstanceEnum failed: 0x%0.8x\n", hr ); +#endif + + if( SUCCEEDED( hr ) && pEnumVideoControllers ) + { + IWbemClassObject* pVideoControllers[10] = {0}; + DWORD uReturned = 0; + BSTR pPropName = nullptr; + + // Get the first one in the list + pEnumVideoControllers->Reset(); + hr = pEnumVideoControllers->Next( 5000, // timeout in 5 seconds + 10, // return the first 10 + pVideoControllers, + &uReturned ); +#ifdef PRINTF_DEBUGGING + if( FAILED( hr ) ) wprintf( L"WMI: pEnumVideoControllers->Next failed: 0x%0.8x\n", hr ); + if( uReturned == 0 ) wprintf( L"WMI: pEnumVideoControllers uReturned == 0\n" ); +#endif + + VARIANT var; + if( SUCCEEDED( hr ) ) + { + bool bFound = false; + for( UINT iController = 0; iController < uReturned; iController++ ) + { + if ( !pVideoControllers[iController] ) + continue; + + pPropName = SysAllocString( L"PNPDeviceID" ); + hr = pVideoControllers[iController]->Get( pPropName, 0L, &var, nullptr, nullptr ); +#ifdef PRINTF_DEBUGGING + if( FAILED( hr ) ) + wprintf( L"WMI: pVideoControllers[iController]->Get PNPDeviceID failed: 0x%0.8x\n", hr ); +#endif + if( SUCCEEDED( hr ) ) + { + if( wcsstr( var.bstrVal, strInputDeviceID ) != 0 ) + bFound = true; + } + VariantClear( &var ); + if( pPropName ) SysFreeString( pPropName ); + + if( bFound ) + { + pPropName = SysAllocString( L"AdapterRAM" ); + hr = pVideoControllers[iController]->Get( pPropName, 0L, &var, nullptr, nullptr ); +#ifdef PRINTF_DEBUGGING + if( FAILED( hr ) ) + wprintf( L"WMI: pVideoControllers[iController]->Get AdapterRAM failed: 0x%0.8x\n", + hr ); +#endif + if( SUCCEEDED( hr ) ) + { + bGotMemory = true; + *pdwAdapterRam = var.ulVal; + } + VariantClear( &var ); + if( pPropName ) SysFreeString( pPropName ); + break; + } + SAFE_RELEASE( pVideoControllers[iController] ); + } + } + } + + if( pClassName ) + SysFreeString( pClassName ); + SAFE_RELEASE( pEnumVideoControllers ); + } + + if( pNamespace ) + SysFreeString( pNamespace ); + SAFE_RELEASE( pIWbemServices ); + } + + SAFE_RELEASE( pIWbemLocator ); + + if( SUCCEEDED( hrCoInitialize ) ) + CoUninitialize(); + + if( bGotMemory ) + return S_OK; + else + return E_FAIL; +} + +void get_wstring(IDxDiagContainer* containerp, WCHAR* wszPropName, WCHAR* wszPropValue, int outputSize) +{ + HRESULT hr; VARIANT var; - WCHAR wszPropValue[256]; VariantInit( &var ); hr = containerp->GetProp(wszPropName, &var ); @@ -76,13 +228,19 @@ std::string get_string(IDxDiagContainer *containerp, WCHAR *wszPropName) wcscpy( wszPropValue, (var.boolVal) ? L"true" : L"false" ); /* Flawfinder: ignore */ break; case VT_BSTR: - wcsncpy( wszPropValue, var.bstrVal, 255 ); /* Flawfinder: ignore */ - wszPropValue[255] = 0; + wcsncpy( wszPropValue, var.bstrVal, outputSize-1 ); /* Flawfinder: ignore */ + wszPropValue[outputSize-1] = 0; break; } } // Clear the variant (this is needed to free BSTR memory) VariantClear( &var ); +} + +std::string get_string(IDxDiagContainer *containerp, WCHAR *wszPropName) +{ + WCHAR wszPropValue[256]; + get_wstring(containerp, wszPropName, wszPropValue, 256); return utf16str_to_utf8str(wszPropValue); } @@ -120,7 +278,7 @@ BOOL LLVersion::set(const std::string &version_string) } if (count < 4) { - //llwarns << "Potentially bogus version string!" << version_string << llendl; + //LL_WARNS() << "Potentially bogus version string!" << version_string << LL_ENDL; for (i = 0; i < 4; i++) { mFields[i] = 0; @@ -160,10 +318,10 @@ std::string LLDXDriverFile::dump() gWriteDebug(mDateString.c_str()); gWriteDebug("\n"); } - llinfos << mFilepath << llendl; - llinfos << mName << llendl; - llinfos << mVersionString << llendl; - llinfos << mDateString << llendl; + LL_INFOS() << mFilepath << LL_ENDL; + LL_INFOS() << mName << LL_ENDL; + LL_INFOS() << mVersionString << LL_ENDL; + LL_INFOS() << mDateString << LL_ENDL; return ""; } @@ -186,11 +344,11 @@ std::string LLDXDevice::dump() gWriteDebug(mPCIString.c_str()); gWriteDebug("\n"); } - llinfos << llendl; - llinfos << "DeviceName:" << mName << llendl; - llinfos << "PCIString:" << mPCIString << llendl; - llinfos << "Drivers" << llendl; - llinfos << "-------" << llendl; + LL_INFOS() << LL_ENDL; + LL_INFOS() << "DeviceName:" << mName << LL_ENDL; + LL_INFOS() << "PCIString:" << mPCIString << LL_ENDL; + LL_INFOS() << "Drivers" << LL_ENDL; + LL_INFOS() << "-------" << LL_ENDL; for (driver_file_map_t::iterator iter = mDriverFiles.begin(), end = mDriverFiles.end(); iter != end; iter++) @@ -361,8 +519,18 @@ BOOL LLDXHardware::getInfo(BOOL vram_only) goto LCleanup; } - // Get the English VRAM string + DWORD vram = 0; + + WCHAR deviceID[512]; + + get_wstring(device_containerp, L"szDeviceID", deviceID, 512); + + if (SUCCEEDED(GetVideoMemoryViaWMI(deviceID, &vram))) { + mVRAM = vram/(1024*1024); + } + else + { // Get the English VRAM string std::string ram_str = get_string(device_containerp, L"szDisplayMemoryEnglish"); // We don't need the device any more @@ -551,7 +719,7 @@ LLSD LLDXHardware::getDisplayInfo() IDxDiagContainer *driver_containerp = NULL; // CoCreate a IDxDiagProvider* - llinfos << "CoCreateInstance IID_IDxDiagProvider" << llendl; + LL_INFOS() << "CoCreateInstance IID_IDxDiagProvider" << LL_ENDL; hr = CoCreateInstance(CLSID_DxDiagProvider, NULL, CLSCTX_INPROC_SERVER, @@ -560,7 +728,7 @@ LLSD LLDXHardware::getDisplayInfo() if (FAILED(hr)) { - llwarns << "No DXDiag provider found! DirectX 9 not installed!" << llendl; + LL_WARNS() << "No DXDiag provider found! DirectX 9 not installed!" << LL_ENDL; gWriteDebug("No DXDiag provider found! DirectX 9 not installed!\n"); goto LCleanup; } @@ -578,14 +746,14 @@ LLSD LLDXHardware::getDisplayInfo() dx_diag_init_params.bAllowWHQLChecks = TRUE; dx_diag_init_params.pReserved = NULL; - llinfos << "dx_diag_providerp->Initialize" << llendl; + LL_INFOS() << "dx_diag_providerp->Initialize" << LL_ENDL; hr = dx_diag_providerp->Initialize(&dx_diag_init_params); if(FAILED(hr)) { goto LCleanup; } - llinfos << "dx_diag_providerp->GetRootContainer" << llendl; + LL_INFOS() << "dx_diag_providerp->GetRootContainer" << LL_ENDL; hr = dx_diag_providerp->GetRootContainer( &dx_diag_rootp ); if(FAILED(hr) || !dx_diag_rootp) { @@ -595,7 +763,7 @@ LLSD LLDXHardware::getDisplayInfo() HRESULT hr; // Get display driver information - llinfos << "dx_diag_rootp->GetChildContainer" << llendl; + LL_INFOS() << "dx_diag_rootp->GetChildContainer" << LL_ENDL; hr = dx_diag_rootp->GetChildContainer(L"DxDiag_DisplayDevices", &devices_containerp); if(FAILED(hr) || !devices_containerp) { @@ -603,7 +771,7 @@ LLSD LLDXHardware::getDisplayInfo() } // Get device 0 - llinfos << "devices_containerp->GetChildContainer" << llendl; + LL_INFOS() << "devices_containerp->GetChildContainer" << LL_ENDL; hr = devices_containerp->GetChildContainer(L"0", &device_containerp); if(FAILED(hr) || !device_containerp) { |