This sounds like it is outside the normal usage pattern for the API
(notice the documentation’s description about how this is useful for
specialized drivers, for example). Thus, this is probably a
documentation bug (it should probably say that you can’t use the
returned MDL for constructing partial MDLs.)
This is very similar to a problem that occurs in file system drivers
where filters substitute in their own MDLs and fail to set the
Irp->UserBuffer to be the same as StartVA properly (see FatNonCachedIo
where it builds the partial MDL and uses Irp->UserBuffer - the issue is
eerily similar to what you describe here.)
In general, one of the important roles of StartVA is to use it for
computing offsets into the MDL when building partials - but this assumes
that you know this fact and pass in the correct offset. That’s why
setting the value in the MDL works properly in your case. Since the
value is really arbitrary for an MDL that isn’t mapped into user mode, I
generally recommend that filter drivers set Irp->UserBuffer to be the
same as this value (returned from the macro MmGetMdlVirtualAddress)
although the reverse direction (which is what you are doing) would also
work. In your case, you could have a magic index value that you set to
MmGetMdlVirtualAddress and then add that index into any subsequent usage
(this is your equivalent of Irp->UserBuffer) and thus you wouldn’t
tamper with the MDL and yet it would work properly.
And just for posterity - if this is NOT your MDL, don’t tinker with the
fields. Even in the case where it IS your MDL, I’d recommend using the
index/offset mechanism rather than changing the value in the MDL even
though the net result will be the same.
Regards,
Tony
Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc.
http://www.osr.com
Looking forward to seeing you at the next OSR File Systems class in
Boston, MA April 24-27, 2006.
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tom Ramsdell
Sent: Tuesday, January 10, 2006 6:26 PM
To: ntdev redirect
Subject: [ntdev] Windows System Software Devs Interest List
I am calling MmAllocatePagesForMdl which returns an MDL whose ByteCount
matches what was requested. Passing the returned MDL to
MmMapLockedPagesSpecifyCache, the MDL is modified such that the
MappedSystemVa matches the returned VA. However, StartVa is NULL.
This becomes a problem later when IoAllocateMdl and IoBuildPartialMdl
are called on a portion of the buffer allocated previously. On return
from IoBuildPartialMdl, the MappedSystemVa is completely wrong. After
some digging, the TargetMdl’s MappedSystemVa is set to
SourceMdl->MappedSystemVa + (VAToIoAllocatePartialMdl -
SourceMdl->StartVa - SourceMdl->ByteOffset).
For VaToIoAllocatePartialMdl, I pass the MappedSysemVa. Since
SourceMdl->StartVa was zero and, in my case, ByteOffset was zero:
TargetMdl->MappedSystemVa = SourceMdl->MappedSystemVa +
VAToIoAllocatePartialMdl
Resulting in TargetMdl->MappedSystemVa being way, way off. Setting the
StartVa to MappedSystemVa after MmMapLockedPagesSpecifyCache results in
IoBuildPartialMdl giving back a usable MDL, though probably for the
wrong reasons.
So, either I’m not using the APIs correctly or
MmMapLockedPagesSpecifyCache should be setting StartVa and is not. Each
of the APIs that take a VA are passed the VA rather than zero or some
relative value. Any insights?
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