/// <summary> /// Stream constructor. /// </summary> /// <param name="stream">The stream that contains the DirectorySectorEntry data.</param> public DirectorySectorEntry(Stream stream) { Debug.Assert(stream.Length >= Constants.DIR_ENTRY_SIZE); BinaryReader reader = new BinaryReader(stream); _name = Reader.ReadSimpleUnicodeString(reader, 64); _nameLength = reader.ReadUInt16(); if (_nameLength > 0) { _nameLength /= 2; --_nameLength; _name = _name.Substring(0, _nameLength); } else { _name = ""; } _type = (Stgty)reader.ReadByte(); _color = (DeColor)reader.ReadByte(); _leftSibling = new Sid(reader.ReadUInt32()); _rightSibling = new Sid(reader.ReadUInt32()); _child = new Sid(reader.ReadUInt32()); _clsId = new Guid(reader.ReadBytes(16)); _userFlags = reader.ReadUInt32(); _createTimeStamp = reader.ReadUInt64(); _modifyTimeStamp = reader.ReadUInt64(); _sectStart = new Sect(reader.ReadUInt32()); _size = reader.ReadUInt32(); _propType = reader.ReadUInt16(); _padding = reader.ReadUInt16(); }
/// <summary> /// Stream constructor. /// </summary> /// <param name="stream">The stream that contains the HeaderSector data.</param> /// <exception cref="Exception">Throws an exception if it encounters any invalid data in the stream.</exception> public HeaderSector(Stream stream) { Debug.Assert(stream.Length >= Constants.SECTOR_SIZE); BinaryReader reader = new BinaryReader(stream); ulong magicNumber = reader.ReadUInt64(); if(magicNumber != MAGIC_NUMBER) throw new Exception("Invalid header magic number."); _clsId = new Guid(reader.ReadBytes(16)); _minorVer = reader.ReadUInt16(); _dllVer = reader.ReadUInt16(); _byteOrder = reader.ReadUInt16(); _sectShift = reader.ReadUInt16(); _miniSectShift = reader.ReadUInt16(); _reserved = reader.ReadUInt16(); _reserved1 = reader.ReadUInt32(); _reserved2 = reader.ReadUInt32(); _sectFatCount = reader.ReadUInt32(); _sectDirStart = new Sect(reader.ReadUInt32()); _signature = reader.ReadUInt32(); _miniSectorCutoff = reader.ReadUInt32(); _sectMiniFatStart = new Sect(reader.ReadUInt32()); _sectMiniFatCount = reader.ReadUInt32(); _sectDifStart = new Sect(reader.ReadUInt32()); _sectDifCount = reader.ReadUInt32(); for(int i = 0; i < _sectFat.Length; ++i) _sectFat[i] = new Sect(reader.ReadUInt32()); }
/// <summary> /// Stream constructor. /// </summary> /// <param name="stream">The stream that contains the HeaderSector data.</param> /// <exception cref="Exception">Throws an exception if it encounters any invalid data in the stream.</exception> public HeaderSector(Stream stream) { Debug.Assert(stream.Length >= Constants.SECTOR_SIZE); BinaryReader reader = new BinaryReader(stream); ulong magicNumber = reader.ReadUInt64(); if (magicNumber != MAGIC_NUMBER) { throw new Exception("Invalid header magic number."); } _clsId = new Guid(reader.ReadBytes(16)); _minorVer = reader.ReadUInt16(); _dllVer = reader.ReadUInt16(); _byteOrder = reader.ReadUInt16(); _sectShift = reader.ReadUInt16(); _miniSectShift = reader.ReadUInt16(); _reserved = reader.ReadUInt16(); _reserved1 = reader.ReadUInt32(); _reserved2 = reader.ReadUInt32(); _sectFatCount = reader.ReadUInt32(); _sectDirStart = new Sect(reader.ReadUInt32()); _signature = reader.ReadUInt32(); _miniSectorCutoff = reader.ReadUInt32(); _sectMiniFatStart = new Sect(reader.ReadUInt32()); _sectMiniFatCount = reader.ReadUInt32(); _sectDifStart = new Sect(reader.ReadUInt32()); _sectDifCount = reader.ReadUInt32(); for (int i = 0; i < _sectFat.Length; ++i) { _sectFat[i] = new Sect(reader.ReadUInt32()); } }
/* private ushort _padding; */ /// <summary> /// Stream constructor. /// </summary> /// <param name="stream">The stream that contains the DirectorySectorEntry data.</param> public DirectorySectorEntry(Stream stream) { Debug.Assert(stream.Length >= Constants.DIR_ENTRY_SIZE); BinaryReader reader = new BinaryReader(stream); _name = Reader.ReadSimpleUnicodeString(reader, 64); _nameLength = reader.ReadUInt16(); if(_nameLength > 0) { _nameLength /= 2; --_nameLength; _name = _name.Substring(0, _nameLength); } else _name = ""; _type = (Stgty)reader.ReadByte(); _color = (DeColor)reader.ReadByte(); _leftSibling = new Sid(reader.ReadUInt32()); _rightSibling = new Sid(reader.ReadUInt32()); _child = new Sid(reader.ReadUInt32()); _clsId = new Guid(reader.ReadBytes(16)); _userFlags = reader.ReadUInt32(); _createTimeStamp = reader.ReadUInt64(); _modifyTimeStamp = reader.ReadUInt64(); _sectStart = new Sect(reader.ReadUInt32()); _size = reader.ReadUInt32(); _propType = reader.ReadUInt16(); /* _padding = */ reader.ReadUInt16(); }
/// <summary> /// Stream constructor. /// </summary> /// <param name="stream">The stream that contains the MiniFatSector data.</param> public MiniFatSector(Stream stream) { Debug.Assert(stream.Length >= Constants.SECTOR_SIZE); BinaryReader reader = new BinaryReader(stream); for(int i = 0; i < _sect.Length; ++i) _sect[i] = new Sect(reader.ReadUInt32()); }
/// <summary> /// Stream constructor. /// </summary> /// <param name="stream">The stream that contains the FatSector data.</param> public FatSector(Stream stream) { Debug.Assert(stream.Length >= Constants.SECTOR_SIZE); BinaryReader reader = new BinaryReader(stream); for (int i = 0; i < _sect.Length; ++i) { _sect[i] = new Sect(reader.ReadUInt32()); } }
/// <summary> /// Indexer of the collection. /// </summary> public Sector this[Sect index] { get { return(InnerList[index.ToInt()]); } set { InnerList[index.ToInt()] = value; } }
/// <summary> /// Builds a directory entry and populates its correct type, children and siblings. /// </summary> /// <param name="entry">The directory sector entry.</param> /// <param name="entries">The current entries.</param> /// <param name="sectors">The data sectors.</param> /// <param name="fat">The FAT.</param> /// <returns>The correct DirectoryEntry object.</returns> public static DirectoryEntry CreateEntry(DirectorySectorEntry entry, DirectorySectorEntryCollection entries, SectorCollection sectors, Sect[] fat) { DirectoryEntry newEntry = null; switch(entry.Type) { case Stgty.Storage : newEntry = new StorageEntry(entry.Name); break; case Stgty.Stream : newEntry = new StreamEntry(entry.Name, entry.Size, entry.SectStart, sectors, fat); break; default: newEntry = new GenericDirectoryEntry(entry.Name, entry.Type); break; } if(!entry.LeftSibling.IsEof) newEntry.LeftSibling = CreateEntry(entries[entry.LeftSibling], entries, sectors, fat); if(!entry.RightSibling.IsEof) newEntry.RightSibling = CreateEntry(entries[entry.RightSibling], entries, sectors, fat); if(!entry.Child.IsEof) newEntry.Child = CreateEntry(entries[entry.Child], entries, sectors, fat); return newEntry; }
/// <summary> /// Constructor. /// </summary> /// <param name="name">The entry Name.</param> /// <param name="length">The stream length.</param> /// <param name="dataOffset">Data offset.</param> /// <param name="sectors">The sectors.</param> /// <param name="fat">The FAT.</param> public StreamEntry(string name, long length, Sect dataOffset, SectorCollection sectors, Sect[] fat) : base(name) { _length = length; _data = new byte[length]; if(!dataOffset.IsEndOfChain) { int left = (int)length; MemoryStream stream = new MemoryStream(_data); Sect sect = dataOffset; do { try { StorageSector sector = (StorageSector)sectors[sect]; int toWrite = Math.Min(sector.Data.Length, left); Debug.Assert(toWrite <= 512); stream.Write(sector.Data, 0, toWrite); left -= toWrite; sect = fat[sect.ToInt()]; } catch(Exception err) { Debug.WriteLine("Stream name is " + name); Debug.WriteLine(err.Message); Debug.WriteLine(err.StackTrace); return; } } while(!sect.IsEndOfChain); Debug.Assert(left == 0); Debug.Assert(stream.Length == stream.Position); } }