Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
Supersedes: 211939-211944
v2: Move the threads first, introduce the unixlib next. Use a new unixlib style interface directly from the start but share the entry point table directly instead of using __wine_unix_call.
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 | 36 ++++++++++++++++----------- dlls/winebus.sys/unix_private.h | 42 +++++++++++++++++++++++++++++++ dlls/winebus.sys/unixlib.c | 44 +++++++++++++++++++++++++++++++++ dlls/winebus.sys/unixlib.h | 43 ++++++++++++++++++++++++++++++++ 9 files changed, 156 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..b231cf51200 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,13 @@ static const WCHAR zero_serialW[]= {'0','0','0','0',0}; static const WCHAR miW[] = {'M','I',0}; static const WCHAR igW[] = {'I','G',0};
+extern const unixlib_entry_t *__wine_unix_call_funcs DECLSPEC_HIDDEN; + +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 +635,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 +645,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 +687,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 +700,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 +713,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 +748,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..003ceb5c9e5 --- /dev/null +++ b/dlls/winebus.sys/unixlib.h @@ -0,0 +1,43 @@ +/* + * 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> + +enum unix_funcs +{ + sdl_init, + sdl_wait, + sdl_stop, + udev_init, + udev_wait, + udev_stop, + iohid_init, + iohid_wait, + iohid_stop, +}; + +#endif /* __WINEBUS_UNIXLIB_H */
On 8/23/21 9:55 AM, Rémi Bernon wrote:
+extern const unixlib_entry_t *__wine_unix_call_funcs DECLSPEC_HIDDEN;
+static NTSTATUS winebus_call(unsigned int code, void *args) +{
- return __wine_unix_call_funcs[code]( args );
+}
Sorry, this is broken. I was so sure it worked, but it needs __wine_unix_call_funcs[] instead or it gets initialized to a NULL pointer (!?). I'll resend.
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 b231cf51200..63c1b57b186 100644 --- a/dlls/winebus.sys/main.c +++ b/dlls/winebus.sys/main.c @@ -413,6 +413,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; @@ -634,6 +648,7 @@ struct bus_main_params { const WCHAR *name;
+ void *init_args; HANDLE init_done; unsigned int init_code; unsigned int wait_code; @@ -645,7 +660,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));
@@ -684,35 +699,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, }; @@ -1122,21 +1157,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 003ceb5c9e5..abd9c8a1d81 100644 --- a/dlls/winebus.sys/unixlib.h +++ b/dlls/winebus.sys/unixlib.h @@ -27,6 +27,21 @@ #include <ddk/wdm.h> #include <hidusage.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 63c1b57b186..5dd6cb98acc 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; @@ -173,10 +173,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) @@ -262,9 +262,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; @@ -273,19 +273,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); @@ -312,8 +310,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 abd9c8a1d81..84391733852 100644 --- a/dlls/winebus.sys/unixlib.h +++ b/dlls/winebus.sys/unixlib.h @@ -42,6 +42,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 5dd6cb98acc..576780779a1 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}; @@ -181,12 +176,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); } @@ -268,7 +262,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]; @@ -278,16 +271,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; }
@@ -295,7 +284,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; @@ -317,8 +306,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; @@ -326,19 +314,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; } } @@ -350,23 +337,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; } } @@ -377,20 +363,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) { @@ -399,10 +384,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); @@ -837,9 +822,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); @@ -855,12 +837,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);