def calculate_android_partition_size_and_offset(image_file): """Return the size and offset of the android partitions. Both the size and offset are in bytes. :param image_file: A string containing the path to the image_file. :return: A list of (offset, size) pairs. """ # Here we can use parted.Device to read the partitions because we're # reading from a regular file rather than a block device. If it was a # block device we'd need root rights. vfat_partition = None disk = Disk(Device(image_file)) partition_info = [] for partition in disk.partitions: # Will ignore any partitions before boot and of type EXTENDED if 'boot' in partition.getFlagsAsString(): vfat_partition = partition geometry = partition.geometry partition_info.append( (geometry.start * SECTOR_SIZE, geometry.length * SECTOR_SIZE)) elif (vfat_partition is not None and partition.type != PARTITION_EXTENDED): geometry = partition.geometry partition_info.append( (geometry.start * SECTOR_SIZE, geometry.length * SECTOR_SIZE)) # NB: don't use vfat_partition.nextPartition() as that might return # a partition of type PARTITION_FREESPACE; it's much easier to # iterate disk.partitions which only returns # parted.PARTITION_NORMAL partitions assert vfat_partition is not None, ("Couldn't find boot partition on %s" % image_file) assert len(partition_info) == 5 return partition_info
def get_default_sector_size(): with NamedTemporaryFile() as fp: # Truncate to zero, so that extending the size in the next call # will cause all the bytes to read as zero. Stevens $4.13 os.truncate(fp.name, 0) os.truncate(fp.name, MiB(1)) return Device(fp.name).sectorSize
def calculate_partition_size_and_offset(image_file): """Return the size and offset of the boot and root partitions. Both the size and offset are in sectors. :param image_file: A string containing the path to the image_file. :return: A 4-tuple containing the offset and size of the boot partition followed by the offset and size of the root partition. """ # Here we can use parted.Device to read the partitions because we're # reading from a regular file rather than a block device. If it was a # block device we'd need root rights. disk = Disk(Device(image_file)) vfat_partition = None linux_partition = None for partition in disk.partitions: assert partition.type == PARTITION_NORMAL, ( "Parted should only return normal partitions but got type %i" % partition.type) if 'boot' in partition.getFlagsAsString(): geometry = partition.geometry vfat_offset = geometry.start * SECTOR_SIZE vfat_size = geometry.length * SECTOR_SIZE vfat_partition = partition elif vfat_partition is not None: # next partition after boot partition is the root partition # NB: don't use vfat_partition.nextPartition() as that might return # a partition of type PARTITION_FREESPACE; it's much easier to # iterate disk.partitions which only returns # parted.PARTITION_NORMAL partitions geometry = partition.geometry linux_offset = geometry.start * SECTOR_SIZE linux_size = geometry.length * SECTOR_SIZE linux_partition = partition break assert vfat_partition is not None, ("Couldn't find boot partition on %s" % image_file) assert linux_partition is not None, ("Couldn't find root partition on %s" % image_file) return vfat_size, vfat_offset, linux_size, linux_offset