private void BuildTables() { CompoundFileData.RedBlackTreeNode rootLevelTag = new CompoundFileData.RedBlackTreeNode { DirectoryEntry = this.ole2File.Root, LeftDID = -1, RightDID = -1, MembersDID = -1 }; this.nodes.Add(rootLevelTag); this.ole2File.Root.VisitAll(new VisitDirectoryEntryHandler(this.ProcessEntry), rootLevelTag); if (base.shortSectorAllocationTable.Count > 0) { base.shortTableSID = CreateChain(base.shortSectorAllocationTable.Count * 4, base.sectorAllocationTable, base.sectorSize); base.SSATSectorCount = base.sectorAllocationTable.Count - base.shortTableSID; base.shortStreamContainerSID = CreateChain((int)base.shortStreamContainer.Length, base.sectorAllocationTable, base.sectorSize); base.shortStreamContainerSize = (int)base.shortStreamContainer.Length; } else { base.shortTableSID = -2; base.SSATSectorCount = 0; base.shortStreamContainerSID = -2; base.shortStreamContainerSize = 0; } base.directoryStreamSID = CreateChain(this.nodes.Count * 128, base.sectorAllocationTable, base.sectorSize); this.BuildSATAndMAT(); }
private void ProcessEntry(VisitDirectoryEntryArgs args) { CompoundFileData.RedBlackTreeNode node = new CompoundFileData.RedBlackTreeNode { DirectoryEntry = args.CurrentEntry, LeftDID = -1, RightDID = -1, MembersDID = -1 }; int newNodeDID = this.nodes.Add(node); Ole2Stream currentEntry = args.CurrentEntry as Ole2Stream; if (currentEntry != null) { if (currentEntry.Size < base.shortThreshold) { currentEntry.WriteSID = CreateChain(currentEntry.Size, base.shortSectorAllocationTable, base.shortSectorSize); WriteOle2Stream(currentEntry, base.shortStreamContainer, base.shortSectorSize); } else { currentEntry.WriteSID = CreateChain(currentEntry.Size, base.sectorAllocationTable, base.sectorSize); } } else { args.LevelTags[args.Level] = node; } CompoundFileData.RedBlackTreeNode node2 = (RedBlackTreeNode)args.LevelTags[args.Level - 1]; this.InsertNodeToTree(ref node2.MembersDID, node.DirectoryEntry.Name, newNodeDID); }
private void WriteDirectoryNode(BinaryWriter bw, CompoundFileData.RedBlackTreeNode node) { CompoundFileData.DirectoryEntryType rootStorage; int shortStreamContainerSID; int shortStreamContainerSize; Ole2DirectoryEntry directoryEntry = node.DirectoryEntry; if (directoryEntry == this.ole2File.root) { rootStorage = CompoundFileData.DirectoryEntryType.RootStorage; shortStreamContainerSID = base.shortStreamContainerSID; shortStreamContainerSize = base.shortStreamContainerSize; } else if (directoryEntry is Ole2Storage) { rootStorage = CompoundFileData.DirectoryEntryType.UserStorage; shortStreamContainerSID = 0; shortStreamContainerSize = 0; } else { if (!(directoryEntry is Ole2Stream)) { throw new CompoundFileException("Internal error: unrecognized entry type."); } Ole2Stream stream = (Ole2Stream)node.DirectoryEntry; rootStorage = CompoundFileData.DirectoryEntryType.UserStream; shortStreamContainerSID = stream.WriteSID; shortStreamContainerSize = stream.Size; } string name = directoryEntry.Name; string str2 = name; for (int i = 0; i < str2.Length; i++) { char ch = str2[i]; bw.Write(ch); } int num3 = 0x20 - name.Length; for (int j = 0; j < num3; j++) { bw.Write(0); } bw.Write((ushort)((name.Length + 1) * 2)); bw.Write((byte)rootStorage); bw.Write(0); bw.Write(node.LeftDID); bw.Write(node.RightDID); bw.Write(node.MembersDID); bw.Write(directoryEntry.UniqueIdentifier); bw.Write(directoryEntry.UserFlags); bw.Write(directoryEntry.TimeStampCreation); bw.Write(directoryEntry.TimeStampModification); bw.Write(shortStreamContainerSID); bw.Write(shortStreamContainerSize); bw.Write(directoryEntry.NotUsed); }
private static void AddTreeMembers(Ole2Storage storage, ArrayList nodes, int nodeDID) { CompoundFileData.RedBlackTreeNode node = nodes[nodeDID] as RedBlackTreeNode; if (node.LeftDID != -1) { AddTreeMembers(storage, nodes, node.LeftDID); } storage.Add(node.DirectoryEntry); if (node.RightDID != -1) { AddTreeMembers(storage, nodes, node.RightDID); } }
private void InsertNodeToTree(ref int currentDID, string newNodeName, int newNodeDID) { if (currentDID == -1) { currentDID = newNodeDID; } else { CompoundFileData.RedBlackTreeNode node = (RedBlackTreeNode)this.nodes[currentDID]; if (NodeNameLess(newNodeName, node.DirectoryEntry.Name)) { this.InsertNodeToTree(ref node.LeftDID, newNodeName, newNodeDID); } else { this.InsertNodeToTree(ref node.RightDID, newNodeName, newNodeDID); } } }
private CompoundFileData.RedBlackTreeNode ReadDirectoryNode(BinaryReader br) { CompoundFileData.RedBlackTreeNode node = null; int num; char[] chArray = new char[0x20]; for (num = 0; num < 0x20; num++) { chArray[num] = (char)br.ReadUInt16(); } num = 0; while (num < 0x20) { if (chArray[num] == null) { break; } num++; } string name = new string(chArray, 0, num); br.ReadUInt16(); CompoundFileData.DirectoryEntryType type = (DirectoryEntryType)br.ReadByte(); br.ReadByte(); int num2 = br.ReadInt32(); int num3 = br.ReadInt32(); int num4 = br.ReadInt32(); byte[] buffer = br.ReadBytes(0x10); byte[] buffer2 = br.ReadBytes(4); byte[] buffer3 = br.ReadBytes(8); byte[] buffer4 = br.ReadBytes(8); int readSID = br.ReadInt32(); int size = br.ReadInt32(); byte[] buffer5 = br.ReadBytes(4); if (type != CompoundFileData.DirectoryEntryType.Empty) { Ole2DirectoryEntry root; node = new CompoundFileData.RedBlackTreeNode { LeftDID = num2, RightDID = num3, MembersDID = num4 }; switch (type) { case CompoundFileData.DirectoryEntryType.UserStorage: root = new Ole2Storage(name); break; case CompoundFileData.DirectoryEntryType.UserStream: root = new Ole2Stream(name, size, readSID, this); break; case CompoundFileData.DirectoryEntryType.RootStorage: base.shortStreamContainerSize = size; base.shortStreamContainerSID = readSID; this.ole2File.root = new Ole2Storage(name); root = this.ole2File.root; break; default: root = null; break; } root.UniqueIdentifier = buffer; root.UserFlags = buffer2; root.TimeStampCreation = buffer3; root.TimeStampModification = buffer4; root.NotUsed = buffer5; node.DirectoryEntry = root; } return(node); }