[v3 1/2] dinput: Keep username same between device objects.

Andrew Eikum aeikum at codeweavers.com
Fri Mar 3 10:50:09 CST 2017


Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>

On Thu, Mar 02, 2017 at 08:51:40PM +0200, Jetro Jormalainen wrote:
> v2: Fixed problems noted by Andrew Eikum.
> v3: Combined test for username between device objects from previous
> test patch.
> 
> Tested on Windows 10, Windows XP, 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 +++++++
>  dlls/dinput8/tests/device.c  | 11 +++++++++++
>  5 files changed, 59 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;
> diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c
> index 6753b73a2d..2b06f624c2 100644
> --- a/dlls/dinput8/tests/device.c
> +++ b/dlls/dinput8/tests/device.c
> @@ -174,6 +174,7 @@ static BOOL CALLBACK enumeration_callback(const DIDEVICEINSTANCEA *lpddi, IDirec
>      struct enum_data *data = pvRef;
>      DWORD cnt;
>      DIDEVICEOBJECTDATA buffer[5];
> +    IDirectInputDevice8A *lpdid2;
>  
>      if (!data) return DIENUM_CONTINUE;
>  
> @@ -205,6 +206,10 @@ static BOOL CALLBACK enumeration_callback(const DIDEVICEINSTANCEA *lpddi, IDirec
>          ok (dwFlags & DIEDBS_MAPPEDPRI1, "Mouse should be mapped as pri1 dwFlags=%08x\n", dwFlags);
>      }
>  
> +    /* Creating second device object to check if it has the same username */
> +    hr = IDirectInput_CreateDevice(data->pDI, &lpddi->guidInstance, &lpdid2, NULL);
> +    ok(SUCCEEDED(hr), "IDirectInput_CreateDevice() failed: %08x\n", hr);
> +
>      /* Building and setting an action map */
>      /* It should not use any pre-stored mappings so we use DIDBAM_HWDEFAULTS */
>      hr = IDirectInputDevice8_BuildActionMap(lpdid, data->lpdiaf, NULL, DIDBAM_HWDEFAULTS);
> @@ -231,6 +236,11 @@ static BOOL CALLBACK enumeration_callback(const DIDEVICEINSTANCEA *lpddi, IDirec
>      ok (SUCCEEDED(hr), "GetProperty failed hr=%08x\n", hr);
>      ok (!lstrcmpW(usernameW, dps.wsz), "Username not set correctly expected=%s, got=%s\n", wine_dbgstr_w(usernameW), wine_dbgstr_w(dps.wsz));
>  
> +    dps.wsz[0] = '\0';
> +    hr = IDirectInputDevice_GetProperty(lpdid2, DIPROP_USERNAME, &dps.diph);
> +    ok (SUCCEEDED(hr), "GetProperty failed hr=%08x\n", hr);
> +    ok (!lstrcmpW(usernameW, dps.wsz), "Username not set correctly expected=%s, got=%s\n", wine_dbgstr_w(usernameW), wine_dbgstr_w(dps.wsz));
> +
>      /* Test buffer size */
>      memset(&dp, 0, sizeof(dp));
>      dp.diph.dwSize = sizeof(dp);
> @@ -315,6 +325,7 @@ static void test_action_mapping(void)
>      af.dwBufferSize = 32;
>  
>      /* This enumeration builds and sets the action map for all devices */
> +    data.pDI = pDI;
>      hr = IDirectInput8_EnumDevicesBySemantics(pDI, 0, &af, enumeration_callback, &data, DIEDBSFL_ATTACHEDONLY);
>      ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed: hr=%08x\n", hr);
>  
> -- 
> 2.11.0
> 
> 
> 



More information about the wine-patches mailing list