X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2FFMMT%2Fcore%2FFMMTOperation.py;fp=BaseTools%2FSource%2FPython%2FFMMT%2Fcore%2FFMMTOperation.py;h=c2cc2e2467407168a1d0d8a33ab48df4c3e2a6f3;hp=0000000000000000000000000000000000000000;hb=a64b944942d828fe98e4843929662aad7f47bcca;hpb=101f4c789221716585b972f2c2a22a85c078ef1d diff --git a/BaseTools/Source/Python/FMMT/core/FMMTOperation.py b/BaseTools/Source/Python/FMMT/core/FMMTOperation.py new file mode 100644 index 0000000000..c2cc2e2467 --- /dev/null +++ b/BaseTools/Source/Python/FMMT/core/FMMTOperation.py @@ -0,0 +1,197 @@ +## @file +# This file is used to define the functions to operate bios binary file. +# +# Copyright (c) 2021-, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## +from core.FMMTParser import * +from core.FvHandler import * +from utils.FvLayoutPrint import * +from utils.FmmtLogger import FmmtLogger as logger + +global Fv_count +Fv_count = 0 + +# The ROOT_TYPE can be 'ROOT_TREE', 'ROOT_FV_TREE', 'ROOT_FFS_TREE', 'ROOT_SECTION_TREE' +def ViewFile(inputfile: str, ROOT_TYPE: str, layoutfile: str=None, outputfile: str=None) -> None: + if not os.path.exists(inputfile): + logger.error("Invalid inputfile, can not open {}.".format(inputfile)) + raise Exception("Process Failed: Invalid inputfile!") + # 1. Data Prepare + with open(inputfile, "rb") as f: + whole_data = f.read() + FmmtParser = FMMTParser(inputfile, ROOT_TYPE) + # 2. DataTree Create + logger.debug('Parsing inputfile data......') + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data) + logger.debug('Done!') + # 3. Log Output + InfoDict = FmmtParser.WholeFvTree.ExportTree() + logger.debug('BinaryTree created, start parsing BinaryTree data......') + FmmtParser.WholeFvTree.parserTree(InfoDict, FmmtParser.BinaryInfo) + logger.debug('Done!') + GetFormatter("").LogPrint(FmmtParser.BinaryInfo) + if layoutfile: + if os.path.splitext(layoutfile)[1]: + layoutfilename = layoutfile + layoutfileformat = os.path.splitext(layoutfile)[1][1:].lower() + else: + layoutfilename = "Layout_{}{}".format(os.path.basename(inputfile),".{}".format(layoutfile.lower())) + layoutfileformat = layoutfile.lower() + GetFormatter(layoutfileformat).dump(InfoDict, FmmtParser.BinaryInfo, layoutfilename) + # 4. Data Encapsulation + if outputfile: + logger.debug('Start encapsulating data......') + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False) + with open(outputfile, "wb") as f: + f.write(FmmtParser.FinalData) + logger.debug('Encapsulated data is saved in {}.'.format(outputfile)) + +def DeleteFfs(inputfile: str, TargetFfs_name: str, outputfile: str, Fv_name: str=None) -> None: + if not os.path.exists(inputfile): + logger.error("Invalid inputfile, can not open {}.".format(inputfile)) + raise Exception("Process Failed: Invalid inputfile!") + # 1. Data Prepare + with open(inputfile, "rb") as f: + whole_data = f.read() + FmmtParser = FMMTParser(inputfile, ROOT_TREE) + # 2. DataTree Create + logger.debug('Parsing inputfile data......') + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data) + logger.debug('Done!') + # 3. Data Modify + FmmtParser.WholeFvTree.FindNode(TargetFfs_name, FmmtParser.WholeFvTree.Findlist) + # Choose the Specfic DeleteFfs with Fv info + if Fv_name: + for item in FmmtParser.WholeFvTree.Findlist: + if item.Parent.key != Fv_name and item.Parent.Data.Name != Fv_name: + FmmtParser.WholeFvTree.Findlist.remove(item) + Status = False + if FmmtParser.WholeFvTree.Findlist != []: + for Delete_Ffs in FmmtParser.WholeFvTree.Findlist: + FfsMod = FvHandler(None, Delete_Ffs) + Status = FfsMod.DeleteFfs() + else: + logger.error('Target Ffs not found!!!') + # 4. Data Encapsulation + if Status: + logger.debug('Start encapsulating data......') + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False) + with open(outputfile, "wb") as f: + f.write(FmmtParser.FinalData) + logger.debug('Encapsulated data is saved in {}.'.format(outputfile)) + +def AddNewFfs(inputfile: str, Fv_name: str, newffsfile: str, outputfile: str) -> None: + if not os.path.exists(inputfile): + logger.error("Invalid inputfile, can not open {}.".format(inputfile)) + raise Exception("Process Failed: Invalid inputfile!") + if not os.path.exists(newffsfile): + logger.error("Invalid ffsfile, can not open {}.".format(newffsfile)) + raise Exception("Process Failed: Invalid ffs file!") + # 1. Data Prepare + with open(inputfile, "rb") as f: + whole_data = f.read() + FmmtParser = FMMTParser(inputfile, ROOT_TREE) + # 2. DataTree Create + logger.debug('Parsing inputfile data......') + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data) + logger.debug('Done!') + # Get Target Fv and Target Ffs_Pad + FmmtParser.WholeFvTree.FindNode(Fv_name, FmmtParser.WholeFvTree.Findlist) + # Create new ffs Tree + with open(newffsfile, "rb") as f: + new_ffs_data = f.read() + NewFmmtParser = FMMTParser(newffsfile, ROOT_FFS_TREE) + Status = False + # 3. Data Modify + if FmmtParser.WholeFvTree.Findlist: + for TargetFv in FmmtParser.WholeFvTree.Findlist: + TargetFfsPad = TargetFv.Child[-1] + logger.debug('Parsing newffsfile data......') + if TargetFfsPad.type == FFS_FREE_SPACE: + NewFmmtParser.ParserFromRoot(NewFmmtParser.WholeFvTree, new_ffs_data, TargetFfsPad.Data.HOffset) + else: + NewFmmtParser.ParserFromRoot(NewFmmtParser.WholeFvTree, new_ffs_data, TargetFfsPad.Data.HOffset+TargetFfsPad.Data.Size) + logger.debug('Done!') + FfsMod = FvHandler(NewFmmtParser.WholeFvTree.Child[0], TargetFfsPad) + Status = FfsMod.AddFfs() + else: + logger.error('Target Fv not found!!!') + # 4. Data Encapsulation + if Status: + logger.debug('Start encapsulating data......') + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False) + with open(outputfile, "wb") as f: + f.write(FmmtParser.FinalData) + logger.debug('Encapsulated data is saved in {}.'.format(outputfile)) + +def ReplaceFfs(inputfile: str, Ffs_name: str, newffsfile: str, outputfile: str, Fv_name: str=None) -> None: + if not os.path.exists(inputfile): + logger.error("Invalid inputfile, can not open {}.".format(inputfile)) + raise Exception("Process Failed: Invalid inputfile!") + # 1. Data Prepare + with open(inputfile, "rb") as f: + whole_data = f.read() + FmmtParser = FMMTParser(inputfile, ROOT_TREE) + # 2. DataTree Create + logger.debug('Parsing inputfile data......') + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data) + logger.debug('Done!') + with open(newffsfile, "rb") as f: + new_ffs_data = f.read() + newFmmtParser = FMMTParser(newffsfile, FV_TREE) + logger.debug('Parsing newffsfile data......') + newFmmtParser.ParserFromRoot(newFmmtParser.WholeFvTree, new_ffs_data) + logger.debug('Done!') + Status = False + # 3. Data Modify + new_ffs = newFmmtParser.WholeFvTree.Child[0] + new_ffs.Data.PadData = GetPadSize(new_ffs.Data.Size, FFS_COMMON_ALIGNMENT) * b'\xff' + FmmtParser.WholeFvTree.FindNode(Ffs_name, FmmtParser.WholeFvTree.Findlist) + if Fv_name: + for item in FmmtParser.WholeFvTree.Findlist: + if item.Parent.key != Fv_name and item.Parent.Data.Name != Fv_name: + FmmtParser.WholeFvTree.Findlist.remove(item) + if FmmtParser.WholeFvTree.Findlist != []: + for TargetFfs in FmmtParser.WholeFvTree.Findlist: + FfsMod = FvHandler(newFmmtParser.WholeFvTree.Child[0], TargetFfs) + Status = FfsMod.ReplaceFfs() + else: + logger.error('Target Ffs not found!!!') + # 4. Data Encapsulation + if Status: + logger.debug('Start encapsulating data......') + FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False) + with open(outputfile, "wb") as f: + f.write(FmmtParser.FinalData) + logger.debug('Encapsulated data is saved in {}.'.format(outputfile)) + +def ExtractFfs(inputfile: str, Ffs_name: str, outputfile: str, Fv_name: str=None) -> None: + if not os.path.exists(inputfile): + logger.error("Invalid inputfile, can not open {}.".format(inputfile)) + raise Exception("Process Failed: Invalid inputfile!") + # 1. Data Prepare + with open(inputfile, "rb") as f: + whole_data = f.read() + FmmtParser = FMMTParser(inputfile, ROOT_TREE) + # 2. DataTree Create + logger.debug('Parsing inputfile data......') + FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data) + logger.debug('Done!') + FmmtParser.WholeFvTree.FindNode(Ffs_name, FmmtParser.WholeFvTree.Findlist) + if Fv_name: + for item in FmmtParser.WholeFvTree.Findlist: + if item.Parent.key != Fv_name and item.Parent.Data.Name != Fv_name: + FmmtParser.WholeFvTree.Findlist.remove(item) + if FmmtParser.WholeFvTree.Findlist != []: + TargetNode = FmmtParser.WholeFvTree.Findlist[0] + TargetFv = TargetNode.Parent + if TargetFv.Data.Header.Attributes & EFI_FVB2_ERASE_POLARITY: + TargetNode.Data.Header.State = c_uint8( + ~TargetNode.Data.Header.State) + FinalData = struct2stream(TargetNode.Data.Header) + TargetNode.Data.Data + with open(outputfile, "wb") as f: + f.write(FinalData) + logger.debug('Extract ffs data is saved in {}.'.format(outputfile)) + else: + logger.error('Target Ffs not found!!!')