[PATCH 3/4] ntoskrnl.exe: Send PnP and Power IRPs to plug and play devices

Sebastian Lackner sebastian at fds-team.de
Wed Aug 31 02:42:15 CDT 2016


On 29.08.2016 20:49, Aric Stewart wrote:
> 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 <aric at codeweavers.com>
> ---
>  dlls/ntoskrnl.exe/pnp_manager.c | 64 +++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 64 insertions(+)
> 
> 
> 
> 0003-ntoskrnl.exe-Send-PnP-and-Power-IRPs-to-plug-and-play-.txt
> 
> 
> 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;
> +}

Such a helper function could also be used to simplify get_device_id.

> +
> +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);

It would be better to handle failure of IoBuildSynchronousFsdRequest like in get_device_id.
The same also applies to send_powerIRP() below.

> +
> +    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)

Please check if its possible to (partially) move this to PoRequestPowerIrp().
If there is not enough information we can keep it like that for now, but according
to the description it sounds very similar.

> +{
> +    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)
> 
> 
> 




More information about the wine-devel mailing list