[PATCH 3/6] winebus.sys: Use the unixlib interface for the UDEV bus thread.
Rémi Bernon
rbernon at codeweavers.com
Thu Aug 19 02:10:01 CDT 2021
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
dlls/winebus.sys/bus.h | 3 -
dlls/winebus.sys/bus_udev.c | 158 ++++++++++++++------------------
dlls/winebus.sys/main.c | 46 +++++++++-
dlls/winebus.sys/unix_private.h | 4 +
dlls/winebus.sys/unixlib.c | 3 +
dlls/winebus.sys/unixlib.h | 10 ++
6 files changed, 128 insertions(+), 96 deletions(-)
diff --git a/dlls/winebus.sys/bus.h b/dlls/winebus.sys/bus.h
index 2c2d26a1525..4618dea1396 100644
--- a/dlls/winebus.sys/bus.h
+++ b/dlls/winebus.sys/bus.h
@@ -28,9 +28,7 @@
typedef int(*enum_func)(DEVICE_OBJECT *device, void *context);
/* Buses */
-NTSTATUS udev_driver_init(void) DECLSPEC_HIDDEN;
NTSTATUS iohid_driver_init(void) DECLSPEC_HIDDEN;
-void udev_driver_unload( void ) DECLSPEC_HIDDEN;
void iohid_driver_unload( void ) DECLSPEC_HIDDEN;
/* Native device function table */
@@ -58,7 +56,6 @@ void process_hid_report(DEVICE_OBJECT *device, BYTE *report, DWORD length) DECLS
DEVICE_OBJECT *bus_enumerate_hid_devices(const WCHAR *bus_id, enum_func function, void *context) DECLSPEC_HIDDEN;
/* General Bus Functions */
-DWORD check_bus_option(const UNICODE_STRING *option, DWORD default_value) DECLSPEC_HIDDEN;
BOOL is_xbox_gamepad(WORD vid, WORD pid) DECLSPEC_HIDDEN;
extern HANDLE driver_key DECLSPEC_HIDDEN;
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c
index 77a242a6087..51d846b3bed 100644
--- a/dlls/winebus.sys/bus_udev.c
+++ b/dlls/winebus.sys/bus_udev.c
@@ -80,6 +80,7 @@
#endif
#include "bus.h"
+#include "unix_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(plugplay);
@@ -87,11 +88,12 @@ WINE_DEFAULT_DEBUG_CHANNEL(plugplay);
WINE_DECLARE_DEBUG_CHANNEL(hid_report);
+static struct udev_bus_options options;
+
static struct udev *udev_context = NULL;
-static DWORD disable_hidraw = 0;
-static DWORD disable_input = 0;
-static HANDLE deviceloop_handle;
+static struct udev_monitor *udev_monitor;
static int deviceloop_control[2];
+static int udev_monitor_fd;
static const WCHAR hidraw_busidW[] = {'H','I','D','R','A','W',0};
static const WCHAR lnxev_busidW[] = {'L','N','X','E','V',0};
@@ -1179,11 +1181,11 @@ static void build_initial_deviceset(void)
return;
}
- if (!disable_hidraw)
+ if (!options.disable_hidraw)
if (udev_enumerate_add_match_subsystem(enumerate, "hidraw") < 0)
WARN("Failed to add subsystem 'hidraw' to enumeration\n");
#ifdef HAS_PROPER_INPUT_HEADER
- if (!disable_input)
+ if (!options.disable_input)
{
if (udev_enumerate_add_match_subsystem(enumerate, "input") < 0)
WARN("Failed to add subsystem 'input' to enumeration\n");
@@ -1210,7 +1212,7 @@ static void build_initial_deviceset(void)
udev_enumerate_unref(enumerate);
}
-static struct udev_monitor *create_monitor(struct pollfd *pfd)
+static struct udev_monitor *create_monitor(int *fd)
{
struct udev_monitor *monitor;
int systems = 0;
@@ -1222,7 +1224,7 @@ static struct udev_monitor *create_monitor(struct pollfd *pfd)
return NULL;
}
- if (!disable_hidraw)
+ if (!options.disable_hidraw)
{
if (udev_monitor_filter_add_match_subsystem_devtype(monitor, "hidraw", NULL) < 0)
WARN("Failed to add 'hidraw' subsystem to monitor\n");
@@ -1230,7 +1232,7 @@ static struct udev_monitor *create_monitor(struct pollfd *pfd)
systems++;
}
#ifdef HAS_PROPER_INPUT_HEADER
- if (!disable_input)
+ if (!options.disable_input)
{
if (udev_monitor_filter_add_match_subsystem_devtype(monitor, "input", NULL) < 0)
WARN("Failed to add 'input' subsystem to monitor\n");
@@ -1247,11 +1249,8 @@ static struct udev_monitor *create_monitor(struct pollfd *pfd)
if (udev_monitor_enable_receiving(monitor) < 0)
goto error;
- if ((pfd->fd = udev_monitor_get_fd(monitor)) >= 0)
- {
- pfd->events = POLLIN;
+ if ((*fd = udev_monitor_get_fd(monitor)) >= 0)
return monitor;
- }
error:
WARN("Failed to start monitoring\n");
@@ -1287,118 +1286,95 @@ static void process_monitor_event(struct udev_monitor *monitor)
udev_device_unref(dev);
}
-static DWORD CALLBACK deviceloop_thread(void *args)
-{
- struct udev_monitor *monitor;
- HANDLE init_done = args;
- struct pollfd pfd[2];
-
- pfd[1].fd = deviceloop_control[0];
- pfd[1].events = POLLIN;
- pfd[1].revents = 0;
-
- monitor = create_monitor(&pfd[0]);
- build_initial_deviceset();
- SetEvent(init_done);
-
- while (monitor)
- {
- if (poll(pfd, 2, -1) <= 0) continue;
- if (pfd[1].revents) break;
- process_monitor_event(monitor);
- }
-
- TRACE("Monitor thread exiting\n");
- if (monitor)
- udev_monitor_unref(monitor);
- return 0;
-}
-
-void udev_driver_unload( void )
+NTSTATUS WINAPI udev_bus_stop(void)
{
- TRACE("Unload Driver\n");
-
- if (!deviceloop_handle)
- return;
+ if (!udev_context) return STATUS_SUCCESS;
write(deviceloop_control[1], "q", 1);
- WaitForSingleObject(deviceloop_handle, INFINITE);
- close(deviceloop_control[0]);
- close(deviceloop_control[1]);
- CloseHandle(deviceloop_handle);
+ return STATUS_SUCCESS;
}
-NTSTATUS udev_driver_init(void)
+NTSTATUS WINAPI udev_bus_init(void *args)
{
- HANDLE events[2];
- DWORD result;
- static const WCHAR hidraw_disabledW[] = {'D','i','s','a','b','l','e','H','i','d','r','a','w',0};
- static const UNICODE_STRING hidraw_disabled = {sizeof(hidraw_disabledW) - sizeof(WCHAR), sizeof(hidraw_disabledW), (WCHAR*)hidraw_disabledW};
- static const WCHAR input_disabledW[] = {'D','i','s','a','b','l','e','I','n','p','u','t',0};
- static const UNICODE_STRING input_disabled = {sizeof(input_disabledW) - sizeof(WCHAR), sizeof(input_disabledW), (WCHAR*)input_disabledW};
+ TRACE("args %p\n", args);
+
+ options = *(struct udev_bus_options *)args;
if (pipe(deviceloop_control) != 0)
{
- ERR("Control pipe creation failed\n");
+ ERR("control pipe creation failed\n");
return STATUS_UNSUCCESSFUL;
}
if (!(udev_context = udev_new()))
{
- ERR("Can't create udev object\n");
- goto error;
+ ERR("udev object creation failed\n");
+ close(deviceloop_control[0]);
+ close(deviceloop_control[1]);
+ return STATUS_UNSUCCESSFUL;
}
- disable_hidraw = check_bus_option(&hidraw_disabled, 0);
- if (disable_hidraw)
- TRACE("UDEV hidraw devices disabled in registry\n");
-
-#ifdef HAS_PROPER_INPUT_HEADER
- disable_input = check_bus_option(&input_disabled, 0);
- if (disable_input)
- TRACE("UDEV input devices disabled in registry\n");
-#endif
-
- if (!(events[0] = CreateEventW(NULL, TRUE, FALSE, NULL)))
- goto error;
- if (!(events[1] = CreateThread(NULL, 0, deviceloop_thread, events[0], 0, NULL)))
+ if (!(udev_monitor = create_monitor(&udev_monitor_fd)))
{
- CloseHandle(events[0]);
- goto error;
+ ERR("udev monitor creation failed\n");
+ close(deviceloop_control[0]);
+ close(deviceloop_control[1]);
+ udev_unref(udev_context);
+ udev_context = NULL;
+ return STATUS_UNSUCCESSFUL;
}
- result = WaitForMultipleObjects(2, events, FALSE, INFINITE);
- CloseHandle(events[0]);
- if (result == WAIT_OBJECT_0)
+ build_initial_deviceset();
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS WINAPI udev_bus_wait(void)
+{
+ struct pollfd pfd[2];
+
+ pfd[0].fd = udev_monitor_fd;
+ pfd[0].events = POLLIN;
+ pfd[0].revents = 0;
+ pfd[1].fd = deviceloop_control[0];
+ pfd[1].events = POLLIN;
+ pfd[1].revents = 0;
+
+ while (1)
{
- deviceloop_handle = events[1];
- TRACE("Initialization successful\n");
- return STATUS_SUCCESS;
+ if (poll(pfd, 2, -1) <= 0) continue;
+ if (pfd[1].revents) break;
+ process_monitor_event(udev_monitor);
}
- CloseHandle(events[1]);
-error:
- ERR("Failed to initialize udev device thread\n");
+ TRACE("UDEV main loop exiting\n");
+ udev_monitor_unref(udev_monitor);
+
+ udev_unref(udev_context);
+ udev_context = NULL;
+
close(deviceloop_control[0]);
close(deviceloop_control[1]);
- if (udev_context)
- {
- udev_unref(udev_context);
- udev_context = NULL;
- }
- return STATUS_UNSUCCESSFUL;
+ return STATUS_SUCCESS;
}
#else
-NTSTATUS udev_driver_init(void)
+NTSTATUS WINAPI udev_bus_init(void *args)
+{
+ WARN("UDEV support not compiled in!\n");
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS WINAPI udev_bus_wait(void)
{
+ WARN("UDEV support not compiled in!\n");
return STATUS_NOT_IMPLEMENTED;
}
-void udev_driver_unload( void )
+NTSTATUS WINAPI udev_bus_stop(void)
{
- TRACE("Stub: Unload Driver\n");
+ WARN("UDEV support not compiled in!\n");
+ return STATUS_NOT_IMPLEMENTED;
}
#endif /* HAVE_UDEV */
diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c
index a4b236cecb7..36a281bec9d 100644
--- a/dlls/winebus.sys/main.c
+++ b/dlls/winebus.sys/main.c
@@ -408,7 +408,7 @@ static NTSTATUS build_device_relations(DEVICE_RELATIONS **devices)
return STATUS_SUCCESS;
}
-DWORD check_bus_option(const UNICODE_STRING *option, DWORD default_value)
+static DWORD check_bus_option(const UNICODE_STRING *option, DWORD default_value)
{
char buffer[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[sizeof(DWORD)])];
KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer;
@@ -705,6 +705,48 @@ static NTSTATUS sdl_driver_init(void)
return STATUS_SUCCESS;
}
+static NTSTATUS udev_driver_init(void)
+{
+ static const WCHAR udev_bus_name[] = {'U','D','E','V',0};
+ static const WCHAR hidraw_disabledW[] = {'D','i','s','a','b','l','e','H','i','d','r','a','w',0};
+ static const UNICODE_STRING hidraw_disabled = {sizeof(hidraw_disabledW) - sizeof(WCHAR), sizeof(hidraw_disabledW), (WCHAR*)hidraw_disabledW};
+ static const WCHAR input_disabledW[] = {'D','i','s','a','b','l','e','I','n','p','u','t',0};
+ static const UNICODE_STRING input_disabled = {sizeof(input_disabledW) - sizeof(WCHAR), sizeof(input_disabledW), (WCHAR*)input_disabledW};
+ struct udev_bus_options udev_params;
+ struct bus_main_params params =
+ {
+ .name = udev_bus_name,
+ .bus_init = unix_funcs->udev_bus_init,
+ .bus_wait = unix_funcs->udev_bus_wait,
+ .bus_params = &udev_params,
+ };
+ DWORD i = bus_count++;
+
+ if (!(params.init = CreateEventW(NULL, FALSE, FALSE, NULL)))
+ {
+ ERR("failed to create UDEV bus event.\n");
+ bus_count--;
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ udev_params.disable_hidraw = check_bus_option(&hidraw_disabled, 0);
+ if (udev_params.disable_hidraw) TRACE("UDEV hidraw devices disabled in registry\n");
+ udev_params.disable_input = check_bus_option(&input_disabled, 0);
+ if (udev_params.disable_input) TRACE("UDEV input devices disabled in registry\n");
+
+ if (!(bus_thread[i] = CreateThread(NULL, 0, bus_main_thread, ¶ms, 0, NULL)))
+ {
+ ERR("failed to create UDEV bus thread.\n");
+ CloseHandle(params.init);
+ bus_count--;
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ WaitForSingleObject(params.init, INFINITE);
+ CloseHandle(params.init);
+ return STATUS_SUCCESS;
+}
+
static NTSTATUS fdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp)
{
static const WCHAR SDL_enabledW[] = {'E','n','a','b','l','e',' ','S','D','L',0};
@@ -733,8 +775,8 @@ static NTSTATUS fdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp)
irp->IoStatus.Status = STATUS_SUCCESS;
break;
case IRP_MN_REMOVE_DEVICE:
- udev_driver_unload();
iohid_driver_unload();
+ unix_funcs->udev_bus_stop();
unix_funcs->sdl_bus_stop();
WaitForMultipleObjects(bus_count, bus_thread, TRUE, INFINITE);
diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h
index 7ac882a03b2..8fb280ac7cd 100644
--- a/dlls/winebus.sys/unix_private.h
+++ b/dlls/winebus.sys/unix_private.h
@@ -31,4 +31,8 @@ extern NTSTATUS WINAPI sdl_bus_init(void *args) DECLSPEC_HIDDEN;
extern NTSTATUS WINAPI sdl_bus_wait(void) DECLSPEC_HIDDEN;
extern NTSTATUS WINAPI sdl_bus_stop(void) DECLSPEC_HIDDEN;
+extern NTSTATUS WINAPI udev_bus_init(void *args) DECLSPEC_HIDDEN;
+extern NTSTATUS WINAPI udev_bus_wait(void) DECLSPEC_HIDDEN;
+extern NTSTATUS WINAPI udev_bus_stop(void) DECLSPEC_HIDDEN;
+
#endif /* __WINEBUS_UNIX_PRIVATE_H */
diff --git a/dlls/winebus.sys/unixlib.c b/dlls/winebus.sys/unixlib.c
index 832a20372d6..cbd29ceecd1 100644
--- a/dlls/winebus.sys/unixlib.c
+++ b/dlls/winebus.sys/unixlib.c
@@ -36,6 +36,9 @@ static const struct unix_funcs unix_funcs =
sdl_bus_init,
sdl_bus_wait,
sdl_bus_stop,
+ udev_bus_init,
+ udev_bus_wait,
+ udev_bus_stop,
};
NTSTATUS CDECL __wine_init_unix_lib(HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out)
diff --git a/dlls/winebus.sys/unixlib.h b/dlls/winebus.sys/unixlib.h
index a5cd57867e4..cd1bce096c7 100644
--- a/dlls/winebus.sys/unixlib.h
+++ b/dlls/winebus.sys/unixlib.h
@@ -32,11 +32,21 @@ struct sdl_bus_options
BOOL map_controllers;
};
+struct udev_bus_options
+{
+ BOOL disable_hidraw;
+ BOOL disable_input;
+};
+
struct unix_funcs
{
NTSTATUS (WINAPI *sdl_bus_init)(void *);
NTSTATUS (WINAPI *sdl_bus_wait)(void);
NTSTATUS (WINAPI *sdl_bus_stop)(void);
+
+ NTSTATUS (WINAPI *udev_bus_init)(void *);
+ NTSTATUS (WINAPI *udev_bus_wait)(void);
+ NTSTATUS (WINAPI *udev_bus_stop)(void);
};
#endif /* __WINEBUS_UNIXLIB_H */
--
2.32.0
More information about the wine-devel
mailing list