예제 #1
0
 /// <summary>
 /// Performs the actual comparison.
 /// </summary>
 /// <param name="Style">Comparison style to be used</param>
 /// <param name="Force">If True, will clear any existing results and perform a fresh comparison.  If False, will not compare again if a comparison has already been performed.  Defaults to False.</param>
 public void DoCompare(ComparisonStyle Style, bool Force = false)
 {
     if (!HaveCompared || Force)
     {
         Files.Clear();
         Files = Compare(String.Empty, SourceA, SourceB, Recursive, Style);
     }
     HaveCompared = true;
 }
        /// <summary>
        /// Construct an EntryComparer to compare entries using the provided
        /// <b>IComparer</b> object according to the specified comparison
        /// style.
        /// </summary>
        /// <remarks>
        /// If the style is <b>ComparisonStyle.Auto</b> then the comparator
        /// type is checked: if the comparer is an instance of the
        /// <see cref="KeyExtractor"/>, <b>ComparisonStyle.Key</b> style will
        /// be assumed; otherwise, the <b>ComparisonStyle.Value</b> style is used.
        /// </remarks>
        /// <param name="comparer">
        /// The comparer to use; if not specified the "natural" comparison is
        /// used.
        /// </param>
        /// <param name="style">
        /// The comparison style to use; valid values are any of the
        /// <see cref="ComparisonStyle"/> values.
        /// </param>
        public EntryComparer(IComparer comparer, ComparisonStyle style) : base(comparer)
        {
            switch (style)
            {
            case ComparisonStyle.Auto:
                style = (comparer != null && IsKeyComparer(comparer)) ? ComparisonStyle.Key : ComparisonStyle.Value;
                break;

            case ComparisonStyle.Value:
            case ComparisonStyle.Key:
            case ComparisonStyle.Entry:
                break;

            default:
                throw new ArgumentException("Invalid comparison style: " + style);
            }

            m_style = style;
        }
예제 #3
0
파일: DiffVHD.cs 프로젝트: virmitio/DiffVHD
        //        private static WellKnownPartitionType GetPartitionType(PartitionInfo Partition)
        //        {
        //            switch (Partition.BiosType)
        //            {
        //                case BiosPartitionTypes.Fat16:
        //                case BiosPartitionTypes.Fat32:
        //                case BiosPartitionTypes.Fat32Lba:
        //                    return WellKnownPartitionType.WindowsFat;
        //                case BiosPartitionTypes.Ntfs:
        //                    return WellKnownPartitionType.WindowsNtfs;
        //                case BiosPartitionTypes.LinuxNative:
        //                    return WellKnownPartitionType.Linux;
        //                case BiosPartitionTypes.LinuxSwap:
        //                    return WellKnownPartitionType.LinuxSwap;
        //                case BiosPartitionTypes.LinuxLvm:
        //                    return WellKnownPartitionType.LinuxLvm;
        //                default:
        //                    throw new ArgumentException(
        //                        String.Format("Unsupported partition type: '{0}'", BiosPartitionTypes.ToString(Partition.BiosType)), "Partition");
        //            }
        //        }
        //
        //        private static DiscFileSystem DetectFileSystem(PartitionInfo Partition)
        //        {
        //            using (var stream = Partition.Open())
        //            {
        //                if (NtfsFileSystem.Detect(stream))
        //                    return new NtfsFileSystem(Partition.Open());
        //                stream.Seek(0, SeekOrigin.Begin);
        //                if (FatFileSystem.Detect(stream))
        //                    return new FatFileSystem(Partition.Open());
        //
        //                /* Ext2/3/4 file system - when Ext becomes fully writable
        //                
        //                stream.Seek(0, SeekOrigin.Begin);
        //                if (ExtFileSystem.Detect(stream))
        //                    return new ExtFileSystem(Partition.Open());
        //                */
        //
        //                return null;
        //            }
        //        }
        private static void DiffPart(DiscFileSystem PartA, DiscFileSystem PartB, DiscFileSystem Output, ComparisonStyle Style = ComparisonStyle.DateTimeOnly, CopyQueue WriteQueue = null)
        {
            if (PartA == null) throw new ArgumentNullException("PartA");
            if (PartB == null) throw new ArgumentNullException("PartB");
            if (Output == null) throw new ArgumentNullException("Output");

            if (PartA is NtfsFileSystem)
            {
                ((NtfsFileSystem) PartA).NtfsOptions.HideHiddenFiles = false;
                ((NtfsFileSystem) PartA).NtfsOptions.HideSystemFiles = false;
            }
            if (PartB is NtfsFileSystem)
            {
                ((NtfsFileSystem) PartB).NtfsOptions.HideHiddenFiles = false;
                ((NtfsFileSystem) PartB).NtfsOptions.HideSystemFiles = false;
            }
            if (Output is NtfsFileSystem)
            {
                ((NtfsFileSystem) Output).NtfsOptions.HideHiddenFiles = false;
                ((NtfsFileSystem) Output).NtfsOptions.HideSystemFiles = false;
            }

            if (WriteQueue == null) WriteQueue = new CopyQueue();

            var RootA = PartA.Root;
            var RootB = PartB.Root;
            var OutRoot = Output.Root;
            var OutFileRoot = Output.GetDirectoryInfo(RootFiles);
            if (!OutFileRoot.Exists) OutFileRoot.Create();

            CompareTree(RootA, RootB, OutFileRoot, WriteQueue, Style);

            WriteQueue.Go();

            // Now handle registry files (if any)
            ParallelQuery<DiscFileInfo> Ofiles;
            lock(OutFileRoot.FileSystem)
                Ofiles = OutFileRoot.GetFiles("*.*", SearchOption.AllDirectories).AsParallel();
            Ofiles = Ofiles.Where(dfi =>
                                    SystemRegistryFiles.Contains(dfi.FullName, StringComparer.CurrentCultureIgnoreCase));

            foreach (var file in Ofiles)
            {
                var A = PartA.GetFileInfo(file.FullName.Substring(RootFiles.Length + 1));
                if (!A.Exists)
                {
                    file.FileSystem.MoveFile(file.FullName, String.Concat(RootSystemRegistry, A.FullName));
                    continue;
                }
                //else
                MemoryStream SideA = new MemoryStream();
                using (var tmp = A.OpenRead()) tmp.CopyTo(SideA);
                MemoryStream SideB = new MemoryStream();
                using (var tmp = file.OpenRead()) tmp.CopyTo(SideB);
                var comp = new RegistryComparison(SideA, SideB, RegistryComparison.Side.B);
                comp.DoCompare();
                var diff = new RegDiff(comp, RegistryComparison.Side.B);
                var outFile = Output.GetFileInfo(Path.Combine(RootSystemRegistry, file.FullName));
                if (!outFile.Directory.Exists)
                {
                    outFile.Directory.Create();
                }
                using (var OUT = outFile.Open(outFile.Exists ? FileMode.Truncate : FileMode.CreateNew, FileAccess.ReadWrite))
                    diff.WriteToStream(OUT);
                file.Delete(); // remove this file from the set of file to copy and overwrite
            }

            lock (OutFileRoot.FileSystem)
                Ofiles = OutFileRoot.GetFiles("*.*", SearchOption.AllDirectories).AsParallel();
            Ofiles = Ofiles.Where(dfi => UserRegisrtyFiles.IsMatch(dfi.FullName));

            foreach (var file in Ofiles)
            {
                var match = UserRegisrtyFiles.Match(file.FullName);
                var A = PartA.GetFileInfo(file.FullName.Substring(RootFiles.Length + 1));
                if (!A.Exists)
                {
                    file.FileSystem.MoveFile(file.FullName,
                                                Path.Combine(RootUserRegistry, match.Groups["user"].Value, A.Name));
                    continue;
                }
                //else
                MemoryStream SideA = new MemoryStream();
                using (var tmp = A.OpenRead()) tmp.CopyTo(SideA);
                MemoryStream SideB = new MemoryStream();
                using (var tmp = file.OpenRead()) tmp.CopyTo(SideB);
                var comp = new RegistryComparison(SideA, SideB, RegistryComparison.Side.B);
                comp.DoCompare();
                var diff = new RegDiff(comp, RegistryComparison.Side.B);
                var outFile =
                    Output.GetFileInfo(Path.Combine(RootUserRegistry, match.Groups["user"].Value, file.FullName));
                if (!outFile.Directory.Exists)
                {
                    outFile.Directory.Create();
                }
                using (var OUT = outFile.Open(outFile.Exists ? FileMode.Truncate : FileMode.CreateNew, FileAccess.ReadWrite))
                    diff.WriteToStream(OUT);
                file.Delete(); // remove this file from the set of file to copy and overwrite
            }
        }
예제 #4
0
파일: DiffVHD.cs 프로젝트: virmitio/DiffVHD
        private static Task CompTree(DiscDirectoryInfo A, DiscDirectoryInfo B, DiscDirectoryInfo Out,
            CopyQueue WriteQueue, ComparisonStyle Style = ComparisonStyle.DateTimeOnly)
        {
            if (WriteQueue == null) throw new ArgumentNullException("WriteQueue");
            List<Task> tasks = new List<Task>();

            DiscFileSystem Alock = A.FileSystem;
            DiscFileSystem Block = B.FileSystem;
            DiscFileSystem Olock = Out.FileSystem;

            ParallelQuery<DiscFileInfo> BFiles;
            lock(Block)
                BFiles = B.GetFiles("*.*", SearchOption.AllDirectories).ToArray().AsParallel();
            BFiles = BFiles.Where(file =>
                                  !ExcludeFiles.Contains(file.FullName.ToUpperInvariant())
                                 ).AsParallel();
            BFiles = ExclusionRules.Aggregate(BFiles, (current, rule) => current.Where(file => !rule.IsMatch(file.FullName)));

                BFiles = BFiles.Where(file =>
                    {
                        DiscFileInfo Atmp;
                        lock (Alock)
                            Atmp = Alock.GetFileInfo(file.FullName);
                        return !CompareFile(Atmp, file, Style);
                    }).ToArray().AsParallel();

            foreach (var file in BFiles)
            {
                DiscFileInfo outFile;
                lock (Olock)
                    outFile = Out.FileSystem.GetFileInfo(Path.Combine(Out.FullName, file.FullName));
                lock (Alock)
                WriteQueue.Add(file, outFile, Alock.GetFileInfo(file.FullName));
            }

            return Task.Factory.StartNew(() => Task.WaitAll(tasks.ToArray()), TaskCreationOptions.AttachedToParent);
        }
예제 #5
0
파일: DiffVHD.cs 프로젝트: virmitio/DiffVHD
 private static void CompareTree(DiscDirectoryInfo A, DiscDirectoryInfo B, DiscDirectoryInfo Out,
     CopyQueue WriteQueue, ComparisonStyle Style = ComparisonStyle.DateTimeOnly)
 {
     CompTree(A, B, Out, WriteQueue, Style).Wait();
 }
예제 #6
0
파일: DiffVHD.cs 프로젝트: virmitio/DiffVHD
        /// <summary>
        /// 
        /// </summary>
        /// <param name="A"></param>
        /// <param name="B"></param>
        /// <param name="Style"></param>
        /// <returns>True if A and B are equivalent.</returns>
        private static bool CompareFile(DiscFileInfo A, DiscFileInfo B, ComparisonStyle Style = ComparisonStyle.DateTimeOnly)
        {
            if (A == null || B == null) return A == B;
            lock (A.FileSystem)
                lock (B.FileSystem)
                    if (!A.Exists || !B.Exists) return false;

            if (Style == ComparisonStyle.Journaled)
                if (A.FileSystem is NtfsFileSystem)
                {
                    lock(A.FileSystem)
                        lock (B.FileSystem)
                        {
                            var An = A.FileSystem as NtfsFileSystem;
                            var Bn = (NtfsFileSystem) (B.FileSystem);
                            long Aid = (long) (An.GetFileId(A.FullName) & 0x0000ffffffffffff);
                            long Bid = (long) (Bn.GetFileId(B.FullName) & 0x0000ffffffffffff);

                            return An.GetMasterFileTable()[Aid].LogFileSequenceNumber ==
                                   Bn.GetMasterFileTable()[Bid].LogFileSequenceNumber;
                        }
                }
                else throw new ArgumentException("Journal comparison only functions on NTFS partitions.", "Style");

            bool LenCheck, WriteCheck;
            lock (A.FileSystem)
                lock (B.FileSystem)
                {
                    LenCheck = A.Length == B.Length;
                    WriteCheck = A.LastWriteTimeUtc == B.LastWriteTimeUtc;
                }

            return LenCheck &&
                   (Style == ComparisonStyle.NameOnly || (Style == ComparisonStyle.BinaryOnly
                                                              ? FilesMatch(A, B)
                                                              : (WriteCheck &&
                                                                 (Style == ComparisonStyle.DateTimeOnly ||
                                                                  FilesMatch(A, B)))));
        }
예제 #7
0
파일: DiffVHD.cs 프로젝트: virmitio/DiffVHD
        /// <summary>
        /// 
        /// </summary>
        /// <param name="OldVHD"></param>
        /// <param name="NewVHD"></param>
        /// <param name="Output">Filename to the output file.  Method will fail if this already exists unless Force is passed as 'true'.</param>
        /// <param name="OutputType">A <see cref="DiskType"/> which specifies the output file format.</param>
        /// <param name="Force">If true, will overwrite the Output file if it already exists.  Defaults to 'false'.</param>
        /// <param name="Partition">An int tuple which declares a specific pair of partitions to compare.  The first value in the tuple will be the 0-indexed partition number from OldVHD to compare against.  The second value of the tuple will be the 0-indexed parition from NewVHD to compare with.</param>
        /// <param name="Style">The <see cref="DiffVHD.ComparisonStyle"/> to be used when comparing individual files.</param>
        /// <param name="AsBinary">If true, the resultant diff will contain the complete binary file from the child for each file found to be different.  Default is to only do this for non-text files and record a textual diff instead whenever possible.</param>
        /// <returns></returns>
        public static void CreateDiff(string OldVHD, string NewVHD, string Output, DiskType OutputType = DiskType.VHD, bool Force = false, Tuple<int, int> Partition = null, ComparisonStyle Style = ComparisonStyle.DateTimeOnly, bool AsBinary = false)
        {
            if (File.Exists(Output) && !Force) throw new ArgumentException("Output file already exists.", "Output");
            if (!File.Exists(OldVHD)) throw new ArgumentException("Input file does not exist.", "OldVHD");
            if (!File.Exists(NewVHD)) throw new ArgumentException("Input file does not exist.", "NewVHD");

            // byte[] CopyBuffer = new byte[1024*1024];
            VirtualDisk Old, New, Out;
            Old = VirtualDisk.OpenDisk(OldVHD, FileAccess.Read);
            New = VirtualDisk.OpenDisk(NewVHD, FileAccess.Read);

            using (Old)
            using (New)
            using (var OutFS = new FileStream(Output, Force ? FileMode.Create : FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None))
            {

                // Check type of filesystems being compared
                if (!Old.IsPartitioned) throw new ArgumentException("Input disk is not partitioned.", "OldVHD");
                if (!New.IsPartitioned) throw new ArgumentException("Input disk is not partitioned.", "NewVHD");

                long CapacityBuffer = 64 * Math.Max(Old.Geometry.BytesPerSector, New.Geometry.BytesPerSector); // starting with 64 sectors as a buffer for partition information in the output file
                long[] OutputCapacities = new long[Partition != null ? 1 : Old.Partitions.Count];

                if (Partition != null)
                {
                    var PartA = Old.Partitions[Partition.Item1];
                    var PartB = New.Partitions[Partition.Item2];
                    if (PartA.BiosType != PartB.BiosType)
                        throw new InvalidFileSystemException(
                            String.Format(
                                "Filesystem of partition {0} in '{1}' does not match filesystem type of partition {2} in '{3}'.",
                                Partition.Item2, NewVHD, Partition.Item1, OldVHD));
                    OutputCapacities[0] += Math.Max(PartA.SectorCount * Old.Geometry.BytesPerSector, PartB.SectorCount * New.Geometry.BytesPerSector);
                }
                else
                {
                    if (Old.Partitions.Count != New.Partitions.Count)
                        throw new ArgumentException(
                            "Input disks do not have the same number of partitions.  To compare specific partitions on mismatched disks, provide the 'Partition' parameter.");
                    for (int i = 0; i < Old.Partitions.Count; i++)
                        if (Old.Partitions[i].BiosType != New.Partitions[i].BiosType)
                            throw new InvalidFileSystemException(String.Format("Filesystem of partition {0} in '{1}' does not match filesystem type of partition {0} in '{2}'.", i, NewVHD, OldVHD));
                        else
                            OutputCapacities[i] = Math.Max(Old.Partitions[i].SectorCount * Old.Geometry.BytesPerSector, New.Partitions[i].SectorCount * New.Geometry.BytesPerSector);
                }

                long OutputCapacity = CapacityBuffer + OutputCapacities.Sum();

                using (Out = VHDBuilder.CreateDisk(OutputType, OutFS, OutputCapacity, New.BlockSize))
                {

                    var OutParts = Out.Partitions;

                    if (Partition != null)
                    {
                        OutParts.Create(VHDBuilder.GetPartitionType(Old.Partitions[Partition.Item1]), false); // there is no need (ever) for a VHD diff to have bootable partitions
                        var OutFileSystem = Out.FormatPartition(0);
                        DiffPart(VHDBuilder.DetectFileSystem(Old.Partitions[Partition.Item1]),
                                 VHDBuilder.DetectFileSystem(New.Partitions[Partition.Item2]),
                                 OutFileSystem,  // As we made the partition spen the entire drive, it should be the only partition
                                 Style, new CopyQueue(AsBinary));
                    }
                    else // Partition == null
                    {
                        for (int i = 0; i < Old.Partitions.Count; i++)
                        {
                            var partIndex = OutParts.Create(Math.Max(Old.Partitions[i].SectorCount * Old.Parameters.BiosGeometry.BytesPerSector,
                                                                     New.Partitions[i].SectorCount * New.Parameters.BiosGeometry.BytesPerSector),
                                                            VHDBuilder.GetPartitionType(Old.Partitions[i]), false);
                            var OutFileSystem = Out.FormatPartition(partIndex);

                            DiffPart(VHDBuilder.DetectFileSystem(Old.Partitions[i]),
                                     VHDBuilder.DetectFileSystem(New.Partitions[i]),
                                     OutFileSystem,
                                     Style, new CopyQueue(AsBinary));
                        }
                    }

                } // using (Out)

            } // using (Old, New, and OutFS)
        }
예제 #8
0
파일: DiffVHD.cs 프로젝트: virmitio/DiffVHD
 /// <summary>
 /// 
 /// </summary>
 /// <param name="OldVHD"></param>
 /// <param name="NewVHD"></param>
 /// <param name="Output">Filename to the output file.  Method will fail if this already exists unless Force is passed as 'true'.</param>
 /// <param name="OutputType">A <see cref="DiskType"/> which specifies the output file format.</param>
 /// <param name="Force">If true, will overwrite the Output file if it already exists.  Defaults to 'false'.</param>
 /// <param name="Partition">The 0-indexed partition number to compare from each disk file.</param>
 /// <param name="Style">The <see cref="DiffVHD.ComparisonStyle"/> to be used when comparing individual files.</param>
 /// <param name="AsBinary">If true, the resultant diff will contain the complete binary file from the child for each file found to be different.  Default is to only do this for non-text files and record a textual diff instead whenever possible.</param>
 /// <returns></returns>
 public static void CreateDiff(string OldVHD, string NewVHD, string Output, int? Partition, DiskType OutputType = DiskType.VHD, bool Force = false, ComparisonStyle Style = ComparisonStyle.DateTimeOnly, bool AsBinary = false)
 {
     CreateDiff(OldVHD, NewVHD, Output, OutputType, Force, Partition.HasValue ? new Tuple<int, int>(Partition.Value, Partition.Value) : null, Style: Style, AsBinary: AsBinary);
 }
예제 #9
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="OldVHD"></param>
        /// <param name="NewVHD"></param>
        /// <param name="Output">Filename to the output file.  Method will fail if this already exists unless Force is passed as 'true'.</param>
        /// <param name="OutputType">A <see cref="VMProvisioningAgent.DiffVHD.DiskType"/> which specifies the output file format.</param>
        /// <param name="Force">If true, will overwrite the Output file if it already exists.  Defaults to 'false'.</param>
        /// <param name="Partition">An int tuple which declares a specific pair of partitions to compare.  The first value in the tuple will be the 0-indexed partition number from OldVHD to compare against.  The second value of the tuple will be the 0-indexed parition from NewVHD to compare with.</param>
        /// <param name="Style"></param>
        /// <returns></returns>
        internal static void CreateDiff(string OldVHD, string NewVHD, string Output, DiskType OutputType = DiskType.VHD, bool Force = false, Tuple<int, int> Partition = null, ComparisonStyle Style = ComparisonStyle.DateTimeOnly)
        {
            if (File.Exists(Output) && !Force) throw new ArgumentException("Output file already exists.", "Output");
            if (!File.Exists(OldVHD)) throw new ArgumentException("Input file does not exist.", "OldVHD");
            if (!File.Exists(NewVHD)) throw new ArgumentException("Input file does not exist.", "NewVHD");

            // byte[] CopyBuffer = new byte[1024*1024];
            VirtualDisk Old, New, Out;
            Old = VirtualDisk.OpenDisk(OldVHD, FileAccess.Read);
            New = VirtualDisk.OpenDisk(NewVHD, FileAccess.Read);

            using (Old)
            using (New)
            using (var OutFS = new FileStream(Output, Force ? FileMode.Create : FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None))
            {

                // Check type of filesystems being compared
                if (!Old.IsPartitioned) throw new ArgumentException("Input disk is not partitioned.", "OldVHD");
                if (!New.IsPartitioned) throw new ArgumentException("Input disk is not partitioned.", "NewVHD");

                long CapacityBuffer = 64 * Math.Max(Old.Geometry.BytesPerSector, New.Geometry.BytesPerSector); // starting with 64 sectors as a buffer for partition information in the output file
                long[] OutputCapacities = new long[Partition != null ? 1 : Old.Partitions.Count];

                if (Partition != null)
                {
                    var PartA = Old.Partitions[Partition.Item1];
                    var PartB = New.Partitions[Partition.Item2];
                    if (PartA.BiosType != PartB.BiosType)
                        throw new InvalidFileSystemException(
                            String.Format(
                                "Filesystem of partition {0} in '{1}' does not match filesystem type of partition {2} in '{3}'.",
                                Partition.Item2, NewVHD, Partition.Item1, OldVHD));
                    OutputCapacities[0] += Math.Max(PartA.SectorCount * Old.Geometry.BytesPerSector, PartB.SectorCount * New.Geometry.BytesPerSector);
                }
                else
                {
                    if (Old.Partitions.Count != New.Partitions.Count)
                        throw new ArgumentException(
                            "Input disks do not have the same number of partitions.  To compare specific partitions on mismatched disks, provide the 'Partition' parameter.");
                    for (int i = 0; i < Old.Partitions.Count; i++)
                        if (Old.Partitions[i].BiosType != New.Partitions[i].BiosType)
                            throw new InvalidFileSystemException(String.Format("Filesystem of partition {0} in '{1}' does not match filesystem type of partition {0} in '{2}'.", i, NewVHD, OldVHD));
                        else
                            OutputCapacities[i] = Math.Max(Old.Partitions[i].SectorCount * Old.Geometry.BytesPerSector, New.Partitions[i].SectorCount * New.Geometry.BytesPerSector);
                }

                long OutputCapacity = CapacityBuffer + OutputCapacities.Sum();
                switch (OutputType)
                {
                    case DiskType.VHD:
                        Out = DiscUtils.Vhd.Disk.InitializeDynamic(OutFS, Ownership.None, OutputCapacity, Math.Max(New.BlockSize, 512 * 1024)); // the Max() is present only because there's currently a bug with blocksize < (8*sectorSize) in DiscUtils
                        break;
                    case DiskType.VHDX:
                        Out = DiscUtils.Vhdx.Disk.InitializeDynamic(OutFS, Ownership.None, OutputCapacity, Math.Max(New.BlockSize, 512 * 1024));
                        break;
                    default:
                        throw new NotSupportedException("The selected disk type is not supported at this time.",
                                                        new ArgumentException(
                                                            "Selected DiskType not currently supported.", "OutputType"));
                }

                using (Out)
                {

                    // set up the output location
                    if (Out is DiscUtils.Vhd.Disk) ((DiscUtils.Vhd.Disk) Out).AutoCommitFooter = false;
                    var OutParts = BiosPartitionTable.Initialize(Out);

                    if (Partition != null)
                    {
                        OutParts.Create(GetPartitionType(Old.Partitions[Partition.Item1]), false); // there is no need (ever) for a VHD diff to have bootable partitions
                        var OutFileSystem = Out.FormatPartition(0);
                        DiffPart(DetectFileSystem(Old.Partitions[Partition.Item1]),
                                 DetectFileSystem(New.Partitions[Partition.Item2]),
                                 OutFileSystem,  // As we made the partition spen the entire drive, it should be the only partition
                                 Style);
                    }
                    else // Partition == null
                    {
                        for (int i = 0; i < Old.Partitions.Count; i++)
                        {
                            var partIndex = OutParts.Create(Math.Max(Old.Partitions[i].SectorCount * Old.Parameters.BiosGeometry.BytesPerSector,
                                                                     New.Partitions[i].SectorCount * New.Parameters.BiosGeometry.BytesPerSector),
                                                            GetPartitionType(Old.Partitions[i]), false);
                            var OutFileSystem = Out.FormatPartition(partIndex);

                            DiffPart(DetectFileSystem(Old.Partitions[i]),
                                     DetectFileSystem(New.Partitions[i]),
                                     OutFileSystem,
                                     Style);
                        }
                    }

                } // using (Out)

            } // using (Old, New, and OutFS)
        }
예제 #10
0
        private static Dictionary<string, FileCondition> Compare(string root, string sideA, string sideB, bool recurse, ComparisonStyle style)
        {
            Dictionary<string, file> Working = new Dictionary<string, file>();

            // A-Side
            var AsideRoot = new DirectoryInfo(Path.Combine(sideA, root));
            var Afiles = AsideRoot.GetFiles("*", recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
            foreach (FileInfo A in Afiles)
            {
                var tmp = A.FullName.Substring(sideA.Length);
                if (tmp.IndexOf(Path.PathSeparator) == 0)
                    tmp = tmp.Substring(1);
                Working.Add(tmp, new file{sideA = A});
            }

            // B-Side
            var BsideRoot = new DirectoryInfo(Path.Combine(sideB, root));
            var Bfiles = BsideRoot.GetFiles("*", recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
            foreach (FileInfo B in Bfiles)
            {
                var tmp = B.FullName.Substring(sideB.Length);
                if (tmp.IndexOf(Path.PathSeparator) == 0)
                    tmp = tmp.Substring(1);
                if (Working.ContainsKey(tmp))
                {
                    file F = Working[tmp];
                    F.sideB = B;
                    Working[tmp] = F;
                }
                else
                {
                    Working.Add(tmp, new file {sideB = B});
                }
            }

            return Working.ToDictionary(item => item.Key, item => item.Value.sideB == null ? FileCondition.OnlyA : item.Value.sideA == null ? FileCondition.OnlyB
                                                                                           // Check ComparisonStyle
                                                                                           : style == ComparisonStyle.NameOnly ? (item.Value.sideA.Length != item.Value.sideB.Length ? FileCondition.Diff : FileCondition.Same)
                                                                                           : style == ComparisonStyle.BinaryOnly ? (item.Value.sideA.Length != item.Value.sideB.Length
                                                                                                                                                            ? FileCondition.Diff
                                                                                                                                                            : FilesMatch(item.Value.sideA, item.Value.sideB) ? FileCondition.Same
                                                                                                                                                                                                             : FileCondition.Diff)
                                                                                           : item.Value.sideA.LastWriteTimeUtc > item.Value.sideB.LastWriteTimeUtc ? FileCondition.NewerA
                                                                                           : item.Value.sideA.LastWriteTimeUtc < item.Value.sideB.LastWriteTimeUtc ? FileCondition.NewerB
                                                                                           : item.Value.sideA.Length != item.Value.sideB.Length ? FileCondition.Diff
                                                                                           : style == ComparisonStyle.DateTimeOnly ? FileCondition.Same
                                                                                           : FilesMatch(item.Value.sideA, item.Value.sideB) ? FileCondition.Same : FileCondition.Diff);
        }
예제 #11
0
 /// <summary>
 /// Performs the actual comparison.
 /// </summary>
 /// <param name="Style">Comparison style to be used</param>
 /// <param name="Force">If True, will clear any existing results and perform a fresh comparison.  If False, will not compare again if a comparison has already been performed.  Defaults to False.</param>
 public void DoCompare(ComparisonStyle Style, bool Force = false)
 {
     if (!HaveCompared || Force)
     {
         Files.Clear();
         Files = Compare(String.Empty, SourceA, SourceB, Recursive, Style);
     }
     HaveCompared = true;
 }
예제 #12
0
 public TableHelper(ComparisonStyle style)
 {
     this.style = style;
 }
예제 #13
0
        private static Dictionary <string, FileCondition> Compare(string root, string sideA, string sideB, bool recurse, ComparisonStyle style)
        {
            Dictionary <string, file> Working = new Dictionary <string, file>();

            // A-Side
            var AsideRoot = new DirectoryInfo(Path.Combine(sideA, root));
            var Afiles    = AsideRoot.GetFiles("*", recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);

            foreach (FileInfo A in Afiles)
            {
                var tmp = A.FullName.Substring(sideA.Length);
                if (tmp.IndexOf(Path.PathSeparator) == 0)
                {
                    tmp = tmp.Substring(1);
                }
                Working.Add(tmp, new file {
                    sideA = A
                });
            }

            // B-Side
            var BsideRoot = new DirectoryInfo(Path.Combine(sideB, root));
            var Bfiles    = BsideRoot.GetFiles("*", recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);

            foreach (FileInfo B in Bfiles)
            {
                var tmp = B.FullName.Substring(sideB.Length);
                if (tmp.IndexOf(Path.PathSeparator) == 0)
                {
                    tmp = tmp.Substring(1);
                }
                if (Working.ContainsKey(tmp))
                {
                    file F = Working[tmp];
                    F.sideB      = B;
                    Working[tmp] = F;
                }
                else
                {
                    Working.Add(tmp, new file {
                        sideB = B
                    });
                }
            }

            return(Working.ToDictionary(item => item.Key, item => item.Value.sideB == null ? FileCondition.OnlyA : item.Value.sideA == null ? FileCondition.OnlyB
                                        // Check ComparisonStyle
                                                                                           : style == ComparisonStyle.NameOnly ? (item.Value.sideA.Length != item.Value.sideB.Length ? FileCondition.Diff : FileCondition.Same)
                                                                                           : style == ComparisonStyle.BinaryOnly ? (item.Value.sideA.Length != item.Value.sideB.Length
                                                                                                                                                            ? FileCondition.Diff
                                                                                                                                                            : FilesMatch(item.Value.sideA, item.Value.sideB) ? FileCondition.Same
                                                                                                                                                                                                             : FileCondition.Diff)
                                                                                           : item.Value.sideA.LastWriteTimeUtc > item.Value.sideB.LastWriteTimeUtc ? FileCondition.NewerA
                                                                                           : item.Value.sideA.LastWriteTimeUtc < item.Value.sideB.LastWriteTimeUtc ? FileCondition.NewerB
                                                                                           : item.Value.sideA.Length != item.Value.sideB.Length ? FileCondition.Diff
                                                                                           : style == ComparisonStyle.DateTimeOnly ? FileCondition.Same
                                                                                           : FilesMatch(item.Value.sideA, item.Value.sideB) ? FileCondition.Same : FileCondition.Diff));
        }