Problem with Irp->MdlAddress

Hello all, I have been lurking on these lists for quite some time absorbing their wisdom and thus far I have not needed to ask any questions of my own because I can usually find the answer after some searching; however, I have found a problem that really perplexes me.

I have a driver which creates a file object. I have a userland program that can read from and write to this device without a problem. However, I have developed a Layered Service Provider (WinSock DLL) that needs to perform some of the same actions as the user land executable. What really perplexes me is that whenever I attempt to write to my driver from within the lsp.dll, it doesn’t work because, for some reason, the Irp->MdlAddress is NULL. I was wondering where I could begin looking for the source of the problem? I am so perplexed because both elements are technically in userland, so behavior shouldn’t be different.

I have pasted relevant portions of code for reference. Please let me know if I can provide any further details. Thank you!

In the driver:
NTSTATUS drvWrite(PDEVICE_OBJECT pDeviceObject, PIRP Irp)
{
NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
PIO_STACK_LOCATION pIoStackIrp = NULL;
PCHAR pWriteDataBuffer;

DbgPrint(“drvWrite called\n”);
pIoStackIrp = IoGetCurrentIrpStackLocation(Irp);
if(NULL != pIoStackIrp && NULL != Irp && NULL != Irp->MdlAddress)
{
pWriteDataBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress,NormalPagePriority);

}

In the LSP’s DllMain:
ghFile = CreateFile(“\\.\Driver”, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if(!ghFile)
{
mydbgprint(“ERROR: Could not open Driver for writing!\n”);
}

In the LSP’s WriteLog:
if(ghFile)
{
if(!WriteFile(ghFile,p,dwSize,&dwBytes,NULL))
{
mydbgprint(“WriteLog: Error could not write to VMDriver! Error: 0x%08x\n”,GetLastError());
}
}
This always fails due to the fact that the actual driver code always has the NULL in the Irp->MdlAddress and this returns STATUS_UNSUCCESSFUL. I can post larger portions of my code, but I would prefer to not bog everyone down with a massive chunk of code.

What IO method do you use??? Please note that Irp->MdlAddress applies to IRP_MJ_READ and IRP_MJ_WRITE requests only if DO_DIRECT_IO is specified in device flags (for IOCTLs IO method depends on IOCTL code, but, again, MDL applies only if IOCTL code implies METHOD_IN_DIRECT or METHOD_OUT_DIRECT). If you driver is not using direct IO, Irp->MdlAddress is NULL …

Anton Bassov

Thanks for the reply Anton. I am in fact using direct I/O and as I stated writing to and reading from the driver works perfectly when done from my userland program. Only when the device is written from the LSP DLL does the buffer become NULL. As a note, I have in fact verified the buffer is not NULL when passed to write.

did you set DO_DIRECT_IO in the Flags for your DeviceObject? Also, you
don’t need to check the return value of IoGetCurrentIrpStackLocation,
you can trust it (besides, it can never return NULL).

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Wednesday, July 11, 2007 2:42 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Problem with Irp->MdlAddress

Hello all, I have been lurking on these lists for quite some time
absorbing their wisdom and thus far I have not needed to ask any
questions of my own because I can usually find the answer after some
searching; however, I have found a problem that really perplexes me.

I have a driver which creates a file object. I have a userland program
that can read from and write to this device without a problem. However,
I have developed a Layered Service Provider (WinSock DLL) that needs to
perform some of the same actions as the user land executable. What
really perplexes me is that whenever I attempt to write to my driver
from within the lsp.dll, it doesn’t work because, for some reason, the
Irp->MdlAddress is NULL. I was wondering where I could begin looking for
the source of the problem? I am so perplexed because both elements are
technically in userland, so behavior shouldn’t be different.

I have pasted relevant portions of code for reference. Please let me
know if I can provide any further details. Thank you!

In the driver:
NTSTATUS drvWrite(PDEVICE_OBJECT pDeviceObject, PIRP Irp)
{
NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
PIO_STACK_LOCATION pIoStackIrp = NULL;
PCHAR pWriteDataBuffer;

DbgPrint(“drvWrite called\n”);
pIoStackIrp = IoGetCurrentIrpStackLocation(Irp);
if(NULL != pIoStackIrp && NULL != Irp && NULL !=
Irp->MdlAddress)
{
pWriteDataBuffer =
MmGetSystemAddressForMdlSafe(Irp->MdlAddress,NormalPagePriority);

}

In the LSP’s DllMain:
ghFile = CreateFile(“\\.\Driver”, GENERIC_READ |
GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if(!ghFile)
{
mydbgprint(“ERROR: Could not open Driver for
writing!\n”);
}

In the LSP’s WriteLog:
if(ghFile)
{
if(!WriteFile(ghFile,p,dwSize,&dwBytes,NULL))
{
mydbgprint(“WriteLog: Error could not write to
VMDriver! Error: 0x%08x\n”,GetLastError());
}
}
This always fails due to the fact that the actual driver code always has
the NULL in the Irp->MdlAddress and this returns STATUS_UNSUCCESSFUL. I
can post larger portions of my code, but I would prefer to not bog
everyone down with a massive chunk of code.


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

Doron, yes I did, the following is (some of) my initialization code:
for(uiIndex = 0; uiIndex < IRP_MJ_MAXIMUM_FUNCTION; uiIndex++)
pDriverObject->MajorFunction[uiIndex] = drvUnsupported;

//register the dispatch functions
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = drvClose;
pDriverObject->MajorFunction[IRP_MJ_CREATE] = drvCreate;
pDriverObject->MajorFunction[IRP_MJ_READ] = drvRead;
pDriverObject->MajorFunction[IRP_MJ_WRITE] = drvWrite;
pDriverObject->DriverUnload = OnUnload;
pDeviceObject->Flags |= DO_DIRECT_IO;
pDeviceObject->Flags &= (~DO_DEVICE_INITIALIZING);
IoCreateSymbolicLink(&usDosDeviceName,&usDriverName);

Thanks for all of the replies so far, hopefully we can resolve this!

Does your driver create only one device object? If you are creating
more than one devobj, are you sure you are setting the DO_DIRECT_IO flag
on all devices your driver creates?

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Wednesday, July 11, 2007 3:26 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Problem with Irp->MdlAddress

Thanks for the reply Anton. I am in fact using direct I/O and as I
stated writing to and reading from the driver works perfectly when done
from my userland program. Only when the device is written from the LSP
DLL does the buffer become NULL. As a note, I have in fact verified the
buffer is not NULL when passed to write.


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 am only creating one device object. The “file” is called Driver and multiple things write to this “file”.

Is there another driver layered on top of yours? Run !devstack device object> and see if it lists anyone else

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Wednesday, July 11, 2007 3:48 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Problem with Irp->MdlAddress

Doron, yes I did, the following is (some of) my initialization code:
for(uiIndex = 0; uiIndex < IRP_MJ_MAXIMUM_FUNCTION; uiIndex++)
pDriverObject->MajorFunction[uiIndex] =
drvUnsupported;

//register the dispatch functions
pDriverObject->MajorFunction[IRP_MJ_CLOSE] =
drvClose;
pDriverObject->MajorFunction[IRP_MJ_CREATE] =
drvCreate;
pDriverObject->MajorFunction[IRP_MJ_READ] =
drvRead;
pDriverObject->MajorFunction[IRP_MJ_WRITE] =
drvWrite;
pDriverObject->DriverUnload = OnUnload;
pDeviceObject->Flags |= DO_DIRECT_IO;
pDeviceObject->Flags &= (~DO_DEVICE_INITIALIZING);
IoCreateSymbolicLink(&usDosDeviceName,&usDriverName);

Thanks for all of the replies so far, hopefully we can resolve this!


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

D, the !devstack command returned this:

kd> !devstack 0x81971868
!DevObj !DrvObj !DevExt ObjectName

81971868 \Driver\VMDRIVER 00000000 VMDriver

It would appear that I am the only device processing theses IRPs.

I found my bug, and it was in the string processing function of my WriteLog file. How embarrassing! The behavior I *was* seemingly magical because it wasn’t caused by the kernel, it was caused by my sleep deprivation. Thank you all for your help, especially you D!

You must set DO_DIRECT_IO flag on your device object for IO manager to
create Irp->MdlAddress in the write path.


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

wrote in message news:xxxxx@ntdev…
> Hello all, I have been lurking on these lists for quite some time absorbing
their wisdom and thus far I have not needed to ask any questions of my own
because I can usually find the answer after some searching; however, I have
found a problem that really perplexes me.
>
> I have a driver which creates a file object. I have a userland program that
can read from and write to this device without a problem. However, I have
developed a Layered Service Provider (WinSock DLL) that needs to perform some
of the same actions as the user land executable. What really perplexes me is
that whenever I attempt to write to my driver from within the lsp.dll, it
doesn’t work because, for some reason, the Irp->MdlAddress is NULL. I was
wondering where I could begin looking for the source of the problem? I am so
perplexed because both elements are technically in userland, so behavior
shouldn’t be different.
>
> I have pasted relevant portions of code for reference. Please let me know if
I can provide any further details. Thank you!
>
> In the driver:
> NTSTATUS drvWrite(PDEVICE_OBJECT pDeviceObject, PIRP Irp)
> {
> NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
> PIO_STACK_LOCATION pIoStackIrp = NULL;
> PCHAR pWriteDataBuffer;
>
> DbgPrint(“drvWrite called\n”);
> pIoStackIrp = IoGetCurrentIrpStackLocation(Irp);
> if(NULL != pIoStackIrp && NULL != Irp && NULL != Irp->MdlAddress)
> {
> pWriteDataBuffer =
MmGetSystemAddressForMdlSafe(Irp->MdlAddress,NormalPagePriority);
> …
> }
>
> In the LSP’s DllMain:
> ghFile = CreateFile(“\\.\Driver”, GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, 0, NULL);
> if(!ghFile)
> {
> mydbgprint(“ERROR: Could not open Driver for writing!\n”);
> }
>
> In the LSP’s WriteLog:
> if(ghFile)
> {
> if(!WriteFile(ghFile,p,dwSize,&dwBytes,NULL))
> {
> mydbgprint(“WriteLog: Error could not write to VMDriver! Error:
0x%08x\n”,GetLastError());
> }
> }
> This always fails due to the fact that the actual driver code always has the
NULL in the Irp->MdlAddress and this returns STATUS_UNSUCCESSFUL. I can post
larger portions of my code, but I would prefer to not bog everyone down with a
massive chunk of code.
>
>

Not to be too caustic, but did you even bother reading the rest of the replies in which I clearly state that I did set that flag? I am new to this list but not new to newsgroups. In general reading the original post as well as follow up replies shows that you are paying attention and avoids redundancy in the thread. Had you read the original replies instead of just mashing the reply button, you would have noticed this. Don’t get me wrong, I appreciate the reply but I am just stating common newsgroup practice. That did come out a little too acrimonious but I guess I’m just trying to show a point. If your mail reader had a delay in sending it, my apologies, and I sincerely thank you for your reply otherwise.

You must set DO_DIRECT_IO flag on your device object for IO manager to create Irp->MdlAddress in
the write path.

If the flag is set - then I would suggest you to step the assembly code of
NtWriteFile related to your device and look why it does not create the MDL.

Half a day of work it seems to me.


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

wrote in message news:xxxxx@ntdev…
> Not to be too caustic, but did you even bother reading the rest of the
replies in which I clearly state that I did set that flag? I am new to this
list but not new to newsgroups. In general reading the original post as well as
follow up replies shows that you are paying attention and avoids redundancy in
the thread. Had you read the original replies instead of just mashing the reply
button, you would have noticed this. Don’t get me wrong, I appreciate the reply
but I am just stating common newsgroup practice. That did come out a little too
acrimonious but I guess I’m just trying to show a point. If your mail reader
had a delay in sending it, my apologies, and I sincerely thank you for your
reply otherwise.
>
> >You must set DO_DIRECT_IO flag on your device object for IO manager to
create Irp->MdlAddress in
> >the write path.
> >- Maxim Shatskih, Windows DDK MVP
> >StorageCraft Corporation xxxxx@storagecraft.com
> >http://www.storagecraft.com
>

Perhaps you missed the part where I said that my problem was solved I mean, you did take my suggestion and read the thread in its entirety? Right. Of course you did.

Maxim is and always has been a bit lagged. He seems to be working out of
a cave somewhere in the vast steppes of asia (or perhaps utah, I can
never get that straight) and either his internet service is
ssssslllllloooooooowwwwwwwww or he responds to the top of a thread
before getting to the bottom. On the other hand he is a grand fellow,
fun to hang out with, and real smart about things inside the NT kernel.
So take it easy.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Thursday, July 12, 2007 2:58 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Problem with Irp->MdlAddress

Not to be too caustic, but did you even bother reading the rest of the
replies in which I clearly state that I did set that flag? I am new to
this list but not new to newsgroups. In general reading the original
post as well as follow up replies shows that you are paying attention
and avoids redundancy in the thread. Had you read the original replies
instead of just mashing the reply button, you would have noticed this.
Don’t get me wrong, I appreciate the reply but I am just stating common
newsgroup practice. That did come out a little too acrimonious but I
guess I’m just trying to show a point. If your mail reader had a delay
in sending it, my apologies, and I sincerely thank you for your reply
otherwise.

You must set DO_DIRECT_IO flag on your device object for IO manager to
create Irp->MdlAddress in
the write path.


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

Like I said, I wasn’t trying to be too unfriendly, I just usually adhere to the strictest of posting rules in order to maximize effectiveness. No harm done, I suppose.

> ----------

From: xxxxx@lists.osr.com[SMTP:xxxxx@lists.osr.com] on behalf of xxxxx@gmail.com[SMTP:xxxxx@gmail.com]
Reply To: Windows System Software Devs Interest List
Sent: Friday, July 13, 2007 1:03 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Problem with Irp->MdlAddress

Like I said, I wasn’t trying to be too unfriendly, I just usually adhere to the strictest of posting rules in order to maximize effectiveness. No harm done, I suppose.

Someone had to say it once :wink:

Anyway, do you realize not everybody here is using newsreader or mailer which is able to show threading? If you don’t include at least a part of an original message (which is IMO one of posting rules), I have no idea to whom and what you reply. I suppose Max has the same problem and in addition he usually replies immediatelly without reading all mails first.

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]