def WriteEntry(image_fname, entry_path, data, do_compress=True, allow_resize=True, write_map=False): """Replace an entry in an image This replaces the data in a particular entry in an image. This size of the new data must match the size of the old data unless allow_resize is True. Args: image_fname: Image filename to process entry_path: Path to entry to extract data: Data to replace with do_compress: True to compress the data if needed, False if data is already compressed so should be used as is allow_resize: True to allow entries to change size (this does a re-pack of the entries), False to raise an exception write_map: True to write a map file Returns: Image object that was updated """ tout.Info("Write entry '%s', file '%s'" % (entry_path, image_fname)) image = Image.FromFile(image_fname) entry = image.FindEntryPath(entry_path) WriteEntryToImage(image, entry, data, do_compress=do_compress, allow_resize=allow_resize, write_map=write_map) return image
def ExtractEntries(image_fname, output_fname, outdir, entry_paths, decomp=True, alt_format=None): """Extract the data from one or more entries and write it to files Args: image_fname: Image filename to process output_fname: Single output filename to use if extracting one file, None otherwise outdir: Output directory to use (for any number of files), else None entry_paths: List of entry paths to extract decomp: True to decompress the entry data Returns: List of EntryInfo records that were written """ image = Image.FromFile(image_fname) if alt_format == 'list': ShowAltFormats(image) return # Output an entry to a single file, as a special case if output_fname: if not entry_paths: raise ValueError('Must specify an entry path to write with -f') if len(entry_paths) != 1: raise ValueError( 'Must specify exactly one entry path to write with -f') entry = image.FindEntryPath(entry_paths[0]) data = entry.ReadData(decomp, alt_format) tools.write_file(output_fname, data) tout.notice("Wrote %#x bytes to file '%s'" % (len(data), output_fname)) return # Otherwise we will output to a path given by the entry path of each entry. # This means that entries will appear in subdirectories if they are part of # a sub-section. einfos = image.GetListEntries(entry_paths)[0] tout.notice('%d entries match and will be written' % len(einfos)) for einfo in einfos: entry = einfo.entry data = entry.ReadData(decomp, alt_format) path = entry.GetPath()[1:] fname = os.path.join(outdir, path) # If this entry has children, create a directory for it and put its # data in a file called 'root' in that directory if entry.GetEntries(): if fname and not os.path.exists(fname): os.makedirs(fname) fname = os.path.join(fname, 'root') tout.notice("Write entry '%s' size %x to '%s'" % (entry.GetPath(), len(data), fname)) tools.write_file(fname, data) return einfos
def ReadEntry(image_fname, entry_path, decomp=True): """Extract an entry from an image This extracts the data from a particular entry in an image Args: image_fname: Image filename to process entry_path: Path to entry to extract decomp: True to return uncompressed data, if the data is compress False to return the raw data Returns: data extracted from the entry """ global Image from binman.image import Image image = Image.FromFile(image_fname) entry = image.FindEntryPath(entry_path) return entry.ReadData(decomp)
def ReplaceEntries(image_fname, input_fname, indir, entry_paths, do_compress=True, allow_resize=True, write_map=False): """Replace the data from one or more entries from input files Args: image_fname: Image filename to process input_fname: Single input ilename to use if replacing one file, None otherwise indir: Input directory to use (for any number of files), else None entry_paths: List of entry paths to extract do_compress: True if the input data is uncompressed and may need to be compressed if the entry requires it, False if the data is already compressed. write_map: True to write a map file Returns: List of EntryInfo records that were written """ image = Image.FromFile(image_fname) # Replace an entry from a single file, as a special case if input_fname: if not entry_paths: raise ValueError('Must specify an entry path to read with -f') if len(entry_paths) != 1: raise ValueError('Must specify exactly one entry path to write with -f') entry = image.FindEntryPath(entry_paths[0]) data = tools.ReadFile(input_fname) tout.Notice("Read %#x bytes from file '%s'" % (len(data), input_fname)) WriteEntryToImage(image, entry, data, do_compress=do_compress, allow_resize=allow_resize, write_map=write_map) return # Otherwise we will input from a path given by the entry path of each entry. # This means that files must appear in subdirectories if they are part of # a sub-section. einfos = image.GetListEntries(entry_paths)[0] tout.Notice("Replacing %d matching entries in image '%s'" % (len(einfos), image_fname)) BeforeReplace(image, allow_resize) for einfo in einfos: entry = einfo.entry if entry.GetEntries(): tout.Info("Skipping section entry '%s'" % entry.GetPath()) continue path = entry.GetPath()[1:] fname = os.path.join(indir, path) if os.path.exists(fname): tout.Notice("Write entry '%s' from file '%s'" % (entry.GetPath(), fname)) data = tools.ReadFile(fname) ReplaceOneEntry(image, entry, data, do_compress, allow_resize) else: tout.Warning("Skipping entry '%s' from missing file '%s'" % (entry.GetPath(), fname)) AfterReplace(image, allow_resize=allow_resize, write_map=write_map) return image