IRQ_NOT_LESS_OR_EQUAL Bulu Screen Error

Hello, everyone:
I try to send a OID request to the underlying driver from a Filter driver, and I got a blue screen error with notice: IRQ_NOT_LESS_OR_EQUAL. I think it may be a memory fault, the following codes try to allocate a buffer with the size of sizeof(DOT11_MAC_INFO), and fill this buffer with zero. This buffer is used to store some infomation about MAC return by the function NdisFOidRequest().
The following is my codes:
NDIS_STATUS
filterCreateNewMACRequest(
IN NDIS_HANDLE FilterModuleContext,
IN NDIS_OID Oid
)
/* Routine Description:
Send OID to underlying driver to create a new MAC
Arguments:
FilterModuleContext - pointer to filter module context
Oid – OID_DOT11_CREATE_MAC
*/
{

PMS_FILTER pFilter =(PMS_FILTER)FilterModuleContext;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
PVOID InformationBuffer = NULL;
ULONG InformationBufferLength;
ULONG OutputBufferLength;
ULONG MethodId;
PULONG pBytesProcessed;

DEBUGP(DL_TEST,(“==>FilterCreateNEwMACRequest!\n”));

NdisZeroMemory(InformationBuffer, sizeof(DOT11_MAC_INFO)); InformationBufferLength = OutputBufferLength = sizeof(DOT11_MAC_INFO);
MethodId = 0;
pBytesProcessed = NULL;
Status = filterDoInternalRequest(pFilter,
NdisRequestMethod, Oid, InformationBuffer, InformationBufferLength, OutputBufferLength, MethodId,
pBytesProcessed);
if(Status == NDIS_STATUS_SUCCESS)

I think there may be something woring the allocation and initialization of the variable InformationBuffer. because there variable used be used in the function of filterDoInternalRequest().

filterDoInternalRequest
(IN PVOID InformationBuffer,
…){

NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer =
InformationBuffer

}

so, does the memory allocation and initialization cause the blue screen? or any other reason?
Thanks

I am just wondering How to allocate and initialize a VOID Point in NDIS6,
PVOID InformationBuffer = NULL;
NdisZeroMemory(InformationBuffer, sizeof(DOT11_MAC_INFO));
is this OK?

Hi,

The following line is what is causing you problems…

NdisZeroMemory(InformationBuffer, sizeof(DOT11_MAC_INFO));

InformationBuffer here is a null pointer and hence the reason for your
crash. First allocate some memmory. Use for example
“NdisAllocateMemoryWithTagPriority” to allocate the memory and then do the
above call if “NdisAllocateMemoryWithTagPriority” returns
NDIS_STATUS_SUCCESS.

Cheers
/Faik

On Mon, Dec 7, 2009 at 9:11 AM, wrote:

> I am just wondering How to allocate and initialize a VOID Point in NDIS6,
> PVOID InformationBuffer = NULL;
> NdisZeroMemory(InformationBuffer, sizeof(DOT11_MAC_INFO));
> is this OK?
>
> —
> 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
>


NdisZeroMemory(InformationBuffer, sizeof(DOT11_MAC_INFO));

InformationBuffer here is a null pointer and hence the reason for your
crash. First allocate some memmory. Use for example
“NdisAllocateMemoryWithTagPriority” to allocate the memory and then do the
above call if “NdisAllocateMemoryWithTagPriority” returns
NDIS_STATUS_SUCCESS.

Yes, you are right. Thanks very much. One more question:

PVOID NdisAllocateMemoryWithTagPriority(
IN NDIS_HANDLE NdisHandle,
IN UINT Length,
IN ULONG Tag,
IN EX_POOL_PRIORITY Priority );
there are four parameters, one of them is a NIDS_HANDLE, is it ok if I set this Handle to NULL.

PUCHAR InformationBuffer = NULL;
InformationBuffer = (PUCHAR)NdisAllocateMemoryWithTagPriority(NULL,sizeof(DOT11_MAC_INFO),FILTER_ALLOC_TAG, LowPoolPriority);
NdisZeroMemory(InformationBuffer, sizeof(DOT11_MAC_INFO));//it should be greater than sizeof(DOT11_MAC_INFO)
InformationBufferLength = OutputBufferLength = sizeof(DOT11_MAC_INFO);

I can compile the codes without errors, But I am not sure about that? if this hanle is NULL, what doesn it mean?
Thanks

Well, I guess that handle is somehow used to pinpoint which NDIS driver the
allocated memory belongs to.

Why would you wan’t to set it to NULL anyway?

The documentation doesn’t say that this parameter is optional and that it is
ok to set it to NULL so I guess you shouldn’t do that either.

Cheers
Faik

On Mon, Dec 7, 2009 at 10:03 AM, wrote:

>
> NdisZeroMemory(InformationBuffer, sizeof(DOT11_MAC_INFO));
>
> InformationBuffer here is a null pointer and hence the reason for your
> crash. First allocate some memmory. Use for example
> “NdisAllocateMemoryWithTagPriority” to allocate the memory and then do the
> above call if “NdisAllocateMemoryWithTagPriority” returns
> NDIS_STATUS_SUCCESS.
>
> Yes, you are right. Thanks very much. One more question:
>
> PVOID NdisAllocateMemoryWithTagPriority(
> IN NDIS_HANDLE NdisHandle,
> IN UINT Length,
> IN ULONG Tag,
> IN EX_POOL_PRIORITY Priority );
> there are four parameters, one of them is a NIDS_HANDLE, is it ok if I set
> this Handle to NULL.
>
> PUCHAR InformationBuffer = NULL;
> InformationBuffer =
> (PUCHAR)NdisAllocateMemoryWithTagPriority(NULL,sizeof(DOT11_MAC_INFO),FILTER_ALLOC_TAG,
> LowPoolPriority);
> NdisZeroMemory(InformationBuffer, sizeof(DOT11_MAC_INFO));//it should
> be greater than sizeof(DOT11_MAC_INFO)
> InformationBufferLength = OutputBufferLength =
> sizeof(DOT11_MAC_INFO);
>
> I can compile the codes without errors, But I am not sure about that? if
> this hanle is NULL, what doesn it mean?
> Thanks
>
> —
> 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
>

Thanks,Faik
I will be going to test whether it works or not. Thanks again~
Leyond

I think there is nothing wrong with the memory allocation and initializaiton, but i still get blue screen.
I list all the codes:
NDIS_STATUS
filterCreateNewMACRequest(
IN NDIS_HANDLE FilterModuleContext,
IN NDIS_OID Oid
)
/* Routine Description:
Send OID to underlying driver to create a new MAC
Arguments:
FilterModuleContext - pointer to filter module context
Oid – OID_DOT11_CREATE_MAC
*/
{

PMS_FILTER pFilter =(PMS_FILTER)FilterModuleContext;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
PVOID InformationBuffer = NULL;
ULONG InformationBufferLength;
ULONG OutputBufferLength;
ULONG MethodId;
PULONG pBytesProcessed = NULL;
//PUCHAR DataExample = “Hello World!”;
DEBUGP(DL_TEST,(“==>FilterCreateNEwMACRequest!\n”));

InformationBuffer = NdisAllocateMemoryWithTagPriority(pFilter->FilterHandle,sizeof(DOT11_MAC_INFO),FILTER_ALLOC_TAG, LowPoolPriority);
NdisZeroMemory(InformationBuffer, sizeof(DOT11_MAC_INFO));
InformationBufferLength = OutputBufferLength = sizeof(DOT11_MAC_INFO);
// RtlCopyMemory(InformationBuffer,DataExample,sizeof(“HelloWorld!”));
MethodId = 0;
pBytesProcessed = (PULONG)NdisAllocateMemoryWithTagPriority(pFilter->FilterHandle,sizeof(ULONG),FILTER_ALLOC_TAG, LowPoolPriority);
*pBytesProcessed = 0;
//DEBUGP(DL_TEST,(“Infomation Buffer is %s and length is %u, and byteprocessed is %u”,InformationBuffer,InformationBufferLength,*pBytesProcessed));
Status = filterDoInternalRequest(pFilter,
NdisRequestMethod,
Oid,
InformationBuffer,
InformationBufferLength,
OutputBufferLength,
MethodId,
pBytesProcessed);
if(Status == NDIS_STATUS_SUCCESS)
{
DEBUGP(DL_TEST,(“Create new mac successfully, and the length is %u!\n”,InformationBufferLength));
goto Exit;
}else
{
DEBUGP(DL_TEST,(“Fail to create new MAC!\n”));
goto Exit;
}
Exit:
return Status;
}
The function of filterDoInternalRequest:
NDIS_STATUS
filterDoInternalRequest(
IN PMS_FILTER FilterModuleContext,
IN NDIS_REQUEST_TYPE RequestType,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
IN ULONG OutputBufferLength, OPTIONAL
IN ULONG MethodId, OPTIONAL
OUT PULONG pBytesProcessed
)
/*++

Routine Description:

Utility routine that forms and sends an NDIS_OID_REQUEST to the
miniport, waits for it to complete, and returns status
to the caller.

NOTE: this assumes that the calling routine ensures validity
of the filter handle until this returns.

Arguments:

FilterModuleContext - pointer to our filter module context
RequestType - NdisRequest[Set|Query|method]Information
Oid - the object being set/queried
InformationBuffer - data for the request
InformationBufferLength - length of the above
OutputBufferLength - valid only for method request
MethodId - valid only for method request
pBytesProcessed - place to return bytes read/written

Return Value:

Status of the set/query request

–*/
{
FILTER_REQUEST FilterRequest;
PNDIS_OID_REQUEST NdisRequest = &FilterRequest.Request;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;

DEBUGP(DL_TEST,(“==>filterDoInternalRequest\n”))
NdisZeroMemory(NdisRequest, sizeof(NDIS_OID_REQUEST));

NdisInitializeEvent(&FilterRequest.ReqEvent);

NdisRequest->Header.Type = NDIS_OBJECT_TYPE_OID_REQUEST;
NdisRequest->Header.Revision = NDIS_OID_REQUEST_REVISION_1;
NdisRequest->Header.Size = sizeof(NDIS_OID_REQUEST);
NdisRequest->RequestType = RequestType;

switch (RequestType)
{
case NdisRequestQueryInformation:
NdisRequest->DATA.QUERY_INFORMATION.Oid = Oid;
NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer =
InformationBuffer;
NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength =
InformationBufferLength;
break;

case NdisRequestSetInformation:
NdisRequest->DATA.SET_INFORMATION.Oid = Oid;
NdisRequest->DATA.SET_INFORMATION.InformationBuffer =
InformationBuffer;
NdisRequest->DATA.SET_INFORMATION.InformationBufferLength =
InformationBufferLength;
break;

case NdisRequestMethod:
NdisRequest->DATA.METHOD_INFORMATION.Oid = Oid;
NdisRequest->DATA.METHOD_INFORMATION.MethodId = MethodId;
NdisRequest->DATA.METHOD_INFORMATION.InformationBuffer =
InformationBuffer;
NdisRequest->DATA.METHOD_INFORMATION.InputBufferLength =
InformationBufferLength;
NdisRequest->DATA.METHOD_INFORMATION.OutputBufferLength = OutputBufferLength;
break;

default:
FILTER_ASSERT(FALSE);
break;
}

NdisRequest->RequestId = (PVOID)FILTER_REQUEST_ID;

Status = NdisFOidRequest(FilterModuleContext->FilterHandle,
NdisRequest);

if (Status == NDIS_STATUS_PENDING)
{

NdisWaitEvent(&FilterRequest.ReqEvent, 0);
Status = FilterRequest.Status;
}

if (Status == NDIS_STATUS_SUCCESS)
{
if (RequestType == NdisRequestSetInformation)
{
*pBytesProcessed = NdisRequest->DATA.SET_INFORMATION.BytesRead;
}

if (RequestType == NdisRequestQueryInformation)
{
*pBytesProcessed = NdisRequest->DATA.QUERY_INFORMATION.BytesWritten;
}

if (RequestType == NdisRequestMethod)
{
*pBytesProcessed = NdisRequest->DATA.METHOD_INFORMATION.BytesWritten;
}

//
// The driver below should set the correct value to BytesWritten
// or BytesRead. But now, we just truncate the value to InformationBufferLength
// It still need to be process …
if (RequestType == NdisRequestMethod)
{
if (*pBytesProcessed > OutputBufferLength)
{
*pBytesProcessed = OutputBufferLength;
}
}
else
{

if (*pBytesProcessed > InformationBufferLength)
{
*pBytesProcessed = InformationBufferLength;
}
}
}

return (Status);
}

I hava a test there is nothing wrong before the program calls the NdisFOidRequest(). So, maybe the parameters in the NdisRequest are invalid? or still memory problem? I have no idea!

feixianyexin@163.com wrote:

I think there is nothing wrong with the memory allocation and initializaiton, but i still get blue screen.

Then you need to hook up your debugger and figure it out.

I list all the codes:
NDIS_STATUS
filterCreateNewMACRequest(
IN NDIS_HANDLE FilterModuleContext,
IN NDIS_OID Oid
)

{

PULONG pBytesProcessed = NULL;

pBytesProcessed = (PULONG)NdisAllocateMemoryWithTagPriority(pFilter->FilterHandle,sizeof(ULONG),FILTER_ALLOC_TAG, LowPoolPriority);
*pBytesProcessed = 0;
Status = filterDoInternalRequest(pFilter,
NdisRequestMethod,
Oid,
InformationBuffer,
InformationBufferLength,
OutputBufferLength,
MethodId,
pBytesProcessed);

I’m astonished at how many people dive into driver development without a
basic understanding of C idioms.

The last parameter of filterDoInternalRequest is NOT supposed to be a
pointer to a buffer. Instead, it’s an OUTPUT parameter. Just do this:
ULONG BytesProcessed;
Status = filterDoInternalRequest( …, &BytesProcessed );

The code as you currently have it has two memory leaks. You are not
freeing the memory you allocated for InformationBuffer or pBytesProcessed.

And, actually, you don’t need to dynamically allocate either one. This
is a synchronous request, so you can put them BOTH on the stack:

DOT11_MAC_INFO InformationBuffer;
ULONG BytesProcessed;
Status = filterDoInternalRequest(
pFilter,
NdisRequestMethod,
Oid,
(PVOID)&InformationBuffer,
sizeof(DOT11_MAC_INFO),
sizeof(DOT11_MAC_INFO),
MethodId,
&BytesProcessed
);


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Dear Roberts,
Thanks for your suggestion, and I will spend more time on basic knowledge of C.
Best wishes.
Leyond

Hi~ It is me again.
Roberts, I have modified my codes according to your suggestion, but, I still get blue screen~. i am wondering what is going on if the underlying driver doesn’t support this OID? except this, I have no idea why this driver always causes the blue screen.

feixianyexin@163.com wrote:

Hi~ It is me again.
Roberts, I have modified my codes according to your suggestion, but, I still get blue screen~. i am wondering what is going on if the underlying driver doesn’t support this OID? except this, I have no idea why this driver always causes the blue screen.

Well, we don’t either. A BIG part of driver development is doing driver
debugging. YOU are the one that needs to figure out whether the
underlying driver supports the OID, by checking the error code you get
from the request. Beyond that, you will have to set a breakpoint in the
debugger and step through to figure out where it goes wrong.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Thanks again, Roberts.
I try to use windbg to figure out which line of codes casuses the blue screen. And I found:
FOLLOWUP_IP:
ndislwf!filterDoInternalRequest+1c1 [c:\users\leyond\desktop\filter_leyond_beta\src\filter\filter.c @ 2012]
93b882f1 8b4df4 mov ecx,dword ptr [ebp-0Ch]

FAULTING_SOURCE_CODE:
2008: if (Status == NDIS_STATUS_PENDING)
2009: {
2010:
2011: NdisWaitEvent(&FilterRequest.ReqEvent, 0);

2012: Status = FilterRequest.Status;
2013: }
2014:
2015:
2016: if (Status == NDIS_STATUS_SUCCESS)
2017: {

SYMBOL_STACK_INDEX: 5

So, the return value of NdisFOidRequest is NDIS_STATUS_PENDING. Actually, I don’t get the meaning of ‘Status = FilterRequest.Status;’. Should I call the FilterOidRequestComplete function manually if the return value is NDIS_STATUS_PENDING. Thanks very much.

Debug Mesage:
*** Fatal System Error: 0x0000007c
(0x00000014,0x00000002,0x00000000,0x00000000)

Break instruction exception - code 80000003 (first chance)

A fatal system error has occurred.
Debugger entered on first try; Bugcheck callbacks have not been invoked.

A fatal system error has occurred.
BugCheck 7C, {14, 2, 0, 0}
…BUGCODE_NDIS_DRIVER (7c)

I check this four parameters in MSDN doc:
parameter1: 0x14
parameter2:The current IRQL value
Parameter3:0
Parameter4:0
Cause of Error: An NDIS driver called NdisWaitEvent at IRQL > PASSIVE_LEVEL. The function must be called at IRQL = PASSIVE_LEVEL.
And that’s why when Driver calls NdisWaitEvent() then gets blue screen. How should change the IRQL’s values ? One more question, I have tested some ohters OID, and also result in blue screen, why? Thanks in advance~

feixianyexin@163.com wrote:


A fatal system error has occurred.
BugCheck 7C, {14, 2, 0, 0}
…BUGCODE_NDIS_DRIVER (7c)

I check this four parameters in MSDN doc:
parameter1: 0x14
parameter2:The current IRQL value
Parameter3:0
Parameter4:0
Cause of Error: An NDIS driver called NdisWaitEvent at IRQL > PASSIVE_LEVEL. The function must be called at IRQL = PASSIVE_LEVEL.
And that’s why when Driver calls NdisWaitEvent() then gets blue screen. How should change the IRQL’s values ? One more question, I have tested some ohters OID, and also result in blue screen, why? Thanks in advance~

You don’t change the IRQL. Instead, you rework your driver so that you
do not NEED to wait at DISPATCH_LEVEL. You can create a work item to
handle this task for you at a normal IRQL.

This is a relatively common misunderstanding, so I want to make sure
it’s clear. A lot of people come up against this restriction and say to
themselves “I need to wait in a DISPATCH_LEVEL function, so I’ll just
temporarily change myself to non-dispatch,” but that’s the wrong way to
think about it. As soon as you drop yourself below dispatch, you lose
the guarantees that you needed to be dispatch in the first place.
Spinlocks and synchronization will break, for example.

The solution is to remember that, in Windows, DISPATCH_LEVEL routines
cannot block, for any reason. If you need to wait for something, you
need to spin off separate code at PASSIVE_LEVEL to do the wait. That
means you have to think about WHY the routine was dispatch in the first
place. Are you holding a spinlock? If so, you’ll have to find some
other way to protect the resource.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Since this is in a NDIS driver one of the most common mistakes is to make a
call to NdisOidRequest (or some other function with a completion routine…)
and immediately wait for completion - at raised IRQL.

The solution to this is NOT to wait. Instead, do the work in the completion
routine when it is called.

Good luck,

Thomas F. Divine


From: “Tim Roberts”
Sent: Thursday, December 10, 2009 1:03 PM
To: “Windows System Software Devs Interest List”
Subject: Re: [ntdev] IRQ_NOT_LESS_OR_EQUAL Bulu Screen Error

> feixianyexin@163.com wrote:
>> …
>> A fatal system error has occurred.
>> BugCheck 7C, {14, 2, 0, 0}
>> …BUGCODE_NDIS_DRIVER (7c)
>> ----
>> I check this four parameters in MSDN doc:
>> parameter1: 0x14
>> parameter2:The current IRQL value
>> Parameter3:0
>> Parameter4:0
>> Cause of Error: An NDIS driver called NdisWaitEvent at IRQL >
>> PASSIVE_LEVEL. The function must be called at IRQL = PASSIVE_LEVEL.
>> And that’s why when Driver calls NdisWaitEvent() then gets blue screen.
>> How should change the IRQL’s values ? One more question, I have tested
>> some ohters OID, and also result in blue screen, why? Thanks in advance~
>>
>
> You don’t change the IRQL. Instead, you rework your driver so that you
> do not NEED to wait at DISPATCH_LEVEL. You can create a work item to
> handle this task for you at a normal IRQL.
>
> This is a relatively common misunderstanding, so I want to make sure
> it’s clear. A lot of people come up against this restriction and say to
> themselves “I need to wait in a DISPATCH_LEVEL function, so I’ll just
> temporarily change myself to non-dispatch,” but that’s the wrong way to
> think about it. As soon as you drop yourself below dispatch, you lose
> the guarantees that you needed to be dispatch in the first place.
> Spinlocks and synchronization will break, for example.
>
> The solution is to remember that, in Windows, DISPATCH_LEVEL routines
> cannot block, for any reason. If you need to wait for something, you
> need to spin off separate code at PASSIVE_LEVEL to do the wait. That
> means you have to think about WHY the routine was dispatch in the first
> place. Are you holding a spinlock? If so, you’ll have to find some
> other way to protect the resource.
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
> —
> 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

Thanks very much, Tim Roberts.
Just like you said, pFilter is holding a lock when calling NdisFoidRequest. Blue screen doesn’t happen again after I deleted the Lock. I have not idea about some ohter ways to protect the resoruce yet.
Thanks, you all.