[4/5] dinput: Device username being assigned at creation time (try 2)
Lucas Fialho Zawacki
lfzawacki at gmail.com
Mon Jan 9 11:18:36 CST 2012
From: Lucas Fialho Zawacki <lfzawacki at gmail.com>
Changes since last try:
* Checking _get_mapping_path for success
* Checking if username extracted from file conforms to buffersize
---
dlls/dinput/device.c | 71 +++++++++++++++++++++++++++++++++++++
dlls/dinput/device_private.h | 2 +
dlls/dinput/joystick_linux.c | 3 ++
dlls/dinput/joystick_linuxinput.c | 3 ++
dlls/dinput/joystick_osx.c | 3 ++
dlls/dinput/keyboard.c | 3 ++
dlls/dinput/mouse.c | 3 ++
7 files changed, 88 insertions(+), 0 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c
index 07d500e..5ec9ead 100644
--- a/dlls/dinput/device.c
+++ b/dlls/dinput/device.c
@@ -617,6 +617,77 @@ static BOOL _write_private_profile_intW(const char *format, WCHAR* section, WCHA
}
/*
+ * _get_mapping_username
+ * Retrieves a device username from the respective mapping file.
+ * The caller has to free the returned string.
+ */
+WCHAR * _get_mapping_username(IDirectInputDeviceImpl *This)
+{
+ static WCHAR fake_username[] = {'*','\0'};
+ static WCHAR delimiter[] = {'X','_','\0'};
+ WCHAR username[MAX_PATH];
+ WCHAR *ret = NULL, *map_path;
+ WIN32_FIND_DATAW find_data;
+ DIDEVICEINSTANCEW didevi;
+ FILETIME most_recent, created;
+ HANDLE handle;
+ int found = 0;
+
+ didevi.dwSize = sizeof(didevi);
+ IDirectInputDevice_GetDeviceInfo(IDirectInputDevice8W_from_impl(This), &didevi);
+
+ /* This path is used to find usernames. Something like: PATH\TO\FILE\*X_DEVICEX_0.INI */
+ map_path = _get_mapping_path(didevi.tszInstanceName, fake_username);
+
+ if (map_path == NULL) return NULL;
+
+ /* We are only interested in the creation time */
+ GetProcessTimes(GetCurrentProcess(), &created, &most_recent, &most_recent, &most_recent);
+ most_recent = created;
+
+ /* Step through each possible username file */
+ handle = FindFirstFileW(map_path, &find_data);
+
+ if (handle != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ /* If file was writen to disk after the proccess was initiated */
+ if (CompareFileTime(&find_data.ftLastWriteTime, &created) > 0)
+ {
+ /* If it is more recent than all the other files */
+ if (CompareFileTime(&find_data.ftLastWriteTime, &most_recent) > 0)
+ {
+ WCHAR *end;
+
+ /* Store filetime as most recent and retrieve the username */
+ most_recent = find_data.ftLastWriteTime;
+ end = strstrW(find_data.cFileName, delimiter);
+
+ /* Extract username from the file, ignore an absurdly long filename */
+ if ((end - find_data.cFileName + 1) < MAX_PATH)
+ {
+ memcpy(username, find_data.cFileName, (end - find_data.cFileName + 1) * sizeof(WCHAR));
+ username[end - find_data.cFileName + 1] = '\0';
+ found = 1;
+ }
+ }
+ }
+ } while (FindNextFileW(handle, &find_data));
+ }
+
+ if (found)
+ {
+ ret = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*lstrlenW(username)+1);
+ lstrcpynW(ret, username, lstrlenW(username));
+ }
+
+ HeapFree(GetProcessHeap(), 0, map_path);
+
+ return ret;
+}
+
+/*
* _get_mapping_path
* For a given username and device name, returns the filename with path of the
* mapping settings files.
diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h
index cf253d4..4f05d2d 100644
--- a/dlls/dinput/device_private.h
+++ b/dlls/dinput/device_private.h
@@ -95,6 +95,8 @@ extern void queue_event(LPDIRECTINPUTDEVICE8A iface, int inst_id, DWORD data, DW
extern int id_to_object(LPCDIDATAFORMAT df, int id) DECLSPEC_HIDDEN;
extern int find_property(const DataFormat *df, LPCDIPROPHEADER ph) DECLSPEC_HIDDEN;
+extern WCHAR* _get_mapping_username(IDirectInputDeviceImpl *This) DECLSPEC_HIDDEN;
+
/* Common joystick stuff */
typedef struct
{
diff --git a/dlls/dinput/joystick_linux.c b/dlls/dinput/joystick_linux.c
index d951e76..a489d8f 100644
--- a/dlls/dinput/joystick_linux.c
+++ b/dlls/dinput/joystick_linux.c
@@ -345,6 +345,9 @@ static HRESULT alloc_device(REFGUID rguid, IDirectInputImpl *dinput,
if (hr != DI_OK)
goto FAILED1;
+ /* If the device was assigned a username with SetActionMap, retrieve it */
+ newDevice->generic.base.username = _get_mapping_username(&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 2902f9f..5308e5e 100644
--- a/dlls/dinput/joystick_linuxinput.c
+++ b/dlls/dinput/joystick_linuxinput.c
@@ -470,6 +470,9 @@ 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;
+ /* If the device was assigned a username with SetActionMap, retrieve it */
+ newDevice->generic.base.username = _get_mapping_username(&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 40268ad..9d18141 100644
--- a/dlls/dinput/joystick_osx.c
+++ b/dlls/dinput/joystick_osx.c
@@ -777,6 +777,9 @@ 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");
+ /* If the device was assigned a username with SetActionMap, retrieve it */
+ newDevice->generic.base.username = _get_mapping_username(&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 3ca7d97..24ddec8 100644
--- a/dlls/dinput/keyboard.c
+++ b/dlls/dinput/keyboard.c
@@ -236,6 +236,9 @@ static SysKeyboardImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput)
InitializeCriticalSection(&newDevice->base.crit);
newDevice->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": SysKeyboardImpl*->base.crit");
+ /* If the device was assigned a username with SetActionMap, retrieve it */
+ newDevice->base.username = _get_mapping_username(&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 06403e1..7c05a6a 100644
--- a/dlls/dinput/mouse.c
+++ b/dlls/dinput/mouse.c
@@ -227,6 +227,9 @@ static SysMouseImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput)
if (appkey) RegCloseKey(appkey);
if (hkey) RegCloseKey(hkey);
+ /* If the device was assigned a username with SetActionMap, retrieve it */
+ newDevice->base.username = _get_mapping_username(&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
More information about the wine-patches
mailing list