[v2 1/4] dinput: Keep username same between device objects.

Jetro Jormalainen jje-wine at jv.jetro.fi
Wed Mar 1 16:11:23 CST 2017


v2: Fixed problems noted by Andrew Eikum.

Tested on Arch Linux and Rally Trophy Demo.

Signed-off-by: Jetro Jormalainen <jje-wine at jv.jetro.fi>
---
 dlls/dinput/device.c         | 38 +++++++++++++++++++++++++++++++++++---
 dlls/dinput/device_private.h |  1 -
 dlls/dinput/dinput_main.c    |  6 ++++++
 dlls/dinput/dinput_private.h |  7 +++++++
 4 files changed, 48 insertions(+), 4 deletions(-)

diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c
index a9ef2d4a3d..7b83a39d4b 100644
--- a/dlls/dinput/device.c
+++ b/dlls/dinput/device.c
@@ -1308,11 +1308,24 @@ HRESULT WINAPI IDirectInputDevice2WImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface,
         case (DWORD_PTR) DIPROP_USERNAME:
         {
             LPDIPROPSTRING ps = (LPDIPROPSTRING)pdiph;
+            struct DevicePlayer *device_player;
 
             if (pdiph->dwSize != sizeof(DIPROPSTRING)) return DIERR_INVALIDPARAM;
 
-            lstrcpynW(ps->wsz, This->username, sizeof(ps->wsz)/sizeof(WCHAR));
-            break;
+            LIST_FOR_EACH_ENTRY(device_player, &This->dinput->device_players,
+                struct DevicePlayer, entry)
+            {
+                if (IsEqualGUID(&device_player->instance_guid, &This->guid))
+                {
+                    if (*device_player->username)
+                    {
+                        lstrcpynW(ps->wsz, device_player->username, sizeof(ps->wsz)/sizeof(WCHAR));
+                        return DI_OK;
+                    }
+                    else break;
+                }
+            }
+            return S_FALSE;
         }
         case (DWORD_PTR) DIPROP_VIDPID:
             FIXME("DIPROP_VIDPID not implemented\n");
@@ -1390,10 +1403,29 @@ HRESULT WINAPI IDirectInputDevice2WImpl_SetProperty(
         case (DWORD_PTR) DIPROP_USERNAME:
         {
             LPCDIPROPSTRING ps = (LPCDIPROPSTRING)pdiph;
+            struct DevicePlayer *device_player;
+            BOOL found = FALSE;
 
             if (pdiph->dwSize != sizeof(DIPROPSTRING)) return DIERR_INVALIDPARAM;
 
-            lstrcpynW(This->username, ps->wsz, sizeof(This->username)/sizeof(WCHAR));
+            LIST_FOR_EACH_ENTRY(device_player, &This->dinput->device_players,
+                struct DevicePlayer, entry)
+            {
+                if (IsEqualGUID(&device_player->instance_guid, &This->guid))
+                {
+                    found = TRUE;
+                    break;
+                }
+            }
+            if (!found && (device_player =
+                    HeapAlloc(GetProcessHeap(), 0, sizeof(struct DevicePlayer))))
+            {
+                list_add_tail(&This->dinput->device_players, &device_player->entry);
+                device_player->instance_guid = This->guid;
+            }
+            if (device_player)
+                lstrcpynW(device_player->username, ps->wsz,
+                    sizeof(device_player->username)/sizeof(WCHAR));
             break;
         }
         default:
diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h
index c4fbe858fe..52bbec4490 100644
--- a/dlls/dinput/device_private.h
+++ b/dlls/dinput/device_private.h
@@ -81,7 +81,6 @@ struct IDirectInputDeviceImpl
     /* Action mapping */
     int                         num_actions; /* number of actions mapped */
     ActionMap                  *action_map;  /* array of mappings */
-    WCHAR                       username[MAX_PATH];
 };
 
 extern BOOL get_app_key(HKEY*, HKEY*) DECLSPEC_HIDDEN;
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c
index ab6a2e8787..2bf9f38ba4 100644
--- a/dlls/dinput/dinput_main.c
+++ b/dlls/dinput/dinput_main.c
@@ -577,6 +577,7 @@ static HRESULT initialize_directinput_instance(IDirectInputImpl *This, DWORD dwV
         This->crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IDirectInputImpl*->crit");
 
         list_init( &This->devices_list );
+        list_init( &This->device_players );
 
         /* Add self to the list of the IDirectInputs */
         EnterCriticalSection( &dinput_hook_crit );
@@ -599,11 +600,16 @@ static void uninitialize_directinput_instance(IDirectInputImpl *This)
 {
     if (This->initialized)
     {
+        struct DevicePlayer *device_player, *device_player2;
         /* Remove self from the list of the IDirectInputs */
         EnterCriticalSection( &dinput_hook_crit );
         list_remove( &This->entry );
         LeaveCriticalSection( &dinput_hook_crit );
 
+        LIST_FOR_EACH_ENTRY_SAFE( device_player, device_player2,
+                &This->device_players, struct DevicePlayer, entry )
+            HeapFree(GetProcessHeap(), 0, device_player);
+
         check_hook_thread();
 
         This->crit.DebugInfo->Spare[0] = 0;
diff --git a/dlls/dinput/dinput_private.h b/dlls/dinput/dinput_private.h
index 176c0e0287..6c93e16e9e 100644
--- a/dlls/dinput/dinput_private.h
+++ b/dlls/dinput/dinput_private.h
@@ -46,6 +46,7 @@ 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                 device_players; /* device instance guid to player name */
 };
 
 /* Function called by all devices that Wine supports */
@@ -56,6 +57,12 @@ struct dinput_device {
     HRESULT (*create_device)(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPVOID *pdev, int unicode);
 };
 
+struct DevicePlayer {
+    GUID instance_guid;
+    WCHAR username[MAX_PATH];
+    struct list entry;
+};
+
 extern const struct dinput_device mouse_device DECLSPEC_HIDDEN;
 extern const struct dinput_device keyboard_device DECLSPEC_HIDDEN;
 extern const struct dinput_device joystick_linux_device DECLSPEC_HIDDEN;
-- 
2.11.0




More information about the wine-patches mailing list