Alistair Leslie-Hughes : dinput: Cap the buffer size to 20.
Module: wine Branch: oldstable Commit: b37845dbcc20bb3534db63ba08b9b73d044578e2 URL: https://source.winehq.org/git/wine.git/?a=commit;h=b37845dbcc20bb3534db63ba0... Author: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com> Date: Sun Jan 12 22:33:24 2020 +0000 dinput: Cap the buffer size to 20. When a program calls SetProperty with DIPROP_BUFFERSIZE, dinput records this value for GetProperty but only uses it when the device can support that number of buffers otherwise a max value. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45732 Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> (cherry picked from commit 8d052561724f9c8d9e7770964bfaebdd01e98e60) Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org> --- dlls/dinput/device.c | 10 ++++++---- dlls/dinput/device_private.h | 3 ++- dlls/dinput/tests/device.c | 25 +++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index 6c446163d1..b9e67c01d8 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -1305,7 +1305,7 @@ HRESULT WINAPI IDirectInputDevice2WImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface, if (pdiph->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM; - pd->dwData = This->queue_len; + pd->dwData = This->buffersize; TRACE("buffersize = %d\n", pd->dwData); break; } @@ -1394,12 +1394,14 @@ HRESULT WINAPI IDirectInputDevice2WImpl_SetProperty( TRACE("buffersize = %d\n", pd->dwData); EnterCriticalSection(&This->crit); + + This->buffersize = pd->dwData; + This->queue_len = min(This->buffersize, 20); HeapFree(GetProcessHeap(), 0, This->data_queue); - This->data_queue = !pd->dwData ? NULL : HeapAlloc(GetProcessHeap(), 0, - pd->dwData * sizeof(DIDEVICEOBJECTDATA)); + This->data_queue = !This->queue_len ? NULL : HeapAlloc(GetProcessHeap(), 0, + This->queue_len * sizeof(DIDEVICEOBJECTDATA)); This->queue_head = This->queue_tail = This->overflow = 0; - This->queue_len = pd->dwData; LeaveCriticalSection(&This->crit); break; diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h index d9e2997eaa..64bdfeb8c7 100644 --- a/dlls/dinput/device_private.h +++ b/dlls/dinput/device_private.h @@ -71,10 +71,11 @@ struct IDirectInputDeviceImpl DI_EVENT_PROC event_proc; /* function to receive mouse & keyboard events */ LPDIDEVICEOBJECTDATA data_queue; /* buffer for 'GetDeviceData'. */ - int queue_len; /* size of the queue - set in 'SetProperty' */ + int queue_len; /* valid size of the queue */ int queue_head; /* position to write new event into queue */ int queue_tail; /* next event to read from queue */ BOOL overflow; /* return DI_BUFFEROVERFLOW in 'GetDeviceData' */ + DWORD buffersize; /* size of the queue - set in 'SetProperty' */ DataFormat data_format; /* user data format and wine to user format converter */ diff --git a/dlls/dinput/tests/device.c b/dlls/dinput/tests/device.c index fa9b6f1436..b036be102b 100644 --- a/dlls/dinput/tests/device.c +++ b/dlls/dinput/tests/device.c @@ -25,6 +25,8 @@ #include "windef.h" #include "dinput.h" +#include <limits.h> + static const DIOBJECTDATAFORMAT obj_data_format[] = { { &GUID_YAxis, 16, DIDFT_OPTIONAL|DIDFT_AXIS |DIDFT_MAKEINSTANCE(1), 0}, { &GUID_Button,15, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(3), 0}, @@ -106,8 +108,22 @@ static void test_object_info(IDirectInputDeviceA *device, HWND hwnd) dp.diph.dwHeaderSize = sizeof(DIPROPHEADER); dp.diph.dwHow = DIPH_DEVICE; dp.diph.dwObj = 0; + dp.dwData = UINT_MAX; + + hr = IDirectInputDevice_GetProperty(device, DIPROP_BUFFERSIZE, &dp.diph); + ok(hr == DI_OK, "Failed: %08x\n", hr); + ok(dp.dwData == 0, "got %d\n", dp.dwData); + + dp.dwData = UINT_MAX; + hr = IDirectInputDevice_SetProperty(device, DIPROP_BUFFERSIZE, (LPCDIPROPHEADER)&dp.diph); + ok(hr == DI_OK, "SetProperty() failed: %08x\n", hr); + dp.dwData = 0; + hr = IDirectInputDevice_GetProperty(device, DIPROP_BUFFERSIZE, &dp.diph); + ok(hr == DI_OK, "Failed: %08x\n", hr); + ok(dp.dwData == UINT_MAX, "got %d\n", dp.dwData); + dp.dwData = 0; hr = IDirectInputDevice_SetProperty(device, DIPROP_BUFFERSIZE, (LPCDIPROPHEADER)&dp.diph); ok(hr == DI_OK, "SetProperty() failed: %08x\n", hr); cnt = 5; @@ -166,6 +182,15 @@ static void test_object_info(IDirectInputDeviceA *device, HWND hwnd) hr = IDirectInputDevice_Unacquire(device); ok(hr == DI_OK, "Unacquire() failed: %08x\n", hr); } + + /* Reset buffer size */ + dp.diph.dwSize = sizeof(DIPROPDWORD); + dp.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dp.diph.dwHow = DIPH_DEVICE; + dp.diph.dwObj = 0; + dp.dwData = 0; + hr = IDirectInputDevice_SetProperty(device, DIPROP_BUFFERSIZE, (LPCDIPROPHEADER)&dp.diph); + ok(hr == DI_OK, "SetProperty() failed: %08x\n", hr); } struct enum_data
participants (1)
-
Alexandre Julliard