Skip to content

Instantly share code, notes, and snippets.

@nickav
Last active September 18, 2023 21:50
  • Star 10 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Embed
What would you like to do?
Example of how to poll ReadDirectoryChangesW on Windows
int main() {
char *path = "/path/to/my/directory";
print("watching %s for changes...\n", path);
HANDLE file = CreateFile(path,
FILE_LIST_DIRECTORY,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
NULL);
assert(file != INVALID_HANDLE_VALUE);
OVERLAPPED overlapped;
overlapped.hEvent = CreateEvent(NULL, FALSE, 0, NULL);
uint8_t change_buf[1024];
BOOL success = ReadDirectoryChangesW(
file, change_buf, 1024, TRUE,
FILE_NOTIFY_CHANGE_FILE_NAME |
FILE_NOTIFY_CHANGE_DIR_NAME |
FILE_NOTIFY_CHANGE_LAST_WRITE,
NULL, &overlapped, NULL);
while (true) {
DWORD result = WaitForSingleObject(overlapped.hEvent, 0);
if (result == WAIT_OBJECT_0) {
DWORD bytes_transferred;
GetOverlappedResult(file, &overlapped, &bytes_transferred, FALSE);
FILE_NOTIFY_INFORMATION *event = (FILE_NOTIFY_INFORMATION*)change_buf;
for (;;) {
DWORD name_len = event->FileNameLength / sizeof(wchar_t);
switch (event->Action) {
case FILE_ACTION_ADDED: {
wprintf(L" Added: %.*s\n", name_len, event->FileName);
} break;
case FILE_ACTION_REMOVED: {
wprintf(L" Removed: %.*s\n", name_len, event->FileName);
} break;
case FILE_ACTION_MODIFIED: {
wprintf(L" Modified: %.*s\n", name_len, event->FileName);
} break;
case FILE_ACTION_RENAMED_OLD_NAME: {
wprintf(L"Renamed from: %.*s\n", name_len, event->FileName);
} break;
case FILE_ACTION_RENAMED_NEW_NAME: {
wprintf(L" to: %.*s\n", name_len, event->FileName);
} break;
default: {
printf("Unknown action!\n");
} break;
}
// Are there more events to handle?
if (event->NextEntryOffset) {
*((uint8_t**)&event) += event->NextEntryOffset;
} else {
break;
}
}
// Queue the next event
BOOL success = ReadDirectoryChangesW(
file, change_buf, 1024, TRUE,
FILE_NOTIFY_CHANGE_FILE_NAME |
FILE_NOTIFY_CHANGE_DIR_NAME |
FILE_NOTIFY_CHANGE_LAST_WRITE,
NULL, &overlapped, NULL);
}
// Do other loop stuff here...
}
}
@ashopson
Copy link

This is great, it does a much better job showing how to work with ReadDirectoryChangesW than any of the MS documentation

@spacebares
Copy link

perfect. clean and actually works unlike everything else on the net

@mikeg-asi
Copy link

Good one

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment