Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/bus.h | 6 +- dlls/winebus.sys/bus_udev.c | 130 ++++++++++++++++-------------------- dlls/winebus.sys/main.c | 15 ++++- 3 files changed, 75 insertions(+), 76 deletions(-)
diff --git a/dlls/winebus.sys/bus.h b/dlls/winebus.sys/bus.h index c5b93b769c9..6dc95a5b803 100644 --- a/dlls/winebus.sys/bus.h +++ b/dlls/winebus.sys/bus.h @@ -28,15 +28,17 @@ 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;
extern NTSTATUS sdl_bus_init(void *) DECLSPEC_HIDDEN; extern NTSTATUS sdl_bus_wait(void *) DECLSPEC_HIDDEN; extern NTSTATUS sdl_bus_stop(void *) DECLSPEC_HIDDEN;
+extern NTSTATUS udev_bus_init(void *) DECLSPEC_HIDDEN; +extern NTSTATUS udev_bus_wait(void *) DECLSPEC_HIDDEN; +extern NTSTATUS udev_bus_stop(void *) DECLSPEC_HIDDEN; + /* Native device function table */ typedef struct { diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index 77a242a6087..67d00670a26 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -88,10 +88,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(plugplay); WINE_DECLARE_DEBUG_CHANNEL(hid_report);
static struct udev *udev_context = NULL; +static struct udev_monitor *udev_monitor; static DWORD disable_hidraw = 0; static DWORD disable_input = 0; -static HANDLE deviceloop_handle; 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}; @@ -1210,7 +1211,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; @@ -1247,11 +1248,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,51 +1285,8 @@ 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 ) -{ - TRACE("Unload Driver\n"); - - if (!deviceloop_handle) - return; - - write(deviceloop_control[1], "q", 1); - WaitForSingleObject(deviceloop_handle, INFINITE); - close(deviceloop_control[0]); - close(deviceloop_control[1]); - CloseHandle(deviceloop_handle); -} - -NTSTATUS udev_driver_init(void) +NTSTATUS 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}; @@ -1339,13 +1294,13 @@ NTSTATUS udev_driver_init(void)
if (pipe(deviceloop_control) != 0) { - ERR("Control pipe creation failed\n"); + ERR("UDEV control pipe creation failed\n"); return STATUS_UNSUCCESSFUL; }
if (!(udev_context = udev_new())) { - ERR("Can't create udev object\n"); + ERR("UDEV object creation failed\n"); goto error; }
@@ -1359,46 +1314,75 @@ NTSTATUS udev_driver_init(void) 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]); + ERR("UDEV monitor creation failed\n"); goto error; }
- result = WaitForMultipleObjects(2, events, FALSE, INFINITE); - CloseHandle(events[0]); - if (result == WAIT_OBJECT_0) - { - deviceloop_handle = events[1]; - TRACE("Initialization successful\n"); - return STATUS_SUCCESS; - } - CloseHandle(events[1]); + build_initial_deviceset(); + return STATUS_SUCCESS;
error: - ERR("Failed to initialize udev device thread\n"); + if (udev_context) udev_unref(udev_context); + udev_context = NULL; close(deviceloop_control[0]); close(deviceloop_control[1]); - if (udev_context) + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS udev_bus_wait(void *args) +{ + 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) { - udev_unref(udev_context); - udev_context = NULL; + if (poll(pfd, 2, -1) <= 0) continue; + if (pfd[1].revents) break; + process_monitor_event(udev_monitor); } - return STATUS_UNSUCCESSFUL; + + 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]); + return STATUS_SUCCESS; +} + +NTSTATUS udev_bus_stop(void *args) +{ + if (!udev_context) return STATUS_SUCCESS; + write(deviceloop_control[1], "q", 1); + return STATUS_SUCCESS; }
#else
-NTSTATUS udev_driver_init(void) +NTSTATUS udev_bus_init(void *args) +{ + WARN("UDEV support not compiled in!\n"); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS udev_bus_wait(void *args) { + WARN("UDEV support not compiled in!\n"); return STATUS_NOT_IMPLEMENTED; }
-void udev_driver_unload( void ) +NTSTATUS udev_bus_stop(void *args) { - 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 6be5e677bba..505fc131be4 100644 --- a/dlls/winebus.sys/main.c +++ b/dlls/winebus.sys/main.c @@ -686,6 +686,19 @@ static NTSTATUS sdl_driver_init(void) return bus_main_thread_start(&bus); }
+static NTSTATUS udev_driver_init(void) +{ + static const WCHAR bus_name[] = {'U','D','E','V',0}; + struct bus_main_params bus = + { + .name = bus_name, + .init_func = udev_bus_init, + .wait_func = udev_bus_wait, + }; + + return bus_main_thread_start(&bus); +} + 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}; @@ -714,9 +727,9 @@ 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(); sdl_bus_stop(NULL); + udev_bus_stop(NULL);
WaitForMultipleObjects(bus_count, bus_thread, TRUE, INFINITE); while (bus_count--) CloseHandle(bus_thread[bus_count]);