Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winebus.sys/bus_iohid.c | 1 - dlls/winebus.sys/bus_sdl.c | 4 +-- dlls/winebus.sys/bus_udev.c | 2 +- dlls/winebus.sys/main.c | 56 +++++++++++++++++++++++++----------- 4 files changed, 42 insertions(+), 21 deletions(-)
diff --git a/dlls/winebus.sys/bus_iohid.c b/dlls/winebus.sys/bus_iohid.c index c275011b491..0123e73f7ba 100644 --- a/dlls/winebus.sys/bus_iohid.c +++ b/dlls/winebus.sys/bus_iohid.c @@ -384,7 +384,6 @@ static void handle_RemovalCallback(void *context, IOReturn result, void *sender, { bus_unlink_hid_device(device); IoInvalidateDeviceRelations(bus_pdo, BusRelations); - bus_remove_hid_device(device); } }
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index 154c0fb19a3..779a1af2736 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -890,8 +890,6 @@ static void try_remove_device(SDL_JoystickID id)
bus_unlink_hid_device(device); IoInvalidateDeviceRelations(bus_pdo, BusRelations); - - bus_remove_hid_device(device); }
static void try_add_device(unsigned int index) @@ -965,6 +963,8 @@ static void try_add_device(unsigned int index) private->sdl_joystick = joystick; private->sdl_controller = controller; private->id = id; + + /* FIXME: We should probably move this to IRP_MN_START_DEVICE. */ if (controller) rc = build_mapped_report_descriptor(private); else diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index c717c13a7db..0c150322006 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -1300,6 +1300,7 @@ static void try_add_device(struct udev_device *dev) private->device_fd = fd; #ifdef HAS_PROPER_INPUT_HEADER if (strcmp(subsystem, "input") == 0) + /* FIXME: We should probably move this to IRP_MN_START_DEVICE. */ if (!build_report_descriptor((struct wine_input_private*)private, dev)) { ERR("Building report descriptor failed, removing device\n"); @@ -1335,7 +1336,6 @@ static void try_remove_device(struct udev_device *dev)
bus_unlink_hid_device(device); IoInvalidateDeviceRelations(bus_pdo, BusRelations); - bus_remove_hid_device(device); }
static void build_initial_deviceset(void) diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c index 598cd2483fa..01e839f02d8 100644 --- a/dlls/winebus.sys/main.c +++ b/dlls/winebus.sys/main.c @@ -367,24 +367,9 @@ void bus_remove_hid_device(DEVICE_OBJECT *device) { struct device_extension *ext = (struct device_extension *)device->DeviceExtension; struct pnp_device *pnp_device = ext->pnp_device; - LIST_ENTRY *entry; - IRP *irp;
TRACE("(%p)\n", device);
- /* Cancel pending IRPs */ - EnterCriticalSection(&ext->cs); - while ((entry = RemoveHeadList(&ext->irp_queue)) != &ext->irp_queue) - { - irp = CONTAINING_RECORD(entry, IRP, Tail.Overlay.s.ListEntry); - irp->IoStatus.u.Status = STATUS_DELETE_PENDING; - irp->IoStatus.Information = 0; - IoCompleteRequest(irp, IO_NO_INCREMENT); - } - LeaveCriticalSection(&ext->cs); - - ext->vtbl->free_device(device); - ext->cs.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&ext->cs);
@@ -606,19 +591,56 @@ static NTSTATUS fdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp)
static NTSTATUS pdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp) { + struct device_extension *ext = device->DeviceExtension; NTSTATUS status = irp->IoStatus.u.Status; IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation(irp);
+ TRACE("device %p, irp %p, minor function %#x.\n", device, irp, irpsp->MinorFunction); + switch (irpsp->MinorFunction) { case IRP_MN_QUERY_ID: - TRACE("IRP_MN_QUERY_ID\n"); status = handle_IRP_MN_QUERY_ID(device, irp); break; + case IRP_MN_QUERY_CAPABILITIES: - TRACE("IRP_MN_QUERY_CAPABILITIES\n"); status = STATUS_SUCCESS; break; + + case IRP_MN_REMOVE_DEVICE: + { + struct pnp_device *pnp_device = ext->pnp_device; + LIST_ENTRY *entry; + + EnterCriticalSection(&ext->cs); + while ((entry = RemoveHeadList(&ext->irp_queue)) != &ext->irp_queue) + { + IRP *queued_irp = CONTAINING_RECORD(entry, IRP, Tail.Overlay.s.ListEntry); + queued_irp->IoStatus.u.Status = STATUS_DELETE_PENDING; + queued_irp->IoStatus.Information = 0; + IoCompleteRequest(queued_irp, IO_NO_INCREMENT); + } + LeaveCriticalSection(&ext->cs); + + ext->vtbl->free_device(device); + + ext->cs.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&ext->cs); + + HeapFree(GetProcessHeap(), 0, ext->serial); + HeapFree(GetProcessHeap(), 0, ext->last_report); + + irp->IoStatus.u.Status = STATUS_SUCCESS; + 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); break;