private unsafe void ReadDirectoryChangesCallback(uint errorCode, uint numBytes, NativeOverlapped* overlappedPointer)
{
AsyncReadState state = (AsyncReadState)ThreadPoolBoundHandle.GetNativeOverlappedState(overlappedPointer);
try
{
if (IsHandleInvalid(state.DirectoryHandle))
return;
if (errorCode != 0)
{
// Inside a service the first completion status is false;
// need to monitor again.
const int ERROR_OPERATION_ABORTED = 995;
if (errorCode != ERROR_OPERATION_ABORTED)
{
OnError(new ErrorEventArgs(new Win32Exception((int)errorCode)));
EnableRaisingEvents = false;
}
return;
}
// Ignore any events that occurred before this "session",
// so we don't get changed or error events after we
// told FSW to stop. Even with this check, though, there's a small
// race condition, as immediately after we do the check, raising
// events could be disabled.
if (state.Session != Volatile.Read(ref _currentSession))
return;
if (numBytes == 0)
{
NotifyInternalBufferOverflowEvent();
}
else
{
ParseEventBufferAndNotifyForEach(state.Buffer);
}
}
finally
{
// Clean up state associated with this one iteration
state.ThreadPoolBinding.FreeNativeOverlapped(overlappedPointer);
// Then call Monitor again to either start the next iteration or
// clean up the whole operation.
Monitor(state);
}
}