2016-07-28 18:13:49 +01:00
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : ext2FS.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Linux extended filesystem 2, 3 and 4 plugin.
//
// --[ Description ] ----------------------------------------------------------
//
// Identifies the Linux extended filesystem 2, 3 and 4 and shows information.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
2017-05-19 20:28:49 +01:00
// Copyright © 2011-2017 Natalia Portillo
2016-07-28 18:13:49 +01:00
// ****************************************************************************/
2014-04-17 19:58:14 +00:00
2012-08-03 01:45:38 +00:00
using System ;
using System.Text ;
2016-07-21 17:16:08 +01:00
using System.Collections.Generic ;
2012-08-03 01:45:38 +00:00
2016-07-21 16:15:39 +01:00
namespace DiscImageChef.Filesystems
2012-08-03 01:45:38 +00:00
{
2016-07-28 22:25:26 +01:00
// Information from the Linux kernel
2017-07-01 03:26:08 +01:00
public class ext2FS : Filesystem
2014-04-14 02:29:13 +00:00
{
2015-10-05 20:04:05 +01:00
public ext2FS ( )
2012-08-03 01:45:38 +00:00
{
2014-04-14 02:29:13 +00:00
Name = "Linux extended Filesystem 2, 3 and 4" ;
PluginUUID = new Guid ( "6AA91B88-150B-4A7B-AD56-F84FB2DF4184" ) ;
2017-06-06 21:23:20 +01:00
CurrentEncoding = Encoding . GetEncoding ( "iso-8859-15" ) ;
2016-07-27 13:32:45 +01:00
}
2017-06-06 21:23:20 +01:00
public ext2FS ( ImagePlugins . ImagePlugin imagePlugin , ulong partitionStart , ulong partitionEnd , Encoding encoding )
2016-07-27 13:32:45 +01:00
{
Name = "Linux extended Filesystem 2, 3 and 4" ;
PluginUUID = new Guid ( "6AA91B88-150B-4A7B-AD56-F84FB2DF4184" ) ;
2017-06-06 21:23:20 +01:00
if ( encoding = = null )
CurrentEncoding = Encoding . GetEncoding ( "iso-8859-15" ) ;
2012-08-03 01:45:38 +00:00
}
2015-04-20 05:09:46 +01:00
public override bool Identify ( ImagePlugins . ImagePlugin imagePlugin , ulong partitionStart , ulong partitionEnd )
2014-04-14 02:29:13 +00:00
{
2016-08-08 18:44:08 +01:00
if ( ( 2 + partitionStart ) > = partitionEnd )
2014-07-09 19:49:14 +01:00
return false ;
2015-04-20 05:09:46 +01:00
byte [ ] sb_sector = imagePlugin . ReadSector ( 2 + partitionStart ) ;
2014-04-14 02:29:13 +00:00
2016-07-28 22:25:26 +01:00
ushort magic = BitConverter . ToUInt16 ( sb_sector , 0x038 ) ;
2016-04-19 02:11:47 +01:00
if ( magic = = ext2FSMagic | | magic = = ext2OldFSMagic )
2014-04-14 02:29:13 +00:00
return true ;
return false ;
}
2015-04-20 05:09:46 +01:00
public override void GetInformation ( ImagePlugins . ImagePlugin imagePlugin , ulong partitionStart , ulong partitionEnd , out string information )
2014-04-14 02:29:13 +00:00
{
information = "" ;
2016-04-19 02:11:47 +01:00
2014-04-14 02:29:13 +00:00
StringBuilder sb = new StringBuilder ( ) ;
ext2FSSuperBlock supblk = new ext2FSSuperBlock ( ) ;
byte [ ] forstrings ;
bool new_ext2 = false ;
bool ext3 = false ;
bool ext4 = false ;
byte [ ] guid_a = new byte [ 16 ] ;
byte [ ] guid_b = new byte [ 16 ] ;
uint sb_size_in_sectors ;
2016-04-19 02:11:47 +01:00
if ( imagePlugin . GetSectorSize ( ) < 1024 )
2014-04-14 02:29:13 +00:00
sb_size_in_sectors = 1024 / imagePlugin . GetSectorSize ( ) ;
else
sb_size_in_sectors = 1 ;
2016-04-19 02:11:47 +01:00
if ( sb_size_in_sectors = = 0 )
2014-04-14 02:29:13 +00:00
{
information = "Error calculating size in sectors of ext2/3/4 superblocks" ;
return ;
}
2015-04-20 05:09:46 +01:00
byte [ ] sb_sector = imagePlugin . ReadSectors ( 2 + partitionStart , sb_size_in_sectors ) ;
2014-04-14 02:29:13 +00:00
supblk . inodes = BitConverter . ToUInt32 ( sb_sector , 0x000 ) ;
supblk . blocks = BitConverter . ToUInt32 ( sb_sector , 0x004 ) ;
supblk . reserved_blocks = BitConverter . ToUInt32 ( sb_sector , 0x008 ) ;
supblk . free_blocks = BitConverter . ToUInt32 ( sb_sector , 0x00C ) ;
supblk . free_inodes = BitConverter . ToUInt32 ( sb_sector , 0x010 ) ;
supblk . first_block = BitConverter . ToUInt32 ( sb_sector , 0x014 ) ;
supblk . block_size = BitConverter . ToUInt32 ( sb_sector , 0x018 ) ;
supblk . frag_size = BitConverter . ToInt32 ( sb_sector , 0x01C ) ;
supblk . blocks_per_grp = BitConverter . ToUInt32 ( sb_sector , 0x020 ) ;
supblk . flags_per_grp = BitConverter . ToUInt32 ( sb_sector , 0x024 ) ;
supblk . inodes_per_grp = BitConverter . ToUInt32 ( sb_sector , 0x028 ) ;
supblk . mount_t = BitConverter . ToUInt32 ( sb_sector , 0x02C ) ;
supblk . write_t = BitConverter . ToUInt32 ( sb_sector , 0x030 ) ;
supblk . mount_c = BitConverter . ToUInt16 ( sb_sector , 0x034 ) ;
supblk . max_mount_c = BitConverter . ToInt16 ( sb_sector , 0x036 ) ;
supblk . magic = BitConverter . ToUInt16 ( sb_sector , 0x038 ) ;
supblk . state = BitConverter . ToUInt16 ( sb_sector , 0x03A ) ;
supblk . err_behaviour = BitConverter . ToUInt16 ( sb_sector , 0x03C ) ;
supblk . minor_revision = BitConverter . ToUInt16 ( sb_sector , 0x03E ) ;
supblk . check_t = BitConverter . ToUInt32 ( sb_sector , 0x040 ) ;
supblk . check_inv = BitConverter . ToUInt32 ( sb_sector , 0x044 ) ;
// From 0.5a onward
supblk . creator_os = BitConverter . ToUInt32 ( sb_sector , 0x048 ) ;
supblk . revision = BitConverter . ToUInt32 ( sb_sector , 0x04C ) ;
supblk . default_uid = BitConverter . ToUInt16 ( sb_sector , 0x050 ) ;
supblk . default_gid = BitConverter . ToUInt16 ( sb_sector , 0x052 ) ;
// From 0.5b onward
supblk . first_inode = BitConverter . ToUInt32 ( sb_sector , 0x054 ) ;
supblk . inode_size = BitConverter . ToUInt16 ( sb_sector , 0x058 ) ;
supblk . block_group_no = BitConverter . ToUInt16 ( sb_sector , 0x05A ) ;
supblk . ftr_compat = BitConverter . ToUInt32 ( sb_sector , 0x05C ) ;
supblk . ftr_incompat = BitConverter . ToUInt32 ( sb_sector , 0x060 ) ;
supblk . ftr_ro_compat = BitConverter . ToUInt32 ( sb_sector , 0x064 ) ;
// Volume UUID
Array . Copy ( sb_sector , 0x068 , guid_a , 0 , 16 ) ;
guid_b [ 0 ] = guid_a [ 3 ] ;
guid_b [ 1 ] = guid_a [ 2 ] ;
guid_b [ 2 ] = guid_a [ 1 ] ;
guid_b [ 3 ] = guid_a [ 0 ] ;
guid_b [ 4 ] = guid_a [ 5 ] ;
guid_b [ 5 ] = guid_a [ 4 ] ;
guid_b [ 6 ] = guid_a [ 7 ] ;
guid_b [ 7 ] = guid_a [ 6 ] ;
guid_b [ 8 ] = guid_a [ 8 ] ;
guid_b [ 9 ] = guid_a [ 9 ] ;
guid_b [ 10 ] = guid_a [ 10 ] ;
guid_b [ 11 ] = guid_a [ 11 ] ;
guid_b [ 12 ] = guid_a [ 12 ] ;
guid_b [ 13 ] = guid_a [ 13 ] ;
guid_b [ 14 ] = guid_a [ 14 ] ;
guid_b [ 15 ] = guid_a [ 15 ] ;
supblk . uuid = new Guid ( guid_b ) ;
// End of volume UUID
forstrings = new byte [ 16 ] ;
Array . Copy ( sb_sector , 0x078 , forstrings , 0 , 16 ) ;
2017-06-06 21:23:20 +01:00
supblk . volume_name = StringHandlers . CToString ( forstrings , CurrentEncoding ) ;
2014-04-14 02:29:13 +00:00
forstrings = new byte [ 64 ] ;
Array . Copy ( sb_sector , 0x088 , forstrings , 0 , 64 ) ;
2017-06-06 21:23:20 +01:00
supblk . last_mount_dir = StringHandlers . CToString ( forstrings , CurrentEncoding ) ;
2014-04-14 02:29:13 +00:00
supblk . algo_usage_bmp = BitConverter . ToUInt32 ( sb_sector , 0x0C8 ) ;
supblk . prealloc_blks = sb_sector [ 0x0CC ] ;
supblk . prealloc_dir_blks = sb_sector [ 0x0CD ] ;
supblk . rsrvd_gdt_blocks = BitConverter . ToUInt16 ( sb_sector , 0x0CE ) ;
// ext3
Array . Copy ( sb_sector , 0x0D0 , guid_a , 0 , 16 ) ;
guid_b [ 0 ] = guid_a [ 3 ] ;
guid_b [ 1 ] = guid_a [ 2 ] ;
guid_b [ 2 ] = guid_a [ 1 ] ;
guid_b [ 3 ] = guid_a [ 0 ] ;
guid_b [ 4 ] = guid_a [ 5 ] ;
guid_b [ 5 ] = guid_a [ 4 ] ;
guid_b [ 6 ] = guid_a [ 7 ] ;
guid_b [ 7 ] = guid_a [ 6 ] ;
guid_b [ 8 ] = guid_a [ 8 ] ;
guid_b [ 9 ] = guid_a [ 9 ] ;
guid_b [ 10 ] = guid_a [ 10 ] ;
guid_b [ 11 ] = guid_a [ 11 ] ;
guid_b [ 12 ] = guid_a [ 12 ] ;
guid_b [ 13 ] = guid_a [ 13 ] ;
guid_b [ 14 ] = guid_a [ 14 ] ;
guid_b [ 15 ] = guid_a [ 15 ] ;
supblk . journal_uuid = new Guid ( guid_b ) ;
supblk . journal_inode = BitConverter . ToUInt32 ( sb_sector , 0x0E0 ) ;
supblk . journal_dev = BitConverter . ToUInt32 ( sb_sector , 0x0E4 ) ;
supblk . last_orphan = BitConverter . ToUInt32 ( sb_sector , 0x0E8 ) ;
supblk . hash_seed_1 = BitConverter . ToUInt32 ( sb_sector , 0x0EC ) ;
supblk . hash_seed_2 = BitConverter . ToUInt32 ( sb_sector , 0x0F0 ) ;
supblk . hash_seed_3 = BitConverter . ToUInt32 ( sb_sector , 0x0F4 ) ;
supblk . hash_seed_4 = BitConverter . ToUInt32 ( sb_sector , 0x0F8 ) ;
supblk . hash_version = sb_sector [ 0x0FC ] ;
supblk . jnl_backup_type = sb_sector [ 0x0FD ] ;
supblk . desc_grp_size = BitConverter . ToUInt16 ( sb_sector , 0x0FE ) ;
supblk . default_mnt_opts = BitConverter . ToUInt32 ( sb_sector , 0x100 ) ;
supblk . first_meta_bg = BitConverter . ToUInt32 ( sb_sector , 0x104 ) ;
// ext4
supblk . mkfs_t = BitConverter . ToUInt32 ( sb_sector , 0x108 ) ;
supblk . blocks_hi = BitConverter . ToUInt32 ( sb_sector , 0x14C ) ;
supblk . reserved_blocks_hi = BitConverter . ToUInt32 ( sb_sector , 0x150 ) ;
supblk . free_blocks_hi = BitConverter . ToUInt32 ( sb_sector , 0x154 ) ;
supblk . min_inode_size = BitConverter . ToUInt16 ( sb_sector , 0x158 ) ;
supblk . rsv_inode_size = BitConverter . ToUInt16 ( sb_sector , 0x15A ) ;
supblk . flags = BitConverter . ToUInt32 ( sb_sector , 0x15C ) ;
supblk . raid_stride = BitConverter . ToUInt16 ( sb_sector , 0x160 ) ;
supblk . mmp_interval = BitConverter . ToUInt16 ( sb_sector , 0x162 ) ;
supblk . mmp_block = BitConverter . ToUInt64 ( sb_sector , 0x164 ) ;
supblk . raid_stripe_width = BitConverter . ToUInt32 ( sb_sector , 0x16C ) ;
supblk . flex_bg_grp_size = sb_sector [ 0x170 ] ;
supblk . kbytes_written = BitConverter . ToUInt64 ( sb_sector , 0x174 ) ;
supblk . snapshot_inum = BitConverter . ToUInt32 ( sb_sector , 0x17C ) ;
supblk . snapshot_id = BitConverter . ToUInt32 ( sb_sector , 0x180 ) ;
supblk . snapshot_blocks = BitConverter . ToUInt64 ( sb_sector , 0x184 ) ;
supblk . snapshot_list = BitConverter . ToUInt32 ( sb_sector , 0x18C ) ;
supblk . error_count = BitConverter . ToUInt32 ( sb_sector , 0x190 ) ;
supblk . first_error_t = BitConverter . ToUInt32 ( sb_sector , 0x194 ) ;
supblk . first_error_inode = BitConverter . ToUInt32 ( sb_sector , 0x198 ) ;
supblk . first_error_block = BitConverter . ToUInt64 ( sb_sector , 0x19C ) ;
forstrings = new byte [ 32 ] ;
Array . Copy ( sb_sector , 0x1A0 , forstrings , 0 , 32 ) ;
2017-06-06 21:23:20 +01:00
supblk . first_error_func = StringHandlers . CToString ( forstrings , CurrentEncoding ) ;
2014-04-14 02:29:13 +00:00
supblk . first_error_line = BitConverter . ToUInt32 ( sb_sector , 0x1B0 ) ;
supblk . last_error_t = BitConverter . ToUInt32 ( sb_sector , 0x1B4 ) ;
supblk . last_error_inode = BitConverter . ToUInt32 ( sb_sector , 0x1B8 ) ;
supblk . last_error_line = BitConverter . ToUInt32 ( sb_sector , 0x1BC ) ;
supblk . last_error_block = BitConverter . ToUInt64 ( sb_sector , 0x1C0 ) ;
forstrings = new byte [ 32 ] ;
Array . Copy ( sb_sector , 0x1C8 , forstrings , 0 , 32 ) ;
2017-06-06 21:23:20 +01:00
supblk . last_error_func = StringHandlers . CToString ( forstrings , CurrentEncoding ) ;
2014-04-14 02:29:13 +00:00
forstrings = new byte [ 64 ] ;
Array . Copy ( sb_sector , 0x1D8 , forstrings , 0 , 64 ) ;
2017-06-06 21:23:20 +01:00
supblk . mount_options = StringHandlers . CToString ( forstrings , CurrentEncoding ) ;
2014-04-14 02:29:13 +00:00
2015-12-05 17:10:27 +00:00
xmlFSType = new Schemas . FileSystemType ( ) ;
2016-04-19 02:11:47 +01:00
if ( supblk . magic = = ext2OldFSMagic )
2014-04-14 02:29:13 +00:00
{
sb . AppendLine ( "ext2 (old) filesystem" ) ;
2015-12-05 17:10:27 +00:00
xmlFSType . Type = "ext2" ;
2014-04-14 02:29:13 +00:00
}
2016-04-19 02:11:47 +01:00
else if ( supblk . magic = = ext2FSMagic )
2014-04-14 02:29:13 +00:00
{
ext3 | = ( supblk . ftr_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL ) = = EXT3_FEATURE_COMPAT_HAS_JOURNAL | | ( supblk . ftr_incompat & EXT3_FEATURE_INCOMPAT_RECOVER ) = = EXT3_FEATURE_INCOMPAT_RECOVER | | ( supblk . ftr_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV ) = = EXT3_FEATURE_INCOMPAT_JOURNAL_DEV ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE ) = = EXT4_FEATURE_RO_COMPAT_HUGE_FILE | |
2014-04-14 02:29:13 +00:00
( supblk . ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM ) = = EXT4_FEATURE_RO_COMPAT_GDT_CSUM | |
( supblk . ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_DIR_NLINK ) = = EXT4_FEATURE_RO_COMPAT_DIR_NLINK | |
( supblk . ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE ) = = EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE | |
( supblk . ftr_incompat & EXT4_FEATURE_INCOMPAT_64BIT ) = = EXT4_FEATURE_INCOMPAT_64BIT | |
( supblk . ftr_incompat & EXT4_FEATURE_INCOMPAT_MMP ) = = EXT4_FEATURE_INCOMPAT_MMP | |
( supblk . ftr_incompat & EXT4_FEATURE_INCOMPAT_FLEX_BG ) = = EXT4_FEATURE_INCOMPAT_FLEX_BG | |
( supblk . ftr_incompat & EXT4_FEATURE_INCOMPAT_EA_INODE ) = = EXT4_FEATURE_INCOMPAT_EA_INODE | |
( supblk . ftr_incompat & EXT4_FEATURE_INCOMPAT_DIRDATA ) = = EXT4_FEATURE_INCOMPAT_DIRDATA )
{
ext3 = false ;
ext4 = true ;
}
new_ext2 | = ! ext3 & & ! ext4 ;
2016-04-19 02:11:47 +01:00
if ( new_ext2 )
2015-12-05 17:10:27 +00:00
{
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "ext2 filesystem" ) ;
2015-12-05 17:10:27 +00:00
xmlFSType . Type = "ext2" ;
}
2016-04-19 02:11:47 +01:00
if ( ext3 )
2015-12-05 17:10:27 +00:00
{
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "ext3 filesystem" ) ;
2015-12-05 17:10:27 +00:00
xmlFSType . Type = "ext3" ;
}
2016-04-19 02:11:47 +01:00
if ( ext4 )
2015-12-05 17:10:27 +00:00
{
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "ext4 filesystem" ) ;
2015-12-05 17:10:27 +00:00
xmlFSType . Type = "ext4" ;
}
2014-04-14 02:29:13 +00:00
}
else
{
information = "Not a ext2/3/4 filesystem" + Environment . NewLine ;
return ;
}
string ext_os ;
2016-04-19 02:11:47 +01:00
switch ( supblk . creator_os )
2014-04-14 02:29:13 +00:00
{
case EXT2_OS_FREEBSD :
ext_os = "FreeBSD" ;
break ;
case EXT2_OS_HURD :
ext_os = "Hurd" ;
break ;
case EXT2_OS_LINUX :
ext_os = "Linux" ;
break ;
case EXT2_OS_LITES :
ext_os = "Lites" ;
break ;
case EXT2_OS_MASIX :
ext_os = "MasIX" ;
break ;
default :
ext_os = string . Format ( "Unknown OS ({0})" , supblk . creator_os ) ;
break ;
}
2017-07-05 02:06:48 +01:00
xmlFSType . SystemIdentifier = ext_os ;
2016-04-19 02:11:47 +01:00
if ( supblk . mkfs_t > 0 )
2015-12-05 17:10:27 +00:00
{
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Volume was created on {0} for {1}" , DateHandlers . UNIXUnsignedToDateTime ( supblk . mkfs_t ) , ext_os ) . AppendLine ( ) ;
2015-12-05 17:10:27 +00:00
xmlFSType . CreationDate = DateHandlers . UNIXUnsignedToDateTime ( supblk . mkfs_t ) ;
2015-12-06 05:09:31 +00:00
xmlFSType . CreationDateSpecified = true ;
2015-12-05 17:10:27 +00:00
}
2014-04-14 02:29:13 +00:00
else
sb . AppendFormat ( "Volume was created for {0}" , ext_os ) . AppendLine ( ) ;
byte [ ] temp_lo , temp_hi ;
byte [ ] temp_bytes = new byte [ 8 ] ;
2016-07-28 22:25:26 +01:00
ulong blocks , reserved , free ;
2014-04-14 02:29:13 +00:00
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_incompat & EXT4_FEATURE_INCOMPAT_64BIT ) = = EXT4_FEATURE_INCOMPAT_64BIT )
2014-04-14 02:29:13 +00:00
{
temp_lo = BitConverter . GetBytes ( supblk . blocks ) ;
temp_hi = BitConverter . GetBytes ( supblk . blocks_hi ) ;
temp_bytes [ 0 ] = temp_lo [ 0 ] ;
temp_bytes [ 1 ] = temp_lo [ 1 ] ;
temp_bytes [ 2 ] = temp_lo [ 2 ] ;
temp_bytes [ 3 ] = temp_lo [ 3 ] ;
temp_bytes [ 4 ] = temp_hi [ 0 ] ;
temp_bytes [ 5 ] = temp_hi [ 1 ] ;
temp_bytes [ 6 ] = temp_hi [ 2 ] ;
temp_bytes [ 7 ] = temp_hi [ 3 ] ;
blocks = BitConverter . ToUInt64 ( temp_bytes , 0 ) ;
temp_lo = BitConverter . GetBytes ( supblk . reserved_blocks ) ;
temp_hi = BitConverter . GetBytes ( supblk . reserved_blocks_hi ) ;
temp_bytes [ 0 ] = temp_lo [ 0 ] ;
temp_bytes [ 1 ] = temp_lo [ 1 ] ;
temp_bytes [ 2 ] = temp_lo [ 2 ] ;
temp_bytes [ 3 ] = temp_lo [ 3 ] ;
temp_bytes [ 4 ] = temp_hi [ 0 ] ;
temp_bytes [ 5 ] = temp_hi [ 1 ] ;
temp_bytes [ 6 ] = temp_hi [ 2 ] ;
temp_bytes [ 7 ] = temp_hi [ 3 ] ;
reserved = BitConverter . ToUInt64 ( temp_bytes , 0 ) ;
temp_lo = BitConverter . GetBytes ( supblk . free_blocks ) ;
temp_hi = BitConverter . GetBytes ( supblk . free_blocks_hi ) ;
temp_bytes [ 0 ] = temp_lo [ 0 ] ;
temp_bytes [ 1 ] = temp_lo [ 1 ] ;
temp_bytes [ 2 ] = temp_lo [ 2 ] ;
temp_bytes [ 3 ] = temp_lo [ 3 ] ;
temp_bytes [ 4 ] = temp_hi [ 0 ] ;
temp_bytes [ 5 ] = temp_hi [ 1 ] ;
temp_bytes [ 6 ] = temp_hi [ 2 ] ;
temp_bytes [ 7 ] = temp_hi [ 3 ] ;
free = BitConverter . ToUInt64 ( temp_bytes , 0 ) ;
}
else
{
blocks = supblk . blocks ;
reserved = supblk . reserved_blocks ;
free = supblk . free_blocks ;
}
2016-04-19 02:11:47 +01:00
if ( supblk . block_size = = 0 ) // Then it is 1024 bytes
2015-12-06 07:18:36 +00:00
supblk . block_size = 1024 ;
2012-08-03 01:45:38 +00:00
2016-04-19 02:11:47 +01:00
sb . AppendFormat ( "Volume has {0} blocks of {1} bytes, for a total of {2} bytes" , blocks , 1024 < < ( int ) supblk . block_size , blocks * ( ulong ) ( 1024 < < ( int ) supblk . block_size ) ) . AppendLine ( ) ;
2015-12-05 17:10:27 +00:00
xmlFSType . Clusters = ( long ) blocks ;
xmlFSType . ClusterSize = 1024 < < ( int ) supblk . block_size ;
2016-04-19 02:11:47 +01:00
if ( supblk . mount_t > 0 | | supblk . mount_c > 0 )
2014-04-14 02:29:13 +00:00
{
2016-04-19 02:11:47 +01:00
if ( supblk . mount_t > 0 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Last mounted on {0}" , DateHandlers . UNIXUnsignedToDateTime ( supblk . mount_t ) ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( supblk . max_mount_c ! = - 1 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Volume has been mounted {0} times of a maximum of {1} mounts before checking" , supblk . mount_c , supblk . max_mount_c ) . AppendLine ( ) ;
else
sb . AppendFormat ( "Volume has been mounted {0} times with no maximum no. of mounts before checking" , supblk . mount_c ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( supblk . last_mount_dir ! = "" )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Last mounted on: \"{0}\"" , supblk . last_mount_dir ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( supblk . mount_options ! = "" )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Last used mount options were: {0}" , supblk . mount_options ) . AppendLine ( ) ;
}
else
{
sb . AppendLine ( "Volume has never been mounted" ) ;
2016-04-19 02:11:47 +01:00
if ( supblk . max_mount_c ! = - 1 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Volume can be mounted {0} times before checking" , supblk . max_mount_c ) . AppendLine ( ) ;
else
sb . AppendLine ( "Volume has no maximum no. of mounts before checking" ) ;
}
2016-04-19 02:11:47 +01:00
if ( supblk . check_t > 0 )
2014-04-14 02:29:13 +00:00
{
2016-04-19 02:11:47 +01:00
if ( supblk . check_inv > 0 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Last checked on {0} (should check every {1} seconds)" , DateHandlers . UNIXUnsignedToDateTime ( supblk . check_t ) , supblk . check_inv ) . AppendLine ( ) ;
else
sb . AppendFormat ( "Last checked on {0}" , DateHandlers . UNIXUnsignedToDateTime ( supblk . check_t ) ) . AppendLine ( ) ;
}
else
{
2016-04-19 02:11:47 +01:00
if ( supblk . check_inv > 0 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Volume has never been checked (should check every {0})" , supblk . check_inv ) . AppendLine ( ) ;
else
sb . AppendLine ( "Volume has never been checked" ) ;
}
2016-04-19 02:11:47 +01:00
if ( supblk . write_t > 0 )
2015-12-05 17:10:27 +00:00
{
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Last written on {0}" , DateHandlers . UNIXUnsignedToDateTime ( supblk . write_t ) ) . AppendLine ( ) ;
2015-12-05 17:10:27 +00:00
xmlFSType . ModificationDate = DateHandlers . UNIXUnsignedToDateTime ( supblk . write_t ) ;
2015-12-06 05:09:31 +00:00
xmlFSType . ModificationDateSpecified = true ;
2015-12-05 17:10:27 +00:00
}
2014-04-14 02:29:13 +00:00
else
sb . AppendLine ( "Volume has never been written" ) ;
2015-12-05 17:10:27 +00:00
xmlFSType . Dirty = true ;
2016-04-19 02:11:47 +01:00
switch ( supblk . state )
2014-04-14 02:29:13 +00:00
{
case EXT2_VALID_FS :
sb . AppendLine ( "Volume is clean" ) ;
2015-12-05 17:10:27 +00:00
xmlFSType . Dirty = false ;
2014-04-14 02:29:13 +00:00
break ;
case EXT2_ERROR_FS :
sb . AppendLine ( "Volume is dirty" ) ;
break ;
case EXT3_ORPHAN_FS :
sb . AppendLine ( "Volume is recovering orphan files" ) ;
break ;
default :
sb . AppendFormat ( "Volume is in an unknown state ({0})" , supblk . state ) . AppendLine ( ) ;
break ;
}
2016-04-19 02:11:47 +01:00
if ( supblk . volume_name ! = "" )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Volume name: \"{0}\"" , supblk . volume_name ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
switch ( supblk . err_behaviour )
2014-04-14 02:29:13 +00:00
{
case EXT2_ERRORS_CONTINUE :
sb . AppendLine ( "On errors, filesystem should continue" ) ;
break ;
case EXT2_ERRORS_RO :
sb . AppendLine ( "On errors, filesystem should remount read-only" ) ;
break ;
case EXT2_ERRORS_PANIC :
sb . AppendLine ( "On errors, filesystem should panic" ) ;
break ;
default :
sb . AppendFormat ( "On errors filesystem will do an unknown thing ({0})" , supblk . err_behaviour ) . AppendLine ( ) ;
break ;
}
2016-04-19 02:11:47 +01:00
if ( supblk . revision > 0 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Filesystem revision: {0}.{1}" , supblk . revision , supblk . minor_revision ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( supblk . uuid ! = Guid . Empty )
2015-12-05 17:10:27 +00:00
{
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Volume UUID: {0}" , supblk . uuid ) . AppendLine ( ) ;
2015-12-05 17:10:27 +00:00
xmlFSType . VolumeSerial = supblk . uuid . ToString ( ) ;
}
2014-04-14 02:29:13 +00:00
2016-04-19 02:11:47 +01:00
if ( supblk . kbytes_written > 0 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "{0} KiB has been written on volume" , supblk . kbytes_written ) . AppendLine ( ) ;
sb . AppendFormat ( "{0} reserved and {1} free blocks" , reserved , free ) . AppendLine ( ) ;
2015-12-05 17:10:27 +00:00
xmlFSType . FreeClusters = ( long ) free ;
2015-12-06 05:09:31 +00:00
xmlFSType . FreeClustersSpecified = true ;
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "{0} inodes with {1} free inodes ({2}%)" , supblk . inodes , supblk . free_inodes , supblk . free_inodes * 100 / supblk . inodes ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( supblk . first_inode > 0 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "First inode is {0}" , supblk . first_inode ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( supblk . frag_size > 0 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "{0} bytes per fragment" , supblk . frag_size ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( supblk . blocks_per_grp > 0 & & supblk . flags_per_grp > 0 & & supblk . inodes_per_grp > 0 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "{0} blocks, {1} flags and {2} inodes per group" , supblk . blocks_per_grp , supblk . flags_per_grp , supblk . inodes_per_grp ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( supblk . first_block > 0 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "{0} is first data block" , supblk . first_block ) . AppendLine ( ) ;
sb . AppendFormat ( "Default UID: {0}, GID: {1}" , supblk . default_uid , supblk . default_gid ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( supblk . block_group_no > 0 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Block group number is {0}" , supblk . block_group_no ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( supblk . desc_grp_size > 0 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Group descriptor size is {0} bytes" , supblk . desc_grp_size ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( supblk . first_meta_bg > 0 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "First metablock group is {0}" , supblk . first_meta_bg ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( supblk . raid_stride > 0 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "RAID stride: {0}" , supblk . raid_stride ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( supblk . raid_stripe_width > 0 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "{0} blocks on all data disks" , supblk . raid_stripe_width ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( supblk . mmp_interval > 0 & & supblk . mmp_block > 0 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "{0} seconds for multi-mount protection wait, on block {1}" , supblk . mmp_interval , supblk . mmp_block ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( supblk . flex_bg_grp_size > 0 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "{0} Flexible block group size" , supblk . flex_bg_grp_size ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( supblk . hash_seed_1 > 0 & & supblk . hash_seed_2 > 0 & & supblk . hash_seed_3 > 0 & & supblk . hash_seed_4 > 0 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Hash seed: {0:X8}{1:X8}{2:X8}{3:X8}, version {4}" , supblk . hash_seed_1 , supblk . hash_seed_2 , supblk . hash_seed_3 , supblk . hash_seed_4 , supblk . hash_version ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL ) = = EXT3_FEATURE_COMPAT_HAS_JOURNAL | |
2014-04-14 02:29:13 +00:00
( supblk . ftr_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV ) = = EXT3_FEATURE_INCOMPAT_JOURNAL_DEV )
{
sb . AppendLine ( "Volume is journaled" ) ;
2016-04-19 02:11:47 +01:00
if ( supblk . journal_uuid ! = Guid . Empty )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Journal UUID: {0}" , supblk . journal_uuid ) . AppendLine ( ) ;
sb . AppendFormat ( "Journal has inode {0}" , supblk . journal_inode ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_compat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV ) = = EXT3_FEATURE_INCOMPAT_JOURNAL_DEV & & supblk . journal_dev > 0 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Journal is on device {0}" , supblk . journal_dev ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( supblk . jnl_backup_type > 0 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Journal backup type: {0}" , supblk . jnl_backup_type ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( supblk . last_orphan > 0 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Last orphaned inode is {0}" , supblk . last_orphan ) . AppendLine ( ) ;
else
sb . AppendLine ( "There are no orphaned inodes" ) ;
}
2016-04-19 02:11:47 +01:00
if ( ext4 )
2014-04-14 02:29:13 +00:00
{
2016-04-19 02:11:47 +01:00
if ( supblk . snapshot_id > 0 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Active snapshot has ID {0}, on inode {1}, with {2} blocks reserved, list starting on block {3}" , supblk . snapshot_id ,
supblk . snapshot_inum , supblk . snapshot_blocks , supblk . snapshot_list ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( supblk . error_count > 0 )
2014-04-14 02:29:13 +00:00
{
sb . AppendFormat ( "{0} errors registered" , supblk . error_count ) . AppendLine ( ) ;
sb . AppendFormat ( "First error occurred on {0}, last on {1}" , DateHandlers . UNIXUnsignedToDateTime ( supblk . first_error_t ) , DateHandlers . UNIXUnsignedToDateTime ( supblk . last_error_t ) ) . AppendLine ( ) ;
sb . AppendFormat ( "First error inode is {0}, last is {1}" , supblk . first_error_inode , supblk . last_error_inode ) . AppendLine ( ) ;
sb . AppendFormat ( "First error block is {0}, last is {1}" , supblk . first_error_block , supblk . last_error_block ) . AppendLine ( ) ;
sb . AppendFormat ( "First error function is \"{0}\", last is \"{1}\"" , supblk . first_error_func , supblk . last_error_func ) . AppendLine ( ) ;
}
}
sb . AppendFormat ( "Flags…:" ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . flags & EXT2_FLAGS_SIGNED_HASH ) = = EXT2_FLAGS_SIGNED_HASH )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Signed directory hash is in use" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . flags & EXT2_FLAGS_UNSIGNED_HASH ) = = EXT2_FLAGS_UNSIGNED_HASH )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Unsigned directory hash is in use" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . flags & EXT2_FLAGS_TEST_FILESYS ) = = EXT2_FLAGS_TEST_FILESYS )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Volume is testing development code" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . flags & 0xFFFFFFF8 ) ! = 0 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Unknown set flags: {0:X8}" , supblk . flags ) ;
sb . AppendLine ( ) ;
sb . AppendFormat ( "Default mount options…:" ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . default_mnt_opts & EXT2_DEFM_DEBUG ) = = EXT2_DEFM_DEBUG )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "(debug): Enable debugging code" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . default_mnt_opts & EXT2_DEFM_BSDGROUPS ) = = EXT2_DEFM_BSDGROUPS )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "(bsdgroups): Emulate BSD behaviour when creating new files" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . default_mnt_opts & EXT2_DEFM_XATTR_USER ) = = EXT2_DEFM_XATTR_USER )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "(user_xattr): Enable user-specified extended attributes" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . default_mnt_opts & EXT2_DEFM_ACL ) = = EXT2_DEFM_ACL )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "(acl): Enable POSIX ACLs" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . default_mnt_opts & EXT2_DEFM_UID16 ) = = EXT2_DEFM_UID16 )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "(uid16): Disable 32bit UIDs and GIDs" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . default_mnt_opts & EXT3_DEFM_JMODE_DATA ) = = EXT3_DEFM_JMODE_DATA )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "(journal_data): Journal data and metadata" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . default_mnt_opts & EXT3_DEFM_JMODE_ORDERED ) = = EXT3_DEFM_JMODE_ORDERED )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "(journal_data_ordered): Write data before journaling metadata" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . default_mnt_opts & EXT3_DEFM_JMODE_WBACK ) = = EXT3_DEFM_JMODE_WBACK )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "(journal_data_writeback): Write journal before data" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . default_mnt_opts & 0xFFFFFE20 ) ! = 0 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Unknown set default mount options: {0:X8}" , supblk . default_mnt_opts ) ;
sb . AppendLine ( ) ;
sb . AppendFormat ( "Compatible features…:" ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_compat & EXT2_FEATURE_COMPAT_DIR_PREALLOC ) = = EXT2_FEATURE_COMPAT_DIR_PREALLOC )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Pre-allocate directories" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES ) = = EXT2_FEATURE_COMPAT_IMAGIC_INODES )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "imagic inodes ?" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL ) = = EXT3_FEATURE_COMPAT_HAS_JOURNAL )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Has journal (ext3)" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_compat & EXT2_FEATURE_COMPAT_EXT_ATTR ) = = EXT2_FEATURE_COMPAT_EXT_ATTR )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Has extended attribute blocks" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_compat & EXT2_FEATURE_COMPAT_RESIZE_INO ) = = EXT2_FEATURE_COMPAT_RESIZE_INO )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Has online filesystem resize reservations" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_compat & EXT2_FEATURE_COMPAT_DIR_INDEX ) = = EXT2_FEATURE_COMPAT_DIR_INDEX )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Can use hashed indexes on directories" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_compat & 0xFFFFFFC0 ) ! = 0 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Unknown compatible features: {0:X8}" , supblk . ftr_compat ) ;
sb . AppendLine ( ) ;
sb . AppendFormat ( "Compatible features if read-only…:" ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_ro_compat & EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER ) = = EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Reduced number of superblocks" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_ro_compat & EXT2_FEATURE_RO_COMPAT_LARGE_FILE ) = = EXT2_FEATURE_RO_COMPAT_LARGE_FILE )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Can have files bigger than 2GiB" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_ro_compat & EXT2_FEATURE_RO_COMPAT_BTREE_DIR ) = = EXT2_FEATURE_RO_COMPAT_BTREE_DIR )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Uses B-Tree for directories" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE ) = = EXT4_FEATURE_RO_COMPAT_HUGE_FILE )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Can have files bigger than 2TiB (ext4)" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM ) = = EXT4_FEATURE_RO_COMPAT_GDT_CSUM )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Group descriptor checksums and sparse inode table (ext4)" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_DIR_NLINK ) = = EXT4_FEATURE_RO_COMPAT_DIR_NLINK )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "More than 32000 directory entries (ext4)" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE ) = = EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Supports nanosecond timestamps and creation time (ext4)" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_ro_compat & 0xFFFFFF80 ) ! = 0 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Unknown read-only compatible features: {0:X8}" , supblk . ftr_ro_compat ) ;
sb . AppendLine ( ) ;
sb . AppendFormat ( "Incompatible features…:" ) . AppendLine ( ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION ) = = EXT2_FEATURE_INCOMPAT_COMPRESSION )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Uses compression" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE ) = = EXT2_FEATURE_INCOMPAT_FILETYPE )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Filetype in directory entries" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_incompat & EXT3_FEATURE_INCOMPAT_RECOVER ) = = EXT3_FEATURE_INCOMPAT_RECOVER )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Journal needs recovery (ext3)" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV ) = = EXT3_FEATURE_INCOMPAT_JOURNAL_DEV )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Has journal on another device (ext3)" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_incompat & EXT2_FEATURE_INCOMPAT_META_BG ) = = EXT2_FEATURE_INCOMPAT_META_BG )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Reduced block group backups" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_incompat & EXT4_FEATURE_INCOMPAT_EXTENTS ) = = EXT4_FEATURE_INCOMPAT_EXTENTS )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Volume use extents (ext4)" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_incompat & EXT4_FEATURE_INCOMPAT_64BIT ) = = EXT4_FEATURE_INCOMPAT_64BIT )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Supports volumes bigger than 2^32 blocks (ext4)" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_incompat & EXT4_FEATURE_INCOMPAT_MMP ) = = EXT4_FEATURE_INCOMPAT_MMP )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Multi-mount protection (ext4)" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_incompat & EXT4_FEATURE_INCOMPAT_FLEX_BG ) = = EXT4_FEATURE_INCOMPAT_FLEX_BG )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Flexible block group metadata location (ext4)" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_incompat & EXT4_FEATURE_INCOMPAT_EA_INODE ) = = EXT4_FEATURE_INCOMPAT_EA_INODE )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Extended attributes can reside in inode (ext4)" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_incompat & EXT4_FEATURE_INCOMPAT_DIRDATA ) = = EXT4_FEATURE_INCOMPAT_DIRDATA )
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Data can reside in directory entry (ext4)" ) ;
2016-04-19 02:11:47 +01:00
if ( ( supblk . ftr_incompat & 0xFFFFF020 ) ! = 0 )
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Unknown incompatible features: {0:X8}" , supblk . ftr_incompat ) ;
information = sb . ToString ( ) ;
}
2012-08-03 01:45:38 +00:00
2015-12-06 07:18:36 +00:00
/// <summary>
/// Same magic for ext2, ext3 and ext4
/// </summary>
2016-07-28 22:25:26 +01:00
public const ushort ext2FSMagic = 0xEF53 ;
2015-12-06 07:18:36 +00:00
2016-07-28 22:25:26 +01:00
public const ushort ext2OldFSMagic = 0xEF51 ;
2015-12-06 07:18:36 +00:00
/// <summary>
/// ext2/3/4 superblock
/// </summary>
2014-04-14 02:29:13 +00:00
public struct ext2FSSuperBlock
{
2015-12-06 07:18:36 +00:00
/// <summary>0x000, inodes on volume</summary>
2016-07-28 22:25:26 +01:00
public uint inodes ;
2015-12-06 07:18:36 +00:00
/// <summary>0x004, blocks on volume</summary>
2016-07-28 22:25:26 +01:00
public uint blocks ;
2015-12-06 07:18:36 +00:00
/// <summary>0x008, reserved blocks</summary>
2016-07-28 22:25:26 +01:00
public uint reserved_blocks ;
2015-12-06 07:18:36 +00:00
/// <summary>0x00C, free blocks count</summary>
2016-07-28 22:25:26 +01:00
public uint free_blocks ;
2015-12-06 07:18:36 +00:00
/// <summary>0x010, free inodes count</summary>
2016-07-28 22:25:26 +01:00
public uint free_inodes ;
2015-12-06 07:18:36 +00:00
/// <summary>0x014, first data block</summary>
2016-07-28 22:25:26 +01:00
public uint first_block ;
2015-12-06 07:18:36 +00:00
/// <summary>0x018, block size</summary>
2016-07-28 22:25:26 +01:00
public uint block_size ;
2015-12-06 07:18:36 +00:00
/// <summary>0x01C, fragment size</summary>
2014-04-14 02:29:13 +00:00
public Int32 frag_size ;
2015-12-06 07:18:36 +00:00
/// <summary>0x020, blocks per group</summary>
2016-07-28 22:25:26 +01:00
public uint blocks_per_grp ;
2015-12-06 07:18:36 +00:00
/// <summary>0x024, fragments per group</summary>
2016-07-28 22:25:26 +01:00
public uint flags_per_grp ;
2015-12-06 07:18:36 +00:00
/// <summary>0x028, inodes per group</summary>
2016-07-28 22:25:26 +01:00
public uint inodes_per_grp ;
2015-12-06 07:18:36 +00:00
/// <summary>0x02C, last mount time</summary>
2016-07-28 22:25:26 +01:00
public uint mount_t ;
2015-12-06 07:18:36 +00:00
/// <summary>0x030, last write time</summary>
2016-07-28 22:25:26 +01:00
public uint write_t ;
2015-12-06 07:18:36 +00:00
/// <summary>0x034, mounts count</summary>
2016-07-28 22:25:26 +01:00
public ushort mount_c ;
2015-12-06 07:18:36 +00:00
/// <summary>0x036, max mounts</summary>
2014-04-14 02:29:13 +00:00
public Int16 max_mount_c ;
2015-12-06 07:18:36 +00:00
/// <summary>0x038, (little endian)</summary>
2016-07-28 22:25:26 +01:00
public ushort magic ;
2015-12-06 07:18:36 +00:00
/// <summary>0x03A, filesystem state</summary>
2016-07-28 22:25:26 +01:00
public ushort state ;
2015-12-06 07:18:36 +00:00
/// <summary>0x03C, behaviour on errors</summary>
2016-07-28 22:25:26 +01:00
public ushort err_behaviour ;
2015-12-06 07:18:36 +00:00
/// <summary>0x03E, From 0.5b onward</summary>
2016-07-28 22:25:26 +01:00
public ushort minor_revision ;
2015-12-06 07:18:36 +00:00
/// <summary>0x040, last check time</summary>
2016-07-28 22:25:26 +01:00
public uint check_t ;
2015-12-06 07:18:36 +00:00
/// <summary>0x044, max time between checks</summary>
2016-07-28 22:25:26 +01:00
public uint check_inv ;
2015-12-06 07:18:36 +00:00
2014-04-14 02:29:13 +00:00
// From 0.5a onward
2015-12-06 07:18:36 +00:00
/// <summary>0x048, Creation OS</summary>
2016-07-28 22:25:26 +01:00
public uint creator_os ;
2015-12-06 07:18:36 +00:00
/// <summary>0x04C, Revison level</summary>
2016-07-28 22:25:26 +01:00
public uint revision ;
2015-12-06 07:18:36 +00:00
/// <summary>0x050, Default UID for reserved blocks</summary>
2016-07-28 22:25:26 +01:00
public ushort default_uid ;
2015-12-06 07:18:36 +00:00
/// <summary>0x052, Default GID for reserved blocks</summary>
2016-07-28 22:25:26 +01:00
public ushort default_gid ;
2015-12-06 07:18:36 +00:00
2014-04-14 02:29:13 +00:00
// From 0.5b onward
2015-12-06 07:18:36 +00:00
/// <summary>0x054, First unreserved inode</summary>
2016-07-28 22:25:26 +01:00
public uint first_inode ;
2015-12-06 07:18:36 +00:00
/// <summary>0x058, inode size</summary>
2016-07-28 22:25:26 +01:00
public ushort inode_size ;
2015-12-06 07:18:36 +00:00
/// <summary>0x05A, Block group number of THIS superblock</summary>
2016-07-28 22:25:26 +01:00
public ushort block_group_no ;
2015-12-06 07:18:36 +00:00
/// <summary>0x05C, Compatible features set</summary>
2016-07-28 22:25:26 +01:00
public uint ftr_compat ;
2015-12-06 07:18:36 +00:00
/// <summary>0x060, Incompatible features set</summary>
2016-07-28 22:25:26 +01:00
public uint ftr_incompat ;
2015-12-06 07:18:36 +00:00
2014-04-14 02:29:13 +00:00
// Found on Linux 2.0.40
2015-12-06 07:18:36 +00:00
/// <summary>0x064, Read-only compatible features set</summary>
2016-07-28 22:25:26 +01:00
public uint ftr_ro_compat ;
2015-12-06 07:18:36 +00:00
2014-04-14 02:29:13 +00:00
// Found on Linux 2.1.132
2015-12-06 07:18:36 +00:00
/// <summary>0x068, 16 bytes, UUID</summary>
2014-04-14 02:29:13 +00:00
public Guid uuid ;
2015-12-06 07:18:36 +00:00
/// <summary>0x078, 16 bytes, volume name</summary>
2014-04-14 02:29:13 +00:00
public string volume_name ;
2015-12-06 07:18:36 +00:00
/// <summary>0x088, 64 bytes, where last mounted</summary>
2014-04-14 02:29:13 +00:00
public string last_mount_dir ;
2015-12-06 07:18:36 +00:00
/// <summary>0x0C8, Usage bitmap algorithm, for compression</summary>
2016-07-28 22:25:26 +01:00
public uint algo_usage_bmp ;
2015-12-06 07:18:36 +00:00
/// <summary>0x0CC, Block to try to preallocate</summary>
2014-04-14 02:29:13 +00:00
public byte prealloc_blks ;
2015-12-06 07:18:36 +00:00
/// <summary>0x0CD, Blocks to try to preallocate for directories</summary>
2014-04-14 02:29:13 +00:00
public byte prealloc_dir_blks ;
2015-12-06 07:18:36 +00:00
/// <summary>0x0CE, Per-group desc for online growth</summary>
2016-07-28 22:25:26 +01:00
public ushort rsrvd_gdt_blocks ;
2015-12-06 07:18:36 +00:00
2014-04-14 02:29:13 +00:00
// Found on Linux 2.4
// ext3
2015-12-06 07:18:36 +00:00
/// <summary>0x0D0, 16 bytes, UUID of journal superblock</summary>
2014-04-14 02:29:13 +00:00
public Guid journal_uuid ;
2015-12-06 07:18:36 +00:00
/// <summary>0x0E0, inode no. of journal file</summary>
2016-07-28 22:25:26 +01:00
public uint journal_inode ;
2015-12-06 07:18:36 +00:00
/// <summary>0x0E4, device no. of journal file</summary>
2016-07-28 22:25:26 +01:00
public uint journal_dev ;
2015-12-06 07:18:36 +00:00
/// <summary>0x0E8, Start of list of inodes to delete</summary>
2016-07-28 22:25:26 +01:00
public uint last_orphan ;
2015-12-06 07:18:36 +00:00
/// <summary>0x0EC, First byte of 128bit HTREE hash seed</summary>
2016-07-28 22:25:26 +01:00
public uint hash_seed_1 ;
2015-12-06 07:18:36 +00:00
/// <summary>0x0F0, Second byte of 128bit HTREE hash seed</summary>
2016-07-28 22:25:26 +01:00
public uint hash_seed_2 ;
2015-12-06 07:18:36 +00:00
/// <summary>0x0F4, Third byte of 128bit HTREE hash seed</summary>
2016-07-28 22:25:26 +01:00
public uint hash_seed_3 ;
2015-12-06 07:18:36 +00:00
/// <summary>0x0F8, Fourth byte of 128bit HTREE hash seed</summary>
2016-07-28 22:25:26 +01:00
public uint hash_seed_4 ;
2015-12-06 07:18:36 +00:00
/// <summary>0x0FC, Hash version</summary>
2014-04-14 02:29:13 +00:00
public byte hash_version ;
2015-12-06 07:18:36 +00:00
/// <summary>0x0FD, Journal backup type</summary>
2014-04-14 02:29:13 +00:00
public byte jnl_backup_type ;
2015-12-06 07:18:36 +00:00
/// <summary>0x0FE, Size of group descriptor</summary>
2016-07-28 22:25:26 +01:00
public ushort desc_grp_size ;
2015-12-06 07:18:36 +00:00
/// <summary>0x100, Default mount options</summary>
2016-07-28 22:25:26 +01:00
public uint default_mnt_opts ;
2015-12-06 07:18:36 +00:00
/// <summary>0x104, First metablock block group</summary>
2016-07-28 22:25:26 +01:00
public uint first_meta_bg ;
2015-12-06 07:18:36 +00:00
2014-04-14 02:29:13 +00:00
// Introduced with ext4, some can be ext3
2015-12-06 07:18:36 +00:00
/// <summary>0x108, Filesystem creation time</summary>
2016-07-28 22:25:26 +01:00
public uint mkfs_t ;
2014-04-14 02:29:13 +00:00
// Follows 17 uint32 (68 bytes) of journal inode backup
// Following 3 fields are valid if EXT4_FEATURE_COMPAT_64BIT is set
2015-12-06 07:18:36 +00:00
/// <summary>0x14C, High 32bits of blocks no.</summary>
2016-07-28 22:25:26 +01:00
public uint blocks_hi ;
2015-12-06 07:18:36 +00:00
/// <summary>0x150, High 32bits of reserved blocks no.</summary>
2016-07-28 22:25:26 +01:00
public uint reserved_blocks_hi ;
2015-12-06 07:18:36 +00:00
/// <summary>0x154, High 32bits of free blocks no.</summary>
2016-07-28 22:25:26 +01:00
public uint free_blocks_hi ;
2015-12-06 07:18:36 +00:00
/// <summary>0x158, inodes minimal size in bytes</summary>
2016-07-28 22:25:26 +01:00
public ushort min_inode_size ;
2015-12-06 07:18:36 +00:00
/// <summary>0x15A, Bytes reserved by new inodes</summary>
2016-07-28 22:25:26 +01:00
public ushort rsv_inode_size ;
2015-12-06 07:18:36 +00:00
/// <summary>0x15C, Flags</summary>
2016-07-28 22:25:26 +01:00
public uint flags ;
2015-12-06 07:18:36 +00:00
/// <summary>0x160, RAID stride</summary>
2016-07-28 22:25:26 +01:00
public ushort raid_stride ;
2015-12-06 07:18:36 +00:00
/// <summary>0x162, Waiting seconds in MMP check</summary>
2016-07-28 22:25:26 +01:00
public ushort mmp_interval ;
2015-12-06 07:18:36 +00:00
/// <summary>0x164, Block for multi-mount protection</summary>
2016-07-28 22:25:26 +01:00
public ulong mmp_block ;
2015-12-06 07:18:36 +00:00
/// <summary>0x16C, Blocks on all data disks (N*stride)</summary>
2016-07-28 22:25:26 +01:00
public uint raid_stripe_width ;
2015-12-06 07:18:36 +00:00
/// <summary>0x170, FLEX_BG group size</summary>
2014-04-14 02:29:13 +00:00
public byte flex_bg_grp_size ;
2015-12-06 07:18:36 +00:00
/// <summary>0x171 Padding</summary>
2014-04-14 02:29:13 +00:00
public byte padding ;
2015-12-06 07:18:36 +00:00
/// <summary>0x172 Padding</summary>
2016-07-28 22:25:26 +01:00
public ushort padding2 ;
2015-12-06 07:18:36 +00:00
2014-04-14 02:29:13 +00:00
// Following are introduced with ext4
2015-12-06 07:18:36 +00:00
/// <summary>0x174, Kibibytes written in volume lifetime</summary>
2016-07-28 22:25:26 +01:00
public ulong kbytes_written ;
2015-12-06 07:18:36 +00:00
/// <summary>0x17C, Active snapshot inode number</summary>
2016-07-28 22:25:26 +01:00
public uint snapshot_inum ;
2015-12-06 07:18:36 +00:00
/// <summary>0x180, Active snapshot sequential ID</summary>
2016-07-28 22:25:26 +01:00
public uint snapshot_id ;
2015-12-06 07:18:36 +00:00
/// <summary>0x184, Reserved blocks for active snapshot's future use</summary>
2016-07-28 22:25:26 +01:00
public ulong snapshot_blocks ;
2015-12-06 07:18:36 +00:00
/// <summary>0x18C, inode number of the on-disk start of the snapshot list</summary>
2016-07-28 22:25:26 +01:00
public uint snapshot_list ;
2015-12-06 07:18:36 +00:00
2014-04-14 02:29:13 +00:00
// Optional ext4 error-handling features
2015-12-06 07:18:36 +00:00
/// <summary>0x190, total registered filesystem errors</summary>
2016-07-28 22:25:26 +01:00
public uint error_count ;
2015-12-06 07:18:36 +00:00
/// <summary>0x194, time on first error</summary>
2016-07-28 22:25:26 +01:00
public uint first_error_t ;
2015-12-06 07:18:36 +00:00
/// <summary>0x198, inode involved in first error</summary>
2016-07-28 22:25:26 +01:00
public uint first_error_inode ;
2015-12-06 07:18:36 +00:00
/// <summary>0x19C, block involved of first error</summary>
2016-07-28 22:25:26 +01:00
public ulong first_error_block ;
2015-12-06 07:18:36 +00:00
/// <summary>0x1A0, 32 bytes, function where the error happened</summary>
2014-04-14 02:29:13 +00:00
public string first_error_func ;
2015-12-06 07:18:36 +00:00
/// <summary>0x1B0, line number where error happened</summary>
2016-07-28 22:25:26 +01:00
public uint first_error_line ;
2015-12-06 07:18:36 +00:00
/// <summary>0x1B4, time of most recent error</summary>
2016-07-28 22:25:26 +01:00
public uint last_error_t ;
2015-12-06 07:18:36 +00:00
/// <summary>0x1B8, inode involved in last error</summary>
2016-07-28 22:25:26 +01:00
public uint last_error_inode ;
2015-12-06 07:18:36 +00:00
/// <summary>0x1BC, line number where error happened</summary>
2016-07-28 22:25:26 +01:00
public uint last_error_line ;
2015-12-06 07:18:36 +00:00
/// <summary>0x1C0, block involved of last error</summary>
2016-07-28 22:25:26 +01:00
public ulong last_error_block ;
2015-12-06 07:18:36 +00:00
/// <summary>0x1C8, 32 bytes, function where the error happened</summary>
2014-04-14 02:29:13 +00:00
public string last_error_func ;
// End of optional error-handling features
2015-12-06 07:18:36 +00:00
// 0x1D8, 64 bytes, last used mount options</summary>
2014-04-14 02:29:13 +00:00
public string mount_options ;
}
2015-12-06 07:18:36 +00:00
2014-04-14 02:29:13 +00:00
// ext? filesystem states
2015-12-06 07:18:36 +00:00
/// <summary>Cleanly-unmounted volume</summary>
2016-07-28 22:25:26 +01:00
public const ushort EXT2_VALID_FS = 0x0001 ;
2015-12-06 07:18:36 +00:00
/// <summary>Dirty volume</summary>
2016-07-28 22:25:26 +01:00
public const ushort EXT2_ERROR_FS = 0x0002 ;
2015-12-06 07:18:36 +00:00
/// <summary>Recovering orphan files</summary>
2016-07-28 22:25:26 +01:00
public const ushort EXT3_ORPHAN_FS = 0x0004 ;
2015-12-06 07:18:36 +00:00
2014-04-14 02:29:13 +00:00
// ext? default mount flags
2015-12-06 07:18:36 +00:00
/// <summary>Enable debugging messages</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT2_DEFM_DEBUG = 0x000001 ;
2015-12-06 07:18:36 +00:00
/// <summary>Emulates BSD behaviour on new file creation</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT2_DEFM_BSDGROUPS = 0x000002 ;
2015-12-06 07:18:36 +00:00
/// <summary>Enable user xattrs</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT2_DEFM_XATTR_USER = 0x000004 ;
2015-12-06 07:18:36 +00:00
/// <summary>Enable POSIX ACLs</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT2_DEFM_ACL = 0x000008 ;
2015-12-06 07:18:36 +00:00
/// <summary>Use 16bit UIDs</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT2_DEFM_UID16 = 0x000010 ;
2015-12-06 07:18:36 +00:00
/// <summary>Journal data mode</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT3_DEFM_JMODE_DATA = 0x000040 ;
2015-12-06 07:18:36 +00:00
/// <summary>Journal ordered mode</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT3_DEFM_JMODE_ORDERED = 0x000080 ;
2015-12-06 07:18:36 +00:00
/// <summary>Journal writeback mode</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT3_DEFM_JMODE_WBACK = 0x000100 ;
2015-12-06 07:18:36 +00:00
2014-04-14 02:29:13 +00:00
// Behaviour on errors
2015-12-06 07:18:36 +00:00
/// <summary>Continue execution</summary>
2016-07-28 22:25:26 +01:00
public const ushort EXT2_ERRORS_CONTINUE = 1 ;
2015-12-06 07:18:36 +00:00
/// <summary>Remount fs read-only</summary>
2016-07-28 22:25:26 +01:00
public const ushort EXT2_ERRORS_RO = 2 ;
2015-12-06 07:18:36 +00:00
/// <summary>Panic</summary>
2016-07-28 22:25:26 +01:00
public const ushort EXT2_ERRORS_PANIC = 3 ;
2015-12-06 07:18:36 +00:00
2014-04-14 02:29:13 +00:00
// OS codes
2016-07-28 22:25:26 +01:00
public const uint EXT2_OS_LINUX = 0 ;
public const uint EXT2_OS_HURD = 1 ;
public const uint EXT2_OS_MASIX = 2 ;
public const uint EXT2_OS_FREEBSD = 3 ;
public const uint EXT2_OS_LITES = 4 ;
2015-12-06 07:18:36 +00:00
2014-04-14 02:29:13 +00:00
// Revision levels
2015-12-06 07:18:36 +00:00
/// <summary>The good old (original) format</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT2_GOOD_OLD_REV = 0 ;
2015-12-06 07:18:36 +00:00
/// <summary>V2 format w/ dynamic inode sizes</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT2_DYNAMIC_REV = 1 ;
2015-12-06 07:18:36 +00:00
2014-04-14 02:29:13 +00:00
// Compatible features
2015-12-06 07:18:36 +00:00
/// <summary>Pre-allocate directories</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT2_FEATURE_COMPAT_DIR_PREALLOC = 0x00000001 ;
2015-12-06 07:18:36 +00:00
/// <summary>imagic inodes ?</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT2_FEATURE_COMPAT_IMAGIC_INODES = 0x00000002 ;
2015-12-06 07:18:36 +00:00
/// <summary>Has journal (it's ext3)</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT3_FEATURE_COMPAT_HAS_JOURNAL = 0x00000004 ;
2015-12-06 07:18:36 +00:00
/// <summary>EA blocks</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT2_FEATURE_COMPAT_EXT_ATTR = 0x00000008 ;
2015-12-06 07:18:36 +00:00
/// <summary>Online filesystem resize reservations</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT2_FEATURE_COMPAT_RESIZE_INO = 0x00000010 ;
2015-12-06 07:18:36 +00:00
/// <summary>Can use hashed indexes on directories</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT2_FEATURE_COMPAT_DIR_INDEX = 0x00000020 ;
2015-12-06 07:18:36 +00:00
2014-04-14 02:29:13 +00:00
// Read-only compatible features
2015-12-06 07:18:36 +00:00
/// <summary>Reduced number of superblocks</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER = 0x00000001 ;
2015-12-06 07:18:36 +00:00
/// <summary>Can have files bigger than 2GiB</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT2_FEATURE_RO_COMPAT_LARGE_FILE = 0x00000002 ;
2015-12-06 07:18:36 +00:00
/// <summary>Use B-Tree for directories</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT2_FEATURE_RO_COMPAT_BTREE_DIR = 0x00000004 ;
2015-12-06 07:18:36 +00:00
/// <summary>Can have files bigger than 2TiB *ext4*</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT4_FEATURE_RO_COMPAT_HUGE_FILE = 0x00000008 ;
2015-12-06 07:18:36 +00:00
/// <summary>Group descriptor checksums and sparse inode table *ext4*</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT4_FEATURE_RO_COMPAT_GDT_CSUM = 0x00000010 ;
2015-12-06 07:18:36 +00:00
/// <summary>More than 32000 directory entries *ext4*</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT4_FEATURE_RO_COMPAT_DIR_NLINK = 0x00000020 ;
2015-12-06 07:18:36 +00:00
/// <summary>Nanosecond timestamps and creation time *ext4*</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE = 0x00000040 ;
2015-12-06 07:18:36 +00:00
2014-04-14 02:29:13 +00:00
// Incompatible features
2015-12-06 07:18:36 +00:00
/// <summary>Uses compression</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT2_FEATURE_INCOMPAT_COMPRESSION = 0x00000001 ;
2015-12-06 07:18:36 +00:00
/// <summary>Filetype in directory entries</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT2_FEATURE_INCOMPAT_FILETYPE = 0x00000002 ;
2015-12-06 07:18:36 +00:00
/// <summary>Journal needs recovery *ext3*</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT3_FEATURE_INCOMPAT_RECOVER = 0x00000004 ;
2015-12-06 07:18:36 +00:00
/// <summary>Has journal on another device *ext3*</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT3_FEATURE_INCOMPAT_JOURNAL_DEV = 0x00000008 ;
2015-12-06 07:18:36 +00:00
/// <summary>Reduced block group backups</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT2_FEATURE_INCOMPAT_META_BG = 0x00000010 ;
2015-12-06 07:18:36 +00:00
/// <summary>Volume use extents *ext4*</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT4_FEATURE_INCOMPAT_EXTENTS = 0x00000040 ;
2015-12-06 07:18:36 +00:00
/// <summary>Supports volumes bigger than 2^32 blocks *ext4*</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT4_FEATURE_INCOMPAT_64BIT = 0x00000080 ;
2015-12-06 07:18:36 +00:00
/// <summary>Multi-mount protection *ext4*</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT4_FEATURE_INCOMPAT_MMP = 0x00000100 ;
2015-12-06 07:18:36 +00:00
/// <summary>Flexible block group metadata location *ext4*</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT4_FEATURE_INCOMPAT_FLEX_BG = 0x00000200 ;
2015-12-06 07:18:36 +00:00
/// <summary>EA in inode *ext4*</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT4_FEATURE_INCOMPAT_EA_INODE = 0x00000400 ;
2015-12-06 07:18:36 +00:00
/// <summary>Data can reside in directory entry *ext4*</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT4_FEATURE_INCOMPAT_DIRDATA = 0x00001000 ;
2015-12-06 07:18:36 +00:00
2014-04-14 02:29:13 +00:00
// Miscellaneous filesystem flags
2015-12-06 07:18:36 +00:00
/// <summary>Signed dirhash in use</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT2_FLAGS_SIGNED_HASH = 0x00000001 ;
2015-12-06 07:18:36 +00:00
/// <summary>Unsigned dirhash in use</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT2_FLAGS_UNSIGNED_HASH = 0x00000002 ;
2015-12-06 07:18:36 +00:00
/// <summary>Testing development code</summary>
2016-07-28 22:25:26 +01:00
public const uint EXT2_FLAGS_TEST_FILESYS = 0x00000004 ;
2016-07-21 17:16:08 +01:00
public override Errno Mount ( )
{
return Errno . NotImplemented ;
}
2016-07-22 00:43:22 +01:00
public override Errno Mount ( bool debug )
{
return Errno . NotImplemented ;
}
2016-07-21 17:16:08 +01:00
public override Errno Unmount ( )
{
return Errno . NotImplemented ;
}
public override Errno MapBlock ( string path , long fileBlock , ref long deviceBlock )
{
return Errno . NotImplemented ;
}
public override Errno GetAttributes ( string path , ref FileAttributes attributes )
{
return Errno . NotImplemented ;
}
public override Errno ListXAttr ( string path , ref List < string > xattrs )
{
return Errno . NotImplemented ;
}
public override Errno GetXattr ( string path , string xattr , ref byte [ ] buf )
{
return Errno . NotImplemented ;
}
public override Errno Read ( string path , long offset , long size , ref byte [ ] buf )
{
return Errno . NotImplemented ;
}
public override Errno ReadDir ( string path , ref List < string > contents )
{
return Errno . NotImplemented ;
}
public override Errno StatFs ( ref FileSystemInfo stat )
{
return Errno . NotImplemented ;
}
public override Errno Stat ( string path , ref FileEntryInfo stat )
{
return Errno . NotImplemented ;
}
public override Errno ReadLink ( string path , ref string dest )
{
return Errno . NotImplemented ;
}
2014-04-14 02:29:13 +00:00
}
2014-04-14 01:14:20 +00:00
}