diff --git a/BuildNo.rc b/BuildNo.rc index 45ba0d9..f7dc662 100644 --- a/BuildNo.rc +++ b/BuildNo.rc @@ -1 +1 @@ -#define BUILD_NUMBER 3 +#define BUILD_NUMBER 4 diff --git a/Common/Logging.h b/Common/Logging.h index 9614919..ed64ec9 100644 --- a/Common/Logging.h +++ b/Common/Logging.h @@ -1,155 +1,168 @@ #pragma once #include +#include #include -namespace Logging -{ - extern std::ofstream LOG; +#ifndef DINPUTTO8NOLOG +extern std::ofstream LOG; +#endif - class Log +class Log +{ +public: + Log() {} + ~Log() { - public: - Log() {} - ~Log() +#ifndef DINPUTTO8NOLOG + if (LOG.is_open()) { - if (LOG.is_open()) - { - LOG << std::endl; - } + LOG << std::endl; } +#endif + } - template - Log& operator<<(const T& t) + template + Log& operator<<(const T& t) + { +#ifndef DINPUTTO8NOLOG + if (LOG.is_open()) { - if (LOG.is_open()) - { - LOG << t; - } - return *this; + LOG << t; } - }; +#else + std::cout << t; +#endif + return *this; + } +}; - class LogDebug +class LogDebug +{ +public: + LogDebug() {} + ~LogDebug() { - public: - LogDebug() {} - ~LogDebug() - { #ifdef _DEBUG - if (LOG.is_open()) - { - LOG << std::endl; - } -#endif // _DEBUG - } - - template - LogDebug& operator<<(const T& t) +#ifndef DINPUTTO8NOLOG + if (LOG.is_open()) { -#ifdef _DEBUG - if (LOG.is_open()) - { - LOG << t; - } -#endif // _DEBUG - return *this; + LOG << std::endl; } - }; +#endif +#endif // _DEBUG + } template - struct Hex + LogDebug& operator<<(const T& t) { - explicit Hex(T val) : val(val) {} - T val; - }; +#ifdef _DEBUG +#ifndef DINPUTTO8NOLOG + if (LOG.is_open()) + { + LOG << t; + } +#else + std::cout << t; +#endif +#else + std::cout << t; +#endif // _DEBUG + return *this; + } +}; - template - static Hex hex(T val) { return Hex(val); } +typedef struct { DWORD num; } hexDWORD; - template - typename std::enable_if::value && !std::is_same::value, std::ostream&>::type operator<<(std::ostream& os, const T& t) - { - return os << static_cast(&t); - } +static hexDWORD hex(DWORD val) { return *(hexDWORD*)&val; } - static std::ostream& operator<<(std::ostream& os, const wchar_t* wchr) - { - std::wstring ws(wchr); - return os << std::string(ws.begin(), ws.end()).c_str(); - } +template +typename std::enable_if::value && !std::is_same::value, std::ostream&>::type operator<<(std::ostream& os, const T& t) +{ + return os << static_cast(&t); +} + +static std::ostream& operator<<(std::ostream& os, hexDWORD num) +{ + return os << std::hex << num.num << std::dec; +} + +static std::ostream& operator<<(std::ostream& os, const wchar_t* wchr) +{ + std::wstring ws(wchr); + return os << std::string(ws.begin(), ws.end()).c_str(); +} #pragma warning(suppress: 4505) - static std::ostream& operator<<(std::ostream& os, REFIID riid) - { +static std::ostream& operator<<(std::ostream& os, REFIID riid) +{ #define CHECK_REFIID(riidPrefix, riidName) \ if (riid == riidPrefix ## _ ## riidName) \ { \ return os << #riidPrefix << "_" << #riidName; \ } - CHECK_REFIID(IID, IUnknown); - CHECK_REFIID(IID, IClassFactory); - // dinput - CHECK_REFIID(CLSID, DirectInput); - CHECK_REFIID(CLSID, DirectInputDevice); - CHECK_REFIID(CLSID, DirectInput8); - CHECK_REFIID(CLSID, DirectInputDevice8); - CHECK_REFIID(IID, IDirectInputA); - CHECK_REFIID(IID, IDirectInputW); - CHECK_REFIID(IID, IDirectInput2A); - CHECK_REFIID(IID, IDirectInput2W); - CHECK_REFIID(IID, IDirectInput7A); - CHECK_REFIID(IID, IDirectInput7W); - CHECK_REFIID(IID, IDirectInput8A); - CHECK_REFIID(IID, IDirectInput8W); - CHECK_REFIID(IID, IDirectInputDeviceA); - CHECK_REFIID(IID, IDirectInputDeviceW); - CHECK_REFIID(IID, IDirectInputDevice2A); - CHECK_REFIID(IID, IDirectInputDevice2W); - CHECK_REFIID(IID, IDirectInputDevice7A); - CHECK_REFIID(IID, IDirectInputDevice7W); - CHECK_REFIID(IID, IDirectInputDevice8A); - CHECK_REFIID(IID, IDirectInputDevice8W); - CHECK_REFIID(IID, IDirectInputEffect); - - return os << "{" - << hex(riid.Data1) << "," - << hex(riid.Data2) << "," - << hex(riid.Data3) << "," - << hex((UINT)riid.Data4[0]) << "," - << hex((UINT)riid.Data4[1]) << "," - << hex((UINT)riid.Data4[2]) << "," - << hex((UINT)riid.Data4[3]) << "," - << hex((UINT)riid.Data4[4]) << "," - << hex((UINT)riid.Data4[5]) << "," - << hex((UINT)riid.Data4[6]) << "," - << hex((UINT)riid.Data4[7]) << "," - << "}"; - } + CHECK_REFIID(IID, IUnknown); + CHECK_REFIID(IID, IClassFactory); + // dinput + CHECK_REFIID(CLSID, DirectInput); + CHECK_REFIID(CLSID, DirectInputDevice); + CHECK_REFIID(CLSID, DirectInput8); + CHECK_REFIID(CLSID, DirectInputDevice8); + CHECK_REFIID(IID, IDirectInputA); + CHECK_REFIID(IID, IDirectInputW); + CHECK_REFIID(IID, IDirectInput2A); + CHECK_REFIID(IID, IDirectInput2W); + CHECK_REFIID(IID, IDirectInput7A); + CHECK_REFIID(IID, IDirectInput7W); + CHECK_REFIID(IID, IDirectInput8A); + CHECK_REFIID(IID, IDirectInput8W); + CHECK_REFIID(IID, IDirectInputDeviceA); + CHECK_REFIID(IID, IDirectInputDeviceW); + CHECK_REFIID(IID, IDirectInputDevice2A); + CHECK_REFIID(IID, IDirectInputDevice2W); + CHECK_REFIID(IID, IDirectInputDevice7A); + CHECK_REFIID(IID, IDirectInputDevice7W); + CHECK_REFIID(IID, IDirectInputDevice8A); + CHECK_REFIID(IID, IDirectInputDevice8W); + CHECK_REFIID(IID, IDirectInputEffect); + + return os << "{" + << hex(riid.Data1) << "," + << hex(riid.Data2) << "," + << hex(riid.Data3) << "," + << hex((UINT)riid.Data4[0]) << "," + << hex((UINT)riid.Data4[1]) << "," + << hex((UINT)riid.Data4[2]) << "," + << hex((UINT)riid.Data4[3]) << "," + << hex((UINT)riid.Data4[4]) << "," + << hex((UINT)riid.Data4[5]) << "," + << hex((UINT)riid.Data4[6]) << "," + << hex((UINT)riid.Data4[7]) << "," + << "}"; +} #pragma warning(suppress: 4505) - static void logf(char * fmt, ...) - { - va_list ap; - va_start(ap, fmt); - auto size = vsnprintf(nullptr, 0, fmt, ap); - std::string output(size + 1, '\0'); - vsprintf_s(&output[0], size + 1, fmt, ap); - Log() << output.c_str(); - va_end(ap); - } +static void logf(char * fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + auto size = vsnprintf(nullptr, 0, fmt, ap); + std::string output(size + 1, '\0'); + vsprintf_s(&output[0], size + 1, fmt, ap); + Log() << output.c_str(); + va_end(ap); +} #pragma warning(suppress: 4505) - static void logf(wchar_t * fmt, ...) - { - va_list ap; - va_start(ap, fmt); +static void logf(wchar_t * fmt, ...) +{ + va_list ap; + va_start(ap, fmt); #pragma warning(suppress: 4996) - auto size = _vsnwprintf(nullptr, 0, fmt, ap); - std::wstring output(size + 1, '\0'); - vswprintf_s(&output[0], size + 1, fmt, ap); - Log() << output.c_str(); - va_end(ap); - } + auto size = _vsnwprintf(nullptr, 0, fmt, ap); + std::wstring output(size + 1, '\0'); + vswprintf_s(&output[0], size + 1, fmt, ap); + Log() << output.c_str(); + va_end(ap); } diff --git a/Common/Wrapper.h b/Common/Wrapper.h index 456d881..1948909 100644 --- a/Common/Wrapper.h +++ b/Common/Wrapper.h @@ -2,6 +2,9 @@ #include #include +#include "Common\Logging.h" + +constexpr UINT MaxIndex = 8; template class AddressLookupTableDinput @@ -11,16 +14,21 @@ class AddressLookupTableDinput ~AddressLookupTableDinput() { ConstructorFlag = true; - for (const auto& entry : g_map) + for (const auto& cache : g_map) { - entry.second->DeleteMe(); + for (const auto& entry : cache) + { + entry.second->DeleteMe(); + } } } template - struct AddressCacheIndex { }; + struct AddressCacheIndex { static constexpr UINT CacheIndex = 0; }; + template <> + struct AddressCacheIndex { static constexpr UINT CacheIndex = 1; }; template <> - struct AddressCacheIndex { + struct AddressCacheIndex { static constexpr UINT CacheIndex = 2; using Type1A = m_IDirectInputA; using Type2A = m_IDirectInput2A; using Type7A = m_IDirectInput7A; @@ -29,7 +37,17 @@ class AddressLookupTableDinput using Type7W = m_IDirectInput7W; }; template <> - struct AddressCacheIndex { + struct AddressCacheIndex { static constexpr UINT CacheIndex = 3; }; + template <> + struct AddressCacheIndex { static constexpr UINT CacheIndex = 4; }; + template <> + struct AddressCacheIndex { static constexpr UINT CacheIndex = 5; }; + template <> + struct AddressCacheIndex { static constexpr UINT CacheIndex = 6; }; + template <> + struct AddressCacheIndex { static constexpr UINT CacheIndex = 1; }; + template <> + struct AddressCacheIndex { static constexpr UINT CacheIndex = 2; using Type1A = m_IDirectInputDeviceA; using Type2A = m_IDirectInputDevice2A; using Type7A = m_IDirectInputDevice7A; @@ -37,6 +55,14 @@ class AddressLookupTableDinput using Type2W = m_IDirectInputDevice2W; using Type7W = m_IDirectInputDevice7W; }; + template <> + struct AddressCacheIndex { static constexpr UINT CacheIndex = 3; }; + template <> + struct AddressCacheIndex { static constexpr UINT CacheIndex = 4; }; + template <> + struct AddressCacheIndex { static constexpr UINT CacheIndex = 5; }; + template <> + struct AddressCacheIndex { static constexpr UINT CacheIndex = 6; }; template T *FindAddress(void *Proxy, DWORD Version, DWORD Type) @@ -77,16 +103,17 @@ class AddressLookupTableDinput } template - T *FindAddress(void *Proxy) + T * FindAddress(void *Proxy) { if (Proxy == nullptr) { return nullptr; } - auto it = g_map.find(Proxy); + constexpr UINT CacheIndex = AddressCacheIndex::CacheIndex; + auto it = g_map[CacheIndex].find(Proxy); - if (it != std::end(g_map)) + if (it != std::end(g_map[CacheIndex])) { return static_cast(it->second); } @@ -97,9 +124,10 @@ class AddressLookupTableDinput template void SaveAddress(T *Wrapper, void *Proxy) { + constexpr UINT CacheIndex = AddressCacheIndex::CacheIndex; if (Wrapper != nullptr && Proxy != nullptr) { - g_map[Proxy] = Wrapper; + g_map[CacheIndex][Proxy] = Wrapper; } } @@ -108,19 +136,20 @@ class AddressLookupTableDinput { if (Wrapper != nullptr && !ConstructorFlag) { - auto it = std::find_if(g_map.begin(), g_map.end(), - [Wrapper](std::pair Map) -> bool { return Map.second == Wrapper; }); + constexpr UINT CacheIndex = AddressCacheIndex::CacheIndex; + auto it = std::find_if(g_map[CacheIndex].begin(), g_map[CacheIndex].end(), + [=](auto Map) -> bool { return Map.second == Wrapper; }); - if (it != std::end(g_map)) + if (it != std::end(g_map[CacheIndex])) { - it = g_map.erase(it); + it = g_map[CacheIndex].erase(it); } } } private: bool ConstructorFlag = false; - std::unordered_map g_map; + std::unordered_map g_map[MaxIndex]; }; class AddressLookupTableObject diff --git a/IDirectInputDeviceX.cpp b/IDirectInputDeviceX.cpp index d5c0173..a8a696e 100644 --- a/IDirectInputDeviceX.cpp +++ b/IDirectInputDeviceX.cpp @@ -18,16 +18,22 @@ HRESULT m_IDirectInputDeviceX::QueryInterface(REFIID riid, LPVOID* ppvObj) { + LogDebug() << __FUNCTION__; + return ProxyQueryInterface(ProxyInterface, riid, ppvObj, WrapperID, WrapperInterface); } ULONG m_IDirectInputDeviceX::AddRef() { + LogDebug() << __FUNCTION__; + return ProxyInterface->AddRef(); } ULONG m_IDirectInputDeviceX::Release() { + LogDebug() << __FUNCTION__; + ULONG x = ProxyInterface->Release(); if (x == 0) @@ -40,6 +46,8 @@ ULONG m_IDirectInputDeviceX::Release() HRESULT m_IDirectInputDeviceX::GetCapabilities(LPDIDEVCAPS lpDIDevCaps) { + LogDebug() << __FUNCTION__; + return ProxyInterface->GetCapabilities(lpDIDevCaps); } @@ -48,51 +56,71 @@ template HRESULT m_IDirectInputDeviceX::EnumObjects HRESULT m_IDirectInputDeviceX::EnumObjects(T lpCallback, LPVOID pvRef, DWORD dwFlags) { + LogDebug() << __FUNCTION__; + return ProxyInterface->EnumObjects((LPDIENUMDEVICEOBJECTSCALLBACKW)lpCallback, pvRef, dwFlags); } HRESULT m_IDirectInputDeviceX::GetProperty(REFGUID rguidProp, LPDIPROPHEADER pdiph) { + LogDebug() << __FUNCTION__; + return ProxyInterface->GetProperty(rguidProp, pdiph); } HRESULT m_IDirectInputDeviceX::SetProperty(REFGUID rguidProp, LPCDIPROPHEADER pdiph) { + LogDebug() << __FUNCTION__; + return ProxyInterface->SetProperty(rguidProp, pdiph); } HRESULT m_IDirectInputDeviceX::Acquire() { + LogDebug() << __FUNCTION__; + return ProxyInterface->Acquire(); } HRESULT m_IDirectInputDeviceX::Unacquire() { + LogDebug() << __FUNCTION__; + return ProxyInterface->Unacquire(); } HRESULT m_IDirectInputDeviceX::GetDeviceState(DWORD cbData, LPVOID lpvData) { + LogDebug() << __FUNCTION__; + return ProxyInterface->GetDeviceState(cbData, lpvData); } HRESULT m_IDirectInputDeviceX::GetDeviceData(DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags) { + LogDebug() << __FUNCTION__; + return ProxyInterface->GetDeviceData(cbObjectData, rgdod, pdwInOut, dwFlags); } HRESULT m_IDirectInputDeviceX::SetDataFormat(LPCDIDATAFORMAT lpdf) { + LogDebug() << __FUNCTION__; + return ProxyInterface->SetDataFormat(lpdf); } HRESULT m_IDirectInputDeviceX::SetEventNotification(HANDLE hEvent) { + LogDebug() << __FUNCTION__; + return ProxyInterface->SetEventNotification(hEvent); } HRESULT m_IDirectInputDeviceX::SetCooperativeLevel(HWND hwnd, DWORD dwFlags) { + LogDebug() << __FUNCTION__; + return ProxyInterface->SetCooperativeLevel(hwnd, dwFlags); } @@ -101,6 +129,8 @@ template HRESULT m_IDirectInputDeviceX::GetObjectInfo template HRESULT m_IDirectInputDeviceX::GetObjectInfo(T pdidoi, DWORD dwObj, DWORD dwHow) { + LogDebug() << __FUNCTION__; + return ProxyInterface->GetObjectInfo((LPDIDEVICEOBJECTINSTANCEW)pdidoi, dwObj, dwHow); } @@ -109,21 +139,29 @@ template HRESULT m_IDirectInputDeviceX::GetDeviceInfo(LPDID template HRESULT m_IDirectInputDeviceX::GetDeviceInfo(T pdidi) { + LogDebug() << __FUNCTION__; + return ProxyInterface->GetDeviceInfo((LPDIDEVICEINSTANCEW)pdidi); } HRESULT m_IDirectInputDeviceX::RunControlPanel(HWND hwndOwner, DWORD dwFlags) { + LogDebug() << __FUNCTION__; + return ProxyInterface->RunControlPanel(hwndOwner, dwFlags); } HRESULT m_IDirectInputDeviceX::Initialize(HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) { + LogDebug() << __FUNCTION__; + return ProxyInterface->Initialize(hinst, dwVersion, rguid); } HRESULT m_IDirectInputDeviceX::CreateEffect(REFGUID rguid, LPCDIEFFECT lpeff, LPDIRECTINPUTEFFECT * ppdeff, LPUNKNOWN punkOuter) { + LogDebug() << __FUNCTION__; + HRESULT hr = ProxyInterface->CreateEffect(rguid, lpeff, ppdeff, punkOuter); if (SUCCEEDED(hr) && ppdeff) @@ -139,6 +177,8 @@ template HRESULT m_IDirectInputDeviceX::EnumEffects(LP template HRESULT m_IDirectInputDeviceX::EnumEffects(T lpCallback, LPVOID pvRef, DWORD dwEffType) { + LogDebug() << __FUNCTION__; + return ProxyInterface->EnumEffects((LPDIENUMEFFECTSCALLBACKW)lpCallback, pvRef, dwEffType); } @@ -147,21 +187,29 @@ template HRESULT m_IDirectInputDeviceX::GetEffectInfo(LPDIEFFEC template HRESULT m_IDirectInputDeviceX::GetEffectInfo(T pdei, REFGUID rguid) { + LogDebug() << __FUNCTION__; + return ProxyInterface->GetEffectInfo((LPDIEFFECTINFOW)pdei, rguid); } HRESULT m_IDirectInputDeviceX::GetForceFeedbackState(LPDWORD pdwOut) { + LogDebug() << __FUNCTION__; + return ProxyInterface->GetForceFeedbackState(pdwOut); } HRESULT m_IDirectInputDeviceX::SendForceFeedbackCommand(DWORD dwFlags) { + LogDebug() << __FUNCTION__; + return ProxyInterface->SendForceFeedbackCommand(dwFlags); } HRESULT m_IDirectInputDeviceX::EnumCreatedEffectObjects(LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, LPVOID pvRef, DWORD fl) { + LogDebug() << __FUNCTION__; + ENUMEFFECT CallbackContext; CallbackContext.pvRef = pvRef; CallbackContext.lpCallback = lpCallback; @@ -171,16 +219,22 @@ HRESULT m_IDirectInputDeviceX::EnumCreatedEffectObjects(LPDIENUMCREATEDEFFECTOBJ HRESULT m_IDirectInputDeviceX::Escape(LPDIEFFESCAPE pesc) { + LogDebug() << __FUNCTION__; + return ProxyInterface->Escape(pesc); } HRESULT m_IDirectInputDeviceX::Poll() { + LogDebug() << __FUNCTION__; + return ProxyInterface->Poll(); } HRESULT m_IDirectInputDeviceX::SendDeviceData(DWORD cbObjectData, LPCDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD fl) { + LogDebug() << __FUNCTION__; + return ProxyInterface->SendDeviceData(cbObjectData, rgdod, pdwInOut, fl); } @@ -189,6 +243,8 @@ template HRESULT m_IDirectInputDeviceX::EnumEffectsInFile(LPCWSTR lpszF template HRESULT m_IDirectInputDeviceX::EnumEffectsInFile(T lpszFileName, LPDIENUMEFFECTSINFILECALLBACK pec, LPVOID pvRef, DWORD dwFlags) { + LogDebug() << __FUNCTION__; + return ProxyInterface->EnumEffectsInFile((LPCWSTR)lpszFileName, pec, pvRef, dwFlags); } @@ -197,5 +253,7 @@ template HRESULT m_IDirectInputDeviceX::WriteEffectToFile(LPCWSTR lpszF template HRESULT m_IDirectInputDeviceX::WriteEffectToFile(T lpszFileName, DWORD dwEntries, LPDIFILEEFFECT rgDiFileEft, DWORD dwFlags) { + LogDebug() << __FUNCTION__; + return ProxyInterface->WriteEffectToFile((LPCWSTR)lpszFileName, dwEntries, rgDiFileEft, dwFlags); } diff --git a/IDirectInputDeviceX.h b/IDirectInputDeviceX.h index ec2b5c9..2d78c92 100644 --- a/IDirectInputDeviceX.h +++ b/IDirectInputDeviceX.h @@ -13,6 +13,8 @@ class m_IDirectInputDeviceX m_IDirectInputDeviceX(IDirectInputDevice8W *aOriginal, DWORD Version, REFIID riid, m_IDirectInputDevice7W *Interface) : ProxyInterface(aOriginal), DirectXVersion(Version), WrapperID(riid), WrapperInterface(Interface) { StringType = GetStringType(WrapperID); + + LogDebug() << "Creating device " << __FUNCTION__ << " converting device from v" << Version << " to v8 using " << ((StringType == UNICODE) ? "UNICODE" : "ANSI"); } ~m_IDirectInputDeviceX() { } diff --git a/IDirectInputEffect.cpp b/IDirectInputEffect.cpp index 4e2f4f1..d9912d7 100644 --- a/IDirectInputEffect.cpp +++ b/IDirectInputEffect.cpp @@ -18,16 +18,22 @@ HRESULT m_IDirectInputEffect::QueryInterface(REFIID riid, LPVOID * ppvObj) { + LogDebug() << __FUNCTION__; + return ProxyQueryInterface(ProxyInterface, riid, ppvObj, WrapperID, WrapperInterface); } ULONG m_IDirectInputEffect::AddRef() { + LogDebug() << __FUNCTION__; + return ProxyInterface->AddRef(); } ULONG m_IDirectInputEffect::Release() { + LogDebug() << __FUNCTION__; + ULONG x = ProxyInterface->Release(); if (x == 0) @@ -40,50 +46,70 @@ ULONG m_IDirectInputEffect::Release() HRESULT m_IDirectInputEffect::Initialize(HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) { + LogDebug() << __FUNCTION__; + return ProxyInterface->Initialize(hinst, dwVersion, rguid); } HRESULT m_IDirectInputEffect::GetEffectGuid(LPGUID pguid) { + LogDebug() << __FUNCTION__; + return ProxyInterface->GetEffectGuid(pguid); } HRESULT m_IDirectInputEffect::GetParameters(LPDIEFFECT peff, DWORD dwFlags) { + LogDebug() << __FUNCTION__; + return ProxyInterface->GetParameters(peff, dwFlags); } HRESULT m_IDirectInputEffect::SetParameters(LPCDIEFFECT peff, DWORD dwFlags) { + LogDebug() << __FUNCTION__; + return ProxyInterface->SetParameters(peff, dwFlags); } HRESULT m_IDirectInputEffect::Start(DWORD dwIterations, DWORD dwFlags) { + LogDebug() << __FUNCTION__; + return ProxyInterface->Start(dwIterations, dwFlags); } HRESULT m_IDirectInputEffect::Stop() { + LogDebug() << __FUNCTION__; + return ProxyInterface->Stop(); } HRESULT m_IDirectInputEffect::GetEffectStatus(LPDWORD pdwFlags) { + LogDebug() << __FUNCTION__; + return ProxyInterface->GetEffectStatus(pdwFlags); } HRESULT m_IDirectInputEffect::Download() { + LogDebug() << __FUNCTION__; + return ProxyInterface->Download(); } HRESULT m_IDirectInputEffect::Unload() { + LogDebug() << __FUNCTION__; + return ProxyInterface->Unload(); } HRESULT m_IDirectInputEffect::Escape(LPDIEFFESCAPE pesc) { + LogDebug() << __FUNCTION__; + return ProxyInterface->Escape(pesc); } diff --git a/IDirectInputEffect.h b/IDirectInputEffect.h index 6f85d92..7ece7e1 100644 --- a/IDirectInputEffect.h +++ b/IDirectInputEffect.h @@ -11,6 +11,8 @@ class m_IDirectInputEffect : public IDirectInputEffect, public AddressLookupTabl m_IDirectInputEffect(IDirectInputEffect *aOriginal) : ProxyInterface(aOriginal), WrapperInterface(this) { ProxyAddressLookupTable.SaveAddress(this, ProxyInterface); + + LogDebug() << "Creating device " << __FUNCTION__; } ~m_IDirectInputEffect() { diff --git a/IDirectInputX.cpp b/IDirectInputX.cpp index ca7b3a5..48a95eb 100644 --- a/IDirectInputX.cpp +++ b/IDirectInputX.cpp @@ -18,16 +18,22 @@ HRESULT m_IDirectInputX::QueryInterface(REFIID riid, LPVOID * ppvObj) { + LogDebug() << __FUNCTION__; + return ProxyQueryInterface(ProxyInterface, riid, ppvObj, WrapperID, WrapperInterface); } ULONG m_IDirectInputX::AddRef() { + LogDebug() << __FUNCTION__; + return ProxyInterface->AddRef(); } ULONG m_IDirectInputX::Release() { + LogDebug() << __FUNCTION__; + ULONG x = ProxyInterface->Release(); if (x == 0) @@ -43,6 +49,8 @@ template HRESULT m_IDirectInputX::CreateDevice(REFGUID rgu template HRESULT m_IDirectInputX::CreateDevice(REFGUID rguid, T *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) { + LogDebug() << __FUNCTION__; + HRESULT hr = ProxyInterface->CreateDevice(rguid, (LPDIRECTINPUTDEVICE8W *)lplpDirectInputDevice, pUnkOuter); if (SUCCEEDED(hr) && lplpDirectInputDevice) @@ -58,21 +66,29 @@ template HRESULT m_IDirectInputX::EnumDevices(DWORD dw template HRESULT m_IDirectInputX::EnumDevices(DWORD dwDevType, T lpCallback, LPVOID pvRef, DWORD dwFlags) { + LogDebug() << __FUNCTION__; + return ProxyInterface->EnumDevices(dwDevType, (LPDIENUMDEVICESCALLBACKW)lpCallback, pvRef, dwFlags); } HRESULT m_IDirectInputX::GetDeviceStatus(REFGUID rguidInstance) { + LogDebug() << __FUNCTION__; + return ProxyInterface->GetDeviceStatus(rguidInstance); } HRESULT m_IDirectInputX::RunControlPanel(HWND hwndOwner, DWORD dwFlags) { + LogDebug() << __FUNCTION__; + return ProxyInterface->RunControlPanel(hwndOwner, dwFlags); } HRESULT m_IDirectInputX::Initialize(HINSTANCE hinst, DWORD dwVersion) { + LogDebug() << __FUNCTION__; + return ProxyInterface->Initialize(hinst, dwVersion); } @@ -81,11 +97,15 @@ template HRESULT m_IDirectInputX::FindDevice(REFGUID rguidClass, LPCWST template HRESULT m_IDirectInputX::FindDevice(REFGUID rguidClass, T ptszName, LPGUID pguidInstance) { + LogDebug() << __FUNCTION__; + return ProxyInterface->FindDevice(rguidClass, (LPCWSTR)ptszName, pguidInstance); } HRESULT m_IDirectInputX::CreateDeviceEx(REFGUID rguid, REFIID riid, LPVOID * ppvObj, LPUNKNOWN pUnkOuter) { + LogDebug() << __FUNCTION__; + HRESULT hr = ProxyInterface->CreateDevice(rguid, (LPDIRECTINPUTDEVICE8W *)ppvObj, pUnkOuter); if (SUCCEEDED(hr)) diff --git a/IDirectInputX.h b/IDirectInputX.h index 8daab79..1e3a9ca 100644 --- a/IDirectInputX.h +++ b/IDirectInputX.h @@ -13,6 +13,8 @@ class m_IDirectInputX m_IDirectInputX(IDirectInput8W *aOriginal, DWORD Version, REFIID riid, m_IDirectInput7W *Interface) : ProxyInterface(aOriginal), DirectXVersion(Version), WrapperID(riid), WrapperInterface(Interface) { StringType = GetStringType(WrapperID); + + LogDebug() << "Creating device " << __FUNCTION__ << " converting device from v" << Version << " to v8 using " << ((StringType == UNICODE) ? "UNICODE" : "ANSI"); } ~m_IDirectInputX() { } diff --git a/InterfaceQuery.cpp b/InterfaceQuery.cpp index 9ec41d4..1af3ad0 100644 --- a/InterfaceQuery.cpp +++ b/InterfaceQuery.cpp @@ -24,6 +24,28 @@ DWORD GetStringType(REFIID riid) riid == IID_IDirectInputDeviceW || riid == IID_IDirectInputDevice2W || riid == IID_IDirectInputDevice7W) ? UNICODE : DIERR_UNSUPPORTED; } +REFIID ConvertREFIID(REFIID riid) +{ + if (riid == IID_IDirectInputA || riid == IID_IDirectInput2A || riid == IID_IDirectInput7A) + { + return IID_IDirectInput8A; + } + else if (riid == IID_IDirectInputW || riid == IID_IDirectInput2W || riid == IID_IDirectInput7W) + { + return IID_IDirectInput8W; + } + else if (riid == IID_IDirectInputDeviceA || riid == IID_IDirectInputDevice2A || riid == IID_IDirectInputDevice7A) + { + return IID_IDirectInputDevice8A; + } + else if (riid == IID_IDirectInputDeviceW || riid == IID_IDirectInputDevice2W || riid == IID_IDirectInputDevice7W) + { + return IID_IDirectInputDevice8W; + } + + return riid; +} + HRESULT ProxyQueryInterface(LPVOID ProxyInterface, REFIID riid, LPVOID * ppvObj, REFIID WrapperID, LPVOID WrapperInterface) { if (!ppvObj) @@ -40,7 +62,9 @@ HRESULT ProxyQueryInterface(LPVOID ProxyInterface, REFIID riid, LPVOID * ppvObj, return S_OK; } - HRESULT hr = ((IUnknown*)ProxyInterface)->QueryInterface(riid, ppvObj); + HRESULT hr = ((IUnknown*)ProxyInterface)->QueryInterface(ConvertREFIID(riid), ppvObj); + + LogDebug() << __FUNCTION__ << " QueryInterface --> '" << riid << "' QueryInterface results: " << hr; if (SUCCEEDED(hr)) { @@ -55,6 +79,7 @@ HRESULT genericQueryInterface(REFIID riid, LPVOID * ppvObj) #define QUERYINTERFACE(x) \ if (riid == IID_ ## x) \ { \ + LogDebug() << "Getting device for: m_" ## #x; \ *ppvObj = ProxyAddressLookupTable.FindAddress(*ppvObj); \ return DI_OK; \ } diff --git a/dinput.h b/dinput.h index 078e18f..9855769 100644 --- a/dinput.h +++ b/dinput.h @@ -24,9 +24,7 @@ class m_IDirectInputDeviceX; #include #include "Common\Wrapper.h" -#ifndef DINPUTTO8NOLOG #include "Common\Logging.h" -#endif typedef HRESULT(WINAPI *DirectInput8CreateProc)(HINSTANCE, DWORD, REFIID, LPVOID*, LPUNKNOWN); typedef HRESULT(WINAPI *DllCanUnloadNowProc)(); @@ -38,6 +36,7 @@ DWORD GetStringType(REFIID riid); HRESULT genericQueryInterface(REFIID CalledID, LPVOID * ppvObj); HRESULT ProxyQueryInterface(LPVOID ProxyInterface, REFIID riid, LPVOID * ppvObj, REFIID WrapperID, LPVOID WrapperInterface); extern AddressLookupTableDinput ProxyAddressLookupTable; +extern DWORD diVersion; #include "Versions\IDirectInputA.h" #include "Versions\IDirectInputW.h" diff --git a/dllmain.cpp b/dllmain.cpp index 5e500e7..53e7595 100644 --- a/dllmain.cpp +++ b/dllmain.cpp @@ -18,63 +18,59 @@ #include "dinput.h" #ifndef DINPUTTO8NOLOG -std::ofstream Logging::LOG("dinput.log"); -#else -std::ofstream Logging::LOG; +std::ofstream LOG("dinput.log"); #endif -AddressLookupTableDinput ProxyAddressLookupTable = AddressLookupTableDinput(); -DirectInput8CreateProc m_pDirectInput8Create; -DllCanUnloadNowProc m_pDllCanUnloadNow; -DllGetClassObjectProc m_pDllGetClassObject; -DllRegisterServerProc m_pDllRegisterServer; -DllUnregisterServerProc m_pDllUnregisterServer; +bool InitFlag = false; +DWORD diVersion = 0; -bool WINAPI DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved) -{ - UNREFERENCED_PARAMETER(lpReserved); - UNREFERENCED_PARAMETER(hModule); +AddressLookupTableDinput ProxyAddressLookupTable = AddressLookupTableDinput(); - static HMODULE dinput8dll = nullptr; +DirectInput8CreateProc m_pDirectInput8Create = nullptr; +DllCanUnloadNowProc m_pDllCanUnloadNow = nullptr; +DllGetClassObjectProc m_pDllGetClassObject = nullptr; +DllRegisterServerProc m_pDllRegisterServer = nullptr; +DllUnregisterServerProc m_pDllUnregisterServer = nullptr; - switch (dwReason) +void InitDinput8() +{ + // Check if already initialized + if (InitFlag) { - case DLL_PROCESS_ATTACH: - // Load dll - char path[MAX_PATH]; - strcpy_s(path, "dinput8.dll"); - Logging::Log() << "Loading " << path; - dinput8dll = LoadLibraryA(path); - - // Get function addresses - m_pDirectInput8Create = (DirectInput8CreateProc)GetProcAddress(dinput8dll, "DirectInput8Create"); - m_pDllCanUnloadNow = (DllCanUnloadNowProc)GetProcAddress(dinput8dll, "DllCanUnloadNow"); - m_pDllGetClassObject = (DllGetClassObjectProc)GetProcAddress(dinput8dll, "DllGetClassObject"); - m_pDllRegisterServer = (DllRegisterServerProc)GetProcAddress(dinput8dll, "DllRegisterServer"); - m_pDllUnregisterServer = (DllUnregisterServerProc)GetProcAddress(dinput8dll, "DllUnregisterServer"); - break; - - case DLL_PROCESS_DETACH: - FreeLibrary(dinput8dll); - break; + return; } - - return true; + InitFlag = true; + + // Load dll + char path[MAX_PATH]; + strcpy_s(path, "dinput8.dll"); + Log() << "Loading " << path; + HMODULE dinput8dll = LoadLibraryA(path); + + // Get function addresses + m_pDirectInput8Create = (DirectInput8CreateProc)GetProcAddress(dinput8dll, "DirectInput8Create"); + m_pDllCanUnloadNow = (DllCanUnloadNowProc)GetProcAddress(dinput8dll, "DllCanUnloadNow"); + m_pDllGetClassObject = (DllGetClassObjectProc)GetProcAddress(dinput8dll, "DllGetClassObject"); + m_pDllRegisterServer = (DllRegisterServerProc)GetProcAddress(dinput8dll, "DllRegisterServer"); + m_pDllUnregisterServer = (DllUnregisterServerProc)GetProcAddress(dinput8dll, "DllUnregisterServer"); } HRESULT WINAPI DirectInputCreateA(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTA* lplpDirectInput, LPUNKNOWN punkOuter) { + InitDinput8(); + if (!m_pDirectInput8Create || !lplpDirectInput) { return E_FAIL; } - Logging::Log() << __FUNCTION__ << " Redirecting to --> 'DirectInput8Create'"; + Log() << __FUNCTION__ << " Redirecting version " << hex(dwVersion) << " to --> 'DirectInput8Create'"; - HRESULT hr = m_pDirectInput8Create(hinst, dwVersion, IID_IDirectInput8A, (LPVOID*)lplpDirectInput, punkOuter); + HRESULT hr = m_pDirectInput8Create(hinst, 0x0800, IID_IDirectInput8A, (LPVOID*)lplpDirectInput, punkOuter); if (SUCCEEDED(hr)) { + diVersion = dwVersion; *lplpDirectInput = ProxyAddressLookupTable.FindAddress(*lplpDirectInput); } @@ -83,17 +79,20 @@ HRESULT WINAPI DirectInputCreateA(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPU HRESULT WINAPI DirectInputCreateEx(HINSTANCE hinst, DWORD dwVersion, REFIID riid, LPVOID * lplpDD, LPUNKNOWN punkOuter) { + InitDinput8(); + if (!m_pDirectInput8Create || !lplpDD) { return E_FAIL; } - Logging::Log() << __FUNCTION__ << " Redirecting to --> 'DirectInput8Create' using " << riid; + Log() << __FUNCTION__ << " Redirecting version " << hex(dwVersion) << " to --> 'DirectInput8Create'"; - HRESULT hr = m_pDirectInput8Create(hinst, dwVersion, (GetStringType(riid) == UNICODE) ? IID_IDirectInput8W : IID_IDirectInput8A, lplpDD, punkOuter); + HRESULT hr = m_pDirectInput8Create(hinst, 0x0800, (GetStringType(riid) == UNICODE) ? IID_IDirectInput8W : IID_IDirectInput8A, lplpDD, punkOuter); if (SUCCEEDED(hr)) { + diVersion = dwVersion; genericQueryInterface(riid, lplpDD); } @@ -102,17 +101,20 @@ HRESULT WINAPI DirectInputCreateEx(HINSTANCE hinst, DWORD dwVersion, REFIID riid HRESULT WINAPI DirectInputCreateW(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTW* lplpDirectInput, LPUNKNOWN punkOuter) { + InitDinput8(); + if (!m_pDirectInput8Create || !lplpDirectInput) { return E_FAIL; } - Logging::Log() << __FUNCTION__ << " Redirecting to --> 'DirectInput8Create'"; + Log() << __FUNCTION__ << " Redirecting version " << hex(dwVersion) << " to --> 'DirectInput8Create'"; - HRESULT hr = m_pDirectInput8Create(hinst, dwVersion, IID_IDirectInput8W, (LPVOID*)lplpDirectInput, punkOuter); + HRESULT hr = m_pDirectInput8Create(hinst, 0x0800, IID_IDirectInput8W, (LPVOID*)lplpDirectInput, punkOuter); if (SUCCEEDED(hr)) { + diVersion = dwVersion; *lplpDirectInput = ProxyAddressLookupTable.FindAddress(*lplpDirectInput); } @@ -121,6 +123,8 @@ HRESULT WINAPI DirectInputCreateW(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPU HRESULT WINAPI DllCanUnloadNow() { + InitDinput8(); + if (!m_pDllCanUnloadNow) { return E_FAIL; @@ -131,6 +135,8 @@ HRESULT WINAPI DllCanUnloadNow() HRESULT WINAPI DllGetClassObject(IN REFCLSID rclsid, IN REFIID riid, OUT LPVOID FAR* ppv) { + InitDinput8(); + if (!m_pDllGetClassObject || !ppv) { return E_FAIL; @@ -150,6 +156,8 @@ HRESULT WINAPI DllGetClassObject(IN REFCLSID rclsid, IN REFIID riid, OUT LPVOID HRESULT WINAPI DllRegisterServer() { + InitDinput8(); + if (!m_pDllRegisterServer) { return E_FAIL; @@ -160,6 +168,8 @@ HRESULT WINAPI DllRegisterServer() HRESULT WINAPI DllUnregisterServer() { + InitDinput8(); + if (!m_pDllUnregisterServer) { return E_FAIL;