OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
OpenCoreUefiUnloadDrivers.c
Go to the documentation of this file.
1
11#include <Uefi.h>
12
13#include <Library/UefiLib.h>
14#include <Library/BaseLib.h>
15#include <Library/DebugLib.h>
16#include <Library/DevicePathLib.h>
17#include <Library/MemoryAllocationLib.h>
18#include <Library/PrintLib.h>
19#include <Library/UefiBootServicesTableLib.h>
20
22
23#include <PiDxe.h>
24
25#include <Protocol/ComponentName2.h>
26#include <Protocol/ComponentName.h>
27#include <Protocol/DriverBinding.h>
28#include <Protocol/FirmwareVolume2.h>
29#include <Protocol/LoadedImage.h>
30
31typedef
32VOID
34 IN VOID *Context,
35 IN CONST CHAR16 *Name,
36 IN EFI_HANDLE Handle
37 );
38
39typedef struct {
40 CHAR16 *UnloadName;
41 BOOLEAN Unloaded;
43
48
49typedef struct {
50 CHAR8 *FileBuffer;
53
66CHAR8 *
67EFIAPI
69 IN CONST CHAR8 *SupportedLanguages,
70 IN CONST CHAR8 *InputLanguage,
71 IN BOOLEAN Iso639Language
72 )
73{
74 CHAR8 *BestLanguage;
75
76 BestLanguage = GetBestLanguage (
77 SupportedLanguages,
78 Iso639Language,
79 (InputLanguage != NULL) ? InputLanguage : "",
80 SupportedLanguages,
81 NULL
82 );
83
84 return BestLanguage;
85}
86
97CONST CHAR16 *
98EFIAPI
100 IN CONST EFI_HANDLE TheHandle,
101 IN CONST CHAR8 *Language
102 )
103{
104 EFI_COMPONENT_NAME2_PROTOCOL *CompNameStruct;
105 EFI_STATUS Status;
106 CHAR16 *RetVal;
107 CHAR8 *BestLang;
108
109 BestLang = NULL;
110
111 Status = gBS->OpenProtocol (
112 TheHandle,
113 &gEfiComponentName2ProtocolGuid,
114 (VOID **)&CompNameStruct,
116 NULL,
117 EFI_OPEN_PROTOCOL_GET_PROTOCOL
118 );
119 if (!EFI_ERROR (Status)) {
120 BestLang = GetBestLanguageForDriver (CompNameStruct->SupportedLanguages, Language, FALSE);
121 Status = CompNameStruct->GetDriverName (CompNameStruct, BestLang, &RetVal);
122 if (BestLang != NULL) {
123 FreePool (BestLang);
124 BestLang = NULL;
125 }
126
127 if (!EFI_ERROR (Status)) {
128 return (RetVal);
129 }
130 }
131
132 Status = gBS->OpenProtocol (
133 TheHandle,
135 (VOID **)&CompNameStruct,
137 NULL,
138 EFI_OPEN_PROTOCOL_GET_PROTOCOL
139 );
140 if (!EFI_ERROR (Status)) {
141 BestLang = GetBestLanguageForDriver (CompNameStruct->SupportedLanguages, Language, FALSE);
142 Status = CompNameStruct->GetDriverName (CompNameStruct, BestLang, &RetVal);
143 if (BestLang != NULL) {
144 FreePool (BestLang);
145 }
146
147 if (!EFI_ERROR (Status)) {
148 return (RetVal);
149 }
150 }
151
152 return (NULL);
153}
154
155VOID
157 IN VOID *Context,
158 IN CONST CHAR16 *Name,
159 IN EFI_HANDLE Handle
160 )
161{
162 DRIVER_REPORT_CONTEXT *ReportContext;
163
164 ReportContext = Context;
165
167 &ReportContext->FileBuffer,
168 &ReportContext->FileBufferSize,
169 "%s\n",
170 Name
171 );
172}
173
174VOID
176 IN VOID *Context,
177 IN CONST CHAR16 *Name,
178 IN EFI_HANDLE Handle
179 )
180{
181 EFI_STATUS Status;
182 UINTN Index;
183 UNLOAD_IMAGE_CONTEXT *UnloadContext;
184
185 UnloadContext = Context;
186
187 for (Index = 0; Index < UnloadContext->UnloadNameCount; Index++) {
188 if (StrCmp (UnloadContext->UnloadInfo[Index].UnloadName, Name) == 0) {
189 Status = gBS->UnloadImage (Handle);
190 DEBUG ((
191 EFI_ERROR (Status) ? DEBUG_WARN : DEBUG_INFO,
192 "OC: UnloadImage %s - %r\n",
193 UnloadContext->UnloadInfo[Index].UnloadName,
194 Status
195 ));
196 UnloadContext->UnloadInfo[Index].Unloaded = TRUE;
197 break;
198 }
199 }
200}
201
202//
203// Perform action for all driver binding protocols which are
204// present on the same handle as loaded image protocol and
205// where the handle has a usable name.
206//
207// Note: In terms of choosing a name to identify the driver, while the loaded image
208// section name is shorter and corresponds better to the driver's file name, and the
209// firmware volume GUID from the loaded image path identifies the driver more uniquely,
210// these are both not always available for a loaded image (across various firmware),
211// whereas the driver component name normally is.
212//
213VOID
215 IN VOID *Context,
216 PROCESS_IMAGE ProcessImage,
217 BOOLEAN Ascending
218 )
219{
220 EFI_STATUS Status;
221 UINTN HandleCount;
222 EFI_HANDLE *HandleBuffer;
223 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
224 UINTN Index;
225 CONST CHAR16 *Name;
226
227 Status = gBS->LocateHandleBuffer (
228 ByProtocol,
230 NULL,
231 &HandleCount,
232 &HandleBuffer
233 );
234 if (EFI_ERROR (Status)) {
235 return;
236 }
237
238 for (
239 Ascending ? (Index = 0) : (Index = HandleCount - 1);
240 Index < HandleCount;
241 Ascending ? Index++ : Index--
242 )
243 {
244 Status = gBS->HandleProtocol (
245 HandleBuffer[Index],
247 (VOID **)&LoadedImage
248 );
249 if (!EFI_ERROR (Status)) {
250 Name = GetStringNameFromHandle (HandleBuffer[Index], NULL);
251 if (Name != NULL) {
252 ProcessImage (Context, Name, HandleBuffer[Index]);
253 }
254 }
255 }
256
257 FreePool (HandleBuffer);
258
259 return;
260}
261
262VOID
264 IN OC_GLOBAL_CONFIG *Config
265 )
266{
267 UINTN Index;
268 UINTN Index2;
269 UINTN UnloadInfoSize;
270 UNLOAD_IMAGE_CONTEXT UnloadContext;
271
272 if (Config->Uefi.Unload.Count == 0) {
273 return;
274 }
275
276 if (!BaseOverflowMulUN (
277 Config->Uefi.Unload.Count,
278 sizeof (*UnloadContext.UnloadInfo),
279 &UnloadInfoSize
280 ))
281 {
282 UnloadContext.UnloadInfo = AllocateZeroPool (UnloadInfoSize);
283 } else {
284 UnloadContext.UnloadInfo = NULL;
285 }
286
287 if (UnloadContext.UnloadInfo == NULL) {
288 DEBUG ((DEBUG_ERROR, "OC: Failed to allocate unload names!\n"));
289 return;
290 }
291
292 for (Index = 0; Index < Config->Uefi.Unload.Count; ++Index) {
293 UnloadContext.UnloadInfo[Index].UnloadName = AsciiStrCopyToUnicode (
295 Config->Uefi.Unload.Values[Index]
296 ),
297 0
298 );
299 if (UnloadContext.UnloadInfo[Index].UnloadName == NULL) {
300 for (Index2 = 0; Index2 < Index; ++Index2) {
301 FreePool (UnloadContext.UnloadInfo[Index2].UnloadName);
302 }
303
304 FreePool (UnloadContext.UnloadInfo);
305 DEBUG ((DEBUG_ERROR, "OC: Failed to allocate unload names!\n"));
306 return;
307 }
308 }
309
310 UnloadContext.UnloadNameCount = Config->Uefi.Unload.Count;
311
312 ProcessAllDrivers (&UnloadContext, UnloadImageByName, FALSE);
313
314 for (Index = 0; Index < Config->Uefi.Unload.Count; ++Index) {
315 if (!UnloadContext.UnloadInfo[Index].Unloaded) {
316 DEBUG ((DEBUG_INFO, "OC: Unload %s - %r\n", UnloadContext.UnloadInfo[Index].UnloadName, EFI_NOT_FOUND));
317 }
318
319 FreePool (UnloadContext.UnloadInfo[Index].UnloadName);
320 }
321
322 FreePool (UnloadContext.UnloadInfo);
323
324 return;
325}
326
327EFI_STATUS
329 IN EFI_FILE_PROTOCOL *Root
330 )
331{
332 EFI_STATUS Status;
333 DRIVER_REPORT_CONTEXT Context;
334 CHAR16 TmpFileName[32];
335
336 ASSERT (Root != NULL);
337
338 Context.FileBufferSize = SIZE_1KB;
339 Context.FileBuffer = AllocateZeroPool (Context.FileBufferSize);
340 if (Context.FileBuffer == NULL) {
341 return EFI_OUT_OF_RESOURCES;
342 }
343
344 ProcessAllDrivers (&Context, ReportImageName, TRUE);
345
346 //
347 // Save dumped driver info to file.
348 //
349 if (Context.FileBuffer != NULL) {
350 UnicodeSPrint (TmpFileName, sizeof (TmpFileName), L"DriverImageNames.txt");
351 Status = OcSetFileData (Root, TmpFileName, Context.FileBuffer, (UINT32)AsciiStrLen (Context.FileBuffer));
352 DEBUG ((DEBUG_INFO, "OC: Dumped driver info - %r\n", Status));
353
354 FreePool (Context.FileBuffer);
355 }
356
357 return EFI_SUCCESS;
358}
EFI_HANDLE gImageHandle
EFI_BOOT_SERVICES * gBS
EFI_STATUS OcSetFileData(IN EFI_FILE_PROTOCOL *WritableFs OPTIONAL, IN CONST CHAR16 *FileName, IN CONST VOID *Buffer, IN UINT32 Size)
VOID EFIAPI OcAsciiPrintBuffer(IN OUT CHAR8 **AsciiBuffer, IN OUT UINTN *AsciiBufferSize, IN CONST CHAR8 *FormatString,...)
Definition OcAsciiLib.c:510
CHAR16 * AsciiStrCopyToUnicode(IN CONST CHAR8 *String, IN UINTN Length)
Definition OcAsciiLib.c:119
#define OC_BLOB_GET(Blob)
APPLE_EVENT_HANDLE Handle
Definition OcTypingLib.h:45
CONST CHAR16 *EFIAPI GetStringNameFromHandle(IN CONST EFI_HANDLE TheHandle, IN CONST CHAR8 *Language)
CHAR8 *EFIAPI GetBestLanguageForDriver(IN CONST CHAR8 *SupportedLanguages, IN CONST CHAR8 *InputLanguage, IN BOOLEAN Iso639Language)
VOID(* PROCESS_IMAGE)(IN VOID *Context, IN CONST CHAR16 *Name, IN EFI_HANDLE Handle)
VOID ReportImageName(IN VOID *Context, IN CONST CHAR16 *Name, IN EFI_HANDLE Handle)
VOID OcUnloadDrivers(IN OC_GLOBAL_CONFIG *Config)
VOID ProcessAllDrivers(IN VOID *Context, PROCESS_IMAGE ProcessImage, BOOLEAN Ascending)
EFI_STATUS OcDriverInfoDump(IN EFI_FILE_PROTOCOL *Root)
VOID UnloadImageByName(IN VOID *Context, IN CONST CHAR16 *Name, IN EFI_HANDLE Handle)
EFI_GUID gEfiDriverBindingProtocolGuid
EFI_GUID gEfiComponentNameProtocolGuid
EFI_GUID gEfiLoadedImageProtocolGuid
#define ASSERT(x)
Definition coder.h:55