Cool, presumably we’re now looking at the same thing and now we’re on to something…
If I do this:
status = NtCreateFile(&handle,
GENERIC_READ,
&objAttr,
&iosb,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN_IF,
FILE_OPEN_REQUIRING_OPLOCK,
NULL,
0);
if (!NT_SUCCESS(status)) {
return 1;
}
status = NtCreateFile(&handle2,
GENERIC_WRITE,
&objAttr,
&iosb,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN_IF,
FILE_COMPLETE_IF_OPLOCKED,
NULL,
0);
The second create completes immediately with STATUS_SUCCESS. This is reasonable though because the first open doesn’t actually have an oplock yet (how would the file system even know what level to give you?). Like I said before it’s in an “oplock like” state though so things that might require breaking an oplock will hang.
The contract with FILE_OPEN_REQUIRING_OPLOCK is that you then need to actually request an oplock. So, if I change the code to something like this:
status = NtCreateFile(&handle,
GENERIC_READ,
&objAttr,
&iosb,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN_IF,
FILE_OPEN_REQUIRING_OPLOCK,
NULL,
0);
if (!NT_SUCCESS(status)) {
return 1;
}
oplockInput.StructureVersion = REQUEST_OPLOCK_CURRENT_VERSION;
oplockInput.StructureLength = sizeof(REQUEST_OPLOCK_INPUT_BUFFER);
oplockInput.RequestedOplockLevel = (OPLOCK_LEVEL_CACHE_READ | OPLOCK_LEVEL_CACHE_WRITE);
oplockInput.Flags = REQUEST_OPLOCK_INPUT_FLAG_REQUEST;
status = NtFsControlFile(handle,
event,
NULL,
NULL,
&iosb,
FSCTL_REQUEST_OPLOCK,
&oplockInput,
sizeof(REQUEST_OPLOCK_INPUT_BUFFER),
&oplockOutput,
sizeof(REQUEST_OPLOCK_OUTPUT_BUFFER));
if (!NT_SUCCESS(status)) {
return 1;
}
status = NtCreateFile(&handle2,
GENERIC_WRITE,
&objAttr,
&iosb,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN_IF,
FILE_COMPLETE_IF_OPLOCKED,
NULL,
0);
Then I get STATUS_OPLOCK_BREAK_IN_PROGRESS on the second open.
I know you said you’re not seeing this behavior, so I’d still like to see you code and figure out what’s different. Can you put it on Dropbox or OneDrive?