]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/FMMT/core/GuidTools.py
a25681709bc86a010f4bfb45228741fe883348a8
[mirror_edk2.git] / BaseTools / Source / Python / FMMT / core / GuidTools.py
1 ## @file
2 # This file is used to define the FMMT dependent external tool management class.
3 #
4 # Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
5 # SPDX-License-Identifier: BSD-2-Clause-Patent
6 ##
7 import glob
8 import logging
9 import os
10 import shutil
11 import sys
12 import tempfile
13 import uuid
14 from FirmwareStorageFormat.Common import *
15 from utils.FmmtLogger import FmmtLogger as logger
16 import subprocess
17
18 def ExecuteCommand(cmd: list) -> None:
19 subprocess.run(cmd,stdout=subprocess.DEVNULL)
20
21 class GUIDTool:
22 def __init__(self, guid: str, short_name: str, command: str) -> None:
23 self.guid: str = guid
24 self.short_name: str = short_name
25 self.command: str = command
26 self.ifexist: bool = False
27
28 def pack(self, buffer: bytes) -> bytes:
29 """
30 compress file.
31 """
32 tool = self.command
33 if tool:
34 tmp = tempfile.mkdtemp(dir=os.environ.get('tmp'))
35 ToolInputFile = os.path.join(tmp, "pack_uncompress_sec_file")
36 ToolOuputFile = os.path.join(tmp, "pack_sec_file")
37 try:
38 file = open(ToolInputFile, "wb")
39 file.write(buffer)
40 file.close()
41 command = [tool, '-e', '-o', ToolOuputFile,
42 ToolInputFile]
43 ExecuteCommand(command)
44 buf = open(ToolOuputFile, "rb")
45 res_buffer = buf.read()
46 except Exception as msg:
47 logger.error(msg)
48 return ""
49 else:
50 buf.close()
51 if os.path.exists(tmp):
52 shutil.rmtree(tmp)
53 return res_buffer
54 else:
55 logger.error(
56 "Error parsing section: EFI_SECTION_GUID_DEFINED cannot be parsed at this time.")
57 logger.info("Its GUID is: %s" % self.guid)
58 return ""
59
60
61 def unpack(self, buffer: bytes) -> bytes:
62 """
63 buffer: remove common header
64 uncompress file
65 """
66 tool = self.command
67 if tool:
68 tmp = tempfile.mkdtemp(dir=os.environ.get('tmp'))
69 ToolInputFile = os.path.join(tmp, "unpack_sec_file")
70 ToolOuputFile = os.path.join(tmp, "unpack_uncompress_sec_file")
71 try:
72 file = open(ToolInputFile, "wb")
73 file.write(buffer)
74 file.close()
75 command = [tool, '-d', '-o', ToolOuputFile, ToolInputFile]
76 ExecuteCommand(command)
77 buf = open(ToolOuputFile, "rb")
78 res_buffer = buf.read()
79 except Exception as msg:
80 logger.error(msg)
81 return ""
82 else:
83 buf.close()
84 if os.path.exists(tmp):
85 shutil.rmtree(tmp)
86 return res_buffer
87 else:
88 logger.error("Error parsing section: EFI_SECTION_GUID_DEFINED cannot be parsed at this time.")
89 logger.info("Its GUID is: %s" % self.guid)
90 return ""
91
92 class GUIDTools:
93 '''
94 GUIDTools is responsible for reading FMMTConfig.ini, verify the tools and provide interfaces to access those tools.
95 '''
96 default_tools = {
97 struct2stream(ModifyGuidFormat("a31280ad-481e-41b6-95e8-127f4c984779")): GUIDTool("a31280ad-481e-41b6-95e8-127f4c984779", "TIANO", "TianoCompress"),
98 struct2stream(ModifyGuidFormat("ee4e5898-3914-4259-9d6e-dc7bd79403cf")): GUIDTool("ee4e5898-3914-4259-9d6e-dc7bd79403cf", "LZMA", "LzmaCompress"),
99 struct2stream(ModifyGuidFormat("fc1bcdb0-7d31-49aa-936a-a4600d9dd083")): GUIDTool("fc1bcdb0-7d31-49aa-936a-a4600d9dd083", "CRC32", "GenCrc32"),
100 struct2stream(ModifyGuidFormat("d42ae6bd-1352-4bfb-909a-ca72a6eae889")): GUIDTool("d42ae6bd-1352-4bfb-909a-ca72a6eae889", "LZMAF86", "LzmaF86Compress"),
101 struct2stream(ModifyGuidFormat("3d532050-5cda-4fd0-879e-0f7f630d5afb")): GUIDTool("3d532050-5cda-4fd0-879e-0f7f630d5afb", "BROTLI", "BrotliCompress"),
102 }
103
104 def __init__(self, tooldef_file: str=None) -> None:
105 self.dir = os.path.join(os.path.dirname(__file__), "..")
106 self.tooldef_file = tooldef_file if tooldef_file else os.path.join(self.dir, "FmmtConf.ini")
107 self.tooldef = dict()
108
109 def SetConfigFile(self) -> None:
110 if os.environ['FmmtConfPath']:
111 self.tooldef_file = os.path.join(os.environ['FmmtConfPath'], 'FmmtConf.ini')
112 else:
113 PathList = os.environ['PATH']
114 for CurrentPath in PathList:
115 if os.path.exists(os.path.join(CurrentPath, 'FmmtConf.ini')):
116 self.tooldef_file = os.path.join(CurrentPath, 'FmmtConf.ini')
117 break
118
119 def VerifyTools(self, guidtool) -> None:
120 """
121 Verify Tools and Update Tools path.
122 """
123 path_env = os.environ.get("PATH")
124 path_env_list = path_env.split(os.pathsep)
125 path_env_list.append(os.path.dirname(__file__))
126 path_env_list = list(set(path_env_list))
127 cmd = guidtool.command
128 if os.path.isabs(cmd):
129 if not os.path.exists(cmd):
130 if guidtool not in self.default_tools:
131 logger.error("Tool Not found %s, which causes compress/uncompress process error." % cmd)
132 logger.error("Please goto edk2 repo in current console, run 'edksetup.bat rebuild' command, and try again.\n")
133 else:
134 logger.error("Tool Not found %s, which causes compress/uncompress process error." % cmd)
135 else:
136 guidtool.ifexist = True
137 else:
138 for syspath in path_env_list:
139 if glob.glob(os.path.join(syspath, cmd+"*")):
140 guidtool.ifexist = True
141 break
142 else:
143 if guidtool not in self.default_tools:
144 logger.error("Tool Not found %s, which causes compress/uncompress process error." % cmd)
145 logger.error("Please goto edk2 repo in current console, run 'edksetup.bat rebuild' command, and try again.\n")
146 else:
147 logger.error("Tool Not found %s, which causes compress/uncompress process error." % cmd)
148
149 def LoadingTools(self) -> None:
150 self.SetConfigFile()
151 if os.path.exists(self.tooldef_file):
152 with open(self.tooldef_file, "r") as fd:
153 config_data = fd.readlines()
154 for line in config_data:
155 try:
156 if not line.startswith("#"):
157 guid, short_name, command = line.split()
158 new_format_guid = struct2stream(ModifyGuidFormat(guid.strip()))
159 self.tooldef[new_format_guid] = GUIDTool(
160 guid.strip(), short_name.strip(), command.strip())
161 except:
162 logger.error("GuidTool load error!")
163 continue
164 else:
165 self.tooldef.update(self.default_tools)
166
167 def __getitem__(self, guid):
168 if not self.tooldef:
169 self.LoadingTools()
170 guid_tool = self.tooldef.get(guid)
171 if guid_tool:
172 self.VerifyTools(guid_tool)
173 return guid_tool
174 else:
175 logger.error("{} GuidTool is not defined!".format(guid))
176 raise Exception("Process Failed: is not defined!")
177
178 guidtools = GUIDTools()
179