Reputation: 7527
I'm trying to monitor file changes but I am not really sure on how to read the filename in the FILE_NOTIFY_INFORMATION struct:
HANDLE dwChangeHandles[2];
DWORD dwWaitStatus;
wChangeHandles[0] = FindFirstChangeNotification(dirname.c_str(), FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE);
if (dwChangeHandles[0] == INVALID_HANDLE_VALUE) printerr(__FILE__,__LINE__,"FindFirstChangeNotification function failed.\n");
...
if ((dwChangeHandles[0] == NULL) || (dwChangeHandles[1] == NULL)) //final validation
printerr(__FILE__,__LINE__,"Unexpected NULL from FindFirstChangeNotification.\n");
while (TRUE) {
std::cout << "Waiting for notification...\n";
dwWaitStatus = WaitForMultipleObjects(2, dwChangeHandles, FALSE, INFINITE);
if(dwWaitStatus==WAIT_OBJECT_0){
std::cout << "Something changed\n";
DWORD BytesReturned;
size_t bufLen = 1024;
FILE_NOTIFY_INFORMATION buffer[bufLen];
if (ReadDirectoryChangesW(dwChangeHandles[0], buffer, bufLen, FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE, &BytesReturned, NULL, NULL)){
std::wcout << std::wstring(buffer->FileName)<< std::endl; //THERE IS NOTHING IN THE EXPECTED OUTPUT HERE
}
if (FindNextChangeNotification(dwChangeHandles[0]) == FALSE ) printerr(__FILE__,__LINE__,"FindNextChangeNotification function failed.\n");
}
else if(dwWaitStatus==WAIT_TIMEOUT) printerr(__FILE__,__LINE__,"No changes in the timeout period.\n");
else printerr(__FILE__,__LINE__,"Unhandled dwWaitStatus.\n");
}
Is there something I am doing wrong
Upvotes: 0
Views: 2329
Reputation: 37122
You have a number of problems that I can see immediately:
According to the docs for the ReadDirectoryChangesW
function, the buffer needs to be DWORD
-aligned. As you are using a buffer on the stack this isn't guaranteed - you should allocate one from the heap instead.
You don't seem to be using the function correctly. Normally you would call ReadDirectoryChangesW
first, and then wait on the event. Not the other way around. When ReadDirectoryChangesW
returns for an asynchronous call there is usually no data in the buffer at that point. You need to wait for notification that the request has been completed before using the buffer contents.
FindNextChangeNotification
is only used with FindFirstChangeNotification
, so this is completely wrong. When the ReadDirectoryChangesW
completes you need to use the NextEntryOffset
field in the FILE_NOTIFY_INFORMATION
structure to loop through the returned events.
Edit: Since you've added more code to your question it's now obvious that you are mixing the two APIs. FindFirstChangeNotification
and FindNextChangeNotification
are one API, and ReadDirectoryChangesW
is another. I believe you've been confused by this passage in the docs:
This function does not indicate the change that satisfied the wait condition. To retrieve information about the specific change as part of the notification, use the ReadDirectoryChangesW function.
I guess your confusion is understandable, but the two APIs can't be used together. If you're using FindFirstChangeNotification
then all you get is a notification that something changed, and you have to re-read the directory to find out what it was. If you want specific notifications at the file level then you have to use ReadDirectoryChangesW
to do the monitoring.
Upvotes: 3