completion routine in IRP_MN_QUERY_DEVICE_RELATIONS

Hi,

I am writing a SCSI port upper filter driver.
I am trying to put a completion routine in IRP_MN_QUERY_DEVICE_RELATIONS.

After the completion routine gets called and the DispatchPnp returns it
BSOD’s with INACCESSIBLE_BOOT_DEVICE

Here’s the code:

case IRP_MN_QUERY_DEVICE_RELATIONS:
{
ULONG i;
NTSTATUS inqStatus;
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
KdPrint((“\nQuerying device relations in port driver\n”));

if (stack->Parameters.QueryDeviceRelations.Type == BusRelations)
{
KdPrint((“Bus relations\n”));
Irp->IoStatus.Status = STATUS_SUCCESS;
status = PortFilterForwardIrpSynchronous(DeviceObject, Irp);
//status = ForwardAndWait(DeviceObject, Irp);

if (!NT_SUCCESS(status))
{
KdPrint((“IRP not successful\n”));
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}

KdPrint((“Bus relations changing DONE\n”));
break;

}
else
{
KdPrint((“\nPortFilterDispatchPnp: Forwarding irp\n”));
return PortFilterSendToNextDriver(DeviceObject, Irp);
}
}

NTSTATUS
PortFilterForwardIrpSynchronous(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)

/*++

Routine Description:

This routine sends the Irp to the next driver in line
when the Irp needs to be processed by the lower drivers
prior to being processed by this one.

Arguments:

DeviceObject
Irp

Return Value:

NTSTATUS

–*/

{
PDEVICE_EXTENSION deviceExtension;
KEVENT event;
NTSTATUS status;

KeInitializeEvent(&event, NotificationEvent, FALSE);
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

//
// copy the irpstack for the next device
//

IoCopyCurrentIrpStackLocationToNext(Irp);

//
// set a completion routine
//

IoSetCompletionRoutine(Irp, PortFilterIrpCompletion,
&event, TRUE, TRUE, TRUE);

//
// call the next lower device
//

status = IoCallDriver(deviceExtension->TargetDeviceObject, Irp);

//
// wait for the actual completion
//

if (status == STATUS_PENDING) {
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
status = Irp->IoStatus.Status;
}

return status;

} // end PortFilterForwardIrpSynchronous()

NTSTATUS
PortFilterIrpCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)

/*++

Routine Description:

Forwarded IRP completion routine. Set an event and return
STATUS_MORE_PROCESSING_REQUIRED. Irp forwarder will wait on this
event and then re-complete the irp after cleaning up.

Arguments:

DeviceObject is the device object of the WMI driver
Irp is the WMI irp that was just completed
Context is a PKEVENT that forwarder will wait on

Return Value:

STATUS_MORE_PORCESSING_REQUIRED

–*/

{
PKEVENT Event = (PKEVENT) Context;

UNREFERENCED_PARAMETER(DeviceObject);
UNREFERENCED_PARAMETER(Irp);

KeSetEvent(Event, IO_NO_INCREMENT, FALSE);

return(STATUS_MORE_PROCESSING_REQUIRED);

} // end PortFilterIrpCompletion()

I’ve also tried ForwardAndWait and OnRequestComplete from Walter Oney’s
book but it does the same BSOD.

Any ideas why this is happening?
I have to put a completion routine here so I can change the relations.

When I comment out the completion routine and send the request to the next
driver the system boots fine.

Thanks

Mike Lamb

I don’t understand why you are only calling IoCompleteRequest for the
failure case after calling PortFilterForwardIrpSynchronous. On the
success-returned path the irp is left in STATUS_MORE_PROCESSING_REQUIRED
state, and this could account for the 7B crash.

Your completion routine must test Irp->PendingReturned and call
IoMarkIrpPending(Irp) if it is set.

Mark Roddy
Windows 2000/NT Consultant
Hollis Technology Solutions
www.hollistech.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of xxxxx@tivoli.com
Sent: Friday, September 15, 2000 12:00 AM
To: NT Developers Interest List
Subject: [ntdev] completion routine in IRP_MN_QUERY_DEVICE_RELATIONS

Hi,

I am writing a SCSI port upper filter driver.
I am trying to put a completion routine in IRP_MN_QUERY_DEVICE_RELATIONS.

After the completion routine gets called and the DispatchPnp returns it
BSOD’s with INACCESSIBLE_BOOT_DEVICE

Here’s the code:

case IRP_MN_QUERY_DEVICE_RELATIONS:
{
ULONG i;
NTSTATUS inqStatus;
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
KdPrint((“\nQuerying device relations in port driver\n”));

if (stack->Parameters.QueryDeviceRelations.Type == BusRelations)
{
KdPrint((“Bus relations\n”));
Irp->IoStatus.Status = STATUS_SUCCESS;
status = PortFilterForwardIrpSynchronous(DeviceObject, Irp);
//status = ForwardAndWait(DeviceObject, Irp);

if (!NT_SUCCESS(status))
{
KdPrint((“IRP not successful\n”));
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}

KdPrint((“Bus relations changing DONE\n”));
break;

}
else
{
KdPrint((“\nPortFilterDispatchPnp: Forwarding irp\n”));
return PortFilterSendToNextDriver(DeviceObject, Irp);
}
}

NTSTATUS
PortFilterForwardIrpSynchronous(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)

/*++

Routine Description:

This routine sends the Irp to the next driver in line
when the Irp needs to be processed by the lower drivers
prior to being processed by this one.

Arguments:

DeviceObject
Irp

Return Value:

NTSTATUS

–*/

{
PDEVICE_EXTENSION deviceExtension;
KEVENT event;
NTSTATUS status;

KeInitializeEvent(&event, NotificationEvent, FALSE);
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

//
// copy the irpstack for the next device
//

IoCopyCurrentIrpStackLocationToNext(Irp);

//
// set a completion routine
//

IoSetCompletionRoutine(Irp, PortFilterIrpCompletion,
&event, TRUE, TRUE, TRUE);

//
// call the next lower device
//

status = IoCallDriver(deviceExtension->TargetDeviceObject, Irp);

//
// wait for the actual completion
//

if (status == STATUS_PENDING) {
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
status = Irp->IoStatus.Status;
}

return status;

} // end PortFilterForwardIrpSynchronous()

NTSTATUS
PortFilterIrpCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)

/*++

Routine Description:

Forwarded IRP completion routine. Set an event and return
STATUS_MORE_PROCESSING_REQUIRED. Irp forwarder will wait on this
event and then re-complete the irp after cleaning up.

Arguments:

DeviceObject is the device object of the WMI driver
Irp is the WMI irp that was just completed
Context is a PKEVENT that forwarder will wait on

Return Value:

STATUS_MORE_PORCESSING_REQUIRED

–*/

{
PKEVENT Event = (PKEVENT) Context;

UNREFERENCED_PARAMETER(DeviceObject);
UNREFERENCED_PARAMETER(Irp);

KeSetEvent(Event, IO_NO_INCREMENT, FALSE);

return(STATUS_MORE_PROCESSING_REQUIRED);

} // end PortFilterIrpCompletion()

I’ve also tried ForwardAndWait and OnRequestComplete from Walter Oney’s
book but it does the same BSOD.

Any ideas why this is happening?
I have to put a completion routine here so I can change the relations.

When I comment out the completion routine and send the request to
the next
driver the system boots fine.

Thanks

Mike Lamb


You are currently subscribed to ntdev as: xxxxx@wattanuck.mv.com
To unsubscribe send a blank email to $subst(‘Email.Unsub’)

mike,
a small query, why is the irp being sent twice to the lower driver,
thru’
PortFilterForwardIrpSynchronous and ForwardAndWait.

chaitanya

----- Original Message -----
From:
To: NT Developers Interest List
Sent: Friday, September 15, 2000 12:00 AM
Subject: [ntdev] completion routine in IRP_MN_QUERY_DEVICE_RELATIONS

> Hi,
>
> I am writing a SCSI port upper filter driver.
> I am trying to put a completion routine in IRP_MN_QUERY_DEVICE_RELATIONS.
>
> After the completion routine gets called and the DispatchPnp returns it
> BSOD’s with INACCESSIBLE_BOOT_DEVICE
>
>
>
> Here’s the code:
>
>
> case IRP_MN_QUERY_DEVICE_RELATIONS:
> {
> ULONG i;
> NTSTATUS inqStatus;
> PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
> KdPrint((“\nQuerying device relations in port driver\n”));
>
> if (stack->Parameters.QueryDeviceRelations.Type == BusRelations)
> {
> KdPrint((“Bus relations\n”));
> Irp->IoStatus.Status = STATUS_SUCCESS;
> status = PortFilterForwardIrpSynchronous(DeviceObject, Irp);
> file://status = ForwardAndWait(DeviceObject, Irp);
>
> if (!NT_SUCCESS(status))
> {
> KdPrint((“IRP not successful\n”));
> Irp->IoStatus.Status = status;
> IoCompleteRequest(Irp, IO_NO_INCREMENT);
> }
>
>
> KdPrint((“Bus relations changing DONE\n”));
> break;
>
> }
> else
> {
> KdPrint((“\nPortFilterDispatchPnp: Forwarding irp\n”));
> return PortFilterSendToNextDriver(DeviceObject, Irp);
> }
> }
>
>
>
>
> NTSTATUS
> PortFilterForwardIrpSynchronous(
> IN PDEVICE_OBJECT DeviceObject,
> IN PIRP Irp
> )
>
> /++
>
> Routine Description:
>
> This routine sends the Irp to the next driver in line
> when the Irp needs to be processed by the lower drivers
> prior to being processed by this one.
>
> Arguments:
>
> DeviceObject
> Irp
>
> Return Value:
>
> NTSTATUS
>
> –
/
>
> {
> PDEVICE_EXTENSION deviceExtension;
> KEVENT event;
> NTSTATUS status;
>
> KeInitializeEvent(&event, NotificationEvent, FALSE);
> deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
>
> //
> // copy the irpstack for the next device
> //
>
> IoCopyCurrentIrpStackLocationToNext(Irp);
>
> //
> // set a completion routine
> //
>
> IoSetCompletionRoutine(Irp, PortFilterIrpCompletion,
> &event, TRUE, TRUE, TRUE);
>
> //
> // call the next lower device
> //
>
> status = IoCallDriver(deviceExtension->TargetDeviceObject, Irp);
>
> //
> // wait for the actual completion
> //
>
> if (status == STATUS_PENDING) {
> KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
> status = Irp->IoStatus.Status;
> }
>
> return status;
>
> } // end PortFilterForwardIrpSynchronous()
>
>
>
> NTSTATUS
> PortFilterIrpCompletion(
> IN PDEVICE_OBJECT DeviceObject,
> IN PIRP Irp,
> IN PVOID Context
> )
>
> /++
>
> Routine Description:
>
> Forwarded IRP completion routine. Set an event and return
> STATUS_MORE_PROCESSING_REQUIRED. Irp forwarder will wait on this
> event and then re-complete the irp after cleaning up.
>
> Arguments:
>
> DeviceObject is the device object of the WMI driver
> Irp is the WMI irp that was just completed
> Context is a PKEVENT that forwarder will wait on
>
> Return Value:
>
> STATUS_MORE_PORCESSING_REQUIRED
>
> –
/
>
> {
> PKEVENT Event = (PKEVENT) Context;
>
> UNREFERENCED_PARAMETER(DeviceObject);
> UNREFERENCED_PARAMETER(Irp);
>
> KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
>
> return(STATUS_MORE_PROCESSING_REQUIRED);
>
> } // end PortFilterIrpCompletion()
>
>
>
> I’ve also tried ForwardAndWait and OnRequestComplete from Walter Oney’s
> book but it does the same BSOD.
>
>
> Any ideas why this is happening?
> I have to put a completion routine here so I can change the relations.
>
> When I comment out the completion routine and send the request to the next
> driver the system boots fine.
>
> Thanks
>
> Mike Lamb
>
> —
> You are currently subscribed to ntdev as: xxxxx@cmcltd.com
> To unsubscribe send a blank email to $subst(‘Email.Unsub’)