diff --git a/Dllmain/BuildNo.rc b/Dllmain/BuildNo.rc index 4ef3de57..6641a4b3 100644 --- a/Dllmain/BuildNo.rc +++ b/Dllmain/BuildNo.rc @@ -1 +1 @@ -#define BUILD_NUMBER 7142 +#define BUILD_NUMBER 7143 diff --git a/Utils/Utils.cpp b/Utils/Utils.cpp index 18fcf7ae..6d35694f 100644 --- a/Utils/Utils.cpp +++ b/Utils/Utils.cpp @@ -1057,99 +1057,105 @@ inline UINT GetValueFromString(wchar_t* str) return num; } -DWORD Utils::GetVideoRam(UINT AdapterNo) +HRESULT Utils::GetVideoRam(UINT AdapterNo, DWORD& TotalMemory) { - UNREFERENCED_PARAMETER(AdapterNo); - - DWORD retSize = 0; + struct ADLIST { + DWORD DeviceID = 0; + DWORD AdapterRAM = 0; + }; + static std::vector AdapterList; -#if (_WIN32_WINNT >= 0x0502) - // Initialize COM - HRESULT hr = CoInitialize(nullptr); - if (FAILED(hr)) + if (AdapterList.size()) { - // Handle error - Logging::Log() << __FUNCTION__ << " Error: Failed to CoInitialize."; - return retSize; - } - - do { - // Create an instance of the IWbemLocator interface - CComPtr spLoc = nullptr; - hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_SERVER, IID_IWbemLocator, (LPVOID*)&spLoc); - if (FAILED(hr)) + for (auto& entry : AdapterList) { - // Handle error - Logging::Log() << __FUNCTION__ << " Error: Failed to CoCreateInstance."; - break; - } - - // Connect to the root\cimv2 namespace with the IWbemServices interface - CComPtr spServices = nullptr; - hr = spLoc->ConnectServer(CComBSTR(L"root\\cimv2"), nullptr, nullptr, nullptr, 0, nullptr, nullptr, &spServices); - if (FAILED(hr)) - { - // Handle error - Logging::Log() << __FUNCTION__ << " Error: Failed to connect to the root\\cimv2 namespace."; - break; + if (entry.DeviceID == AdapterNo) + { + TotalMemory = entry.AdapterRAM; + return S_OK; + } } + return E_FAIL; + } - // Set the security levels for the proxy - hr = CoSetProxyBlanket(spServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE); - if (FAILED(hr)) - { - // Handle error - Logging::Log() << __FUNCTION__ << " Error: Failed to set the security levels."; - break; - } + HRESULT hr = E_FAIL; + HRESULT t_hr = E_FAIL; + IWbemLocator* pLoc = NULL; + IWbemServices* pSvc = NULL; + IEnumWbemClassObject* pEnumerator = NULL; + IWbemClassObject* pclsObj = NULL; + ULONG uReturn = 0; - // Create an enumerator for Win32_VideoController instances - CComPtr spEnumInst = nullptr; - hr = spServices->CreateInstanceEnum(CComBSTR(L"Win32_VideoController"), WBEM_FLAG_SHALLOW, nullptr, &spEnumInst); - if (FAILED(hr)) + HRESULT c_hr = CoInitializeEx(0, COINIT_MULTITHREADED); + bool AlreadyInitialized = (c_hr == S_FALSE || c_hr == RPC_E_CHANGED_MODE); + if ((SUCCEEDED(c_hr) || AlreadyInitialized) && + SUCCEEDED(t_hr = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL)) && + SUCCEEDED(t_hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc))) + { + if (SUCCEEDED(t_hr = pLoc->ConnectServer(_bstr_t(L"root\\cimv2"), NULL, NULL, 0, NULL, 0, 0, &pSvc))) { - // Handle error - Logging::Log() << __FUNCTION__ << " Error: Failed to create an enumerator for Win32_VideoController instances."; - break; - } - - // Loop through the instances and retrieve the video RAM - ULONG uNumOfInstances = 0; - do { - CComPtr spInstance = nullptr; - hr = spEnumInst->Next(WBEM_INFINITE, 1, &spInstance, &uNumOfInstances); - if (SUCCEEDED(hr) && uNumOfInstances) + if (SUCCEEDED(t_hr = CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE)) && + SUCCEEDED(t_hr = pSvc->ExecQuery(bstr_t("WQL"), bstr_t("SELECT * FROM Win32_VideoController"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator))) { - // Get the DeviceID property from the instance - CComVariant varId; - hr = spInstance->Get(CComBSTR(L"DeviceID"), 0, &varId, nullptr, nullptr); - if (SUCCEEDED(hr)) + while (pEnumerator) { - UINT VideoAdapter = GetValueFromString(varId.bstrVal); + t_hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + if (FAILED(t_hr) || 0 == uReturn) + { + break; + } - // Check adapter number - if (AdapterNo == VideoAdapter) + VARIANT varId = {}; + + t_hr = pclsObj->Get(L"DeviceID", 0, &varId, 0, 0); + if (SUCCEEDED(t_hr)) { - // Get the AdapterRAM property from the instance - CComVariant varSize; - if (SUCCEEDED(spInstance->Get(CComBSTR(L"AdapterRAM"), 0, &varSize, nullptr, nullptr))) + UINT DeviceID = GetValueFromString(varId.bstrVal); + VariantClear(&varId); + + VARIANT vtTotalMemory = {}; + + t_hr = pclsObj->Get(L"AdapterRAM", 0, &vtTotalMemory, 0, 0); + if (SUCCEEDED(t_hr)) { - Logging::LogDebug() << __FUNCTION__ << " Found AdapterRAM on adapter: " << VideoAdapter << " Size: " << varSize.intVal; - retSize = varSize.intVal; - break; + Logging::Log() << __FUNCTION__ << " Found AdapterRAM on adapter: " << vtTotalMemory.ulVal / (1024 * 1024) << "MBs on DeviceID: " << DeviceID; + + ADLIST tmpItem = { DeviceID, vtTotalMemory.ulVal }; + AdapterList.push_back(tmpItem); + + // Check adapter number + if (AdapterNo == DeviceID) + { + TotalMemory = vtTotalMemory.ulVal; + hr = S_OK; + } + VariantClear(&vtTotalMemory); } } + pclsObj->Release(); } + pEnumerator->Release(); } - } while (SUCCEEDED(hr) && uNumOfInstances); - - } while (false); - - CoUninitialize(); -#endif // _WIN32_WINNT >= 0x0502 + pSvc->Release(); + } + pLoc->Release(); + } + if (c_hr == S_OK) + { + CoUninitialize(); + } + else if (AlreadyInitialized) + { + Logging::Log() << __FUNCTION__ << " Warning: CoInitializeEx() was already initialized: " << Logging::hex(hr); + } + else + { + Logging::Log() << __FUNCTION__ << " Error: CoInitializeEx() returned an error: " << Logging::hex(hr); + } - return retSize; + return hr; } + bool Utils::SetWndProcFilter(HWND hWnd) { // Check window handle diff --git a/Utils/Utils.h b/Utils/Utils.h index c77a6a82..a88a08c8 100644 --- a/Utils/Utils.h +++ b/Utils/Utils.h @@ -58,7 +58,7 @@ namespace Utils void GetScreenSize(HWND hwnd, LONG &screenWidth, LONG &screenHeight); void GetScreenSize(HWND hwnd, int &screenWidth, int &screenHeight); void GetDesktopRect(HWND hWnd, RECT& screenRect); - DWORD GetVideoRam(UINT AdapterNo); // Adapters start numbering from '1', based on "Win32_VideoController" WMI class and "DeviceID" property. + HRESULT GetVideoRam(UINT AdapterNo, DWORD& TotalMemory); // Adapters start numbering from '1', based on "Win32_VideoController" WMI class and "DeviceID" property. } namespace WriteMemory diff --git a/ddraw/IDirectDrawX.cpp b/ddraw/IDirectDrawX.cpp index 4e1f27f6..5b077adc 100644 --- a/ddraw/IDirectDrawX.cpp +++ b/ddraw/IDirectDrawX.cpp @@ -2047,23 +2047,17 @@ HRESULT m_IDirectDrawX::GetAvailableVidMem2(LPDDSCAPS2 lpDDSCaps2, LPDWORD lpdwT DWORD TotalMemory = 0; DWORD AvailableMemory = 0; - // Get texture/surface memory - if (lpDDSCaps2 && (lpDDSCaps2->dwCaps & (DDSCAPS_TEXTURE | DDSCAPS_OFFSCREENPLAIN | DDSCAPS_ZBUFFER))) + // Get memory + if (lpDDSCaps2 && ((lpDDSCaps2->dwCaps & (DDSCAPS_TEXTURE | DDSCAPS_OFFSCREENPLAIN | DDSCAPS_ZBUFFER)) || // Surface and Texture memory + (lpDDSCaps2->dwCaps & (DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_3DDEVICE)))) // Video memory { - GetTextureMemory(AvailableMemory); - } - // Get video memory - else if (lpDDSCaps2 && (lpDDSCaps2->dwCaps & (DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_3DDEVICE))) - { - // Open the first adapter in the system - if (OpenD3DDDI(GetDC()) && D3DDDIGetVideoMemory(TotalMemory, AvailableMemory)) + if (!OpenD3DDDI(GetDC()) || !D3DDDIGetVideoMemory(TotalMemory, AvailableMemory)) { - // Memory acquired using D3DDDI - } - // Failover to texture memory if DDI does not work - else - { - GetTextureMemory(AvailableMemory); + if (d3d9Device) + { + AvailableMemory = d3d9Device->GetAvailableTextureMem(); + } + Utils::GetVideoRam(1, TotalMemory); // Just get memory for the first adapter for now } } // Get non-local video memory @@ -2119,55 +2113,6 @@ HRESULT m_IDirectDrawX::GetAvailableVidMem2(LPDDSCAPS2 lpDDSCaps2, LPDWORD lpdwT return hr; } -void m_IDirectDrawX::GetTextureMemory(DWORD& AvailableMemory) -{ - if (d3d9Device) - { - AvailableMemory = d3d9Device->GetAvailableTextureMem(); - return; - } - - // Check for device interface - if (FAILED(CheckInterface(__FUNCTION__, false))) - { - AvailableMemory = 0; - return; - } - - LOG_LIMIT(100, __FUNCTION__ << " Creating temporary Direct3D9 device"); - - // Create a temporary window - HWND hWnd = CreateWindow(TEXT("TempD3DWindow"), TEXT("DxWrapper Temporary Window"), WS_POPUPWINDOW, - CW_USEDEFAULT, CW_USEDEFAULT, 100, 100, NULL, NULL, NULL, NULL); - if (!hWnd) - { - LOG_LIMIT(100, __FUNCTION__ << " Error: failed to create temporary window!"); - return; - } - - // Set up the Direct3D device parameters - D3DPRESENT_PARAMETERS d3dpp = {}; - d3dpp.Windowed = TRUE; - d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; - - // Create the Direct3D device - LPDIRECT3DDEVICE9 tmpD9Device = nullptr; - HRESULT hr = d3d9Object->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_NOWINDOWCHANGES, &d3dpp, &tmpD9Device); - if (FAILED(hr)) - { - AvailableMemory = 0; - LOG_LIMIT(100, __FUNCTION__ << " Error: failed to create temporary Direct3D9 device: " << (D3DERR)hr); - } - else - { - AvailableMemory = tmpD9Device->GetAvailableTextureMem(); - tmpD9Device->Release(); - } - - // Clean up the temporary window if we created one - DestroyWindow(hWnd); -} - /*********************************/ /*** Added in the V4 Interface ***/ /*********************************/ diff --git a/ddraw/IDirectDrawX.h b/ddraw/IDirectDrawX.h index 23407147..5793bd93 100644 --- a/ddraw/IDirectDrawX.h +++ b/ddraw/IDirectDrawX.h @@ -79,9 +79,6 @@ class m_IDirectDrawX : public IUnknown, public AddressLookupTableDdrawObject void InitDdraw(DWORD DirectXVersion); void ReleaseDdraw(); - // Get texture memory - void GetTextureMemory(DWORD &AvailableMemory); - // Direct3D9 interface functions HRESULT CheckInterface(char *FunctionName, bool CheckD3DDevice); HRESULT CreateD3D9Object();