Figure 1   FilterOpLock.cpp

 /******************************************************************************
 Module:  FilterOpLock.cpp
 Notices: Written by Jeffrey Richter
 ******************************************************************************/
 
 #define UNICODE
 #define _UNICODE
 #include <Windows.h>
 #include <tchar.h>
 
 ///////////////////////////////////////////////////////////////////////////////
 
 // Helper function to make setting an Oplock easier
 inline RequestOpLock(DWORD dwCode, HANDLE hfile, OVERLAPPED* po) {
    DWORD dw;
    return(DeviceIoControl(hfile, dwCode, NULL, 0, NULL, 0, &dw, po));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 int WINAPI _tWinMain(HINSTANCE hinstExe, HINSTANCE, LPTSTR pszCmdLine, int) {
 
    TCHAR szFilename[] = TEXT("FilterOpLock.dat");
    HANDLE hfileLocking = INVALID_HANDLE_VALUE;
    HANDLE hfileReading = INVALID_HANDLE_VALUE;
    HMODULE hmod = NULL;
    OVERLAPPED o = { 0 };
    PCTSTR pszReport = NULL;
 
    __try {
       // Attempt to open the file for processing (must be asynchronous)
       MessageBox(NULL, TEXT("Open file's locking handle?"), NULL, MB_OK);
 
       // Open the file without requesting GENERIC_READ or GENERIC_WRITE
       // so that this call NEVER fails.
       hfileLocking = CreateFile(szFilename, 0, FILE_SHARE_READ, NULL, 
          OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, NULL);
       if (hfileLocking == INVALID_HANDLE_VALUE) {
          pszReport = TEXT("Can't open file for locking.");
          __leave;
       }
 
       // After opening the file (above) and before requesting the 
       // Oplock (below), another process can sucessfully access the file
       // including delete the file.
 
       // Request the Filter Oplock on the file.
       // When another process attempts to access the file, the system will 
       // signal the event and block the other process until we close the file
       MessageBox(NULL, TEXT("Request filter oplock?"), NULL, MB_OK);
       o.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
       if (RequestOpLock(FSCTL_REQUEST_FILTER_OPLOCK, hfileLocking, &o) ||
          (GetLastError() != ERROR_IO_PENDING)) {
          pszReport = TEXT("Failed to set opportunistic lock.");
          __leave;
       }
 
 #if 1
       // Attempt to open the file again to perform our own processing
       MessageBox(NULL, TEXT("Open file for processing?"), NULL, MB_OK);
       hfileReading = CreateFile(szFilename, GENERIC_READ, 
          FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, 
          OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
       if (hfileReading == INVALID_HANDLE_VALUE) {
          // The file was deleted or opened exclusively by another process.
          pszReport = TEXT("Can't open file for reading.");
          __leave;
       }
 #else
       // NOTE: To experiment with a DLL change szFilename to a DLL file, 
       //       comment out the code above, uncomment this code and rebuild 
       //       this sample application.
       // Attempt to load the DLL to use it (Example: Explorer Shell Extension)
       MessageBox(NULL, TEXT("Load DLL?"), NULL, MB_OK);
       hmod = LoadLibrary(szFilename);
       if (hmod == NULL) {
          // The DLL was deleted or opened exclusively by another process.
          pszReport = TEXT("Can't load DLL.");
          __leave;
       }
 #endif
 
       // Work with the file for 15 seconds (simulated)
       // Wait for lock to be broken
       MessageBox(NULL, TEXT("Access file/DLL for 15 seconds?"), NULL, MB_OK);
       if (WaitForSingleObject(o.hEvent, 15000) == WAIT_OBJECT_0) {
          // Event is signaled: Another process is trying to access the file
          // The other process is suspended until we close the file
          MessageBox (NULL, 
             TEXT("Another process is attempting to access the file.\n")
             TEXT("Close file/DLL and allow the other process access?"),
             NULL, MB_OK);
          pszReport = TEXT("The file/DLL is closed.");
       } else {
          // Another process did NOT attempt to access the file at the same 
          // time, we'll just close the file.
          pszReport = TEXT("We're finished accessing the file/DLL.");
       }
    }
    __finally {
       // Clean up everything we did sucessfully.
       if (hfileLocking != INVALID_HANDLE_VALUE)
          CloseHandle(hfileLocking);
 
       if (hfileReading != INVALID_HANDLE_VALUE)
          CloseHandle(hfileReading);
 
       if (hmod != NULL)
          FreeLibrary(hmod);
 
       if (o.hEvent != NULL)
          CloseHandle(o.hEvent);
 
       if (pszReport != NULL)
          MessageBox(NULL, pszReport, TEXT("Final report"), MB_OK);
    }
    return(0);
 }
 
 //////////////////////////////// End of File //////////////////////////////////
 
 #if 0
 What File System does to open a file:
 Open
    Break batch/filter op lock (blocked til close pending)
 Sharing mode check
 ACL check
     Break exclusive lock
 Opened
 
 NOTE: Filter lock: open w/read attributes only
 #endif