"""
Extension 2 (ext2)
Used in Linux systems
"""
from construct import *
Char = SLInt8
UChar = ULInt8
Short = SLInt16
UShort = ULInt16
Long = SLInt32
ULong = ULInt32
def BlockPointer(name):
return Struct(name,
ULong("block_number"),
OnDemandPointer(lambda ctx: ctx["block_number"]),
)
superblock = Struct("superblock",
ULong('inodes_count'),
ULong('blocks_count'),
ULong('reserved_blocks_count'),
ULong('free_blocks_count'),
ULong('free_inodes_count'),
ULong('first_data_block'),
Enum(ULong('log_block_size'),
OneKB = 0,
TwoKB = 1,
FourKB = 2,
),
Long('log_frag_size'),
ULong('blocks_per_group'),
ULong('frags_per_group'),
ULong('inodes_per_group'),
ULong('mtime'),
ULong('wtime'),
UShort('mnt_count'),
Short('max_mnt_count'),
Const(UShort('magic'), 0xEF53),
UShort('state'),
UShort('errors'),
Padding(2),
ULong('lastcheck'),
ULong('checkinterval'),
ULong('creator_os'),
ULong('rev_level'),
Padding(235 * 4),
)
group_descriptor = Struct("group_descriptor",
ULong('block_bitmap'),
ULong('inode_bitmap'),
ULong('inode_table'),
UShort('free_blocks_count'),
UShort('free_inodes_count'),
UShort('used_dirs_count'),
Padding(14),
)
inode = Struct("inode",
FlagsEnum(UShort('mode'),
IXOTH = 0x0001,
IWOTH = 0x0002,
IROTH = 0x0004,
IRWXO = 0x0007,
IXGRP = 0x0008,
IWGRP = 0x0010,
IRGRP = 0x0020,
IRWXG = 0x0038,
IXUSR = 0x0040,
IWUSR = 0x0080,
IRUSR = 0x0100,
IRWXU = 0x01C0,
ISVTX = 0x0200,
ISGID = 0x0400,
ISUID = 0x0800,
IFIFO = 0x1000,
IFCHR = 0x2000,
IFDIR = 0x4000,
IFBLK = 0x6000,
IFREG = 0x8000,
IFLNK = 0xC000,
IFSOCK = 0xA000,
IFMT = 0xF000,
),
UShort('uid'),
ULong('size'),
ULong('atime'),
ULong('ctime'),
ULong('mtime'),
ULong('dtime'),
UShort('gid'),
UShort('links_count'),
ULong('blocks'),
FlagsEnum(ULong('flags'),
SecureDelete = 0x0001,
AllowUndelete = 0x0002,
Compressed = 0x0004,
Synchronous = 0x0008,
),
Padding(4),
Array(12, ULong('blocks')),
ULong("indirect1_block"),
ULong("indirect2_block"),
ULong("indirect3_block"),
ULong('version'),
ULong('file_acl'),
ULong('dir_acl'),
ULong('faddr'),
UChar('frag'),
Byte('fsize'),
Padding(10) ,
)
# special inodes
EXT2_BAD_INO = 1
EXT2_ROOT_INO = 2
EXT2_ACL_IDX_INO = 3
EXT2_ACL_DATA_INO = 4
EXT2_BOOT_LOADER_INO = 5
EXT2_UNDEL_DIR_INO = 6
EXT2_FIRST_INO = 11
directory_record = Struct("directory_entry",
ULong("inode"),
UShort("rec_length"),
UShort("name_length"),
Field("name", lambda ctx: ctx["name_length"]),
Padding(lambda ctx: ctx["rec_length"] - ctx["name_length"])
)
if __name__ == "__main__":
print (superblock.sizeof())