ReadDirectoryChangesW: how to detect buffer overflow when using asynchronously?

1.1k Views Asked by At

I'm using ReadDirectoryChangesW (Windows API) asynchronously in combination with GetQueuedCompletionStatus. How can I detect a possible buffer overflow to understand that at least one file system change event has been lost?

3

There are 3 best solutions below

2
On BEST ANSWER

When using ReadDirectoryChangesW asynchronously, you will get the first group of events, then you have to call it again for more events. Having more events than fit in your buffer is not an error. Having more events than fit in the OS-level buffer is the error condition, and you find out like so:

  1. Some event happens.
  2. The asynchronous operation started by ReadDirectoryChangesW completes successfully. Your buffer is filled, your event handle is set or the IOCP is triggered.
  3. Additional events happen, which are stored in the OS-level buffer.
  4. More additional events happen, which overflow the OS-level buffer. This doesn't change the status of the overlapped operation, which already succeeded at step 2.
  5. You wait on the event handle, or process the IOCP, and discover the completed OVERLAPPED call.
  6. You call ReadDirectoryChangesW again to begin an asynchronous overlapped operation checking for any events that happened since step 2. This call fails synchronously, with GetLastError() == ERROR_NOTIFY_ENUM_DIR, or succeeds with dwBytesTransferred == 0, since the documentation says this also means to re-enumerate the directory

If the number of bytes transferred is zero, the buffer was either too large for the system to allocate or too small to provide detailed information on all the changes that occurred in the directory or subtree. In this case, you should compute the changes by enumerating the directory or subtree.

0
On

Judging from here, it seems like there is no such error code returned asynchronously.

Suggestion: Monitor for changes synchronously, but in a dedicated thread, and watch out for ERROR_NOTIFY_ENUM_DIR.

0
On

You may not be able to accomplish your detections that way, but here is a great tutorial that may help.

You might also check out the answer to this other question.