/// <summary> /// Writes the mini stream chain to the fat and the mini stream data to the output stream of the current context. /// </summary> internal override void writeReferencedStream() { VirtualStream virtualMiniStream = new VirtualStream(_miniStream.BaseStream, Context.Fat, Context.Header.SectorSize, Context.TempOutputStream); virtualMiniStream.write(); this.StartSector = virtualMiniStream.StartSector; this.SizeOfStream = virtualMiniStream.Length; }
/// <summary> /// Writes the structured storage to a given stream. /// </summary> /// <param name="outputStream">The output stream.</param> public void write(Stream outputStream) { _context.RootDirectoryEntry.RecursiveCreateRedBlackTrees(); List <BaseDirectoryEntry> allEntries = _context.RootDirectoryEntry.RecursiveGetAllDirectoryEntries(); allEntries.Sort( delegate(BaseDirectoryEntry a, BaseDirectoryEntry b) { return(a.Sid.CompareTo(b.Sid)); } ); //foreach (BaseDirectoryEntry entry in allEntries) //{ // Console.WriteLine(entry.Sid + ":"); // Console.WriteLine("{0}: {1}", entry.Name, entry.LengthOfName); // string hexName = ""; // string hexNameU = ""; // for (int i = 0; i < entry.Name.Length; i++) // { // hexName += String.Format("{0:X2} ", (UInt32)entry.Name[i]); // hexNameU += String.Format("{0:X2} ", (UInt32)entry.Name.ToUpper()[i]); // } // Console.WriteLine("{0}", hexName); // Console.WriteLine("{0}", hexNameU); // UInt32 left = entry.LeftSiblingSid; // UInt32 right = entry.RightSiblingSid; // UInt32 child = entry.ChildSiblingSid; // Console.WriteLine("{0:X02}: Left: {2:X02}, Right: {3:X02}, Child: {4:X02}, Name: {1}, Color: {5}", entry.Sid, entry.Name, (left > 0xFF) ? 0xFF : left, (right > 0xFF) ? 0xFF : right, (child > 0xFF) ? 0xFF : child, entry.Color.ToString()); // Console.WriteLine("----------"); // Console.WriteLine(""); //} // write Streams foreach (BaseDirectoryEntry entry in allEntries) { if (entry.Sid == 0x0) { // root entry continue; } entry.writeReferencedStream(); } // root entry has to be written after all other streams as it contains the ministream to which other _entries write to _context.RootDirectoryEntry.writeReferencedStream(); // write Directory Entries to directory stream foreach (BaseDirectoryEntry entry in allEntries) { entry.write(); } // Directory Entry: 128 bytes UInt32 dirEntriesPerSector = _context.Header.SectorSize / 128u; UInt32 numToPad = dirEntriesPerSector - ((UInt32)allEntries.Count % dirEntriesPerSector); EmptyDirectoryEntry emptyEntry = new EmptyDirectoryEntry(_context); for (int i = 0; i < numToPad; i++) { emptyEntry.write(); } // write directory stream VirtualStream virtualDirectoryStream = new VirtualStream(_context.DirectoryStream.BaseStream, _context.Fat, _context.Header.SectorSize, _context.TempOutputStream); virtualDirectoryStream.write(); _context.Header.DirectoryStartSector = virtualDirectoryStream.StartSector; if (_context.Header.SectorSize == 0x1000) { _context.Header.NoSectorsInDirectoryChain4KB = (UInt32)virtualDirectoryStream.SectorCount; } // write MiniFat _context.MiniFat.write(); _context.Header.MiniFatStartSector = _context.MiniFat.MiniFatStart; _context.Header.NoSectorsInMiniFatChain = _context.MiniFat.NumMiniFatSectors; // write fat _context.Fat.write(); // set header values _context.Header.NoSectorsInDiFatChain = _context.Fat.NumDiFatSectors; _context.Header.NoSectorsInFatChain = _context.Fat.NumFatSectors; _context.Header.DiFatStartSector = _context.Fat.DiFatStartSector; // write header _context.Header.write(); // write temporary streams to the output streams. _context.Header.writeToStream(outputStream); _context.TempOutputStream.writeToStream(outputStream); }