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