Skip to content

Instantly share code, notes, and snippets.

@lfzawacki
Created August 5, 2011 12:56
Show Gist options
  • Save lfzawacki/1127485 to your computer and use it in GitHub Desktop.
Save lfzawacki/1127485 to your computer and use it in GitHub Desktop.
From 7d5e47af3bd3fe2d1cf42e6f01d1ce75ed7d3b7f Mon Sep 17 00:00:00 2001
From: Lucas Fialho Zawacki <[email protected]>
Date: Wed, 3 Aug 2011 22:23:20 -0300
Subject: [PATCH 1/4] dinput: Added a username field to devices and a list of device ownerships to the dinput
---
dlls/dinput/device_private.h | 4 ++++
dlls/dinput/dinput_main.c | 16 ++++++++++++++++
dlls/dinput/dinput_private.h | 7 +++++++
dlls/dinput/joystick_linux.c | 2 ++
dlls/dinput/joystick_linuxinput.c | 2 ++
dlls/dinput/joystick_osx.c | 2 ++
dlls/dinput/keyboard.c | 2 ++
dlls/dinput/mouse.c | 2 ++
8 files changed, 37 insertions(+), 0 deletions(-)
diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h
index e8fe00a..d5be046 100644
--- a/dlls/dinput/device_private.h
+++ b/dlls/dinput/device_private.h
@@ -81,6 +81,8 @@ struct IDirectInputDeviceImpl
/* Action mapping */
int num_actions; /* number of actions mapped */
ActionMap *action_map; /* array of mappings */
+
+ WCHAR *username; /* username of the device owner */
};
extern BOOL get_app_key(HKEY*, HKEY*) DECLSPEC_HIDDEN;
@@ -127,6 +129,8 @@ extern const char *_dump_dinput_GUID(const GUID *guid) DECLSPEC_HIDDEN;
extern DWORD semantic_to_obj_id(IDirectInputDeviceImpl* This, DWORD dwSemantic) DECLSPEC_HIDDEN;
extern LPDIOBJECTDATAFORMAT dataformat_to_odf_by_type(LPCDIDATAFORMAT df, int n, DWORD type) DECLSPEC_HIDDEN;
+extern void _assign_device_ownership(IDirectInputImpl*, IDirectInputDeviceImpl *) DECLSPEC_HIDDEN;
+
/* And the stubs */
extern HRESULT WINAPI IDirectInputDevice2AImpl_Acquire(LPDIRECTINPUTDEVICE8A iface) DECLSPEC_HIDDEN;
extern HRESULT WINAPI IDirectInputDevice2WImpl_Acquire(LPDIRECTINPUTDEVICE8W iface) DECLSPEC_HIDDEN;
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c
index 6ddcd71..a15b6f3 100644
--- a/dlls/dinput/dinput_main.c
+++ b/dlls/dinput/dinput_main.c
@@ -349,6 +349,19 @@ static DWORD _diactionformat_priorityW(LPDIACTIONFORMATW lpdiaf, DWORD genre)
return priorityFlags;
}
+/* _assign_device_ownership
+ *
+ * Finds out if the device has a username assigned and sets it.
+ */
+void _assign_device_ownership(IDirectInputImpl *dinput, IDirectInputDeviceImpl *This)
+{
+ struct guid_user* gu;
+
+ if (!list_empty(&dinput->guid_user_list))
+ LIST_FOR_EACH_ENTRY(gu, &dinput->guid_user_list, struct guid_user, entry)
+ if (IsEqualGUID(&gu->guid, &This->guid)) This->username = gu->username;
+}
+
/******************************************************************************
* IDirectInputA_EnumDevices
*/
@@ -535,6 +548,9 @@ static HRESULT initialize_directinput_instance(IDirectInputImpl *This, DWORD dwV
list_add_head( &direct_input_list, &This->entry );
LeaveCriticalSection( &dinput_hook_crit );
+ /* Initialize device ownership list */
+ list_init( &This->guid_user_list );
+
This->initialized = TRUE;
if (!check_hook_thread())
diff --git a/dlls/dinput/dinput_private.h b/dlls/dinput/dinput_private.h
index 94b16a5..a9c08e6 100644
--- a/dlls/dinput/dinput_private.h
+++ b/dlls/dinput/dinput_private.h
@@ -44,6 +44,13 @@ struct IDirectInputImpl
DWORD evsequence; /* unique sequence number for events */
DWORD dwVersion; /* direct input version number */
struct list devices_list; /* list of all created dinput devices */
+ struct list guid_user_list; /* list of guid/username for the devices */
+};
+
+struct guid_user {
+ struct list entry;
+ GUID guid;
+ WCHAR username[MAX_PATH];
};
/* Function called by all devices that Wine supports */
diff --git a/dlls/dinput/joystick_linux.c b/dlls/dinput/joystick_linux.c
index 3ad592d..18d7c4e 100644
--- a/dlls/dinput/joystick_linux.c
+++ b/dlls/dinput/joystick_linux.c
@@ -348,6 +348,8 @@ static HRESULT alloc_device(REFGUID rguid, IDirectInputImpl *dinput,
if (hr != DI_OK)
goto FAILED1;
+ _assign_device_ownership(dinput, &newDevice->generic.base);
+
/* Create copy of default data format */
if (!(df = HeapAlloc(GetProcessHeap(), 0, c_dfDIJoystick2.dwSize))) goto FAILED;
memcpy(df, &c_dfDIJoystick2, c_dfDIJoystick2.dwSize);
diff --git a/dlls/dinput/joystick_linuxinput.c b/dlls/dinput/joystick_linuxinput.c
index a88391c..dbeaf53 100644
--- a/dlls/dinput/joystick_linuxinput.c
+++ b/dlls/dinput/joystick_linuxinput.c
@@ -473,6 +473,8 @@ static JoystickImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput, unsig
/* do any user specified configuration */
if (setup_dinput_options(&newDevice->generic, default_axis_map) != DI_OK) goto failed;
+ _assign_device_ownership(dinput, &newDevice->generic.base);
+
/* Create copy of default data format */
if (!(df = HeapAlloc(GetProcessHeap(), 0, c_dfDIJoystick2.dwSize))) goto failed;
memcpy(df, &c_dfDIJoystick2, c_dfDIJoystick2.dwSize);
diff --git a/dlls/dinput/joystick_osx.c b/dlls/dinput/joystick_osx.c
index cbd005c..89f10b2 100644
--- a/dlls/dinput/joystick_osx.c
+++ b/dlls/dinput/joystick_osx.c
@@ -777,6 +777,8 @@ static HRESULT alloc_device(REFGUID rguid, IDirectInputImpl *dinput,
InitializeCriticalSection(&newDevice->generic.base.crit);
newDevice->generic.base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": JoystickImpl*->generic.base.crit");
+ _assign_device_ownership(dinput, &newDevice->generic.base);
+
/* Create copy of default data format */
if (!(df = HeapAlloc(GetProcessHeap(), 0, c_dfDIJoystick2.dwSize))) goto FAILED;
memcpy(df, &c_dfDIJoystick2, c_dfDIJoystick2.dwSize);
diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c
index 3c93bcd..f9920a9 100644
--- a/dlls/dinput/keyboard.c
+++ b/dlls/dinput/keyboard.c
@@ -236,6 +236,8 @@ static SysKeyboardImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput)
InitializeCriticalSection(&newDevice->base.crit);
newDevice->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": SysKeyboardImpl*->base.crit");
+ _assign_device_ownership(dinput, &newDevice->base);
+
/* Create copy of default data format */
if (!(df = HeapAlloc(GetProcessHeap(), 0, c_dfDIKeyboard.dwSize))) goto failed;
memcpy(df, &c_dfDIKeyboard, c_dfDIKeyboard.dwSize);
diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c
index 8da35f4..a7543d0 100644
--- a/dlls/dinput/mouse.c
+++ b/dlls/dinput/mouse.c
@@ -227,6 +227,8 @@ static SysMouseImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput)
if (appkey) RegCloseKey(appkey);
if (hkey) RegCloseKey(hkey);
+ _assign_device_ownership(dinput, &newDevice->base);
+
/* Create copy of default data format */
if (!(df = HeapAlloc(GetProcessHeap(), 0, c_dfDIMouse2.dwSize))) goto failed;
memcpy(df, &c_dfDIMouse2, c_dfDIMouse2.dwSize);
--
1.7.0.4
From f9e63000e691618f8ded4eb75c0cc2f8fb9891e4 Mon Sep 17 00:00:00 2001
From: Lucas Fialho Zawacki <[email protected]>
Date: Thu, 4 Aug 2011 13:33:59 -0300
Subject: [PATCH 2/4] dinput8/tests: Test username property
---
dlls/dinput8/tests/device.c | 57 +++++++++++++++++++++++++++++++++++++++++-
1 files changed, 55 insertions(+), 2 deletions(-)
diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c
index 30c702f..41ff135 100644
--- a/dlls/dinput8/tests/device.c
+++ b/dlls/dinput8/tests/device.c
@@ -37,6 +37,8 @@ struct enum_data {
/* Dummy GUID */
static const GUID ACTION_MAPPING_GUID = { 0x1, 0x2, 0x3, { 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb } };
+HINSTANCE hInstance;
+
enum {
DITEST_AXIS,
DITEST_BUTTON,
@@ -231,7 +233,6 @@ static BOOL CALLBACK counting_callback(
static void test_action_mapping(void)
{
HRESULT hr;
- HINSTANCE hinst = GetModuleHandle(NULL);
LPDIRECTINPUT8 pDI = NULL;
DIACTIONFORMAT af;
struct enum_data data = {pDI, &af, NULL, NULL, 0};
@@ -248,7 +249,7 @@ static void test_action_mapping(void)
ok(SUCCEEDED(hr), "DirectInput8 Create failed: hr=%08x\n", hr);
if (FAILED(hr)) return;
- hr = IDirectInput8_Initialize(pDI,hinst, DIRECTINPUT_VERSION);
+ hr = IDirectInput8_Initialize(pDI, hInstance, DIRECTINPUT_VERSION);
if (hr == DIERR_OLDDIRECTINPUTVERSION || hr == DIERR_BETADIRECTINPUTVERSION)
{
win_skip("ActionMapping requires dinput8\n");
@@ -340,11 +341,63 @@ static void test_action_mapping(void)
todo_wine ok(FAILED(hr), "EnumDevicesBySemantics succeeded with invalid GUID hr=%08x\n", hr);
}
+void test_SetProperty(void)
+{
+ IDirectInput8A *pDI;
+ IDirectInputDevice8A *pDID;
+ DIPROPSTRING dps;
+ WCHAR username[] = { 'L', 'u', 'c', 'a', 's', '\0' };
+
+ HRESULT hr;
+
+ hr = CoCreateInstance(&CLSID_DirectInput8, 0, 1, &IID_IDirectInput8A, (LPVOID*)&pDI);
+ if (hr == DIERR_OLDDIRECTINPUTVERSION ||
+ hr == DIERR_BETADIRECTINPUTVERSION ||
+ hr == REGDB_E_CLASSNOTREG)
+ {
+ win_skip("Can't test dinput8 properties\n");
+ return;
+ }
+ ok (SUCCEEDED(hr), "IDirectInput8_Create failed: hr=%08x\n", hr);
+ if (FAILED(hr)) return;
+
+ hr = IDirectInput8_Initialize(pDI, hInstance, DIRECTINPUT_VERSION);
+ if (hr == DIERR_OLDDIRECTINPUTVERSION || hr == DIERR_BETADIRECTINPUTVERSION)
+ {
+ win_skip("Can't test dinput8 properties\n");
+ return;
+ }
+ ok (SUCCEEDED(hr), "IDirectInput8_Initialize failed: hr=%08x\n", hr);
+ if (FAILED(hr)) return;
+
+ hr = IDirectInput8_CreateDevice(pDI, &GUID_SysKeyboard, &pDID, NULL);
+ ok (SUCCEEDED(hr), "IDirectInput8_CreateDevice failed: hr=%08x\n", hr);
+
+ /* Username property */
+ dps.diph.dwSize = sizeof(DIPROPSTRING);
+ dps.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+ dps.diph.dwObj = 0;
+ dps.diph.dwHow = DIPH_DEVICE;
+ lstrcpyW(dps.wsz, username);
+
+ hr = IDirectInputDevice_SetProperty(pDID, DIPROP_USERNAME, &dps.diph);
+ ok (SUCCEEDED(hr), "IDirectInputDevice_SetProperty failed: hr=%08x\n", hr);
+
+ memset(dps.wsz, 0, MAX_PATH);
+ hr = IDirectInputDevice_GetProperty(pDID, DIPROP_USERNAME, &dps.diph);
+ ok (SUCCEEDED(hr), "IDirectInputDevice_GetProperty failed: hr=%08x\n", hr);
+
+ ok (lstrcmpW(username, dps.wsz) == 0, "SetProperty: wrong username expected: %s got: %s\n", wine_dbgstr_w(username), wine_dbgstr_w(dps.wsz));
+}
+
START_TEST(device)
{
+ hInstance = GetModuleHandle(NULL);
+
CoInitialize(NULL);
test_action_mapping();
+ test_SetProperty();
CoUninitialize();
}
--
1.7.0.4
From 81114be04d7a7579d29da58ece9a8a80cc013859 Mon Sep 17 00:00:00 2001
From: Lucas Fialho Zawacki <[email protected]>
Date: Thu, 4 Aug 2011 13:34:26 -0300
Subject: [PATCH 3/4] dinput: SetProperty for DIPROP_USERNAME
---
dlls/dinput/device.c | 27 +++++++++++++++++++++++++++
1 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c
index 8719066..74721ec 100644
--- a/dlls/dinput/device.c
+++ b/dlls/dinput/device.c
@@ -1049,6 +1049,33 @@ HRESULT WINAPI IDirectInputDevice2WImpl_SetProperty(
LeaveCriticalSection(&This->crit);
break;
}
+ case (DWORD_PTR) DIPROP_USERNAME:
+ {
+ LPDIPROPSTRING ps = (LPDIPROPSTRING)pdiph;
+
+ if (pdiph->dwSize != sizeof(DIPROPSTRING)) return DIERR_INVALIDPARAM;
+
+ /* If a username has never been assigned to this device */
+ if (This->username == NULL)
+ {
+ /* Let's store the relation between this name and the device in dinput */
+ IDirectInputImpl *dinput = This->dinput;
+ struct guid_user* new_guid_user = HeapAlloc(GetProcessHeap(), 0, sizeof(struct guid_user));
+
+ EnterCriticalSection(&dinput->crit);
+ new_guid_user->guid = This->guid;
+ This->username = new_guid_user->username;
+
+ list_add_head(&dinput->guid_user_list, &new_guid_user->entry);
+ LeaveCriticalSection(&dinput->crit);
+ }
+
+ /* Copy the new username */
+ lstrcpyW(This->username, ps->wsz);
+
+ break;
+ }
+
default:
WARN("Unknown property %s\n", debugstr_guid(rguid));
return DIERR_UNSUPPORTED;
--
1.7.0.4
From bd77226c5d9a042848874b67098aeed0be838027 Mon Sep 17 00:00:00 2001
From: Lucas Fialho Zawacki <[email protected]>
Date: Fri, 5 Aug 2011 09:48:12 -0300
Subject: [PATCH 4/4] dinput: GetProperty for DIPROP_USERNAME
---
dlls/dinput/device.c | 12 ++++++++++++
1 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c
index 74721ec..2792952 100644
--- a/dlls/dinput/device.c
+++ b/dlls/dinput/device.c
@@ -979,6 +979,18 @@ HRESULT WINAPI IDirectInputDevice2WImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface,
case (DWORD_PTR) DIPROP_VIDPID:
FIXME("DIPROP_VIDPID not implemented\n");
return DIERR_UNSUPPORTED;
+ case (DWORD_PTR) DIPROP_USERNAME:
+ {
+ LPDIPROPSTRING ps = (LPDIPROPSTRING)pdiph;
+
+ if (pdiph->dwSize != sizeof(DIPROPSTRING)) return DIERR_INVALIDPARAM;
+
+ /* No username set */
+ if (This->username == NULL) return S_FALSE;
+
+ lstrcpyW(ps->wsz, This->username);
+ break;
+ }
default:
FIXME("Unknown property %s\n", debugstr_guid(rguid));
return DIERR_INVALIDPARAM;
--
1.7.0.4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment