| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455 |
- /************************************************************************************
- Filename : Util_GetSystemSpecs.cpp
- Content : This code needs to be shared by applications, but can't be in LibOVR.
- Define GET_SYSTEM_SPECS and include directly in a cpp file.
- Created : Feb 27, 2015
- Authors : Kevin Jenkins (moved from RiftConfigUtil)
- Copyright : Copyright 2015 Oculus, Inc. All Rights reserved.
- Use of this software is subject to the terms of the Oculus Inc license
- agreement provided at the time of installation or download, or which
- otherwise accompanies this software in either electronic or hard copy form.
- *************************************************************************************/
- #if defined(GET_SYSTEM_SPECS)
- #ifndef WCHAR_TO_OVR_STRING
- //Qt redefines wchar_t , but our String has an explicit constructor. Use this hack for desired behavior
- #define WCHAR_TO_OVR_STRING(wchar_array) String() + wchar_array
- #endif
- #include <QtCore/QMap>
- #include <QtCore/QStringList>
- #include "Util/Util_SystemInfo.h"
- #if defined(OVR_OS_WIN32)
- #define _WIN32_DCOM
- #include <comdef.h>
- #include <Wbemidl.h>
- # pragma comment(lib, "wbemuuid.lib")
- #include "DXGI.h"
- JSON* GetSystemSpecs()
- {
- JSON* specs = JSON::CreateObject();
- HRESULT hres;
- IWbemLocator *pLoc = NULL;
- hres = CoCreateInstance(
- CLSID_WbemLocator,
- 0,
- CLSCTX_INPROC_SERVER,
- IID_IWbemLocator, (LPVOID *)&pLoc);
- if (FAILED(hres))
- {
- return specs; // 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 (for example, Kerberos)
- 0, // Context object
- &pSvc // pointer to IWbemServices proxy
- );
- if (FAILED(hres))
- {
- pLoc->Release();
- return specs; // Program has failed.
- }
- 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))
- {
- pSvc->Release();
- pLoc->Release();
- return specs; // Program has failed.
- }
- IEnumWbemClassObject* pEnumerator = NULL;
- hres = pSvc->ExecQuery(
- bstr_t("WQL"),
- bstr_t("SELECT Caption FROM Win32_OperatingSystem"),
- WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
- NULL,
- &pEnumerator);
- if (FAILED(hres))
- {
- pSvc->Release();
- pLoc->Release();
- return specs; // Program has failed.
- }
- IWbemClassObject *pclsObj;
- ULONG uReturn = 0;
- while (pEnumerator)
- {
- HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
- &pclsObj, &uReturn);
- if (0 == uReturn)
- {
- break;
- }
- VARIANT vtProp;
- // Get the value of the Name property
- hr = pclsObj->Get(L"Caption", 0, &vtProp, 0, 0);
- specs->AddStringItem("Operating System", WCHAR_TO_OVR_STRING(vtProp.bstrVal));
- VariantClear(&vtProp);
- pclsObj->Release();
- }
- pEnumerator = NULL;
- hres = pSvc->ExecQuery(
- bstr_t("WQL"),
- bstr_t("SELECT Name FROM Win32_processor"),
- WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
- NULL,
- &pEnumerator);
- if (FAILED(hres))
- {
- pSvc->Release();
- pLoc->Release();
- return specs; // Program has failed.
- }
- uReturn = 0;
- while (pEnumerator)
- {
- HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
- &pclsObj, &uReturn);
- if (0 == uReturn)
- {
- break;
- }
- VARIANT vtProp;
- // Get the value of the Name property
- hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);
- specs->AddStringItem("Processor", WCHAR_TO_OVR_STRING(vtProp.bstrVal));
- VariantClear(&vtProp);
- pclsObj->Release();
- }
- pEnumerator = NULL;
- hres = pSvc->ExecQuery(
- bstr_t("WQL"),
- bstr_t("SELECT Name , AdapterRam, DriverVersion, VideoModeDescription FROM Win32_VideoController"),
- WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
- NULL,
- &pEnumerator);
- if (FAILED(hres))
- {
- pSvc->Release();
- pLoc->Release();
- return specs; // Program has failed.
- }
- JSON* graphicsadapters = JSON::CreateArray();
- uReturn = 0;
- while (pEnumerator)
- {
- JSON* graphicscard = JSON::CreateObject();
- HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
- &pclsObj, &uReturn);
- if (0 == uReturn)
- {
- break;
- }
- VARIANT vtProp;
- // Get the value of the Name property
- hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);
- graphicscard->AddStringItem("Name", WCHAR_TO_OVR_STRING(vtProp.bstrVal));
- VariantClear(&vtProp);
- // Get the value of the Name property
- hr = pclsObj->Get(L"AdapterRam", 0, &vtProp, 0, 0);
- uint32_t capacity = vtProp.uintVal;
- graphicscard->AddNumberItem("Video Controller RAM (MB)", capacity / 1048576);
- VariantClear(&vtProp);
- //get driver version
- hr = pclsObj->Get(L"DriverVersion", 0, &vtProp, 0, 0);
- graphicscard->AddStringItem("Driver Version", WCHAR_TO_OVR_STRING(vtProp.bstrVal));
- //get resolution
- hr = pclsObj->Get(L"VideoModeDescription", 0, &vtProp, 0, 0);
- graphicscard->AddStringItem("Video Mode", WCHAR_TO_OVR_STRING(vtProp.bstrVal));
- VariantClear(&vtProp);
- pclsObj->Release();
- graphicsadapters->AddArrayElement(graphicscard);
- }
- specs->AddItem("Graphics Adapters", graphicsadapters);
- pEnumerator = NULL;
- hres = pSvc->ExecQuery(
- bstr_t("WQL"),
- bstr_t("SELECT Capacity FROM Win32_PhysicalMemory"),
- WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
- NULL,
- &pEnumerator);
- if (FAILED(hres))
- {
- pSvc->Release();
- pLoc->Release();
- return specs; // Program has failed.
- }
- uint64_t totalram = 0;
- uReturn = 0;
- while (pEnumerator)
- {
- HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
- &pclsObj, &uReturn);
- if (0 == uReturn)
- {
- break;
- }
- VARIANT vtProp;
- // Get the value of the Name property
- hr = pclsObj->Get(L"Capacity", 0, &vtProp, 0, 0);
- uint64_t capacity = QString::fromWCharArray(vtProp.bstrVal).toLongLong();
- totalram += capacity;
- VariantClear(&vtProp);
- pclsObj->Release();
- }
- specs->AddNumberItem("Total RAM (GB)", totalram / 1073741824.0);
- JSON* usbtree = JSON::CreateArray();
- QMap<QString, QStringList> antecedents;
- pEnumerator = NULL;
- hres = pSvc->ExecQuery(
- bstr_t("WQL"),
- bstr_t("SELECT Antecedent,Dependent FROM Win32_USBControllerDevice"),
- WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
- NULL,
- &pEnumerator);
- if (FAILED(hres))
- {
- pSvc->Release();
- pLoc->Release();
- return specs; // Program has failed.
- }
- VARIANT vtProp;
- while (pEnumerator)
- {
- HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
- &pclsObj, &uReturn);
- if (0 == uReturn)
- {
- break;
- }
- // Get the reference value of the Antecedent property. There is not a function to dereference the value.
- hr = pclsObj->Get(L"Antecedent", 0, &vtProp, 0, 0);
- BSTR name = vtProp.bstrVal;
- //sanitize the string input to just the output
- QString antecedent = QString::fromWCharArray(name).split("=")[1].replace("\"", "");
- VariantClear(&vtProp);
- // Get the reference value of the Dependent property. There is not a function to dereference the value.
- hr = pclsObj->Get(L"Dependent", 0, &vtProp, 0, 0);
- name = vtProp.bstrVal;
- //sanitize the string input to just the output
- QString dependent = QString::fromWCharArray(name).split("=")[1].replace("\"", "");
- antecedents[antecedent].append(dependent);
- VariantClear(&vtProp);
- }
- for (int ant = 0; ant < antecedents.size(); ant++)
- {
- QString antecedent_name = antecedents.keys()[ant];
- //get antecedent object in a new enumerator
- IEnumWbemClassObject* pEnumerator2 = NULL;
- IWbemClassObject *pclsObj2;
- hres = pSvc->ExecQuery(
- bstr_t("WQL"),
- bstr_t("SELECT Manufacturer, Name, DeviceID, Caption FROM WIN32_USBController where deviceid = '") + bstr_t(antecedent_name.toUtf8()) + bstr_t("'"),
- WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
- NULL,
- &pEnumerator2);
- if (FAILED(hres))
- {
- pSvc->Release();
- pLoc->Release();
- return specs; // Program has failed.
- }
- JSON* USBAntecedent = JSON::CreateObject();
- while (pEnumerator2)
- {
- HRESULT hr = pEnumerator2->Next(WBEM_INFINITE, 1,
- &pclsObj2, &uReturn);
- if (0 == uReturn)
- {
- break;
- }
- VARIANT vtProp;
- // Get the value of the Name property
- hr = pclsObj2->Get(L"Name", 0, &vtProp, 0, 0);
- USBAntecedent->AddStringItem("name", WCHAR_TO_OVR_STRING(vtProp.bstrVal));
- VariantClear(&vtProp);
- // Get the value of the DeviceID property
- hr = pclsObj2->Get(L"DeviceID", 0, &vtProp, 0, 0);
- USBAntecedent->AddStringItem("deviceid", WCHAR_TO_OVR_STRING(vtProp.bstrVal));
- VariantClear(&vtProp);
- // Get the value of the caption property
- hr = pclsObj2->Get(L"Caption", 0, &vtProp, 0, 0);
- USBAntecedent->AddStringItem("caption", WCHAR_TO_OVR_STRING(vtProp.bstrVal));
- VariantClear(&vtProp);
- // Get the value of the manufacturer property
- hr = pclsObj2->Get(L"Manufacturer", 0, &vtProp, 0, 0);
- USBAntecedent->AddStringItem("manufacturer", WCHAR_TO_OVR_STRING(vtProp.bstrVal));
- VariantClear(&vtProp);
- pclsObj2->Release();
- }
- JSON* devices = JSON::CreateArray();
- for (int dev = 0; dev < antecedents[antecedent_name].size(); ++dev)
- {
- //get antecedent object in a new enumerator
- pEnumerator2 = NULL;
- if (!pclsObj2) pclsObj2->Release();
- hres = pSvc->ExecQuery(
- bstr_t("WQL"),
- bstr_t("SELECT Manufacturer,Name FROM Win32_PnPEntity where DeviceID = '") + bstr_t(antecedents[antecedent_name][dev].toUtf8()) + bstr_t("'"),
- WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
- NULL,
- &pEnumerator2);
- if (FAILED(hres))
- {
- pSvc->Release();
- pLoc->Release();
- return specs; // Program has failed.
- }
- while (pEnumerator2)
- {
- HRESULT hr = pEnumerator2->Next(WBEM_INFINITE, 1,
- &pclsObj2, &uReturn);
- if (0 == uReturn)
- {
- break;
- }
- VARIANT vtProp;
- JSON* properties = JSON::CreateObject();
- // Get the value of the Manufacturer property
- hr = pclsObj2->Get(L"Manufacturer", 0, &vtProp, 0, 0);
- properties->AddStringItem("manufacturer", WCHAR_TO_OVR_STRING(vtProp.bstrVal));
- VariantClear(&vtProp);
- // Get the value of the Manufacturer property
- hr = pclsObj2->Get(L"Name", 0, &vtProp, 0, 0);
- properties->AddStringItem("name", WCHAR_TO_OVR_STRING(vtProp.bstrVal));
- VariantClear(&vtProp);
- pclsObj2->Release();
- devices->AddArrayElement(properties);
- }
- }
- USBAntecedent->AddItem("Devices", devices);
- usbtree->AddArrayElement(USBAntecedent);
- }
- specs->AddItem("USB Tree", usbtree);
- // Cleanup
- // ========
- pSvc->Release();
- pLoc->Release();
- pEnumerator->Release();
- if (!pclsObj) pclsObj->Release();
- return specs;
- }
- #endif
- #ifdef OVR_OS_MAC
- JSON* GetSystemSpecs()
- {
- return nullptr;
- }
- #endif
- #ifdef OVR_OS_LINUX
- JSON* GetSystemSpecs()
- {
- return nullptr;
- }
- #endif
- #endif // GET_SYSTEM_SPECS
|