status = ZwCreateEvent(&EventHandle,
EVENT_ALL_ACCESS,
0,
NotificationEvent,FALSE);
if (NT_SUCCESS(status))
{
InitializeObjectAttributes(&oa,
MagicFilePath,
OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
0,0);
//notice here, AP will get sharing violation
//if they try to modify
//"\\SystemRoot\\OplockTest",
//with oplock we can avoid sharing violation.
status = ZwCreateFile(&MagicFileHandle,
GENERIC_READ,
&oa,
&iosb,
0,
0,
FILE_SHARE_READ,
FILE_OPEN_IF,
FILE_NON_DIRECTORY_FILE,0,0);
if (NT_SUCCESS(status))
{
status = ZwFsControlFile(MagicFileHandle,
EventHandle,
NULL,
NULL,
&iosb,
FSCTL_REQUEST_FILTER_OPLOCK,
0,
0,
0,
0);
//
//STATUS_PENDING means we got oplock,
//
if (status == STATUS_PENDING)
{
//
//Event will be signalled when the sharing
//violation happen. Polling the oplock event to
//see if the oplock has broken. You can
//wait for the event in a different thread.
//
LARGE_INTEGER Timeout;
Timeout.QuadPart = (LONGLONG)-10000000;
while(TRUE)
{
status = ZwWaitForSingleObject(
EventHandle,
false,
&Timeout);
if (!NT_SUCCESS(status))
{
//
//error happened
//
goto CleanupAndExit;
}
else if(status == STATUS_TIMEOUT)
{
//
// Perform major task here.
//
KdPrint(("access file...\n",
status));
continue;
}
else
{
//
//Some operation is waiting
//quickly finish up and get out.
//
KdPrint(("ackonwledge oplock break \n",
status));
goto CleanupAndExit;
}
}
}
}
}
eanupAndExit:
if (MagicFileHandle)
{
//
//close handle will relinquishes oplock (acknowledge
//the oplock break) Until acknowledge oplock break
//AP thread will <<<<<HANG>>>>> if AP doesn't specify
//FILE_COMPLETE_IF_OPLOCKED in CreateFile
//
ZwClose(MagicFileHandle);
MagicFileHandle = 0;
}