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