IEEE 1394 Streaming Filter Driver IRP Processing Requirements Complex Form (Windows CE 5.0)
The following code sample is significantly more complex than the previous, but handles more realistic situations where your driver has allocated some sort of resources on the context of the create vector. In that case, if the lower-level drivers fail the IRP when you send it down to them, your code will need to have a failure path, where it frees the resources previously allocated before propagating the returned error from the lower-level drivers and failing the IRP itself.
static NTSTATUS YourSubunit_Create_Complete(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
{
UNREFERENCED_PARAMETER (DeviceObject);
if (Irp->PendingReturned)
{
IoMarkIrpPending(Irp);
}
KeSetEvent ((PKEVENT) Context, 1, FALSE);
return STATUS_MORE_PROCESSING_REQUIRED;
}
static NTSTATUS YourSubunit_CreateVector(PDEVICE_OBJECT devObj, PIRP Irp)
{
NTSTATUS status;
KEVENT event;
PIO_STACK_LOCATION IrpStack;
//
// Local allocations and processing would typically be done here,
// before the IRP was sent to the next lower-level driver.
//
// <<Local Processing>>
//
// Send the IRP down and wait for it to complete.
//
IrpStack = IoGetCurrentIrpStackLocation(Irp);
KeInitializeEvent(&event, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp, YourSubunit_Create_Complete, &event, TRUE, TRUE, TRUE);
//
// 'ParentDeviceObject', below, is the value returned from your call to
// IoAttachDeviceToDeviceStack().
//
status = IoCallDriver(ParentDeviceObject, Irp);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
}
status = Irp->IoStatus.Status;
if (!NT_SUCCESS(status))
{
// The lower-level driver(s) failed the request.
// We need to release any resources we allocated
// in our Local Processing.
// <<Free Local Resources>>
}
return(status);
}
Send Feedback on this topic to the authors