Beispiel #1
0
        /// <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()
        {
            var virtualMiniStream = new VirtualStream(this._miniStream.BaseStream, this.Context.Fat, this.Context.Header.SectorSize, this.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)
        {
            this._context.RootDirectoryEntry.RecursiveCreateRedBlackTrees();

            var allEntries = this._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 (var 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
            this._context.RootDirectoryEntry.writeReferencedStream();

            // write Directory Entries to directory stream
            foreach (var entry in allEntries)
            {
                entry.write();
            }

            // Directory Entry: 128 bytes
            uint dirEntriesPerSector = this._context.Header.SectorSize / 128u;
            uint numToPad            = dirEntriesPerSector - ((uint)allEntries.Count % dirEntriesPerSector);

            var emptyEntry = new EmptyDirectoryEntry(this._context);

            for (int i = 0; i < numToPad; i++)
            {
                emptyEntry.write();
            }

            // write directory stream
            var virtualDirectoryStream = new VirtualStream(this._context.DirectoryStream.BaseStream, this._context.Fat, this._context.Header.SectorSize, this._context.TempOutputStream);

            virtualDirectoryStream.write();
            this._context.Header.DirectoryStartSector = virtualDirectoryStream.StartSector;
            if (this._context.Header.SectorSize == 0x1000)
            {
                this._context.Header.NoSectorsInDirectoryChain4KB = (uint)virtualDirectoryStream.SectorCount;
            }

            // write MiniFat
            this._context.MiniFat.write();
            this._context.Header.MiniFatStartSector      = this._context.MiniFat.MiniFatStart;
            this._context.Header.NoSectorsInMiniFatChain = this._context.MiniFat.NumMiniFatSectors;

            // write fat
            this._context.Fat.write();

            // set header values
            this._context.Header.NoSectorsInDiFatChain = this._context.Fat.NumDiFatSectors;
            this._context.Header.NoSectorsInFatChain   = this._context.Fat.NumFatSectors;
            this._context.Header.DiFatStartSector      = this._context.Fat.DiFatStartSector;

            // write header
            this._context.Header.write();

            // write temporary streams to the output streams.
            this._context.Header.writeToStream(outputStream);
            this._context.TempOutputStream.writeToStream(outputStream);
        }