]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/FMMT/core/GuidTools.py
BaseTools: Add FMMT Python Tool
[mirror_edk2.git] / BaseTools / Source / Python / FMMT / core / GuidTools.py
diff --git a/BaseTools/Source/Python/FMMT/core/GuidTools.py b/BaseTools/Source/Python/FMMT/core/GuidTools.py
new file mode 100644 (file)
index 0000000..a256817
--- /dev/null
@@ -0,0 +1,179 @@
+## @file\r
+# This file is used to define the FMMT dependent external tool management class.\r
+#\r
+# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+##\r
+import glob\r
+import logging\r
+import os\r
+import shutil\r
+import sys\r
+import tempfile\r
+import uuid\r
+from FirmwareStorageFormat.Common import *\r
+from utils.FmmtLogger import FmmtLogger as logger\r
+import subprocess\r
+\r
+def ExecuteCommand(cmd: list) -> None:\r
+    subprocess.run(cmd,stdout=subprocess.DEVNULL)\r
+\r
+class GUIDTool:\r
+    def __init__(self, guid: str, short_name: str, command: str) -> None:\r
+        self.guid: str = guid\r
+        self.short_name: str = short_name\r
+        self.command: str = command\r
+        self.ifexist: bool = False\r
+\r
+    def pack(self, buffer: bytes) -> bytes:\r
+        """\r
+        compress file.\r
+        """\r
+        tool = self.command\r
+        if tool:\r
+            tmp = tempfile.mkdtemp(dir=os.environ.get('tmp'))\r
+            ToolInputFile = os.path.join(tmp, "pack_uncompress_sec_file")\r
+            ToolOuputFile = os.path.join(tmp, "pack_sec_file")\r
+            try:\r
+                file = open(ToolInputFile, "wb")\r
+                file.write(buffer)\r
+                file.close()\r
+                command = [tool, '-e', '-o', ToolOuputFile,\r
+                                  ToolInputFile]\r
+                ExecuteCommand(command)\r
+                buf = open(ToolOuputFile, "rb")\r
+                res_buffer = buf.read()\r
+            except Exception as msg:\r
+                logger.error(msg)\r
+                return ""\r
+            else:\r
+                buf.close()\r
+                if os.path.exists(tmp):\r
+                    shutil.rmtree(tmp)\r
+                return res_buffer\r
+        else:\r
+            logger.error(\r
+                "Error parsing section: EFI_SECTION_GUID_DEFINED cannot be parsed at this time.")\r
+            logger.info("Its GUID is: %s" % self.guid)\r
+            return ""\r
+\r
+\r
+    def unpack(self, buffer: bytes) -> bytes:\r
+        """\r
+        buffer: remove common header\r
+        uncompress file\r
+        """\r
+        tool = self.command\r
+        if tool:\r
+            tmp = tempfile.mkdtemp(dir=os.environ.get('tmp'))\r
+            ToolInputFile = os.path.join(tmp, "unpack_sec_file")\r
+            ToolOuputFile = os.path.join(tmp, "unpack_uncompress_sec_file")\r
+            try:\r
+                file = open(ToolInputFile, "wb")\r
+                file.write(buffer)\r
+                file.close()\r
+                command = [tool, '-d', '-o', ToolOuputFile, ToolInputFile]\r
+                ExecuteCommand(command)\r
+                buf = open(ToolOuputFile, "rb")\r
+                res_buffer = buf.read()\r
+            except Exception as msg:\r
+                logger.error(msg)\r
+                return ""\r
+            else:\r
+                buf.close()\r
+                if os.path.exists(tmp):\r
+                    shutil.rmtree(tmp)\r
+                return res_buffer\r
+        else:\r
+            logger.error("Error parsing section: EFI_SECTION_GUID_DEFINED cannot be parsed at this time.")\r
+            logger.info("Its GUID is: %s" % self.guid)\r
+            return ""\r
+\r
+class GUIDTools:\r
+    '''\r
+    GUIDTools is responsible for reading FMMTConfig.ini, verify the tools and provide interfaces to access those tools.\r
+    '''\r
+    default_tools = {\r
+        struct2stream(ModifyGuidFormat("a31280ad-481e-41b6-95e8-127f4c984779")): GUIDTool("a31280ad-481e-41b6-95e8-127f4c984779", "TIANO", "TianoCompress"),\r
+        struct2stream(ModifyGuidFormat("ee4e5898-3914-4259-9d6e-dc7bd79403cf")): GUIDTool("ee4e5898-3914-4259-9d6e-dc7bd79403cf", "LZMA", "LzmaCompress"),\r
+        struct2stream(ModifyGuidFormat("fc1bcdb0-7d31-49aa-936a-a4600d9dd083")): GUIDTool("fc1bcdb0-7d31-49aa-936a-a4600d9dd083", "CRC32", "GenCrc32"),\r
+        struct2stream(ModifyGuidFormat("d42ae6bd-1352-4bfb-909a-ca72a6eae889")): GUIDTool("d42ae6bd-1352-4bfb-909a-ca72a6eae889", "LZMAF86", "LzmaF86Compress"),\r
+        struct2stream(ModifyGuidFormat("3d532050-5cda-4fd0-879e-0f7f630d5afb")): GUIDTool("3d532050-5cda-4fd0-879e-0f7f630d5afb", "BROTLI", "BrotliCompress"),\r
+    }\r
+\r
+    def __init__(self, tooldef_file: str=None) -> None:\r
+        self.dir = os.path.join(os.path.dirname(__file__), "..")\r
+        self.tooldef_file = tooldef_file if tooldef_file else os.path.join(self.dir, "FmmtConf.ini")\r
+        self.tooldef = dict()\r
+\r
+    def SetConfigFile(self) -> None:\r
+        if os.environ['FmmtConfPath']:\r
+            self.tooldef_file = os.path.join(os.environ['FmmtConfPath'], 'FmmtConf.ini')\r
+        else:\r
+            PathList = os.environ['PATH']\r
+            for CurrentPath in PathList:\r
+                if os.path.exists(os.path.join(CurrentPath, 'FmmtConf.ini')):\r
+                    self.tooldef_file = os.path.join(CurrentPath, 'FmmtConf.ini')\r
+                    break\r
+\r
+    def VerifyTools(self, guidtool) -> None:\r
+        """\r
+        Verify Tools and Update Tools path.\r
+        """\r
+        path_env = os.environ.get("PATH")\r
+        path_env_list = path_env.split(os.pathsep)\r
+        path_env_list.append(os.path.dirname(__file__))\r
+        path_env_list = list(set(path_env_list))\r
+        cmd = guidtool.command\r
+        if os.path.isabs(cmd):\r
+            if not os.path.exists(cmd):\r
+                if guidtool not in self.default_tools:\r
+                    logger.error("Tool Not found %s, which causes compress/uncompress process error." % cmd)\r
+                    logger.error("Please goto edk2 repo in current console, run 'edksetup.bat rebuild' command, and try again.\n")\r
+                else:\r
+                    logger.error("Tool Not found %s, which causes compress/uncompress process error." % cmd)\r
+            else:\r
+                guidtool.ifexist = True\r
+        else:\r
+            for syspath in path_env_list:\r
+                if glob.glob(os.path.join(syspath, cmd+"*")):\r
+                    guidtool.ifexist = True\r
+                    break\r
+            else:\r
+                if guidtool not in self.default_tools:\r
+                    logger.error("Tool Not found %s, which causes compress/uncompress process error." % cmd)\r
+                    logger.error("Please goto edk2 repo in current console, run 'edksetup.bat rebuild' command, and try again.\n")\r
+                else:\r
+                    logger.error("Tool Not found %s, which causes compress/uncompress process error." % cmd)\r
+\r
+    def LoadingTools(self) -> None:\r
+        self.SetConfigFile()\r
+        if os.path.exists(self.tooldef_file):\r
+            with open(self.tooldef_file, "r") as fd:\r
+                config_data = fd.readlines()\r
+            for line in config_data:\r
+                try:\r
+                    if not line.startswith("#"):\r
+                        guid, short_name, command = line.split()\r
+                        new_format_guid = struct2stream(ModifyGuidFormat(guid.strip()))\r
+                        self.tooldef[new_format_guid] = GUIDTool(\r
+                            guid.strip(), short_name.strip(), command.strip())\r
+                except:\r
+                    logger.error("GuidTool load error!")\r
+                    continue\r
+        else:\r
+            self.tooldef.update(self.default_tools)\r
+\r
+    def __getitem__(self, guid):\r
+        if not self.tooldef:\r
+            self.LoadingTools()\r
+        guid_tool = self.tooldef.get(guid)\r
+        if guid_tool:\r
+            self.VerifyTools(guid_tool)\r
+            return guid_tool\r
+        else:\r
+            logger.error("{} GuidTool is not defined!".format(guid))\r
+            raise Exception("Process Failed: is not defined!")\r
+\r
+guidtools = GUIDTools()\r
+\r