diff options
Diffstat (limited to 'indra')
| -rwxr-xr-x | indra/llwindow/lldxhardware.cpp | 178 | 
1 files changed, 173 insertions, 5 deletions
| diff --git a/indra/llwindow/lldxhardware.cpp b/indra/llwindow/lldxhardware.cpp index ba5bc8fcfb..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);  } @@ -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 | 
