mirror of
git://source.winehq.org/git/wine.git
synced 2024-07-21 09:14:10 +00:00
dinput: Handle username in EnumDevicesBySemantics.
EnumDevicesBySemantics enums only devices with given username when DIEDBSFL_THISUSER is set and only unowned devices when DIEDBSFL_AVAILABLEDEVICES is set. Signed-off-by: Jetro Jormalainen <jje-wine@jv.jetro.fi> Signed-off-by: Andrew Eikum <aeikum@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
967399eba0
commit
41b126b5fc
|
@ -923,6 +923,47 @@ static HRESULT WINAPI IDirectInput8WImpl_FindDevice(LPDIRECTINPUT8W iface, REFGU
|
||||||
return IDirectInput2WImpl_FindDevice( &This->IDirectInput7W_iface, rguid, pszName, pguidInstance );
|
return IDirectInput2WImpl_FindDevice( &This->IDirectInput7W_iface, rguid, pszName, pguidInstance );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL should_enumerate_device(const WCHAR *username, DWORD dwFlags,
|
||||||
|
struct list *device_players, REFGUID guid)
|
||||||
|
{
|
||||||
|
BOOL should_enumerate = TRUE;
|
||||||
|
struct DevicePlayer *device_player;
|
||||||
|
|
||||||
|
/* Check if user owns this device */
|
||||||
|
if (dwFlags & DIEDBSFL_THISUSER && username && *username)
|
||||||
|
{
|
||||||
|
should_enumerate = FALSE;
|
||||||
|
LIST_FOR_EACH_ENTRY(device_player, device_players, struct DevicePlayer, entry)
|
||||||
|
{
|
||||||
|
if (IsEqualGUID(&device_player->instance_guid, guid))
|
||||||
|
{
|
||||||
|
if (*device_player->username && !lstrcmpW(username, device_player->username))
|
||||||
|
return TRUE; /* Device username matches */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if this device is not owned by anyone */
|
||||||
|
if (dwFlags & DIEDBSFL_AVAILABLEDEVICES) {
|
||||||
|
BOOL found = FALSE;
|
||||||
|
should_enumerate = FALSE;
|
||||||
|
LIST_FOR_EACH_ENTRY(device_player, device_players, struct DevicePlayer, entry)
|
||||||
|
{
|
||||||
|
if (IsEqualGUID(&device_player->instance_guid, guid))
|
||||||
|
{
|
||||||
|
if (*device_player->username)
|
||||||
|
found = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
return TRUE; /* Device does not have a username */
|
||||||
|
}
|
||||||
|
|
||||||
|
return should_enumerate;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics(
|
static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics(
|
||||||
LPDIRECTINPUT8A iface, LPCSTR ptszUserName, LPDIACTIONFORMATA lpdiActionFormat,
|
LPDIRECTINPUT8A iface, LPCSTR ptszUserName, LPDIACTIONFORMATA lpdiActionFormat,
|
||||||
LPDIENUMDEVICESBYSEMANTICSCBA lpCallback,
|
LPDIENUMDEVICESBYSEMANTICSCBA lpCallback,
|
||||||
|
@ -939,6 +980,7 @@ static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics(
|
||||||
int device_count = 0;
|
int device_count = 0;
|
||||||
int remain;
|
int remain;
|
||||||
DIDEVICEINSTANCEA *didevis = 0;
|
DIDEVICEINSTANCEA *didevis = 0;
|
||||||
|
WCHAR *username_w = 0;
|
||||||
|
|
||||||
FIXME("(this=%p,%s,%p,%p,%p,%04x): semi-stub\n", This, debugstr_a(ptszUserName), lpdiActionFormat,
|
FIXME("(this=%p,%s,%p,%p,%p,%04x): semi-stub\n", This, debugstr_a(ptszUserName), lpdiActionFormat,
|
||||||
lpCallback, pvRef, dwFlags);
|
lpCallback, pvRef, dwFlags);
|
||||||
|
@ -955,6 +997,14 @@ static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics(
|
||||||
|
|
||||||
didevi.dwSize = sizeof(didevi);
|
didevi.dwSize = sizeof(didevi);
|
||||||
|
|
||||||
|
if (ptszUserName)
|
||||||
|
{
|
||||||
|
int len = MultiByteToWideChar(CP_ACP, 0, ptszUserName, -1, 0, 0);
|
||||||
|
|
||||||
|
username_w = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*len);
|
||||||
|
MultiByteToWideChar(CP_ACP, 0, ptszUserName, -1, username_w, len);
|
||||||
|
}
|
||||||
|
|
||||||
/* Enumerate all the joysticks */
|
/* Enumerate all the joysticks */
|
||||||
for (i = 0; i < NB_DINPUT_DEVICES; i++)
|
for (i = 0; i < NB_DINPUT_DEVICES; i++)
|
||||||
{
|
{
|
||||||
|
@ -968,7 +1018,8 @@ static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics(
|
||||||
|
|
||||||
/* Default behavior is to enumerate attached game controllers */
|
/* Default behavior is to enumerate attached game controllers */
|
||||||
enumSuccess = dinput_devices[i]->enum_deviceA(DI8DEVCLASS_GAMECTRL, DIEDFL_ATTACHEDONLY | dwFlags, &didevi, This->dwVersion, j);
|
enumSuccess = dinput_devices[i]->enum_deviceA(DI8DEVCLASS_GAMECTRL, DIEDFL_ATTACHEDONLY | dwFlags, &didevi, This->dwVersion, j);
|
||||||
if (enumSuccess == S_OK)
|
if (enumSuccess == S_OK &&
|
||||||
|
should_enumerate_device(username_w, dwFlags, &This->device_players, &didevi.guidInstance))
|
||||||
{
|
{
|
||||||
if (device_count++)
|
if (device_count++)
|
||||||
didevis = HeapReAlloc(GetProcessHeap(), 0, didevis, sizeof(DIDEVICEINSTANCEA)*device_count);
|
didevis = HeapReAlloc(GetProcessHeap(), 0, didevis, sizeof(DIDEVICEINSTANCEA)*device_count);
|
||||||
|
@ -980,8 +1031,15 @@ static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics(
|
||||||
}
|
}
|
||||||
|
|
||||||
remain = device_count;
|
remain = device_count;
|
||||||
|
/* Add keyboard and mouse to remaining device count */
|
||||||
if (!(dwFlags & DIEDBSFL_FORCEFEEDBACK))
|
if (!(dwFlags & DIEDBSFL_FORCEFEEDBACK))
|
||||||
remain += sizeof(guids)/sizeof(guids[0]);
|
{
|
||||||
|
for (i = 0; i < sizeof(guids) / sizeof(guids[0]); i++)
|
||||||
|
{
|
||||||
|
if (should_enumerate_device(username_w, dwFlags, &This->device_players, guids[i]))
|
||||||
|
remain++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < device_count; i++)
|
for (i = 0; i < device_count; i++)
|
||||||
{
|
{
|
||||||
|
@ -991,26 +1049,38 @@ static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics(
|
||||||
if (lpCallback(&didevis[i], lpdid, callbackFlags, --remain, pvRef) == DIENUM_STOP)
|
if (lpCallback(&didevis[i], lpdid, callbackFlags, --remain, pvRef) == DIENUM_STOP)
|
||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(), 0, didevis);
|
HeapFree(GetProcessHeap(), 0, didevis);
|
||||||
|
HeapFree(GetProcessHeap(), 0, username_w);
|
||||||
return DI_OK;
|
return DI_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, didevis);
|
HeapFree(GetProcessHeap(), 0, didevis);
|
||||||
|
|
||||||
if (dwFlags & DIEDBSFL_FORCEFEEDBACK) return DI_OK;
|
if (dwFlags & DIEDBSFL_FORCEFEEDBACK)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, username_w);
|
||||||
|
return DI_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/* Enumerate keyboard and mouse */
|
/* Enumerate keyboard and mouse */
|
||||||
for(i=0; i < sizeof(guids)/sizeof(guids[0]); i++)
|
for(i=0; i < sizeof(guids)/sizeof(guids[0]); i++)
|
||||||
{
|
{
|
||||||
callbackFlags = diactionformat_priorityA(lpdiActionFormat, actionMasks[i]);
|
if (should_enumerate_device(username_w, dwFlags, &This->device_players, guids[i]))
|
||||||
|
{
|
||||||
|
callbackFlags = diactionformat_priorityA(lpdiActionFormat, actionMasks[i]);
|
||||||
|
|
||||||
IDirectInput_CreateDevice(iface, guids[i], &lpdid, NULL);
|
IDirectInput_CreateDevice(iface, guids[i], &lpdid, NULL);
|
||||||
IDirectInputDevice_GetDeviceInfo(lpdid, &didevi);
|
IDirectInputDevice_GetDeviceInfo(lpdid, &didevi);
|
||||||
|
|
||||||
if (lpCallback(&didevi, lpdid, callbackFlags, sizeof(guids)/sizeof(guids[0]) - (i+1), pvRef) == DIENUM_STOP)
|
if (lpCallback(&didevi, lpdid, callbackFlags, --remain, pvRef) == DIENUM_STOP)
|
||||||
return DI_OK;
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, username_w);
|
||||||
|
return DI_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, username_w);
|
||||||
return DI_OK;
|
return DI_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1049,7 +1119,8 @@ static HRESULT WINAPI IDirectInput8WImpl_EnumDevicesBySemantics(
|
||||||
|
|
||||||
/* Default behavior is to enumerate attached game controllers */
|
/* Default behavior is to enumerate attached game controllers */
|
||||||
enumSuccess = dinput_devices[i]->enum_deviceW(DI8DEVCLASS_GAMECTRL, DIEDFL_ATTACHEDONLY | dwFlags, &didevi, This->dwVersion, j);
|
enumSuccess = dinput_devices[i]->enum_deviceW(DI8DEVCLASS_GAMECTRL, DIEDFL_ATTACHEDONLY | dwFlags, &didevi, This->dwVersion, j);
|
||||||
if (enumSuccess == S_OK)
|
if (enumSuccess == S_OK &&
|
||||||
|
should_enumerate_device(ptszUserName, dwFlags, &This->device_players, &didevi.guidInstance))
|
||||||
{
|
{
|
||||||
if (device_count++)
|
if (device_count++)
|
||||||
didevis = HeapReAlloc(GetProcessHeap(), 0, didevis, sizeof(DIDEVICEINSTANCEW)*device_count);
|
didevis = HeapReAlloc(GetProcessHeap(), 0, didevis, sizeof(DIDEVICEINSTANCEW)*device_count);
|
||||||
|
@ -1061,8 +1132,15 @@ static HRESULT WINAPI IDirectInput8WImpl_EnumDevicesBySemantics(
|
||||||
}
|
}
|
||||||
|
|
||||||
remain = device_count;
|
remain = device_count;
|
||||||
|
/* Add keyboard and mouse to remaining device count */
|
||||||
if (!(dwFlags & DIEDBSFL_FORCEFEEDBACK))
|
if (!(dwFlags & DIEDBSFL_FORCEFEEDBACK))
|
||||||
remain += sizeof(guids)/sizeof(guids[0]);
|
{
|
||||||
|
for (i = 0; i < sizeof(guids) / sizeof(guids[0]); i++)
|
||||||
|
{
|
||||||
|
if (should_enumerate_device(ptszUserName, dwFlags, &This->device_players, guids[i]))
|
||||||
|
remain++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < device_count; i++)
|
for (i = 0; i < device_count; i++)
|
||||||
{
|
{
|
||||||
|
@ -1083,13 +1161,16 @@ static HRESULT WINAPI IDirectInput8WImpl_EnumDevicesBySemantics(
|
||||||
/* Enumerate keyboard and mouse */
|
/* Enumerate keyboard and mouse */
|
||||||
for(i=0; i < sizeof(guids)/sizeof(guids[0]); i++)
|
for(i=0; i < sizeof(guids)/sizeof(guids[0]); i++)
|
||||||
{
|
{
|
||||||
callbackFlags = diactionformat_priorityW(lpdiActionFormat, actionMasks[i]);
|
if (should_enumerate_device(ptszUserName, dwFlags, &This->device_players, guids[i]))
|
||||||
|
{
|
||||||
|
callbackFlags = diactionformat_priorityW(lpdiActionFormat, actionMasks[i]);
|
||||||
|
|
||||||
IDirectInput_CreateDevice(iface, guids[i], &lpdid, NULL);
|
IDirectInput_CreateDevice(iface, guids[i], &lpdid, NULL);
|
||||||
IDirectInputDevice_GetDeviceInfo(lpdid, &didevi);
|
IDirectInputDevice_GetDeviceInfo(lpdid, &didevi);
|
||||||
|
|
||||||
if (lpCallback(&didevi, lpdid, callbackFlags, sizeof(guids)/sizeof(guids[0]) - (i+1), pvRef) == DIENUM_STOP)
|
if (lpCallback(&didevi, lpdid, callbackFlags, --remain, pvRef) == DIENUM_STOP)
|
||||||
return DI_OK;
|
return DI_OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return DI_OK;
|
return DI_OK;
|
||||||
|
|
|
@ -562,6 +562,13 @@ static void test_EnumDevicesBySemantics(void)
|
||||||
/* Keep the device total */
|
/* Keep the device total */
|
||||||
device_total = data.device_count;
|
device_total = data.device_count;
|
||||||
|
|
||||||
|
/* There should be no devices for any user. No device should be enumerated with DIEDBSFL_THISUSER.
|
||||||
|
MSDN defines that all unowned devices are also enumerated but this doesn't seem to be happening. */
|
||||||
|
data.device_count = 0;
|
||||||
|
hr = IDirectInput8_EnumDevicesBySemantics(pDI, "Sh4d0w M4g3", &diaf, enum_semantics_callback, &data, DIEDBSFL_THISUSER);
|
||||||
|
ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed hr=%08x\n", hr);
|
||||||
|
ok (data.device_count == 0, "No devices should be assigned for this user assigned=%d\n", data.device_count);
|
||||||
|
|
||||||
/* This enumeration builds and sets the action map for all devices with a NULL username */
|
/* This enumeration builds and sets the action map for all devices with a NULL username */
|
||||||
hr = IDirectInput8_EnumDevicesBySemantics(pDI, NULL, &diaf, set_action_map_callback, &data, DIEDBSFL_ATTACHEDONLY);
|
hr = IDirectInput8_EnumDevicesBySemantics(pDI, NULL, &diaf, set_action_map_callback, &data, DIEDBSFL_ATTACHEDONLY);
|
||||||
ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed: hr=%08x\n", hr);
|
ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed: hr=%08x\n", hr);
|
||||||
|
@ -570,7 +577,7 @@ static void test_EnumDevicesBySemantics(void)
|
||||||
data.device_count = 0;
|
data.device_count = 0;
|
||||||
hr = IDirectInput8_EnumDevicesBySemantics(pDI, NULL, &diaf, enum_semantics_callback, &data, DIEDBSFL_AVAILABLEDEVICES);
|
hr = IDirectInput8_EnumDevicesBySemantics(pDI, NULL, &diaf, enum_semantics_callback, &data, DIEDBSFL_AVAILABLEDEVICES);
|
||||||
ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed hr=%08x\n", hr);
|
ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed hr=%08x\n", hr);
|
||||||
todo_wine ok (data.device_count == 0, "No device should be available after action mapping available=%d\n", data.device_count);
|
ok (data.device_count == 0, "No device should be available after action mapping available=%d\n", data.device_count);
|
||||||
|
|
||||||
/* Now we'll give all the devices to a specific user */
|
/* Now we'll give all the devices to a specific user */
|
||||||
data.username = "Sh4d0w M4g3";
|
data.username = "Sh4d0w M4g3";
|
||||||
|
@ -593,7 +600,7 @@ static void test_EnumDevicesBySemantics(void)
|
||||||
data.device_count = 0;
|
data.device_count = 0;
|
||||||
hr = IDirectInput8_EnumDevicesBySemantics(pDI, "Ninja Brian", &diaf, enum_semantics_callback, &data, DIEDBSFL_THISUSER);
|
hr = IDirectInput8_EnumDevicesBySemantics(pDI, "Ninja Brian", &diaf, enum_semantics_callback, &data, DIEDBSFL_THISUSER);
|
||||||
ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed hr=%08x\n", hr);
|
ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed hr=%08x\n", hr);
|
||||||
todo_wine ok (data.device_count == 0, "This user should own no devices owned=%d\n", data.device_count);
|
ok (data.device_count == 0, "This user should own no devices owned=%d\n", data.device_count);
|
||||||
|
|
||||||
/* Sh4d0w M4g3 has ownership of all devices */
|
/* Sh4d0w M4g3 has ownership of all devices */
|
||||||
data.device_count = 0;
|
data.device_count = 0;
|
||||||
|
|
Loading…
Reference in a new issue