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);

            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.");
            }
        }
        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.");
            }
        }