public DiffData(DIFF_STATE state, string baseDir, Win32.FIND_DATA src, Win32.FIND_DATA trg) { this.state = state; this.baseDir = baseDir; this.src = src; this.trg = trg; }
public static IEnumerable <Spi.Native.Win32.FIND_DATA> EntriesEx(StringBuilder FullDirname, ErrorHandler errorHandler) { Win32.FIND_DATA find_data = new Win32.FIND_DATA(); FullDirname.Append("\\*"); IntPtr SearchHandle = IntPtr.Zero; try { SearchHandle = Win32.FindFirstFileEx( FullDirname.ToString() , Win32.FINDEX_INFO_LEVELS.FindExInfoBasic , ref find_data , Win32.FINDEX_SEARCH_OPS.FindExSearchNameMatch , IntPtr.Zero , Win32.FINDEX_ADDITIONAL_FLAGS.FIND_FIRST_EX_LARGE_FETCH); FullDirname.Length -= 2; if (SearchHandle == Win32.INVALID_HANDLE_VALUE) { int LastWinError = Marshal.GetLastWin32Error(); if (LastWinError == Win32.ERROR_PATH_NOT_FOUND || LastWinError == Win32.ERROR_DIRECTORY) { yield break; } else { errorHandler?.Invoke(LastWinError, "FindFirstFile, " + FullDirname); } } else { do { if (Spi.Misc.IsDotOrDotDotDirectory(find_data.cFileName)) { continue; } yield return(find_data); }while (Win32.FindNextFile_IntPtr(SearchHandle, ref find_data)); if (Marshal.GetLastWin32Error() != Win32.ERROR_NO_MORE_FILES) { errorHandler?.Invoke(Marshal.GetLastWin32Error(), "FindNextFile, " + FullDirname); } } } finally { if (SearchHandle != IntPtr.Zero) { Win32.FindClose_IntPtr(SearchHandle); } } }
private static bool FileAppearInMoreDirectories(Win32.FIND_DATA newFile, List <string> newDirs, Win32.FIND_DATA delFile, List <string> delDirs, TextWriter errWriter) { if (newDirs.Count == 1 && delDirs.Count == 1) { return(false); } WriteErrorWhenFileIsInMoreThanOneDirectory(newFile.cFileName, newDirs, "b", errWriter); WriteErrorWhenFileIsInMoreThanOneDirectory(delFile.cFileName, delDirs, "a", errWriter); return(true); }
private static void WriteModifyLine(TextWriter writer, ref Win32.FIND_DATA src, ref Win32.FIND_DATA trg, string FullFilename) { writer.WriteLine( "{0:X}|{1:X}" + "\t{2}|{3}" + "\t{4}|{5}" + "\t{6}" , src.dwFileAttributes , (trg.dwFileAttributes == src.dwFileAttributes ? "-" : trg.dwFileAttributes.ToString("X")) , ConvertFiletimeToString(src.ftLastWriteTime, FullFilename, "lastWriteTime") , CmpDirs.CmpFileTimes(src.ftLastWriteTime, trg.ftLastWriteTime) == 0 ? "-" : ConvertFiletimeToString(trg.ftLastWriteTime, FullFilename, "lastWriteTime") , src.FileSize , src.FileSize == trg.FileSize ? "-" : trg.FileSize.ToString() , FullFilename ); }
private static void WriteFindDataLine(TextWriter writer, ref Win32.FIND_DATA findData, string FullFilename) { uint attr = findData.dwFileAttributes; writer.WriteLine( "{0}{1}{2}{3}{4}\t{5:X}" // attributes (human \t machine) + "\t{6}\t{7}\t{8}" // create, access, modify (human) + "\t{9}\t{10}" // filesize, filename , (((attr & (uint)System.IO.FileAttributes.Archive) != 0) ? 'A' : '-') , (((attr & (uint)System.IO.FileAttributes.System) != 0) ? 'S' : '-') , (((attr & (uint)System.IO.FileAttributes.Hidden) != 0) ? 'H' : '-') , (((attr & (uint)System.IO.FileAttributes.ReadOnly) != 0) ? 'R' : '-') , (((attr & (uint)System.IO.FileAttributes.Directory) != 0) ? 'D' : '-') , attr , ConvertFiletimeToString(findData.ftCreationTime, FullFilename, "creationTime") , ConvertFiletimeToString(findData.ftLastAccessTime, FullFilename, "lastAccessTime") , ConvertFiletimeToString(findData.ftLastWriteTime, FullFilename, "lastWriteTime") , findData.FileSize , FullFilename ); }
public static int CompareFindData_Name_Size_Modified(Win32.FIND_DATA a, Win32.FIND_DATA b) { int cmp; if ((cmp = String.Compare(a.cFileName, b.cFileName)) != 0) { return(cmp); } //if ((cmp = Misc.CompareULongsToInt(a.FileSize, b.FileSize)) != 0) return cmp; if ((cmp = Comparer <ulong> .Default.Compare(a.FileSize, b.FileSize)) != 0) { return(cmp); } //if ((cmp = Misc.CmpFileTimes(a.ftCreationTime, b.ftCreationTime)) != 0) return cmp; if ((cmp = Misc.CmpFileTimes(a.ftLastWriteTime, b.ftLastWriteTime)) != 0) { return(cmp); } return(0); }
/// <summary> /// ATTENZIONE!!!! --- DANGER-ZONE --- MULTI-THREADING AHEAD!!! /// </summary> public void DiffCallback(DIFF_STATE state, string basedir, ref Win32.FIND_DATA find_data_src, ref Win32.FIND_DATA find_data_trg) { Win32.FIND_DATA?File_Data_ToUse; Win32.FIND_DATA?File_Data_NewDel; TextWriter toWriteTo; ProcessDiffState_UpdateCounters(state, ref find_data_src, ref find_data_trg, out toWriteTo, out File_Data_ToUse, out File_Data_NewDel); if (!_writeSameSame && state == DIFF_STATE.SAMESAME) { return; } if (toWriteTo == null) { return; } string filenameToPrint = (state == DIFF_STATE.NEW) ? find_data_src.cFileName : find_data_trg.cFileName; string FullFilename = Path.Combine(basedir, filenameToPrint); if (File_Data_ToUse.HasValue) { var findData = File_Data_ToUse.Value; if (state == DIFF_STATE.MODIFY) { WriteModifyLine(toWriteTo, ref find_data_src, ref find_data_trg, FullFilename); } else { WriteFindDataLine(toWriteTo, ref findData, FullFilename); } } else { toWriteTo.WriteLine($"{FullFilename}"); } }
private void ProcessDiffState_UpdateCounters(DIFF_STATE state, ref Win32.FIND_DATA find_data_src, ref Win32.FIND_DATA find_data_trg, out TextWriter toWriteTo, out Win32.FIND_DATA?File_Data_ToUse, out Win32.FIND_DATA?File_Data_NewDel) { File_Data_NewDel = null; switch (state) { default: throw new Exception($"internal error. no such writer for this kind of state. [{state.ToString()}]"); case DIFF_STATE.SAMESAME: if (!Spi.Misc.IsDirectory(find_data_src)) { Interlocked.Increment(ref _stats.FilesSame); Interlocked.Add(ref _stats.FilesSameBytes, (long)find_data_src.FileSize); toWriteTo = _writers.sameWriter; File_Data_ToUse = find_data_src; } else { toWriteTo = null; File_Data_ToUse = null; } break; case DIFF_STATE.NEW: if (Spi.Misc.IsDirectory(find_data_src)) { Interlocked.Increment(ref _stats.DirsNew); toWriteTo = _writers.newDirWriter; File_Data_ToUse = null; } else { Interlocked.Increment(ref _stats.FilesNew); Interlocked.Add(ref _stats.FilesNewBytes, (long)find_data_src.FileSize); toWriteTo = _writers.newWriter; File_Data_ToUse = find_data_src; File_Data_NewDel = find_data_src; } break; case DIFF_STATE.MODIFY: toWriteTo = _writers.modWriter; Interlocked.Increment(ref _stats.FilesMod); Interlocked.Add(ref _stats.FilesModBytes, (long)find_data_trg.FileSize - (long)find_data_src.FileSize); File_Data_ToUse = find_data_trg; break; case DIFF_STATE.DELETE: if (Spi.Misc.IsDirectory(find_data_trg)) { toWriteTo = _writers.delDirWriter; File_Data_ToUse = null; Interlocked.Increment(ref _stats.DirsDel); } else { toWriteTo = _writers.delWriter; Interlocked.Increment(ref _stats.FilesDel); Interlocked.Add(ref _stats.FilesDelBytes, (long)find_data_trg.FileSize); File_Data_ToUse = find_data_trg; File_Data_NewDel = find_data_trg; } break; } }