FILE_COMPLETE_IF_OPLOCKED not working on windows 10

Hi Scott,

My previous comment went missing, so please forgive me if this is a duplicate post.

Your second request would have failed because it requests GENERIC_READ | GENERIC_WRITE but no sharing was allowed by the first and second open.
I have tried the flags used in your sample and was able to reproduce the sharing violation behavior you are seeing, then added FILE_SHARE_READ and FILE_SHARE_WRITE in both open requests and it gave STATUS_SUCCESS in both requests.
Also, if I remove FILE_OPEN_REQUIRING_OPLOCK and FILE_COMPLETE_IF_OPLOCKED it doesn’t change the behavior.

Here is relevant code snippet which I had originally used:

status = ZwCreateFile(&hFile1,
FILE_WRITE_DATA | SYNCHRONIZE,
&oa,
&ioStatus,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
FILE_OPEN_IF,
FILE_NON_DIRECTORY_FILE | FILE_RANDOM_ACCESS | FILE_OPEN_REQUIRING_OPLOCK,
NULL,
0);
if (status != 0)
{
return status;
}

status = ZwCreateFile(&hFile2,
        FILE_WRITE_DATA | SYNCHRONIZE | DELETE,
        &oa,
        &ioStatus,
        NULL,
        FILE_ATTRIBUTE_NORMAL,
        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
        FILE_OPEN,
        FILE_NON_DIRECTORY_FILE | FILE_COMPLETE_IF_OPLOCKED,
        NULL,
       0);

if (status != 0)
{

}

Also attached the source file here (since it won’t let me attach a .cpp file, added .txt extension to it)

Thanks,
Arun

One of the use cases for oplocks is to avoid sharing violations. If an open is going to trigger a sharing violation and there is an oplock active of a particular type, the file system will break the oplock, wait for acknowledgement, and then retry the create. The primary use case of this is to avoid background scanning activities (A/V, search indexer, etc.) to cause sharing violations for the user.

If someone opens with FILE_OPEN_REQUIRING_OPLOCK (and thus puts the stream in the “awaiting oplock request” state) and an open occurs that would trigger a sharing violation the file system says, “gee, I might need to break the oplock that the first open is going to eventually send”. This causes the second open to hang indefinitely until the oplock is sent or the first handle is closed. Try the following exact arguments:

    status = NtCreateFile(&handle, 
                          GENERIC_READ | GENERIC_WRITE, 
                          &objAttr, 
                          &iosb, 
                          NULL, 
                          FILE_ATTRIBUTE_NORMAL, 
                          0, 
                          FILE_OPEN_IF, 
                          FILE_OPEN_REQUIRING_OPLOCK, 
                          NULL, 
                          0);

    if (!NT_SUCCESS(status)) {
        return 1;
    }

    status = NtCreateFile(&handle2, 
                          GENERIC_READ | GENERIC_WRITE, 
                          &objAttr, 
                          &iosb, 
                          NULL, 
                          FILE_ATTRIBUTE_NORMAL, 
                          0, 
                          FILE_OPEN_IF, 
                          0, 
                          NULL, 
                          0);

You should see the second create hang forever. If you add FILE_COMPLETE_IF_OPLOCKED on the second open you’ll immediately get a sharing violation.

The code you provided “just works” because it’s not going to cause a sharing violation and so all of that processing is bypassed during create.