From: Aric Stewart Subject: [PATCH v2 3/4] ntoskrnl.exe: Send PnP and Power IRPs to plug and play devices Message-Id: <5fb795e3-1822-cf17-df23-58086d38a25c@codeweavers.com> Date: Wed, 31 Aug 2016 11:38:40 -0500 v2: use same helper function as get_device_id Suggestions from Sebastian Lackner 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 | 47 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/dlls/ntoskrnl.exe/pnp_manager.c b/dlls/ntoskrnl.exe/pnp_manager.c index 04b218b..4bde2b6 100644 --- a/dlls/ntoskrnl.exe/pnp_manager.c +++ b/dlls/ntoskrnl.exe/pnp_manager.c @@ -135,6 +135,42 @@ static NTSTATUS find_driver_for_id(const WCHAR *id, WCHAR *driver) return rc; } +static NTSTATUS send_pnp_irp(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); + if (irp == NULL) + return STATUS_NO_MEMORY; + + irpsp = IoGetNextIrpStackLocation(irp); + irpsp->MinorFunction = minor; + + irpsp->Parameters.StartDevice.AllocatedResources = NULL; + irpsp->Parameters.StartDevice.AllocatedResourcesTranslated = NULL; + + return send_device_irp(device, irp, NULL); +} + +static NTSTATUS send_power_irp(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); + if (irp == NULL) + return STATUS_NO_MEMORY; + + irpsp = IoGetNextIrpStackLocation(irp); + irpsp->MinorFunction = IRP_MN_SET_POWER; + + irpsp->Parameters.Power.Type = DevicePowerState; + irpsp->Parameters.Power.State.DeviceState = power; + + return send_device_irp(device, irp, NULL); +} + static void handle_bus_relations(DEVICE_OBJECT *device) { static const WCHAR driverW[] = {'\\','D','r','i','v','e','r','\\',0}; @@ -210,7 +246,18 @@ static void handle_bus_relations(DEVICE_OBJECT *device) ObDereferenceObject(driver_obj); if (status != STATUS_SUCCESS) + { ERR("AddDevice failed for driver %s\n", debugstr_w(driver)); + return; + } + + if (device->AttachedDevice) + { + send_pnp_irp(device->AttachedDevice, IRP_MN_START_DEVICE); + send_power_irp(device->AttachedDevice, PowerDeviceD0); + } + else + ERR("No attached device (driver %s)\n", debugstr_w(driver)); } /***********************************************************************