|
4 | 4 | import logging |
5 | 5 | import mmap |
6 | 6 | from dataclasses import dataclass |
7 | | -from functools import singledispatchmethod |
| 7 | +from typing import cast |
8 | 8 | from uuid import UUID |
9 | 9 |
|
10 | 10 | import archinfo |
@@ -104,40 +104,36 @@ def __init__(self, *args, **kwargs) -> None: |
104 | 104 | if self.loader._main_object is self: |
105 | 105 | self.loader._main_object = None |
106 | 106 |
|
107 | | - @singledispatchmethod |
108 | | - def _load(self, uefi_obj): # pylint: disable=no-self-use |
109 | | - raise CLEUnknownFormatError(f"Can't load firmware object: {uefi_obj}") |
| 107 | + def _load(self, uefi_obj): |
| 108 | + if uefi_obj is None: |
| 109 | + return |
| 110 | + if uefi_firmware is None: |
| 111 | + raise ImportError("The UEFI backend requires the uefi-firmware package") |
| 112 | + |
| 113 | + is_firmware_file = isinstance(uefi_obj, uefi_firmware.uefi.FirmwareFile) |
| 114 | + old_uuid = self._current_file |
| 115 | + if is_firmware_file: |
| 116 | + if uefi_obj.type == 7: # driver |
| 117 | + uuid = UUID(bytes=uefi_obj.guid) |
| 118 | + self._drivers_pending[uuid] = UefiModulePending() |
| 119 | + self._current_file = uuid |
| 120 | + elif isinstance(uefi_obj, uefi_firmware.uefi.FirmwareFileSystemSection): |
| 121 | + pending = self._drivers_pending.get(self._current_file) if self._current_file is not None else None |
| 122 | + if pending is not None: |
| 123 | + if uefi_obj.type == 16: # pe32 image |
| 124 | + pending.pe_image = cast(bytes, uefi_obj.content) |
| 125 | + elif uefi_obj.type == 18: # te image |
| 126 | + pending.te_image = cast(bytes, uefi_obj.content) |
| 127 | + elif uefi_obj.type == 21: # user interface name |
| 128 | + pending.name = cast(bytes, uefi_obj.content).decode("utf-16").strip("\0") |
| 129 | + elif not isinstance(uefi_obj, uefi_firmware.FirmwareObject): |
| 130 | + raise CLEUnknownFormatError(f"Can't load firmware object: {uefi_obj}") |
110 | 131 |
|
111 | | - @_load.register |
112 | | - def _load_generic(self, uefi_obj: uefi_firmware.FirmwareObject): |
113 | 132 | for obj in uefi_obj.objects: |
114 | 133 | self._load(obj) |
115 | 134 |
|
116 | | - @_load.register |
117 | | - def _load_none(self, uefi_obj: None): |
118 | | - pass |
119 | | - |
120 | | - @_load.register |
121 | | - def _load_firmwarefile(self, uefi_obj: uefi_firmware.uefi.FirmwareFile): |
122 | | - old_uuid = self._current_file |
123 | | - if uefi_obj.type == 7: # driver |
124 | | - uuid = UUID(bytes=uefi_obj.guid) |
125 | | - self._drivers_pending[uuid] = UefiModulePending() |
126 | | - self._current_file = uuid |
127 | | - self._load_generic(uefi_obj) |
128 | | - self._current_file = old_uuid |
129 | | - |
130 | | - @_load.register |
131 | | - def _load_firmwarefilesection(self, uefi_obj: uefi_firmware.uefi.FirmwareFileSystemSection): |
132 | | - pending = self._drivers_pending.get(self._current_file, None) |
133 | | - if pending is not None: |
134 | | - if uefi_obj.type == 16: # pe32 image |
135 | | - pending.pe_image = uefi_obj.content |
136 | | - elif uefi_obj.type == 18: # te image |
137 | | - pending.te_image = uefi_obj.content |
138 | | - elif uefi_obj.type == 21: # user interface name |
139 | | - pending.name = uefi_obj.content.decode("utf-16").strip("\0") |
140 | | - self._load_generic(uefi_obj) |
| 135 | + if is_firmware_file: |
| 136 | + self._current_file = old_uuid |
141 | 137 |
|
142 | 138 |
|
143 | 139 | @dataclass |
@@ -184,7 +180,7 @@ def __init__(self, *args, guid: UUID, name: str | None, **kwargs): |
184 | 180 | def __repr__(self): |
185 | 181 | return ( |
186 | 182 | f"<{type(self).__name__} Object " |
187 | | - f'{self.guid}{f" {self.user_interface_name}" if self.user_interface_name else ""}, ' |
| 183 | + f"{self.guid}{f' {self.user_interface_name}' if self.user_interface_name else ''}, " |
188 | 184 | f"maps [{self.min_addr:#x}:{self.max_addr:#x}]>" |
189 | 185 | ) |
190 | 186 |
|
|
0 commit comments