q about driver allocated IRPs

Hi,

i’m writting a virtual serial port driver which redirects all incoming
IRPs to another
serial port (this is to make for example COM28 available to applications
which don’t
enumerate all serial ports but instead just provide 4 radio buttons to
select COM1-COM4
and is also the first driver i am writting…)

my driver is not directly layered onto some serial ports driver (because
i want a new serial port
to become reserved by the system) but opens a DeviceObject pointer to
the “underlaying” driver through a
IoGetDeviceObjectPointer call from within IRP_MJ_CREATE dispatch routine.

now my problem is that all the IRP_MJ_xxx dispatch routines work fine
except from the IRP_MJ_READ routine.
my READ dispatch routine is getting called, marks the current IRP
pending, allocates a new IRP, sets a completion
routine and calls the “underlaying” driver. as some character is
received my completion routine is getting called,
frees the allocated IRP, completes the original IRP and returns
STATUS_MORE_PROCESSING_REQUIRED.
but hyperterminal simply doesnt display the received character, although
it recognizes the completed IRP and issues
a new read request.

so my first question is wheter or not i need to copy the buffer of the
driver-allocated IRP to original IRPs buffer ?
my second question is whether or not i need to adjust the IRP Stack Size
of my drivers DeviceObject in that case ?

and my third question (although unrelated to this topic) is if there’s
some way to change the com port number of my
driver that’s displayed by device manager (of course if i took care that
this port is not used otherwise, before…) ?

thx a lot.
regards, daniel.

Are you setting Irp->IoStatus.Information in the original irp with the
Information value from your own completed irp?

As for the com port name, if you are installed as a pnp device, the com
port name arbiter gives you the name at install time. you can change the
name using the ComDB functions (see the latest DDK).

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of L3sT4Rd
Sent: Saturday, January 28, 2006 3:52 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] q about driver allocated IRPs

Hi,

i’m writting a virtual serial port driver which redirects all incoming
IRPs to another
serial port (this is to make for example COM28 available to applications

which don’t
enumerate all serial ports but instead just provide 4 radio buttons to
select COM1-COM4
and is also the first driver i am writting…)

my driver is not directly layered onto some serial ports driver (because

i want a new serial port
to become reserved by the system) but opens a DeviceObject pointer to
the “underlaying” driver through a
IoGetDeviceObjectPointer call from within IRP_MJ_CREATE dispatch
routine.

now my problem is that all the IRP_MJ_xxx dispatch routines work fine
except from the IRP_MJ_READ routine.
my READ dispatch routine is getting called, marks the current IRP
pending, allocates a new IRP, sets a completion
routine and calls the “underlaying” driver. as some character is
received my completion routine is getting called,
frees the allocated IRP, completes the original IRP and returns
STATUS_MORE_PROCESSING_REQUIRED.
but hyperterminal simply doesnt display the received character, although

it recognizes the completed IRP and issues
a new read request.

so my first question is wheter or not i need to copy the buffer of the
driver-allocated IRP to original IRPs buffer ?
my second question is whether or not i need to adjust the IRP Stack Size

of my drivers DeviceObject in that case ?

and my third question (although unrelated to this topic) is if there’s
some way to change the com port number of my
driver that’s displayed by device manager (of course if i took care that

this port is not used otherwise, before…) ?

thx a lot.
regards, daniel.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Doron Holan wrote:

Are you setting Irp->IoStatus.Information in the original irp with the
Information value from your own completed irp?

i tried this, makes no difference.
but i thought i do not need to set Information field because
i’m passing a pointer to the original IRPs IoStatus Block to
the IoBuildAsynchronousFsdRequest call…!?

this is the code, perhaps somebody can tell me
what’s wrong with it ?

NTSTATUS SerMapRead(IN PDEVICE_OBJECT DeviceObject, IN PIRP pIrp)
{
PIRP lowerIrp;
PDEVICE_EXTENSION extension;
PIO_STACK_LOCATION irpStackLocation;

extension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;

KdPrint( (“SerMap: Read\n”) );

if (NULL == extension->mappedDevice)
{
KdPrint( (" …failed (not inited) !\n") );
pIrp->IoStatus.Status = STATUS_CANCELLED;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_CANCELLED;
}

irpStackLocation = IoGetCurrentIrpStackLocation(pIrp);
IoMarkIrpPending(pIrp);
lowerIrp = IoBuildAsynchronousFsdRequest(IRP_MJ_READ,
extension->mappedDevice,

pIrp->AssociatedIrp.SystemBuffer,

irpStackLocation->Parameters.Read.Length,

&irpStackLocation->Parameters.Read.ByteOffset,
&pIrp->IoStatus);
if (NULL == lowerIrp)
{
KdPrint( (“…failed to allocate IRP.”) );
pIrp->IoStatus.Status = STATUS_CANCELLED;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_CANCELLED;
}

IoSetCompletionRoutine(lowerIrp, SerMapReadCompletion, (PVOID)pIrp,
TRUE, TRUE, TRUE);
IoCallDriver(extension->mappedDevice, lowerIrp);
return STATUS_PENDING;
}

NTSTATUS SerMapReadCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP
pIrp, IN PVOID Context)
{
PIRP pOrgIrp = (PIRP)Context;

KdPrint( (“SerMap: Read completion routine.\n”) );

//pOrgIrp->IoStatus.Information = pIrp->IoStatus.Information;

IoFreeIrp(pIrp);
IoCompleteRequest(pOrgIrp, IO_NO_INCREMENT);
return STATUS_MORE_PROCESSING_REQUIRED;
}

As for the com port name, if you are installed as a pnp device, the com
port name arbiter gives you the name at install time. you can change the
name using the ComDB functions (see the latest DDK).

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of L3sT4Rd
Sent: Saturday, January 28, 2006 3:52 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] q about driver allocated IRPs

Hi,

i’m writting a virtual serial port driver which redirects all incoming
IRPs to another
serial port (this is to make for example COM28 available to applications

which don’t
enumerate all serial ports but instead just provide 4 radio buttons to
select COM1-COM4
and is also the first driver i am writting…)

my driver is not directly layered onto some serial ports driver (because

i want a new serial port
to become reserved by the system) but opens a DeviceObject pointer to
the “underlaying” driver through a
IoGetDeviceObjectPointer call from within IRP_MJ_CREATE dispatch
routine.

now my problem is that all the IRP_MJ_xxx dispatch routines work fine
except from the IRP_MJ_READ routine.
my READ dispatch routine is getting called, marks the current IRP
pending, allocates a new IRP, sets a completion
routine and calls the “underlaying” driver. as some character is
received my completion routine is getting called,
frees the allocated IRP, completes the original IRP and returns
STATUS_MORE_PROCESSING_REQUIRED.
but hyperterminal simply doesnt display the received character, although

it recognizes the completed IRP and issues
a new read request.

so my first question is wheter or not i need to copy the buffer of the
driver-allocated IRP to original IRPs buffer ?
my second question is whether or not i need to adjust the IRP Stack Size

of my drivers DeviceObject in that case ?

and my third question (although unrelated to this topic) is if there’s
some way to change the com port number of my
driver that’s displayed by device manager (of course if i took care that

this port is not used otherwise, before…) ?

thx a lot.
regards, daniel.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: unknown lmsubst tag argument: ‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com

Can’t tell just from looking at the code, but I have a couple of other
suggestions

  1. once you mark an irp pending you are *required* to return
    STATUS_PENDING from the dispatch routine, so I would mark the irp
    pendingo only after you have allocated your 2ndary PIRP
  2. if the allocation of the 2ndary PIRP fails, I would return
    STATUS_INSUFFICIENT_RESOURCES, not STATUS_CANCELLED. STATUS_CANCELLED
    means that someone actually canceled the i/o and there may be state in
    the app sending the i/o that explicitly checks for canceled and does
    something different
  3. speaking of cancellation, if the original PIRP is canceled, your
    underlying PIRP is not canceled, so you are effectively hanging the app
    until the underlying PIRP completes. That is not good.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of L3sT4Rd
Sent: Sunday, January 29, 2006 6:01 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] q about driver allocated IRPs

Doron Holan wrote:

Are you setting Irp->IoStatus.Information in the original irp with the
Information value from your own completed irp?

i tried this, makes no difference.
but i thought i do not need to set Information field because
i’m passing a pointer to the original IRPs IoStatus Block to
the IoBuildAsynchronousFsdRequest call…!?

this is the code, perhaps somebody can tell me
what’s wrong with it ?

NTSTATUS SerMapRead(IN PDEVICE_OBJECT DeviceObject, IN PIRP pIrp)
{
PIRP lowerIrp;
PDEVICE_EXTENSION extension;
PIO_STACK_LOCATION irpStackLocation;

extension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;

KdPrint( (“SerMap: Read\n”) );

if (NULL == extension->mappedDevice)
{
KdPrint( (" …failed (not inited) !\n") );
pIrp->IoStatus.Status = STATUS_CANCELLED;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_CANCELLED;
}

irpStackLocation = IoGetCurrentIrpStackLocation(pIrp);
IoMarkIrpPending(pIrp);
lowerIrp = IoBuildAsynchronousFsdRequest(IRP_MJ_READ,
extension->mappedDevice,

pIrp->AssociatedIrp.SystemBuffer,

irpStackLocation->Parameters.Read.Length,

&irpStackLocation->Parameters.Read.ByteOffset,
&pIrp->IoStatus);
if (NULL == lowerIrp)
{
KdPrint( (“…failed to allocate IRP.”) );
pIrp->IoStatus.Status = STATUS_CANCELLED;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_CANCELLED;
}

IoSetCompletionRoutine(lowerIrp, SerMapReadCompletion, (PVOID)pIrp,
TRUE, TRUE, TRUE);
IoCallDriver(extension->mappedDevice, lowerIrp);
return STATUS_PENDING;
}

NTSTATUS SerMapReadCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP
pIrp, IN PVOID Context)
{
PIRP pOrgIrp = (PIRP)Context;

KdPrint( (“SerMap: Read completion routine.\n”) );

//pOrgIrp->IoStatus.Information = pIrp->IoStatus.Information;

IoFreeIrp(pIrp);
IoCompleteRequest(pOrgIrp, IO_NO_INCREMENT);
return STATUS_MORE_PROCESSING_REQUIRED;
}

As for the com port name, if you are installed as a pnp device, the com
port name arbiter gives you the name at install time. you can change
the
name using the ComDB functions (see the latest DDK).

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of L3sT4Rd
Sent: Saturday, January 28, 2006 3:52 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] q about driver allocated IRPs

Hi,

i’m writting a virtual serial port driver which redirects all incoming
IRPs to another
serial port (this is to make for example COM28 available to
applications

which don’t
enumerate all serial ports but instead just provide 4 radio buttons to
select COM1-COM4
and is also the first driver i am writting…)

my driver is not directly layered onto some serial ports driver
(because

i want a new serial port
to become reserved by the system) but opens a DeviceObject pointer to
the “underlaying” driver through a
IoGetDeviceObjectPointer call from within IRP_MJ_CREATE dispatch
routine.

now my problem is that all the IRP_MJ_xxx dispatch routines work fine
except from the IRP_MJ_READ routine.
my READ dispatch routine is getting called, marks the current IRP
pending, allocates a new IRP, sets a completion
routine and calls the “underlaying” driver. as some character is
received my completion routine is getting called,
frees the allocated IRP, completes the original IRP and returns
STATUS_MORE_PROCESSING_REQUIRED.
but hyperterminal simply doesnt display the received character,
although

it recognizes the completed IRP and issues
a new read request.

so my first question is wheter or not i need to copy the buffer of the
driver-allocated IRP to original IRPs buffer ?
my second question is whether or not i need to adjust the IRP Stack
Size

of my drivers DeviceObject in that case ?

and my third question (although unrelated to this topic) is if there’s
some way to change the com port number of my
driver that’s displayed by device manager (of course if i took care
that

this port is not used otherwise, before…) ?

thx a lot.
regards, daniel.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: unknown lmsubst tag argument:
‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Doron Holan wrote:

Can’t tell just from looking at the code, but I have a couple of other
suggestions

  1. once you mark an irp pending you are *required* to return
    STATUS_PENDING from the dispatch routine, so I would mark the irp
    pendingo only after you have allocated your 2ndary PIRP
  2. if the allocation of the 2ndary PIRP fails, I would return
    STATUS_INSUFFICIENT_RESOURCES, not STATUS_CANCELLED. STATUS_CANCELLED
    means that someone actually canceled the i/o and there may be state in
    the app sending the i/o that explicitly checks for canceled and does
    something different

first thanks for your help, i’ll follow your suggestions.
i figured out the problem myself now, it’s been that
although i passed OriginalIrp->AssociatedIrp.SystemBuffer
to the IoBuildAsynchronousFsdRequest routine, the
I/O Manager allocated a new buffer for my driver-created
IRP…

  1. speaking of cancellation, if the original PIRP is canceled, your
    underlying PIRP is not canceled, so you are effectively hanging the app
    until the underlying PIRP completes. That is not good.

this means i need to setup a cancel routine for the
original IRP and from there call IoCancelIrp on the
driver allocated IRP and therefor somehow queue
all forwarded and original IRPs since i can’t pass
a context to the cancel routine, right?

in your first reply you said something about ComDB functions
to change the port name of my virtual port. i can’t find
anything about ComDB (also tried CommDB, Com DB, …)
on MSDN or 2k/2k3/XP IFS & DDK documentation.
could you please give me another keyword / function name
to look for ?
(just for clarification, i’m able to change the SymbolicLink
name and registry settings at the moment, so that my port
becomes accessible under a different name, but device
manager still displays the port name assigned at installation
time and this doesnt look nice and i guess this way it’s
possible that the com port name arbiter or whatever
may assign a name that’s already in use to a new port
installed after my driver has loaded…)

sry for all the questions and again, thx for your help :slight_smile:
daniel.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of L3sT4Rd
Sent: Sunday, January 29, 2006 6:01 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] q about driver allocated IRPs

Doron Holan wrote:

>Are you setting Irp->IoStatus.Information in the original irp with the
>Information value from your own completed irp?
>
>
>
>
i tried this, makes no difference.
but i thought i do not need to set Information field because
i’m passing a pointer to the original IRPs IoStatus Block to
the IoBuildAsynchronousFsdRequest call…!?

this is the code, perhaps somebody can tell me
what’s wrong with it ?

NTSTATUS SerMapRead(IN PDEVICE_OBJECT DeviceObject, IN PIRP pIrp)
{
PIRP lowerIrp;
PDEVICE_EXTENSION extension;
PIO_STACK_LOCATION irpStackLocation;

extension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;

KdPrint( (“SerMap: Read\n”) );

if (NULL == extension->mappedDevice)
{
KdPrint( (" …failed (not inited) !\n") );
pIrp->IoStatus.Status = STATUS_CANCELLED;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_CANCELLED;
}

irpStackLocation = IoGetCurrentIrpStackLocation(pIrp);
IoMarkIrpPending(pIrp);
lowerIrp = IoBuildAsynchronousFsdRequest(IRP_MJ_READ,
extension->mappedDevice,

pIrp->AssociatedIrp.SystemBuffer,

irpStackLocation->Parameters.Read.Length,

&irpStackLocation->Parameters.Read.ByteOffset,
&pIrp->IoStatus);
if (NULL == lowerIrp)
{
KdPrint( (“…failed to allocate IRP.”) );
pIrp->IoStatus.Status = STATUS_CANCELLED;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_CANCELLED;
}

IoSetCompletionRoutine(lowerIrp, SerMapReadCompletion, (PVOID)pIrp,
TRUE, TRUE, TRUE);
IoCallDriver(extension->mappedDevice, lowerIrp);
return STATUS_PENDING;
}

NTSTATUS SerMapReadCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP
pIrp, IN PVOID Context)
{
PIRP pOrgIrp = (PIRP)Context;

KdPrint( (“SerMap: Read completion routine.\n”) );

//pOrgIrp->IoStatus.Information = pIrp->IoStatus.Information;

IoFreeIrp(pIrp);
IoCompleteRequest(pOrgIrp, IO_NO_INCREMENT);
return STATUS_MORE_PROCESSING_REQUIRED;
}

>As for the com port name, if you are installed as a pnp device, the com
>port name arbiter gives you the name at install time. you can change
>
>
the

>name using the ComDB functions (see the latest DDK).
>
>d
>
>-----Original Message-----
>From: xxxxx@lists.osr.com
>[mailto:xxxxx@lists.osr.com] On Behalf Of L3sT4Rd
>Sent: Saturday, January 28, 2006 3:52 PM
>To: Windows System Software Devs Interest List
>Subject: [ntdev] q about driver allocated IRPs
>
>Hi,
>
>i’m writting a virtual serial port driver which redirects all incoming
>IRPs to another
>serial port (this is to make for example COM28 available to
>
>
applications

>which don’t
>enumerate all serial ports but instead just provide 4 radio buttons to
>select COM1-COM4
>and is also the first driver i am writting…)
>
>my driver is not directly layered onto some serial ports driver
>
>
(because

>i want a new serial port
>to become reserved by the system) but opens a DeviceObject pointer to
>the “underlaying” driver through a
>IoGetDeviceObjectPointer call from within IRP_MJ_CREATE dispatch
>routine.
>
>now my problem is that all the IRP_MJ_xxx dispatch routines work fine
>except from the IRP_MJ_READ routine.
>my READ dispatch routine is getting called, marks the current IRP
>pending, allocates a new IRP, sets a completion
>routine and calls the “underlaying” driver. as some character is
>received my completion routine is getting called,
>frees the allocated IRP, completes the original IRP and returns
>STATUS_MORE_PROCESSING_REQUIRED.
>but hyperterminal simply doesnt display the received character,
>
>
although

>it recognizes the completed IRP and issues
>a new read request.
>
>so my first question is wheter or not i need to copy the buffer of the
>driver-allocated IRP to original IRPs buffer ?
>my second question is whether or not i need to adjust the IRP Stack
>
>
Size

>of my drivers DeviceObject in that case ?
>
>and my third question (although unrelated to this topic) is if there’s
>some way to change the com port number of my
>driver that’s displayed by device manager (of course if i took care
>
>
that

>this port is not used otherwise, before…) ?
>
>thx a lot.
>regards, daniel.
>
>
>
>
>—
>Questions? First check the Kernel Driver FAQ at
>http://www.osronline.com/article.cfm?id=256
>
>You are currently subscribed to ntdev as: xxxxx@microsoft.com
>To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>—
>Questions? First check the Kernel Driver FAQ at
>
>
http://www.osronline.com/article.cfm?id=256

>You are currently subscribed to ntdev as: unknown lmsubst tag argument:
>
>
‘’

>To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>
>
>


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: unknown lmsubst tag argument: ‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com

For some reason, I thought that the i/o manager copied the results from
the buffer to the original buffer. I still think it does, I can’t
remember when it does it though.

For the cancel path, you will need to make sure that your allocated irp
is not freed when you are calling IoCancelIrp. Basically, you must
prevent the completion routine from calling IoFreeIrp on it. Oney’s
book has a example on how to manage this race.

See the topic “COM Port Database Support Routines” in the DDK. I saw
this in the server 2003 SP1 DDK. Specifically ComDBReleasePort and
ComDBClaimPort/ClaimNextFreePort

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of L3sT4Rd
Sent: Sunday, January 29, 2006 2:51 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] q about driver allocated IRPs

Doron Holan wrote:

Can’t tell just from looking at the code, but I have a couple of other
suggestions

  1. once you mark an irp pending you are *required* to return
    STATUS_PENDING from the dispatch routine, so I would mark the irp
    pendingo only after you have allocated your 2ndary PIRP
  2. if the allocation of the 2ndary PIRP fails, I would return
    STATUS_INSUFFICIENT_RESOURCES, not STATUS_CANCELLED. STATUS_CANCELLED
    means that someone actually canceled the i/o and there may be state in
    the app sending the i/o that explicitly checks for canceled and does
    something different

first thanks for your help, i’ll follow your suggestions.
i figured out the problem myself now, it’s been that
although i passed OriginalIrp->AssociatedIrp.SystemBuffer
to the IoBuildAsynchronousFsdRequest routine, the
I/O Manager allocated a new buffer for my driver-created
IRP…

  1. speaking of cancellation, if the original PIRP is canceled, your
    underlying PIRP is not canceled, so you are effectively hanging the app
    until the underlying PIRP completes. That is not good.

this means i need to setup a cancel routine for the
original IRP and from there call IoCancelIrp on the
driver allocated IRP and therefor somehow queue
all forwarded and original IRPs since i can’t pass
a context to the cancel routine, right?

in your first reply you said something about ComDB functions
to change the port name of my virtual port. i can’t find
anything about ComDB (also tried CommDB, Com DB, …)
on MSDN or 2k/2k3/XP IFS & DDK documentation.
could you please give me another keyword / function name
to look for ?
(just for clarification, i’m able to change the SymbolicLink
name and registry settings at the moment, so that my port
becomes accessible under a different name, but device
manager still displays the port name assigned at installation
time and this doesnt look nice and i guess this way it’s
possible that the com port name arbiter or whatever
may assign a name that’s already in use to a new port
installed after my driver has loaded…)

sry for all the questions and again, thx for your help :slight_smile:
daniel.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of L3sT4Rd
Sent: Sunday, January 29, 2006 6:01 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] q about driver allocated IRPs

Doron Holan wrote:

>Are you setting Irp->IoStatus.Information in the original irp with the
>Information value from your own completed irp?
>
>
>
>
i tried this, makes no difference.
but i thought i do not need to set Information field because
i’m passing a pointer to the original IRPs IoStatus Block to
the IoBuildAsynchronousFsdRequest call…!?

this is the code, perhaps somebody can tell me
what’s wrong with it ?

NTSTATUS SerMapRead(IN PDEVICE_OBJECT DeviceObject, IN PIRP pIrp)
{
PIRP lowerIrp;
PDEVICE_EXTENSION extension;
PIO_STACK_LOCATION irpStackLocation;

extension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;

KdPrint( (“SerMap: Read\n”) );

if (NULL == extension->mappedDevice)
{
KdPrint( (" …failed (not inited) !\n") );
pIrp->IoStatus.Status = STATUS_CANCELLED;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_CANCELLED;
}

irpStackLocation = IoGetCurrentIrpStackLocation(pIrp);
IoMarkIrpPending(pIrp);
lowerIrp = IoBuildAsynchronousFsdRequest(IRP_MJ_READ,
extension->mappedDevice,

pIrp->AssociatedIrp.SystemBuffer,

irpStackLocation->Parameters.Read.Length,

&irpStackLocation->Parameters.Read.ByteOffset,
&pIrp->IoStatus);
if (NULL == lowerIrp)
{
KdPrint( (“…failed to allocate IRP.”) );
pIrp->IoStatus.Status = STATUS_CANCELLED;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_CANCELLED;
}

IoSetCompletionRoutine(lowerIrp, SerMapReadCompletion, (PVOID)pIrp,

TRUE, TRUE, TRUE);
IoCallDriver(extension->mappedDevice, lowerIrp);
return STATUS_PENDING;
}

NTSTATUS SerMapReadCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP
pIrp, IN PVOID Context)
{
PIRP pOrgIrp = (PIRP)Context;

KdPrint( (“SerMap: Read completion routine.\n”) );

//pOrgIrp->IoStatus.Information = pIrp->IoStatus.Information;

IoFreeIrp(pIrp);
IoCompleteRequest(pOrgIrp, IO_NO_INCREMENT);
return STATUS_MORE_PROCESSING_REQUIRED;
}

>As for the com port name, if you are installed as a pnp device, the
com
>port name arbiter gives you the name at install time. you can change
>
>
the

>name using the ComDB functions (see the latest DDK).
>
>d
>
>-----Original Message-----
>From: xxxxx@lists.osr.com
>[mailto:xxxxx@lists.osr.com] On Behalf Of L3sT4Rd
>Sent: Saturday, January 28, 2006 3:52 PM
>To: Windows System Software Devs Interest List
>Subject: [ntdev] q about driver allocated IRPs
>
>Hi,
>
>i’m writting a virtual serial port driver which redirects all incoming

>IRPs to another
>serial port (this is to make for example COM28 available to
>
>
applications

>which don’t
>enumerate all serial ports but instead just provide 4 radio buttons to

>select COM1-COM4
>and is also the first driver i am writting…)
>
>my driver is not directly layered onto some serial ports driver
>
>
(because

>i want a new serial port
>to become reserved by the system) but opens a DeviceObject pointer to
>the “underlaying” driver through a
>IoGetDeviceObjectPointer call from within IRP_MJ_CREATE dispatch
>routine.
>
>now my problem is that all the IRP_MJ_xxx dispatch routines work fine
>except from the IRP_MJ_READ routine.
>my READ dispatch routine is getting called, marks the current IRP
>pending, allocates a new IRP, sets a completion
>routine and calls the “underlaying” driver. as some character is
>received my completion routine is getting called,
>frees the allocated IRP, completes the original IRP and returns
>STATUS_MORE_PROCESSING_REQUIRED.
>but hyperterminal simply doesnt display the received character,
>
>
although

>it recognizes the completed IRP and issues
>a new read request.
>
>so my first question is wheter or not i need to copy the buffer of the

>driver-allocated IRP to original IRPs buffer ?
>my second question is whether or not i need to adjust the IRP Stack
>
>
Size

>of my drivers DeviceObject in that case ?
>
>and my third question (although unrelated to this topic) is if there’s

>some way to change the com port number of my
>driver that’s displayed by device manager (of course if i took care
>
>
that

>this port is not used otherwise, before…) ?
>
>thx a lot.
>regards, daniel.
>
>
>
>
>—
>Questions? First check the Kernel Driver FAQ at
>http://www.osronline.com/article.cfm?id=256
>
>You are currently subscribed to ntdev as: xxxxx@microsoft.com
>To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>—
>Questions? First check the Kernel Driver FAQ at
>
>
http://www.osronline.com/article.cfm?id=256

>You are currently subscribed to ntdev as: unknown lmsubst tag
argument:
>
>
‘’

>To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>
>
>


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: unknown lmsubst tag argument:
‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Doron Holan wrote:

For some reason, I thought that the i/o manager copied the results from
the buffer to the original buffer. I still think it does, I can’t
remember when it does it though.

if i got this right the documentation looks like it does…
and it also copies the buffer on write request (or at
least uses the same buffer…) but now i copy the
buffer myself and everthing’s fine…
daniel.

For the cancel path, you will need to make sure that your allocated irp
is not freed when you are calling IoCancelIrp. Basically, you must
prevent the completion routine from calling IoFreeIrp on it. Oney’s
book has a example on how to manage this race.

//

See the topic “COM Port Database Support Routines” in the DDK. I saw
this in the server 2003 SP1 DDK. Specifically ComDBReleasePort and
ComDBClaimPort/ClaimNextFreePort

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of L3sT4Rd
Sent: Sunday, January 29, 2006 2:51 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] q about driver allocated IRPs

Doron Holan wrote:

>Can’t tell just from looking at the code, but I have a couple of other
>suggestions
>1) once you mark an irp pending you are *required* to return
>STATUS_PENDING from the dispatch routine, so I would mark the irp
>pendingo only after you have allocated your 2ndary PIRP
>2) if the allocation of the 2ndary PIRP fails, I would return
>STATUS_INSUFFICIENT_RESOURCES, not STATUS_CANCELLED. STATUS_CANCELLED
>means that someone actually canceled the i/o and there may be state in
>the app sending the i/o that explicitly checks for canceled and does
>something different
>
>
>
>
first thanks for your help, i’ll follow your suggestions.
i figured out the problem myself now, it’s been that
although i passed OriginalIrp->AssociatedIrp.SystemBuffer
to the IoBuildAsynchronousFsdRequest routine, the
I/O Manager allocated a new buffer for my driver-created
IRP…

>3) speaking of cancellation, if the original PIRP is canceled, your
>underlying PIRP is not canceled, so you are effectively hanging the app
>until the underlying PIRP completes. That is not good.
>
>
>
>
this means i need to setup a cancel routine for the
original IRP and from there call IoCancelIrp on the
driver allocated IRP and therefor somehow queue
all forwarded and original IRPs since i can’t pass
a context to the cancel routine, right?

in your first reply you said something about ComDB functions
to change the port name of my virtual port. i can’t find
anything about ComDB (also tried CommDB, Com DB, …)
on MSDN or 2k/2k3/XP IFS & DDK documentation.
could you please give me another keyword / function name
to look for ?
(just for clarification, i’m able to change the SymbolicLink
name and registry settings at the moment, so that my port
becomes accessible under a different name, but device
manager still displays the port name assigned at installation
time and this doesnt look nice and i guess this way it’s
possible that the com port name arbiter or whatever
may assign a name that’s already in use to a new port
installed after my driver has loaded…)

sry for all the questions and again, thx for your help :slight_smile:
daniel.

>d
>
>
>
>-----Original Message-----
>From: xxxxx@lists.osr.com
>[mailto:xxxxx@lists.osr.com] On Behalf Of L3sT4Rd
>Sent: Sunday, January 29, 2006 6:01 AM
>To: Windows System Software Devs Interest List
>Subject: Re: [ntdev] q about driver allocated IRPs
>
>Doron Holan wrote:
>
>
>
>
>
>>Are you setting Irp->IoStatus.Information in the original irp with the
>>Information value from your own completed irp?
>>
>>
>>
>>
>>
>>
>i tried this, makes no difference.
>but i thought i do not need to set Information field because
>i’m passing a pointer to the original IRPs IoStatus Block to
>the IoBuildAsynchronousFsdRequest call…!?
>
>this is the code, perhaps somebody can tell me
>what’s wrong with it ?
>
>NTSTATUS SerMapRead(IN PDEVICE_OBJECT DeviceObject, IN PIRP pIrp)
>{
> PIRP lowerIrp;
> PDEVICE_EXTENSION extension;
> PIO_STACK_LOCATION irpStackLocation;
>
> extension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
>
> KdPrint( (“SerMap: Read\n”) );
>
> if (NULL == extension->mappedDevice)
> {
> KdPrint( (" …failed (not inited) !\n") );
> pIrp->IoStatus.Status = STATUS_CANCELLED;
> IoCompleteRequest(pIrp, IO_NO_INCREMENT);
> return STATUS_CANCELLED;
> }
>
> irpStackLocation = IoGetCurrentIrpStackLocation(pIrp);
> IoMarkIrpPending(pIrp);
> lowerIrp = IoBuildAsynchronousFsdRequest(IRP_MJ_READ,
> extension->mappedDevice,
>
>pIrp->AssociatedIrp.SystemBuffer,
>
>irpStackLocation->Parameters.Read.Length,
>
>&irpStackLocation->Parameters.Read.ByteOffset,
> &pIrp->IoStatus);
> if (NULL == lowerIrp)
> {
> KdPrint( (“…failed to allocate IRP.”) );
> pIrp->IoStatus.Status = STATUS_CANCELLED;
> IoCompleteRequest(pIrp, IO_NO_INCREMENT);
> return STATUS_CANCELLED;
> }
>
> IoSetCompletionRoutine(lowerIrp, SerMapReadCompletion, (PVOID)pIrp,
>
>

>TRUE, TRUE, TRUE);
> IoCallDriver(extension->mappedDevice, lowerIrp);
> return STATUS_PENDING;
>}
>
>NTSTATUS SerMapReadCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP
>pIrp, IN PVOID Context)
>{
> PIRP pOrgIrp = (PIRP)Context;
>
> KdPrint( (“SerMap: Read completion routine.\n”) );
>
> //pOrgIrp->IoStatus.Information = pIrp->IoStatus.Information;
>
> IoFreeIrp(pIrp);
> IoCompleteRequest(pOrgIrp, IO_NO_INCREMENT);
> return STATUS_MORE_PROCESSING_REQUIRED;
>}
>
>
>
>
>
>
>>As for the com port name, if you are installed as a pnp device, the
>>
>>
com

>>port name arbiter gives you the name at install time. you can change
>>
>>
>>
>>
>the
>
>
>
>
>>name using the ComDB functions (see the latest DDK).
>>
>>d
>>
>>-----Original Message-----
>>From: xxxxx@lists.osr.com
>>[mailto:xxxxx@lists.osr.com] On Behalf Of L3sT4Rd
>>Sent: Saturday, January 28, 2006 3:52 PM
>>To: Windows System Software Devs Interest List
>>Subject: [ntdev] q about driver allocated IRPs
>>
>>Hi,
>>
>>i’m writting a virtual serial port driver which redirects all incoming
>>
>>

>>IRPs to another
>>serial port (this is to make for example COM28 available to
>>
>>
>>
>>
>applications
>
>
>
>
>>which don’t
>>enumerate all serial ports but instead just provide 4 radio buttons to
>>
>>

>>select COM1-COM4
>>and is also the first driver i am writting…)
>>
>>my driver is not directly layered onto some serial ports driver
>>
>>
>>
>>
>(because
>
>
>
>
>>i want a new serial port
>>to become reserved by the system) but opens a DeviceObject pointer to
>>the “underlaying” driver through a
>>IoGetDeviceObjectPointer call from within IRP_MJ_CREATE dispatch
>>routine.
>>
>>now my problem is that all the IRP_MJ_xxx dispatch routines work fine
>>except from the IRP_MJ_READ routine.
>>my READ dispatch routine is getting called, marks the current IRP
>>pending, allocates a new IRP, sets a completion
>>routine and calls the “underlaying” driver. as some character is
>>received my completion routine is getting called,
>>frees the allocated IRP, completes the original IRP and returns
>>STATUS_MORE_PROCESSING_REQUIRED.
>>but hyperterminal simply doesnt display the received character,
>>
>>
>>
>>
>although
>
>
>
>
>>it recognizes the completed IRP and issues
>>a new read request.
>>
>>so my first question is wheter or not i need to copy the buffer of the
>>
>>

>>driver-allocated IRP to original IRPs buffer ?
>>my second question is whether or not i need to adjust the IRP Stack
>>
>>
>>
>>
>Size
>
>
>
>
>>of my drivers DeviceObject in that case ?
>>
>>and my third question (although unrelated to this topic) is if there’s
>>
>>

>>some way to change the com port number of my
>>driver that’s displayed by device manager (of course if i took care
>>
>>
>>
>>
>that
>
>
>
>
>>this port is not used otherwise, before…) ?
>>
>>thx a lot.
>>regards, daniel.
>>
>>
>>
>>
>>—
>>Questions? First check the Kernel Driver FAQ at
>>http://www.osronline.com/article.cfm?id=256
>>
>>You are currently subscribed to ntdev as: xxxxx@microsoft.com
>>To unsubscribe send a blank email to xxxxx@lists.osr.com
>>
>>
>>—
>>Questions? First check the Kernel Driver FAQ at
>>
>>
>>
>>
>http://www.osronline.com/article.cfm?id=256
>
>
>
>
>>You are currently subscribed to ntdev as: unknown lmsubst tag
>>
>>
argument:

>>
>>
>>
>>
>‘’
>
>
>
>
>>To unsubscribe send a blank email to xxxxx@lists.osr.com
>>
>>
>>
>>
>>
>>
>>
>—
>Questions? First check the Kernel Driver FAQ at
>http://www.osronline.com/article.cfm?id=256
>
>You are currently subscribed to ntdev as: xxxxx@microsoft.com
>To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>—
>Questions? First check the Kernel Driver FAQ at
>
>
http://www.osronline.com/article.cfm?id=256

>You are currently subscribed to ntdev as: unknown lmsubst tag argument:
>
>
‘’

>To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>
>
>


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: unknown lmsubst tag argument: ‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com

Daniel,

Moving away from your question specifically but possibly towards a solution
to your problem:

Have you considered that DefineDosDevice() can simply ‘define’ COM2 to point
at whatever device object you wish and no layered driver to ‘redirect’ is
required? When your redirection is canceled, you can call DefineDosDevice()
again to ‘pop’ the definition and restore it to the previous (underlying)
device.

Good Luck,
Dave Cattley
Consulting Engineer
Sytstems Software Development

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of L3sT4Rd
Sent: Saturday, January 28, 2006 6:52 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] q about driver allocated IRPs

Hi,

i’m writting a virtual serial port driver which redirects all incoming IRPs
to another serial port (this is to make for example COM28 available to
applications which don’t enumerate all serial ports but instead just provide
4 radio buttons to select COM1-COM4 and is also the first driver i am
writting…)

my driver is not directly layered onto some serial ports driver (because i
want a new serial port to become reserved by the system) but opens a
DeviceObject pointer to the “underlaying” driver through a
IoGetDeviceObjectPointer call from within IRP_MJ_CREATE dispatch routine.

now my problem is that all the IRP_MJ_xxx dispatch routines work fine except
from the IRP_MJ_READ routine.
my READ dispatch routine is getting called, marks the current IRP pending,
allocates a new IRP, sets a completion routine and calls the “underlaying”
driver. as some character is received my completion routine is getting
called, frees the allocated IRP, completes the original IRP and returns
STATUS_MORE_PROCESSING_REQUIRED.
but hyperterminal simply doesnt display the received character, although it
recognizes the completed IRP and issues a new read request.

so my first question is wheter or not i need to copy the buffer of the
driver-allocated IRP to original IRPs buffer ?
my second question is whether or not i need to adjust the IRP Stack Size of
my drivers DeviceObject in that case ?

and my third question (although unrelated to this topic) is if there’s some
way to change the com port number of my driver that’s displayed by device
manager (of course if i took care that this port is not used otherwise,
before…) ?

thx a lot.
regards, daniel.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@msn.com To unsubscribe
send a blank email to xxxxx@lists.osr.com

Hi Dave,

something similiar has also been my first approach; i wrote a simple
legacy driver to create symbolic links (cause i didn’t find the user
mode equivalent to IoCreateSymbolicLink; guess now i got it :wink: …)

the reasons that i mess arround with layered drivers and forwarded IRPs
are that i want to learn as much as possible about writing drivers, that
i plan to extend this driver somewhere along the way to support traffic
logging / monitoring as well as possibly connecting several serial ports
so that two or more applications which claim exlusive access to the port
can open a port at the same time anyway (just for the purpose of
developement / reverse engineering).
and finally i did not know how to prevent the system from assigning “my”
port name to another driver if for example a pnp usb to serial converter
is plugged into the machine after i created the link.

hope this explains why i’m trying it that way…

daniel.

David R. Cattley wrote:

Daniel,

Moving away from your question specifically but possibly towards a solution
to your problem:

Have you considered that DefineDosDevice() can simply ‘define’ COM2 to point
at whatever device object you wish and no layered driver to ‘redirect’ is
required? When your redirection is canceled, you can call DefineDosDevice()
again to ‘pop’ the definition and restore it to the previous (underlying)
device.

Good Luck,
Dave Cattley
Consulting Engineer
Sytstems Software Development

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of L3sT4Rd
Sent: Saturday, January 28, 2006 6:52 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] q about driver allocated IRPs

Hi,

i’m writting a virtual serial port driver which redirects all incoming IRPs
to another serial port (this is to make for example COM28 available to
applications which don’t enumerate all serial ports but instead just provide
4 radio buttons to select COM1-COM4 and is also the first driver i am
writting…)

my driver is not directly layered onto some serial ports driver (because i
want a new serial port to become reserved by the system) but opens a
DeviceObject pointer to the “underlaying” driver through a
IoGetDeviceObjectPointer call from within IRP_MJ_CREATE dispatch routine.

now my problem is that all the IRP_MJ_xxx dispatch routines work fine except
>from the IRP_MJ_READ routine.
my READ dispatch routine is getting called, marks the current IRP pending,
allocates a new IRP, sets a completion routine and calls the “underlaying”
driver. as some character is received my completion routine is getting
called, frees the allocated IRP, completes the original IRP and returns
STATUS_MORE_PROCESSING_REQUIRED.
but hyperterminal simply doesnt display the received character, although it
recognizes the completed IRP and issues a new read request.

so my first question is wheter or not i need to copy the buffer of the
driver-allocated IRP to original IRPs buffer ?
my second question is whether or not i need to adjust the IRP Stack Size of
my drivers DeviceObject in that case ?

and my third question (although unrelated to this topic) is if there’s some
way to change the com port number of my driver that’s displayed by device
manager (of course if i took care that this port is not used otherwise,
before…) ?

thx a lot.
regards, daniel.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@msn.com To unsubscribe
send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@gmx.net
To unsubscribe send a blank email to xxxxx@lists.osr.com