Skip to content

Commit

Permalink
Fix crash when array is used in dod
Browse files Browse the repository at this point in the history
Fix GetDeviceData() and SendDeviceData() functions
  • Loading branch information
elishacloud committed Feb 17, 2019
1 parent e322f5f commit 8cf5470
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 10 deletions.
2 changes: 1 addition & 1 deletion BuildNo.rc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
#define BUILD_NUMBER 15
#define BUILD_NUMBER 16
66 changes: 57 additions & 9 deletions IDirectInputDeviceX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,20 +104,42 @@ HRESULT m_IDirectInputDeviceX::GetDeviceData(DWORD cbObjectData, LPDIDEVICEOBJEC
{
Logging::LogDebug() << __FUNCTION__ << "(" << this << ")";

if (!rgdod || !cbObjectData || cbObjectData > sizeof(DIDEVICEOBJECTDATA))
if (*pdwInOut == (DWORD)-1)
{
return DIERR_INVALIDPARAM;
}

DIDEVICEOBJECTDATA dod;
// Verify that only one thrad can use the varable at a time
while (dodThreadFlag) {}
dodThreadFlag = true;

HRESULT hr = ProxyInterface->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), &dod, pdwInOut, dwFlags);
// Check the size of the array
if (rgdod && *pdwInOut && *pdwInOut != dodSize)
{
if (pdod)
{
delete pdod;
}

dodSize = *pdwInOut;
pdod = new DIDEVICEOBJECTDATA[dodSize];

Logging::LogDebug() << __FUNCTION__ << " Created dod memory! " << dodSize;
}

if (SUCCEEDED(hr))
HRESULT hr = ProxyInterface->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), (rgdod) ? pdod : nullptr, pdwInOut, dwFlags);

// Copy array
if (SUCCEEDED(hr) && rgdod && cbObjectData)
{
CopyMemory(rgdod, &dod, cbObjectData);
for (UINT x = 0; x < *pdwInOut; x++)
{
CopyMemory((void*)((DWORD)rgdod + (cbObjectData * x)), &pdod[x], cbObjectData);
}
}

dodThreadFlag = false;

return hr;
}

Expand Down Expand Up @@ -257,16 +279,42 @@ HRESULT m_IDirectInputDeviceX::SendDeviceData(DWORD cbObjectData, LPCDIDEVICEOBJ
{
Logging::LogDebug() << __FUNCTION__ << "(" << this << ")";

if (!rgdod || !cbObjectData || cbObjectData > sizeof(DIDEVICEOBJECTDATA))
if (*pdwInOut == (DWORD)-1)
{
return DIERR_INVALIDPARAM;
}

DIDEVICEOBJECTDATA dod = { NULL };
// Verify that only one thrad can use the varable at a time
while (dodThreadFlag) {}
dodThreadFlag = true;

// Check the size of the array
if (rgdod && *pdwInOut && *pdwInOut != dodSize)
{
if (pdod)
{
delete pdod;
}

dodSize = *pdwInOut;
pdod = new DIDEVICEOBJECTDATA[dodSize];

Logging::LogDebug() << __FUNCTION__ << " Created dod memory! " << dodSize;
}

// Copy array
if (rgdod && cbObjectData)
{
ZeroMemory(pdod, sizeof(DIDEVICEOBJECTDATA) * dodSize);
for (UINT x = 0; x < *pdwInOut; x++)
{
CopyMemory(&pdod[x], (void*)((DWORD)rgdod + (cbObjectData * x)), cbObjectData);
}
}

CopyMemory(&dod, rgdod, cbObjectData);
HRESULT hr = ProxyInterface->SendDeviceData(sizeof(DIDEVICEOBJECTDATA), pdod, pdwInOut, fl);

HRESULT hr = ProxyInterface->SendDeviceData(sizeof(DIDEVICEOBJECTDATA), &dod, pdwInOut, fl);
dodThreadFlag = false;

return hr;
}
Expand Down
10 changes: 10 additions & 0 deletions IDirectInputDeviceX.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ class m_IDirectInputDeviceX
DWORD StringType;
ULONG RefCount = 1;

// For DeviceData
bool dodThreadFlag = false;
DIDEVICEOBJECTDATA *pdod = nullptr;
DWORD dodSize = 0;

public:
m_IDirectInputDeviceX(IDirectInputDevice8W *aOriginal, DWORD Version, REFIID riid, m_IDirectInputDevice7W *Interface) : ProxyInterface(aOriginal), DirectXVersion(Version), WrapperID(riid), WrapperInterface(Interface)
{
Expand All @@ -20,6 +25,11 @@ class m_IDirectInputDeviceX
~m_IDirectInputDeviceX()
{
Logging::LogDebug() << __FUNCTION__ << "(" << this << ")" << " deleting device!";

if (pdod)
{
delete pdod;
}
}

// Helper functions
Expand Down

0 comments on commit 8cf5470

Please sign in to comment.