Source code for rawdisk.scheme.gpt

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


import uuid
import struct
import logging
from rawdisk.util.rawstruct import RawStruct
from .headers import GPT_HEADER, GPT_PARTITION_ENTRY
from ctypes import c_ubyte


GPT_HEADER_OFFSET = 0x200
GPT_SIG_SIZE = 8
GPT_SIGNATURE = b'EFI PART'

logger = logging.getLogger(__name__)


[docs]class GptPartitionEntry(RawStruct): def __init__(self, data): RawStruct.__init__(self, data) self.fields = GPT_PARTITION_ENTRY( (c_ubyte * 16).from_buffer_copy( self.get_chunk(0, 16)), # type_guid (c_ubyte * 16).from_buffer_copy( self.get_chunk(0x10, 16)), # part_guid self.get_ulonglong_le(0x20), # first_lba self.get_ulonglong_le(0x28), # last_lba self.get_ulonglong_le(0x30), # attr_flags self.get_chunk(0x38, 72).decode('utf-16'), # name ) @property def type_guid(self): return uuid.UUID(bytes_le=bytes(self.fields.type_guid)) @property def part_guid(self): return uuid.UUID(bytes_le=bytes(self.fields.part_guid)) @property def first_lba(self): return self.fields.first_lba @property def last_lba(self): return self.fields.last_lba
[docs]class Gpt(object): """Represents GPT partition table. Attributes: partition_entries (list): List of initialized \ :class:`GptPartition` objects. header (GptHeader): Initialized :class:`GptHeader` object """ def __init__(self): self.__partition_entries = [] @property def partition_entries(self): return self.__partition_entries
[docs] def load(self, filename, bs=512): """Loads GPT partition table. Args: filename (str): path to file or device to open for reading bs (uint): Block size of the volume, default: 512 Raises: IOError: If file does not exist or not readable """ with open(filename, 'rb') as f: f.seek(GPT_HEADER_OFFSET + 0x0C) header_size = struct.unpack("<I", f.read(4))[0] f.seek(GPT_HEADER_OFFSET) header_data = f.read(header_size) self.header = GPT_HEADER(header_data) if (self.header.signature != GPT_SIGNATURE): raise Exception("Invalid GPT signature") self.__load_partition_entries(f, bs)
def __load_partition_entries(self, fd, bs): """Loads the list of :class:`GptPartition` partition entries Args: bs (uint): Block size of the volume """ fd.seek(self.header.part_lba * bs) for p in range(0, self.header.num_partitions): data = fd.read(self.header.part_size) entry = GptPartitionEntry(data) if entry.type_guid != uuid.UUID( '{00000000-0000-0000-0000-000000000000}' ): self.__partition_entries.append(entry) else: # stop loading on empty partition entry break