You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
123 lines
3.8 KiB
Python
123 lines
3.8 KiB
Python
1 year ago
|
#!/usr/bin/env python
|
||
|
#############################################################
|
||
|
# ubi_reader/ubi
|
||
|
# (c) 2013 Jason Pruitt (jrspruitt@gmail.com)
|
||
|
#
|
||
|
# This program is free software: you can redistribute it and/or modify
|
||
|
# it under the terms of the GNU General Public License as published by
|
||
|
# the Free Software Foundation, either version 3 of the License, or
|
||
|
# (at your option) any later version.
|
||
|
#
|
||
|
# This program is distributed in the hope that it will be useful,
|
||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
# GNU General Public License for more details.
|
||
|
|
||
|
# You should have received a copy of the GNU General Public License
|
||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
#############################################################
|
||
|
|
||
|
from ubireader.debug import log
|
||
|
from ubireader.ubi import display
|
||
|
from ubireader.ubi.block import sort, get_blocks_in_list, rm_old_blocks
|
||
|
|
||
|
class description(object):
|
||
|
"""UBI Volume object
|
||
|
|
||
|
Attributes:
|
||
|
Int:vol_id -- Volume ID
|
||
|
Str:name -- Name of volume.
|
||
|
Obj:vol_rec -- Volume record object
|
||
|
Int:block_count -- Number of block associated with volume.
|
||
|
|
||
|
Methods:
|
||
|
display(tab) -- Print Volume information
|
||
|
Str:tab -- (optional) '\t' to preface lines with.
|
||
|
|
||
|
get_blocks(blocks) -- Returns list of block objects tied to this volume
|
||
|
|
||
|
Volume object is basically a list of block indexes and some metadata
|
||
|
describing a volume found in a UBI image.
|
||
|
"""
|
||
|
def __init__(self, vol_id, vol_rec, block_list):
|
||
|
self._vol_id = vol_id
|
||
|
self._vol_rec = vol_rec
|
||
|
self._name = self._vol_rec.name
|
||
|
self._block_list = block_list
|
||
|
log(description, 'Create Volume: %s, ID: %s, Block Cnt: %s' % (self.name, self.vol_id, len(self.block_list)))
|
||
|
|
||
|
|
||
|
def __repr__(self):
|
||
|
return 'Volume: %s' % (self.name.decode('utf-8'))
|
||
|
|
||
|
|
||
|
def _get_name(self):
|
||
|
return self._name
|
||
|
name = property(_get_name)
|
||
|
|
||
|
|
||
|
def _get_vol_id(self):
|
||
|
return self._vol_id
|
||
|
vol_id = property(_get_vol_id)
|
||
|
|
||
|
|
||
|
def _get_block_count(self):
|
||
|
return len(self._block_list)
|
||
|
block_count = property(_get_block_count)
|
||
|
|
||
|
|
||
|
def _get_vol_rec(self):
|
||
|
return self._vol_rec
|
||
|
vol_rec = property(_get_vol_rec)
|
||
|
|
||
|
|
||
|
def _get_block_list(self):
|
||
|
return self._block_list
|
||
|
block_list = property(_get_block_list)
|
||
|
|
||
|
|
||
|
def get_blocks(self, blocks):
|
||
|
return get_blocks_in_list(blocks, self._block_list)
|
||
|
|
||
|
|
||
|
def display(self, tab=''):
|
||
|
return display.volume(self, tab)
|
||
|
|
||
|
|
||
|
def reader(self, ubi):
|
||
|
last_leb = 0
|
||
|
for block in sort.by_leb(self.get_blocks(ubi.blocks)):
|
||
|
if block == 'x':
|
||
|
last_leb += 1
|
||
|
yield b'\xff'*ubi.leb_size
|
||
|
else:
|
||
|
last_leb += 1
|
||
|
yield ubi.file.read_block_data(ubi.blocks[block])
|
||
|
|
||
|
|
||
|
def get_volumes(blocks, layout_info):
|
||
|
"""Get a list of UBI volume objects from list of blocks
|
||
|
|
||
|
Arguments:
|
||
|
List:blocks -- List of layout block objects
|
||
|
List:layout_info -- Layout info (indexes of layout blocks and
|
||
|
associated data blocks.)
|
||
|
|
||
|
Returns:
|
||
|
Dict -- Of Volume objects by volume name, including any
|
||
|
relevant blocks.
|
||
|
"""
|
||
|
volumes = {}
|
||
|
|
||
|
vol_blocks_lists = sort.by_vol_id(blocks, layout_info[2])
|
||
|
for vol_rec in blocks[layout_info[0]].vtbl_recs:
|
||
|
vol_name = vol_rec.name.strip(b'\x00').decode('utf-8')
|
||
|
if vol_rec.rec_index not in vol_blocks_lists:
|
||
|
vol_blocks_lists[vol_rec.rec_index] = []
|
||
|
|
||
|
vol_blocks_lists[vol_rec.rec_index] = rm_old_blocks(blocks, vol_blocks_lists[vol_rec.rec_index])
|
||
|
volumes[vol_name] = description(vol_rec.rec_index, vol_rec, vol_blocks_lists[vol_rec.rec_index])
|
||
|
|
||
|
return volumes
|
||
|
|