MmMapLockedPagesSpecifyCache: Execption under Server2003-32

You are putting data in your output buffer but you did you did not check if
it’s valid, you do not check the status of functions such as
WdfRequestRetrieveOutputBuffer.

Also, did you compile with /w4 or/wall, fix all your warnings and enabled
verifier on the driver as was suggested before ? I suppose not, here’s how
to get started: click Start, then Run and type verifier. You are really
going to need it.

//Daniel

status = WdfRequestRetrieveOutputBuffer
(Request,sizeof(FIOA_READ_LONG_REPLY),
&pOutBuffer, &Length);
pReadReply = (FIOA_READ_LONG_REPLY *)pOutBuffer;
//KdPrint((“ReadLong: Address=%x\n”,pReadRequest->Address));
pReadReply->Data = READ_REGISTER_ULONG
((PULONG)(devExt->Bar1Address+pReadRequest->Address));

wrote in message news:xxxxx@ntdev…
> Dear Pavel,
>
> What are “private functions” ? How can I set the code so that all
> functions will be “public” ?
>
> Following Mr. Zhang request here is the code of IoControl.c:
>
> /++
>
> Copyright (c) Microsoft Corporation. All rights reserved.
>
> THIS CODE AND INFORMATION IS PROVIDED “AS IS” WITHOUT WARRANTY OF ANY
> KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
> IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
> PURPOSE.
>
> Module Name:
>
> IoControl.c
>
> Abstract:
>
>
> Environment:
>
> Kernel mode
>
> –
/
>
> #include “precomp.h”
> #include “…\Common\FioAdapterIoControl.h”
>
> /
> Function: PlxIoDeviceControl
>
> Description:
>
* /
> VOID PLxEvtIoControl ( IN WDFQUEUE Queue,
> IN WDFREQUEST Request,
> IN size_t OutputBufferLength,
> IN size_t InputBufferLength,
> IN ULONG IoControlCode)
> /++
>
> Routine Description:
>
> This event is called when the framework receives IRP_MJ_DEVICE_CONTROL
> requests from the system.
>
> Arguments:
>
> Queue - Handle to the framework queue object that is associated
> with the I/O request.
> Request - Handle to a framework request object.
>
> OutputBufferLength - length of the request’s output buffer,
> if an output buffer is available.
> InputBufferLength - length of the request’s input buffer,
> if an input buffer is available.
>
> IoControlCode - the driver-defined or system-defined I/O control code
> (IOCTL) that is associated with the request.
> Return Value:
>
> VOID
>
> –
/
> {
> WDFDEVICE device;
> PDEVICE_EXTENSION devExt = NULL;
> size_t bytesReturned = 0;
> BOOLEAN requestPending = FALSE;
> NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
> //unsigned long Address;
> unsigned long Length;
> void *pInBuffer;
> void *pOutBuffer;
>
> FIOA_WRITE_LONG *pWriteRequest;
> FIOA_READ_LONG *pReadRequest;
>
> FIOA_READ_LONG_REPLY *pReadReply;
>
> WDFREQUEST InternalRequest;
> WDFREQUEST DpcRequest;
>
> PMDL CommonBufferMdl;
> PVOID CommonBufferVirtualAddress;
> ULONG CommonBufferLength;
> PUCHAR pDst;
>
> UNREFERENCED_PARAMETER(InputBufferLength);
> UNREFERENCED_PARAMETER(OutputBufferLength);
>
> KdPrint((“–> PlxEvtIoDeviceControl Code=%x\n”,IoControlCode));
> //
> // initialize variables
> //
> device = WdfIoQueueGetDevice(Queue);
>
> devExt = PLxGetDeviceContext(device);
>
> switch (IoControlCode)
> {
> case FIOA_WRITE_LONG_CODE:
> status = WdfRequestRetrieveInputBuffer (Request,sizeof(FIOA_WRITE_LONG),
> &pInBuffer, &Length);
> pWriteRequest = (FIOA_WRITE_LONG *)pInBuffer;
>
> /KdPrint((“Write (Address=%x,Data=%x)\n”,pWriteRequest->Address,
> pWriteRequest->Data));
/
> WRITE_REGISTER_ULONG((PULONG)(devExt->Bar1Address+pWriteRequest->Address),
> pWriteRequest->Data);
>
> bytesReturned = 0;
>
> WdfRequestCompleteWithInformation (Request,STATUS_SUCCESS,bytesReturned);
> break;
>
> case FIOA_READ_LONG_CODE:
> status = WdfRequestRetrieveInputBuffer (Request,sizeof(FIOA_READ_LONG),
> &pInBuffer, &Length);
> pReadRequest = (FIOA_READ_LONG *)pInBuffer;
>
> status = WdfRequestRetrieveOutputBuffer
> (Request,sizeof(FIOA_READ_LONG_REPLY),
> &pOutBuffer, &Length);
> pReadReply = (FIOA_READ_LONG_REPLY *)pOutBuffer;
>
> //KdPrint((“ReadLong: Address=%x\n”,pReadRequest->Address));
>
> pReadReply->Data = READ_REGISTER_ULONG
> ((PULONG)(devExt->Bar1Address+pReadRequest->Address));
>
> //KdPrint((“ReadLong: Data=%x\n”,pReadReply->Data));
>
> bytesReturned = sizeof(FIOA_READ_LONG_REPLY);
>
> WdfRequestCompleteWithInformation (Request,STATUS_SUCCESS,bytesReturned);
> break;
>
> case FIOA_INTERRUPT_CODE:
> //Forward IOCTL request to a queue. Request will be completed in DPC
> //status = WdfRequestForwardToIoQueue(Request,devExt->InternalQueue);
> break;
>
> case FIOA_ALLOCATE_COMMON_BUFFER:
> status = WdfRequestRetrieveOutputBuffer
> (Request,sizeof(FIOA_READ_LONG_REPLY),
> &pOutBuffer, &Length);
>
> pReadReply = (FIOA_READ_LONG_REPLY *)pOutBuffer;
>
> bytesReturned = sizeof(FIOA_READ_LONG_REPLY);
>
> //Map common buffer to user space. This can be done only upon IOCTL
> request
> __try
> {
> devExt->UserSpaceCommonBuffer =
> MmMapLockedPagesSpecifyCache(devExt->CommonBufferMdl,
> UserMode,
> MmCached ,
> NULL,
> FALSE,
> NormalPagePriority);
>
> if (!devExt->UserSpaceCommonBuffer)
> {
> KdPrint ((“MmMapLockedPagesSpecifyCache failed.\n”));
> }
> }
>__except (EXCEPTION_EXECUTE_HANDLER)
> {
> devExt->UserSpaceCommonBuffer = 0x0;
> KdPrint ((“MmMapLockedPagesSpecifyCache caused exception:
> %x\n”,GetExceptionCode()));
> }
>
> pReadReply->Data = (unsigned long)devExt->UserSpaceCommonBuffer;
>
> WdfRequestCompleteWithInformation (Request,STATUS_SUCCESS,sizeof(long));
> break;
> }
>
> KdPrint((“<– PlxEvtIoDeviceControl\n”));
>
> return;
> }
>
> Thanks,
> Zvika.
>

On 14-Dec-2011 16:00, xxxxx@gmail.com wrote:

Dear Pavel,

What are “private functions” ?

Functions not exported by the Windows kernel. Debugger cannot show them
by names, only as offset from some other (exported) symbol.
So when the call stack contains something like nt!MiDecommitPages+0x2ca
we can’t be 100% sure it really belongs to nt!MiDecommitPages. It can be
something else.

Your own functions are all visible, unless you do something unnatural
with the pdb.

– pa

“Pavel A” wrote in message news:xxxxx@ntdev…

Functions not exported by the Windows kernel. Debugger cannot show them by
names, only as offset from some other (exported) symbol.

Sure it can. The public PDBs retain function name information for exported
and non-exported functions, so even though you won’t get the parameters for
the functions you can see the name. If you do not have PDBs for an image
then, yes, WinDBG will default to, “Export Symbols” which means it shows
names relative to existing exports.

So when the call stack contains something like nt!MiDecommitPages+0x2ca we
can’t be 100% sure it really belongs to nt!MiDecommitPages. It can be
something else.

That can indeed be true, though if you have PDBs it’s likely due to the
optimizer’s code movement (described nicely here on MSDN:
http://bit.ly/uRtIUI).

It’s pretty easy to see in this case that the call stack is hosed and the
symbols are not correct. The root cause appears to be the fact that this is
a mini-dump and the image path is not set correctly.

To the OP: You’ll save yourself LOTS of time and annoyance by switching to
kernel summary or full memory dumps and analyzing those. Note that the
commands that Pavel suggested you run will NOT work with the mini-dump that
you currently have. See this KB article for information on how to configure
the system for kernel or full memory dumps: http://bit.ly/rh0jhE.

-scott


Scott Noone
Consulting Associate and Chief System Problem Analyst
OSR Open Systems Resources, Inc.
http://www.osronline.com

Hi Pavel,
Does the try block generate the MiDecommitPages ?
Marvin

On Wed, Dec 14, 2011 at 8:44 PM, Pavel A. wrote:

> “Marvin(Fan) Zhang” wrote in message
> news:xxxxx@ntdev…
>
> Very strange. Your driver should have had BSOD in
>> MmMapLockedPagesSpecifyCache . However, according to call stack,
>> MiDecommitPages make you BSOD.
>>
>
> Maybe it is not in MiDecommitPages but in some private functions. Note the
> offset.
>
> – pa
>
>
>
>
> —
> 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=ListServerhttp:
></http:>

On 14-Dec-2011 17:25, Scott Noone wrote:

“Pavel A” wrote in message news:xxxxx@ntdev…
> Functions not exported by the Windows kernel. Debugger cannot show
> them by names, only as offset from some other (exported) symbol.

Sure it can. The public PDBs retain function name information for
exported and non-exported functions,

Unless some of them are stripped.
But I tend to agree with Daniel: the bug is somewhere else in handling
of the ioctl.

Zvi, please, find a local consultant. There are dozens of knowledgeable
driver devs in radius of 30 km from you. Many of them also have the
clearance.

/* Electronic engineers trying to write a driver often look, er… like
software devs trying to fix their car or fridge. Let pros do their stuff. */

– pa

Dear Grigora,

In WinDbg I clicked: ‘File’,‘Symbol File Path…’ and entered the location
where I extracted the symbols of “Windows Server 2003-32-SP2”

Then I clicked: ‘File’,‘Source File Path…’ and entered the directory of
the sources.

Then I clicked: ‘File’,‘Open Crash Dump…’ and opened the crash dump file.

Is it the right way to load the symbols ?

I’m sure
Thanks,
Zvika.

-----Original Message-----
From: xxxxx@broadcom.com
Sent: Wednesday, December 14, 2011 4:12 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] MmMapLockedPagesSpecifyCache: Execption under
Server2003-32

Until the correct symbols are loaded by the debugger, the crash stack is
bogus.


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

Hi Pavel,

You are right. I’m not a WDF specialist.
But I already wrote 2 device drivers that work great.
All drivers are based on Plx9x5x supplied with DDK.
WDF is designed so that also “regular” people will be able to write kernel
drivers.

Thanks,
Zvika

-----Original Message-----
From: Pavel A
Sent: Wednesday, December 14, 2011 5:48 PM Newsgroups: ntdev
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] MmMapLockedPagesSpecifyCache: Execption under
Server2003-32

On 14-Dec-2011 17:25, Scott Noone wrote:

“Pavel A” wrote in message news:xxxxx@ntdev…
> Functions not exported by the Windows kernel. Debugger cannot show
> them by names, only as offset from some other (exported) symbol.

Sure it can. The public PDBs retain function name information for
exported and non-exported functions,

Unless some of them are stripped.
But I tend to agree with Daniel: the bug is somewhere else in handling
of the ioctl.

Zvi, please, find a local consultant. There are dozens of knowledgeable
driver devs in radius of 30 km from you. Many of them also have the
clearance.

/* Electronic engineers trying to write a driver often look, er… like
software devs trying to fix their car or fridge. Let pros do their stuff. */

– pa


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

The best way to get symbols is to use MS symbol server.

Also, you can’t map to user mode while in DriverEntry context. You’re not in any user process context now. This might well cause the bugcheck.

>There are dozens of knowledgeable driver devs in radius of 30 km from you.

If Zvi lives in Tel-aviv, the whole Gush-dan is around him. It is full of programmers, including driver devs.

Hi Grigora,

MmMapLockedPagesSpecifyCache is called upon IOCTL request from user space.
When I skipped MmMapLockedPagesSpecifyCache in the request, all worked
fine.

Upon DriverEntry I call to:
MmAllocateContiguousMemorySpecifyCache
IoAllocateMdl
MmBuildMdlForNonPagedPool

The relevant code is in my first mail.

Thanks,
Zvika.

-----Original Message-----
From: xxxxx@broadcom.com
Sent: Wednesday, December 14, 2011 7:43 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] MmMapLockedPagesSpecifyCache: Execption under
Server2003-32

The best way to get symbols is to use MS symbol server.

Also, you can’t map to user mode while in DriverEntry context. You’re not in
any user process context now. This might well cause the bugcheck.


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

OK. Reproduce the bugcheck with the correct symbols loaded, then we’ll talk. DON’T specify image path for the debugger.

+1

Mm
On Dec 14, 2011 5:12 PM, wrote:

> OK. Reproduce the bugcheck with the correct symbols loaded, then we’ll
> talk. DON’T specify image path for the debugger.
>
> —
> 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
>

> Dear Pavel,

What are “private functions” ? How can I set the code so that all
functions will be “public” ?

****
Public and private relative to what namespace?
****

Following Mr. Zhang request here is the code of IoControl.c:

/*++

Copyright (c) Microsoft Corporation. All rights reserved.

THIS CODE AND INFORMATION IS PROVIDED “AS IS” WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
PURPOSE.

Module Name:

IoControl.c

Abstract:

Environment:

Kernel mode

–*/

#include “precomp.h”
#include “…\Common\FioAdapterIoControl.h”

/***************************************************************************
Function: PlxIoDeviceControl

Description:
****************************************************************************/
VOID PLxEvtIoControl ( IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t OutputBufferLength,
IN size_t InputBufferLength,
IN ULONG IoControlCode)
/*++

Routine Description:

This event is called when the framework receives IRP_MJ_DEVICE_CONTROL
requests from the system.

Arguments:

Queue - Handle to the framework queue object that is associated
with the I/O request.
Request - Handle to a framework request object.

OutputBufferLength - length of the request’s output buffer,
if an output buffer is available.
InputBufferLength - length of the request’s input buffer,
if an input buffer is available.

IoControlCode - the driver-defined or system-defined I/O control code
(IOCTL) that is associated with the request.
Return Value:

VOID

–*/
{
WDFDEVICE device;
PDEVICE_EXTENSION devExt = NULL;
size_t bytesReturned = 0;
BOOLEAN requestPending = FALSE;
NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
//unsigned long Address;
unsigned long Length;
void *pInBuffer;
void *pOutBuffer;

FIOA_WRITE_LONG *pWriteRequest;
FIOA_READ_LONG *pReadRequest;

FIOA_READ_LONG_REPLY *pReadReply;

WDFREQUEST InternalRequest;
WDFREQUEST DpcRequest;

PMDL CommonBufferMdl;
PVOID CommonBufferVirtualAddress;
ULONG CommonBufferLength;
PUCHAR pDst;

UNREFERENCED_PARAMETER(InputBufferLength);
UNREFERENCED_PARAMETER(OutputBufferLength);

KdPrint((“–> PlxEvtIoDeviceControl Code=%x\n”,IoControlCode));
//
// initialize variables
//
device = WdfIoQueueGetDevice(Queue);

devExt = PLxGetDeviceContext(device);

switch (IoControlCode)
{
case FIOA_WRITE_LONG_CODE:
status = WdfRequestRetrieveInputBuffer (Request,sizeof(FIOA_WRITE_LONG),
&pInBuffer, &Length);
pWriteRequest = (FIOA_WRITE_LONG *)pInBuffer;

/*KdPrint((“Write (Address=%x,Data=%x)\n”,pWriteRequest->Address,
pWriteRequest->Data));*/
WRITE_REGISTER_ULONG((PULONG)(devExt->Bar1Address+pWriteRequest->Address),
pWriteRequest->Data);

bytesReturned = 0;

WdfRequestCompleteWithInformation
(Request,STATUS_SUCCESS,bytesReturned);
break;

case FIOA_READ_LONG_CODE:
status = WdfRequestRetrieveInputBuffer (Request,sizeof(FIOA_READ_LONG),
&pInBuffer, &Length);
pReadRequest = (FIOA_READ_LONG *)pInBuffer;

status = WdfRequestRetrieveOutputBuffer
(Request,sizeof(FIOA_READ_LONG_REPLY),
&pOutBuffer, &Length);
pReadReply = (FIOA_READ_LONG_REPLY *)pOutBuffer;

//KdPrint((“ReadLong: Address=%x\n”,pReadRequest->Address));

pReadReply->Data = READ_REGISTER_ULONG
((PULONG)(devExt->Bar1Address+pReadRequest->Address));

//KdPrint((“ReadLong: Data=%x\n”,pReadReply->Data));

bytesReturned = sizeof(FIOA_READ_LONG_REPLY);

WdfRequestCompleteWithInformation
(Request,STATUS_SUCCESS,bytesReturned);
break;

case FIOA_INTERRUPT_CODE:
//Forward IOCTL request to a queue. Request will be completed in DPC
//status = WdfRequestForwardToIoQueue(Request,devExt->InternalQueue);
break;

case FIOA_ALLOCATE_COMMON_BUFFER:
status = WdfRequestRetrieveOutputBuffer
(Request,sizeof(FIOA_READ_LONG_REPLY),
&pOutBuffer, &Length);

pReadReply = (FIOA_READ_LONG_REPLY *)pOutBuffer;

bytesReturned = sizeof(FIOA_READ_LONG_REPLY);

//Map common buffer to user space. This can be done only upon IOCTL
request
__try
{
devExt->UserSpaceCommonBuffer =
MmMapLockedPagesSpecifyCache(devExt->CommonBufferMdl,
UserMode,
MmCached ,
NULL,
FALSE,
NormalPagePriority);

if (!devExt->UserSpaceCommonBuffer)
{
KdPrint ((“MmMapLockedPagesSpecifyCache failed.\n”));
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
devExt->UserSpaceCommonBuffer = 0x0;
KdPrint ((“MmMapLockedPagesSpecifyCache caused exception:
%x\n”,GetExceptionCode()));
}

pReadReply->Data = (unsigned long)devExt->UserSpaceCommonBuffer;

WdfRequestCompleteWithInformation (Request,STATUS_SUCCESS,sizeof(long));
break;
}

KdPrint((“<– PlxEvtIoDeviceControl\n”));

return;
}

Thanks,
Zvika.


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