Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
Supersedes: 211680-211686
dlls/winebus.sys/bus.h | 1 + dlls/winebus.sys/bus_iohid.c | 6 ++++++ dlls/winebus.sys/bus_sdl.c | 6 ++++++ dlls/winebus.sys/bus_udev.c | 12 ++++++++++++ dlls/winebus.sys/main.c | 33 ++++++++++++++++++++++++++++----- 5 files changed, 53 insertions(+), 5 deletions(-)
diff --git a/dlls/winebus.sys/bus.h b/dlls/winebus.sys/bus.h index 72bd071135b..f46daa7144d 100644 --- a/dlls/winebus.sys/bus.h +++ b/dlls/winebus.sys/bus.h @@ -39,6 +39,7 @@ typedef struct { void (*free_device)(DEVICE_OBJECT *device); int (*compare_platform_device)(DEVICE_OBJECT *device, void *platform_dev); + NTSTATUS (*start_device)(DEVICE_OBJECT *device); 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); NTSTATUS (*begin_report_processing)(DEVICE_OBJECT *device); diff --git a/dlls/winebus.sys/bus_iohid.c b/dlls/winebus.sys/bus_iohid.c index eb6765d6aac..9b9e93f5c49 100644 --- a/dlls/winebus.sys/bus_iohid.c +++ b/dlls/winebus.sys/bus_iohid.c @@ -148,6 +148,11 @@ static int compare_platform_device(DEVICE_OBJECT *device, void *platform_dev) return 0; }
+static NTSTATUS start_device(DEVICE_OBJECT *device) +{ + return STATUS_SUCCESS; +} + static NTSTATUS get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *out_length) { struct platform_private *private = impl_from_DEVICE_OBJECT(device); @@ -274,6 +279,7 @@ static const platform_vtbl iohid_vtbl = { free_device, compare_platform_device, + start_device, get_reportdescriptor, get_string, begin_report_processing, diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index c833b4e4c06..e7b7c1fef22 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -487,6 +487,11 @@ static int compare_platform_device(DEVICE_OBJECT *device, void *context) return impl_from_DEVICE_OBJECT(device)->id - PtrToUlong(context); }
+static NTSTATUS start_device(DEVICE_OBJECT *device) +{ + return STATUS_SUCCESS; +} + static NTSTATUS get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *out_length) { struct platform_private *ext = impl_from_DEVICE_OBJECT(device); @@ -596,6 +601,7 @@ static const platform_vtbl sdl_vtbl = { free_device, compare_platform_device, + start_device, get_reportdescriptor, get_string, begin_report_processing, diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index 9176dff69a7..eb6434ad2a5 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -558,6 +558,11 @@ static int compare_platform_device(DEVICE_OBJECT *device, void *platform_dev) return strcmp(udev_device_get_syspath(dev1), udev_device_get_syspath(dev2)); }
+static NTSTATUS hidraw_start_device(DEVICE_OBJECT *device) +{ + return STATUS_SUCCESS; +} + static NTSTATUS hidraw_get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *out_length) { #ifdef HAVE_LINUX_HIDRAW_H @@ -818,6 +823,7 @@ static const platform_vtbl hidraw_vtbl = { hidraw_free_device, compare_platform_device, + hidraw_start_device, hidraw_get_reportdescriptor, hidraw_get_string, begin_report_processing, @@ -854,6 +860,11 @@ static void lnxev_free_device(DEVICE_OBJECT *device) udev_device_unref(ext->base.udev_device); }
+static NTSTATUS lnxev_start_device(DEVICE_OBJECT *device) +{ + return STATUS_SUCCESS; +} + 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); @@ -967,6 +978,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_start_device, lnxev_get_reportdescriptor, lnxev_get_string, lnxev_begin_report_processing, diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c index a60e3cc9a2c..f15e7da47b2 100644 --- a/dlls/winebus.sys/main.c +++ b/dlls/winebus.sys/main.c @@ -109,11 +109,17 @@ struct pnp_device DEVICE_OBJECT *device; };
+enum device_state +{ + DEVICE_STATE_STOPPED, + DEVICE_STATE_STARTED, + DEVICE_STATE_REMOVED, +}; + struct device_extension { CRITICAL_SECTION cs; - - BOOL removed; + enum device_state state;
struct pnp_device *pnp_device;
@@ -480,6 +486,11 @@ static void mouse_free_device(DEVICE_OBJECT *device) { }
+static NTSTATUS mouse_start_device(DEVICE_OBJECT *device) +{ + return STATUS_SUCCESS; +} + static NTSTATUS mouse_get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *ret_length) { TRACE("buffer %p, length %u.\n", buffer, length); @@ -528,6 +539,7 @@ static NTSTATUS mouse_set_feature_report(DEVICE_OBJECT *device, UCHAR id, BYTE * static const platform_vtbl mouse_vtbl = { .free_device = mouse_free_device, + .start_device = mouse_start_device, .get_reportdescriptor = mouse_get_reportdescriptor, .get_string = mouse_get_string, .begin_report_processing = mouse_begin_report_processing, @@ -555,6 +567,11 @@ static void keyboard_free_device(DEVICE_OBJECT *device) { }
+static NTSTATUS keyboard_start_device(DEVICE_OBJECT *device) +{ + return STATUS_SUCCESS; +} + static NTSTATUS keyboard_get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *ret_length) { TRACE("buffer %p, length %u.\n", buffer, length); @@ -603,6 +620,7 @@ static NTSTATUS keyboard_set_feature_report(DEVICE_OBJECT *device, UCHAR id, BYT static const platform_vtbl keyboard_vtbl = { .free_device = keyboard_free_device, + .start_device = keyboard_start_device, .get_reportdescriptor = keyboard_get_reportdescriptor, .get_string = keyboard_get_string, .begin_report_processing = keyboard_begin_report_processing, @@ -695,13 +713,18 @@ static NTSTATUS pdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp) break;
case IRP_MN_START_DEVICE: - status = STATUS_SUCCESS; + EnterCriticalSection(&ext->cs); + if (ext->state != DEVICE_STATE_STOPPED) status = STATUS_SUCCESS; + else if (ext->state == DEVICE_STATE_REMOVED) status = STATUS_DELETE_PENDING; + else if (!(status = ext->vtbl->start_device(device))) ext->state = DEVICE_STATE_STARTED; + else ERR("failed to start device %p, status %#x\n", device, status); + LeaveCriticalSection(&ext->cs); break;
case IRP_MN_SURPRISE_REMOVAL: EnterCriticalSection(&ext->cs); remove_pending_irps(device); - ext->removed = TRUE; + ext->state = DEVICE_STATE_REMOVED; LeaveCriticalSection(&ext->cs); status = STATUS_SUCCESS; break; @@ -834,7 +857,7 @@ static NTSTATUS WINAPI hid_internal_dispatch(DEVICE_OBJECT *device, IRP *irp)
EnterCriticalSection(&ext->cs);
- if (ext->removed) + if (ext->state == DEVICE_STATE_REMOVED) { LeaveCriticalSection(&ext->cs); irp->IoStatus.Status = STATUS_DELETE_PENDING;