summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llwindow/lldxhardware.cpp155
-rw-r--r--indra/llwindow/lldxhardware.h2
-rw-r--r--indra/newview/llappviewer.cpp15
3 files changed, 169 insertions, 3 deletions
diff --git a/indra/llwindow/lldxhardware.cpp b/indra/llwindow/lldxhardware.cpp
index e7afef63f8..d4790f9f29 100644
--- a/indra/llwindow/lldxhardware.cpp
+++ b/indra/llwindow/lldxhardware.cpp
@@ -35,6 +35,7 @@
#undef INITGUID
#include <wbemidl.h>
+#include <comdef.h>
#include <boost/tokenizer.hpp>
@@ -206,6 +207,160 @@ HRESULT GetVideoMemoryViaWMI( WCHAR* strInputDeviceID, DWORD* pdwAdapterRam )
return E_FAIL;
}
+//Getting the version of graphics controller driver via WMI
+std::string LLDXHardware::getDriverVersionWMI()
+{
+ std::string mDriverVersion;
+ HRESULT hrCoInitialize = S_OK;
+ HRESULT hres;
+ hrCoInitialize = CoInitialize(0);
+ IWbemLocator *pLoc = NULL;
+
+ hres = CoCreateInstance(
+ CLSID_WbemLocator,
+ 0,
+ CLSCTX_INPROC_SERVER,
+ IID_IWbemLocator, (LPVOID *)&pLoc);
+
+ if (FAILED(hres))
+ {
+ LL_DEBUGS("AppInit") << "Failed to initialize COM library. Error code = 0x" << hres << LL_ENDL;
+ return std::string(); // Program has failed.
+ }
+
+ IWbemServices *pSvc = NULL;
+
+ // Connect to the root\cimv2 namespace with
+ // the current user and obtain pointer pSvc
+ // to make IWbemServices calls.
+ hres = pLoc->ConnectServer(
+ _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
+ NULL, // User name. NULL = current user
+ NULL, // User password. NULL = current
+ 0, // Locale. NULL indicates current
+ NULL, // Security flags.
+ 0, // Authority (e.g. Kerberos)
+ 0, // Context object
+ &pSvc // pointer to IWbemServices proxy
+ );
+
+ if (FAILED(hres))
+ {
+ LL_WARNS("AppInit") << "Could not connect. Error code = 0x" << hres << LL_ENDL;
+ pLoc->Release();
+ CoUninitialize();
+ return std::string(); // Program has failed.
+ }
+
+ LL_DEBUGS("AppInit") << "Connected to ROOT\\CIMV2 WMI namespace" << LL_ENDL;
+
+ // Set security levels on the proxy -------------------------
+ hres = CoSetProxyBlanket(
+ pSvc, // Indicates the proxy to set
+ RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
+ RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
+ NULL, // Server principal name
+ RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx
+ RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
+ NULL, // client identity
+ EOAC_NONE // proxy capabilities
+ );
+
+ if (FAILED(hres))
+ {
+ LL_WARNS("AppInit") << "Could not set proxy blanket. Error code = 0x" << hres << LL_ENDL;
+ pSvc->Release();
+ pLoc->Release();
+ CoUninitialize();
+ return std::string(); // Program has failed.
+ }
+ IEnumWbemClassObject* pEnumerator = NULL;
+
+ // Get the data from the query
+ ULONG uReturn = 0;
+ hres = pSvc->ExecQuery(
+ bstr_t("WQL"),
+ bstr_t("SELECT * FROM Win32_VideoController"), //Consider using Availability to filter out disabled controllers
+ WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
+ NULL,
+ &pEnumerator);
+
+ if (FAILED(hres))
+ {
+ LL_WARNS("AppInit") << "Query for operating system name failed." << " Error code = 0x" << hres << LL_ENDL;
+ pSvc->Release();
+ pLoc->Release();
+ CoUninitialize();
+ return std::string(); // Program has failed.
+ }
+
+ while (pEnumerator)
+ {
+ IWbemClassObject *pclsObj = NULL;
+ HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
+ &pclsObj, &uReturn);
+
+ if (0 == uReturn)
+ {
+ break; // If quantity less then 1.
+ }
+
+ VARIANT vtProp;
+
+ // Get the value of the Name property
+ hr = pclsObj->Get(L"DriverVersion", 0, &vtProp, 0, 0);
+
+ if (FAILED(hr))
+ {
+ LL_WARNS("AppInit") << "Query for name property failed." << " Error code = 0x" << hr << LL_ENDL;
+ pSvc->Release();
+ pLoc->Release();
+ CoUninitialize();
+ return std::string(); // Program has failed.
+ }
+
+ // use characters in the returned driver version
+ BSTR driverVersion(vtProp.bstrVal);
+
+ //convert BSTR to std::string
+ std::wstring ws(driverVersion, SysStringLen(driverVersion));
+ std::string str(ws.begin(), ws.end());
+ LL_INFOS("AppInit") << " DriverVersion : " << str << LL_ENDL;
+
+ if (mDriverVersion.empty())
+ {
+ mDriverVersion = str;
+ }
+ else if (mDriverVersion != str)
+ {
+ LL_WARNS("DriverVersion") << "Different versions of drivers. Version of second driver : " << str << LL_ENDL;
+ }
+
+ VariantClear(&vtProp);
+ pclsObj->Release();
+ }
+
+ // Cleanup
+ // ========
+ if (pSvc)
+ {
+ pSvc->Release();
+ }
+ if (pLoc)
+ {
+ pLoc->Release();
+ }
+ if (pEnumerator)
+ {
+ pEnumerator->Release();
+ }
+ if (SUCCEEDED(hrCoInitialize))
+ {
+ CoUninitialize();
+ }
+ return mDriverVersion;
+}
+
void get_wstring(IDxDiagContainer* containerp, WCHAR* wszPropName, WCHAR* wszPropValue, int outputSize)
{
HRESULT hr;
diff --git a/indra/llwindow/lldxhardware.h b/indra/llwindow/lldxhardware.h
index 61a32bf0fb..cf33db8b37 100644
--- a/indra/llwindow/lldxhardware.h
+++ b/indra/llwindow/lldxhardware.h
@@ -88,6 +88,8 @@ public:
// vram_only TRUE does a "light" probe.
BOOL getInfo(BOOL vram_only);
+ std::string getDriverVersionWMI();
+
S32 getVRAM() const { return mVRAM; }
LLSD getDisplayInfo();
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index f53ba01d37..4095f1c8ef 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -3347,10 +3347,19 @@ LLSD LLAppViewer::getViewerInfo() const
info["GRAPHICS_CARD"] = (const char*)(glGetString(GL_RENDERER));
#if LL_WINDOWS
- LLSD driver_info = gDXHardware.getDisplayInfo();
- if (driver_info.has("DriverVersion"))
+ std::string drvinfo = gDXHardware.getDriverVersionWMI();
+ if (!drvinfo.empty())
{
- info["GRAPHICS_DRIVER_VERSION"] = driver_info["DriverVersion"];
+ info["GRAPHICS_DRIVER_VERSION"] = drvinfo;
+ }
+ else
+ {
+ LL_WARNS("Driver version")<< "Cannot get driver version from getDriverVersionWMI" << LL_ENDL;
+ LLSD driver_info = gDXHardware.getDisplayInfo();
+ if (driver_info.has("DriverVersion"))
+ {
+ info["GRAPHICS_DRIVER_VERSION"] = driver_info["DriverVersion"];
+ }
}
#endif