SDV Detected False Positively Acquiring and Releasing of IoRemoveLocks

I am migrating the USB driver(written using WDM) from Windows 7 to Windows 10/11 operating systems.
While running the Static Driver Verifier tool, it detected issues around RemoveLock for IRP.
As per the code, when an IRP is received, IoRemoveLock is acquired with the IRP itself as a tag.
The acquired IoRemoveLock with the IRP tag is released in the context of the completion routine of that particular IRP.

But, SDV is detecting incorrectly for Acquiring and Releasing of IoRemoveLock. SDV is only checking for the IoAcquireRemovelock and IoReleaseRemoveLock pair, whereas ideally, it should check for the acquire-release pair concerning the Tag, because of this SDV is resulting in false defects.

Can anyone tell me how to make a False Positive for SDV in the above scenario?

Below are the list of SDV rules that are failed:
removelock
removelockcheck
removelockforward
removelockforward2
removelockforwarddevicecontrol
removelockmnremove
removelockmnremove2
removelockrelease2
removelockreleasecleanup

I’m not sure exactly what you are asking, but it is usually wrong for a lock to be acquired in one context, and released in another. Otherwise, what is the lock protecting? Even if it is not a bug per se, it probably reduces performance

remove locks are typically set in one context and released in another.
Mark Roddy

SDV has been deprecated since Windows 11 22H2. The current standard for static tools logo test is Codeql. Please visit for more information https://learn.microsoft.com/en-us/windows-hardware/drivers/devtest/static-tools-and-codeql

SDV has been deprecated since Windows 11 22H2

Citation, please?

CodeQL has been added … but, to the best of my knowledge, SDV has not been deprecated

And, as a side note, the last time I spent time with CodeQL it had a long, long, long, way to go before it did anything useful for driver devs.

Every time I investigate codeql I run into the absurd licensing quagmire and the installation mess and conclude that I’ll once again put off doing anything about it until that mess is cleaned up. If I have to whql something I’ll grudgingly use it.

(not to mention that, the last time I used it, there was no way to tell it to suppress a given instance of a warning. Which is, on its face, ridiculous.)

Hi Mark,

Yes, that is true, basically we acquire the removelock by using the tag as PIRP so that it would be easier to track the IRP. Initially when an IO Request is triggered, we acquire the IoRemoveLock with IRP as tag and add the same to the pending, later when this IRP is serviced, in completion routine we are releasing the IoRemoveLock with the same PIRP tag.
When I run SDV, even though the tags are different, it is giving false positive results.

Can anyone tell me how to use __assume_analysis or similar tags to make SDV false positive? Specially in case of Acquiring and releasing of IoRemoveLocks?

Hi All,

Can anyone help me with this?

Well, you're not giving us much to go on. I mean, how can we help you when all you tell us about your problem is "SDV is giving me a false positive"? The question I have is: Is SDV wrong, or is your code actually broken?

Hmmm... well... probably not. Just like the tag on pool allocations, the tag on Remove Locks is informative for debugging purposes. It doesn't actually cause any change in behaviors of the Remove Lock logic.

In other words, it's not clear to me if your code is correct or not.

Hello Peter,

No, my code is not broken. It is using the IoRemoveLock's properly.

Following is the flow of acquiring and releasing IoRemoveLock w.r.t IRP handling.

1. Once the IoRequest is triggered
2. From the driver side,
	A. It will acquire the lock with IRP as tag
	B. Verify the Device PNP state
		i. If device is not busy mark current IRP as active and process the IRP
			a) IoSetCompletion Routine to SyncComplete routine
			b) Call the lower driver
			c) And return 
		ii. Else, if device is busy addressing another IORequest
			a) Add the IRP to the PendingIoQueue and
			b) Return
	C. Once lower driver completes processing the IRP and the SyncComplete routine is triggered
		i. Do the necessary tasks
		ii. While, doing the cleanup, it will release the IoRemoveLock acquired at step.2.A

For every IRP received, the driver acquires the IoRemoveLock, adds the IRP to PendingIoQueue, and returns.
Later, when the driver processes each IRP in the queue, it completes the IRP and releases the IoRemoveLock.

In this way, acquiring and releasing of IoRemoveLock is handled in correct manner.

SDV Issue Scenario:
Consider the IRP_MN_REMOVE_DEVICE case:
Suppose there is an existing IRP (with IRP-tag=1) in PendingIoQueue and driver receives IRP_MN_REMOVE_DEVICE (here IRP-tag=2)

1. When the driver receives IRP_MN_REMOVE_DEVICE (here IRP-tag=2),
2. Driver acquires IoRemoveLock with the IRP-tag=2
3. For each IRP existing in PendingIoQueue
        A. Free allocated resources
        B. cancel all IRPs with status=STATUS_DELETE_PENDING and
        C. Release the IoRemoveLock acquired for that particular IRP tag
            ***> SDV Error: Actual problem is here. As per code, we are releasing the lock acquired for IRP-tag=1, but SDV assumes that this IoReleaseLock is for IRP-tag2***
4. Set the IoStatus to success and pass IRP to lower driver
5. Release the IoRemoveLock for IRP-tag=2 
    ***> SDV Error: As SDV assumes that acquired lock is released earlier in Step3.C here it is failing with error "The routine was called without first acquiring the RemoveLock"***.
6. Detach and delete device.
7. Return status.

Can anyone help me with this?

I'd suggest just ignoring it. You have to submit DVL logs, as far as I know errors in them do not disqualify your submission.

Hello @Mark_Roddy,

Thanks for inputs.

I have ignored the SDV errors and generated the DVL file.
With the generated DVL file as input to the Static Tools Logo Test, is failing withe error:

Error: DVL test failed:

Microsoft.SaticToolsLogo.ObjectModel.DvlException: Missing checksum for DVL C:\dvl\WaUsb.DVL.XML. Please re-generate the DVL.
at DevfundTests.DvlTest.DvlCheck() [Failed]
EndGroup: DevfundTests.DvlTest.DvlCheck() [Failed]

Even after re-generating the DVL again, it fails with the same error.
Can you please let me know what I am missing here?