@@ -154,7 +154,7 @@ template <class T>
154154HRESULT 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