From 9235e08e8750ddaa56a37d410f1a177a5666733a Mon Sep 17 00:00:00 2001 From: Elisha Riedlinger Date: Wed, 26 Jun 2024 12:07:26 -0700 Subject: [PATCH] Return an effect class even on failure --- BuildNo.rc | 2 +- IDirectInputDeviceX.cpp | 12 ++++-- IDirectInputDeviceX.h | 8 ++++ IDirectInputEffect.cpp | 83 +++++++++++++++++++++++++++++++++++++++++ IDirectInputEffect.h | 1 + 5 files changed, 102 insertions(+), 4 deletions(-) diff --git a/BuildNo.rc b/BuildNo.rc index f4eb9ba..9b98e6b 100644 --- a/BuildNo.rc +++ b/BuildNo.rc @@ -1 +1 @@ -#define BUILD_NUMBER 72 +#define BUILD_NUMBER 73 diff --git a/IDirectInputDeviceX.cpp b/IDirectInputDeviceX.cpp index 88a7915..6451e4c 100644 --- a/IDirectInputDeviceX.cpp +++ b/IDirectInputDeviceX.cpp @@ -706,14 +706,20 @@ HRESULT m_IDirectInputDeviceX::CreateEffect(REFGUID rguid, LPCDIEFFECT lpeff, LP if (SUCCEEDED(hr) && ppdeff) { - m_IDirectInputEffect* DIEffect = new m_IDirectInputEffect((IDirectInputEffect*)*ppdeff); - DIEffect->SetVersion(diVersion); + m_IDirectInputEffect* pEffect = new m_IDirectInputEffect((IDirectInputEffect*)*ppdeff); + pEffect->SetVersion(diVersion); - *ppdeff = DIEffect; + *ppdeff = pEffect; } else { Logging::LogDebug() << __FUNCTION__ << " (" << this << ") Failed! hr: " << (DIERR)hr; + + m_IDirectInputEffect* pEffect = new m_IDirectInputEffect(nullptr); + effects.push_back(pEffect); + + // Return an effect class even on failure becasue some games don't check for failure + *ppdeff = pEffect; } return hr; diff --git a/IDirectInputDeviceX.h b/IDirectInputDeviceX.h index 4efed24..f3b3d71 100644 --- a/IDirectInputDeviceX.h +++ b/IDirectInputDeviceX.h @@ -18,6 +18,9 @@ class m_IDirectInputDeviceX : public AddressLookupTableDinputObject void *WrapperInterface2; void *WrapperInterface7; + // Vector to store instances of m_IDirectInputEffect + std::vector effects; + // For CooperativeLevel bool CanAquireDevice = false; @@ -155,6 +158,11 @@ class m_IDirectInputDeviceX : public AddressLookupTableDinputObject ((m_IDirectInput7W*)WrapperInterface7)->DeleteMe(); } + for (auto& entry : effects) + { + entry.DeleteMe(); + } + // Delete Critical Section DeleteCriticalSection(&dics); } diff --git a/IDirectInputEffect.cpp b/IDirectInputEffect.cpp index 27f53aa..144256c 100644 --- a/IDirectInputEffect.cpp +++ b/IDirectInputEffect.cpp @@ -20,6 +20,25 @@ HRESULT m_IDirectInputEffect::QueryInterface(REFIID riid, LPVOID * ppvObj) { Logging::LogDebug() << __FUNCTION__ << " (" << this << ")"; + if (!ProxyInterface) + { + if (!ppvObj) + { + return E_POINTER; + } + *ppvObj = nullptr; + + if (riid == WrapperID || riid == IID_IUnknown) + { + *ppvObj = this; + + AddRef(); + + return DI_OK; + } + return E_POINTER; + } + return ProxyQueryInterface(ProxyInterface, riid, ppvObj, WrapperID, WrapperInterface); } @@ -27,6 +46,11 @@ ULONG m_IDirectInputEffect::AddRef() { Logging::LogDebug() << __FUNCTION__ << " (" << this << ")"; + if (!ProxyInterface) + { + return InterlockedIncrement(&Ref); + } + return ProxyInterface->AddRef(); } @@ -34,6 +58,16 @@ ULONG m_IDirectInputEffect::Release() { Logging::LogDebug() << __FUNCTION__ << " (" << this << ")"; + if (!ProxyInterface) + { + if (InterlockedCompareExchange(&Ref, 0, 0) == 0) + { + return 0; + } + + return InterlockedDecrement(&Ref); + } + ULONG ref = ProxyInterface->Release(); if (ref == 0) @@ -48,6 +82,11 @@ HRESULT m_IDirectInputEffect::Initialize(HINSTANCE hinst, DWORD dwVersion, REFGU { Logging::LogDebug() << __FUNCTION__ << " (" << this << ")"; + if (!ProxyInterface) + { + return DIERR_INCOMPLETEEFFECT; + } + HRESULT hr = hresValidInstanceAndVersion(hinst, dwVersion); if (SUCCEEDED(hr)) { @@ -66,6 +105,11 @@ HRESULT m_IDirectInputEffect::GetEffectGuid(LPGUID pguid) { Logging::LogDebug() << __FUNCTION__ << " (" << this << ")"; + if (!ProxyInterface) + { + return DIERR_NOTINITIALIZED; + } + return ProxyInterface->GetEffectGuid(pguid); } @@ -73,6 +117,11 @@ HRESULT m_IDirectInputEffect::GetParameters(LPDIEFFECT lpeff, DWORD dwFlags) { Logging::LogDebug() << __FUNCTION__ << " (" << this << ")"; + if (!ProxyInterface) + { + return DIERR_NOTINITIALIZED; + } + if (!lpeff || !lpeff->dwSize) { return DIERR_INVALIDPARAM; @@ -95,6 +144,11 @@ HRESULT m_IDirectInputEffect::SetParameters(LPCDIEFFECT lpeff, DWORD dwFlags) { Logging::LogDebug() << __FUNCTION__ << " (" << this << ") Trying! " << Logging::hex(dwFlags); + if (!ProxyInterface) + { + return DIERR_NOTINITIALIZED; + } + #ifdef _DEBUG GUID guid; GetEffectGuid(&guid); @@ -123,6 +177,10 @@ HRESULT m_IDirectInputEffect::Start(DWORD dwIterations, DWORD dwFlags) { Logging::LogDebug() << __FUNCTION__ << " (" << this << ") Trying! " << dwIterations << " " << Logging::hex(dwFlags); + if (!ProxyInterface) + { + return DIERR_NOTINITIALIZED; + } HRESULT hr = ProxyInterface->Start(dwIterations, dwFlags); @@ -138,6 +196,11 @@ HRESULT m_IDirectInputEffect::Stop() { Logging::LogDebug() << __FUNCTION__ << " (" << this << ")"; + if (!ProxyInterface) + { + return DIERR_NOTINITIALIZED; + } + return ProxyInterface->Stop(); } @@ -145,6 +208,11 @@ HRESULT m_IDirectInputEffect::GetEffectStatus(LPDWORD pdwFlags) { Logging::LogDebug() << __FUNCTION__ << " (" << this << ")"; + if (!ProxyInterface) + { + return DIERR_NOTINITIALIZED; + } + return ProxyInterface->GetEffectStatus(pdwFlags); } @@ -152,6 +220,11 @@ HRESULT m_IDirectInputEffect::Download() { Logging::LogDebug() << __FUNCTION__ << " (" << this << ")"; + if (!ProxyInterface) + { + return DIERR_NOTINITIALIZED; + } + return ProxyInterface->Download(); } @@ -159,6 +232,11 @@ HRESULT m_IDirectInputEffect::Unload() { Logging::LogDebug() << __FUNCTION__ << " (" << this << ")"; + if (!ProxyInterface) + { + return DIERR_NOTINITIALIZED; + } + return ProxyInterface->Unload(); } @@ -166,5 +244,10 @@ HRESULT m_IDirectInputEffect::Escape(LPDIEFFESCAPE pesc) { Logging::LogDebug() << __FUNCTION__ << " (" << this << ")"; + if (!ProxyInterface) + { + return DIERR_NOTINITIALIZED; + } + return ProxyInterface->Escape(pesc); } diff --git a/IDirectInputEffect.h b/IDirectInputEffect.h index f8ceb05..e4f0629 100644 --- a/IDirectInputEffect.h +++ b/IDirectInputEffect.h @@ -6,6 +6,7 @@ class m_IDirectInputEffect : public IDirectInputEffect, public AddressLookupTabl IDirectInputEffect *ProxyInterface; m_IDirectInputEffect *WrapperInterface; REFIID WrapperID = IID_IDirectInputEffect; + ULONG Ref = 1; // Requested DirectInput version - used to alter behaviour by requested version DWORD diVersion = 0;