Friday, August 10, 2012

How to monitor a directory for changes with ReadDirectoryChangesW

Here's how to use ReadDirectoryChangesW without knowing all of this and without using this overkill C++ class library (remove the &o parameter in the call to make it blocking instead of async. Note: This only returns one change, you have to step trough a buffer of FILE_NOTIFY_INFORMATIONs if you need to get more):


HANDLE hDirectory;
OVERLAPPED o = {0};
union {
    FILE_NOTIFY_INFORMATION i;
    char d[sizeof(FILE_NOTIFY_INFORMATION)+MAX_PATH];
} fni;


int checkAutoCompile() {
    DWORD b;

    if (!hDirectory) {
        hDirectory = CreateFile(".", 
        FILE_LIST_DIRECTORY | GENERIC_READ, 
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        0, 
        OPEN_EXISTING, 
        FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, 
        0
        );
        o.hEvent = CreateEvent(0,0,0,0);
    }
    ReadDirectoryChangesW(hDirectory,
        &fni,
        sizeof(fni),
        TRUE,
        FILE_NOTIFY_CHANGE_LAST_WRITE,
        &b,
        &o, 
        0);
    
    GetOverlappedResult(hDirectory,&o,&b,FALSE);
    if (fni.i.Action != 0) {
        wprintf(L"action %d, b: %d, %s\n", fni.i.Action, b, fni.i.FileName);
        fni.i.Action = 0;
    }

    return 0;
}