On 7/1/21 11:29 AM, Rémi Bernon wrote:
On 7/1/21 5:16 PM, Zebediah Figura (she/her) wrote:
diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c index 5f59257cdf7..5d6fb3d068c 100644 --- a/dlls/hidclass.sys/pnp.c +++ b/dlls/hidclass.sys/pnp.c @@ -359,11 +359,24 @@ static NTSTATUS fdo_pnp(DEVICE_OBJECT *device, IRP *irp) } } +static void remove_pending_irps(BASE_DEVICE_EXTENSION *ext) +{ + IRP *irp;
+ while ((irp = pop_irp_from_queue(ext))) + { + irp->IoStatus.Status = STATUS_DELETE_PENDING; + IoCompleteRequest(irp, IO_NO_INCREMENT); + } +}
static NTSTATUS pdo_pnp(DEVICE_OBJECT *device, IRP *irp) { IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation(irp); BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; NTSTATUS status = irp->IoStatus.Status; + IRP *queued_irp; + KIRQL irql; TRACE("irp %p, minor function %#x.\n", irp, irpsp->MinorFunction); @@ -453,12 +466,14 @@ static NTSTATUS pdo_pnp(DEVICE_OBJECT *device, IRP *irp)
IoSetDeviceInterfaceState(&ext->u.pdo.mouse_link_name, TRUE); if (ext->u.pdo.is_keyboard)
IoSetDeviceInterfaceState(&ext->u.pdo.keyboard_link_name, TRUE);
+ ext->u.pdo.removed = FALSE; status = STATUS_SUCCESS; break; case IRP_MN_REMOVE_DEVICE: { - IRP *queued_irp; + remove_pending_irps(ext);
In that case there's no reason to delete queued IRPs later in the handler.
Well, according to [1] it's what we are supposed to do:
- Prevent any new I/O operations on the device.
[...]
- Fail outstanding I/O requests on the device.
As I understand step 4 corresponds to setting the 'removed' flag to TRUE. Also, I'm talking about IRP_MN_REMOVE_DEVICE here, and not IRP_MN_SURPRISE_REMOVAL. Currently we're failing outstanding I/O twice.
[1] https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/handling-an...