Making a new IRP and Copy IRP Parameters

Hello All,

I want to find out about the problems I am getting in creating my own IRP and copying its parametrs. Be patient while reading the code because I am very new to Windows Kernel.

Below is my code.


// Allocating my own IRP as shown below
PIrpLocal = (PIRP)ExAllocatePool (NonPagedPool,IoManagerIrp->Size);
// where IoManagerIrp->Size is the size of the IRP got from I/O Manager


// Now initializing our new IRP
IoInitializeIrp (PIrpLocal,IoManagerIrp->Size,(CCHAR)(IoManagerIrp->StackCount));
// where IoManagerIrp->StackCount is the stack count of the IRP got from I/O Manager


// Filling IRP arguments
PIrpLocal->Type=IoManagerIrp->Type;
PIrpLocal->Size=IoManagerIrp->Size;
PIrpLocal->MdlAddress = IoManagerIrp->MdlAddress;
PIrpLocal->RequestorMode=IoManagerIrp->RequestorMode;
PIrpLocal->StackCount=IoManagerIrp->StackCount;
PIrpLocal->CurrentLocation=IoManagerIrp->CurrentLocation;


The BSD I am getting is that of NO_MORE_IRP_STACK_LOCATIONS

Waiting for reply.

Thanks,
Uzair Lakhani,
Karachi, Pakistan.

> PIrpLocal->CurrentLocation=IoManagerIrp->CurrentLocation;

This is an error. Do not do this.

In addition-

ExAllocatePool (NonPagedPool,IoManagerIrp->Size);
IoInitializeIrp
(PIrpLocal,IoManagerIrp->Size,(CCHAR)(IoManagerIrp->StackCount));

IoAllocateIrp() fits best.

PIrpLocal->Type=IoManagerIrp->Type;
PIrpLocal->Size=IoManagerIrp->Size;
PIrpLocal->StackCount=IoManagerIrp->StackCount;

Already done in IoInitializeIrp() or IoAllocateIrp()


Slava Imameyev, xxxxx@hotmail.com

wrote in message news:xxxxx@ntdev…
> Hello All,
>
> I want to find out about the problems I am getting in creating my own IRP
> and copying its parametrs. Be patient while reading the code because I am
> very new to Windows Kernel.
>
> Below is my code.
>
> …
> // Allocating my own IRP as shown below
> PIrpLocal = (PIRP)ExAllocatePool (NonPagedPool,IoManagerIrp->Size);
> // where IoManagerIrp->Size is the size of the IRP got from I/O Manager
>
> …
> // Now initializing our new IRP
> IoInitializeIrp
> (PIrpLocal,IoManagerIrp->Size,(CCHAR)(IoManagerIrp->StackCount));
> // where IoManagerIrp->StackCount is the stack count of the IRP got from
> I/O Manager
>
> …
> // Filling IRP arguments
> PIrpLocal->Type=IoManagerIrp->Type;
> PIrpLocal->Size=IoManagerIrp->Size;
> PIrpLocal->MdlAddress = IoManagerIrp->MdlAddress;
> PIrpLocal->RequestorMode=IoManagerIrp->RequestorMode;
> PIrpLocal->StackCount=IoManagerIrp->StackCount;
> PIrpLocal->CurrentLocation=IoManagerIrp->CurrentLocation;
>
> …
> The BSD I am getting is that of NO_MORE_IRP_STACK_LOCATIONS
>
> Waiting for reply.
>
> Thanks,
> Uzair Lakhani,
> Karachi, Pakistan.
>

Hello Slava Imameyev,

Thanks for the reply. But what do I do with the CurrentLocation field of my newly created IRP.

Thanks,
Uzair Lakhani,
Karachi, Pakistan.

Well, first, as was already mentioned, allocate the IRP using IoAllocateIrp(…) – Use the stack size value from DeviceObject->StackSize of the device object to which you’re going to send the IRP.

When you allocate an IRP, YOU don’t get an I/O Stack Location… But, you don’t need one. YOU’RE not going to process the IRP, the next driver to get it is going to process it. So, you initialize the NEXT I/O stack location, not the current one… IOW, you:

irp = IoAllocateIrp(…);
ios = IoGetNextIrpStackLocation(…);

Then setup the parameters in the NEXT I/O Stack Location.

Finally, the IRP you’re getting from the I/O Manager (the one you’re copying stuff out of)… You’re going to HOLD ON to that IRP while the one you’ve created is in progress, right? Because if you copy the parameters as you’re doing, you can’t let the original IRP complete (the I/O Manager will, for example, release the MDL and perhaps its underlying mapping when the original IRP is completed).

Peter
OSR

Hello All,
Thanks for the reply. Now below is my code

PIrpLocal = IoAllocateIrp (DeviceObject->StackSize,FALSE);

if(PIrpLocal==NULL)
{
DbgPrint(“GenerateIRP()…PIrpLocal Not Allocated IRP\n”);
DbgPrint(“GenerateIRP()…IoBuildAsynchronousFsdRequest FAILED\n”);
return STATUS_INSUFFICIENT_RESOURCES;
}
else
{
DbgPrint(“GenerateIRP()…PIrpLocal Allocated Successfully IRP\n”);
//IoInitializeIrp (PIrpLocal,IoManagerIrp->Size,(CCHAR)(IoManagerIrp->StackCount));
MyIrpStack= IoGetNextIrpStackLocation(PIrpLocal);

switch (irpStack->MajorFunction)
{
case IRP_MJ_READ:
{
MyIrpStack->Parameters.Read.Length = irpStack->Parameters.Read.Length;
MyIrpStack->Parameters.Read.ByteOffset = irpStack->Parameters.Read.ByteOffset;
MyIrpStack->MajorFunction = irpStack->MajorFunction;
MyIrpStack->MinorFunction = irpStack->MinorFunction;

PDiskIrp->ReadWriteOffset= irpStack->Parameters.Read.ByteOffset;
break;
}
case IRP_MJ_WRITE:
{
MyIrpStack->Parameters.Write.Length = irpStack->Parameters.Write.Length;
MyIrpStack->Parameters.Write.ByteOffset = irpStack->Parameters.Write.ByteOffset;
MyIrpStack->MajorFunction = irpStack->MajorFunction;
MyIrpStack->MinorFunction = irpStack->MinorFunction;
PDiskIrp->ReadWriteOffset= irpStack->Parameters.Write.ByteOffset;
break;
}
}


Note that I am not changing any field of my newly created IRP and I am getting the BSD of FAT_FILE_SYSTEM

I thought that it is because our newly created IRP’s MdlAddress field is NULL so I added a line of code just below the above mentioned code. The added line was this

PIrpLocal->MdlAddress = IoManagerIrp->MdlAddress;

But this is giving me BSD of UNEXPECTED_KERNEL_MODE_TRAP

Hope I am able to explain my problem. Waiting for reply.

Thanks,
Uzair Lakhani,
Karachi, Pakistan.

First, don’t use Irp->Size. Use IoSizeOfIrp(TargetDeviceObject->StackSize).

Don’t modify Irp->Size, Type, StackCount, or especially CurrentLocation. IoAllocateIrp / IoInitializeIrp does all of this for you. Since CurrentLocation is a pointer within the IRP body, you’ve set up a new IRP to point to the internal body of a *different* IRP. This is bound to cause some severe heartache.

The general pattern is:

SomeFunction(…)
{
PIRP Irp;
PIO_STACK_LOCATION Ios;
PDEVICE_OBJECT TargetDeviceObject = (?);

Irp = IoAllocateIrp(TargetDeviceObject->StackSize, FALSE);
if (Irp == NULL) { … deal with error … }

Ios = IoGetNextIrpStackLocation(Irp);
Ios->MajorFunction = IRP_MJ_XXX;
Ios->MinorFunction = IRP_MN_YYY;
Ios->Parameters… = xxx;
// … this is where you copy parameters from one IRP to another …
// … or set up whatever parameters you want …

Status = IoSetCompletionRoutineEx(MyDeviceObject, Irp, MyCompletionRoutine, …);
if (!NT_SUCCESS(Status)) {
IoFreeIrp(Irp);
… deal with error …
}

Status = IoCallDriver(TargetDeviceObject, Irp);
}

MyCompletionRoutine(…)
{
IoFreeIrp(Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}

– arlie

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@yahoo.com
Sent: Wednesday, September 06, 2006 4:11 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Making a new IRP and Copy IRP Parameters

Hello All,

I want to find out about the problems I am getting in creating my own IRP and copying its parametrs. Be patient while reading the code because I am very new to Windows Kernel.

Below is my code.


// Allocating my own IRP as shown below
PIrpLocal = (PIRP)ExAllocatePool (NonPagedPool,IoManagerIrp->Size);
// where IoManagerIrp->Size is the size of the IRP got from I/O Manager


// Now initializing our new IRP
IoInitializeIrp (PIrpLocal,IoManagerIrp->Size,(CCHAR)(IoManagerIrp->StackCount));
// where IoManagerIrp->StackCount is the stack count of the IRP got from I/O Manager


// Filling IRP arguments
PIrpLocal->Type=IoManagerIrp->Type;
PIrpLocal->Size=IoManagerIrp->Size;
PIrpLocal->MdlAddress = IoManagerIrp->MdlAddress;
PIrpLocal->RequestorMode=IoManagerIrp->RequestorMode;
PIrpLocal->StackCount=IoManagerIrp->StackCount;
PIrpLocal->CurrentLocation=IoManagerIrp->CurrentLocation;


The BSD I am getting is that of NO_MORE_IRP_STACK_LOCATIONS

Waiting for reply.

Thanks,
Uzair Lakhani,
Karachi, Pakistan.


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

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

> PIrpLocal = (PIRP)ExAllocatePool (NonPagedPool,IoManagerIrp->Size);

Use IoAllocateIrp instead.

// Filling IRP arguments
PIrpLocal->Type=IoManagerIrp->Type;
PIrpLocal->Size=IoManagerIrp->Size;

No need, IoAllocateIrp does this.

PIrpLocal->StackCount=IoManagerIrp->StackCount;
PIrpLocal->CurrentLocation=IoManagerIrp->CurrentLocation;

These 2 are also filled by IoAllocateIrp.

The BSD I am getting is that of NO_MORE_IRP_STACK_LOCATIONS

Proper use of IoAllocateIrp is a fix.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

The first, you convert Paging IO to common non paging IO, you definitely
will crash or dead lock the system.
The second, the IRP_MJ_WRITE/READ requests obey the DeviceObject flags for
buffer passing, except the Paging IO requests that always use MDL( and
Irp->UserBuffer! ).
All Microsoft’s FSDs uses neither bufferd no direct mode.
So you must copy the Irp->UserBuffer and Irp->MdlAddress fields( the
both! ) and ( IRP->Flags & ( IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO ) )
flags. Also, you must copy the FileObject pointer from the current stack
location.
I hope you do this for fun.


Slava Imameyev, xxxxx@hotmail.com

wrote in message news:xxxxx@ntdev…
> Hello All,
> Thanks for the reply. Now below is my code
>
> …
>
> PIrpLocal = IoAllocateIrp (DeviceObject->StackSize,FALSE);
>
> if(PIrpLocal==NULL)
> {
> DbgPrint(“GenerateIRP()…PIrpLocal Not Allocated IRP\n”);
> DbgPrint(“GenerateIRP()…IoBuildAsynchronousFsdRequest FAILED\n”);
> return STATUS_INSUFFICIENT_RESOURCES;
> }
> else
> {
> DbgPrint(“GenerateIRP()…PIrpLocal Allocated Successfully IRP\n”);
> //IoInitializeIrp
> (PIrpLocal,IoManagerIrp->Size,(CCHAR)(IoManagerIrp->StackCount));
> MyIrpStack= IoGetNextIrpStackLocation(PIrpLocal);
>
> switch (irpStack->MajorFunction)
> {
> case IRP_MJ_READ:
> {
> MyIrpStack->Parameters.Read.Length = irpStack->Parameters.Read.Length;
> MyIrpStack->Parameters.Read.ByteOffset =
> irpStack->Parameters.Read.ByteOffset;
> MyIrpStack->MajorFunction = irpStack->MajorFunction;
> MyIrpStack->MinorFunction = irpStack->MinorFunction;
>
> PDiskIrp->ReadWriteOffset= irpStack->Parameters.Read.ByteOffset;
> break;
> }
> case IRP_MJ_WRITE:
> {
> MyIrpStack->Parameters.Write.Length = irpStack->Parameters.Write.Length;
> MyIrpStack->Parameters.Write.ByteOffset =
> irpStack->Parameters.Write.ByteOffset;
> MyIrpStack->MajorFunction = irpStack->MajorFunction;
> MyIrpStack->MinorFunction = irpStack->MinorFunction;
> PDiskIrp->ReadWriteOffset= irpStack->Parameters.Write.ByteOffset;
> break;
> }
> }
>
> …
> Note that I am not changing any field of my newly created IRP and I am
> getting the BSD of FAT_FILE_SYSTEM
>
> I thought that it is because our newly created IRP’s MdlAddress field is
> NULL so I added a line of code just below the above mentioned code. The
> added line was this
>
> PIrpLocal->MdlAddress = IoManagerIrp->MdlAddress;
>
> But this is giving me BSD of UNEXPECTED_KERNEL_MODE_TRAP
>
> Hope I am able to explain my problem. Waiting for reply.
>
> Thanks,
> Uzair Lakhani,
> Karachi, Pakistan.
>
>

> Thanks for the reply. But what do I do with the CurrentLocation field of my
newly

created IRP.

Use IoAllocateIrp and forget about the CurrentLocation field forever. It is set
up automatically.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

IoCopyCurrentIrpStackLocationToNext is a macro in ntddk.h. it provides
sufficient hints about what all needs to be copied from Irp1’s Current
stack location to Irp2’s next stack location.

Based on the code snippets posted, I would like to know the performance
impact of in the IO path.

I’ve tried to follow the rule in my driver that IO path should not be
doing any allocations and|or de-allocations.

I prefer to have my own Irps initialized out of a pool of pre-allocated
non-paged memory. This makes it a counted resource so I work with a
configurable numbers of IRPs in the available Q per device.

I understand that IO manager does slab allocations for IRPs but it
seems!! more efficient to have Irp come out of your own managed pool.
This also avoids calling out of my driver in the completion routine.

Harish

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:bounce-261345-
xxxxx@lists.osr.com] On Behalf Of Slava Imameyev
Sent: Wednesday, September 06, 2006 10:52 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Making a new IRP and Copy IRP Parameters

The first, you convert Paging IO to common non paging IO, you
definitely
will crash or dead lock the system.
The second, the IRP_MJ_WRITE/READ requests obey the DeviceObject
flags
for
buffer passing, except the Paging IO requests that always use MDL( and
Irp->UserBuffer! ).
All Microsoft’s FSDs uses neither bufferd no direct mode.
So you must copy the Irp->UserBuffer and Irp->MdlAddress fields( the
both! ) and ( IRP->Flags & ( IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO
) )
flags. Also, you must copy the FileObject pointer from the current
stack
location.
I hope you do this for fun.


Slava Imameyev, xxxxx@hotmail.com

wrote in message news:xxxxx@ntdev…
> > Hello All,
> > Thanks for the reply. Now below is my code
> >
> > …
> >
> > PIrpLocal = IoAllocateIrp (DeviceObject->StackSize,FALSE);
> >
> > if(PIrpLocal==NULL)
> > {
> > DbgPrint(“GenerateIRP()…PIrpLocal Not Allocated IRP\n”);
> > DbgPrint(“GenerateIRP()…IoBuildAsynchronousFsdRequest FAILED\n”);
> > return STATUS_INSUFFICIENT_RESOURCES;
> > }
> > else
> > {
> > DbgPrint(“GenerateIRP()…PIrpLocal Allocated Successfully IRP\n”);
> > //IoInitializeIrp
> > (PIrpLocal,IoManagerIrp->Size,(CCHAR)(IoManagerIrp->StackCount));
> > MyIrpStack= IoGetNextIrpStackLocation(PIrpLocal);
> >
> > switch (irpStack->MajorFunction)
> > {
> > case IRP_MJ_READ:
> > {
> > MyIrpStack->Parameters.Read.Length =
irpStack->Parameters.Read.Length;
> > MyIrpStack->Parameters.Read.ByteOffset =
> > irpStack->Parameters.Read.ByteOffset;
> > MyIrpStack->MajorFunction = irpStack->MajorFunction;
> > MyIrpStack->MinorFunction = irpStack->MinorFunction;
> >
> > PDiskIrp->ReadWriteOffset= irpStack->Parameters.Read.ByteOffset;
> > break;
> > }
> > case IRP_MJ_WRITE:
> > {
> > MyIrpStack->Parameters.Write.Length =
irpStack->Parameters.Write.Length;
> > MyIrpStack->Parameters.Write.ByteOffset =
> > irpStack->Parameters.Write.ByteOffset;
> > MyIrpStack->MajorFunction = irpStack->MajorFunction;
> > MyIrpStack->MinorFunction = irpStack->MinorFunction;
> > PDiskIrp->ReadWriteOffset= irpStack->Parameters.Write.ByteOffset;
> > break;
> > }
> > }
> >
> > …
> > Note that I am not changing any field of my newly created IRP and I
am
> > getting the BSD of FAT_FILE_SYSTEM
> >
> > I thought that it is because our newly created IRP’s MdlAddress
field is
> > NULL so I added a line of code just below the above mentioned code.
The
> > added line was this
> >
> > PIrpLocal->MdlAddress = IoManagerIrp->MdlAddress;
> >
> > But this is giving me BSD of UNEXPECTED_KERNEL_MODE_TRAP
> >
> > Hope I am able to explain my problem. Waiting for reply.
> >
> > Thanks,
> > Uzair Lakhani,
> > Karachi, Pakistan.
> >
> >
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer

In general, the I/O manager has been highly tuned to get the most
performance it can out of allocating/freeing PIRPs. Furthermore, it does
this at runtime based on the load of the OS and other dynamic inputs. I
doubt you can match this functionality. Trust the I/O manager here,
making a call to IoFreeIrp is not expensive.

If you need to make guaranteed fwd progress and not rely on allocations,
that is a different story.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Harish Arora
Sent: Wednesday, September 06, 2006 1:52 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] Making a new IRP and Copy IRP Parameters

IoCopyCurrentIrpStackLocationToNext is a macro in ntddk.h. it provides
sufficient hints about what all needs to be copied from Irp1’s Current
stack location to Irp2’s next stack location.

Based on the code snippets posted, I would like to know the performance
impact of in the IO path.

I’ve tried to follow the rule in my driver that IO path should not be
doing any allocations and|or de-allocations.

I prefer to have my own Irps initialized out of a pool of pre-allocated
non-paged memory. This makes it a counted resource so I work with a
configurable numbers of IRPs in the available Q per device.

I understand that IO manager does slab allocations for IRPs but it
seems!! more efficient to have Irp come out of your own managed pool.
This also avoids calling out of my driver in the completion routine.

Harish

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:bounce-261345-
xxxxx@lists.osr.com] On Behalf Of Slava Imameyev
Sent: Wednesday, September 06, 2006 10:52 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Making a new IRP and Copy IRP Parameters

The first, you convert Paging IO to common non paging IO, you
definitely
will crash or dead lock the system.
The second, the IRP_MJ_WRITE/READ requests obey the DeviceObject
flags
for
buffer passing, except the Paging IO requests that always use MDL( and
Irp->UserBuffer! ).
All Microsoft’s FSDs uses neither bufferd no direct mode.
So you must copy the Irp->UserBuffer and Irp->MdlAddress fields( the
both! ) and ( IRP->Flags & ( IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO
) )
flags. Also, you must copy the FileObject pointer from the current
stack
location.
I hope you do this for fun.


Slava Imameyev, xxxxx@hotmail.com

wrote in message news:xxxxx@ntdev…
> > Hello All,
> > Thanks for the reply. Now below is my code
> >
> > …
> >
> > PIrpLocal = IoAllocateIrp (DeviceObject->StackSize,FALSE);
> >
> > if(PIrpLocal==NULL)
> > {
> > DbgPrint(“GenerateIRP()…PIrpLocal Not Allocated IRP\n”);
> > DbgPrint(“GenerateIRP()…IoBuildAsynchronousFsdRequest FAILED\n”);
> > return STATUS_INSUFFICIENT_RESOURCES;
> > }
> > else
> > {
> > DbgPrint(“GenerateIRP()…PIrpLocal Allocated Successfully IRP\n”);
> > //IoInitializeIrp
> > (PIrpLocal,IoManagerIrp->Size,(CCHAR)(IoManagerIrp->StackCount));
> > MyIrpStack= IoGetNextIrpStackLocation(PIrpLocal);
> >
> > switch (irpStack->MajorFunction)
> > {
> > case IRP_MJ_READ:
> > {
> > MyIrpStack->Parameters.Read.Length =
irpStack->Parameters.Read.Length;
> > MyIrpStack->Parameters.Read.ByteOffset =
> > irpStack->Parameters.Read.ByteOffset;
> > MyIrpStack->MajorFunction = irpStack->MajorFunction;
> > MyIrpStack->MinorFunction = irpStack->MinorFunction;
> >
> > PDiskIrp->ReadWriteOffset= irpStack->Parameters.Read.ByteOffset;
> > break;
> > }
> > case IRP_MJ_WRITE:
> > {
> > MyIrpStack->Parameters.Write.Length =
irpStack->Parameters.Write.Length;
> > MyIrpStack->Parameters.Write.ByteOffset =
> > irpStack->Parameters.Write.ByteOffset;
> > MyIrpStack->MajorFunction = irpStack->MajorFunction;
> > MyIrpStack->MinorFunction = irpStack->MinorFunction;
> > PDiskIrp->ReadWriteOffset= irpStack->Parameters.Write.ByteOffset;
> > break;
> > }
> > }
> >
> > …
> > Note that I am not changing any field of my newly created IRP and I
am
> > getting the BSD of FAT_FILE_SYSTEM
> >
> > I thought that it is because our newly created IRP’s MdlAddress
field is
> > NULL so I added a line of code just below the above mentioned code.
The
> > added line was this
> >
> > PIrpLocal->MdlAddress = IoManagerIrp->MdlAddress;
> >
> > But this is giving me BSD of UNEXPECTED_KERNEL_MODE_TRAP
> >
> > Hope I am able to explain my problem. Waiting for reply.
> >
> > Thanks,
> > Uzair Lakhani,
> > Karachi, Pakistan.
> >
> >
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer


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

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Harish Arora wrote:

Based on the code snippets posted, I would like to know the performance
impact of in the IO path.

I’ve tried to follow the rule in my driver that IO path should not be
doing any allocations and|or de-allocations.

I prefer to have my own Irps initialized out of a pool of pre-allocated
non-paged memory. This makes it a counted resource so I work with a
configurable numbers of IRPs in the available Q per device.

I understand that IO manager does slab allocations for IRPs but it
seems!! more efficient to have Irp come out of your own managed pool.
This also avoids calling out of my driver in the completion routine.

They’re both coming from the same memory pools. I’d rather let the I/O
manager worry about handling low memory and no memory conditions. It
knows better than I what critical actions to take.

And, if you will permit me to ask, what does it matter? Unless you’re
handling many hundreds of thousands of IRPs per second, a few dozen
cycles per IRP is not going to be significant.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hello All,

Thanks very much for the reply. Below is my some what changed code but still it is giving me BSD of UNEXPECTED_KERNEL_MODE_TRAP due to Double Fault.

According to Debugging Tools for Windows, it is due to A kernel stack overflow.

Waiting for reply.

Thanks,
Uzair Lakhani,
Karachi, Pakistan.

irpStack = IoGetCurrentIrpStackLocation(IoManagerIrp);

PIrpLocal = IoAllocateIrp (DeviceObject->StackSize,FALSE);

if(PIrpLocal==NULL)
{
DbgPrint(“GenerateIRP()…PIrpLocal Not Allocated IRP\n”);
DbgPrint(“GenerateIRP()…IoBuildAsynchronousFsdRequest FAILED\n”);
return STATUS_INSUFFICIENT_RESOURCES;
}
else
{
DbgPrint(“GenerateIRP()…PIrpLocal Allocated Successfully IRP\n”);
//IoInitializeIrp (PIrpLocal,IoManagerIrp->Size,(CCHAR)(IoManagerIrp->StackCount));

MyIrpStack= IoGetNextIrpStackLocation(PIrpLocal);
switch (irpStack->MajorFunction)
{
case IRP_MJ_READ:
{
MyIrpStack->Parameters.Read.Length = irpStack->Parameters.Read.Length;
MyIrpStack->Parameters.Read.Key = irpStack->Parameters.Read.Key;
MyIrpStack->Parameters.Read.ByteOffset = irpStack->Parameters.Read.ByteOffset;
MyIrpStack->MajorFunction = irpStack->MajorFunction;
MyIrpStack->MinorFunction = irpStack->MinorFunction;
PDiskIrp->ReadWriteOffset= irpStack->Parameters.Read.ByteOffset;
break;
}
case IRP_MJ_WRITE:
{
MyIrpStack->Parameters.Write.Length = irpStack->Parameters.Write.Length;
MyIrpStack->Parameters.Write.Key = irpStack->Parameters.Write.Key;
MyIrpStack->Parameters.Write.ByteOffset = irpStack->Parameters.Write.ByteOffset;
MyIrpStack->MajorFunction = irpStack->MajorFunction;
MyIrpStack->MinorFunction = irpStack->MinorFunction;
PDiskIrp->ReadWriteOffset= irpStack->Parameters.Write.ByteOffset;
break;
}
}

/*New*/FillingIrpArguments(PIrpLocal,IoManagerIrp);

IoSetCompletionRoutine( PIrpLocal,
(PIO_COMPLETION_ROUTINE)CompletionRoutine,
(PDISK_IRP)PDiskIrp,
TRUE,
TRUE,
TRUE);
}

status = IoCallDriver(DeviceObject, PIrpLocal);

return status;

}

NTSTATUS CompletionRoutine(PDEVICE_OBJECT fdo, PIRP Irp, PDISK_IRP PDisk_Irp)
{

PIRP OriginalIrp;
PMDL mdl, nextMdl;
ULONG ReadWriteLength;

NTSTATUS Status;
ULONG Information;
PIO_STACK_LOCATION irpStack;
PUCHAR OriginalBuffVA,MyBuffVA;

OriginalIrp = PDisk_Irp->POriginalIrp;

DbgPrint(“CompletionRoutine Called \n”);

OriginalIrp->IoStatus.Status = Irp->IoStatus.Status;
OriginalIrp->IoStatus.Information = Irp->IoStatus.Information;

if (Irp->PendingReturned){
IoMarkIrpPending (Irp);
IoMarkIrpPending (OriginalIrp);
return STATUS_PENDING;
}
else{
return STATUS_SUCCESS;
}

}

void FillingIrpArguments(PIRP PIrpLocal,PIRP IoManagerIrp)
{
PIrpLocal->MdlAddress = IoManagerIrp->MdlAddress;
PIrpLocal->UserBuffer = IoManagerIrp->UserBuffer;
PIrpLocal->RequestorMode=IoManagerIrp->RequestorMode;

}

The following code
if (Irp->PendingReturned){
IoMarkIrpPending (Irp);
IoMarkIrpPending (OriginalIrp);
return STATUS_PENDING;
}
else{
return STATUS_SUCCESS;
}

has 4 problems with it.

  1. you should not mark your irp (e.g. IoMarkIrpPending (Irp):wink: as
    pending. This sets a flag in the current stack location for the irp, but
    for a IRP that you allocated on your own, no current stack location
    exists

  2. you should only mark the original irp as pending in the dispatch
    routine, not the completion routine. When you mark it as pending, you
    must always return STATUS_PENDING from the dispatch routine.

  3. Think of the return value from the completion routine as a BOOLEAN,
    not an NTSTATUS. by returning the value
    STATUS_MORE_PROCESSING_REQUIRED, you are telling the i/o manager to stop
    the completion process. An irp allocated by IoAllcoateIrp must never be
    completed back to the I/O manager. By returning a value !=
    STATUS_MORE_PROCESSING_REQUIRED, you are telling the i/o manager to
    continue completion. You need to free the irp and return
    STATUS_MORE_PROCESSING_REQUIRED

  4. you are not completing OriginalIrp

So,in the end it should be something like this

NTSTATUS CompletionRoutine(PDEVICE_OBJECT fdo, PIRP Irp, PDISK_IRP
PDisk_Irp)
{

PIRP OriginalIrp;
PMDL mdl, nextMdl;
ULONG ReadWriteLength;

NTSTATUS Status;
ULONG Information;
PIO_STACK_LOCATION irpStack;
PUCHAR OriginalBuffVA,MyBuffVA;

OriginalIrp = PDisk_Irp->POriginalIrp;

DbgPrint(“CompletionRoutine Called \n”);

OriginalIrp->IoStatus.Status = Irp->IoStatus.Status;
OriginalIrp->IoStatus.Information = Irp->IoStatus.Information;
IoCompleteReqest(OriginalIrp, IO_NO_INCREMENT);

IoFreeIrp(Irp);

return STATUS_MORE_PROCESSING_REQUIRED;
}

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@yahoo.com
Sent: Thursday, September 07, 2006 11:09 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Making a new IRP and Copy IRP Parameters

Hello All,

Thanks very much for the reply. Below is my some what changed code but
still it is giving me BSD of UNEXPECTED_KERNEL_MODE_TRAP due to Double
Fault.

According to Debugging Tools for Windows, it is due to A kernel stack
overflow.

Waiting for reply.

Thanks,
Uzair Lakhani,
Karachi, Pakistan.

irpStack = IoGetCurrentIrpStackLocation(IoManagerIrp);

PIrpLocal = IoAllocateIrp (DeviceObject->StackSize,FALSE);

if(PIrpLocal==NULL)
{
DbgPrint(“GenerateIRP()…PIrpLocal Not Allocated IRP\n”);
DbgPrint(“GenerateIRP()…IoBuildAsynchronousFsdRequest
FAILED\n”);
return STATUS_INSUFFICIENT_RESOURCES;
}
else
{
DbgPrint(“GenerateIRP()…PIrpLocal Allocated Successfully
IRP\n”);
//IoInitializeIrp
(PIrpLocal,IoManagerIrp->Size,(CCHAR)(IoManagerIrp->StackCount));

MyIrpStack= IoGetNextIrpStackLocation(PIrpLocal);
switch (irpStack->MajorFunction)
{
case IRP_MJ_READ:
{
MyIrpStack->Parameters.Read.Length =
irpStack->Parameters.Read.Length;
MyIrpStack->Parameters.Read.Key =
irpStack->Parameters.Read.Key;
MyIrpStack->Parameters.Read.ByteOffset =
irpStack->Parameters.Read.ByteOffset;
MyIrpStack->MajorFunction =
irpStack->MajorFunction;
MyIrpStack->MinorFunction =
irpStack->MinorFunction;
PDiskIrp->ReadWriteOffset=
irpStack->Parameters.Read.ByteOffset;
break;
}
case IRP_MJ_WRITE:
{
MyIrpStack->Parameters.Write.Length =
irpStack->Parameters.Write.Length;
MyIrpStack->Parameters.Write.Key =
irpStack->Parameters.Write.Key;
MyIrpStack->Parameters.Write.ByteOffset =
irpStack->Parameters.Write.ByteOffset;
MyIrpStack->MajorFunction =
irpStack->MajorFunction;
MyIrpStack->MinorFunction =
irpStack->MinorFunction;
PDiskIrp->ReadWriteOffset=
irpStack->Parameters.Write.ByteOffset;
break;
}
}

/*New*/FillingIrpArguments(PIrpLocal,IoManagerIrp);

IoSetCompletionRoutine( PIrpLocal,

(PIO_COMPLETION_ROUTINE)CompletionRoutine,
(PDISK_IRP)PDiskIrp,
TRUE,
TRUE,
TRUE);
}

status = IoCallDriver(DeviceObject, PIrpLocal);

return status;

}

NTSTATUS CompletionRoutine(PDEVICE_OBJECT fdo, PIRP Irp, PDISK_IRP
PDisk_Irp)
{

PIRP OriginalIrp;
PMDL mdl, nextMdl;
ULONG ReadWriteLength;

NTSTATUS Status;
ULONG Information;
PIO_STACK_LOCATION irpStack;
PUCHAR OriginalBuffVA,MyBuffVA;

OriginalIrp = PDisk_Irp->POriginalIrp;

DbgPrint(“CompletionRoutine Called \n”);

OriginalIrp->IoStatus.Status = Irp->IoStatus.Status;
OriginalIrp->IoStatus.Information = Irp->IoStatus.Information;

if (Irp->PendingReturned){
IoMarkIrpPending (Irp);
IoMarkIrpPending (OriginalIrp);
return STATUS_PENDING;
}
else{
return STATUS_SUCCESS;
}

}

void FillingIrpArguments(PIRP PIrpLocal,PIRP IoManagerIrp)
{
PIrpLocal->MdlAddress = IoManagerIrp->MdlAddress;
PIrpLocal->UserBuffer = IoManagerIrp->UserBuffer;
PIrpLocal->RequestorMode=IoManagerIrp->RequestorMode;

}


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

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Hello All,
I have changed my code as guided but still getting the same problem. Below is my code:

PIrpLocal = IoAllocateIrp (DeviceObject->StackSize,FALSE);

if(PIrpLocal==NULL)
{
DbgPrint(“GenerateIRP()…PIrpLocal Not Allocated IRP\n”);
DbgPrint(“GenerateIRP()…IoBuildAsynchronousFsdRequest FAILED\n”);
return STATUS_INSUFFICIENT_RESOURCES;
}
else
{
DbgPrint(“GenerateIRP()…PIrpLocal Allocated Successfully IRP\n”);
//IoInitializeIrp (PIrpLocal,IoManagerIrp->Size,(CCHAR)(IoManagerIrp->StackCount));
MyIrpStack= IoGetNextIrpStackLocation(PIrpLocal);
switch (irpStack->MajorFunction)
{
case IRP_MJ_READ:
{
MyIrpStack->Parameters.Read.Length = irpStack->Parameters.Read.Length;
MyIrpStack->Parameters.Read.Key = irpStack->Parameters.Read.Key;
MyIrpStack->Parameters.Read.ByteOffset = irpStack
->Parameters.Read.ByteOffset;
MyIrpStack->MajorFunction = irpStack->MajorFunction;
MyIrpStack->MinorFunction = irpStack->MinorFunction;

PDiskIrp->ReadWriteOffset= irpStack->Parameters.Read.ByteOffset;
break;
}
case IRP_MJ_WRITE:
{
MyIrpStack->Parameters.Write.Length = irpStack->Parameters.Write.Length;
MyIrpStack->Parameters.Write.Key = irpStack->Parameters.Write.Key;
MyIrpStack->Parameters.Write.ByteOffset = irpStack- >Parameters.Write.ByteOffset;
MyIrpStack->MajorFunction = irpStack->MajorFunction;
MyIrpStack->MinorFunction = irpStack->MinorFunction;
PDiskIrp->ReadWriteOffset= irpStack->Parameters.Write.ByteOffset;
break;
}
}

/*New*/FillingIrpArguments(PIrpLocal,IoManagerIrp);

IoSetCompletionRoutine( PIrpLocal,
(PIO_COMPLETION_ROUTINE)CompletionRoutine,
(PDISK_IRP)PDiskIrp,
TRUE,
TRUE,
TRUE);

}

status = IoCallDriver(DeviceObject, PIrpLocal);

if (status == STATUS_PENDING){
IoMarkIrpPending (IoManagerIrp);
return STATUS_PENDING;
}

return status;
}

NTSTATUS CompletionRoutine(PDEVICE_OBJECT fdo, PIRP Irp, PDISK_IRP PDisk_Irp)
{
PIRP OriginalIrp;
PMDL mdl, nextMdl;
ULONG ReadWriteLength;

NTSTATUS Status;
ULONG Information;
PIO_STACK_LOCATION irpStack;
PUCHAR OriginalBuffVA,MyBuffVA;

OriginalIrp = PDisk_Irp->POriginalIrp;

OriginalIrp->IoStatus.Status = Irp->IoStatus.Status;
OriginalIrp->IoStatus.Information = Irp->IoStatus.Information;

IoCompleteRequest(OriginalIrp, IO_NO_INCREMENT);

IoFreeIrp(Irp);

return STATUS_MORE_PROCESSING_REQUIRED;
}

void FillingIrpArguments(PIRP PIrpLocal,PIRP IoManagerIrp)
{
PIrpLocal->MdlAddress = IoManagerIrp->MdlAddress;
PIrpLocal->UserBuffer = IoManagerIrp->UserBuffer;
PIrpLocal->RequestorMode=IoManagerIrp->RequestorMode;
}

Thanks,
Uzair Lakhani

Don’t you need a IoCopyCurrentIrpStackLocationToNext before you go to
the next stack location?

Also, where is PDiskIrp allocated at. If you expect this to hang around
for the completion callback then you can’t allocate this as a local
variable in the subroutine that is starting the IRP.

I ask again, where exactly is this code failing?

MKE.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@yahoo.com
Sent: Friday, September 08, 2006 4:45 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Making a new IRP and Copy IRP Parameters

Hello All,
I have changed my code as guided but still getting the same problem.
Below is my code:

PIrpLocal = IoAllocateIrp (DeviceObject->StackSize,FALSE);

if(PIrpLocal==NULL)
{
DbgPrint(“GenerateIRP()…PIrpLocal Not Allocated IRP\n”);
DbgPrint(“GenerateIRP()…IoBuildAsynchronousFsdRequest
FAILED\n”);
return STATUS_INSUFFICIENT_RESOURCES;
}
else
{
DbgPrint(“GenerateIRP()…PIrpLocal Allocated Successfully
IRP\n”);
//IoInitializeIrp
(PIrpLocal,IoManagerIrp->Size,(CCHAR)(IoManagerIrp->StackCount));
MyIrpStack= IoGetNextIrpStackLocation(PIrpLocal);
switch (irpStack->MajorFunction)
{
case IRP_MJ_READ:
{
MyIrpStack->Parameters.Read.Length =
irpStack->Parameters.Read.Length;
MyIrpStack->Parameters.Read.Key =
irpStack->Parameters.Read.Key;
MyIrpStack->Parameters.Read.ByteOffset = irpStack
->Parameters.Read.ByteOffset;
MyIrpStack->MajorFunction = irpStack->MajorFunction;
MyIrpStack->MinorFunction = irpStack->MinorFunction;

PDiskIrp->ReadWriteOffset=
irpStack->Parameters.Read.ByteOffset;
break;
}
case IRP_MJ_WRITE:
{
MyIrpStack->Parameters.Write.Length =
irpStack->Parameters.Write.Length;
MyIrpStack->Parameters.Write.Key =
irpStack->Parameters.Write.Key;
MyIrpStack->Parameters.Write.ByteOffset = irpStack-

Parameters.Write.ByteOffset;
MyIrpStack->MajorFunction = irpStack->MajorFunction;
MyIrpStack->MinorFunction = irpStack->MinorFunction;
PDiskIrp->ReadWriteOffset=
irpStack->Parameters.Write.ByteOffset;
break;
}
}

/*New*/FillingIrpArguments(PIrpLocal,IoManagerIrp);

IoSetCompletionRoutine( PIrpLocal,

(PIO_COMPLETION_ROUTINE)CompletionRoutine,
(PDISK_IRP)PDiskIrp,
TRUE,
TRUE,
TRUE);

}

status = IoCallDriver(DeviceObject, PIrpLocal);

if (status == STATUS_PENDING){
IoMarkIrpPending (IoManagerIrp);
return STATUS_PENDING;
}

return status;
}

NTSTATUS CompletionRoutine(PDEVICE_OBJECT fdo, PIRP Irp, PDISK_IRP
PDisk_Irp)
{
PIRP OriginalIrp;
PMDL mdl, nextMdl;
ULONG ReadWriteLength;

NTSTATUS Status;
ULONG Information;
PIO_STACK_LOCATION irpStack;
PUCHAR OriginalBuffVA,MyBuffVA;

OriginalIrp = PDisk_Irp->POriginalIrp;

OriginalIrp->IoStatus.Status = Irp->IoStatus.Status;
OriginalIrp->IoStatus.Information = Irp->IoStatus.Information;

IoCompleteRequest(OriginalIrp, IO_NO_INCREMENT);

IoFreeIrp(Irp);

return STATUS_MORE_PROCESSING_REQUIRED;
}

void FillingIrpArguments(PIRP PIrpLocal,PIRP IoManagerIrp)
{
PIrpLocal->MdlAddress = IoManagerIrp->MdlAddress;
PIrpLocal->UserBuffer = IoManagerIrp->UserBuffer;
PIrpLocal->RequestorMode=IoManagerIrp->RequestorMode;
}

Thanks,
Uzair Lakhani


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

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

> Don’t you need a IoCopyCurrentIrpStackLocationToNext before you go to
the next stack location?

If you are referring to this code
MyIrpStack= IoGetNextIrpStackLocation(PIrpLocal);

Then NO, you do not need to copy current to next. When you allocate an
irp, there is no current irp stack location. This has been noted in
this thread earlier. The first valid stack location is the next stack
location (the one which will be used by the target device object).

d

– I can spell, I just can’t type.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Eschmann,
Michael K
Sent: Friday, September 08, 2006 6:59 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] Making a new IRP and Copy IRP Parameters

Don’t you need a IoCopyCurrentIrpStackLocationToNext before you go to
the next stack location?

Also, where is PDiskIrp allocated at. If you expect this to hang around
for the completion callback then you can’t allocate this as a local
variable in the subroutine that is starting the IRP.

I ask again, where exactly is this code failing?

MKE.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@yahoo.com
Sent: Friday, September 08, 2006 4:45 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Making a new IRP and Copy IRP Parameters

Hello All,
I have changed my code as guided but still getting the same problem.
Below is my code:

PIrpLocal = IoAllocateIrp (DeviceObject->StackSize,FALSE);

if(PIrpLocal==NULL)
{
DbgPrint(“GenerateIRP()…PIrpLocal Not Allocated IRP\n”);
DbgPrint(“GenerateIRP()…IoBuildAsynchronousFsdRequest
FAILED\n”);
return STATUS_INSUFFICIENT_RESOURCES;
}
else
{
DbgPrint(“GenerateIRP()…PIrpLocal Allocated Successfully
IRP\n”);
//IoInitializeIrp
(PIrpLocal,IoManagerIrp->Size,(CCHAR)(IoManagerIrp->StackCount));
MyIrpStack= IoGetNextIrpStackLocation(PIrpLocal);
switch (irpStack->MajorFunction)
{
case IRP_MJ_READ:
{
MyIrpStack->Parameters.Read.Length =
irpStack->Parameters.Read.Length;
MyIrpStack->Parameters.Read.Key =
irpStack->Parameters.Read.Key;
MyIrpStack->Parameters.Read.ByteOffset = irpStack
->Parameters.Read.ByteOffset;
MyIrpStack->MajorFunction = irpStack->MajorFunction;
MyIrpStack->MinorFunction = irpStack->MinorFunction;

PDiskIrp->ReadWriteOffset=
irpStack->Parameters.Read.ByteOffset;
break;
}
case IRP_MJ_WRITE:
{
MyIrpStack->Parameters.Write.Length =
irpStack->Parameters.Write.Length;
MyIrpStack->Parameters.Write.Key =
irpStack->Parameters.Write.Key;
MyIrpStack->Parameters.Write.ByteOffset = irpStack-

Parameters.Write.ByteOffset;
MyIrpStack->MajorFunction = irpStack->MajorFunction;
MyIrpStack->MinorFunction = irpStack->MinorFunction;
PDiskIrp->ReadWriteOffset=
irpStack->Parameters.Write.ByteOffset;
break;
}
}

/*New*/FillingIrpArguments(PIrpLocal,IoManagerIrp);

IoSetCompletionRoutine( PIrpLocal,

(PIO_COMPLETION_ROUTINE)CompletionRoutine,
(PDISK_IRP)PDiskIrp,
TRUE,
TRUE,
TRUE);

}

status = IoCallDriver(DeviceObject, PIrpLocal);

if (status == STATUS_PENDING){
IoMarkIrpPending (IoManagerIrp);
return STATUS_PENDING;
}

return status;
}

NTSTATUS CompletionRoutine(PDEVICE_OBJECT fdo, PIRP Irp, PDISK_IRP
PDisk_Irp)
{
PIRP OriginalIrp;
PMDL mdl, nextMdl;
ULONG ReadWriteLength;

NTSTATUS Status;
ULONG Information;
PIO_STACK_LOCATION irpStack;
PUCHAR OriginalBuffVA,MyBuffVA;

OriginalIrp = PDisk_Irp->POriginalIrp;

OriginalIrp->IoStatus.Status = Irp->IoStatus.Status;
OriginalIrp->IoStatus.Information = Irp->IoStatus.Information;

IoCompleteRequest(OriginalIrp, IO_NO_INCREMENT);

IoFreeIrp(Irp);

return STATUS_MORE_PROCESSING_REQUIRED; }

void FillingIrpArguments(PIRP PIrpLocal,PIRP IoManagerIrp) {
PIrpLocal->MdlAddress = IoManagerIrp->MdlAddress;
PIrpLocal->UserBuffer = IoManagerIrp->UserBuffer;
PIrpLocal->RequestorMode=IoManagerIrp->RequestorMode;
}

Thanks,
Uzair Lakhani


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

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


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

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

A wild guess (meaning strong possibility that it’s wrong!!)
Who owns the device object to which you send the newly constructed IRP.

It is your own device object or the one to which you are attached.
If it is your own, then I can understand the bug check reason (stack
over flow)

Harish

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:bounce-261635-
xxxxx@lists.osr.com] On Behalf Of Doron Holan
Sent: Friday, September 08, 2006 7:54 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] Making a new IRP and Copy IRP Parameters

> Don’t you need a IoCopyCurrentIrpStackLocationToNext before you go
to
the next stack location?

If you are referring to this code
MyIrpStack= IoGetNextIrpStackLocation(PIrpLocal);

Then NO, you do not need to copy current to next. When you allocate
an
irp, there is no current irp stack location. This has been noted in
this thread earlier. The first valid stack location is the next stack
location (the one which will be used by the target device object).

d

– I can spell, I just can’t type.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Eschmann,
Michael K
Sent: Friday, September 08, 2006 6:59 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] Making a new IRP and Copy IRP Parameters

Don’t you need a IoCopyCurrentIrpStackLocationToNext before you go to
the next stack location?

Also, where is PDiskIrp allocated at. If you expect this to hang
around
for the completion callback then you can’t allocate this as a local
variable in the subroutine that is starting the IRP.

I ask again, where exactly is this code failing?

MKE.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@yahoo.com
Sent: Friday, September 08, 2006 4:45 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Making a new IRP and Copy IRP Parameters

Hello All,
I have changed my code as guided but still getting the same problem.
Below is my code:

PIrpLocal = IoAllocateIrp (DeviceObject->StackSize,FALSE);

if(PIrpLocal==NULL)
{
DbgPrint(“GenerateIRP()…PIrpLocal Not Allocated IRP\n”);
DbgPrint(“GenerateIRP()…IoBuildAsynchronousFsdRequest
FAILED\n”);
return STATUS_INSUFFICIENT_RESOURCES;
}
else
{
DbgPrint(“GenerateIRP()…PIrpLocal Allocated Successfully
IRP\n”);
//IoInitializeIrp
(PIrpLocal,IoManagerIrp->Size,(CCHAR)(IoManagerIrp->StackCount));
MyIrpStack= IoGetNextIrpStackLocation(PIrpLocal);
switch (irpStack->MajorFunction)
{
case IRP_MJ_READ:
{
MyIrpStack->Parameters.Read.Length =
irpStack->Parameters.Read.Length;
MyIrpStack->Parameters.Read.Key =
irpStack->Parameters.Read.Key;
MyIrpStack->Parameters.Read.ByteOffset = irpStack
->Parameters.Read.ByteOffset;
MyIrpStack->MajorFunction = irpStack->MajorFunction;
MyIrpStack->MinorFunction = irpStack->MinorFunction;

PDiskIrp->ReadWriteOffset=
irpStack->Parameters.Read.ByteOffset;
break;
}
case IRP_MJ_WRITE:
{
MyIrpStack->Parameters.Write.Length =
irpStack->Parameters.Write.Length;
MyIrpStack->Parameters.Write.Key =
irpStack->Parameters.Write.Key;
MyIrpStack->Parameters.Write.ByteOffset = irpStack-
>Parameters.Write.ByteOffset;
MyIrpStack->MajorFunction = irpStack->MajorFunction;
MyIrpStack->MinorFunction = irpStack->MinorFunction;
PDiskIrp->ReadWriteOffset=
irpStack->Parameters.Write.ByteOffset;
break;
}
}

/*New*/FillingIrpArguments(PIrpLocal,IoManagerIrp);

IoSetCompletionRoutine( PIrpLocal,

(PIO_COMPLETION_ROUTINE)CompletionRoutine,
(PDISK_IRP)PDiskIrp,
TRUE,
TRUE,
TRUE);

}

status = IoCallDriver(DeviceObject, PIrpLocal);

if (status == STATUS_PENDING){
IoMarkIrpPending (IoManagerIrp);
return STATUS_PENDING;
}

return status;
}

NTSTATUS CompletionRoutine(PDEVICE_OBJECT fdo, PIRP Irp, PDISK_IRP
PDisk_Irp)
{
PIRP OriginalIrp;
PMDL mdl, nextMdl;
ULONG ReadWriteLength;

NTSTATUS Status;
ULONG Information;
PIO_STACK_LOCATION irpStack;
PUCHAR OriginalBuffVA,MyBuffVA;

OriginalIrp = PDisk_Irp->POriginalIrp;

OriginalIrp->IoStatus.Status = Irp->IoStatus.Status;
OriginalIrp->IoStatus.Information = Irp->IoStatus.Information;

IoCompleteRequest(OriginalIrp, IO_NO_INCREMENT);

IoFreeIrp(Irp);

return STATUS_MORE_PROCESSING_REQUIRED; }

void FillingIrpArguments(PIRP PIrpLocal,PIRP IoManagerIrp) {
PIrpLocal->MdlAddress = IoManagerIrp->MdlAddress;
PIrpLocal->UserBuffer = IoManagerIrp->UserBuffer;
PIrpLocal->RequestorMode=IoManagerIrp->RequestorMode;
}

Thanks,
Uzair Lakhani


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

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


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

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


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

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

You have set the parameters for the transfer, but you have not set up the transfer buffer, or may have set it up incorrectly.

Who is the lower device object? i.e. who are you submitting IRPs to? Is it an I/O device, or a filesystem?

You’re going to need to learn a few things about IRP_MJ_READ and IRP_MJ_WRITE before you continue. Read/write IRPs can be quite complicated. They can potentially be part of the paging path, they can be submitted at various dispatch levels, etc.

You’ll need to understand buffered vs. direct I/O, and you’ll need to make sure that you’re building the kind of read/write IRPs that the target device object is expecting. Read the documentation on IRP_MJ_READ. If the device is using buffered I/O, you’ll need to set Irp->AssociatedIrp.SystemBuffer to a pointer to kernel pool (*not* a user-mode process-relative address). In all likelihood, it needs to be non-paged, unless you have a really firm grasp of paged vs. non-paged pool, and you know what your lower driver is expecting. But I don’t think you’re there yet. If the device is using direct I/O, you’ll need to understand what MDLs (Memory Descriptor Lists) are and how to properly use them. The transfer MDL is stored at Irp->MdlAddress.

Also, if you are a layered device driver, i.e. a FDO or an FiDO, you can simply use the IRP stacks, as they were intended, rather than building a whole new IRP.

Honestly, I think you need to read more and understand the architecture more before you just pound away on a driver until it limps along. There are a lot of good resources, both in print and on the web.

If you want to continue, please post the output of !analyze -v, and make sure your symbols are loaded correctly. People here are willing to help, but only if you are willing to do your homework.

– arlie

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@yahoo.com
Sent: Friday, September 08, 2006 4:45 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Making a new IRP and Copy IRP Parameters

Hello All,
I have changed my code as guided but still getting the same problem. Below is my code:

PIrpLocal = IoAllocateIrp (DeviceObject->StackSize,FALSE);

if(PIrpLocal==NULL)
{
DbgPrint(“GenerateIRP()…PIrpLocal Not Allocated IRP\n”);
DbgPrint(“GenerateIRP()…IoBuildAsynchronousFsdRequest FAILED\n”);
return STATUS_INSUFFICIENT_RESOURCES;
}
else
{
DbgPrint(“GenerateIRP()…PIrpLocal Allocated Successfully IRP\n”);
//IoInitializeIrp (PIrpLocal,IoManagerIrp->Size,(CCHAR)(IoManagerIrp->StackCount));
MyIrpStack= IoGetNextIrpStackLocation(PIrpLocal);
switch (irpStack->MajorFunction)
{
case IRP_MJ_READ:
{
MyIrpStack->Parameters.Read.Length = irpStack->Parameters.Read.Length;
MyIrpStack->Parameters.Read.Key = irpStack->Parameters.Read.Key;
MyIrpStack->Parameters.Read.ByteOffset = irpStack
->Parameters.Read.ByteOffset;
MyIrpStack->MajorFunction = irpStack->MajorFunction;
MyIrpStack->MinorFunction = irpStack->MinorFunction;

PDiskIrp->ReadWriteOffset= irpStack->Parameters.Read.ByteOffset;
break;
}
case IRP_MJ_WRITE:
{
MyIrpStack->Parameters.Write.Length = irpStack->Parameters.Write.Length;
MyIrpStack->Parameters.Write.Key = irpStack->Parameters.Write.Key;
MyIrpStack->Parameters.Write.ByteOffset = irpStack- >Parameters.Write.ByteOffset;
MyIrpStack->MajorFunction = irpStack->MajorFunction;
MyIrpStack->MinorFunction = irpStack->MinorFunction;
PDiskIrp->ReadWriteOffset= irpStack->Parameters.Write.ByteOffset;
break;
}
}

/*New*/FillingIrpArguments(PIrpLocal,IoManagerIrp);

IoSetCompletionRoutine( PIrpLocal,
(PIO_COMPLETION_ROUTINE)CompletionRoutine,
(PDISK_IRP)PDiskIrp,
TRUE,
TRUE,
TRUE);

}

status = IoCallDriver(DeviceObject, PIrpLocal);

if (status == STATUS_PENDING){
IoMarkIrpPending (IoManagerIrp);
return STATUS_PENDING;
}

return status;
}

NTSTATUS CompletionRoutine(PDEVICE_OBJECT fdo, PIRP Irp, PDISK_IRP PDisk_Irp)
{
PIRP OriginalIrp;
PMDL mdl, nextMdl;
ULONG ReadWriteLength;

NTSTATUS Status;
ULONG Information;
PIO_STACK_LOCATION irpStack;
PUCHAR OriginalBuffVA,MyBuffVA;

OriginalIrp = PDisk_Irp->POriginalIrp;

OriginalIrp->IoStatus.Status = Irp->IoStatus.Status;
OriginalIrp->IoStatus.Information = Irp->IoStatus.Information;

IoCompleteRequest(OriginalIrp, IO_NO_INCREMENT);

IoFreeIrp(Irp);

return STATUS_MORE_PROCESSING_REQUIRED;
}

void FillingIrpArguments(PIRP PIrpLocal,PIRP IoManagerIrp)
{
PIrpLocal->MdlAddress = IoManagerIrp->MdlAddress;
PIrpLocal->UserBuffer = IoManagerIrp->UserBuffer;
PIrpLocal->RequestorMode=IoManagerIrp->RequestorMode;
}

Thanks,
Uzair Lakhani


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

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

>I prefer to have my own Irps initialized out of a pool of pre-allocated

non-paged memory. This makes it a counted resource so I work with a
configurable numbers of IRPs in the available Q per device.

No need. But even if you insist on it - use IoSizeOfIrp and IoInitializeIrp.

I understand that IO manager does slab allocations for IRPs but it
seems!! more efficient to have Irp come out of your own managed pool.

I don’t think that there are many drivers which use their own IRP pools.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com