OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
HandleParsingMin.c
Go to the documentation of this file.
1
11#include <Uefi.h>
12#include <Library/BaseLib.h>
13#include <Library/BaseMemoryLib.h>
14#include <Library/DebugLib.h>
15#include <Library/MemoryAllocationLib.h>
16#include <Library/UefiLib.h>
17#include <Library/UefiBootServicesTableLib.h>
18#include <Protocol/LoadedImage.h>
19
20#include "HandleParsingMin.h"
21
23 {
24 { NULL, NULL }, 0, 0
25 }, 0
26};
27
34STATIC
35EFI_STATUS
37 VOID
38 )
39{
40 EFI_STATUS Status;
41 EFI_HANDLE *HandleBuffer;
42 UINTN HandleCount;
43 HANDLE_LIST *ListWalker;
44
45 if (mHandleList.NextIndex != 0) {
46 return EFI_SUCCESS;
47 }
48
49 InitializeListHead (&mHandleList.List.Link);
51 Status = gBS->LocateHandleBuffer (
52 AllHandles,
53 NULL,
54 NULL,
55 &HandleCount,
56 &HandleBuffer
57 );
58 ASSERT_EFI_ERROR (Status);
59 if (EFI_ERROR (Status)) {
60 return (Status);
61 }
62
63 for (mHandleList.NextIndex = 1; mHandleList.NextIndex <= HandleCount; mHandleList.NextIndex++) {
64 ListWalker = AllocateZeroPool (sizeof (HANDLE_LIST));
65 if (ListWalker != NULL) {
66 ListWalker->TheHandle = HandleBuffer[mHandleList.NextIndex - 1];
67 ListWalker->TheIndex = mHandleList.NextIndex;
68 InsertTailList (&mHandleList.List.Link, &ListWalker->Link);
69 }
70 }
71
72 FreePool (HandleBuffer);
73 return (EFI_SUCCESS);
74}
75
87UINTN
88EFIAPI
90 IN CONST EFI_HANDLE TheHandle
91 )
92{
93 EFI_STATUS Status;
94 EFI_GUID **ProtocolBuffer;
95 UINTN ProtocolCount;
96 HANDLE_LIST *ListWalker;
97
98 if (TheHandle == NULL) {
99 return 0;
100 }
101
103
104 for (ListWalker = (HANDLE_LIST *)GetFirstNode (&mHandleList.List.Link)
105 ; !IsNull (&mHandleList.List.Link, &ListWalker->Link)
106 ; ListWalker = (HANDLE_LIST *)GetNextNode (&mHandleList.List.Link, &ListWalker->Link)
107 )
108 {
109 if (ListWalker->TheHandle == TheHandle) {
110 //
111 // Verify that TheHandle is still present in the Handle Database
112 //
113 Status = gBS->ProtocolsPerHandle (TheHandle, &ProtocolBuffer, &ProtocolCount);
114 if (EFI_ERROR (Status)) {
115 //
116 // TheHandle is not present in the Handle Database, so delete from the handle list
117 //
118 RemoveEntryList (&ListWalker->Link);
119 return 0;
120 }
121
122 FreePool (ProtocolBuffer);
123 return (ListWalker->TheIndex);
124 }
125 }
126
127 //
128 // Verify that TheHandle is valid handle
129 //
130 Status = gBS->ProtocolsPerHandle (TheHandle, &ProtocolBuffer, &ProtocolCount);
131 if (EFI_ERROR (Status)) {
132 //
133 // TheHandle is not valid, so do not add to handle list
134 //
135 return 0;
136 }
137
138 FreePool (ProtocolBuffer);
139
140 ListWalker = AllocateZeroPool (sizeof (HANDLE_LIST));
141 if (ListWalker == NULL) {
142 return 0;
143 }
144
145 ListWalker->TheHandle = TheHandle;
146 ListWalker->TheIndex = mHandleList.NextIndex++;
147 InsertTailList (&mHandleList.List.Link, &ListWalker->Link);
148 return (ListWalker->TheIndex);
149}
150
177STATIC
178EFI_STATUS
179EFIAPI
181 IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL,
182 IN CONST EFI_HANDLE ControllerHandle OPTIONAL,
183 IN UINTN *HandleCount,
184 OUT EFI_HANDLE **HandleBuffer,
185 OUT UINTN **HandleType
186 )
187{
188 EFI_STATUS Status;
189 UINTN HandleIndex;
190 EFI_GUID **ProtocolGuidArray;
191 UINTN ArrayCount;
192 UINTN ProtocolIndex;
193 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;
194 UINTN OpenInfoCount;
195 UINTN OpenInfoIndex;
196 UINTN ChildIndex;
197 INTN DriverBindingHandleIndex;
198
199 ASSERT (HandleCount != NULL);
200 ASSERT (HandleBuffer != NULL);
201 ASSERT (HandleType != NULL);
202 ASSERT (DriverBindingHandle != NULL || ControllerHandle != NULL);
203
204 *HandleCount = 0;
205 *HandleBuffer = NULL;
206 *HandleType = NULL;
207
208 //
209 // Retrieve the list of all handles from the handle database
210 //
211 Status = gBS->LocateHandleBuffer (
212 AllHandles,
213 NULL,
214 NULL,
215 HandleCount,
216 HandleBuffer
217 );
218 if (EFI_ERROR (Status)) {
219 return (Status);
220 }
221
222 *HandleType = AllocateZeroPool (*HandleCount * sizeof (UINTN));
223 if (*HandleType == NULL) {
224 if (*HandleBuffer != NULL) {
225 FreePool (*HandleBuffer);
226 *HandleBuffer = NULL;
227 }
228
229 *HandleCount = 0;
230 return EFI_OUT_OF_RESOURCES;
231 }
232
233 DriverBindingHandleIndex = -1;
234 for (HandleIndex = 0; HandleIndex < *HandleCount; HandleIndex++) {
235 if ((DriverBindingHandle != NULL) && ((*HandleBuffer)[HandleIndex] == DriverBindingHandle)) {
236 DriverBindingHandleIndex = (INTN)HandleIndex;
237 }
238 }
239
240 for (HandleIndex = 0; HandleIndex < *HandleCount; HandleIndex++) {
241 //
242 // Retrieve the list of all the protocols on each handle
243 //
244 Status = gBS->ProtocolsPerHandle (
245 (*HandleBuffer)[HandleIndex],
246 &ProtocolGuidArray,
247 &ArrayCount
248 );
249 if (EFI_ERROR (Status)) {
250 continue;
251 }
252
253 for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
254 //
255 // Set the bit describing what this handle has
256 //
257 if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiLoadedImageProtocolGuid)) {
258 (*HandleType)[HandleIndex] |= (UINTN)HR_IMAGE_HANDLE;
259 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverBindingProtocolGuid)) {
260 (*HandleType)[HandleIndex] |= (UINTN)HR_DRIVER_BINDING_HANDLE;
261 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverConfiguration2ProtocolGuid)) {
262 (*HandleType)[HandleIndex] |= (UINTN)HR_DRIVER_CONFIGURATION_HANDLE;
263 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverConfigurationProtocolGuid)) {
264 (*HandleType)[HandleIndex] |= (UINTN)HR_DRIVER_CONFIGURATION_HANDLE;
265 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverDiagnostics2ProtocolGuid)) {
266 (*HandleType)[HandleIndex] |= (UINTN)HR_DRIVER_DIAGNOSTICS_HANDLE;
267 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverDiagnosticsProtocolGuid)) {
268 (*HandleType)[HandleIndex] |= (UINTN)HR_DRIVER_DIAGNOSTICS_HANDLE;
269 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentName2ProtocolGuid)) {
270 (*HandleType)[HandleIndex] |= (UINTN)HR_COMPONENT_NAME_HANDLE;
271 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentNameProtocolGuid)) {
272 (*HandleType)[HandleIndex] |= (UINTN)HR_COMPONENT_NAME_HANDLE;
273 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDevicePathProtocolGuid)) {
274 (*HandleType)[HandleIndex] |= (UINTN)HR_DEVICE_HANDLE;
275 }
276
277 //
278 // Retrieve the list of agents that have opened each protocol
279 //
280 Status = gBS->OpenProtocolInformation (
281 (*HandleBuffer)[HandleIndex],
282 ProtocolGuidArray[ProtocolIndex],
283 &OpenInfo,
284 &OpenInfoCount
285 );
286 if (EFI_ERROR (Status)) {
287 continue;
288 }
289
290 if (ControllerHandle == NULL) {
291 //
292 // ControllerHandle == NULL and DriverBindingHandle != NULL.
293 // Return information on all the controller handles that the driver specified by DriverBindingHandle is managing
294 //
295 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
296 if ((OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) && ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0)) {
297 (*HandleType)[HandleIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);
298 if (DriverBindingHandleIndex != -1) {
299 (*HandleType)[DriverBindingHandleIndex] |= (UINTN)HR_DEVICE_DRIVER;
300 }
301 }
302
303 if ((OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) && ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0)) {
304 (*HandleType)[HandleIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);
305 if (DriverBindingHandleIndex != -1) {
306 (*HandleType)[DriverBindingHandleIndex] |= (UINTN)(HR_BUS_DRIVER | HR_DEVICE_DRIVER);
307 }
308
309 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
310 if (OpenInfo[OpenInfoIndex].ControllerHandle == (*HandleBuffer)[ChildIndex]) {
311 (*HandleType)[ChildIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CHILD_HANDLE);
312 }
313 }
314 }
315 }
316 }
317
318 if ((DriverBindingHandle == NULL) && (ControllerHandle != NULL)) {
319 if (ControllerHandle == (*HandleBuffer)[HandleIndex]) {
320 (*HandleType)[HandleIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);
321 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
322 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
323 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
324 if (OpenInfo[OpenInfoIndex].AgentHandle == (*HandleBuffer)[ChildIndex]) {
325 (*HandleType)[ChildIndex] |= (UINTN)HR_DEVICE_DRIVER;
326 }
327 }
328 }
329
330 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
331 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
332 if (OpenInfo[OpenInfoIndex].AgentHandle == (*HandleBuffer)[ChildIndex]) {
333 (*HandleType)[ChildIndex] |= (UINTN)(HR_BUS_DRIVER | HR_DEVICE_DRIVER);
334 }
335
336 if (OpenInfo[OpenInfoIndex].ControllerHandle == (*HandleBuffer)[ChildIndex]) {
337 (*HandleType)[ChildIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CHILD_HANDLE);
338 }
339 }
340 }
341 }
342 } else {
343 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
344 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
345 if (OpenInfo[OpenInfoIndex].ControllerHandle == ControllerHandle) {
346 (*HandleType)[HandleIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_PARENT_HANDLE);
347 }
348 }
349 }
350 }
351 }
352
353 if ((DriverBindingHandle != NULL) && (ControllerHandle != NULL)) {
354 if (ControllerHandle == (*HandleBuffer)[HandleIndex]) {
355 (*HandleType)[HandleIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);
356 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
357 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
358 if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) {
359 if (DriverBindingHandleIndex != -1) {
360 (*HandleType)[DriverBindingHandleIndex] |= (UINTN)HR_DEVICE_DRIVER;
361 }
362 }
363 }
364
365 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
366 if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) {
367 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
368 if (OpenInfo[OpenInfoIndex].ControllerHandle == (*HandleBuffer)[ChildIndex]) {
369 (*HandleType)[ChildIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CHILD_HANDLE);
370 }
371 }
372 }
373
374 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
375 if (OpenInfo[OpenInfoIndex].AgentHandle == (*HandleBuffer)[ChildIndex]) {
376 (*HandleType)[ChildIndex] |= (UINTN)(HR_BUS_DRIVER | HR_DEVICE_DRIVER);
377 }
378 }
379 }
380 }
381 } else {
382 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
383 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
384 if (OpenInfo[OpenInfoIndex].ControllerHandle == ControllerHandle) {
385 (*HandleType)[HandleIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_PARENT_HANDLE);
386 }
387 }
388 }
389 }
390 }
391
392 FreePool (OpenInfo);
393 }
394
395 FreePool (ProtocolGuidArray);
396 }
397
398 return EFI_SUCCESS;
399}
400
429EFI_STATUS
430EFIAPI
432 IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL,
433 IN CONST EFI_HANDLE ControllerHandle OPTIONAL,
434 IN CONST UINTN Mask,
435 IN UINTN *MatchingHandleCount,
436 OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL
437 )
438{
439 EFI_STATUS Status;
440 UINTN HandleCount;
441 EFI_HANDLE *HandleBuffer;
442 UINTN *HandleType;
443 UINTN HandleIndex;
444
445 ASSERT (MatchingHandleCount != NULL);
446 ASSERT (DriverBindingHandle != NULL || ControllerHandle != NULL);
447
448 if ((Mask & HR_VALID_MASK) != Mask) {
449 return (EFI_INVALID_PARAMETER);
450 }
451
452 if (((Mask & HR_CHILD_HANDLE) != 0) && (DriverBindingHandle == NULL)) {
453 return (EFI_INVALID_PARAMETER);
454 }
455
456 *MatchingHandleCount = 0;
457 if (MatchingHandleBuffer != NULL) {
458 *MatchingHandleBuffer = NULL;
459 }
460
461 HandleBuffer = NULL;
462 HandleType = NULL;
463
465 DriverBindingHandle,
466 ControllerHandle,
467 &HandleCount,
468 &HandleBuffer,
469 &HandleType
470 );
471 if (!EFI_ERROR (Status)) {
472 //
473 // Count the number of handles that match the attributes in Mask
474 //
475 for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
476 if ((HandleType[HandleIndex] & Mask) == Mask) {
477 (*MatchingHandleCount)++;
478 }
479 }
480
481 //
482 // If no handles match the attributes in Mask then return EFI_NOT_FOUND
483 //
484 if (*MatchingHandleCount == 0) {
485 Status = EFI_NOT_FOUND;
486 } else {
487 if (MatchingHandleBuffer == NULL) {
488 //
489 // Someone just wanted the count...
490 //
491 Status = EFI_SUCCESS;
492 } else {
493 //
494 // Allocate a handle buffer for the number of handles that matched the attributes in Mask
495 //
496 *MatchingHandleBuffer = AllocateZeroPool ((*MatchingHandleCount +1)* sizeof (EFI_HANDLE));
497 if (*MatchingHandleBuffer == NULL) {
498 Status = EFI_OUT_OF_RESOURCES;
499 } else {
500 for (HandleIndex = 0, *MatchingHandleCount = 0
501 ; HandleIndex < HandleCount
502 ; HandleIndex++
503 )
504 {
505 //
506 // Fill the allocated buffer with the handles that matched the attributes in Mask
507 //
508 if ((HandleType[HandleIndex] & Mask) == Mask) {
509 (*MatchingHandleBuffer)[(*MatchingHandleCount)++] = HandleBuffer[HandleIndex];
510 }
511 }
512
513 //
514 // Make the last one NULL
515 //
516 (*MatchingHandleBuffer)[*MatchingHandleCount] = NULL;
517
518 Status = EFI_SUCCESS;
519 } // *MatchingHandleBuffer == NULL (ELSE)
520 } // MacthingHandleBuffer == NULL (ELSE)
521 } // *MatchingHandleCount == 0 (ELSE)
522 } // no error on ParseHandleDatabaseByRelationshipWithType
523
524 if (HandleBuffer != NULL) {
525 FreePool (HandleBuffer);
526 }
527
528 if (HandleType != NULL) {
529 FreePool (HandleType);
530 }
531
532 ASSERT (
533 (MatchingHandleBuffer == NULL) ||
534 (*MatchingHandleCount == 0 && *MatchingHandleBuffer == NULL) ||
535 (*MatchingHandleCount != 0 && *MatchingHandleBuffer != NULL)
536 );
537 return Status;
538}
STATIC EFI_STATUS EFIAPI ParseHandleDatabaseByRelationshipWithType(IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL, IN CONST EFI_HANDLE ControllerHandle OPTIONAL, IN UINTN *HandleCount, OUT EFI_HANDLE **HandleBuffer, OUT UINTN **HandleType)
EFI_STATUS EFIAPI InternalParseHandleDatabaseByRelationship(IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL, IN CONST EFI_HANDLE ControllerHandle OPTIONAL, IN CONST UINTN Mask, IN UINTN *MatchingHandleCount, OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL)
UINTN EFIAPI InternalConvertHandleToHandleIndex(IN CONST EFI_HANDLE TheHandle)
STATIC EFI_STATUS InternalShellInitHandleList(VOID)
STATIC HANDLE_INDEX_LIST mHandleList
#define HR_DRIVER_BINDING_HANDLE
#define HR_DRIVER_CONFIGURATION_HANDLE
#define HR_CONTROLLER_HANDLE
#define HR_CHILD_HANDLE
#define HR_IMAGE_HANDLE
#define HR_COMPONENT_NAME_HANDLE
#define HR_BUS_DRIVER
#define HR_PARENT_HANDLE
#define HR_DEVICE_HANDLE
#define HR_DRIVER_DIAGNOSTICS_HANDLE
#define HR_VALID_MASK
#define HR_DEVICE_DRIVER
EFI_BOOT_SERVICES * gBS
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
EFI_GUID gEfiDriverBindingProtocolGuid
EFI_GUID gEfiComponentNameProtocolGuid
EFI_GUID gEfiLoadedImageProtocolGuid
EFI_GUID gEfiDevicePathProtocolGuid
#define ASSERT(x)
Definition coder.h:55
LIST_ENTRY Link
EFI_HANDLE TheHandle