Rémi Bernon : winebus.sys: Load SDL bus mappings before calling bus_init.
Alexandre Julliard
julliard at winehq.org
Thu Sep 16 15:34:30 CDT 2021
Module: wine
Branch: master
Commit: 0017b5eb636ee4963636eaf83ae34f6077d695fd
URL: https://source.winehq.org/git/wine.git/?a=commit;h=0017b5eb636ee4963636eaf83ae34f6077d695fd
Author: Rémi Bernon <rbernon at codeweavers.com>
Date: Thu Sep 16 10:17:55 2021 +0200
winebus.sys: Load SDL bus mappings before calling bus_init.
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
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(-)
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
More information about the wine-cvs
mailing list