Source code for rawdisk.scheme.mbr

# -*- coding: utf-8 -*-


from rawdisk.util.rawstruct import RawStruct


MBR_SIGNATURE = 0xAA55
MBR_SIG_SIZE = 2
MBR_SIG_OFFSET = 0x1FE
MBR_SIZE = 512
PT_ENTRY_SIZE = 16
PT_TABLE_OFFSET = 0x1BE
PT_TABLE_SIZE = PT_ENTRY_SIZE * 4
SECTOR_SIZE = 512


[docs]class PartitionEntry(RawStruct): """Represents MBR partition entry Args: data (str): byte array to initialize structure with. Attributes: boot_indicator (ubyte): Boot indicator bit flag: 0 = no, 0x80 = \ bootable (or "active") starting_head (ubyte): Starting head for the partition starting_sector (6 bits): Starting sector for the partition starting_cylinder (10 bits): Starting cylinder for the partition part_type (ubyte): Partition type id ending_head (ubyte): Ending head of the partition ending_sector (6 bits): Ending sector ending_cylinder (10 bits): Ending cylinder relative_sector (uint): The offset from the beginning of the disk to \ the beginning of the volume, counting by sectors. total_sectors (uint): The total number of sectors in the volume. part_offset (uint): The offset from the beginning of the disk \ to the beginning of the volume, counting by bytes. See Also: | MBR Table (http://technet.microsoft.com/en-us/library/cc976786.aspx) | MBR Partition Types \ (http://en.wikipedia.org/wiki/Partition_type#List_of_partition_IDs) """ def __init__(self, data): RawStruct.__init__(self, data) self.boot_indicator = self.get_uchar(0) self.starting_head = self.get_uchar(1) tmp = self.get_uchar(2) self.starting_sector = tmp & 0x3F # Only bits 0-5 are used self.starting_cylinder = ((tmp & 0xC0) << 2) + \ self.get_uchar(3) self.part_type = self.get_uchar(4) self.ending_head = self.get_uchar(5) tmp = self.get_uchar(6) self.ending_sector = tmp & 0x3F self.ending_cylinder = ((tmp & 0xC0) << 2) + \ self.get_uchar(7) self.relative_sector = self.get_uint_le(8) self.total_sectors = self.get_uint_le(12) self.part_offset = SECTOR_SIZE*self.relative_sector
[docs]class PartitionTable(RawStruct): """Represents MBR partition table. Args: data (str): byte array to initialize structure with. Attributes: entries (list): List of initialized :class:`PartitionEntry` objects """ def __init__(self, data): RawStruct.__init__(self, data) self.entries = [] for i in range(0, 4): entry = PartitionEntry( self.get_chunk(PT_ENTRY_SIZE * i, PT_ENTRY_SIZE) ) if (entry.part_type != 0): self.entries.append(entry)
[docs]class Mbr(RawStruct): """Represents the Master Boot Record of the filesystem. Args: filename (str): path to file or device to open for reading Attributes: partition_table (PartitionTable): Initialized \ :class:`PartitionTable` object Raises: IOError: If file does not exist or is not readable. Exception: If source has invalid MBR signature """ def _load_partition_table(self): self.partition_table = PartitionTable( self.get_chunk(PT_TABLE_OFFSET, PT_TABLE_SIZE) ) def __init__(self, filename=None, load_partition_table=True): RawStruct.__init__( self, filename=filename, length=MBR_SIZE ) signature = self.get_ushort_le(MBR_SIG_OFFSET) if (signature != MBR_SIGNATURE): raise Exception("Invalid MBR signature") if (load_partition_table): self._load_partition_table()