trouble with completing irp

hi!
I’m beginer in writing drivers and need some help. I’m writing a kernel
driver, creating serial-like device to get i/o request from some aplication
and redirect its to TDI. I’ve known how to interact with TDI, I think so,
the trouble at another point.
When I get IRP (write, read, io_control) I create new IRP to send it down
to tcp/ip driver. I use TdiBuildInternalDeviceControlIrp and TdiBuildxxx
macros. I set completion routine to complete orginal IRP if only lower
driver finishing its work. I can’t use EventObject because I have to handle
overlapped calls from application. IoCallDriver return with pending status,
and i finish dispatch routine with the same status. Then my completion
routine is called, but here starts the trouble. If only I’m trying to
complet original request after return from my routine an blue screen
occurs. But if I didn’t complete original irp, the application which had
sent it would stall. I’ve tried returning with status_success and
status_more_procesing_required.
I’m not sure what about PendingReturned flag in IRP struct, I’ve read
there’s need to check it and call IoMarkIrpPending.
I’ve seeked the ntdev mailinglist, but i can’t get any solution on my
question. I hope there’s somebody how can help me. Thanks a lot.

Sebastian Slezak
software developer, Mikronika, Poland

Here is my completion routine:

NTSTATUS SetBaudRate_Completion( IN PDEVICE_OBJECT DeviceObject, IN PIRP
Irp, IN PVOID Context )
{
NTSTATUS Status;
PVSERIAL_DEVICE_EXTENSION Extension = Context;
PVOID SystemBuffer;

KdPrint(( “completion routine set_baud_rate\n”));

Status = Irp->IoStatus.Status;
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;

if ( NT_SUCCESS( Status ) )
{
Extension->CurrentBaud = *(PSERIAL_BAUD_RATE)SystemBuffer;
KdPrint(( “pending set_baud_rate IRP completed successful, Information =
%u\n”, Irp->IoStatus.Information ));
}

Extension->CurrentWriteIrp->IoStatus.Status = Status;

IoCompleteRequest( Extension->CurrentWriteIrp, IO_NETWORK_INCREMENT );

Extension->CurrentWriteIrp = NULL;

if (Irp->PendingReturned)
IoMarkIrpPending(Irp);

return STATUS_MORE_PROCESSING_REQUIRED;
return STATUS_SUCCESS;

Here is a piece of code from dispatch routine which call lower driver:


SendDatagramIrp = TdiBuildInternalDeviceControlIrp (
TDI_SENDDATAGRAM,
Extension->pUdpDeviceObject,
Extension->pTransAddrFileObject_SerialCtrl,
NULL,//&NotifyEvent,
&IoStatusBlock
);

if ( !SendDatagramIrp ) return STATUS_INSUFFICIENT_RESOURCES;

Mdl = IoAllocateMdl( DataBuffer, DataSize, FALSE, FALSE, NULL );

if ( !Mdl )
{
IoFreeIrp( SendDatagramIrp );
return STATUS_INSUFFICIENT_RESOURCES;
}

MmProbeAndLockPages( Mdl, KernelMode, IoReadAccess );

TdiBuildSendDatagram (
SendDatagramIrp,
Extension->pTcpDeviceObject,
Extension->pTransAddrFileObject_SerialCtrl,
SetBaudRate_Completion, // completion routine
Extension, // contex for completion routine
Mdl, // descriptor for data buffer
DataSize,
&SendDatagramInfo
);

SendDatagramIrp->UserIosb = &IoStatusBlock;

Status = IoCallDriver( Extension->pUdpDeviceObject, SendDatagramIrp );
IoMarkIrpPending( Irp );

return Status;


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

Mark it pending before you make the call to IoCallDriver().

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Sebastian Slezak
Sent: Tuesday, November 27, 2001 11:01 AM
To: NT Developers Interest List
Subject: [ntdev] trouble with completing irp

hi!
I’m beginer in writing drivers and need some help. I’m writing a kernel
driver, creating serial-like device to get i/o request from some
aplication
and redirect its to TDI. I’ve known how to interact with TDI, I think
so,
the trouble at another point.
When I get IRP (write, read, io_control) I create new IRP to send it
down
to tcp/ip driver. I use TdiBuildInternalDeviceControlIrp and TdiBuildxxx

macros. I set completion routine to complete orginal IRP if only lower
driver finishing its work. I can’t use EventObject because I have to
handle
overlapped calls from application. IoCallDriver return with pending
status,
and i finish dispatch routine with the same status. Then my completion
routine is called, but here starts the trouble. If only I’m trying to
complet original request after return from my routine an blue screen
occurs. But if I didn’t complete original irp, the application which had

sent it would stall. I’ve tried returning with status_success and
status_more_procesing_required.
I’m not sure what about PendingReturned flag in IRP struct, I’ve read
there’s need to check it and call IoMarkIrpPending.
I’ve seeked the ntdev mailinglist, but i can’t get any solution on my
question. I hope there’s somebody how can help me. Thanks a lot.

Sebastian Slezak
software developer, Mikronika, Poland

Here is my completion routine:

NTSTATUS SetBaudRate_Completion( IN PDEVICE_OBJECT DeviceObject, IN PIRP

Irp, IN PVOID Context )
{
NTSTATUS Status;
PVSERIAL_DEVICE_EXTENSION Extension = Context;
PVOID SystemBuffer;

KdPrint(( “completion routine set_baud_rate\n”));

Status = Irp->IoStatus.Status;
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;

if ( NT_SUCCESS( Status ) )
{
Extension->CurrentBaud =
*(PSERIAL_BAUD_RATE)SystemBuffer;
KdPrint(( “pending set_baud_rate IRP completed
successful, Information =
%u\n”, Irp->IoStatus.Information ));
}

Extension->CurrentWriteIrp->IoStatus.Status = Status;

IoCompleteRequest( Extension->CurrentWriteIrp,
IO_NETWORK_INCREMENT );

Extension->CurrentWriteIrp = NULL;

if (Irp->PendingReturned)
IoMarkIrpPending(Irp);

return STATUS_MORE_PROCESSING_REQUIRED;
return STATUS_SUCCESS;

Here is a piece of code from dispatch routine which call lower driver:


SendDatagramIrp = TdiBuildInternalDeviceControlIrp (
TDI_SENDDATAGRAM,
Extension->pUdpDeviceObject,
Extension->pTransAddrFileObject_SerialCtrl,
NULL,//&NotifyEvent,
&IoStatusBlock
);

if ( !SendDatagramIrp ) return STATUS_INSUFFICIENT_RESOURCES;

Mdl = IoAllocateMdl( DataBuffer, DataSize, FALSE, FALSE, NULL );

if ( !Mdl )
{
IoFreeIrp( SendDatagramIrp );
return STATUS_INSUFFICIENT_RESOURCES;
}

MmProbeAndLockPages( Mdl, KernelMode, IoReadAccess );

TdiBuildSendDatagram (
SendDatagramIrp,
Extension->pTcpDeviceObject,
Extension->pTransAddrFileObject_SerialCtrl,
SetBaudRate_Completion, // completion routine
Extension, // contex for completion routine
Mdl, // descriptor for data buffer
DataSize,
&SendDatagramInfo
);

SendDatagramIrp->UserIosb = &IoStatusBlock;

Status = IoCallDriver( Extension->pUdpDeviceObject,
SendDatagramIrp );
IoMarkIrpPending( Irp );

return Status;


You are currently subscribed to ntdev as: xxxxx@storagecraft.com To
unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

…but I’ve marked pending original irp (which my driver obtains from io
manager), before call lower driver and there’s the same effect: if
completion routine call IoCompletRequest with the original irp, system will
crash with bugcode 44 (MULTIPLE_IRP_COMPLETE_REQUESTS). I see, you don’t
meam to mark pending this irp, I’ve created to send TDI request, do I?
Maybe I have to do some additional work with one. Thanks a for help.

Sebastian Slezak


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

IoMarkIrpPending(OriginalIrp);
PutIrpOnQueue(OriginalIrp);
IoCallDriver(TdiIrp);
return STATUS_PENDING; // ignore the return value from iocalldriver!
}

CompletionHandler(TdiIrp,…)
{
if (TdiIrp->PendingReturned) {
IoMarkIrpPending(TdiIrp);
}
IoCompleteRequest(OriginalIrp,…);

DoSomethingWithTheTdiIrp(TdiIrp);

Return STATUS_MORE_PROCESSING_REQUIRED;
}

You have to both mark the irp pending on the dispatch side and return
status pending on the dispatch side, or you will get a multiple irp
completions bug from your completion handler.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Sebastian Slezak
Sent: Wednesday, November 28, 2001 2:53 AM
To: NT Developers Interest List
Subject: [ntdev] RE: trouble with completing irp

…but I’ve marked pending original irp (which my driver
obtains from io
manager), before call lower driver and there’s the same effect: if
completion routine call IoCompletRequest with the original
irp, system will
crash with bugcode 44 (MULTIPLE_IRP_COMPLETE_REQUESTS). I
see, you don’t
meam to mark pending this irp, I’ve created to send TDI
request, do I?
Maybe I have to do some additional work with one. Thanks a for help.

Sebastian Slezak


You are currently subscribed to ntdev as:
xxxxx@hollistech.com To unsubscribe send a blank email to
leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com