Source code for rawdisk.scheme.gpt
# -*- coding: utf-8 -*-
import uuid
import struct
from rawdisk.util.rawstruct import RawStruct
GPT_HEADER_OFFSET = 0x200
GPT_SIG_SIZE = 8
GPT_SIGNATURE = 'EFI PART'
[docs]class GptHeader(RawStruct):
"""Represents GUID partition table header (LBA1).
Args:
data (str): byte array to initialize structure with. \
Must be valid gpt header.
Attributes:
signature (str): "EFI PART", 45h 46h 49h 20h 50h 41h 52h 54h
revision (uint): GPT Revision
header_size (uint): Total length of gpt header
crc32 (uint): CRC32 of the header
current_lba (ulonglong): LBA location of this header
backup_lba (ulonglong): LBA loction of header's copy
first_usable_lba (ulonglong): First usable LBA for partitions
last_usable_lba (ulonglong): Last usable LBA for partitions
disk_guid (uuid): Disk GUID (UUID for Unixes)
part_lba (ulonglong): Starting LBA of array of partition entries
num_partitions (uint): Number of partition entries in array
part_size (uint): Size of a single partition entry (usually 128)
part_array_crc32 (uint): CRC32 of partition array
Raises:
Exception: If signature does not match valid GPT signature
See Also:
http://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_table_header_.28LBA_1.29
"""
def __init__(self, data):
RawStruct.__init__(self, data)
self.signature = self.get_string(0, 8)
if (self.signature != GPT_SIGNATURE):
raise Exception("Invalid GPT signature")
self.revision = self.get_uint_le(0x08)
self.header_size = self.get_uint_le(0x0C)
self.crc32 = self.get_uint_le(0x10)
# 4 bytes @0x14 reserved, must be 0
self.current_lba = self.get_ulonglong_le(0x18)
self.backup_lba = self.get_ulonglong_le(0x20)
self.first_usable_lba = self.get_ulonglong_le(0x28)
self.last_usable_lba = self.get_ulonglong_le(0x30)
self.disk_guid = self.get_uuid_le(0x38)
self.part_lba = self.get_ulonglong_le(0x48)
self.num_partitions = self.get_uint_le(0x50)
self.part_size = self.get_uint_le(0x54)
self.part_array_crc32 = self.get_uint_le(0x58)
# Rest of bytes @ 0x5C must be zeroes (420 for 512 sectors)
[docs]class GptPartitionEntry(RawStruct):
"""Represents GPT partition entry.
Args:
data (str): byte array that belongs to valid GPT partition entry.
Attributes:
type_guid (uuid): Partition type GUID
part_guid (uuid): Unique partition GUID
first_lba (ulonglong): First LBA of partition
last_lba (ulonglong): Last LBA of partition
attr_flags (ulonglong): Attribute flags (e.g. bit 60 denotes read-only)
name (str): Partition name (36 UTF-16LE code units)
See Also:
http://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_entries
"""
def __init__(self, data):
RawStruct.__init__(self, data)
self.type_guid = self.get_uuid_le(0x00)
self.part_guid = self.get_uuid_le(0x10)
self.first_lba = self.get_ulonglong_le(0x20)
self.last_lba = self.get_ulonglong_le(0x28)
self.attr_flags = self.get_ulonglong_le(0x30)
self.name = self.get_chunk(
0x38, 72).decode('utf-16').partition(b'\0')[0]
[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 = []
[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)
self.header = GptHeader(f.read(header_size))
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 xrange(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