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@hotmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
(cherry picked from commit 8d05256172)
Signed-off-by: Michael Stefaniuc <mstefani@winehq.org>
oldstable
Alistair Leslie-Hughes 2020-01-12 22:33:24 +00:00 committed by Michael Stefaniuc
parent 4818f65c04
commit b37845dbcc
3 changed files with 34 additions and 6 deletions

View File

@ -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;

View File

@ -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 */

View File

@ -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 = 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