PIRP
IoBuildDeviceIoControlRequest(
IN ULONG IoControlCode,
IN PDEVICE_OBJECT DeviceObject,
IN PVOID InputBuffer, /* optional */
IN ULONG InputBufferLength,
IN OUT PVOID OutputBuffer, /* optional */
IN ULONG OutputBufferLength,
IN BOOLEAN InternalDeviceIoControl,
IN PKEVENT Event,
OUT PIO_STATUS_BLOCK IoStatusBlock
);
IoBuildDeviceIoControlRequest allocates and sets up an IRP for a device control request, optionally with an I/O buffer if the I/O control code requires the caller to supply an input or output buffer.
IoBuildDeviceIoControlRequest returns a pointer to an IRP with the next-lower driver’s I/O stack location partially set up from the supplied parameters. The returned pointer is NULL if an IRP cannot be allocated.
An intermediate or highest-level driver can call IoBuildDeviceIoControlRequest to set up IRPs for requests sent to lower-level drivers. The next-lower driver’s I/O stack location is set up with the given IoControlCode at Parameters.DeviceIoControl.IoControlCode. Because the caller can wait on the completion of this driver-allocated IRP by calling KeWaitForSingleObject on the given Event, the caller need not set an IoCompletion routine in the IRP before calling IoCallDriver. When the next-lower driver completes this IRP, the I/O Manager releases it.
Callers of IoBuildDeviceIoControlRequest must be running at IRQL PASSIVE_LEVEL.
IO_STACK_LOCATION, IoAllocateIrp, IoBuildAsynchronousFsdRequest, IoBuildSynchronousFsdRequest, IoCallDriver, IoCompleteRequest, IRP, KeInitializeEvent, KeWaitForSingleObject