FmmtConf file saves the target guidtool used in compress/uncompress process.\\r
If do not provide, FMMT tool will search the inputfile folder for FmmtConf.ini firstly, if not found,\\r
the FmmtConf.ini saved in FMMT tool's folder will be used as default.")\r
+parser.add_argument("-s", "--ShrinkFv", dest="ShrinkFv", nargs='+',\r
+ help="Shrink the Fv file: '-s InputFvfile OutputFvfile")\r
\r
def print_banner():\r
print("")\r
else:\r
ReplaceFfs(inputfile, self.CheckFfsName(Ffs_name), newffsfile, outputfile)\r
\r
+ def Shrink(self,inputfile: str, outputfile: str) -> None:\r
+ self.SetDestPath(inputfile)\r
+ ShrinkFv(inputfile, outputfile)\r
\r
def main():\r
args=parser.parse_args()\r
fmmt.Replace(args.Replace[0],args.Replace[2],args.Replace[3],args.Replace[4],args.Replace[1])\r
else:\r
fmmt.Replace(args.Replace[0],args.Replace[1],args.Replace[2],args.Replace[3])\r
+ elif args.ShrinkFv:\r
+ fmmt.Shrink(args.ShrinkFv[0], args.ShrinkFv[1])\r
else:\r
parser.print_help()\r
except Exception as e:\r
logger.debug('Extract ffs data is saved in {}.'.format(outputfile))\r
else:\r
logger.error('Target Ffs/Fv not found!!!')\r
+\r
+def ShrinkFv(inputfile: str, outputfile: str) -> None:\r
+ if not os.path.exists(inputfile):\r
+ logger.error("Invalid inputfile, can not open {}.".format(inputfile))\r
+ raise Exception("Process Failed: Invalid inputfile!")\r
+ # 1. Data Prepare\r
+ with open(inputfile, "rb") as f:\r
+ whole_data = f.read()\r
+ FmmtParser = FMMTParser(inputfile, ROOT_TREE)\r
+ # 2. DataTree Create\r
+ logger.debug('Parsing inputfile data......')\r
+ FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)\r
+ logger.debug('Done!')\r
+ TargetFv = FmmtParser.WholeFvTree.Child[0]\r
+ if TargetFv:\r
+ FvMod = FvHandler(TargetFv)\r
+ Status = FvMod.ShrinkFv()\r
+ else:\r
+ logger.error('Target Fv not found!!!')\r
+ # 4. Data Encapsulation\r
+ if Status:\r
+ logger.debug('Start encapsulating data......')\r
+ FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)\r
+ with open(outputfile, "wb") as f:\r
+ f.write(FmmtParser.FinalData)\r
+ logger.debug('Encapsulated data is saved in {}.'.format(outputfile))\r
TargetFv.Data.Data += struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData\r
\r
class FvHandler:\r
- def __init__(self, NewFfs, TargetFfs) -> None:\r
+ def __init__(self, NewFfs, TargetFfs=None) -> None:\r
self.NewFfs = NewFfs\r
self.TargetFfs = TargetFfs\r
self.Status = False\r
self.Status = True\r
logger.debug('Done!')\r
return self.Status\r
+\r
+ def ShrinkFv(self) -> bool:\r
+ TargetFv = self.NewFfs\r
+ TargetFv.Data.Data = b''\r
+ if not TargetFv.Data.Free_Space:\r
+ self.Status = True\r
+ else:\r
+ BlockSize = TargetFv.Data.Header.BlockMap[0].Length\r
+ New_Free_Space = TargetFv.Data.Free_Space%BlockSize\r
+ Removed_Space = TargetFv.Data.Free_Space - New_Free_Space\r
+ TargetFv.Child[-1].Data.Data = b'\xff' * New_Free_Space\r
+ TargetFv.Data.Size -= Removed_Space\r
+ TargetFv.Data.Header.Fvlength = TargetFv.Data.Size\r
+ ModifyFvSystemGuid(TargetFv)\r
+ for item in TargetFv.Child:\r
+ if item.type == FFS_FREE_SPACE:\r
+ TargetFv.Data.Data += item.Data.Data + item.Data.PadData\r
+ else:\r
+ TargetFv.Data.Data += struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData\r
+ TargetFv.Data.ModFvExt()\r
+ TargetFv.Data.ModFvSize()\r
+ TargetFv.Data.ModExtHeaderData()\r
+ ModifyFvExtData(TargetFv)\r
+ TargetFv.Data.ModCheckSum()\r
+ self.Status = True\r
+ return self.Status\r