Exemple #1
0
 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;
 }
Exemple #2
0
        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);
                }
            }
        }
Exemple #3
0
        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
                );
        }
Exemple #6
0
        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;
            }
        }