winebus.sys: Split destroy to a separate stop method.
So we can stop the device when it's removed from the ntoskrnl.exe device list, and then destroy it only when it's not referenced anymore. Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
bb727d2e98
commit
cd830398dd
|
@ -167,6 +167,13 @@ static NTSTATUS iohid_device_start(struct unix_device *iface, DEVICE_OBJECT *dev
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void iohid_device_stop(struct unix_device *iface)
|
||||||
|
{
|
||||||
|
struct platform_private *private = impl_from_unix_device(iface);
|
||||||
|
|
||||||
|
IOHIDDeviceRegisterInputReportCallback(private->device, NULL, 0, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS iohid_device_get_report_descriptor(struct unix_device *iface, BYTE *buffer,
|
static NTSTATUS iohid_device_get_report_descriptor(struct unix_device *iface, BYTE *buffer,
|
||||||
DWORD length, DWORD *out_length)
|
DWORD length, DWORD *out_length)
|
||||||
{
|
{
|
||||||
|
@ -246,6 +253,7 @@ static const struct unix_device_vtbl iohid_device_vtbl =
|
||||||
iohid_device_destroy,
|
iohid_device_destroy,
|
||||||
iohid_device_compare,
|
iohid_device_compare,
|
||||||
iohid_device_start,
|
iohid_device_start,
|
||||||
|
iohid_device_stop,
|
||||||
iohid_device_get_report_descriptor,
|
iohid_device_get_report_descriptor,
|
||||||
iohid_device_set_output_report,
|
iohid_device_set_output_report,
|
||||||
iohid_device_get_feature_report,
|
iohid_device_get_feature_report,
|
||||||
|
|
|
@ -482,12 +482,6 @@ static void sdl_device_destroy(struct unix_device *iface)
|
||||||
{
|
{
|
||||||
struct platform_private *ext = impl_from_unix_device(iface);
|
struct platform_private *ext = impl_from_unix_device(iface);
|
||||||
|
|
||||||
pSDL_JoystickClose(ext->sdl_joystick);
|
|
||||||
if (ext->sdl_controller)
|
|
||||||
pSDL_GameControllerClose(ext->sdl_controller);
|
|
||||||
if (ext->sdl_haptic)
|
|
||||||
pSDL_HapticClose(ext->sdl_haptic);
|
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, ext);
|
HeapFree(GetProcessHeap(), 0, ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -503,6 +497,15 @@ static NTSTATUS sdl_device_start(struct unix_device *iface, DEVICE_OBJECT *devic
|
||||||
return build_report_descriptor(ext);
|
return build_report_descriptor(ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sdl_device_stop(struct unix_device *iface)
|
||||||
|
{
|
||||||
|
struct platform_private *private = impl_from_unix_device(iface);
|
||||||
|
|
||||||
|
pSDL_JoystickClose(private->sdl_joystick);
|
||||||
|
if (private->sdl_controller) pSDL_GameControllerClose(private->sdl_controller);
|
||||||
|
if (private->sdl_haptic) pSDL_HapticClose(private->sdl_haptic);
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS sdl_device_get_reportdescriptor(struct unix_device *iface, BYTE *buffer,
|
static NTSTATUS sdl_device_get_reportdescriptor(struct unix_device *iface, BYTE *buffer,
|
||||||
DWORD length, DWORD *out_length)
|
DWORD length, DWORD *out_length)
|
||||||
{
|
{
|
||||||
|
@ -579,6 +582,7 @@ static const struct unix_device_vtbl sdl_device_vtbl =
|
||||||
sdl_device_destroy,
|
sdl_device_destroy,
|
||||||
sdl_device_compare,
|
sdl_device_compare,
|
||||||
sdl_device_start,
|
sdl_device_start,
|
||||||
|
sdl_device_stop,
|
||||||
sdl_device_get_reportdescriptor,
|
sdl_device_get_reportdescriptor,
|
||||||
sdl_device_set_output_report,
|
sdl_device_set_output_report,
|
||||||
sdl_device_get_feature_report,
|
sdl_device_get_feature_report,
|
||||||
|
|
|
@ -558,19 +558,6 @@ static void hidraw_device_destroy(struct unix_device *iface)
|
||||||
{
|
{
|
||||||
struct platform_private *private = impl_from_unix_device(iface);
|
struct platform_private *private = impl_from_unix_device(iface);
|
||||||
|
|
||||||
EnterCriticalSection(&udev_cs);
|
|
||||||
list_remove(&private->unix_device.entry);
|
|
||||||
LeaveCriticalSection(&udev_cs);
|
|
||||||
|
|
||||||
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);
|
close(private->device_fd);
|
||||||
udev_device_unref(private->udev_device);
|
udev_device_unref(private->udev_device);
|
||||||
|
|
||||||
|
@ -608,6 +595,24 @@ static NTSTATUS hidraw_device_start(struct unix_device *iface, DEVICE_OBJECT *de
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void hidraw_device_stop(struct unix_device *iface)
|
||||||
|
{
|
||||||
|
struct platform_private *private = impl_from_unix_device(iface);
|
||||||
|
|
||||||
|
EnterCriticalSection(&udev_cs);
|
||||||
|
list_remove(&private->unix_device.entry);
|
||||||
|
LeaveCriticalSection(&udev_cs);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS hidraw_device_get_report_descriptor(struct unix_device *iface, BYTE *buffer,
|
static NTSTATUS hidraw_device_get_report_descriptor(struct unix_device *iface, BYTE *buffer,
|
||||||
DWORD length, DWORD *out_length)
|
DWORD length, DWORD *out_length)
|
||||||
{
|
{
|
||||||
|
@ -780,6 +785,7 @@ static const struct unix_device_vtbl hidraw_device_vtbl =
|
||||||
hidraw_device_destroy,
|
hidraw_device_destroy,
|
||||||
udev_device_compare,
|
udev_device_compare,
|
||||||
hidraw_device_start,
|
hidraw_device_start,
|
||||||
|
hidraw_device_stop,
|
||||||
hidraw_device_get_report_descriptor,
|
hidraw_device_get_report_descriptor,
|
||||||
hidraw_device_set_output_report,
|
hidraw_device_set_output_report,
|
||||||
hidraw_device_get_feature_report,
|
hidraw_device_get_feature_report,
|
||||||
|
@ -802,19 +808,6 @@ static void lnxev_device_destroy(struct unix_device *iface)
|
||||||
{
|
{
|
||||||
struct wine_input_private *ext = input_impl_from_unix_device(iface);
|
struct wine_input_private *ext = input_impl_from_unix_device(iface);
|
||||||
|
|
||||||
EnterCriticalSection(&udev_cs);
|
|
||||||
list_remove(&ext->base.unix_device.entry);
|
|
||||||
LeaveCriticalSection(&udev_cs);
|
|
||||||
|
|
||||||
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->current_report_buffer);
|
||||||
HeapFree(GetProcessHeap(), 0, ext->last_report_buffer);
|
HeapFree(GetProcessHeap(), 0, ext->last_report_buffer);
|
||||||
hid_descriptor_free(&ext->desc);
|
hid_descriptor_free(&ext->desc);
|
||||||
|
@ -853,6 +846,24 @@ static NTSTATUS lnxev_device_start(struct unix_device *iface, DEVICE_OBJECT *dev
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void lnxev_device_stop(struct unix_device *iface)
|
||||||
|
{
|
||||||
|
struct wine_input_private *ext = input_impl_from_unix_device(iface);
|
||||||
|
|
||||||
|
EnterCriticalSection(&udev_cs);
|
||||||
|
list_remove(&ext->base.unix_device.entry);
|
||||||
|
LeaveCriticalSection(&udev_cs);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS lnxev_device_get_report_descriptor(struct unix_device *iface, BYTE *buffer,
|
static NTSTATUS lnxev_device_get_report_descriptor(struct unix_device *iface, BYTE *buffer,
|
||||||
DWORD length, DWORD *out_length)
|
DWORD length, DWORD *out_length)
|
||||||
{
|
{
|
||||||
|
@ -920,6 +931,7 @@ static const struct unix_device_vtbl lnxev_device_vtbl =
|
||||||
lnxev_device_destroy,
|
lnxev_device_destroy,
|
||||||
udev_device_compare,
|
udev_device_compare,
|
||||||
lnxev_device_start,
|
lnxev_device_start,
|
||||||
|
lnxev_device_stop,
|
||||||
lnxev_device_get_report_descriptor,
|
lnxev_device_get_report_descriptor,
|
||||||
lnxev_device_set_output_report,
|
lnxev_device_set_output_report,
|
||||||
lnxev_device_get_feature_report,
|
lnxev_device_get_feature_report,
|
||||||
|
|
|
@ -34,6 +34,7 @@ struct unix_device_vtbl
|
||||||
void (*destroy)(struct unix_device *iface);
|
void (*destroy)(struct unix_device *iface);
|
||||||
int (*compare)(struct unix_device *iface, void *platform_dev);
|
int (*compare)(struct unix_device *iface, void *platform_dev);
|
||||||
NTSTATUS (*start)(struct unix_device *iface, DEVICE_OBJECT *device);
|
NTSTATUS (*start)(struct unix_device *iface, DEVICE_OBJECT *device);
|
||||||
|
void (*stop)(struct unix_device *iface);
|
||||||
NTSTATUS (*get_report_descriptor)(struct unix_device *iface, BYTE *buffer, DWORD length, DWORD *out_length);
|
NTSTATUS (*get_report_descriptor)(struct unix_device *iface, BYTE *buffer, DWORD length, DWORD *out_length);
|
||||||
void (*set_output_report)(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io);
|
void (*set_output_report)(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io);
|
||||||
void (*get_feature_report)(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io);
|
void (*get_feature_report)(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io);
|
||||||
|
|
|
@ -37,7 +37,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(plugplay);
|
||||||
static struct hid_descriptor mouse_desc;
|
static struct hid_descriptor mouse_desc;
|
||||||
static struct hid_descriptor keyboard_desc;
|
static struct hid_descriptor keyboard_desc;
|
||||||
|
|
||||||
static void mouse_remove(struct unix_device *iface)
|
static void mouse_destroy(struct unix_device *iface)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +58,10 @@ static NTSTATUS mouse_start(struct unix_device *iface, DEVICE_OBJECT *device)
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mouse_stop(struct unix_device *iface)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS mouse_get_report_descriptor(struct unix_device *iface, BYTE *buffer, DWORD length, DWORD *ret_length)
|
static NTSTATUS mouse_get_report_descriptor(struct unix_device *iface, BYTE *buffer, DWORD length, DWORD *ret_length)
|
||||||
{
|
{
|
||||||
TRACE("buffer %p, length %u.\n", buffer, length);
|
TRACE("buffer %p, length %u.\n", buffer, length);
|
||||||
|
@ -92,9 +96,10 @@ static void mouse_set_feature_report(struct unix_device *iface, HID_XFER_PACKET
|
||||||
|
|
||||||
static const struct unix_device_vtbl mouse_vtbl =
|
static const struct unix_device_vtbl mouse_vtbl =
|
||||||
{
|
{
|
||||||
mouse_remove,
|
mouse_destroy,
|
||||||
mouse_compare,
|
mouse_compare,
|
||||||
mouse_start,
|
mouse_start,
|
||||||
|
mouse_stop,
|
||||||
mouse_get_report_descriptor,
|
mouse_get_report_descriptor,
|
||||||
mouse_set_output_report,
|
mouse_set_output_report,
|
||||||
mouse_get_feature_report,
|
mouse_get_feature_report,
|
||||||
|
@ -120,7 +125,7 @@ static NTSTATUS mouse_device_create(void *args)
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void keyboard_remove(struct unix_device *iface)
|
static void keyboard_destroy(struct unix_device *iface)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,6 +146,10 @@ static NTSTATUS keyboard_start(struct unix_device *iface, DEVICE_OBJECT *device)
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void keyboard_stop(struct unix_device *iface)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS keyboard_get_report_descriptor(struct unix_device *iface, BYTE *buffer, DWORD length, DWORD *ret_length)
|
static NTSTATUS keyboard_get_report_descriptor(struct unix_device *iface, BYTE *buffer, DWORD length, DWORD *ret_length)
|
||||||
{
|
{
|
||||||
TRACE("buffer %p, length %u.\n", buffer, length);
|
TRACE("buffer %p, length %u.\n", buffer, length);
|
||||||
|
@ -175,9 +184,10 @@ static void keyboard_set_feature_report(struct unix_device *iface, HID_XFER_PACK
|
||||||
|
|
||||||
static const struct unix_device_vtbl keyboard_vtbl =
|
static const struct unix_device_vtbl keyboard_vtbl =
|
||||||
{
|
{
|
||||||
keyboard_remove,
|
keyboard_destroy,
|
||||||
keyboard_compare,
|
keyboard_compare,
|
||||||
keyboard_start,
|
keyboard_start,
|
||||||
|
keyboard_stop,
|
||||||
keyboard_get_report_descriptor,
|
keyboard_get_report_descriptor,
|
||||||
keyboard_set_output_report,
|
keyboard_set_output_report,
|
||||||
keyboard_get_feature_report,
|
keyboard_get_feature_report,
|
||||||
|
@ -206,6 +216,7 @@ static NTSTATUS keyboard_device_create(void *args)
|
||||||
static NTSTATUS unix_device_remove(void *args)
|
static NTSTATUS unix_device_remove(void *args)
|
||||||
{
|
{
|
||||||
struct unix_device *iface = args;
|
struct unix_device *iface = args;
|
||||||
|
iface->vtbl->stop(iface);
|
||||||
iface->vtbl->destroy(iface);
|
iface->vtbl->destroy(iface);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue