I am writing a kmdf driver. I have virtually dis-contiguous memory buffers which needs to be used for a single IO and want to create MDL chain for this.
I was looking for KMDF APIs which would create wdf memory object representing MDL chain. I want to format a wdf request with this memory object.
I read the documentation of WdfMemoryCreate, WdfMemoryCreatePreallocated but doesnt seem to solve the purpose.
It seems I can get it working by creating IRP (in WDM way) and not wdf request.
Any help would highly be appreciated
KMDF does not support this scenario. The driver you are sending the io to also has to understand MDL chains (not many do)
d
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Tuesday, November 01, 2011 11:26 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] KMDF and MDL chain
I am writing a kmdf driver. I have virtually dis-contiguous memory buffers which needs to be used for a single IO and want to create MDL chain for this.
I was looking for KMDF APIs which would create wdf memory object representing MDL chain. I want to format a wdf request with this memory object.
I read the documentation of WdfMemoryCreate, WdfMemoryCreatePreallocated but doesnt seem to solve the purpose.
It seems I can get it working by creating IRP (in WDM way) and not wdf request.
Any help would highly be appreciated
NTDEV is sponsored by OSR
For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars
To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
I believe it supports chained MDLs. I will validate and update here.
So, if it is supporting chained MDLs, can I create IRP in KMDF driver. There seems no restriction using DDIs in KMDF
You can format the underlying IRP if you want. The io target will want you that you have used at some kind of KMDF formatting call though, typically WdfRequestWdmFormatUsingStackLocation works quite well in this scenario.
d
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Tuesday, November 01, 2011 11:43 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] KMDF and MDL chain
I believe it supports chained MDLs. I will validate and update here.
So, if it is supporting chained MDLs, can I create IRP in KMDF driver. There seems no restriction using DDIs in KMDF
NTDEV is sponsored by OSR
For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars
To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
Yes, you CAN create your own IRPs and manage your own buffers/MDLs within a KMDF driver. That’s one of the beauties of KMDF.
But, as Doron suggested… proceed with caution. It is difficult to know whether the ultimate target of your I/O Request will support chained MDLs. For example, whether chained MDLs are supported or not can depend on which SPECIFIC DMA APIs the ultimate driver handling the request uses.
Good luck,
Peter
OSR
>your I/O Request will support chained MDLs
Things like TDI, for instance, surely support them.
–
Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com
Thanks Maxim, Doron, Peter for your quick reply.
Let me explain my requirement in a bit detail. The driver (Storage driver - disk/volume class drivers) I am sending the io, supports MDL chains. I tried MDL chain support with a test driver. Please confirm if this holds always true.
>WdfRequestWdmFormatUsingStackLocation works quite well in this scenario.
So, using WdfRequestWdmFormatUsingStackLocation I can set wdf request parameters. This will not set buffer (MDL in this case) for the request. I need to get the IRP using WdfRequestWdmGetIrp and set MdlAddress to MDL chain. Please correct me if I am wrong.
Yes, you need to set the mdl yourself. I didn’t think the underlying storage stack supported chained mdls
d
debt from my phone
From: xxxxx@gmail.com
Sent: 11/1/2011 9:37 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] KMDF and MDL chain
Thanks Maxim, Doron, Peter for your quick reply.
Let me explain my requirement in a bit detail. The driver (Storage driver - disk/volume class drivers) I am sending the io, supports MDL chains. I tried MDL chain support with a test driver. Please confirm if this holds always true.
>WdfRequestWdmFormatUsingStackLocation works quite well in this scenario.
So, using WdfRequestWdmFormatUsingStackLocation I can set wdf request parameters. This will not set buffer (MDL in this case) for the request. I need to get the IRP using WdfRequestWdmGetIrp and set MdlAddress to MDL chain. Please correct me if I am wrong.
NTDEV is sponsored by OSR
For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars
To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
Thanks Doron
> I didn’t think the underlying storage stack supported chained mdls
I have not found any documentation discussing MDL chain support with these drivers. It seems. there are chances that MDL chain support may not be consistent on different windows versions for these drivers and subject to change.
The alternative design to MDL chain, was to divide the IO (not standard windows IO request) into multiples (windows IO requests) considering contiguous virtual addresses which I wanted to avoid.
> Let me explain my requirement in a bit detail. The driver (Storage driver - disk/volume class drivers) I
am sending the io, supports MDL chains. I tried MDL chain support with a test driver. Please confirm
if this holds always true.
Storage stack actually was never ever supported MDL chains, I’m surprised it is so.
–
Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com
This is how I verified MDL chain on windows 2008 R2
#define NUMBER_OF_PAGES 10
PVOID Vaddress[NUMBER_OF_PAGES] = {0};
PVOID Vaddress_hole[NUMBER_OF_PAGES] = {0};
PMDL MdlArr[NUMBER_OF_PAGES] = {0};
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
ULONG i;
PDEVICE_OBJECT DeviceObject;
NTSTATUS ntStatus = STATUS_SUCCESS;
PMDL SingleMdl;
PVOID buffer;
DriverObject->DriverUnload = Unload;
for (i =0 ; i < NUMBER_OF_PAGES; i++)
{
Vaddress[i] = ExAllocatePoolWithTag(NonPagedPool,4096, TEST_TAG);
ASSERT(Vaddress[i]);
DbgPrint(“Vaddress[%d] = %p\n”, i, Vaddress[i]);
MdlArr[i] = IoAllocateMdl(
Vaddress[i] ,
4096,
FALSE,
FALSE,
NULL
);
DbgPrint(“MdlArr[%d] = %p\n”, i, MdlArr[i]);
MmBuildMdlForNonPagedPool(MdlArr[i]);
if( i != 0)
{
MdlArr[i - 1]->Next = MdlArr[i];
}
Vaddress_hole[i] = ExAllocatePoolWithTag(NonPagedPool,4096, TEST_TAG);
ASSERT(Vaddress_hole[i]);
}
ntStatus = GetDeviceObject(&DeviceObject);
ASSERT(NT_SUCCESS(ntStatus));
if(!NT_SUCCESS(ntStatus))
{
goto claenup;
}
ntStatus =VolRead(DeviceObject, MdlArr[0],4096 * NUMBER_OF_PAGES);
ASSERT(NT_SUCCESS(ntStatus));
buffer = ExAllocatePoolWithTag(NonPagedPool,4096 * NUMBER_OF_PAGES,TEST_TAG);
ASSERT(buffer);
SingleMdl = IoAllocateMdl(
buffer,
4096 * 10,
FALSE,
FALSE,
NULL
);
MmBuildMdlForNonPagedPool(SingleMdl);
ASSERT(SingleMdl);
ntStatus =VolRead(DeviceObject, SingleMdl,4096 * NUMBER_OF_PAGES);
ASSERT(NT_SUCCESS(ntStatus));
for (i =0 ; i < NUMBER_OF_PAGES; i++)
{
ULONG MatchedBytes =RtlCompareMemory(
(PCHAR)buffer + (i * 4096),
Vaddress[i],
4096
);
ASSERT( 4096 == MatchedBytes);
}
claenup:
for (i =0 ; i < NUMBER_OF_PAGES; i++)
{
IoFreeMdl(MdlArr[i]);
ExFreePool(Vaddress[i]);
ExFreePool(Vaddress_hole[i]);
}
IoFreeMdl(SingleMdl);
ExFreePool(buffer);
return STATUS_SUCCESS;
}
Can anybody from MS tell whether this is a supported scenario?
What about large (>64K requests), for a case Disk.sys to split the request to several smaller ones? will they work?
What about 3rd party filter drivers? will all of them crash due to this code? I think there is a very major probability with this.
Will this work on both SATA and USB-connected storage? what about iSCSI?
I personally would never ever write such code in the product, unless some authority source within MS will answer “yes, it is OK”. Not only the question is about older Windows, but also about the compat issues listed above.
–
Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com
wrote in message news:xxxxx@ntdev…
> This is how I verified MDL chain on windows 2008 R2
>
> #define NUMBER_OF_PAGES 10
>
> PVOID Vaddress[NUMBER_OF_PAGES] = {0};
> PVOID Vaddress_hole[NUMBER_OF_PAGES] = {0};
>
> PMDL MdlArr[NUMBER_OF_PAGES] = {0};
>
> NTSTATUS
> DriverEntry(
> IN PDRIVER_OBJECT DriverObject,
> IN PUNICODE_STRING RegistryPath
> )
> {
> ULONG i;
> PDEVICE_OBJECT DeviceObject;
> NTSTATUS ntStatus = STATUS_SUCCESS;
> PMDL SingleMdl;
> PVOID buffer;
>
> DriverObject->DriverUnload = Unload;
>
> for (i =0 ; i < NUMBER_OF_PAGES; i++)
> {
> Vaddress[i] = ExAllocatePoolWithTag(NonPagedPool,4096, TEST_TAG);
> ASSERT(Vaddress[i]);
>
> DbgPrint(“Vaddress[%d] = %p\n”, i, Vaddress[i]);
>
> MdlArr[i] = IoAllocateMdl(
> Vaddress[i] ,
> 4096,
> FALSE,
> FALSE,
> NULL
> );
>
> DbgPrint(“MdlArr[%d] = %p\n”, i, MdlArr[i]);
> MmBuildMdlForNonPagedPool(MdlArr[i]);
>
> if( i != 0)
> {
> MdlArr[i - 1]->Next = MdlArr[i];
> }
>
> Vaddress_hole[i] = ExAllocatePoolWithTag(NonPagedPool,4096, TEST_TAG);
> ASSERT(Vaddress_hole[i]);
> }
>
>
> ntStatus = GetDeviceObject(&DeviceObject);
> ASSERT(NT_SUCCESS(ntStatus));
> if(!NT_SUCCESS(ntStatus))
> {
> goto claenup;
> }
>
> ntStatus =VolRead(DeviceObject, MdlArr[0],4096 * NUMBER_OF_PAGES);
> ASSERT(NT_SUCCESS(ntStatus));
>
> buffer = ExAllocatePoolWithTag(NonPagedPool,4096 * NUMBER_OF_PAGES,TEST_TAG);
> ASSERT(buffer);
>
> SingleMdl = IoAllocateMdl(
> buffer,
> 4096 * 10,
> FALSE,
> FALSE,
> NULL
> );
>
> MmBuildMdlForNonPagedPool(SingleMdl);
> ASSERT(SingleMdl);
>
> ntStatus =VolRead(DeviceObject, SingleMdl,4096 * NUMBER_OF_PAGES);
> ASSERT(NT_SUCCESS(ntStatus));
>
> for (i =0 ; i < NUMBER_OF_PAGES; i++)
> {
> ULONG MatchedBytes =RtlCompareMemory(
> (PCHAR)buffer + (i * 4096),
> Vaddress[i],
> 4096
> );
>
> ASSERT( 4096 == MatchedBytes);
> }
>
> claenup:
> for (i =0 ; i < NUMBER_OF_PAGES; i++)
> {
> IoFreeMdl(MdlArr[i]);
> ExFreePool(Vaddress[i]);
> ExFreePool(Vaddress_hole[i]);
> }
>
> IoFreeMdl(SingleMdl);
> ExFreePool(buffer);
>
> return STATUS_SUCCESS;
> }
>
>
>
Thanks Maxim.
> What about large (>64K requests), for a case Disk.sys to split the request
> to several smaller ones? will they work?
Just out of curiosity - Can you elaborate on request splitting ? Does it also happen at volume layer (I can think of scenario of striped volume) ?
I also found MmProbeAndLockSelectedPages (http://msdn.microsoft.com/en-us/library/windows/hardware/hh406526(v=vs.85).aspx) which create single MDL from dis-contiguous address space. But not available on all windows versions.
“Maxim S. Shatskih” wrote in message news:xxxxx@ntdev…
What about large (>64K requests), for a case Disk.sys to split the request
to several smaller ones? will they work?
There was a post here a few months back where someone had system crash due
to sending disk.sys chained MDLs. More evidence that this has never been
supported in the storage stack.
-scott
–
Scott Noone
Consulting Associate and Chief System Problem Analyst
OSR Open Systems Resources, Inc.
http://www.osronline.com
“Maxim S. Shatskih” wrote in message news:xxxxx@ntdev…
Can anybody from MS tell whether this is a supported scenario?
What about large (>64K requests), for a case Disk.sys to split the
request to several smaller ones? will they work?
What about 3rd party filter drivers? will all of them crash due to
this code? I think there is a very major probability with this.
Will this work on both SATA and USB-connected storage? what about iSCSI?
I personally would never ever write such code in the product, unless
some authority source within MS will answer “yes, it is OK”. Not only the
question is about older Windows, but also about the compat issues listed
above.
–
Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com
wrote in message news:xxxxx@ntdev…
> This is how I verified MDL chain on windows 2008 R2
>
> #define NUMBER_OF_PAGES 10
>
> PVOID Vaddress[NUMBER_OF_PAGES] = {0};
> PVOID Vaddress_hole[NUMBER_OF_PAGES] = {0};
>
> PMDL MdlArr[NUMBER_OF_PAGES] = {0};
>
> NTSTATUS
> DriverEntry(
> IN PDRIVER_OBJECT DriverObject,
> IN PUNICODE_STRING RegistryPath
> )
> {
> ULONG i;
> PDEVICE_OBJECT DeviceObject;
> NTSTATUS ntStatus = STATUS_SUCCESS;
> PMDL SingleMdl;
> PVOID buffer;
>
> DriverObject->DriverUnload = Unload;
>
> for (i =0 ; i < NUMBER_OF_PAGES; i++)
> {
> Vaddress[i] = ExAllocatePoolWithTag(NonPagedPool,4096, TEST_TAG);
> ASSERT(Vaddress[i]);
>
> DbgPrint(“Vaddress[%d] = %p\n”, i, Vaddress[i]);
>
> MdlArr[i] = IoAllocateMdl(
> Vaddress[i] ,
> 4096,
> FALSE,
> FALSE,
> NULL
> );
>
> DbgPrint(“MdlArr[%d] = %p\n”, i, MdlArr[i]);
> MmBuildMdlForNonPagedPool(MdlArr[i]);
>
> if( i != 0)
> {
> MdlArr[i - 1]->Next = MdlArr[i];
> }
>
> Vaddress_hole[i] = ExAllocatePoolWithTag(NonPagedPool,4096, TEST_TAG);
> ASSERT(Vaddress_hole[i]);
> }
>
>
> ntStatus = GetDeviceObject(&DeviceObject);
> ASSERT(NT_SUCCESS(ntStatus));
> if(!NT_SUCCESS(ntStatus))
> {
> goto claenup;
> }
>
> ntStatus =VolRead(DeviceObject, MdlArr[0],4096 * NUMBER_OF_PAGES);
> ASSERT(NT_SUCCESS(ntStatus));
>
> buffer = ExAllocatePoolWithTag(NonPagedPool,4096 *
> NUMBER_OF_PAGES,TEST_TAG);
> ASSERT(buffer);
>
> SingleMdl = IoAllocateMdl(
> buffer,
> 4096 * 10,
> FALSE,
> FALSE,
> NULL
> );
>
> MmBuildMdlForNonPagedPool(SingleMdl);
> ASSERT(SingleMdl);
>
> ntStatus =VolRead(DeviceObject, SingleMdl,4096 * NUMBER_OF_PAGES);
> ASSERT(NT_SUCCESS(ntStatus));
>
> for (i =0 ; i < NUMBER_OF_PAGES; i++)
> {
> ULONG MatchedBytes =RtlCompareMemory(
> (PCHAR)buffer + (i * 4096),
> Vaddress[i],
> 4096
> );
>
> ASSERT( 4096 == MatchedBytes);
> }
>
> claenup:
> for (i =0 ; i < NUMBER_OF_PAGES; i++)
> {
> IoFreeMdl(MdlArr[i]);
> ExFreePool(Vaddress[i]);
> ExFreePool(Vaddress_hole[i]);
> }
>
> IoFreeMdl(SingleMdl);
> ExFreePool(buffer);
>
> return STATUS_SUCCESS;
> }
>
>
>
>Just out of curiosity - Can you elaborate on request splitting ? Does it
also happen at volume layer (I can think of scenario of striped volume) ?
Absolutely. It can happen at file system layer (fragmentation), the volume
layer (RAID), and the disk layer (maximum adapter transfer length). Normally
it’s done by associated IRPs (either the O/S support or custom) and partial
MDLs. See ServiceTransferRequest in the classpnp source for how disk.sys
does the splitting.
-scott
–
Scott Noone
Consulting Associate and Chief System Problem Analyst
OSR Open Systems Resources, Inc.
http://www.osronline.com
wrote in message news:xxxxx@ntdev…
Thanks Maxim.
> What about large (>64K requests), for a case Disk.sys to split the
> request
> to several smaller ones? will they work?
Just out of curiosity - Can you elaborate on request splitting ? Does it
also happen at volume layer (I can think of scenario of striped volume) ?
I also found MmProbeAndLockSelectedPages
(http://msdn.microsoft.com/en-us/library/windows/hardware/hh406526(v=vs.85).aspx)
which create single MDL from dis-contiguous address space. But not available
on all windows versions.
Talking to the storage team developers, it doesn’t sound like anyone has added mdl chain support recently.
I’d say it’s unsupported and this experiment was a fluke if it really worked.
Don’t try to use chained mdls in the storage stack.
-p
Sent from my Windows Phone
From: Maxim S. Shatskih
Sent: 11/2/2011 9:00 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] KMDF and MDL chain
Can anybody from MS tell whether this is a supported scenario?
What about large (>64K requests), for a case Disk.sys to split the request to several smaller ones? will they work?
What about 3rd party filter drivers? will all of them crash due to this code? I think there is a very major probability with this.
Will this work on both SATA and USB-connected storage? what about iSCSI?
I personally would never ever write such code in the product, unless some authority source within MS will answer “yes, it is OK”. Not only the question is about older Windows, but also about the compat issues listed above.
–
Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com
wrote in message news:xxxxx@ntdev…
> This is how I verified MDL chain on windows 2008 R2
>
> #define NUMBER_OF_PAGES 10
>
> PVOID Vaddress[NUMBER_OF_PAGES] = {0};
> PVOID Vaddress_hole[NUMBER_OF_PAGES] = {0};
>
> PMDL MdlArr[NUMBER_OF_PAGES] = {0};
>
> NTSTATUS
> DriverEntry(
> IN PDRIVER_OBJECT DriverObject,
> IN PUNICODE_STRING RegistryPath
> )
> {
> ULONG i;
> PDEVICE_OBJECT DeviceObject;
> NTSTATUS ntStatus = STATUS_SUCCESS;
> PMDL SingleMdl;
> PVOID buffer;
>
> DriverObject->DriverUnload = Unload;
>
> for (i =0 ; i < NUMBER_OF_PAGES; i++)
> {
> Vaddress[i] = ExAllocatePoolWithTag(NonPagedPool,4096, TEST_TAG);
> ASSERT(Vaddress[i]);
>
> DbgPrint(“Vaddress[%d] = %p\n”, i, Vaddress[i]);
>
> MdlArr[i] = IoAllocateMdl(
> Vaddress[i] ,
> 4096,
> FALSE,
> FALSE,
> NULL
> );
>
> DbgPrint(“MdlArr[%d] = %p\n”, i, MdlArr[i]);
> MmBuildMdlForNonPagedPool(MdlArr[i]);
>
> if( i != 0)
> {
> MdlArr[i - 1]->Next = MdlArr[i];
> }
>
> Vaddress_hole[i] = ExAllocatePoolWithTag(NonPagedPool,4096, TEST_TAG);
> ASSERT(Vaddress_hole[i]);
> }
>
>
> ntStatus = GetDeviceObject(&DeviceObject);
> ASSERT(NT_SUCCESS(ntStatus));
> if(!NT_SUCCESS(ntStatus))
> {
> goto claenup;
> }
>
> ntStatus =VolRead(DeviceObject, MdlArr[0],4096 * NUMBER_OF_PAGES);
> ASSERT(NT_SUCCESS(ntStatus));
>
> buffer = ExAllocatePoolWithTag(NonPagedPool,4096 * NUMBER_OF_PAGES,TEST_TAG);
> ASSERT(buffer);
>
> SingleMdl = IoAllocateMdl(
> buffer,
> 4096 * 10,
> FALSE,
> FALSE,
> NULL
> );
>
> MmBuildMdlForNonPagedPool(SingleMdl);
> ASSERT(SingleMdl);
>
> ntStatus =VolRead(DeviceObject, SingleMdl,4096 * NUMBER_OF_PAGES);
> ASSERT(NT_SUCCESS(ntStatus));
>
> for (i =0 ; i < NUMBER_OF_PAGES; i++)
> {
> ULONG MatchedBytes =RtlCompareMemory(
> (PCHAR)buffer + (i * 4096),
> Vaddress[i],
> 4096
> );
>
> ASSERT( 4096 == MatchedBytes);
> }
>
> claenup:
> for (i =0 ; i < NUMBER_OF_PAGES; i++)
> {
> IoFreeMdl(MdlArr[i]);
> ExFreePool(Vaddress[i]);
> ExFreePool(Vaddress_hole[i]);
> }
>
> IoFreeMdl(SingleMdl);
> ExFreePool(buffer);
>
> return STATUS_SUCCESS;
> }
>
>
>
—
NTDEV is sponsored by OSR
For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars
To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
I spend a lot of time reading code, and I’ve never seen chained MDLs used or
supported anywhere outside of networking.
Jake Oshins
Hyper-V I/O Architect
Windows Kernel Group
This post implies no warranties and confers no rights.
“Peter Wieland” wrote in message
news:xxxxx@ntdev…
Talking to the storage team developers, it doesn’t sound like anyone has
added mdl chain support recently.
I’d say it’s unsupported and this experiment was a fluke if it really
worked.
Don’t try to use chained mdls in the storage stack.
-p
Sent from my Windows Phone
From: Maxim S. Shatskih
Sent: 11/2/2011 9:00 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] KMDF and MDL chain
Can anybody from MS tell whether this is a supported scenario?
What about large (>64K requests), for a case Disk.sys to split the
request to several smaller ones? will they work?
What about 3rd party filter drivers? will all of them crash due to
this code? I think there is a very major probability with this.
Will this work on both SATA and USB-connected storage? what about iSCSI?
I personally would never ever write such code in the product, unless
some authority source within MS will answer “yes, it is OK”. Not only the
question is about older Windows, but also about the compat issues listed
above.
–
Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com
wrote in message news:xxxxx@ntdev…
> This is how I verified MDL chain on windows 2008 R2
>
> #define NUMBER_OF_PAGES 10
>
> PVOID Vaddress[NUMBER_OF_PAGES] = {0};
> PVOID Vaddress_hole[NUMBER_OF_PAGES] = {0};
>
> PMDL MdlArr[NUMBER_OF_PAGES] = {0};
>
> NTSTATUS
> DriverEntry(
> IN PDRIVER_OBJECT DriverObject,
> IN PUNICODE_STRING RegistryPath
> )
> {
> ULONG i;
> PDEVICE_OBJECT DeviceObject;
> NTSTATUS ntStatus = STATUS_SUCCESS;
> PMDL SingleMdl;
> PVOID buffer;
>
> DriverObject->DriverUnload = Unload;
>
> for (i =0 ; i < NUMBER_OF_PAGES; i++)
> {
> Vaddress[i] = ExAllocatePoolWithTag(NonPagedPool,4096, TEST_TAG);
> ASSERT(Vaddress[i]);
>
> DbgPrint(“Vaddress[%d] = %p\n”, i, Vaddress[i]);
>
> MdlArr[i] = IoAllocateMdl(
> Vaddress[i] ,
> 4096,
> FALSE,
> FALSE,
> NULL
> );
>
> DbgPrint(“MdlArr[%d] = %p\n”, i, MdlArr[i]);
> MmBuildMdlForNonPagedPool(MdlArr[i]);
>
> if( i != 0)
> {
> MdlArr[i - 1]->Next = MdlArr[i];
> }
>
> Vaddress_hole[i] = ExAllocatePoolWithTag(NonPagedPool,4096, TEST_TAG);
> ASSERT(Vaddress_hole[i]);
> }
>
>
> ntStatus = GetDeviceObject(&DeviceObject);
> ASSERT(NT_SUCCESS(ntStatus));
> if(!NT_SUCCESS(ntStatus))
> {
> goto claenup;
> }
>
> ntStatus =VolRead(DeviceObject, MdlArr[0],4096 * NUMBER_OF_PAGES);
> ASSERT(NT_SUCCESS(ntStatus));
>
> buffer = ExAllocatePoolWithTag(NonPagedPool,4096 *
> NUMBER_OF_PAGES,TEST_TAG);
> ASSERT(buffer);
>
> SingleMdl = IoAllocateMdl(
> buffer,
> 4096 * 10,
> FALSE,
> FALSE,
> NULL
> );
>
> MmBuildMdlForNonPagedPool(SingleMdl);
> ASSERT(SingleMdl);
>
> ntStatus =VolRead(DeviceObject, SingleMdl,4096 * NUMBER_OF_PAGES);
> ASSERT(NT_SUCCESS(ntStatus));
>
> for (i =0 ; i < NUMBER_OF_PAGES; i++)
> {
> ULONG MatchedBytes =RtlCompareMemory(
> (PCHAR)buffer + (i * 4096),
> Vaddress[i],
> 4096
> );
>
> ASSERT( 4096 == MatchedBytes);
> }
>
> claenup:
> for (i =0 ; i < NUMBER_OF_PAGES; i++)
> {
> IoFreeMdl(MdlArr[i]);
> ExFreePool(Vaddress[i]);
> ExFreePool(Vaddress_hole[i]);
> }
>
> IoFreeMdl(SingleMdl);
> ExFreePool(buffer);
>
> return STATUS_SUCCESS;
> }
>
>
>
—
NTDEV is sponsored by OSR
For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars
To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer
Thanks Scott for detailed explanation about request splitting.
Thanks Peter and Jake from conforming. I am trying to find different solutions than using chained MDL.
> Just out of curiosity - Can you elaborate on request splitting ?
When Disk/ClassPnP translate from MJ_READ to SCSIOP_READ, they split the single request to many smaller requests according to the storage controller’s maximum request size.
–
Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com