internal Superblock(byte[] bytes) { Signature = BitConverter.ToUInt16(bytes, 0x38); TotalInodeCount = BitConverter.ToUInt32(bytes, 0x00); TotalBlockCount = BitConverter.ToUInt32(bytes, 0x04); s_r_blocks_count_lo = BitConverter.ToUInt32(bytes, 0x08); FreeBlockCount = BitConverter.ToUInt32(bytes, 0x0C); FreeInodeCount = BitConverter.ToUInt32(bytes, 0x10); FirstDataBlock = BitConverter.ToUInt32(bytes, 0x14); BlockSize = BitConverter.ToUInt32(bytes, 0x18); ClusterSize = BitConverter.ToUInt32(bytes, 0x1C); BlocksPerGroup = BitConverter.ToUInt32(bytes, 0x20); ClustersPerGroup = BitConverter.ToUInt32(bytes, 0x24); InodesPerGroup = BitConverter.ToUInt32(bytes, 0x28); MountTime = NativeMethods.FromUnixTime(BitConverter.ToUInt32(bytes, 0x2C)); WriteTime = NativeMethods.FromUnixTime(BitConverter.ToUInt32(bytes, 0x30)); MountCount = BitConverter.ToUInt16(bytes, 0x34); MaxMountCount = BitConverter.ToUInt16(bytes, 0x36); State = (S_STATE)BitConverter.ToUInt16(bytes, 0x3A); Errors = (S_ERRORS)BitConverter.ToUInt32(bytes, 0x3C); MinorRevisionLevel = BitConverter.ToUInt16(bytes, 0x3E); LastCheckTime = NativeMethods.FromUnixTime(BitConverter.ToUInt32(bytes, 0x40)); CheckInterval = BitConverter.ToUInt32(bytes, 0x44); CreatorOS = (S_CREATOR_OS)BitConverter.ToUInt32(bytes, 0x48); RevisionLevel = BitConverter.ToUInt32(bytes, 0x4C); s_def_resuid = BitConverter.ToUInt16(bytes, 0x50); s_def_resgid = BitConverter.ToUInt16(bytes, 0x52); FirstNonReservedInode = BitConverter.ToUInt32(bytes, 0x54); InodeSize = BitConverter.ToUInt16(bytes, 0x58); BlockGroupNumber = BitConverter.ToUInt16(bytes, 0x5A); FeatureCompat = (S_FEATURE_COMPAT)BitConverter.ToUInt32(bytes, 0x5C); FeatureIncompat = (S_FEATURE_INCOMPAT)BitConverter.ToUInt32(bytes, 0x60); FeatureROCompat = (S_FEATURE_RO_COMPAT)BitConverter.ToUInt32(bytes, 0x64); VolumeUUID = new Guid(NativeMethods.GetSubArray(bytes, 0x68, 0x10)); VolumeLabel = Encoding.ASCII.GetString(bytes, 0x78, 0x10).TrimEnd('\0'); LastMountedDirectory = Encoding.ASCII.GetString(bytes, 0x88, 0x40).TrimEnd('\0'); s_algorithm_usage_bitmap = BitConverter.ToUInt32(bytes, 0xC8); PreAllocatedBlocks = bytes[0xCC]; PreAllocatedDirectoryBlocks = bytes[0xCD]; ReservedGDTBlocks = BitConverter.ToUInt16(bytes, 0xCE); JournalSuperblockUUID = new Guid(NativeMethods.GetSubArray(bytes, 0xD0, 0x10)); JournalInode = BitConverter.ToUInt32(bytes, 0xE0); JournalDeviceNumber = BitConverter.ToUInt32(bytes, 0xE4); s_last_orphan = BitConverter.ToUInt32(bytes, 0xE8); HTREEHashSeed = BitConverter.ToUInt32(bytes, 0xEC); HashVersion = (S_DEF_HASH_VERSION)bytes[0xFC]; s_jnl_backup_type = bytes[0xFD]; GroupDescriptorSize = BitConverter.ToUInt16(bytes, 0xFE); DefaultMountOptions = (S_DEFAULT_MOUNT_OPTS)BitConverter.ToUInt32(bytes, 0x100); FirstMetablockBlockGroup = BitConverter.ToUInt32(bytes, 0x104); FileSystemCreationTime = NativeMethods.FromUnixTime(BitConverter.ToUInt32(bytes, 0x108)); s_jnl_blocks = BitConverter.ToUInt32(bytes, 0x10C); BlockCountHi = BitConverter.ToUInt32(bytes, 0x150); ReservedBlockCountHi = BitConverter.ToUInt32(bytes, 0x154); FreeBlockCount = BitConverter.ToUInt32(bytes, 0x158); s_min_extra_isize = BitConverter.ToUInt16(bytes, 0x15C); s_want_extra_isize = BitConverter.ToUInt16(bytes, 0x15E); Flags = (S_FLAGS)BitConverter.ToUInt32(bytes, 0x160); RAIDStride = BitConverter.ToUInt16(bytes, 0x164); MMPInterval = BitConverter.ToUInt16(bytes, 0x166); MMPBlockNumber = BitConverter.ToUInt64(bytes, 0x168); RAIDStripeWidth = BitConverter.ToUInt32(bytes, 0x170); FlexibleBlockGroupSize = bytes[0x174]; ChecksumType = (S_CHECKSUM_TYPE)bytes[0x175]; KBWrittenLifetime = BitConverter.ToUInt64(bytes, 0x178); ActiveSnapshotInode = BitConverter.ToUInt32(bytes, 0x180); ActiveSnapshotId = BitConverter.ToUInt32(bytes, 0x184); s_snapshot_r_blocks_count = BitConverter.ToUInt64(bytes, 0x188); SnapshotListInode = BitConverter.ToUInt32(bytes, 0x190); ErrorCount = BitConverter.ToUInt32(bytes, 0x194); FirstErrorTime = NativeMethods.FromUnixTime(BitConverter.ToUInt32(bytes, 0x198)); FirstErrorInode = BitConverter.ToUInt32(bytes, 0x19C); FirstErrorBlockNumber = BitConverter.ToUInt64(bytes, 0x1A0); FirstErrorFunctionName = Encoding.ASCII.GetString(bytes, 0x1A8, 0x20).TrimEnd('\0'); FirstErrorLineNumber = BitConverter.ToUInt32(bytes, 0x1C8); LastErrorTime = NativeMethods.FromUnixTime(BitConverter.ToUInt32(bytes, 0x1CC)); LastErrorInode = BitConverter.ToUInt32(bytes, 0x1D0); LastErrorLineNumber = BitConverter.ToUInt32(bytes, 0x1D4); LastErrorBlockNumber = BitConverter.ToUInt64(bytes, 0x1D8); //LastErrorFunctionName = Encoding.ASCII.GetString(bytes, 0x1A8, 0x20).TrimEnd('\0'); MountOptions = Encoding.ASCII.GetString(bytes, 0x200, 0x64).TrimEnd('\0'); UserQuotaInode = BitConverter.ToUInt32(bytes, 0x240); GroupQuotaInode = BitConverter.ToUInt32(bytes, 0x244); OverheadBlocks = BitConverter.ToUInt32(bytes, 0x248); s_backup_bgs = BitConverter.ToUInt32(bytes, 0x24C); EncryptionAlgorithm = (S_ENCRYPT_ALGOS)BitConverter.ToUInt32(bytes, 0x24E); Checksum = BitConverter.ToUInt32(bytes, 0x3FC); }
internal Superblock(byte[] bytes) { Signature = BitConverter.ToUInt16(bytes, 0x38); if (Signature != EXT2_SUPER_MAGIC) { TotalInodeCount = BitConverter.ToUInt32(bytes, 0x00); TotalBlockCount = BitConverter.ToUInt32(bytes, 0x04); SuperUserReservedBlockCount = BitConverter.ToUInt32(bytes, 0x08); FreeBlockCount = BitConverter.ToUInt32(bytes, 0x0C); FreeInodeCount = BitConverter.ToUInt32(bytes, 0x10); FirstDataBlock = BitConverter.ToUInt32(bytes, 0x14); #region BlockSize uint s_log_block_size = BitConverter.ToUInt32(bytes, 0x18); BlockSize = (uint)1024 << (ushort)s_log_block_size; #endregion BlockSize #region ClusterSize uint s_log_frag_size = BitConverter.ToUInt32(bytes, 0x1C); ClusterSize = (uint)1024 << (ushort)s_log_frag_size; #endregion ClusterSize BlocksPerGroup = BitConverter.ToUInt32(bytes, 0x20); ClustersPerGroup = BitConverter.ToUInt32(bytes, 0x24); InodesPerGroup = BitConverter.ToUInt32(bytes, 0x28); MountTime = NativeMethods.FromUnixTime(BitConverter.ToUInt32(bytes, 0x2C)); WriteTime = NativeMethods.FromUnixTime(BitConverter.ToUInt32(bytes, 0x30)); MountCount = BitConverter.ToUInt16(bytes, 0x34); MaxMountCount = BitConverter.ToUInt16(bytes, 0x36); State = (S_STATE)BitConverter.ToUInt16(bytes, 0x3A); Errors = (S_ERRORS)BitConverter.ToUInt32(bytes, 0x3C); MinorRevisionLevel = BitConverter.ToUInt16(bytes, 0x3E); LastCheckTime = NativeMethods.FromUnixTime(BitConverter.ToUInt32(bytes, 0x40)); CheckInterval = BitConverter.ToUInt32(bytes, 0x44); CreatorOS = (S_CREATOR_OS)BitConverter.ToUInt32(bytes, 0x48); RevisionLevel = BitConverter.ToUInt32(bytes, 0x4C); DefaultUID = BitConverter.ToUInt16(bytes, 0x50); DefaultGID = BitConverter.ToUInt16(bytes, 0x52); FirstNonReservedInode = BitConverter.ToUInt32(bytes, 0x54); InodeSize = BitConverter.ToUInt16(bytes, 0x58); BlockGroupNumber = BitConverter.ToUInt16(bytes, 0x5A); FeatureCompat = (S_FEATURE_COMPAT)BitConverter.ToUInt32(bytes, 0x5C); FeatureIncompat = (S_FEATURE_INCOMPAT)BitConverter.ToUInt32(bytes, 0x60); FeatureROCompat = (S_FEATURE_RO_COMPAT)BitConverter.ToUInt32(bytes, 0x64); VolumeUUID = new Guid(NativeMethods.GetSubArray(bytes, 0x68, 0x10)); VolumeName = Encoding.ASCII.GetString(bytes, 0x78, 0x10).TrimEnd('\0'); LastMountedDirectory = Encoding.ASCII.GetString(bytes, 0x88, 0x40).Split('\0')[0]; AlgorithmBitmap = (S_ALGO_BITMAP)BitConverter.ToUInt32(bytes, 0xC8); PreAllocatedBlocks = bytes[0xCC]; PreAllocatedDirectoryBlocks = bytes[0xCD]; JournalSuperblockUUID = new Guid(NativeMethods.GetSubArray(bytes, 0xD0, 0x10)); JournalInode = BitConverter.ToUInt32(bytes, 0xE0); JournalDeviceNumber = BitConverter.ToUInt32(bytes, 0xE4); OrphanListOffset = BitConverter.ToUInt32(bytes, 0xE8); HTREEHashSeed = BitConverter.ToUInt32(bytes, 0xEC); HashVersion = (S_DEF_HASH_VERSION)bytes[0xFC]; DefaultMountOptions = (S_DEFAULT_MOUNT_OPTS)BitConverter.ToUInt32(bytes, 0x100); FirstMetablockBlockGroup = BitConverter.ToUInt32(bytes, 0x104); } else { throw new Exception("Invalid Superblock Signature."); } }