internal static bool Detect(Stream stream) { if (stream.Length < SuperBlock.Length + SuperblockOffsets[0]) { return(false); } stream.Position = SuperblockOffsets[0]; byte[] superblockData = StreamUtilities.ReadExact(stream, SuperBlock.Length); SuperBlock superblock = new SuperBlock(); superblock.ReadFrom(superblockData, 0); return(superblock.Magic == SuperBlock.BtrfsMagic); }
public VfsBtrfsFileSystem(Stream stream, BtrfsFileSystemOptions options) : base(options) { Context = new Context(options) { RawStream = stream, }; foreach (var offset in BtrfsFileSystem.SuperblockOffsets) { if (offset + SuperBlock.Length > stream.Length) { break; } stream.Position = offset; var superblockData = StreamUtilities.ReadExact(stream, SuperBlock.Length); var superblock = new SuperBlock(); superblock.ReadFrom(superblockData, 0); if (superblock.Magic != SuperBlock.BtrfsMagic) { throw new IOException("Invalid Superblock Magic"); } if (Context.SuperBlock == null) { Context.SuperBlock = superblock; } else if (Context.SuperBlock.Generation < superblock.Generation) { Context.SuperBlock = superblock; } Context.VerifyChecksum(superblock.Checksum, superblockData, 0x20, 0x1000 - 0x20); } if (Context.SuperBlock == null) { throw new IOException("No Superblock detected"); } Context.ChunkTreeRoot = Context.ReadTree(Context.SuperBlock.ChunkRoot, Context.SuperBlock.ChunkRootLevel); Context.RootTreeRoot = Context.ReadTree(Context.SuperBlock.Root, Context.SuperBlock.RootLevel); var rootDir = (DirItem)Context.FindKey(Context.SuperBlock.RootDirObjectid, ItemType.DirItem); RootItem fsTreeLocation; if (!options.UseDefaultSubvolume) { fsTreeLocation = (RootItem)Context.FindKey(options.SubvolumeId, ItemType.RootItem); } else { fsTreeLocation = (RootItem)Context.FindKey(rootDir.ChildLocation.ObjectId, rootDir.ChildLocation.ItemType); } var rootDirObjectId = fsTreeLocation.RootDirId; Context.FsTrees.Add(rootDir.ChildLocation.ObjectId, Context.ReadTree(fsTreeLocation.ByteNr, fsTreeLocation.Level)); var dirEntry = new DirEntry(rootDir.ChildLocation.ObjectId, rootDirObjectId); RootDirectory = new Directory(dirEntry, Context); }