/// <summary> /// Recursive addition of tree nodes foreach child of current item in the storage /// </summary> /// <param name="node">Current TreeNode</param> /// <param name="cfs">Current storage associated with node</param> private void AddNodes(TreeNode node, CFStorage cfs) { VisitedEntryAction va = delegate(CFItem target) { TreeNode temp = node.Nodes.Add( target.Name, target.Name + (target.IsStream ? " (" + target.Size + " bytes )" : "") ); temp.Tag = target; if (target.IsStream) { //Stream temp.ImageIndex = 1; temp.SelectedImageIndex = 1; } else { //Storage temp.ImageIndex = 0; temp.SelectedImageIndex = 0; //Recursion into the storage AddNodes(temp, (CFStorage)target); } }; //Visit NON-recursively (first level only) cfs.VisitEntries(va, false); }
/// <summary> /// Returns the complete tree with all the <see cref="CFStorage"/> and <see cref="CFStream"/> children /// </summary> /// <param name="rootStorage"></param> /// <param name="storage"></param> private static void GetStorageChain(CFStorage rootStorage, CFStorage storage) { Logger.WriteToLog("Copying storage to compound file"); void Entries(CFItem item) { if (item.IsStorage) { var newRootStorage = rootStorage.AddStorage(item.Name); GetStorageChain(newRootStorage, item as CFStorage); } else if (item.IsStream) { var childStream = item as CFStream; if (childStream == null) { return; } var stream = rootStorage.AddStream(item.Name); var bytes = childStream.GetData(); stream.SetData(bytes); } } storage.VisitEntries(Entries, false); }
private void HandleFile(FileStream fs, string fileName) { var type = GetApplicationName(fileName); using (var cf = new CompoundFile(fs, CFSUpdateMode.Update, CFSConfiguration.SectorRecycle | CFSConfiguration.NoValidationException | CFSConfiguration.EraseFreeSectors)) { CFStorage storage = cf.RootStorage; int numDeleted = 0; Action <CFItem> va = delegate(CFItem target) { bool doFilter = ContainsPattern(storage, target.Name); bool canFilter = !"DestList".Equals(target.Name); if (doFilter) { if (canFilter) { Logger.Debug($"Deleting {target.Name} from {fileName} {type}"); storage.Delete(target.Name); numDeleted++; } else { Logger.Debug($"Found but skipping {target.Name} from {fileName}"); } } }; storage.VisitEntries(va, false); if (numDeleted > 0) { cf.Commit(); Logger.Debug($"Modifying {fileName}, deleted {numDeleted} entries"); } } }
static void DeleteStorageChildren(CFStorage target) { target.VisitEntries(i => { if (i.IsStorage) { DeleteStorageChildren((CFStorage)i); } target.Delete(i.Name); }, false); }
public static List <CFNode> ExploreStorage(CFStorage storage, string path) { List <CFNode> listCFItems = new List <CFNode>(); storage.VisitEntries(delegate(CFItem item) { CFUtil.AddItemToList(item, path, listCFItems); }, false); return(listCFItems); }
public VPXFile(string filename) { _cf = new CompoundFile(filename, CFSUpdateMode.ReadOnly, CFSConfiguration.Default); CFStorage gameStg = _cf.RootStorage.GetStorage("GameStg"); UInt32 version = new VPXReader(gameStg.GetStream("Version")).ReadUInt32(); void visitor(CFItem item) { if (item.Name.StartsWith("Image") && item is CFStream stream) { ReadImage(stream, true); } } gameStg.VisitEntries(visitor, true); }
private void CopyStorage(CFStorage source, CFStorage dest) { source.VisitEntries(i => { if (i.IsStorage) { CopyStorage((CFStorage)i, dest.AddStorage(i.Name)); } else if (i.IsStream) { var newStream = dest.AddStream(i.Name); var currStream = (CFStream)i; newStream.SetData(currStream.GetData()); } }, false); }
static void CopyCfStreamsExcept(CFStorage src, CFStorage dest, string excludeName) { src.VisitEntries(i => { if (i.Name?.Equals(excludeName, StringComparison.InvariantCultureIgnoreCase) ?? false) { return; } if (i.IsStorage) { dest.AddStorage(i.Name); CopyCfStreamsExcept((CFStorage)i, dest.GetStorage(i.Name), null); } else { dest.AddStream(i.Name); dest.GetStream(i.Name).SetData(((CFStream)i).GetData()); } }, false); }
/// <summary> /// Processes sub streams and storage on the specified storage. /// </summary> /// <param name="storage"> The storage to get sub streams and storage for. </param> protected virtual void LoadStorage(CFStorage storage) { if (storage == null) { return; } _rootStorage = storage; storage.VisitEntries(cfItem => { if (cfItem.IsStorage) { _subStorageStatistics.Add(cfItem.Name, cfItem as CFStorage); } else { _streamStatistics.Add(cfItem.Name, cfItem as CFStream); } }, false); }
private static void AddNodes(String depth, CFStorage cfs) { Action <CFItem> va = delegate(CFItem target) { String temp = target.Name + (target is CFStorage ? "" : " (" + target.Size + " bytes )"); //Stream Console.WriteLine(depth + temp); if (target is CFStorage) { //Storage String newDepth = depth + " "; //Recursion into the storage AddNodes(newDepth, (CFStorage)target); } }; //Visit NON-recursively (first level only) cfs.VisitEntries(va, false); }
protected static void Visit(CFItem item) { Console.WriteLine(String.Format("Item: {0}. Is Storage: {1}. Is Stream: {2}", item.Name, item.IsStorage, item.IsStream)); if (item.IsStorage) { CFStorage storage = (CFStorage)item; Console.WriteLine("Visiting Children of storage " + storage.Name); storage.VisitEntries(Visit, false); } if (item.IsStream && item.Name == "ThisWorkbook") { Console.WriteLine("Parsing ThisWorkbook"); CFStream stream = (CFStream)item; byte[] data = stream.GetData(); File.WriteAllBytes("ThisWorkbook.bin", data); } }
/// <summary> /// Copies the given <paramref name="source"/> to the given <paramref name="destination"/> /// </summary> /// <param name="source"></param> /// <param name="destination"></param> public static void Copy(CFStorage source, CFStorage destination) { source.VisitEntries(action => { if (action.IsStorage) { var destionationStorage = destination.AddStorage(action.Name); destionationStorage.CLSID = action.CLSID; destionationStorage.CreationDate = action.CreationDate; destionationStorage.ModifyDate = action.ModifyDate; Copy(action as CFStorage, destionationStorage); } else { var sourceStream = action as CFStream; var destinationStream = destination.AddStream(action.Name); if (sourceStream != null) { destinationStream.SetData(sourceStream.GetData()); } } }, false); }
/// <summary> /// Returns the complete tree with all the <see cref="CFStorage"/> and <see cref="CFStream"/> children /// </summary> /// <param name="rootStorage"></param> /// <param name="storage"></param> private static void GetStorageChain(CFStorage rootStorage, CFStorage storage) { Action <CFItem> entries = item => { if (item.IsStorage) { var newRootStorage = rootStorage.AddStorage(item.Name); GetStorageChain(newRootStorage, item as CFStorage); } else if (item.IsStream) { var childStream = item as CFStream; if (childStream == null) { return; } var stream = rootStorage.AddStream(item.Name); var bytes = childStream.GetData(); stream.SetData(bytes); } }; storage.VisitEntries(entries, false); }
protected virtual void LoadStorage(CFStorage storage) { _storage = storage; _keys = new List <string>(); _storage.VisitEntries(i => _keys.Add(i.Name), false); }
private static bool CfStoragesAreDifferent(CFStorage s1, CFStorage s2, out string explain) { var s1Names = new List <Tuple <string, bool> >(); var s2Names = new List <Tuple <string, bool> >(); s1.VisitEntries(i => s1Names.Add(Tuple.Create(i.Name, i.IsStorage)), false); s2.VisitEntries(i => s2Names.Add(Tuple.Create(i.Name, i.IsStorage)), false); s1Names.Sort(); s2Names.Sort(); if (!s1Names.SequenceEqual(s2Names)) { explain = string.Format(VBASyncResources.ExplainFrxDifferentFileLists, s1.Name, string.Join("', '", s1Names.Select(t => t.Item1)), string.Join("', '", s2Names.Select(t => t.Item1))); return(true); } FormControl fc1 = null; FormControl fc2 = null; foreach (var t in s1Names) { if (t.Item2) { if (CfStoragesAreDifferent(s1.GetStorage(t.Item1), s2.GetStorage(t.Item1), out explain)) { return(true); } } else if (t.Item1 == "f") { fc1 = new FormControl(s1.GetStream("f").GetData()); fc2 = new FormControl(s2.GetStream("f").GetData()); if (!fc1.Equals(fc2)) { explain = string.Format(VBASyncResources.ExplainFrxGeneralStreamDifference, "f", s1.Name); return(true); } } else if (t.Item1 == "o" && fc1 != null && fc2 != null) { var fc2SitesList = fc2.Sites.ToList(); var o1Controls = DecomposeOStream(fc1.Sites, s1.GetStream("o").GetData()); var o2Controls = DecomposeOStream(fc2.Sites, s2.GetStream("o").GetData()); for (var siteIdx1 = 0; siteIdx1 < fc1.Sites.Length; ++siteIdx1) { var siteIdx2 = fc2SitesList.FindIndex(s => s.Id == fc1.Sites[siteIdx1].Id); if (!Equals(o1Controls[siteIdx1], o2Controls[siteIdx2])) { explain = string.Format(VBASyncResources.ExplainFrxOStreamDifference, fc1.Sites[siteIdx1].Name, s1.Name); return(true); } } } else if (!s1.GetStream(t.Item1).GetData().SequenceEqual(s2.GetStream(t.Item1).GetData())) { explain = string.Format(VBASyncResources.ExplainFrxGeneralStreamDifference, t.Item1, s1.Name); return(true); } } explain = "No differences found."; return(false); }
static bool CfStoragesAreDifferent(CFStorage s1, CFStorage s2, out string explain) { var s1Names = new List <Tuple <string, bool> >(); var s2Names = new List <Tuple <string, bool> >(); s1.VisitEntries(i => s1Names.Add(Tuple.Create(i.Name, i.IsStorage)), false); s2.VisitEntries(i => s2Names.Add(Tuple.Create(i.Name, i.IsStorage)), false); s1Names.Sort(); s2Names.Sort(); if (!s1Names.SequenceEqual(s2Names)) { explain = $"Different file lists in storage '{s1.Name}'.\r\nFile 1: {{'{string.Join("', '", s1Names)}'}}\r\nFile 2: {{'{string.Join("'', '", s2Names)}'}}."; return(true); } FormControl fc1 = null; foreach (var t in s1Names) { if (t.Item2) { if (CfStoragesAreDifferent(s1.GetStorage(t.Item1), s2.GetStorage(t.Item1), out explain)) { return(true); } } else if (t.Item1 == "f") { fc1 = new FormControl(s1.GetStream("f").GetData()); var fc2 = new FormControl(s2.GetStream("f").GetData()); if (!fc1.Equals(fc2)) { explain = $"Different contents of stream 'f' in storage '{s1.Name}'."; return(true); } } else if (t.Item1 == "o" && fc1 != null) { var o1 = s1.GetStream("o").GetData(); var o2 = s2.GetStream("o").GetData(); uint idx = 0; foreach (var site in fc1.Sites) { explain = $"Different contents of stream 'o', site '{site.Name}' in storage '{s1.Name}'."; var o1Range = o1.Range(idx, site.ObjectStreamSize); var o2Range = o2.Range(idx, site.ObjectStreamSize); switch (site.ClsidCacheIndex) { case 15: // MorphData case 26: // CheckBox case 25: // ComboBox case 24: // ListBox case 27: // OptionButton case 23: // TextBox case 28: // ToggleButton if (!new MorphDataControl(o1Range).Equals(new MorphDataControl(o2Range))) { return(true); } break; case 17: // CommandButton if (!new CommandButtonControl(o1Range).Equals(new CommandButtonControl(o2Range))) { return(true); } break; case 21: // Label if (!new LabelControl(o1Range).Equals(new LabelControl(o2Range))) { return(true); } break; default: if (!o1Range.SequenceEqual(o2Range)) { return(true); } break; } idx += site.ObjectStreamSize; } } else if (!s1.GetStream(t.Item1).GetData().SequenceEqual(s2.GetStream(t.Item1).GetData())) { explain = $"Different contents of stream '{t.Item1}' in storage '{s1.Name}'."; return(true); } } explain = "No differences found."; return(false); }
private static bool CfStoragesAreDifferent(CFStorage s1, CFStorage s2, out string explain) { var s1Names = new List <Tuple <string, bool> >(); var s2Names = new List <Tuple <string, bool> >(); s1.VisitEntries(i => s1Names.Add(Tuple.Create(i.Name, i.IsStorage)), false); s2.VisitEntries(i => s2Names.Add(Tuple.Create(i.Name, i.IsStorage)), false); s1Names.Sort(); s2Names.Sort(); if (!s1Names.SequenceEqual(s2Names)) { explain = string.Format(VBASyncResources.ExplainFrxDifferentFileLists, s1.Name, string.Join("', '", s1Names.Select(t => t.Item1)), string.Join("', '", s2Names.Select(t => t.Item1))); return(true); } FormControl fc1 = null; foreach (var t in s1Names) { if (t.Item2) { if (CfStoragesAreDifferent(s1.GetStorage(t.Item1), s2.GetStorage(t.Item1), out explain)) { return(true); } } else if (t.Item1 == "f") { fc1 = new FormControl(s1.GetStream("f").GetData()); var fc2 = new FormControl(s2.GetStream("f").GetData()); if (!fc1.Equals(fc2)) { explain = string.Format(VBASyncResources.ExplainFrxGeneralStreamDifference, "f", s1.Name); return(true); } } else if (t.Item1 == "o" && fc1 != null) { var o1 = s1.GetStream("o").GetData(); var o2 = s2.GetStream("o").GetData(); uint idx = 0; foreach (var site in fc1.Sites) { explain = string.Format(VBASyncResources.ExplainFrxOStreamDifference, site.Name, s1.Name); var o1Range = o1.Range(idx, site.ObjectStreamSize); var o2Range = o2.Range(idx, site.ObjectStreamSize); switch (site.ClsidCacheIndex) { case 15: // MorphData case 26: // CheckBox case 25: // ComboBox case 24: // ListBox case 27: // OptionButton case 23: // TextBox case 28: // ToggleButton if (!new MorphDataControl(o1Range).Equals(new MorphDataControl(o2Range))) { return(true); } break; case 17: // CommandButton if (!new CommandButtonControl(o1Range).Equals(new CommandButtonControl(o2Range))) { return(true); } break; case 18: // TabStrip if (!new TabStripControl(o1Range).Equals(new TabStripControl(o2Range))) { return(true); } break; case 21: // Label if (!new LabelControl(o1Range).Equals(new LabelControl(o2Range))) { return(true); } break; default: if (!o1Range.SequenceEqual(o2Range)) { return(true); } break; } idx += site.ObjectStreamSize; } } else if (!s1.GetStream(t.Item1).GetData().SequenceEqual(s2.GetStream(t.Item1).GetData())) { explain = string.Format(VBASyncResources.ExplainFrxGeneralStreamDifference, t.Item1, s1.Name); return(true); } } explain = "No differences found."; return(false); }