I'm puzzled with the strange behavior of ReadDirectoryChangesW failing with error 995. Scenario explained below.
FileHandle was obtained using CreateFileW.
FileHandle obtained in step1 was used in ReadDirectoryChangesW. It success and sends the request to server
Poll for 10 seconds and if no change notify was generated by server, cancel the chnagenotify request using cancelIo. It sends cancel & server responds.
Now again setting change notify with ReadDirectoryChangesW using the file handle obtained in step1, it fails with "995 - The I/O operation has been aborted because of either a thread exit or an application request." No actual request was sent to server by this step.
Immediately again call ReadDirectoryChangesW using the file handle obtained in step1 & it succeeds and sends request to server.
steps 3,4,5 are repeated in a loop & every alternate ReadDirectoryChangesW fails with 995 and immediate next one succeeds.
Can anyone tell me whats going on ? Below is the Code
void setnotify(WCHAR* _path)
{
OVERLAPPED _overlapped;
HANDLE _handle;
char _buffer[8192] = {0};
DWORD _bufferSize = 8192;
CnState _state = CN_READY;
DWORD _inactivityTime = 0;
typedef enum State
{
CN_READY,
CN_REQUEST_PENDING,
CN_RESPONSE_RECEIVED,
CN_REQUEST_CANCELLED
} CnState;
_handle = CreateFileW(_path,
GENERIC_READ, // access
FILE_SHARE_READ |
FILE_SHARE_WRITE |
FILE_SHARE_DELETE, // share
NULL, // sec
OPEN_EXISTING, // disp
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, // flags
0);
if (_handle == INVALID_HANDLE_VALUE)
{
exit(-1);
}
memset(&_overlapped, 0, sizeof(OVERLAPPED));
if (!ReadDirectoryChangesW(_handle,
_buffer,
_bufferSize,
true,
0x255,
NULL,
&_overlapped,
NULL)) {
exit(-1);
} else {
_state = CN_REQUEST_PENDING;
wprintf(L"Sent Change notify to Server\n");
}
while (1)
{
if ((_state == CN_REQUEST_PENDING) && (HasOverlappedIoCompleted(&_overlapped))) {
wprintf(L"Response Received from Server\n");
_state = CN_RESPONSE_RECEIVED;
}
if ((_state == CN_RESPONSE_RECEIVED) || (_state == CN_REQUEST_CANCELLED)) {
memset(&_overlapped, 0, sizeof(OVERLAPPED));
_inactivityTime = 0;
if (!ReadDirectoryChangesW(_handle,
_buffer,
_bufferSize,
true,
255,
NULL,
&_overlapped,
NULL)) {
wprintf(L"Sent Change notify to Server Failed.\n");
} else {
wprintf(L"Sent Change notify to Server\n");
_state = CN_REQUEST_PENDING;
}
}
if ((_state == ChangeNotifyRequest::CN_REQUEST_PENDING) &&
(_inactivityTime >= 5000)){
if (CancelIo(_handle)) {
_state = CN_REQUEST_CANCELLED;
wprintf(L"Cancelled Pending Requests.\n");
} else {
wprintf(L"Cancelled failed");
}
}
Sleep(50);
_inactivityTime += 50;
}
}
Below is the Sample O/P:
Sent Change notify to Server
Cancelled Pending Requests.
Sent Change notify to Server
Cancelled Pending Requests.
Sent Change notify to Server Failed.
Sent Change notify to Server
Cancelled Pending Requests.
Sent Change notify to Server Failed.
Sent Change notify to Server
Cancelled Pending Requests.
Sent Change notify to Server Failed.
Sent Change notify to Server