Hello,
I get a bug check (PAGE_FAULT_IN_NONPAGED_AREA) when accessing the last
page described by the MdlAddress used for a read operation after that
read operation has completed by the lower driver. As far as I know, the
IO Manager allocates and locks the MdlAddress and it also unlocks it. Or
maybe the file system below (NTFS on Win2000) is unlocking it when
completing the read operation. If so, do I have to call MmProbeAndLock
again for that MdlAddress ? I tried that and it didn’t work. I tried
also with MmBuildMdlForNonPagedPool and it worked, but when I close the
process involved I get another bug check (PROCESS_HASH_LOCKED_PAGES).
It this normal for a MdlAddress to be unlocked before I complete the
read request ? How can I solve this ?
Daniel
What are you trying to do as the end result? Access the data in the
read
completion?
If an Mdl was supplied already, when your driver is called, then you
can
use MmGetSystemAddressForMdlSafe in the completion. If not, and you do
want
to access the buffer in the completion, then you have to allocate an Mdl
to
wrap around the user buffer and MmProbeAndLockPages on it in the
dispatch
routine. You can see that FastFat does that (In FatLockUserBuffer) for
certain operations, if it posts an IRP - since the user buffer might be
invalid in the completion routine.
You must also take into account MDL reads/writes - unless you handle
IRP_NOCACHE flag only.
During IRP_MJ_WRITE: you should ignore the call if the Minor
Function is
IRP_MN_MDL, as that only returns the MDL describing the file range - the
Cc
assumes the entire range will be overwritten. I suppose it zeroes out
the
pages. You will have NO MdlAddress or UserBuffer in the dispatch in this
case. An Mdl will be provided in the completion - if the call is
successful.
During IRP_MN_COMPLETE_MDL the MDL is returned to the file system - note
that IRP_MN_MDL and IRP_MN_COMPLETE_MDL won’t have IRP_NOCACHE bit in
Irp->Flags.
During IRP_MJ_READ: IRP_MN_MDL - the same. MdlAddress and UserBuffer
are
both NULL in the dispatch, and MdlAddress is set before your completion
is
called - if the call is successful.
MDLs returned for IRP_MN_MDL calls are locked in memory, so you can
just
call MmGetSystemAddressForMdlSafe in the completion. It is common that
these
MDLs are chained - so you need to handle Irp->MdlAddress->Next (and on)
which I have never seen for paging I/O (can’t say it won’t happen of
course…) and I’d like to know whether it’s possible that MDLs provided
in paging I/O can be chained or will it always be just one MDL.
Regards, Dejan.
Daniel Turcanu wrote:
Hello,
I get a bug check (PAGE_FAULT_IN_NONPAGED_AREA) when accessing the last
page described by the MdlAddress used for a read operation after that
read operation has completed by the lower driver. As far as I know, the
IO Manager allocates and locks the MdlAddress and it also unlocks it. Or
maybe the file system below (NTFS on Win2000) is unlocking it when
completing the read operation. If so, do I have to call MmProbeAndLock
again for that MdlAddress ? I tried that and it didn’t work. I tried
also with MmBuildMdlForNonPagedPool and it worked, but when I close the
process involved I get another bug check (PROCESS_HASH_LOCKED_PAGES).
It this normal for a MdlAddress to be unlocked before I complete the
read request ? How can I solve this ?
–
Kind regards, Dejan M. MVP for DDK
http://www.alfasp.com E-mail: xxxxx@alfasp.com
Alfa Transparent File Encryptor - Transparent file encryption services.
Alfa File Protector - File protection and hiding library for Win32
developers.
Alfa File Monitor - File monitoring library for Win32 developers.
What I was trying to do is this:
- send forward the read operation with the length truncated to be a
multiple of 4096
- after completion (wait for event etc.) get the buffer (if MdlAddress
is active I use the MmGetSystemAddressForMdl function)
- decrypt that data
- for the rest of the data I send another read Irp with 4096 len
- decrypt that data and copy it to the user buffer (and here it crashes)
Now I am getting the system address for the buffer before sending
forward the request and the read works perfectly. I don’t get the exact
logic of this, but it works. So, programmers all over the world, don’t
try to access MdlAddress after the file system below has processed the
operation, or else…
Thanks for the MN_MDL advice, it is a good thing to know.
Daniel
Dejan Maksimovic wrote:
What are you trying to do as the end result? Access the data in the
read
completion?
If an Mdl was supplied already, when your driver is called, then you
can
use MmGetSystemAddressForMdlSafe in the completion. If not, and you do
want
to access the buffer in the completion, then you have to allocate an Mdl
to
wrap around the user buffer and MmProbeAndLockPages on it in the
dispatch
routine. You can see that FastFat does that (In FatLockUserBuffer) for
certain operations, if it posts an IRP - since the user buffer might be
invalid in the completion routine.
You must also take into account MDL reads/writes - unless you handle
IRP_NOCACHE flag only.
During IRP_MJ_WRITE: you should ignore the call if the Minor
Function is
IRP_MN_MDL, as that only returns the MDL describing the file range - the
Cc
assumes the entire range will be overwritten. I suppose it zeroes out
the
pages. You will have NO MdlAddress or UserBuffer in the dispatch in this
case. An Mdl will be provided in the completion - if the call is
successful.
During IRP_MN_COMPLETE_MDL the MDL is returned to the file system - note
that IRP_MN_MDL and IRP_MN_COMPLETE_MDL won’t have IRP_NOCACHE bit in
Irp->Flags.
During IRP_MJ_READ: IRP_MN_MDL - the same. MdlAddress and UserBuffer
are
both NULL in the dispatch, and MdlAddress is set before your completion
is
called - if the call is successful.
MDLs returned for IRP_MN_MDL calls are locked in memory, so you can
just
call MmGetSystemAddressForMdlSafe in the completion. It is common that
these
MDLs are chained - so you need to handle Irp->MdlAddress->Next (and on)
which I have never seen for paging I/O (can’t say it won’t happen of
course…) and I’d like to know whether it’s possible that MDLs provided
in paging I/O can be chained or will it always be just one MDL.
Regards, Dejan.
Daniel Turcanu wrote:
>Hello,
>
>I get a bug check (PAGE_FAULT_IN_NONPAGED_AREA) when accessing the last
>page described by the MdlAddress used for a read operation after that
>read operation has completed by the lower driver. As far as I know, the
>IO Manager allocates and locks the MdlAddress and it also unlocks it. Or
>maybe the file system below (NTFS on Win2000) is unlocking it when
>completing the read operation. If so, do I have to call MmProbeAndLock
>again for that MdlAddress ? I tried that and it didn’t work. I tried
>also with MmBuildMdlForNonPagedPool and it worked, but when I close the
>process involved I get another bug check (PROCESS_HASH_LOCKED_PAGES).
>It this normal for a MdlAddress to be unlocked before I complete the
>read request ? How can I solve this ?
>
>
–
Kind regards, Dejan M. MVP for DDK
http://www.alfasp.com E-mail: xxxxx@alfasp.com
Alfa Transparent File Encryptor - Transparent file encryption services.
Alfa File Protector - File protection and hiding library for Win32
developers.
Alfa File Monitor - File monitoring library for Win32 developers.
You are currently subscribed to ntfsd as: xxxxx@ipdevel.ro
To unsubscribe send a blank email to xxxxx@lists.osr.com
> Now I am getting the system address for the buffer before sending
forward the request and the read works perfectly. I don’t get the exact
logic of this, but it works. So, programmers all over the world, don’t
try to access MdlAddress after the file system below has processed the
operation, or else…
Whatever you are doing must be wrong then - you may access the
Irp->MdlAddress after the file system has finished processing - i.e. after
your completion routine was called. Otherwise, what data would you decrypt on
read…
–
Kind regards, Dejan M. MVP for DDK
http://www.alfasp.com E-mail: xxxxx@alfasp.com
Alfa Transparent File Encryptor - Transparent file encryption services.
Alfa File Protector - File protection and hiding library for Win32 developers.
Alfa File Monitor - File monitoring library for Win32 developers.