MmGetSystemAddressForMdl* creates a range of system PTE entries if they
don’t already exist. Go look at the macro - see that call to
MmMapLockedPages?
To tear it down, you have to have a corresponding MmUnmapPages call if you
actually mapped the pages. Unlocking them is not sufficient.
This is the one area in which you are FAR better allowing the I/O subsystem
to do the work for you - attach these to an IRP and they’ll be torn down
properly. FYI - to tear them down “properly” requires violating the opacity
of MDLs, which is why it is better to let the I/O Manager do it. (This
becomes an issue because you don’t unlock non-paged addresses, you don’t
unmap if you didn’t map, etc. So you need to know what happened inside
these macros and functions).
Regards,
Tony
Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc.
http://www.osr.com
-----Original Message-----
From: Vladimir Chtchetkine [mailto:xxxxx@starbase.com]
Sent: Friday, June 07, 2002 1:14 PM
To: NT Developers Interest List
Subject: [ntdev] RE: MmProbeAndLockPages
Well, I have same problem. Here is the function where I lock/unlock pages
and I would highly appreciate if anybody can find my mistake (I just lost
last hope). The only thing is that I’m allocating MDLs and lock them for all
types of buffers that come to my routine (including not only those that
address UM buffer, but also KM buffers, including MDLs):
BOOL CCTLDevice::OnHandleAppMessage( PVOID pInput, ULONG InpLen, PVOID
pOutput, ULONG OutLen,
PIO_STATUS_BLOCK pIoStatus, BOOL /*bFastIo*/)
{
PMDL pAmInMdlBuffer = NULL;
PMDL pAmOutMdlBuffer = NULL;
PVOID pLockedInAmBuffer = NULL;
PVOID pLockedOutAmBuffer = NULL;
bool isInBufferLocked = false;
bool isOutBufferLocked = false;
NTSTATUS devCtrlStatus = STATUS_SUCCESS;
__try
{
//
// Handle memory issues. The assumption is that the IOCTL
used
// METHOD DIRECT_OUT
//
//
// 1) Allocate an MDL for the input AM buffers:
//
if( pInput && InpLen )
{
pAmInMdlBuffer = IoAllocateMdl( pInput, InpLen,
FALSE, FALSE, NULL);
if( NULL == pAmInMdlBuffer )
{
DBGREPORT(“\nAMInterface Device could not
allocate mdl for AM IN buffer”);
pIoStatus -> Information = 0;
pIoStatus -> Status = STATUS_NO_MEMORY;
return FALSE;
}
}
if( pOutput && OutLen )
{
pAmOutMdlBuffer = IoAllocateMdl( pOutput, OutLen,
FALSE, FALSE, NULL);
if( NULL == pAmOutMdlBuffer )
{
DBGREPORT(“\nAMInterface Device could not
allocate mdl for AM OUT buffer”);
if( pAmInMdlBuffer != NULL )
{
IoFreeMdl(pAmInMdlBuffer);
}
pIoStatus -> Information = 0;
pIoStatus -> Status = STATUS_NO_MEMORY;
return FALSE;
}
}
//
// 2) Probe and lock the pages:
//
if( pAmInMdlBuffer )
{
MmProbeAndLockPages( pAmInMdlBuffer, KernelMode,
IoReadAccess);
isInBufferLocked = true;
}
if( pAmOutMdlBuffer )
{
MmProbeAndLockPages( pAmOutMdlBuffer, KernelMode,
IoWriteAccess);
isOutBufferLocked = true;
}
// 3) Get an VA that we can use:
#if (WINVER>=0x500)
pLockedInAmBuffer = MmGetSystemAddressForMdlSafe(
pAmInMdlBuffer, NormalPagePriority);
pLockedOutAmBuffer = MmGetSystemAddressForMdlSafe(
pAmOutMdlBuffer, NormalPagePriority);
#else // (WINVER>=0x500)
pLockedInAmBuffer = MmGetSystemAddressForMdl( pAmInMdlBuffer
);
pLockedOutAmBuffer = MmGetSystemAddressForMdl(
pAmOutMdlBuffer );
#endif // (WINVER>=0x500)
//
// Now, we can call the "real handler:
//
devCtrlStatus = m_pMsgDispatcher -> DispatchMessage( 0,
pLockedInAmBuffer, InpLen,
pLockedOutAmBuffer, OutLen,
pIoStatus -> Information );
pIoStatus -> Status = devCtrlStatus;
//
// Not matter what the return status, let’s unlock the
// buffer, and free the mdl:
//
if( NULL != pAmOutMdlBuffer && isOutBufferLocked)
{
MmUnlockPages(pAmOutMdlBuffer);
isOutBufferLocked = false;
}
if( NULL != pAmOutMdlBuffer )
{
IoFreeMdl(pAmOutMdlBuffer);
pAmOutMdlBuffer = NULL;
}
if( NULL != pAmInMdlBuffer && isInBufferLocked)
{
MmUnlockPages(pAmInMdlBuffer);
isInBufferLocked = false;
}
if( NULL != pAmInMdlBuffer )
{
IoFreeMdl(pAmInMdlBuffer);
pAmInMdlBuffer = NULL;
}
return TRUE;
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
DBGREPORTEXCEPTION();
if( NULL != pAmOutMdlBuffer && isOutBufferLocked)
{
MmUnlockPages(pAmOutMdlBuffer);
}
if(NULL != pAmOutMdlBuffer)
{
IoFreeMdl(pAmOutMdlBuffer);
}
if( NULL != pAmInMdlBuffer && isInBufferLocked)
{
MmUnlockPages(pAmInMdlBuffer);
}
if(NULL != pAmInMdlBuffer)
{
IoFreeMdl(pAmInMdlBuffer);
}
pIoStatus -> Status = GetExceptionCode();
pIoStatus -> Information = 0;
return FALSE;
}
}
-----Original Message-----
From: Peter Wieland [mailto:xxxxx@windows.microsoft.com
mailto:xxxxx ]
Sent: Friday, June 07, 2002 9:56 AM
To: NT Developers Interest List
Subject: [ntdev] RE: MmProbeAndLockPages
C:\Documents and Settings\peterwie>winerror -s c00000a1
1453 ERROR_WORKING_SET_QUOTA <–> c00000a1 STATUS_WORKING_SET_QUOTA
sounds like perhaps you aren’t unlocking everything that you locked
down.
-p
-----Original Message-----
From: Benjamin Hejl [mailto:xxxxx@yahoo.com mailto:xxxxx]
Sent: Friday, June 07, 2002 8:16 AM
To: NT Developers Interest List
Subject: [ntdev] MmProbeAndLockPages
What causes MmProbeAndLockPages to raise the exception 0xC00000A1L. I
call this function in my read dispatch function to lock the pages in a
user mode buffer to return data. Before I complete the request I call
MmUnlockPages to unlock the pages. On the 2500th call to
MmProbeAndLockPages it raises this exception. Why does this happen?
Ben
__________________________________________________
Do You Yahoo!?
Yahoo! - Official partner of 2002 FIFA World Cup
http://fifaworldcup.yahoo.com http:
—
You are currently subscribed to ntdev as: xxxxx@microsoft.com To
unsubscribe send a blank email to %%email.unsub%%
—
You are currently subscribed to ntdev as: xxxxx@Starbase.com
To unsubscribe send a blank email to %%email.unsub%%
—
You are currently subscribed to ntdev as: xxxxx@osr.com
To unsubscribe send a blank email to %%email.unsub%%</http:></mailto:xxxxx></mailto:xxxxx>