Share via


Example 3: Calling a Function at Incorrect IRQL

The IRQL at which a driver routine runs determines which kernel-mode routines it can call and whether it can access paged memory, use kernel-dispatcher objects, or take other actions that might cause a page fault. Some routines require that the caller be running at a particular IRQL or within a particular range, whereas others can be called at any IRQL.

When PREfast for Drivers detects that the caller is running at an IRQL that is too high, it reports Warning 28121, as shown in the following example. In this example, the driver sets a flag based on the content of a string and the flag is a member of a data structure that needs protected access. A call to ExAcquireFastMutex raises the caller's IRQL to APC_LEVEL before acquiring the mutex, but RtlCompareUnicodeString can be called only when the caller is executing at PASSIVE_LEVEL.

11    void IsFlagSet(
12        IN PUNICODE_STRING s)
13    {

PREfast analysis path begins

14        ExAcquireFastMutex(&mutex);
15    
 16        if (RtlCompareUnicodeString(s, &t, TRUE)) {

IRQL.c(16) : warning 28121: The function RtlCompareUnicodeString is not permitted to be called at the current IRQ level. The current level is too high: The level might have been inferred from the function signature.problem occurs in function 'IsFlagSet'Path includes 2 statements on the following lines:14 16

17            MyGlobal.FlagIsSet = 1;
18        }
19
20        ExReleaseFastMutex(&mutex);
21    }

In this case, one possible solution is to call RtlCompareUnicodeString before calling KeAcquireFastMutex and then to test the result after acquiring the mutex. The corrected code would look like this:

void IsFlagSet(
    IN PUNICODE_STRING s)
{
    int tmp = 0;
    if (RtlCompareUnicodeString(s, &t, true)) {
        tmp = 1;
    }
    ExAcquireFastMutex(&mutex);
    if (tmp) {
        MyGlobal.FlagIsSet = 1;
    }
    ExReleaseFastMutex(&mutex);
}

 

 

Send comments about this topic to Microsoft

Build date: 5/3/2011