prefast warning 28144

I get the following warning for my routine

warning 28144: Within a cancel routine, at the point of exit, the IRQL in
Irp->CancelIrql should be the current IRQL.: The value need not be restored
by any specific function, but must be restored before exit. PREfast was
unable to determine that it was restored to the required value.
Found in function 'ListCancelRoutine'

here is the faulting function, can someonetell me why this is flagging when
I have done wht is already said in the above warning.

*VOID ListCancelRoutine(* queue.cpp(1101) : warning 28144:
Within a cancel routine, at the point of exit, the IRQL in Irp->CancelIrql
should be the current IRQL.: The value need not be restored by any specific
function, but must be restored before exit. PREfast was unable to determine
that it was restored to the required value.
Found in function 'ListCancelRoutine'
Path includes 12 statements on the following lines:
1106 1107 1109 1115 1118 1121 1124 1127 1130 1131 1133 1135
1102 IN PDEVICE_OBJECT DeviceObject,
1103 IN PIRP Irp
1104 )
1105 {

PREfast analysis path begins
1106 KIRQL oldIrql;
1107 P_LIST list;
1108
1109 oldIrql = Irp->CancelIrql;
1110
1111
1112 //AP: To remove Warning 28144
1113 // release the system cancel spinlock
1114 //IoReleaseCancelSpinLock(DISPATCH_LEVEL);
1115 IoReleaseCancelSpinLock(Irp->CancelIrql);
1116
1117 // get our list context from the IRP
1118 list = (P_LIST)Irp->Tail.Overlay.DriverContext[0];
1119
1120 // grab the list protection
1121 KeAcquireSpinLockAtDpcLevel(&list->ListLock);
1122
1123 // remove our IRP from the list
1124 RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
1125
1126 // drop the list protection
1127 KeReleaseSpinLock(&list->ListLock, oldIrql);
1128
1129 // cancel the IRP
1130 Irp->IoStatus.Status = STATUS_CANCELLED;
1131 Irp->IoStatus.Information = 0;
1132
1133 IoCompleteRequest(Irp, IO_NO_INCREMENT);
1134
1135 return;

The line of code here:
1121 KeAcquireSpinLockAtDpcLevel(&list->ListLock);

is wrong as there is no guarantee that you are at DPC level at that point in
time. You are instead at Irp->CancelIrql, and prefast ought to complain
about that, but is instead making some other and probably bogus complaint.

Mark Roddy

On Thu, Feb 12, 2009 at 5:57 AM, A P wrote:

> KeAcquireSpinLockAtDpcLevel(&list->ListLock);

Right. The code did the right thing with the original line you removed:

1114 //IoReleaseCancelSpinLock(DISPATCH_LEVEL);

But when you replace that with the following:

1115 IoReleaseCancelSpinLock(Irp->CancelIrql);

Your broke the function. Ask yourself: What happens if Irp->CancelIrql is IRQL PASSIVE_LEVEL when you later do this:

1121 KeAcquireSpinLockAtDpcLevel(&list->ListLock);

May I make a suggestion? Instead of this old, crappy, code… why not use cancel-safe queues?

Peter
OSR

dear peter, all,

the original code had the same warning, so I replaced the commented out line
with the new one. but the error remains.
as for peter’s question about using cancel safe queues, we are migrating
this driver to kmdf, so not worth fixing the legacy much. however, the
client wants it to be prefast clean, where i stumbled upon this issue.

this brings to mind an important question, what all warnings are mandatory
to be removed in prefast examination?

thanks

ap

On Thu, Feb 12, 2009 at 9:06 PM, wrote:

>
> Right. The code did the right thing with the original line you removed:
>
> 1114 //IoReleaseCancelSpinLock(DISPATCH_LEVEL);
>
> But when you replace that with the following:
>
> 1115 IoReleaseCancelSpinLock(Irp->CancelIrql);
>
> Your broke the function. Ask yourself: What happens if Irp->CancelIrql is
> IRQL PASSIVE_LEVEL when you later do this:
>
> 1121 KeAcquireSpinLockAtDpcLevel(&list->ListLock);
>
> May I make a suggestion? Instead of this old, crappy, code… why not use
> cancel-safe queues?
>
> Peter
> OSR
>
> —
> 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
>

Is it possible prefast is getting confused by this?

1120 // grab the list protection
1121 KeAcquireSpinLockAtDpcLevel(&list->ListLock);

1126 // drop the list protection
1127 KeReleaseSpinLock(&list->ListLock, oldIrql);

Well… the initial code was correct. Your updated code is not, and risks introducing a deadlock.

Note that the Prefast warning you’re seeing is just that: A WARNING. It’s saying Prefast isn’t smart enough to determine if your code is doing the right thing. Either ignore it, or suppress it with a comment describing how the IRQL is being properly restored. I would personally do the latter.

I hope that helps,

Peter