public void MoveQueueTo(CopyQueue other) { lock (this) while (_queue.Any()) { var item = _queue.First(); other.Add(item.Value.Source, item.Key, item.Value.Base); _queue.Remove(item.Key); } }
// 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 } }
private static void CompareTree(DiscDirectoryInfo A, DiscDirectoryInfo B, DiscDirectoryInfo Out, CopyQueue WriteQueue, ComparisonStyle Style = ComparisonStyle.DateTimeOnly) { CompTree(A, B, Out, WriteQueue, Style).Wait(); }
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); }
private static void ApplyPartDiff(PartitionInfo Base, PartitionInfo Diff) { CopyQueue queue = new CopyQueue(); var BFS = VHDBuilder.DetectFileSystem(Base); var DFS = VHDBuilder.DetectFileSystem(Diff); if (BFS is NtfsFileSystem) { ((NtfsFileSystem)BFS).NtfsOptions.HideHiddenFiles = false; ((NtfsFileSystem)BFS).NtfsOptions.HideSystemFiles = false; } if (DFS is NtfsFileSystem) { ((NtfsFileSystem)DFS).NtfsOptions.HideHiddenFiles = false; ((NtfsFileSystem)DFS).NtfsOptions.HideSystemFiles = false; } var DRoot = DFS.Root; var DFRoots = DRoot.GetDirectories(RootFiles); if (DFRoots.Any()) { var DFileRoot = DFRoots.Single(); foreach (var file in DFileRoot.GetFiles("*.*", SearchOption.AllDirectories)) { var BFile = BFS.GetFileInfo(file.FullName.Substring(RootFiles.Length + 1)); queue.Add(file, BFile); // TODO: fix this for applying diffs!!! } queue.Go(); } var DsysRegs = DRoot.GetDirectories(RootSystemRegistry); if (DsysRegs.Any()) { var DsysReg = DsysRegs.Single(); foreach (var file in DsysReg.GetFiles("*.*", SearchOption.AllDirectories)) { var BReg = BFS.GetFileInfo(file.FullName.Substring(RootSystemRegistry.Length + 1)); if (!BReg.Exists) queue.Add(file, BReg); else { var BHive = new RegistryHive(BReg.Open(FileMode.Open, FileAccess.ReadWrite)); RegDiff.ReadFromStream(file.OpenRead()).ApplyTo(BHive.Root); } } queue.Go(); } var DuserRegs = DRoot.GetDirectories(RootUserRegistry); if (DuserRegs.Any()) { var DuserReg = DuserRegs.Single(); var Bfiles = BFS.GetFiles(String.Empty, "*.*", SearchOption.AllDirectories) .Where(str => UserRegisrtyFiles.IsMatch(str)) .ToArray(); foreach (var file in DuserReg.GetFiles("*.*", SearchOption.AllDirectories)) { var username = DiffUserRegistry.Match(file.FullName).Groups["user"].Value; var userFile = Bfiles.Where(str => GetUserRegex(username).IsMatch(str)).ToArray(); if (!userFile.Any()) continue; var BReg = BFS.GetFileInfo(userFile.Single()); if (!BReg.Exists) continue; var BHive = new RegistryHive(BReg.Open(FileMode.Open, FileAccess.ReadWrite)); RegDiff.ReadFromStream(file.OpenRead()).ApplyTo(BHive.Root); } } }