Skip to content

Commit 9d2be14

Browse files
committed
Fix how DirectInput interfaces are created
#537
1 parent 6dab9f5 commit 9d2be14

File tree

6 files changed

+56
-41
lines changed

6 files changed

+56
-41
lines changed

Dllmain/BuildNo.rc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
#define BUILD_NUMBER 8317
1+
#define BUILD_NUMBER 8318

dinput8/IDirectInput8.cpp

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -68,19 +68,20 @@ template HRESULT m_IDirectInput8::CreateDeviceT<IDirectInput8W, LPDIRECTINPUTDEV
6868
template <class T, class V>
6969
HRESULT m_IDirectInput8::CreateDeviceT(T* ProxyInterfaceT, REFGUID rguid, V lplpDirectInputDevice, LPUNKNOWN pUnkOuter)
7070
{
71+
UNREFERENCED_PARAMETER(ProxyInterfaceT);
72+
7173
Logging::LogDebug() << __FUNCTION__ << " (" << this << ")";
7274

73-
HRESULT hr = ProxyInterfaceT->CreateDevice(rguid, lplpDirectInputDevice, pUnkOuter);
75+
IDirectInputDevice8W* ProxyDevice;
76+
HRESULT hr = ProxyInterface->CreateDevice(rguid, &ProxyDevice, pUnkOuter);
7477

75-
if (SUCCEEDED(hr) && lplpDirectInputDevice)
78+
if (SUCCEEDED(hr))
7679
{
77-
m_IDirectInputDevice8* pAddressX = new m_IDirectInputDevice8((IDirectInputDevice8W*)*lplpDirectInputDevice);
78-
79-
*lplpDirectInputDevice = pAddressX;
80+
m_IDirectInputDevice8* DIDevice = new m_IDirectInputDevice8(ProxyDevice);
8081

8182
bool isMouse = false;
8283

83-
if (IsEqualGUID(GUID_SysMouse, rguid) || IsEqualIID(GUID_SysMouseEm, rguid) || IsEqualIID(GUID_SysMouseEm2, rguid))
84+
if (IsEqualGUID(GUID_SysMouse, rguid) || IsEqualGUID(GUID_SysMouseEm, rguid) || IsEqualGUID(GUID_SysMouseEm2, rguid))
8485
{
8586
isMouse = true;
8687
}
@@ -89,7 +90,7 @@ HRESULT m_IDirectInput8::CreateDeviceT(T* ProxyInterfaceT, REFGUID rguid, V lplp
8990
DIDEVCAPS caps = {};
9091
caps.dwSize = sizeof(DIDEVCAPS);
9192

92-
if (SUCCEEDED(pAddressX->GetCapabilities(&caps)))
93+
if (SUCCEEDED(DIDevice->GetCapabilities(&caps)))
9394
{
9495
if (GET_DIDEVICE_TYPE(caps.dwDevType) == DI8DEVTYPE_MOUSE)
9596
{
@@ -100,8 +101,13 @@ HRESULT m_IDirectInput8::CreateDeviceT(T* ProxyInterfaceT, REFGUID rguid, V lplp
100101

101102
if (isMouse)
102103
{
103-
pAddressX->SetAsMouse();
104+
DIDevice->SetAsMouse();
104105
}
106+
107+
REFGUID riid = std::is_same_v<T, IDirectInput8A> ? IID_IDirectInputDevice8A : IID_IDirectInputDevice8W;
108+
109+
hr = DIDevice->QueryInterface(riid, reinterpret_cast<LPVOID*>(lplpDirectInputDevice));
110+
DIDevice->Release();
105111
}
106112

107113
return hr;
@@ -234,12 +240,35 @@ HRESULT m_IDirectInput8::EnumDevicesBySemanticsT(T* ProxyInterfaceT, V ptszUserN
234240

235241
if (lpdid)
236242
{
237-
m_IDirectInputDevice8* WrapperDevice = ProxyAddressLookupTableDinput8.FindAddress<m_IDirectInputDevice8>(lpdid);
238-
if (WrapperDevice == nullptr)
243+
m_IDirectInputDevice8* DIDevice = ProxyAddressLookupTableDinput8.FindAddress<m_IDirectInputDevice8>(lpdid);
244+
if (DIDevice == nullptr)
245+
{
246+
m_IDirectInputDevice8::proxy_type* ProxyDevice;
247+
HRESULT hr = lpdid->QueryInterface(m_IDirectInputDevice8::proxy_iid, reinterpret_cast<LPVOID*>(&ProxyDevice));
248+
if (FAILED(hr))
249+
{
250+
LOG_LIMIT(100, __FUNCTION__ << " Error: could not query interface for: " << m_IDirectInputDevice8::proxy_iid);
251+
return DIENUM_CONTINUE;
252+
}
253+
254+
DIDevice = new m_IDirectInputDevice8(ProxyDevice);
255+
lpdid->Release();
256+
257+
REFGUID riid = std::is_same_v<T, IDirectInput8A> ? IID_IDirectInputDevice8A : IID_IDirectInputDevice8W;
258+
259+
hr = DIDevice->QueryInterface(riid, reinterpret_cast<LPVOID*>(lpdid));
260+
DIDevice->Release();
261+
262+
if (FAILED(hr))
263+
{
264+
LOG_LIMIT(100, __FUNCTION__ << " Error: failed to get interface for: " << riid);
265+
return DIENUM_CONTINUE;
266+
}
267+
}
268+
else
239269
{
240-
WrapperDevice = new m_IDirectInputDevice8(lpdid);
270+
lpdid = DIDevice;
241271
}
242-
lpdid = WrapperDevice;
243272
}
244273

245274
return self->lpCallback(lpddi, lpdid, dwFlags, dwRemaining, self->pvRef);

dinput8/IDirectInput8.h

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -55,20 +55,11 @@ class m_IDirectInput8 final : public IDirectInput8A, public IDirectInput8W, Addr
5555
inline HRESULT ConfigureDevicesT(T* ProxyInterfaceT, LPDICONFIGUREDEVICESCALLBACK lpdiCallback, V lpdiCDParams, DWORD dwFlags, LPVOID pvRefData);
5656

5757
public:
58-
m_IDirectInput8(IUnknown* aOriginal) : AddressLookupTableDinput8Object(aOriginal)
58+
m_IDirectInput8(proxy_type* aOriginal) : AddressLookupTableDinput8Object(aOriginal), ProxyInterface(aOriginal)
5959
{
60-
LOG_LIMIT(3, "Creating interface " << __FUNCTION__ << " (" << this << ")");
61-
62-
aOriginal->QueryInterface(IID_IDirectInput8A, reinterpret_cast<LPVOID*>(&ProxyInterfaceA));
63-
aOriginal->QueryInterface(IID_IDirectInput8W, reinterpret_cast<LPVOID*>(&ProxyInterface));
64-
if (aOriginal == ProxyInterface || aOriginal == ProxyInterfaceA)
65-
{
66-
aOriginal->Release();
67-
}
68-
else
69-
{
70-
LOG_LIMIT(3, __FUNCTION__ << " Warning: passed interface does not match either ProxyInterface values!");
71-
}
60+
LOG_LIMIT(3, "Creating interface " << __FUNCTION__ << "(" << this << ")");
61+
62+
ProxyInterface->QueryInterface(IID_IDirectInput8A, reinterpret_cast<LPVOID*>(&ProxyInterfaceA));
7263
}
7364
~m_IDirectInput8()
7465
{

dinput8/IDirectInputDevice8.h

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -82,20 +82,11 @@ class m_IDirectInputDevice8 final : public IDirectInputDevice8A, public IDirectI
8282
inline HRESULT GetImageInfoT(T* ProxyInterfaceT, V lpdiDevImageInfoHeader);
8383

8484
public:
85-
m_IDirectInputDevice8(IUnknown* aOriginal) : AddressLookupTableDinput8Object(aOriginal)
85+
m_IDirectInputDevice8(proxy_type* aOriginal) : AddressLookupTableDinput8Object(aOriginal), ProxyInterface(aOriginal)
8686
{
8787
LOG_LIMIT(3, "Creating interface " << __FUNCTION__ << " (" << this << ")");
8888

89-
aOriginal->QueryInterface(IID_IDirectInputDevice8A, reinterpret_cast<LPVOID*>(&ProxyInterfaceA));
90-
aOriginal->QueryInterface(IID_IDirectInputDevice8W, reinterpret_cast<LPVOID*>(&ProxyInterface));
91-
if (aOriginal == ProxyInterface || aOriginal == ProxyInterfaceA)
92-
{
93-
aOriginal->Release();
94-
}
95-
else
96-
{
97-
LOG_LIMIT(3, __FUNCTION__ << " Warning: passed interface does not match either ProxyInterface values!");
98-
}
89+
ProxyInterface->QueryInterface(IID_IDirectInputDevice8A, reinterpret_cast<LPVOID*>(&ProxyInterfaceA));
9990

10091
ProcessID = GetCurrentProcessId();
10192

dinput8/dinput8.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,15 @@ HRESULT WINAPI di8_DirectInput8Create(HINSTANCE hinst, DWORD dwVersion, REFIID r
4848

4949
LOG_LIMIT(3, "Redirecting 'DirectInput8Create' ...");
5050

51-
HRESULT hr = DirectInput8Create(hinst, dwVersion, m_IDirectInput8::proxy_iid, ppvOut, punkOuter);
51+
typename m_IDirectInput8::proxy_type* Proxy;
52+
HRESULT hr = DirectInput8Create(hinst, dwVersion, m_IDirectInput8::proxy_iid, reinterpret_cast<LPVOID*>(&Proxy), punkOuter);
5253

53-
if (SUCCEEDED(hr) && ppvOut)
54+
if (SUCCEEDED(hr))
5455
{
55-
*ppvOut = new m_IDirectInput8((IDirectInput8W*)*ppvOut);
56+
m_IDirectInput8* Interface = new m_IDirectInput8(Proxy);
57+
58+
hr = Interface->QueryInterface(riid, ppvOut);
59+
Interface->Release();
5660
}
5761

5862
return hr;

0 commit comments

Comments
 (0)