Commit f8ec3fdc authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

winebus.sys: Move platform-specific device cleanup to a callback function.

parent b6409950
......@@ -29,6 +29,7 @@ void sdl_driver_unload( void ) DECLSPEC_HIDDEN;
/* Native device function table */
typedef struct
{
void (*free_device)(DEVICE_OBJECT *device);
int (*compare_platform_device)(DEVICE_OBJECT *device, void *platform_dev);
NTSTATUS (*get_reportdescriptor)(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *out_length);
NTSTATUS (*get_string)(DEVICE_OBJECT *device, DWORD index, WCHAR *buffer, DWORD length);
......
......@@ -136,6 +136,10 @@ static void handle_IOHIDDeviceIOHIDReportCallback(void *context,
process_hid_report(device, report, report_length);
}
static void free_device(DEVICE_OBJECT *device)
{
}
static int compare_platform_device(DEVICE_OBJECT *device, void *platform_dev)
{
struct platform_private *private = impl_from_DEVICE_OBJECT(device);
......@@ -270,6 +274,7 @@ static NTSTATUS set_feature_report(DEVICE_OBJECT *device, UCHAR id, BYTE *report
static const platform_vtbl iohid_vtbl =
{
free_device,
compare_platform_device,
get_reportdescriptor,
get_string,
......
......@@ -605,6 +605,17 @@ static BOOL build_mapped_report_descriptor(struct platform_private *ext)
return TRUE;
}
static void free_device(DEVICE_OBJECT *device)
{
struct platform_private *ext = impl_from_DEVICE_OBJECT(device);
pSDL_JoystickClose(ext->sdl_joystick);
if (ext->sdl_controller)
pSDL_GameControllerClose(ext->sdl_controller);
if (ext->sdl_haptic)
pSDL_HapticClose(ext->sdl_haptic);
}
static int compare_platform_device(DEVICE_OBJECT *device, void *platform_dev)
{
SDL_JoystickID id1 = impl_from_DEVICE_OBJECT(device)->id;
......@@ -722,6 +733,7 @@ static NTSTATUS set_feature_report(DEVICE_OBJECT *device, UCHAR id, BYTE *report
static const platform_vtbl sdl_vtbl =
{
free_device,
compare_platform_device,
get_reportdescriptor,
get_string,
......@@ -872,29 +884,14 @@ static BOOL set_mapped_report_from_event(SDL_Event *event)
static void try_remove_device(SDL_JoystickID id)
{
DEVICE_OBJECT *device = NULL;
struct platform_private *private;
SDL_Joystick *sdl_joystick;
SDL_GameController *sdl_controller;
SDL_Haptic *sdl_haptic;
device = bus_enumerate_hid_devices(&sdl_vtbl, compare_joystick_id, ULongToPtr(id));
if (!device) return;
private = impl_from_DEVICE_OBJECT(device);
sdl_joystick = private->sdl_joystick;
sdl_controller = private->sdl_controller;
sdl_haptic = private->sdl_haptic;
bus_unlink_hid_device(device);
IoInvalidateDeviceRelations(bus_pdo, BusRelations);
bus_remove_hid_device(device);
pSDL_JoystickClose(sdl_joystick);
if (sdl_controller)
pSDL_GameControllerClose(sdl_controller);
if (sdl_haptic)
pSDL_HapticClose(sdl_haptic);
}
static void try_add_device(unsigned int index)
......
......@@ -653,6 +653,23 @@ static WCHAR *get_sysattr_string(struct udev_device *dev, const char *sysattr)
return strdupAtoW(attr);
}
static void hidraw_free_device(DEVICE_OBJECT *device)
{
struct platform_private *private = impl_from_DEVICE_OBJECT(device);
if (private->report_thread)
{
write(private->control_pipe[1], "q", 1);
WaitForSingleObject(private->report_thread, INFINITE);
close(private->control_pipe[0]);
close(private->control_pipe[1]);
CloseHandle(private->report_thread);
}
close(private->device_fd);
udev_device_unref(private->udev_device);
}
static int compare_platform_device(DEVICE_OBJECT *device, void *platform_dev)
{
struct udev_device *dev1 = impl_from_DEVICE_OBJECT(device)->udev_device;
......@@ -921,6 +938,7 @@ static NTSTATUS hidraw_set_feature_report(DEVICE_OBJECT *device, UCHAR id, BYTE
static const platform_vtbl hidraw_vtbl =
{
hidraw_free_device,
compare_platform_device,
hidraw_get_reportdescriptor,
hidraw_get_string,
......@@ -937,6 +955,27 @@ static inline struct wine_input_private *input_impl_from_DEVICE_OBJECT(DEVICE_OB
return (struct wine_input_private*)get_platform_private(device);
}
static void lnxev_free_device(DEVICE_OBJECT *device)
{
struct wine_input_private *ext = input_impl_from_DEVICE_OBJECT(device);
if (ext->base.report_thread)
{
write(ext->base.control_pipe[1], "q", 1);
WaitForSingleObject(ext->base.report_thread, INFINITE);
close(ext->base.control_pipe[0]);
close(ext->base.control_pipe[1]);
CloseHandle(ext->base.report_thread);
}
HeapFree(GetProcessHeap(), 0, ext->current_report_buffer);
HeapFree(GetProcessHeap(), 0, ext->last_report_buffer);
HeapFree(GetProcessHeap(), 0, ext->report_descriptor);
close(ext->base.device_fd);
udev_device_unref(ext->base.udev_device);
}
static NTSTATUS lnxev_get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *out_length)
{
struct wine_input_private *ext = input_impl_from_DEVICE_OBJECT(device);
......@@ -1051,6 +1090,7 @@ static NTSTATUS lnxev_set_feature_report(DEVICE_OBJECT *device, UCHAR id, BYTE *
}
static const platform_vtbl lnxev_vtbl = {
lnxev_free_device,
compare_platform_device,
lnxev_get_reportdescriptor,
lnxev_get_string,
......@@ -1285,54 +1325,17 @@ static void try_add_device(struct udev_device *dev)
static void try_remove_device(struct udev_device *dev)
{
DEVICE_OBJECT *device = NULL;
struct platform_private* private;
#ifdef HAS_PROPER_INPUT_HEADER
BOOL is_input = FALSE;
#endif
device = bus_find_hid_device(&hidraw_vtbl, dev);
#ifdef HAS_PROPER_INPUT_HEADER
if (device == NULL)
{
device = bus_find_hid_device(&lnxev_vtbl, dev);
is_input = TRUE;
}
#endif
if (!device) return;
bus_unlink_hid_device(device);
IoInvalidateDeviceRelations(bus_pdo, BusRelations);
private = impl_from_DEVICE_OBJECT(device);
if (private->report_thread)
{
write(private->control_pipe[1], "q", 1);
WaitForSingleObject(private->report_thread, INFINITE);
close(private->control_pipe[0]);
close(private->control_pipe[1]);
CloseHandle(private->report_thread);
#ifdef HAS_PROPER_INPUT_HEADER
if (strcmp(udev_device_get_subsystem(dev), "input") == 0)
{
HeapFree(GetProcessHeap(), 0, ((struct wine_input_private*)private)->current_report_buffer);
HeapFree(GetProcessHeap(), 0, ((struct wine_input_private*)private)->last_report_buffer);
}
#endif
}
#ifdef HAS_PROPER_INPUT_HEADER
if (is_input)
{
struct wine_input_private *ext = (struct wine_input_private*)private;
HeapFree(GetProcessHeap(), 0, ext->report_descriptor);
}
#endif
dev = private->udev_device;
close(private->device_fd);
bus_remove_hid_device(device);
udev_device_unref(dev);
}
static void build_initial_deviceset(void)
......@@ -1482,12 +1485,6 @@ static DWORD CALLBACK deviceloop_thread(void *args)
return 0;
}
static int device_unload(DEVICE_OBJECT *device, void *context)
{
try_remove_device(impl_from_DEVICE_OBJECT(device)->udev_device);
return 1;
}
void udev_driver_unload( void )
{
TRACE("Unload Driver\n");
......@@ -1500,11 +1497,6 @@ void udev_driver_unload( void )
close(deviceloop_control[0]);
close(deviceloop_control[1]);
CloseHandle(deviceloop_handle);
bus_enumerate_hid_devices(&hidraw_vtbl, device_unload, NULL);
#ifdef HAS_PROPER_INPUT_HEADER
bus_enumerate_hid_devices(&lnxev_vtbl, device_unload, NULL);
#endif
}
NTSTATUS udev_driver_init(void)
......
......@@ -377,6 +377,8 @@ void bus_remove_hid_device(DEVICE_OBJECT *device)
}
LeaveCriticalSection(&ext->cs);
ext->vtbl->free_device(device);
ext->cs.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&ext->cs);
......@@ -474,6 +476,10 @@ static NTSTATUS handle_IRP_MN_QUERY_ID(DEVICE_OBJECT *device, IRP *irp)
return status;
}
static void mouse_free_device(DEVICE_OBJECT *device)
{
}
static NTSTATUS mouse_get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *ret_length)
{
TRACE("buffer %p, length %u.\n", buffer, length);
......@@ -526,6 +532,7 @@ static NTSTATUS mouse_set_feature_report(DEVICE_OBJECT *device, UCHAR id, BYTE *
static const platform_vtbl mouse_vtbl =
{
.free_device = mouse_free_device,
.get_reportdescriptor = mouse_get_reportdescriptor,
.get_string = mouse_get_string,
.begin_report_processing = mouse_begin_report_processing,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment