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