コード例 #1
0
        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);
        }
コード例 #2
0
        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);
        }