Title: APC re-enabled in recursive ERESOURCE lite.

Hello,

As per documentation:

  1. one can acquire ERESOURCE recursively.
  2. Normal kernel APC delivery must be disabled before calling this routine. Disable normal kernel APC delivery by calling KeEnterCriticalRegion. Delivery must remain disabled until the resource is released, at which point it can be reenabled by calling KeLeaveCriticalRegion.

Will the following code sequence works perfectly?
Case 1.
KeEnterCriticalRegion().
ExAcquireResourceExclusiveLite(X).
// do some work.

KeEnterCriticalRegion().
ExAcquireResourceExclusiveLite(X).
// do some work.
ExReleaseResourceLite(X)
KeLeaveCriticalRegion() // will re-enabled normal kernel APC delivery.

// do some work.
ExReleaseResourceLite(X) // will it be issue here because kernel APC delivery is already re-enabled above?
KeLeaveCriticalRegion()

Case 2.
KeEnterCriticalRegion().
ExAcquireResourceExclusiveLite(X).
// do some work.

KeEnterCriticalRegion().
ExAcquireResourceExclusiveLite(Y).
// do some work.
ExReleaseResourceLite(Y)
KeLeaveCriticalRegion() // will re-enabled normal kernel APC delivery.

// do some work.
ExReleaseResourceLite(X) // will it be issue here because kernel APC delivery is already re-enabled above?
KeLeaveCriticalRegion()

Thanks in advance.

> Will the following code sequence works perfectly?

Yes, Within reason (its a 16 bit count) APC delivery can be stacked.
FltAcquireResource follows this paradigm, which has the side effects of
giving you a great warning if you exit a system service with a lock held
(because your APC siable level will have changed).

KeEnterCriticalRegion().
ExAcquireResourceExclusiveLite(X).
KeEnterCriticalRegion().
ExAcquireResourceExclusiveLite(X).
ExReleaseResourceLite(X)
KeLeaveCriticalRegion() // will re-enabled normal kernel APC delivery.

No, it won’t.

There is one important edge case when you cannot automatically enter the
region before grabbing a resource and that is in the AcquireForModeWriter
path. In this situation you are expected to know that APCs are disabled.
If you do Enter in Acquire and Leave in Release Verifier will bugcheck on
you. But this is an extreme edge case which you shouldn’t have to worry
about.

Critical regions can be entered recursively and each call to KeEnterCriticalRegion must have a matching call to KeLeaveCriticalRegion
so all will be ok here
KeLeaveCriticalRegion() // will re-enabled normal kernel APC delivery.

  • no,only second call reenable it

Thank you Rod and Harald for your helpful replies. It clears all my doubts.