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