MmProbeAndLockPages() & UserMode address

Hi,

I need to access in KernelMode driver (in work item queued from worker
thread) some memory ptr UserMode app pass me via device control. I use
MmProbeAndLockPages( ptr, UserMode, IoModifyAccess ). Do I need to call
MmXxx from device control dispatcher before I’ve queued IRP and I’m still
in callers thread context or I can call MmXxx directly in work item when
I’m in system thread context? Right now I call it from dispatcher and get
sometimes exception code 0xC0000005 (access violation) on valid buffer ptrs
passed by UserMode app. What can it be?

Thanks for help,
Anton

CoolDev.Com - Toolkits for Network & Storage Software Developers
“KoolSockets” & “KoolStorage” - TDI Client, SCSI miniport, iSCSI
www.CoolDev.Com xxxxx@CoolDev.Com xxxxx@CoolDev.com


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

I use the following class for that. Constructor must be called in the user
process context.

/////////////////////////////////////////////////////////////////
// File: lockedmem.cpp
// Description:
// Locked buffer class
// Author: Lyadvinsky M.V.
// Date: 23.11.2000
/////////////////////////////////////////////////////////////////
#include “lockedmem.h”

CLockedMem::CLockedMem(PVOID pBuffer,
ULONG uSize, NTSTATUS* pStatus) :
m_pBuffer(pBuffer),
m_pSysBuffer(NULL),
m_uSize(uSize),
m_pMdl(NULL)
{
NTSTATUS ntStatus;

// Check parameters
if (uSize && pBuffer)
ntStatus = STATUS_SUCCESS;
else
ntStatus = STATUS_INVALID_PARAMETER;

// Allocate MDL
if (NT_SUCCESS(ntStatus))
{
m_pMdl =
DL)nonpagednew(
MmSizeOfMdl(m_pBuffer, m_uSize));
if (!m_pMdl)
ntStatus = STATUS_NO_MEMORY;
}

// Initialize and lock MDL
if (NT_SUCCESS(ntStatus))
{
MmInitializeMdl(m_pMdl,
m_pBuffer, m_uSize);

__try
{
MmProbeAndLockPages(m_pMdl,
UserMode, IoWriteAccess);
m_pSysBuffer = MmGetSystemAddressForMdl(m_pMdl);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
m_pSysBuffer = NULL;
ntStatus = STATUS_ACCESS_VIOLATION;
}
}

// Return status
if (pStatus)
*pStatus = ntStatus;
}

CLockedMem::~CLockedMem()
{
if (m_pSysBuffer)
MmUnlockPages(m_pMdl);
if (m_pMdl)
delete m_pMdl;
}

Regards,
Max

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of
xxxxx@hotmail.com
Sent: Monday, June 18, 2001 6:52 AM
To: NT Developers Interest List
Subject: [ntdev] MmProbeAndLockPages() & UserMode address

Hi,

I need to access in KernelMode driver (in work item queued from worker
thread) some memory ptr UserMode app pass me via device control. I use
MmProbeAndLockPages( ptr, UserMode, IoModifyAccess ). Do I need to call
MmXxx from device control dispatcher before I’ve queued IRP and I’m still
in callers thread context or I can call MmXxx directly in work item when
I’m in system thread context? Right now I call it from dispatcher and get
sometimes exception code 0xC0000005 (access violation) on valid buffer ptrs
passed by UserMode app. What can it be?

Thanks for help,
Anton

CoolDev.Com - Toolkits for Network & Storage Software Developers
“KoolSockets” & “KoolStorage” - TDI Client, SCSI miniport, iSCSI
www.CoolDev.Com xxxxx@CoolDev.Com xxxxx@CoolDev.com


You are currently subscribed to ntdev as: xxxxx@acronis.com
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

BTW, it isn’t necessary to lock the user memory if you use it below dispatch
level. Just create mdl for that then call MmGetSystemAddressForMdl.

Regards,
Max Lyadvinsky

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of
xxxxx@hotmail.com
Sent: Monday, June 18, 2001 6:52 AM
To: NT Developers Interest List
Subject: [ntdev] MmProbeAndLockPages() & UserMode address

Hi,

I need to access in KernelMode driver (in work item queued from worker
thread) some memory ptr UserMode app pass me via device control. I use
MmProbeAndLockPages( ptr, UserMode, IoModifyAccess ). Do I need to call
MmXxx from device control dispatcher before I’ve queued IRP and I’m still
in callers thread context or I can call MmXxx directly in work item when
I’m in system thread context? Right now I call it from dispatcher and get
sometimes exception code 0xC0000005 (access violation) on valid buffer ptrs
passed by UserMode app. What can it be?

Thanks for help,
Anton

CoolDev.Com - Toolkits for Network & Storage Software Developers
“KoolSockets” & “KoolStorage” - TDI Client, SCSI miniport, iSCSI
www.CoolDev.Com xxxxx@CoolDev.Com xxxxx@CoolDev.com


You are currently subscribed to ntdev as: xxxxx@acronis.com
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

Thanks, Max!

So I need thread context…

As I understand I do not need neither MmUnlockPages() (in such a case
system crashes with exception PROCESS_HAD_LOCKED_PAGES. I beleive I/O
Manager trys to unlock the MDL’s already unlocked memory from IRP’s
associated MDL and lock counter for that memory region becomes (-1)). But
do I need to free MDL I allocate via call to IoAllocateMdl()? Does I/O
Manager frees MDL when I call IofCompleteRequest()?

Regards,
Anton

BTW, it isn’t necessary to lock the user memory if you use it below dispatch
level. Just create mdl for that then call MmGetSystemAddressForMdl.


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

> I need to access in KernelMode driver (in work item queued from worker

thread) some memory ptr UserMode app pass me via device control. I use
MmProbeAndLockPages( ptr, UserMode, IoModifyAccess ). Do I need to call
MmXxx from device control dispatcher before I’ve queued IRP and I’m still

Yes, from the correct process context. After you have locked a MDL - you can
use it from any thread context.

Max


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

> BTW, it isn’t necessary to lock the user memory if you use it below
dispatch

level. Just create mdl for that then call MmGetSystemAddressForMdl.

Not so.
The pager will be able to swap out the pages in this MDL and reuse the
physical frames pointed to by your system PTEs.
Such an approach will lead to a bug inevitable - sooner or later. Yes, this
bug can occur only once per 1000 times - but it is a bug nevertheless.

Max


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

> As I understand I do not need neither MmUnlockPages() (in such a case

system crashes with exception PROCESS_HAD_LOCKED_PAGES. I beleive I/O
Manager trys to unlock the MDL’s already unlocked memory from IRP’s
associated MDL and lock counter for that memory region becomes (-1)). But
do I need to free MDL I allocate via call to IoAllocateMdl()? Does I/O
Manager frees MDL when I call IofCompleteRequest()?

Locked MDL requires MmUnlockPages. IoFreeMdl does not do this.
MmUnlockPages will reverse MmGetSystemAddressForMdl for you -
MmUnmapLockedPages is not necessary.

The IO system will automatically call MmUnlockPages for IRP-associated MDL.
You must call it yourself for other MDLs.

Max


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

Yep, you are right, you should always lock the pages before calling
MmGetSystemAddressForMdl

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Maxim S. Shatskih
Sent: Monday, June 18, 2001 8:37 PM
To: NT Developers Interest List
Subject: [ntdev] RE: MmProbeAndLockPages() & UserMode address

BTW, it isn’t necessary to lock the user memory if you use it below
dispatch
level. Just create mdl for that then call MmGetSystemAddressForMdl.

Not so.
The pager will be able to swap out the pages in this MDL and reuse the
physical frames pointed to by your system PTEs.
Such an approach will lead to a bug inevitable - sooner or later. Yes, this
bug can occur only once per 1000 times - but it is a bug nevertheless.

Max


You are currently subscribed to ntdev as: xxxxx@acronis.com
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

> Locked MDL requires MmUnlockPages. IoFreeMdl does not do this.

MmUnlockPages will reverse MmGetSystemAddressForMdl for you -
MmUnmapLockedPages is not necessary.

The IO system will automatically call MmUnlockPages for IRP-associated MDL.
You must call it yourself for other MDLs.

I use IRP’s associated MDL. So at dispatcher I call IoAllocateMdl(…, pIrp
) & MmProbeAndLockPages(…, UserMode,…) and I/O Managers calls
MmUnlockPages() as many times as it requires [ twice as I explicitly lock
MDL first and call MmGetSystemAddressForMdlSafe() in work item ] when I
call IoCompleteRequest(). I do not call MmUnlockPages() & IoFreeMdl()
myself. Correct?

Anton

CoolDev.Com - Toolkits for Network & Storage Software Developers
“KoolSockets” & “KoolStorage” - TDI Client, Kernel Sockets, SCSI miniport,
iSCSI
http://www.CoolDev.Com, xxxxx@CoolDev.Com,
xxxxx@CoolDev.com


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

> I use IRP’s associated MDL. So at dispatcher I call IoAllocateMdl(…,
pIrp

) & MmProbeAndLockPages(…, UserMode,…) and I/O Managers calls
MmUnlockPages() as many times as it requires [ twice as I explicitly lock
MDL first and call MmGetSystemAddressForMdlSafe() in work item ] when I

MmGetSystemAddressForMdlSafe does not touch the lock reference count on
pages.

call IoCompleteRequest(). I do not call MmUnlockPages() & IoFreeMdl()
myself. Correct?

Looks like so.

Max


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com