public DfsFileStream(DragonFs fs, DfsDirectoryEntry root, FileAccess access) { _Fs = fs; _Root = root; if (root.FilePointer != 0) { if ((access == FileAccess.Write) || (access == FileAccess.ReadWrite)) { throw new NotSupportedException("Writing an existing file is not supported"); } // Create MemoryStream from existing data _MemStream = new MemoryStream((int)(_Root.Flags & ~DfsDirectoryEntry.FLAG_MASK)); int remainingBytes = (int)Length; uint offset = root.FilePointer; while (remainingBytes > 0) { // Fetch a sector and write to the stream DfsSector sector = _Fs.FindSector(offset); int sectorBytes = (int)DfsSector.SECTOR_SIZE; if (sectorBytes >= remainingBytes) { sectorBytes = remainingBytes; } _MemStream.Write(sector.Buffer, 0, sectorBytes); remainingBytes -= sectorBytes; offset += DfsSector.SECTOR_SIZE; } _MemStream.Seek(0, SeekOrigin.Begin); } else { if (access == FileAccess.Read) { throw new NotSupportedException("Cannot read file without content"); } // Create MemoryStream for all file operations _MemStream = new MemoryStream(); } switch (access) { case FileAccess.Read: _CanRead = true; break; case FileAccess.ReadWrite: _CanRead = true; _CanWrite = true; break; case FileAccess.Write: _CanWrite = true; break; } }
public static DragonFs CreateFromStream(Stream source) { DragonFs newFs = new DragonFs(); DfsSector sector = new DfsSector(0); source.Read(sector.Buffer, 0, (int)DfsSector.SECTOR_SIZE); DfsDirectoryEntry root = new DfsDirectoryEntry(sector); bool checkValid = true; if ((root.Flags != ROOT_FLAGS) || (root.NextEntry != ROOT_NEXTENTRY)) { checkValid = false; } else { // Check DFS version string if (!root.Path.Equals(DragonFs.ROOT_PATH)) { checkValid = false; } } if (checkValid == false) { throw new ArgumentException("source", "The stream does not contain a valid DFS 2.0 image"); } while (source.Position != source.Length) { sector = newFs.NewSector(); source.Read(sector.Buffer, 0, (int)DfsSector.SECTOR_SIZE); } // The virtual root directory entry needs to point to the first sector // TODO: Can this be done better? newFs._RootDirectory.FilePointer = DfsSector.SECTOR_SIZE; return(newFs); }