/// <summary> /// Initializes a new instance of the NtfsFileSystem class. /// </summary> /// <param name="stream">The stream containing the NTFS file system.</param> public NtfsFileSystem(Stream stream) : base(new NtfsOptions()) { _context = new NtfsContext(); _context.RawStream = stream; _context.Options = NtfsOptions; _context.GetFileByIndex = GetFile; _context.GetFileByRef = GetFile; _context.GetDirectoryByRef = GetDirectory; _context.GetDirectoryByIndex = GetDirectory; _context.AllocateFile = AllocateFile; _context.ForgetFile = ForgetFile; _context.ReadOnly = !stream.CanWrite; _fileCache = new ObjectCache<long, File>(); stream.Position = 0; byte[] bytes = Utilities.ReadFully(stream, 512); _context.BiosParameterBlock = BiosParameterBlock.FromBytes(bytes, 0); if (!IsValidBPB(_context.BiosParameterBlock, stream.Length)) { throw new InvalidFileSystemException("BIOS Parameter Block is invalid for an NTFS file system"); } if (NtfsOptions.ReadCacheEnabled) { BlockCacheSettings cacheSettings = new BlockCacheSettings(); cacheSettings.BlockSize = _context.BiosParameterBlock.BytesPerCluster; _context.RawStream = new BlockCacheStream(SparseStream.FromStream(stream, Ownership.None), Ownership.None, cacheSettings); } // Bootstrap the Master File Table _context.Mft = new MasterFileTable(_context); File mftFile = new File(_context, _context.Mft.GetBootstrapRecord()); _fileCache[MasterFileTable.MftIndex] = mftFile; _context.Mft.Initialize(mftFile); // Get volume information (includes version number) File volumeInfoFile = GetFile(MasterFileTable.VolumeIndex); _volumeInfo = volumeInfoFile.GetStream(AttributeType.VolumeInformation, null).GetContent<VolumeInformation>(); // Initialize access to the other well-known metadata files _context.ClusterBitmap = new ClusterBitmap(GetFile(MasterFileTable.BitmapIndex)); _context.AttributeDefinitions = new AttributeDefinitions(GetFile(MasterFileTable.AttrDefIndex)); _context.UpperCase = new UpperCase(GetFile(MasterFileTable.UpCaseIndex)); if (_volumeInfo.Version >= VolumeInformation.VersionW2k) { _context.SecurityDescriptors = new SecurityDescriptors(GetFile(MasterFileTable.SecureIndex)); _context.ObjectIds = new ObjectIds(GetFile(GetDirectoryEntry(@"$Extend\$ObjId").Reference)); _context.ReparsePoints = new ReparsePoints(GetFile(GetDirectoryEntry(@"$Extend\$Reparse").Reference)); _context.Quotas = new Quotas(GetFile(GetDirectoryEntry(@"$Extend\$Quota").Reference)); } #if false byte[] buffer = new byte[1024]; for (int i = 0; i < buffer.Length; ++i) { buffer[i] = 0xFF; } using (Stream s = OpenFile("$LogFile", FileMode.Open, FileAccess.ReadWrite)) { while (s.Position != s.Length) { s.Write(buffer, 0, (int)Math.Min(buffer.Length, s.Length - s.Position)); } } #endif }
/// <summary> /// Creates a new instance from a stream. /// </summary> /// <param name="stream">The stream containing the NTFS file system</param> public NtfsFileSystem(Stream stream) : base(new NtfsOptions()) { _context = new NtfsContext(); _context.RawStream = stream; _context.Options = NtfsOptions; _context.GetFileByIndex = GetFile; _context.GetFileByRef = GetFile; _context.GetDirectoryByRef = GetDirectory; _context.GetDirectoryByIndex = GetDirectory; _context.AllocateFile = AllocateFile; _context.ForgetFile = ForgetFile; _context.ReadOnly = !stream.CanWrite; _fileCache = new ObjectCache<long, File>(); stream.Position = 0; byte[] bytes = Utilities.ReadFully(stream, 512); _context.BiosParameterBlock = BiosParameterBlock.FromBytes(bytes, 0); // Bootstrap the Master File Table _context.Mft = new MasterFileTable(_context); File mftFile = new File(_context, _context.Mft.GetBootstrapRecord()); _fileCache[MasterFileTable.MftIndex] = mftFile; _context.Mft.Initialize(mftFile); // Initialize access to the other well-known metadata files _context.ClusterBitmap = new ClusterBitmap(GetFile(MasterFileTable.BitmapIndex)); _context.AttributeDefinitions = new AttributeDefinitions(GetFile(MasterFileTable.AttrDefIndex)); _context.UpperCase = new UpperCase(GetFile(MasterFileTable.UpCaseIndex)); _context.SecurityDescriptors = new SecurityDescriptors(GetFile(MasterFileTable.SecureIndex)); _context.ObjectIds = new ObjectIds(GetFile(GetDirectoryEntry(@"$Extend\$ObjId").Reference)); _context.ReparsePoints = new ReparsePoints(GetFile(GetDirectoryEntry(@"$Extend\$Reparse").Reference)); _context.Quotas = new Quotas(GetFile(GetDirectoryEntry(@"$Extend\$Quota").Reference)); File volumeInfoFile = GetFile(MasterFileTable.VolumeIndex); _volumeInfo = volumeInfoFile.GetStream(AttributeType.VolumeInformation, null).GetContent<VolumeInformation>(); #if false byte[] buffer = new byte[1024]; for (int i = 0; i < buffer.Length; ++i) { buffer[i] = 0xFF; } using (Stream s = OpenFile("$LogFile", FileMode.Open, FileAccess.ReadWrite)) { while (s.Position != s.Length) { s.Write(buffer, 0, (int)Math.Min(buffer.Length, s.Length - s.Position)); } } #endif }