Skip to content

Commit 8c092ff

Browse files
committed
Fix missing buffer overflow message
#493
1 parent 974bb2b commit 8c092ff

File tree

2 files changed

+47
-25
lines changed

2 files changed

+47
-25
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 8146
1+
#define BUILD_NUMBER 8147

dinput8/IDirectInputDevice8.cpp

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ template <class T>
154154
HRESULT m_IDirectInputDevice8::GetMouseDeviceData(DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags, std::vector<T>& dod)
155155
{
156156
// Check arguments
157-
if (!pdwInOut)
157+
if (!pdwInOut || (rgdod && *pdwInOut == 0))
158158
{
159159
return DIERR_INVALIDPARAM;
160160
}
@@ -169,27 +169,20 @@ HRESULT m_IDirectInputDevice8::GetMouseDeviceData(DWORD cbObjectData, LPDIDEVICE
169169
// Lock for concurrency
170170
ScopedCriticalSection ThreadLock(&dics);
171171

172+
bool isBufferOverflow = false;
173+
DWORD dwItems = INFINITE;
174+
172175
// Determine number of records to store
173-
DWORD dwItems = MouseBufferSize;
174-
if (MouseBufferSize == 0)
176+
HRESULT hr = ProxyInterface->GetDeviceData(cbObjectData, nullptr, &dwItems, DIGDD_PEEK);
177+
if (hr == DI_BUFFEROVERFLOW)
175178
{
176-
DIPROPDWORD dipdw = {};
177-
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
178-
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
179-
dipdw.diph.dwObj = 0;
180-
dipdw.diph.dwHow = DIPH_DEVICE;
181-
182-
if (SUCCEEDED(ProxyInterface->GetProperty(DIPROP_BUFFERSIZE, &dipdw.diph)))
183-
{
184-
MouseBufferSize = dipdw.dwData;
185-
RequestedMouseBufferSize = dipdw.dwData;
186-
}
187-
else
188-
{
189-
LOG_LIMIT(100, __FUNCTION__ << " Warning: failed to get default mouse buffer size!");
190-
}
179+
isBufferOverflow = true;
180+
}
181+
else if (FAILED(hr))
182+
{
183+
*pdwInOut = 0;
184+
return hr;
191185
}
192-
dwItems = MouseBufferSize ? min(dwItems, MouseBufferSize) : dwItems;
193186

194187
// Ensure buffer is large enough
195188
const DWORD requiredBytes = dwItems * cbObjectData;
@@ -202,8 +195,12 @@ HRESULT m_IDirectInputDevice8::GetMouseDeviceData(DWORD cbObjectData, LPDIDEVICE
202195
LPDIDEVICEOBJECTDATA lpdod = reinterpret_cast<LPDIDEVICEOBJECTDATA>(tmp_dod.data());
203196

204197
// Get device data from buffer
205-
HRESULT hr = ProxyInterface->GetDeviceData(cbObjectData, lpdod, &dwItems, 0);
206-
if (FAILED(hr))
198+
hr = ProxyInterface->GetDeviceData(cbObjectData, lpdod, &dwItems, 0);
199+
if (hr == DI_BUFFEROVERFLOW)
200+
{
201+
isBufferOverflow = true;
202+
}
203+
else if (FAILED(hr))
207204
{
208205
*pdwInOut = 0;
209206
return hr;
@@ -302,12 +299,32 @@ HRESULT m_IDirectInputDevice8::GetMouseDeviceData(DWORD cbObjectData, LPDIDEVICE
302299
// Fill device object data
303300
else
304301
{
305-
dwOut = min(dod.size(), *pdwInOut);
306-
if (*pdwInOut > 0x10000 && RequestedMouseBufferSize)
302+
if (MouseBufferSize == 0)
307303
{
308-
dwOut = min(dwOut, RequestedMouseBufferSize);
304+
DIPROPDWORD dipdw = {};
305+
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
306+
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
307+
dipdw.diph.dwObj = 0;
308+
dipdw.diph.dwHow = DIPH_DEVICE;
309+
310+
if (SUCCEEDED(ProxyInterface->GetProperty(DIPROP_BUFFERSIZE, &dipdw.diph)))
311+
{
312+
MouseBufferSize = dipdw.dwData;
313+
RequestedMouseBufferSize = dipdw.dwData;
314+
}
315+
else
316+
{
317+
LOG_LIMIT(100, __FUNCTION__ << " Warning: failed to get default mouse buffer size!");
318+
}
309319
}
310320

321+
DWORD dwRequested = *pdwInOut;
322+
if (dwRequested == INFINITE && RequestedMouseBufferSize)
323+
{
324+
dwRequested = RequestedMouseBufferSize;
325+
}
326+
dwOut = min(dod.size(), dwRequested);
327+
311328
memcpy(rgdod, dod.data(), sizeof(T) * dwOut);
312329

313330
// Remove used entries from buffer
@@ -326,6 +343,11 @@ HRESULT m_IDirectInputDevice8::GetMouseDeviceData(DWORD cbObjectData, LPDIDEVICE
326343

327344
*pdwInOut = dwOut;
328345

346+
if (isBufferOverflow)
347+
{
348+
return DI_BUFFEROVERFLOW;
349+
}
350+
329351
return DI_OK;
330352
}
331353

0 commit comments

Comments
 (0)