From: Aric Stewart Subject: [PATCH 3/4] ntoskrnl.exe: Send PnP and Power IRPs to plug and play devices Message-Id: Date: Mon, 29 Aug 2016 13:49:42 -0500 The drivers AddDevice function will be well behaved and call IoAttachDeviceToDeviceStack. The Plug and Play manager will look at the bus device after AddDevice and if there is an AttachedDevice then will proceed to call IRP_MN_START_DEVICE on the attached device. Then a IRP_MJ_POWER/IRP_MN_SET_POWER to PowerDeviceD0. Signed-off-by: Aric Stewart --- dlls/ntoskrnl.exe/pnp_manager.c | 64 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/dlls/ntoskrnl.exe/pnp_manager.c b/dlls/ntoskrnl.exe/pnp_manager.c index f1f3109..912f5fd 100644 --- a/dlls/ntoskrnl.exe/pnp_manager.c +++ b/dlls/ntoskrnl.exe/pnp_manager.c @@ -148,6 +148,60 @@ static NTSTATUS get_device_id(DEVICE_OBJECT *device, BUS_QUERY_ID_TYPE type, WCH return status; } +static NTSTATUS send_deviceIRP(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 send_pnpIRP(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 send_deviceIRP(device, irp); +} + +static NTSTATUS send_powerIRP(DEVICE_OBJECT *device, DEVICE_POWER_STATE power) +{ + IO_STATUS_BLOCK irp_status; + IO_STACK_LOCATION *irpsp; + + IRP *irp = IoBuildSynchronousFsdRequest(IRP_MJ_POWER, device, NULL, 0, NULL, NULL, &irp_status); + + irpsp = IoGetNextIrpStackLocation(irp); + irpsp->MinorFunction = IRP_MN_SET_POWER; + + irpsp->Parameters.Power.Type = DevicePowerState; + irpsp->Parameters.Power.State.DeviceState = power; + + return send_deviceIRP(device, irp); +} + static void handle_bus_relations(DEVICE_OBJECT *device) { static const WCHAR szDriverW[] = {'\\','D','r','i','v','e','r','\\',0}; @@ -244,6 +298,16 @@ static void handle_bus_relations(DEVICE_OBJECT *device) ERR("AddDevice failed\n"); return; } + + if (device->AttachedDevice) + { + send_pnpIRP(device->AttachedDevice, IRP_MN_START_DEVICE); + send_powerIRP(device->AttachedDevice, PowerDeviceD0); + } + else + { + ERR("No attached device\n"); + } } static void initialize_driver_store(void)