From: Aric Stewart Subject: [3/5](resend/rebased)hidclass.sys: Implement sending IRP_MJ_PNP to the minidriver Message-Id: <55F85F9C.9010601@codeweavers.com> Date: Tue, 15 Sep 2015 13:12:44 -0500 --- dlls/hidclass.sys/pnp.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c index c3d6f64..f05c61a 100644 --- a/dlls/hidclass.sys/pnp.c +++ b/dlls/hidclass.sys/pnp.c @@ -41,6 +41,51 @@ typedef struct _NATIVE_DEVICE { static struct list tracked_devices = LIST_INIT(tracked_devices); +static NTSTATUS WINAPI internalComplete(DEVICE_OBJECT *deviceObject, IRP *irp, + void *context ) +{ + SetEvent(irp->UserEvent); + return STATUS_MORE_PROCESSING_REQUIRED; +} + +static NTSTATUS SendDeviceIRP(DEVICE_OBJECT* device, IRP *irp) +{ + NTSTATUS status; + IO_STACK_LOCATION *irpsp; + HANDLE event = CreateEventA(NULL, FALSE, FALSE, NULL); + + irp->UserEvent = event; + irpsp = IoGetNextIrpStackLocation(irp); + irpsp->CompletionRoutine = internalComplete; + irpsp->Control = SL_INVOKE_ON_SUCCESS | SL_INVOKE_ON_ERROR; + + IoCallDriver(device, irp); + + if (irp->IoStatus.u.Status == STATUS_PENDING) + WaitForSingleObject(event, INFINITE); + + status = irp->IoStatus.u.Status; + IoCompleteRequest(irp, IO_NO_INCREMENT ); + CloseHandle(event); + return status; +} + +static NTSTATUS PNP_SendPnPIRP(DEVICE_OBJECT *device, UCHAR minor) +{ + IO_STACK_LOCATION *irpsp; + IO_STATUS_BLOCK irp_status; + + IRP *irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, device, NULL, 0, NULL, NULL, &irp_status); + + irpsp = IoGetNextIrpStackLocation(irp); + irpsp->MinorFunction = minor; + + irpsp->Parameters.StartDevice.AllocatedResources = NULL; + irpsp->Parameters.StartDevice.AllocatedResourcesTranslated = NULL; + + return SendDeviceIRP(device, irp); +} + NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO) { DEVICE_OBJECT *device = NULL; @@ -80,12 +125,21 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO) return status; } + status = PNP_SendPnPIRP(device, IRP_MN_START_DEVICE); + if (status != STATUS_SUCCESS) + { + ERR("Minidriver IRP_MN_START_DEVICE failed (%x)\n",status); + HID_DeleteDevice(&minidriver->minidriver, device); + return status; + } + status = call_minidriver(IOCTL_HID_GET_DEVICE_ATTRIBUTES, device, NULL, 0, &attr, sizeof(attr)); if (status != STATUS_SUCCESS) { ERR("Minidriver failed to get Attributes(%x)\n",status); + PNP_SendPnPIRP(device, IRP_MN_REMOVE_DEVICE); HID_DeleteDevice(&minidriver->minidriver, device); return status; } @@ -112,6 +166,7 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO) if (status != STATUS_SUCCESS) { ERR("Cannot get Device Descriptor(%x)\n",status); + PNP_SendPnPIRP(device, IRP_MN_REMOVE_DEVICE); HID_DeleteDevice(&minidriver->minidriver, device); return status; } @@ -122,6 +177,7 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO) if (i >= descriptor.bNumDescriptors) { ERR("No Report Descriptor found in reply\n"); + PNP_SendPnPIRP(device, IRP_MN_REMOVE_DEVICE); HID_DeleteDevice(&minidriver->minidriver, device); return status; } @@ -180,6 +236,7 @@ void PNP_CleanupPNP(DRIVER_OBJECT *driver) if (tracked_device->minidriver->DriverObject == driver) { list_remove(&tracked_device->entry); + PNP_SendPnPIRP(tracked_device->FDO, IRP_MN_REMOVE_DEVICE); HID_DeleteDevice(tracked_device->minidriver, tracked_device->FDO); HeapFree(GetProcessHeap(), 0, tracked_device); }