Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
v3: Declare a const unixlib_entry_t __wine_unix_call_funcs[] variable in unixlib.h, instead of const unixlib_entry_t *__wine_unix_call_funcs which was not resolved...
dlls/winebus.sys/bus.h | 6 +- dlls/winebus.sys/bus_sdl.c | 150 +++++++++++++++---------------------- dlls/winebus.sys/main.c | 85 ++++++++++++++++++--- 3 files changed, 139 insertions(+), 102 deletions(-)
diff --git a/dlls/winebus.sys/bus.h b/dlls/winebus.sys/bus.h index 3e53b9c53f1..c5b93b769c9 100644 --- a/dlls/winebus.sys/bus.h +++ b/dlls/winebus.sys/bus.h @@ -30,10 +30,12 @@ typedef int(*enum_func)(DEVICE_OBJECT *device, void *context); /* Buses */ NTSTATUS udev_driver_init(void) DECLSPEC_HIDDEN; NTSTATUS iohid_driver_init(void) DECLSPEC_HIDDEN; -NTSTATUS sdl_driver_init(void) DECLSPEC_HIDDEN; void udev_driver_unload( void ) DECLSPEC_HIDDEN; void iohid_driver_unload( void ) DECLSPEC_HIDDEN; -void sdl_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;
/* Native device function table */ typedef struct diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index 84e3ef20664..02509f1560c 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -63,7 +63,6 @@ static const WCHAR sdl_busidW[] = {'S','D','L','J','O','Y',0}; static DWORD map_controllers = 0;
static void *sdl_handle = NULL; -static HANDLE deviceloop_handle; static UINT quit_event = -1;
#define MAKE_FUNCPTR(f) static typeof(f) * p##f = NULL @@ -889,68 +888,15 @@ static void sdl_load_mappings(void) } }
-static DWORD CALLBACK deviceloop_thread(void *args) +NTSTATUS sdl_bus_init(void *args) { - HANDLE init_done = args; - SDL_Event event; - - if (pSDL_Init(SDL_INIT_GAMECONTROLLER|SDL_INIT_HAPTIC) < 0) - { - ERR("Can't init SDL: %s\n", pSDL_GetError()); - return STATUS_UNSUCCESSFUL; - } - - pSDL_JoystickEventState(SDL_ENABLE); - pSDL_GameControllerEventState(SDL_ENABLE); - - /* Process mappings */ - if (pSDL_GameControllerAddMapping != NULL) sdl_load_mappings(); - - SetEvent(init_done); - - while (1) { - while (pSDL_WaitEvent(&event) != 0) { - if (event.type == quit_event) { - TRACE("Device thread exiting\n"); - return 0; - } - process_device_event(&event); - } - } -} - -void sdl_driver_unload( void ) -{ - SDL_Event event; - - TRACE("Unload Driver\n"); - - if (!deviceloop_handle) - return; - - quit_event = pSDL_RegisterEvents(1); - if (quit_event == -1) { - ERR("error registering quit event\n"); - return; - } - - event.type = quit_event; - if (pSDL_PushEvent(&event) != 1) { - ERR("error pushing quit event\n"); - return; - } - - WaitForSingleObject(deviceloop_handle, INFINITE); - CloseHandle(deviceloop_handle); - dlclose(sdl_handle); -} + static const WCHAR controller_modeW[] = {'M','a','p',' ','C','o','n','t','r','o','l','l','e','r','s',0}; + static const UNICODE_STRING controller_mode = {sizeof(controller_modeW) - sizeof(WCHAR), sizeof(controller_modeW), (WCHAR*)controller_modeW};
-static BOOL sdl_initialize(void) -{ if (!(sdl_handle = dlopen(SONAME_LIBSDL2, RTLD_NOW))) { WARN("could not load %s\n", SONAME_LIBSDL2); - return FALSE; + return STATUS_UNSUCCESSFUL; } #define LOAD_FUNCPTR(f) \ if ((p##f = dlsym(sdl_handle, #f)) == NULL) \ @@ -1000,63 +946,85 @@ static BOOL sdl_initialize(void) pSDL_JoystickGetProduct = dlsym(sdl_handle, "SDL_JoystickGetProduct"); pSDL_JoystickGetProductVersion = dlsym(sdl_handle, "SDL_JoystickGetProductVersion"); pSDL_JoystickGetVendor = dlsym(sdl_handle, "SDL_JoystickGetVendor"); - return TRUE; + + if (pSDL_Init(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) < 0) + { + ERR("could not init SDL: %s\n", pSDL_GetError()); + goto failed; + } + + if ((quit_event = pSDL_RegisterEvents(1)) == -1) + { + ERR("error registering quit event\n"); + goto failed; + } + + pSDL_JoystickEventState(SDL_ENABLE); + pSDL_GameControllerEventState(SDL_ENABLE); + + map_controllers = check_bus_option(&controller_mode, 1); + + /* Process mappings */ + if (pSDL_GameControllerAddMapping != NULL) sdl_load_mappings(); + + return STATUS_SUCCESS;
failed: dlclose(sdl_handle); sdl_handle = NULL; - return FALSE; + return STATUS_UNSUCCESSFUL; }
-NTSTATUS sdl_driver_init(void) +NTSTATUS sdl_bus_wait(void *args) { - static const WCHAR controller_modeW[] = {'M','a','p',' ','C','o','n','t','r','o','l','l','e','r','s',0}; - static const UNICODE_STRING controller_mode = {sizeof(controller_modeW) - sizeof(WCHAR), sizeof(controller_modeW), (WCHAR*)controller_modeW}; + SDL_Event event;
- HANDLE events[2]; - DWORD result; + do + { + if (pSDL_WaitEvent(&event) != 0) process_device_event(&event); + else WARN("SDL_WaitEvent failed: %s\n", pSDL_GetError()); + } while (event.type != quit_event);
- if (!sdl_handle && !sdl_initialize()) return STATUS_UNSUCCESSFUL; + TRACE("SDL main loop exiting\n"); + dlclose(sdl_handle); + sdl_handle = NULL; + return STATUS_SUCCESS; +}
- map_controllers = check_bus_option(&controller_mode, 1); +NTSTATUS sdl_bus_stop(void *args) +{ + SDL_Event event;
- if (!(events[0] = CreateEventW(NULL, TRUE, FALSE, NULL))) - { - WARN("CreateEvent failed\n"); - return STATUS_UNSUCCESSFUL; - } - if (!(events[1] = CreateThread(NULL, 0, deviceloop_thread, events[0], 0, NULL))) - { - WARN("CreateThread failed\n"); - CloseHandle(events[0]); - return STATUS_UNSUCCESSFUL; - } + if (!sdl_handle) return STATUS_SUCCESS;
- result = WaitForMultipleObjects(2, events, FALSE, INFINITE); - CloseHandle(events[0]); - if (result == WAIT_OBJECT_0) + event.type = quit_event; + if (pSDL_PushEvent(&event) != 1) { - TRACE("Initialization successful\n"); - deviceloop_handle = events[1]; - return STATUS_SUCCESS; + ERR("error pushing quit event\n"); + return STATUS_UNSUCCESSFUL; } - CloseHandle(events[1]);
- dlclose(sdl_handle); - sdl_handle = NULL; - return STATUS_UNSUCCESSFUL; + return STATUS_SUCCESS; }
#else
-NTSTATUS sdl_driver_init(void) +NTSTATUS sdl_bus_init(void *args) { + WARN("SDL support not compiled in!\n"); return STATUS_NOT_IMPLEMENTED; }
-void sdl_driver_unload( void ) +NTSTATUS sdl_bus_wait(void *args) { - TRACE("Stub: Unload Driver\n"); + WARN("SDL support not compiled in!\n"); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS sdl_bus_stop(void *args) +{ + WARN("SDL support not compiled in!\n"); + return STATUS_NOT_IMPLEMENTED; }
#endif /* SONAME_LIBSDL2 */ diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c index e372ec6db3f..6be5e677bba 100644 --- a/dlls/winebus.sys/main.c +++ b/dlls/winebus.sys/main.c @@ -618,6 +618,74 @@ static void keyboard_device_create(void) IoInvalidateDeviceRelations(bus_pdo, BusRelations); }
+static DWORD bus_count; +static HANDLE bus_thread[16]; + +struct bus_main_params +{ + const WCHAR *name; + + HANDLE init_done; + NTSTATUS (*init_func)(void *args); + + NTSTATUS (*wait_func)(void *args); +}; + +static DWORD CALLBACK bus_main_thread(void *args) +{ + struct bus_main_params bus = *(struct bus_main_params *)args; + NTSTATUS status; + + TRACE("%s main loop starting\n", debugstr_w(bus.name)); + status = bus.init_func(NULL); + SetEvent(bus.init_done); + TRACE("%s main loop started\n", debugstr_w(bus.name)); + + if (status) WARN("%s bus init returned status %#x\n", debugstr_w(bus.name), status); + else status = bus.wait_func(NULL); + + if (status) WARN("%s bus wait returned status %#x\n", debugstr_w(bus.name), status); + else TRACE("%s main loop exited\n", debugstr_w(bus.name)); + return status; +} + +static NTSTATUS bus_main_thread_start(struct bus_main_params *bus) +{ + DWORD i = bus_count++; + + if (!(bus->init_done = CreateEventW(NULL, FALSE, FALSE, NULL))) + { + ERR("failed to create %s bus init done event.\n", debugstr_w(bus->name)); + bus_count--; + return STATUS_UNSUCCESSFUL; + } + + if (!(bus_thread[i] = CreateThread(NULL, 0, bus_main_thread, bus, 0, NULL))) + { + ERR("failed to create %s bus thread.\n", debugstr_w(bus->name)); + CloseHandle(bus->init_done); + bus_count--; + return STATUS_UNSUCCESSFUL; + } + + WaitForSingleObject(bus->init_done, INFINITE); + CloseHandle(bus->init_done); + return STATUS_SUCCESS; +} + +static NTSTATUS sdl_driver_init(void) +{ + static const WCHAR bus_name[] = {'S','D','L',0}; + struct bus_main_params bus = + { + .name = bus_name, + .init_func = sdl_bus_init, + .wait_func = sdl_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}; @@ -634,16 +702,12 @@ static NTSTATUS fdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp) mouse_device_create(); keyboard_device_create();
- if (check_bus_option(&SDL_enabled, 1)) + if (!check_bus_option(&SDL_enabled, 1) || sdl_driver_init()) { - if (sdl_driver_init() == STATUS_SUCCESS) - { - irp->IoStatus.Status = STATUS_SUCCESS; - break; - } + udev_driver_init(); + iohid_driver_init(); } - udev_driver_init(); - iohid_driver_init(); + irp->IoStatus.Status = STATUS_SUCCESS; break; case IRP_MN_SURPRISE_REMOVAL: @@ -652,7 +716,10 @@ static NTSTATUS fdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp) case IRP_MN_REMOVE_DEVICE: udev_driver_unload(); iohid_driver_unload(); - sdl_driver_unload(); + sdl_bus_stop(NULL); + + WaitForMultipleObjects(bus_count, bus_thread, TRUE, INFINITE); + while (bus_count--) CloseHandle(bus_thread[bus_count]);
irp->IoStatus.Status = STATUS_SUCCESS; IoSkipCurrentIrpStackLocation(irp);
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]);
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/bus.h | 7 +++-- dlls/winebus.sys/bus_iohid.c | 59 +++++++++++++++++------------------- dlls/winebus.sys/main.c | 15 ++++++++- 3 files changed, 46 insertions(+), 35 deletions(-)
diff --git a/dlls/winebus.sys/bus.h b/dlls/winebus.sys/bus.h index 6dc95a5b803..cecde2aa83c 100644 --- a/dlls/winebus.sys/bus.h +++ b/dlls/winebus.sys/bus.h @@ -28,9 +28,6 @@ typedef int(*enum_func)(DEVICE_OBJECT *device, void *context);
/* Buses */ -NTSTATUS iohid_driver_init(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; @@ -39,6 +36,10 @@ extern NTSTATUS udev_bus_init(void *) DECLSPEC_HIDDEN; extern NTSTATUS udev_bus_wait(void *) DECLSPEC_HIDDEN; extern NTSTATUS udev_bus_stop(void *) DECLSPEC_HIDDEN;
+extern NTSTATUS iohid_bus_init(void *) DECLSPEC_HIDDEN; +extern NTSTATUS iohid_bus_wait(void *) DECLSPEC_HIDDEN; +extern NTSTATUS iohid_bus_stop(void *) DECLSPEC_HIDDEN; + /* Native device function table */ typedef struct { diff --git a/dlls/winebus.sys/bus_iohid.c b/dlls/winebus.sys/bus_iohid.c index 4eb0ea0e4b3..49774dd0662 100644 --- a/dlls/winebus.sys/bus_iohid.c +++ b/dlls/winebus.sys/bus_iohid.c @@ -96,7 +96,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(plugplay);
static IOHIDManagerRef hid_manager; static CFRunLoopRef run_loop; -static HANDLE run_loop_handle;
static const WCHAR busidW[] = {'I','O','H','I','D',0};
@@ -385,63 +384,61 @@ static void handle_RemovalCallback(void *context, IOReturn result, void *sender, } }
-/* This puts the relevant run loop for event handling into a WINE thread */ -static DWORD CALLBACK runloop_thread(void *args) +NTSTATUS iohid_bus_init(void *args) { + if (!(hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, 0L))) + { + ERR("IOHID manager creation failed\n"); + return STATUS_UNSUCCESSFUL; + } + run_loop = CFRunLoopGetCurrent();
IOHIDManagerSetDeviceMatching(hid_manager, NULL); IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, handle_DeviceMatchingCallback, NULL); IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, handle_RemovalCallback, NULL); IOHIDManagerScheduleWithRunLoop(hid_manager, run_loop, kCFRunLoopDefaultMode); - - CFRunLoopRun(); - TRACE("Run Loop exiting\n"); - return 1; - + return STATUS_SUCCESS; }
-NTSTATUS iohid_driver_init(void) +NTSTATUS iohid_bus_wait(void *args) { - hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, 0L); - if (!(run_loop_handle = CreateThread(NULL, 0, runloop_thread, NULL, 0, NULL))) - { - ERR("Failed to initialize IOHID Manager thread\n"); - CFRelease(hid_manager); - return STATUS_UNSUCCESSFUL; - } + CFRunLoopRun();
- TRACE("Initialization successful\n"); + TRACE("IOHID main loop exiting\n"); + IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, NULL, NULL); + IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, NULL, NULL); + CFRelease(hid_manager); return STATUS_SUCCESS; }
-void iohid_driver_unload( void ) +NTSTATUS iohid_bus_stop(void *args) { - TRACE("Unloading Driver\n"); - - if (!run_loop_handle) - return; + if (!run_loop) return STATUS_SUCCESS;
IOHIDManagerUnscheduleFromRunLoop(hid_manager, run_loop, kCFRunLoopDefaultMode); CFRunLoopStop(run_loop); - WaitForSingleObject(run_loop_handle, INFINITE); - CloseHandle(run_loop_handle); - IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, NULL, NULL); - IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, NULL, NULL); - CFRelease(hid_manager); - TRACE("Driver Unloaded\n"); + return STATUS_SUCCESS; }
#else
-NTSTATUS iohid_driver_init(void) +NTSTATUS iohid_bus_init(void *args) +{ + WARN("IOHID support not compiled in!\n"); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS iohid_bus_wait(void *args) { + WARN("IOHID support not compiled in!\n"); return STATUS_NOT_IMPLEMENTED; }
-void iohid_driver_unload( void ) +NTSTATUS iohid_bus_stop(void *args) { - TRACE("Stub: Unload Driver\n"); + WARN("IOHID support not compiled in!\n"); + return STATUS_NOT_IMPLEMENTED; }
#endif /* HAVE_IOHIDMANAGERCREATE */ diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c index 505fc131be4..9d57a0c4db2 100644 --- a/dlls/winebus.sys/main.c +++ b/dlls/winebus.sys/main.c @@ -699,6 +699,19 @@ static NTSTATUS udev_driver_init(void) return bus_main_thread_start(&bus); }
+static NTSTATUS iohid_driver_init(void) +{ + static const WCHAR bus_name[] = {'I','O','H','I','D'}; + struct bus_main_params bus = + { + .name = bus_name, + .init_func = iohid_bus_init, + .wait_func = iohid_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}; @@ -727,9 +740,9 @@ static NTSTATUS fdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp) irp->IoStatus.Status = STATUS_SUCCESS; break; case IRP_MN_REMOVE_DEVICE: - iohid_driver_unload(); sdl_bus_stop(NULL); udev_bus_stop(NULL); + iohid_bus_stop(NULL);
WaitForMultipleObjects(bus_count, bus_thread, TRUE, INFINITE); while (bus_count--) CloseHandle(bus_thread[bus_count]);
And use it for bus entry points.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/Makefile.in | 3 ++- dlls/winebus.sys/bus.h | 13 --------- dlls/winebus.sys/bus_iohid.c | 1 + dlls/winebus.sys/bus_sdl.c | 1 + dlls/winebus.sys/bus_udev.c | 1 + dlls/winebus.sys/main.c | 34 ++++++++++++++---------- dlls/winebus.sys/unix_private.h | 42 +++++++++++++++++++++++++++++ dlls/winebus.sys/unixlib.c | 44 ++++++++++++++++++++++++++++++ dlls/winebus.sys/unixlib.h | 47 +++++++++++++++++++++++++++++++++ 9 files changed, 158 insertions(+), 28 deletions(-) create mode 100644 dlls/winebus.sys/unix_private.h create mode 100644 dlls/winebus.sys/unixlib.c create mode 100644 dlls/winebus.sys/unixlib.h
diff --git a/dlls/winebus.sys/Makefile.in b/dlls/winebus.sys/Makefile.in index 8cde3c7b422..658d27b70fd 100644 --- a/dlls/winebus.sys/Makefile.in +++ b/dlls/winebus.sys/Makefile.in @@ -9,6 +9,7 @@ C_SRCS = \ bus_sdl.c \ bus_udev.c \ hid.c \ - main.c + main.c \ + unixlib.c
RC_SRCS = winebus.rc diff --git a/dlls/winebus.sys/bus.h b/dlls/winebus.sys/bus.h index cecde2aa83c..a3e84bf8bd8 100644 --- a/dlls/winebus.sys/bus.h +++ b/dlls/winebus.sys/bus.h @@ -27,19 +27,6 @@
typedef int(*enum_func)(DEVICE_OBJECT *device, void *context);
-/* Buses */ -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; - -extern NTSTATUS iohid_bus_init(void *) DECLSPEC_HIDDEN; -extern NTSTATUS iohid_bus_wait(void *) DECLSPEC_HIDDEN; -extern NTSTATUS iohid_bus_stop(void *) DECLSPEC_HIDDEN; - /* Native device function table */ typedef struct { diff --git a/dlls/winebus.sys/bus_iohid.c b/dlls/winebus.sys/bus_iohid.c index 49774dd0662..f1fe34e1780 100644 --- a/dlls/winebus.sys/bus_iohid.c +++ b/dlls/winebus.sys/bus_iohid.c @@ -90,6 +90,7 @@ #include "wine/debug.h"
#include "bus.h" +#include "unix_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(plugplay); #ifdef HAVE_IOHIDMANAGERCREATE diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index 02509f1560c..cf81120c2f9 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -51,6 +51,7 @@ #endif
#include "bus.h" +#include "unix_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(plugplay);
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index 67d00670a26..a4b20f3efae 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);
diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c index 9d57a0c4db2..b678e86bc8b 100644 --- a/dlls/winebus.sys/main.c +++ b/dlls/winebus.sys/main.c @@ -32,8 +32,10 @@ #include "wine/debug.h" #include "wine/unicode.h" #include "wine/list.h" +#include "wine/unixlib.h"
#include "bus.h" +#include "unixlib.h"
WINE_DEFAULT_DEBUG_CHANNEL(plugplay); WINE_DECLARE_DEBUG_CHANNEL(hid_report); @@ -155,6 +157,11 @@ static const WCHAR zero_serialW[]= {'0','0','0','0',0}; static const WCHAR miW[] = {'M','I',0}; static const WCHAR igW[] = {'I','G',0};
+static NTSTATUS winebus_call(unsigned int code, void *args) +{ + return __wine_unix_call_funcs[code]( args ); +} + static inline WCHAR *strdupW(const WCHAR *src) { WCHAR *dst; @@ -626,9 +633,8 @@ struct bus_main_params const WCHAR *name;
HANDLE init_done; - NTSTATUS (*init_func)(void *args); - - NTSTATUS (*wait_func)(void *args); + unsigned int init_code; + unsigned int wait_code; };
static DWORD CALLBACK bus_main_thread(void *args) @@ -637,12 +643,12 @@ static DWORD CALLBACK bus_main_thread(void *args) NTSTATUS status;
TRACE("%s main loop starting\n", debugstr_w(bus.name)); - status = bus.init_func(NULL); + status = winebus_call(bus.init_code, NULL); SetEvent(bus.init_done); TRACE("%s main loop started\n", debugstr_w(bus.name));
if (status) WARN("%s bus init returned status %#x\n", debugstr_w(bus.name), status); - else status = bus.wait_func(NULL); + else status = winebus_call(bus.wait_code, NULL);
if (status) WARN("%s bus wait returned status %#x\n", debugstr_w(bus.name), status); else TRACE("%s main loop exited\n", debugstr_w(bus.name)); @@ -679,8 +685,8 @@ static NTSTATUS sdl_driver_init(void) struct bus_main_params bus = { .name = bus_name, - .init_func = sdl_bus_init, - .wait_func = sdl_bus_wait, + .init_code = sdl_init, + .wait_code = sdl_wait, };
return bus_main_thread_start(&bus); @@ -692,8 +698,8 @@ static NTSTATUS udev_driver_init(void) struct bus_main_params bus = { .name = bus_name, - .init_func = udev_bus_init, - .wait_func = udev_bus_wait, + .init_code = udev_init, + .wait_code = udev_wait, };
return bus_main_thread_start(&bus); @@ -705,8 +711,8 @@ static NTSTATUS iohid_driver_init(void) struct bus_main_params bus = { .name = bus_name, - .init_func = iohid_bus_init, - .wait_func = iohid_bus_wait, + .init_code = iohid_init, + .wait_code = iohid_wait, };
return bus_main_thread_start(&bus); @@ -740,9 +746,9 @@ static NTSTATUS fdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp) irp->IoStatus.Status = STATUS_SUCCESS; break; case IRP_MN_REMOVE_DEVICE: - sdl_bus_stop(NULL); - udev_bus_stop(NULL); - iohid_bus_stop(NULL); + winebus_call(sdl_stop, NULL); + winebus_call(udev_stop, NULL); + winebus_call(iohid_stop, NULL);
WaitForMultipleObjects(bus_count, bus_thread, TRUE, INFINITE); while (bus_count--) CloseHandle(bus_thread[bus_count]); diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h new file mode 100644 index 00000000000..9468cac45e9 --- /dev/null +++ b/dlls/winebus.sys/unix_private.h @@ -0,0 +1,42 @@ +/* + * Copyright 2021 Rémi Bernon for CodeWeavers + * + * 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 + */ + +#ifndef __WINEBUS_UNIX_PRIVATE_H +#define __WINEBUS_UNIX_PRIVATE_H + +#include <stdarg.h> + +#include <windef.h> +#include <winbase.h> +#include <winternl.h> + +#include "unixlib.h" + +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; + +extern NTSTATUS iohid_bus_init(void *) DECLSPEC_HIDDEN; +extern NTSTATUS iohid_bus_wait(void *) DECLSPEC_HIDDEN; +extern NTSTATUS iohid_bus_stop(void *) DECLSPEC_HIDDEN; + +#endif /* __WINEBUS_UNIX_PRIVATE_H */ diff --git a/dlls/winebus.sys/unixlib.c b/dlls/winebus.sys/unixlib.c new file mode 100644 index 00000000000..c4090861675 --- /dev/null +++ b/dlls/winebus.sys/unixlib.c @@ -0,0 +1,44 @@ +/* + * Copyright 2021 Rémi Bernon for CodeWeavers + * + * 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 "config.h" + +#include <stdarg.h> +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winternl.h" + +#include "wine/debug.h" +#include "wine/unixlib.h" + +#include "unix_private.h" + +const unixlib_entry_t __wine_unix_call_funcs[] = +{ + sdl_bus_init, + sdl_bus_wait, + sdl_bus_stop, + udev_bus_init, + udev_bus_wait, + udev_bus_stop, + iohid_bus_init, + iohid_bus_wait, + iohid_bus_stop, +}; diff --git a/dlls/winebus.sys/unixlib.h b/dlls/winebus.sys/unixlib.h new file mode 100644 index 00000000000..51765f2f2d6 --- /dev/null +++ b/dlls/winebus.sys/unixlib.h @@ -0,0 +1,47 @@ +/* + * Copyright 2021 Rémi Bernon for CodeWeavers + * + * 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 + */ + +#ifndef __WINEBUS_UNIXLIB_H +#define __WINEBUS_UNIXLIB_H + +#include <stdarg.h> + +#include <windef.h> +#include <winbase.h> +#include <winternl.h> +#include <ddk/wdm.h> +#include <hidusage.h> + +#include "wine/unixlib.h" + +enum unix_funcs +{ + sdl_init, + sdl_wait, + sdl_stop, + udev_init, + udev_wait, + udev_stop, + iohid_init, + iohid_wait, + iohid_stop, +}; + +extern const unixlib_entry_t __wine_unix_call_funcs[] DECLSPEC_HIDDEN; + +#endif /* __WINEBUS_UNIXLIB_H */
FWIW, in case this needs a bit more context, the idea here is to ultimately have the "unix buses" work in a single thread each, and pass a pre-allocated "bus event" to the unix side with each "bus wait" call.
On return, the event (device creation, removal, or input report) will be processed on the Win32 side, and passed again to the next wait call for unix side cleanup, and to get the next event.
The device vtable will also go through the unixlib interface, to notify unix side of device start / remove, get their report descriptor and handle output and feature reports.
And pass them to bus_init function.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/bus.h | 1 - dlls/winebus.sys/bus_iohid.c | 5 ++++ dlls/winebus.sys/bus_sdl.c | 12 ++++----- dlls/winebus.sys/bus_udev.c | 28 ++++++------------- dlls/winebus.sys/main.c | 52 +++++++++++++++++++++++++----------- dlls/winebus.sys/unixlib.h | 15 +++++++++++ 6 files changed, 69 insertions(+), 44 deletions(-)
diff --git a/dlls/winebus.sys/bus.h b/dlls/winebus.sys/bus.h index a3e84bf8bd8..1e4f37ae896 100644 --- a/dlls/winebus.sys/bus.h +++ b/dlls/winebus.sys/bus.h @@ -52,7 +52,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_iohid.c b/dlls/winebus.sys/bus_iohid.c index f1fe34e1780..18d9dc2dbe9 100644 --- a/dlls/winebus.sys/bus_iohid.c +++ b/dlls/winebus.sys/bus_iohid.c @@ -99,6 +99,7 @@ static IOHIDManagerRef hid_manager; static CFRunLoopRef run_loop;
static const WCHAR busidW[] = {'I','O','H','I','D',0}; +static struct iohid_bus_options options;
struct platform_private { @@ -387,6 +388,10 @@ static void handle_RemovalCallback(void *context, IOReturn result, void *sender,
NTSTATUS iohid_bus_init(void *args) { + TRACE("args %p\n", args); + + options = *(struct iohid_bus_options *)args; + if (!(hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, 0L))) { ERR("IOHID manager creation failed\n"); diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index cf81120c2f9..cc0bafa89ba 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -60,8 +60,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(plugplay); WINE_DECLARE_DEBUG_CHANNEL(hid_report);
static const WCHAR sdl_busidW[] = {'S','D','L','J','O','Y',0}; - -static DWORD map_controllers = 0; +static struct sdl_bus_options options;
static void *sdl_handle = NULL; static UINT quit_event = -1; @@ -748,7 +747,7 @@ static void try_add_device(unsigned int index) return; }
- if (map_controllers && pSDL_IsGameController(index)) + if (options.map_controllers && pSDL_IsGameController(index)) controller = pSDL_GameControllerOpen(index);
id = pSDL_JoystickInstanceID(joystick); @@ -891,8 +890,9 @@ static void sdl_load_mappings(void)
NTSTATUS sdl_bus_init(void *args) { - static const WCHAR controller_modeW[] = {'M','a','p',' ','C','o','n','t','r','o','l','l','e','r','s',0}; - static const UNICODE_STRING controller_mode = {sizeof(controller_modeW) - sizeof(WCHAR), sizeof(controller_modeW), (WCHAR*)controller_modeW}; + TRACE("args %p\n", args); + + options = *(struct sdl_bus_options *)args;
if (!(sdl_handle = dlopen(SONAME_LIBSDL2, RTLD_NOW))) { @@ -963,8 +963,6 @@ NTSTATUS sdl_bus_init(void *args) pSDL_JoystickEventState(SDL_ENABLE); pSDL_GameControllerEventState(SDL_ENABLE);
- map_controllers = check_bus_option(&controller_mode, 1); - /* Process mappings */ if (pSDL_GameControllerAddMapping != NULL) sdl_load_mappings();
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index a4b20f3efae..953d1d9436c 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -90,13 +90,12 @@ 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 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}; +static struct udev_bus_options options;
struct platform_private { @@ -1181,11 +1180,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"); @@ -1224,7 +1223,7 @@ static struct udev_monitor *create_monitor(int *fd) 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"); @@ -1232,7 +1231,7 @@ static struct udev_monitor *create_monitor(int *fd) 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"); @@ -1288,10 +1287,9 @@ static void process_monitor_event(struct udev_monitor *monitor)
NTSTATUS udev_bus_init(void *args) { - 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) { @@ -1305,16 +1303,6 @@ NTSTATUS udev_bus_init(void *args) goto error; }
- 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 (!(udev_monitor = create_monitor(&udev_monitor_fd))) { ERR("UDEV monitor creation failed\n"); diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c index b678e86bc8b..466cf29107a 100644 --- a/dlls/winebus.sys/main.c +++ b/dlls/winebus.sys/main.c @@ -411,6 +411,20 @@ static NTSTATUS build_device_relations(DEVICE_RELATIONS **devices) return STATUS_SUCCESS; }
+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; + DWORD size; + + if (NtQueryValueKey(driver_key, option, KeyValuePartialInformation, info, sizeof(buffer), &size) == STATUS_SUCCESS) + { + if (info->Type == REG_DWORD) return *(DWORD *)info->Data; + } + + return default_value; +} + static NTSTATUS handle_IRP_MN_QUERY_DEVICE_RELATIONS(IRP *irp) { NTSTATUS status = irp->IoStatus.Status; @@ -632,6 +646,7 @@ struct bus_main_params { const WCHAR *name;
+ void *init_args; HANDLE init_done; unsigned int init_code; unsigned int wait_code; @@ -643,7 +658,7 @@ static DWORD CALLBACK bus_main_thread(void *args) NTSTATUS status;
TRACE("%s main loop starting\n", debugstr_w(bus.name)); - status = winebus_call(bus.init_code, NULL); + status = winebus_call(bus.init_code, bus.init_args); SetEvent(bus.init_done); TRACE("%s main loop started\n", debugstr_w(bus.name));
@@ -682,35 +697,55 @@ static NTSTATUS bus_main_thread_start(struct bus_main_params *bus) static NTSTATUS sdl_driver_init(void) { static const WCHAR bus_name[] = {'S','D','L',0}; + static const WCHAR controller_modeW[] = {'M','a','p',' ','C','o','n','t','r','o','l','l','e','r','s',0}; + static const UNICODE_STRING controller_mode = {sizeof(controller_modeW) - sizeof(WCHAR), sizeof(controller_modeW), (WCHAR*)controller_modeW}; + struct sdl_bus_options bus_options; struct bus_main_params bus = { .name = bus_name, + .init_args = &bus_options, .init_code = sdl_init, .wait_code = sdl_wait, };
+ 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"); + return bus_main_thread_start(&bus); }
static NTSTATUS udev_driver_init(void) { static const WCHAR 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 bus_options; struct bus_main_params bus = { .name = bus_name, + .init_args = &bus_options, .init_code = udev_init, .wait_code = udev_wait, };
+ bus_options.disable_hidraw = check_bus_option(&hidraw_disabled, 0); + if (bus_options.disable_hidraw) TRACE("UDEV hidraw devices disabled in registry\n"); + bus_options.disable_input = check_bus_option(&input_disabled, 0); + if (bus_options.disable_input) TRACE("UDEV input devices disabled in registry\n"); + return bus_main_thread_start(&bus); }
static NTSTATUS iohid_driver_init(void) { static const WCHAR bus_name[] = {'I','O','H','I','D'}; + struct iohid_bus_options bus_options; struct bus_main_params bus = { .name = bus_name, + .init_args = &bus_options, .init_code = iohid_init, .wait_code = iohid_wait, }; @@ -1120,21 +1155,6 @@ void process_hid_report(DEVICE_OBJECT *device, BYTE *report, DWORD length) LeaveCriticalSection(&ext->cs); }
-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; - DWORD size; - - if (NtQueryValueKey(driver_key, option, KeyValuePartialInformation, info, sizeof(buffer), &size) == STATUS_SUCCESS) - { - if (info->Type == REG_DWORD) - return *(DWORD*)info->Data; - } - - return default_value; -} - BOOL is_xbox_gamepad(WORD vid, WORD pid) { int i; diff --git a/dlls/winebus.sys/unixlib.h b/dlls/winebus.sys/unixlib.h index 51765f2f2d6..3e84d997848 100644 --- a/dlls/winebus.sys/unixlib.h +++ b/dlls/winebus.sys/unixlib.h @@ -29,6 +29,21 @@
#include "wine/unixlib.h"
+struct sdl_bus_options +{ + BOOL map_controllers; +}; + +struct udev_bus_options +{ + BOOL disable_hidraw; + BOOL disable_input; +}; + +struct iohid_bus_options +{ +}; + enum unix_funcs { sdl_init,
And use an opaque struct unix_device as private data.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/bus.h | 8 ++++---- dlls/winebus.sys/bus_iohid.c | 23 ++++++++++++++++------- dlls/winebus.sys/bus_sdl.c | 25 ++++++++++++++++--------- dlls/winebus.sys/bus_udev.c | 31 ++++++++++++++++++++++++------- dlls/winebus.sys/main.c | 25 +++++++++++-------------- dlls/winebus.sys/unix_private.h | 4 ++++ dlls/winebus.sys/unixlib.h | 2 ++ 7 files changed, 77 insertions(+), 41 deletions(-)
diff --git a/dlls/winebus.sys/bus.h b/dlls/winebus.sys/bus.h index 1e4f37ae896..803ffaad132 100644 --- a/dlls/winebus.sys/bus.h +++ b/dlls/winebus.sys/bus.h @@ -40,12 +40,12 @@ typedef struct void (*set_feature_report)(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io); } platform_vtbl;
-void *get_platform_private(DEVICE_OBJECT *device) DECLSPEC_HIDDEN; +struct unix_device *get_unix_device(DEVICE_OBJECT *device) DECLSPEC_HIDDEN;
/* HID Plug and Play Bus */ -DEVICE_OBJECT *bus_create_hid_device(const WCHAR *busidW, WORD vid, WORD pid, - WORD input, DWORD version, DWORD uid, const WCHAR *serialW, BOOL is_gamepad, - const platform_vtbl *vtbl, DWORD platform_data_size) DECLSPEC_HIDDEN; +DEVICE_OBJECT *bus_create_hid_device(const WCHAR *busidW, WORD vid, WORD pid, WORD input, + DWORD version, DWORD uid, const WCHAR *serialW, BOOL is_gamepad, + const platform_vtbl *vtbl, struct unix_device *unix_device) DECLSPEC_HIDDEN; DEVICE_OBJECT *bus_find_hid_device(const WCHAR *bus_id, void *platform_dev) DECLSPEC_HIDDEN; void bus_unlink_hid_device(DEVICE_OBJECT *device) DECLSPEC_HIDDEN; void process_hid_report(DEVICE_OBJECT *device, BYTE *report, DWORD length) DECLSPEC_HIDDEN; diff --git a/dlls/winebus.sys/bus_iohid.c b/dlls/winebus.sys/bus_iohid.c index 18d9dc2dbe9..eb5eddd60fa 100644 --- a/dlls/winebus.sys/bus_iohid.c +++ b/dlls/winebus.sys/bus_iohid.c @@ -103,13 +103,19 @@ static struct iohid_bus_options options;
struct platform_private { + struct unix_device unix_device; IOHIDDeviceRef device; uint8_t *buffer; };
+static inline struct platform_private *impl_from_unix_device(struct unix_device *iface) +{ + return CONTAINING_RECORD(iface, struct platform_private, unix_device); +} + static inline struct platform_private *impl_from_DEVICE_OBJECT(DEVICE_OBJECT *device) { - return (struct platform_private *)get_platform_private(device); + return impl_from_unix_device(get_unix_device(device)); }
static void CFStringToWSTR(CFStringRef cstr, LPWSTR wstr, int length) @@ -137,6 +143,8 @@ static void handle_IOHIDDeviceIOHIDReportCallback(void *context,
static void free_device(DEVICE_OBJECT *device) { + struct platform_private *private = impl_from_DEVICE_OBJECT(device); + HeapFree(GetProcessHeap(), 0, private); }
static int compare_platform_device(DEVICE_OBJECT *device, void *platform_dev) @@ -285,6 +293,7 @@ static const platform_vtbl iohid_vtbl =
static void handle_DeviceMatchingCallback(void *context, IOReturn result, void *sender, IOHIDDeviceRef IOHIDDevice) { + struct platform_private *private; DEVICE_OBJECT *device; DWORD vid, pid, version, uid; CFStringRef str = NULL; @@ -355,14 +364,14 @@ static void handle_DeviceMatchingCallback(void *context, IOReturn result, void * if (is_gamepad) input = 0;
- device = bus_create_hid_device(busidW, vid, pid, input, - version, uid, str ? serial_string : NULL, is_gamepad, - &iohid_vtbl, sizeof(struct platform_private)); - if (!device) - ERR("Failed to create device\n"); + if (!(private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct platform_private)))) + return; + + device = bus_create_hid_device(busidW, vid, pid, input, version, uid, str ? serial_string : NULL, + is_gamepad, &iohid_vtbl, &private->unix_device); + if (!device) HeapFree(GetProcessHeap(), 0, private); else { - struct platform_private *private = impl_from_DEVICE_OBJECT(device); private->device = IOHIDDevice; private->buffer = NULL; IoInvalidateDeviceRelations(bus_pdo, BusRelations); diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index cc0bafa89ba..61d1240e05d 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -110,6 +110,8 @@ static Uint16 (*pSDL_JoystickGetVendor)(SDL_Joystick * joystick);
struct platform_private { + struct unix_device unix_device; + SDL_Joystick *sdl_joystick; SDL_GameController *sdl_controller; SDL_JoystickID id; @@ -128,9 +130,14 @@ struct platform_private int haptic_effect_id; };
+static inline struct platform_private *impl_from_unix_device(struct unix_device *iface) +{ + return CONTAINING_RECORD(iface, struct platform_private, unix_device); +} + static inline struct platform_private *impl_from_DEVICE_OBJECT(DEVICE_OBJECT *device) { - return (struct platform_private *)get_platform_private(device); + return impl_from_unix_device(get_unix_device(device)); }
#define CONTROLLER_NUM_BUTTONS 11 @@ -479,6 +486,8 @@ static void free_device(DEVICE_OBJECT *device) pSDL_GameControllerClose(ext->sdl_controller); if (ext->sdl_haptic) pSDL_HapticClose(ext->sdl_haptic); + + HeapFree(GetProcessHeap(), 0, ext); }
static int compare_platform_device(DEVICE_OBJECT *device, void *context) @@ -730,6 +739,7 @@ static void try_remove_device(DEVICE_OBJECT *device) static void try_add_device(unsigned int index) { DWORD vid = 0, pid = 0, version = 0; + struct platform_private *private; DEVICE_OBJECT *device = NULL; WCHAR serial[34] = {0}; char guid_str[34]; @@ -788,21 +798,18 @@ static void try_add_device(unsigned int index) if (is_xbox_gamepad) input = 0;
- device = bus_create_hid_device(sdl_busidW, vid, pid, input, version, index, - serial, is_xbox_gamepad, &sdl_vtbl, sizeof(struct platform_private)); + if (!(private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*private)))) return;
- if (device) + device = bus_create_hid_device(sdl_busidW, vid, pid, input, version, index, serial, is_xbox_gamepad, + &sdl_vtbl, &private->unix_device); + if (!device) HeapFree(GetProcessHeap(), 0, private); + else { - struct platform_private *private = impl_from_DEVICE_OBJECT(device); private->sdl_joystick = joystick; private->sdl_controller = controller; private->id = id; IoInvalidateDeviceRelations(bus_pdo, BusRelations); } - else - { - WARN("Ignoring device %i\n", id); - } }
static void process_device_event(SDL_Event *event) diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index 953d1d9436c..bd70a66f2cd 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -99,6 +99,8 @@ static struct udev_bus_options options;
struct platform_private { + struct unix_device unix_device; + struct udev_device *udev_device; int device_fd;
@@ -106,9 +108,14 @@ struct platform_private int control_pipe[2]; };
+static inline struct platform_private *impl_from_unix_device(struct unix_device *iface) +{ + return CONTAINING_RECORD(iface, struct platform_private, unix_device); +} + static inline struct platform_private *impl_from_DEVICE_OBJECT(DEVICE_OBJECT *device) { - return (struct platform_private *)get_platform_private(device); + return impl_from_unix_device(get_unix_device(device)); }
#ifdef HAS_PROPER_INPUT_HEADER @@ -550,6 +557,8 @@ static void hidraw_free_device(DEVICE_OBJECT *device)
close(private->device_fd); udev_device_unref(private->udev_device); + + HeapFree(GetProcessHeap(), 0, private); }
static int compare_platform_device(DEVICE_OBJECT *device, void *platform_dev) @@ -833,7 +842,7 @@ static const platform_vtbl hidraw_vtbl =
static inline struct wine_input_private *input_impl_from_DEVICE_OBJECT(DEVICE_OBJECT *device) { - return (struct wine_input_private*)get_platform_private(device); + return CONTAINING_RECORD(impl_from_DEVICE_OBJECT(device), struct wine_input_private, base); }
static void lnxev_free_device(DEVICE_OBJECT *device) @@ -855,6 +864,8 @@ static void lnxev_free_device(DEVICE_OBJECT *device)
close(ext->base.device_fd); udev_device_unref(ext->base.udev_device); + + HeapFree(GetProcessHeap(), 0, ext); }
static DWORD CALLBACK lnxev_device_report_thread(void *args); @@ -1050,6 +1061,7 @@ static void get_device_subsystem_info(struct udev_device *dev, char const *subsy static void try_add_device(struct udev_device *dev) { DWORD vid = 0, pid = 0, version = 0, input = -1; + struct platform_private *private; DEVICE_OBJECT *device = NULL; const char *subsystem; const char *devnode; @@ -1127,20 +1139,25 @@ static void try_add_device(struct udev_device *dev)
if (strcmp(subsystem, "hidraw") == 0) { - device = bus_create_hid_device(hidraw_busidW, vid, pid, input, version, 0, serial, is_gamepad, - &hidraw_vtbl, sizeof(struct platform_private)); + if (!(private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct platform_private)))) + return; + device = bus_create_hid_device(hidraw_busidW, vid, pid, input, version, 0, serial, + is_gamepad, &hidraw_vtbl, &private->unix_device); + if (!device) HeapFree(GetProcessHeap(), 0, private); } #ifdef HAS_PROPER_INPUT_HEADER else if (strcmp(subsystem, "input") == 0) { - device = bus_create_hid_device(lnxev_busidW, vid, pid, input, version, 0, serial, is_gamepad, - &lnxev_vtbl, sizeof(struct wine_input_private)); + if (!(private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct wine_input_private)))) + return; + device = bus_create_hid_device(lnxev_busidW, vid, pid, input, version, 0, serial, + is_gamepad, &lnxev_vtbl, &private->unix_device); + if (!device) HeapFree(GetProcessHeap(), 0, private); } #endif
if (device) { - struct platform_private *private = impl_from_DEVICE_OBJECT(device); private->udev_device = udev_device_ref(dev); private->device_fd = fd; IoInvalidateDeviceRelations(bus_pdo, BusRelations); diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c index 466cf29107a..f0e94648d4e 100644 --- a/dlls/winebus.sys/main.c +++ b/dlls/winebus.sys/main.c @@ -139,7 +139,7 @@ struct device_extension DWORD buffer_size; LIST_ENTRY irp_queue;
- BYTE platform_private[1]; + struct unix_device *unix_device; };
static CRITICAL_SECTION device_list_cs; @@ -171,10 +171,10 @@ static inline WCHAR *strdupW(const WCHAR *src) return dst; }
-void *get_platform_private(DEVICE_OBJECT *device) +struct unix_device *get_unix_device(DEVICE_OBJECT *device) { struct device_extension *ext = (struct device_extension *)device->DeviceExtension; - return ext->platform_private; + return ext->unix_device; }
static DWORD get_device_index(WORD vid, WORD pid, WORD input) @@ -260,9 +260,9 @@ static void remove_pending_irps(DEVICE_OBJECT *device) } }
-DEVICE_OBJECT *bus_create_hid_device(const WCHAR *busidW, WORD vid, WORD pid, - WORD input, DWORD version, DWORD uid, const WCHAR *serialW, BOOL is_gamepad, - const platform_vtbl *vtbl, DWORD platform_data_size) +DEVICE_OBJECT *bus_create_hid_device(const WCHAR *busidW, WORD vid, WORD pid, WORD input, + DWORD version, DWORD uid, const WCHAR *serialW, BOOL is_gamepad, + const platform_vtbl *vtbl, struct unix_device *unix_device) { static const WCHAR device_name_fmtW[] = {'\','D','e','v','i','c','e','\','%','s','#','%','p',0}; struct device_extension *ext; @@ -271,19 +271,17 @@ DEVICE_OBJECT *bus_create_hid_device(const WCHAR *busidW, WORD vid, WORD pid, UNICODE_STRING nameW; WCHAR dev_name[256]; NTSTATUS status; - DWORD length;
- TRACE("(%s, %04x, %04x, %04x, %u, %u, %s, %u, %p, %u)\n", - debugstr_w(busidW), vid, pid, input, version, uid, debugstr_w(serialW), - is_gamepad, vtbl, platform_data_size); + TRACE("bus_id %s, vid %04x, pid %04x, input %04x, version %u, uid %u, serial %s, " + "is_gamepad %u, vtbl %p, unix_device %p\n", debugstr_w(busidW), vid, pid, input, + version, uid, debugstr_w(serialW), is_gamepad, vtbl, unix_device);
if (!(pnp_dev = HeapAlloc(GetProcessHeap(), 0, sizeof(*pnp_dev)))) return NULL;
sprintfW(dev_name, device_name_fmtW, busidW, pnp_dev); RtlInitUnicodeString(&nameW, dev_name); - length = FIELD_OFFSET(struct device_extension, platform_private[platform_data_size]); - status = IoCreateDevice(driver_obj, length, &nameW, 0, 0, FALSE, &device); + status = IoCreateDevice(driver_obj, sizeof(struct device_extension), &nameW, 0, 0, FALSE, &device); if (status) { FIXME("failed to create device error %x\n", status); @@ -310,8 +308,7 @@ DEVICE_OBJECT *bus_create_hid_device(const WCHAR *busidW, WORD vid, WORD pid, ext->last_report_size = 0; ext->last_report_read = TRUE; ext->buffer_size = 0; - - memset(ext->platform_private, 0, platform_data_size); + ext->unix_device = unix_device;
InitializeListHead(&ext->irp_queue); InitializeCriticalSection(&ext->cs); diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h index 9468cac45e9..aff1e86263a 100644 --- a/dlls/winebus.sys/unix_private.h +++ b/dlls/winebus.sys/unix_private.h @@ -27,6 +27,10 @@
#include "unixlib.h"
+struct unix_device +{ +}; + extern NTSTATUS sdl_bus_init(void *) DECLSPEC_HIDDEN; extern NTSTATUS sdl_bus_wait(void *) DECLSPEC_HIDDEN; extern NTSTATUS sdl_bus_stop(void *) DECLSPEC_HIDDEN; diff --git a/dlls/winebus.sys/unixlib.h b/dlls/winebus.sys/unixlib.h index 3e84d997848..c0de991d20a 100644 --- a/dlls/winebus.sys/unixlib.h +++ b/dlls/winebus.sys/unixlib.h @@ -44,6 +44,8 @@ struct iohid_bus_options { };
+struct unix_device; + enum unix_funcs { sdl_init,
Instead of a separately allocated device list entry pointer. And link the device object into the device list directly.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/main.c | 69 ++++++++++++++--------------------------- 1 file changed, 23 insertions(+), 46 deletions(-)
diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c index f0e94648d4e..41aef8ab018 100644 --- a/dlls/winebus.sys/main.c +++ b/dlls/winebus.sys/main.c @@ -105,12 +105,6 @@ static DEVICE_OBJECT *bus_fdo;
HANDLE driver_key;
-struct pnp_device -{ - struct list entry; - DEVICE_OBJECT *device; -}; - enum device_state { DEVICE_STATE_STOPPED, @@ -120,11 +114,12 @@ enum device_state
struct device_extension { + struct list entry; + DEVICE_OBJECT *device; + CRITICAL_SECTION cs; enum device_state state;
- struct pnp_device *pnp_device; - WORD vid, pid, input; DWORD uid, version, index; BOOL is_gamepad; @@ -151,7 +146,7 @@ static CRITICAL_SECTION_DEBUG critsect_debug = }; static CRITICAL_SECTION device_list_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
-static struct list pnp_devset = LIST_INIT(pnp_devset); +static struct list device_list = LIST_INIT(device_list);
static const WCHAR zero_serialW[]= {'0','0','0','0',0}; static const WCHAR miW[] = {'M','I',0}; @@ -179,12 +174,11 @@ struct unix_device *get_unix_device(DEVICE_OBJECT *device)
static DWORD get_device_index(WORD vid, WORD pid, WORD input) { - struct pnp_device *ptr; + struct device_extension *ext; DWORD index = 0;
- LIST_FOR_EACH_ENTRY(ptr, &pnp_devset, struct pnp_device, entry) + LIST_FOR_EACH_ENTRY(ext, &device_list, struct device_extension, entry) { - struct device_extension *ext = (struct device_extension *)ptr->device->DeviceExtension; if (ext->vid == vid && ext->pid == pid && ext->input == input) index = max(ext->index + 1, index); } @@ -266,7 +260,6 @@ DEVICE_OBJECT *bus_create_hid_device(const WCHAR *busidW, WORD vid, WORD pid, WO { static const WCHAR device_name_fmtW[] = {'\','D','e','v','i','c','e','\','%','s','#','%','p',0}; struct device_extension *ext; - struct pnp_device *pnp_dev; DEVICE_OBJECT *device; UNICODE_STRING nameW; WCHAR dev_name[256]; @@ -276,16 +269,12 @@ DEVICE_OBJECT *bus_create_hid_device(const WCHAR *busidW, WORD vid, WORD pid, WO "is_gamepad %u, vtbl %p, unix_device %p\n", debugstr_w(busidW), vid, pid, input, version, uid, debugstr_w(serialW), is_gamepad, vtbl, unix_device);
- if (!(pnp_dev = HeapAlloc(GetProcessHeap(), 0, sizeof(*pnp_dev)))) - return NULL; - - sprintfW(dev_name, device_name_fmtW, busidW, pnp_dev); + sprintfW(dev_name, device_name_fmtW, busidW, unix_device); RtlInitUnicodeString(&nameW, dev_name); status = IoCreateDevice(driver_obj, sizeof(struct device_extension), &nameW, 0, 0, FALSE, &device); if (status) { FIXME("failed to create device error %x\n", status); - HeapFree(GetProcessHeap(), 0, pnp_dev); return NULL; }
@@ -293,7 +282,7 @@ DEVICE_OBJECT *bus_create_hid_device(const WCHAR *busidW, WORD vid, WORD pid, WO
/* fill out device_extension struct */ ext = (struct device_extension *)device->DeviceExtension; - ext->pnp_device = pnp_dev; + ext->device = device; ext->vid = vid; ext->pid = pid; ext->input = input; @@ -315,8 +304,7 @@ DEVICE_OBJECT *bus_create_hid_device(const WCHAR *busidW, WORD vid, WORD pid, WO ext->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": cs");
/* add to list of pnp devices */ - pnp_dev->device = device; - list_add_tail(&pnp_devset, &pnp_dev->entry); + list_add_tail(&device_list, &ext->entry);
LeaveCriticalSection(&device_list_cs); return device; @@ -324,19 +312,18 @@ DEVICE_OBJECT *bus_create_hid_device(const WCHAR *busidW, WORD vid, WORD pid, WO
DEVICE_OBJECT *bus_find_hid_device(const WCHAR *bus_id, void *platform_dev) { - struct pnp_device *dev; + struct device_extension *ext; DEVICE_OBJECT *ret = NULL;
TRACE("bus_id %s, platform_dev %p\n", debugstr_w(bus_id), platform_dev);
EnterCriticalSection(&device_list_cs); - LIST_FOR_EACH_ENTRY(dev, &pnp_devset, struct pnp_device, entry) + LIST_FOR_EACH_ENTRY(ext, &device_list, struct device_extension, entry) { - struct device_extension *ext = (struct device_extension *)dev->device->DeviceExtension; if (strcmpW(ext->busid, bus_id)) continue; - if (ext->vtbl->compare_platform_device(dev->device, platform_dev) == 0) + if (ext->vtbl->compare_platform_device(ext->device, platform_dev) == 0) { - ret = dev->device; + ret = ext->device; break; } } @@ -348,23 +335,22 @@ DEVICE_OBJECT *bus_find_hid_device(const WCHAR *bus_id, void *platform_dev)
DEVICE_OBJECT *bus_enumerate_hid_devices(const WCHAR *bus_id, enum_func function, void *context) { - struct pnp_device *dev, *dev_next; + struct device_extension *ext, *next; DEVICE_OBJECT *ret = NULL; int cont;
TRACE("bus_id %p\n", debugstr_w(bus_id));
EnterCriticalSection(&device_list_cs); - LIST_FOR_EACH_ENTRY_SAFE(dev, dev_next, &pnp_devset, struct pnp_device, entry) + LIST_FOR_EACH_ENTRY_SAFE(ext, next, &device_list, struct device_extension, entry) { - struct device_extension *ext = (struct device_extension *)dev->device->DeviceExtension; if (strcmpW(ext->busid, bus_id)) continue; LeaveCriticalSection(&device_list_cs); - cont = function(dev->device, context); + cont = function(ext->device, context); EnterCriticalSection(&device_list_cs); if (!cont) { - ret = dev->device; + ret = ext->device; break; } } @@ -375,20 +361,19 @@ DEVICE_OBJECT *bus_enumerate_hid_devices(const WCHAR *bus_id, enum_func function void bus_unlink_hid_device(DEVICE_OBJECT *device) { struct device_extension *ext = (struct device_extension *)device->DeviceExtension; - struct pnp_device *pnp_device = ext->pnp_device;
EnterCriticalSection(&device_list_cs); - list_remove(&pnp_device->entry); + list_remove(&ext->entry); LeaveCriticalSection(&device_list_cs); }
static NTSTATUS build_device_relations(DEVICE_RELATIONS **devices) { + struct device_extension *ext; int i; - struct pnp_device *ptr;
EnterCriticalSection(&device_list_cs); - *devices = ExAllocatePool(PagedPool, offsetof(DEVICE_RELATIONS, Objects[list_count(&pnp_devset)])); + *devices = ExAllocatePool(PagedPool, offsetof(DEVICE_RELATIONS, Objects[list_count(&device_list)]));
if (!*devices) { @@ -397,10 +382,10 @@ static NTSTATUS build_device_relations(DEVICE_RELATIONS **devices) }
i = 0; - LIST_FOR_EACH_ENTRY(ptr, &pnp_devset, struct pnp_device, entry) + LIST_FOR_EACH_ENTRY(ext, &device_list, struct device_extension, entry) { - (*devices)->Objects[i] = ptr->device; - call_fastcall_func1(ObfReferenceObject, ptr->device); + (*devices)->Objects[i] = ext->device; + call_fastcall_func1(ObfReferenceObject, ext->device); i++; } LeaveCriticalSection(&device_list_cs); @@ -835,9 +820,6 @@ static NTSTATUS pdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp) break;
case IRP_MN_REMOVE_DEVICE: - { - struct pnp_device *pnp_device = ext->pnp_device; - remove_pending_irps(device);
bus_unlink_hid_device(device); @@ -853,12 +835,7 @@ static NTSTATUS pdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp) IoCompleteRequest(irp, IO_NO_INCREMENT);
IoDeleteDevice(device); - - /* pnp_device must be released after the device is gone */ - HeapFree(GetProcessHeap(), 0, pnp_device); - return STATUS_SUCCESS; - }
default: FIXME("Unhandled function %08x\n", irpsp->MinorFunction);