Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/bus.h | 30 ------------ dlls/winebus.sys/bus_iohid.c | 1 - dlls/winebus.sys/bus_sdl.c | 69 +++++++--------------------- dlls/winebus.sys/bus_udev.c | 1 - dlls/winebus.sys/main.c | 88 ++++++++++++++++++++++++++++++++++-- dlls/winebus.sys/unixlib.h | 3 ++ 6 files changed, 105 insertions(+), 87 deletions(-) delete mode 100644 dlls/winebus.sys/bus.h
diff --git a/dlls/winebus.sys/bus.h b/dlls/winebus.sys/bus.h deleted file mode 100644 index 96503a8267f..00000000000 --- a/dlls/winebus.sys/bus.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2016 Aric Stewart - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include <stdarg.h> - -#include <windef.h> -#include <winbase.h> -#include <winternl.h> -#include <ddk/wdm.h> -#include <ddk/hidclass.h> -#include <hidusage.h> - -#include "unixlib.h" - -extern HANDLE driver_key DECLSPEC_HIDDEN; diff --git a/dlls/winebus.sys/bus_iohid.c b/dlls/winebus.sys/bus_iohid.c index f3b55cc0f70..6d3f621a15a 100644 --- a/dlls/winebus.sys/bus_iohid.c +++ b/dlls/winebus.sys/bus_iohid.c @@ -89,7 +89,6 @@ #include "ddk/hidtypes.h" #include "wine/debug.h"
-#include "bus.h" #include "unix_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(plugplay); diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index bc7abcb933b..ff3a7ca09d8 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -50,7 +50,6 @@ # define LE_WORD(x) (x) #endif
-#include "bus.h" #include "unix_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(plugplay); @@ -815,59 +814,11 @@ static void process_device_event(SDL_Event *event) LeaveCriticalSection(&sdl_cs); }
-static void sdl_load_mappings(void) +NTSTATUS sdl_bus_init(void *args) { - HKEY key; - static const WCHAR szPath[] = {'m','a','p',0}; const char *mapping; + int i;
- if ((mapping = getenv("SDL_GAMECONTROLLERCONFIG"))) - { - TRACE("Setting environment mapping %s\n", debugstr_a(mapping)); - if (pSDL_GameControllerAddMapping(mapping) < 0) - WARN("Failed to add environment mapping %s\n", pSDL_GetError()); - } - else if (!RegOpenKeyExW(driver_key, szPath, 0, KEY_QUERY_VALUE, &key)) - { - DWORD index = 0; - CHAR *buffer = NULL; - DWORD buffer_len = 0; - LSTATUS rc; - - do - { - CHAR name[255]; - DWORD name_len; - DWORD type; - DWORD data_len = buffer_len; - - name_len = sizeof(name); - rc = RegEnumValueA(key, index, name, &name_len, NULL, &type, (LPBYTE)buffer, &data_len); - if (rc == ERROR_MORE_DATA || buffer == NULL) - { - if (buffer) buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, data_len); - else buffer = HeapAlloc(GetProcessHeap(), 0, data_len); - buffer_len = data_len; - - name_len = sizeof(name); - rc = RegEnumValueA(key, index, name, &name_len, NULL, &type, (LPBYTE)buffer, &data_len); - } - - if (rc == STATUS_SUCCESS) - { - TRACE("Setting registry mapping %s\n", debugstr_a(buffer)); - if (pSDL_GameControllerAddMapping(buffer) < 0) - WARN("Failed to add registry mapping %s\n", pSDL_GetError()); - index++; - } - } while (rc == STATUS_SUCCESS); - HeapFree(GetProcessHeap(), 0, buffer); - NtClose(key); - } -} - -NTSTATUS sdl_bus_init(void *args) -{ TRACE("args %p\n", args);
options = *(struct sdl_bus_options *)args; @@ -942,7 +893,21 @@ NTSTATUS sdl_bus_init(void *args) pSDL_GameControllerEventState(SDL_ENABLE);
/* Process mappings */ - if (pSDL_GameControllerAddMapping != NULL) sdl_load_mappings(); + if (pSDL_GameControllerAddMapping) + { + if ((mapping = getenv("SDL_GAMECONTROLLERCONFIG"))) + { + TRACE("Setting environment mapping %s\n", debugstr_a(mapping)); + if (pSDL_GameControllerAddMapping(mapping) < 0) + WARN("Failed to add environment mapping %s\n", pSDL_GetError()); + } + else for (i = 0; i < options.mappings_count; ++i) + { + TRACE("Setting registry mapping %s\n", debugstr_a(options.mappings[i])); + if (pSDL_GameControllerAddMapping(options.mappings[i]) < 0) + WARN("Failed to add registry mapping %s\n", pSDL_GetError()); + } + }
return STATUS_SUCCESS;
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index bfeb7bfc09b..b8b3a0f0a84 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -79,7 +79,6 @@ #define LE_DWORD(x) (x) #endif
-#include "bus.h" #include "unix_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(plugplay); diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c index f1b0430509a..4528673f880 100644 --- a/dlls/winebus.sys/main.c +++ b/dlls/winebus.sys/main.c @@ -34,7 +34,6 @@ #include "wine/list.h" #include "wine/unixlib.h"
-#include "bus.h" #include "unixlib.h"
WINE_DEFAULT_DEBUG_CHANNEL(plugplay); @@ -66,7 +65,7 @@ static DEVICE_OBJECT *keyboard_obj; static DEVICE_OBJECT *bus_pdo; static DEVICE_OBJECT *bus_fdo;
-HANDLE driver_key; +static HANDLE driver_key;
enum device_state { @@ -630,6 +629,85 @@ static NTSTATUS bus_main_thread_start(struct bus_main_params *bus) return STATUS_SUCCESS; }
+static void sdl_bus_free_mappings(struct sdl_bus_options *options) +{ + DWORD count = options->mappings_count; + char **mappings = options->mappings; + + while (count) HeapFree(GetProcessHeap(), 0, mappings[--count]); + HeapFree(GetProcessHeap(), 0, mappings); +} + +static void sdl_bus_load_mappings(struct sdl_bus_options *options) +{ + static const WCHAR szPath[] = {'m','a','p',0}; + + ULONG idx = 0, len, count = 0, capacity, info_size, info_max_size; + KEY_VALUE_FULL_INFORMATION *info; + OBJECT_ATTRIBUTES attr = {0}; + char **mappings = NULL; + UNICODE_STRING path; + NTSTATUS status; + HANDLE key; + + options->mappings_count = 0; + options->mappings = NULL; + + RtlInitUnicodeString(&path, szPath); + InitializeObjectAttributes(&attr, &path, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, driver_key, NULL); + status = NtOpenKey(&key, KEY_ALL_ACCESS, &attr); + if (status) return; + + capacity = 1024; + mappings = HeapAlloc(GetProcessHeap(), 0, capacity * sizeof(*mappings)); + info_max_size = offsetof(KEY_VALUE_FULL_INFORMATION, Name) + 512; + info = HeapAlloc(GetProcessHeap(), 0, info_max_size); + + while (!status && info && mappings) + { + status = NtEnumerateValueKey(key, idx, KeyValueFullInformation, info, info_max_size, &info_size); + while (status == STATUS_BUFFER_OVERFLOW) + { + info_max_size = info_size; + if (!(info = HeapReAlloc(GetProcessHeap(), 0, info, info_max_size))) break; + status = NtEnumerateValueKey(key, idx, KeyValueFullInformation, info, info_max_size, &info_size); + } + + if (status == STATUS_NO_MORE_ENTRIES) + { + options->mappings_count = count; + options->mappings = mappings; + goto done; + } + + idx++; + if (status) break; + if (info->Type != REG_SZ) continue; + + RtlUnicodeToMultiByteSize(&len, (WCHAR *)((char *)info + info->DataOffset), info_size - info->DataOffset); + if (!len) continue; + + if (!(mappings[count++] = HeapAlloc(GetProcessHeap(), 0, len + 1))) break; + if (count > capacity) + { + capacity = capacity * 3 / 2; + if (!(mappings = HeapReAlloc(GetProcessHeap(), 0, mappings, capacity * sizeof(*mappings)))) + break; + } + + RtlUnicodeToMultiByteN(mappings[count], len, NULL, (WCHAR *)((char *)info + info->DataOffset), + info_size - info->DataOffset); + if (mappings[len - 1]) mappings[len] = 0; + } + + if (mappings) while (count) HeapFree(GetProcessHeap(), 0, mappings[--count]); + HeapFree(GetProcessHeap(), 0, mappings); + +done: + HeapFree(GetProcessHeap(), 0, info); + NtClose(key); +} + static NTSTATUS sdl_driver_init(void) { static const WCHAR bus_name[] = {'S','D','L',0}; @@ -643,11 +721,15 @@ static NTSTATUS sdl_driver_init(void) .init_code = sdl_init, .wait_code = sdl_wait, }; + NTSTATUS status;
bus_options.map_controllers = check_bus_option(&controller_mode, 1); if (!bus_options.map_controllers) TRACE("SDL controller to XInput HID gamepad mapping disabled\n"); + sdl_bus_load_mappings(&bus_options);
- return bus_main_thread_start(&bus); + status = bus_main_thread_start(&bus); + sdl_bus_free_mappings(&bus_options); + return status; }
static NTSTATUS udev_driver_init(void) diff --git a/dlls/winebus.sys/unixlib.h b/dlls/winebus.sys/unixlib.h index ccca8d12e8b..55ba42500cf 100644 --- a/dlls/winebus.sys/unixlib.h +++ b/dlls/winebus.sys/unixlib.h @@ -49,6 +49,9 @@ struct device_desc struct sdl_bus_options { BOOL map_controllers; + /* freed after bus_init */ + DWORD mappings_count; + char **mappings; };
struct udev_bus_options