// This function walks all watched files, collects changes, and updates state private FileChangeList ComputeChangesAndUpdateState() { _version++; var changes = new FileChangeList(); WIN32_FIND_DATAW fileData = new WIN32_FIND_DATAW(); unsafe { WIN32_FIND_DATAW* pFileData = &fileData; for(int index=0; index < _directories.Count; index++) { var directory = _directories[index]; var handle = DllImports.FindFirstFileExW(directory, FINDEX_INFO_LEVELS.FindExInfoBasic, pFileData, FINDEX_SEARCH_OPS.FindExSearchNameMatch, IntPtr.Zero, DllImports.FIND_FIRST_EX_LARGE_FETCH); if (handle == DllImports.INVALID_HANDLE_VALUE) { // directory got deleted if (Tracing.Switch.ShouldTrace(TraceEventType.Information)) { Tracing.TraceEvent(TraceEventType.Warning, 2, "Directory could not be opened {0}", directory); } _directories.Remove(directory); continue; } try { do { if (IsSpecial(fileData.cFileName)) continue; if (!IsWatched(fileData.cFileName)) continue; UpdateState(directory, ref changes, ref fileData, fileData.cFileName); } while (DllImports.FindNextFileW(handle, pFileData)); } finally { DllImports.FindClose(handle); } } } foreach (var value in _state) { if (value._version != _version) { changes.AddRemoved(value.Directory, value.Path); _state.Remove(value.Directory, value.Path); } } return changes; }
private unsafe void UpdateState(string directory, ref FileChangeList changes, ref WIN32_FIND_DATAW file, char* filename) { int index = _state.IndexOf(directory, filename); if (index == -1) // file added { string path = new string(filename); if (file.IsDirectory) { if (_includeSubdirectories) { _directories.Add(Path.Combine(directory.TrimEnd('*'), path, "*")); } } changes.AddAdded(directory, path); var newFileState = new FileState(directory, path); newFileState.LastWrite = file.LastWrite; newFileState.FileSize = file.FileSize; newFileState._version = _version; _state.Add(directory, path, newFileState); return; } _state.Values[index]._version = _version; if (file.IsDirectory) { return; } var previousState = _state.Values[index]; if (file.LastWrite != previousState.LastWrite || file.FileSize != previousState.FileSize) { changes.AddChanged(directory, previousState.Path); _state.Values[index].LastWrite = file.LastWrite; _state.Values[index].FileSize = file.FileSize; } }