• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2   Provides interface to advanced shell functionality for parsing both handle and protocol database.
3 
4   Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
5   (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>
6   (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>
7   This program and the accompanying materials
8   are licensed and made available under the terms and conditions of the BSD License
9   which accompanies this distribution.  The full text of the license may be found at
10   http://opensource.org/licenses/bsd-license.php
11 
12   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 
15 **/
16 
17 #include "UefiHandleParsingLib.h"
18 #include "IndustryStandard/Acpi10.h"
19 
20 EFI_HANDLE        mHandleParsingHiiHandle = NULL;
21 HANDLE_INDEX_LIST mHandleList = {{{NULL,NULL},0,0},0};
22 GUID_INFO_BLOCK   *GuidList;
23 UINTN             GuidListCount;
24 /**
25   Function to translate the EFI_MEMORY_TYPE into a string.
26 
27   @param[in] Memory     The memory type.
28 
29   @retval               A string representation of the type allocated from BS Pool.
30 **/
31 CHAR16*
ConvertMemoryType(IN CONST EFI_MEMORY_TYPE Memory)32 ConvertMemoryType (
33   IN CONST EFI_MEMORY_TYPE Memory
34   )
35 {
36   CHAR16 *RetVal;
37   RetVal = NULL;
38 
39   switch (Memory) {
40   case EfiReservedMemoryType:       StrnCatGrow(&RetVal, NULL, L"EfiReservedMemoryType", 0);        break;
41   case EfiLoaderCode:               StrnCatGrow(&RetVal, NULL, L"EfiLoaderCode", 0);                break;
42   case EfiLoaderData:               StrnCatGrow(&RetVal, NULL, L"EfiLoaderData", 0);                break;
43   case EfiBootServicesCode:         StrnCatGrow(&RetVal, NULL, L"EfiBootServicesCode", 0);          break;
44   case EfiBootServicesData:         StrnCatGrow(&RetVal, NULL, L"EfiBootServicesData", 0);          break;
45   case EfiRuntimeServicesCode:      StrnCatGrow(&RetVal, NULL, L"EfiRuntimeServicesCode", 0);       break;
46   case EfiRuntimeServicesData:      StrnCatGrow(&RetVal, NULL, L"EfiRuntimeServicesData", 0);       break;
47   case EfiConventionalMemory:       StrnCatGrow(&RetVal, NULL, L"EfiConventionalMemory", 0);        break;
48   case EfiUnusableMemory:           StrnCatGrow(&RetVal, NULL, L"EfiUnusableMemory", 0);            break;
49   case EfiACPIReclaimMemory:        StrnCatGrow(&RetVal, NULL, L"EfiACPIReclaimMemory", 0);         break;
50   case EfiACPIMemoryNVS:            StrnCatGrow(&RetVal, NULL, L"EfiACPIMemoryNVS", 0);             break;
51   case EfiMemoryMappedIO:           StrnCatGrow(&RetVal, NULL, L"EfiMemoryMappedIO", 0);            break;
52   case EfiMemoryMappedIOPortSpace:  StrnCatGrow(&RetVal, NULL, L"EfiMemoryMappedIOPortSpace", 0);   break;
53   case EfiPalCode:                  StrnCatGrow(&RetVal, NULL, L"EfiPalCode", 0);                   break;
54   case EfiMaxMemoryType:            StrnCatGrow(&RetVal, NULL, L"EfiMaxMemoryType", 0);             break;
55   default: ASSERT(FALSE);
56   }
57   return (RetVal);
58 }
59 
60 /**
61   Function to translate the EFI_GRAPHICS_PIXEL_FORMAT into a string.
62 
63   @param[in] Fmt     The format type.
64 
65   @retval               A string representation of the type allocated from BS Pool.
66 **/
67 CHAR16*
ConvertPixelFormat(IN CONST EFI_GRAPHICS_PIXEL_FORMAT Fmt)68 ConvertPixelFormat (
69   IN CONST EFI_GRAPHICS_PIXEL_FORMAT Fmt
70   )
71 {
72   CHAR16 *RetVal;
73   RetVal = NULL;
74 
75   switch (Fmt) {
76   case PixelRedGreenBlueReserved8BitPerColor: StrnCatGrow(&RetVal, NULL, L"PixelRedGreenBlueReserved8BitPerColor", 0);  break;
77   case PixelBlueGreenRedReserved8BitPerColor: StrnCatGrow(&RetVal, NULL, L"PixelBlueGreenRedReserved8BitPerColor", 0);  break;
78   case PixelBitMask:                          StrnCatGrow(&RetVal, NULL, L"PixelBitMask", 0);                           break;
79   case PixelBltOnly:                          StrnCatGrow(&RetVal, NULL, L"PixelBltOnly", 0);                           break;
80   case PixelFormatMax:                        StrnCatGrow(&RetVal, NULL, L"PixelFormatMax", 0);                         break;
81   default: ASSERT(FALSE);
82   }
83   return (RetVal);
84 }
85 
86 /**
87   Constructor for the library.
88 
89   @param[in] ImageHandle    Ignored.
90   @param[in] SystemTable    Ignored.
91 
92   @retval EFI_SUCCESS   The operation was successful.
93 **/
94 EFI_STATUS
95 EFIAPI
HandleParsingLibConstructor(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)96 HandleParsingLibConstructor (
97   IN EFI_HANDLE        ImageHandle,
98   IN EFI_SYSTEM_TABLE  *SystemTable
99   )
100 {
101   GuidListCount = 0;
102   GuidList      = NULL;
103 
104   //
105   // Do nothing with mHandleParsingHiiHandle.  Initialize HII as needed.
106   //
107   return (EFI_SUCCESS);
108 }
109 
110 /**
111   Initialization function for HII packages.
112 
113 **/
114 VOID
HandleParsingHiiInit(VOID)115 HandleParsingHiiInit (VOID)
116 {
117   if (mHandleParsingHiiHandle == NULL) {
118     mHandleParsingHiiHandle = HiiAddPackages (&gHandleParsingHiiGuid, gImageHandle, UefiHandleParsingLibStrings, NULL);
119     ASSERT (mHandleParsingHiiHandle != NULL);
120   }
121 }
122 
123 /**
124   Destructor for the library.  free any resources.
125 
126   @param[in] ImageHandle    Ignored.
127   @param[in] SystemTable    Ignored.
128 
129   @retval EFI_SUCCESS   The operation was successful.
130 **/
131 EFI_STATUS
132 EFIAPI
HandleParsingLibDestructor(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)133 HandleParsingLibDestructor (
134   IN EFI_HANDLE        ImageHandle,
135   IN EFI_SYSTEM_TABLE  *SystemTable
136   )
137 {
138   UINTN                 LoopCount;
139 
140   for (LoopCount = 0; GuidList != NULL && LoopCount < GuidListCount; LoopCount++) {
141     SHELL_FREE_NON_NULL(GuidList[LoopCount].GuidId);
142   }
143 
144   SHELL_FREE_NON_NULL(GuidList);
145   if (mHandleParsingHiiHandle != NULL) {
146     HiiRemovePackages(mHandleParsingHiiHandle);
147   }
148   return (EFI_SUCCESS);
149 }
150 
151 /**
152   Function to dump information about LoadedImage.
153 
154   This will allocate the return buffer from boot services pool.
155 
156   @param[in] TheHandle      The handle that has LoadedImage installed.
157   @param[in] Verbose        TRUE for additional information, FALSE otherwise.
158 
159   @retval A poitner to a string containing the information.
160 **/
161 CHAR16*
162 EFIAPI
LoadedImageProtocolDumpInformation(IN CONST EFI_HANDLE TheHandle,IN CONST BOOLEAN Verbose)163 LoadedImageProtocolDumpInformation(
164   IN CONST EFI_HANDLE TheHandle,
165   IN CONST BOOLEAN    Verbose
166   )
167 {
168   EFI_LOADED_IMAGE_PROTOCOL         *LoadedImage;
169   EFI_STATUS                        Status;
170   CHAR16                            *RetVal;
171   CHAR16                            *Temp;
172   CHAR16                            *CodeType;
173   CHAR16                            *DataType;
174 
175   if (!Verbose) {
176     return (CatSPrint(NULL, L"LoadedImage"));
177   }
178 
179   HandleParsingHiiInit();
180 
181   Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_LI_DUMP_MAIN), NULL);
182   if (Temp == NULL) {
183     return NULL;
184   }
185 
186   Status = gBS->OpenProtocol (
187                 TheHandle,
188                 &gEfiLoadedImageProtocolGuid,
189                 (VOID**)&LoadedImage,
190                 gImageHandle,
191                 NULL,
192                 EFI_OPEN_PROTOCOL_GET_PROTOCOL
193                );
194 
195   if (EFI_ERROR (Status)) {
196     SHELL_FREE_NON_NULL (Temp);
197     return NULL;
198   }
199 
200   DataType = ConvertMemoryType(LoadedImage->ImageDataType);
201   CodeType = ConvertMemoryType(LoadedImage->ImageCodeType);
202 
203   RetVal = CatSPrint(
204              NULL,
205              Temp,
206              LoadedImage->Revision,
207              LoadedImage->ParentHandle,
208              LoadedImage->SystemTable,
209              LoadedImage->DeviceHandle,
210              LoadedImage->FilePath,
211              LoadedImage->LoadOptionsSize,
212              LoadedImage->LoadOptions,
213              LoadedImage->ImageBase,
214              LoadedImage->ImageSize,
215              CodeType,
216              DataType,
217              LoadedImage->Unload
218              );
219 
220 
221   SHELL_FREE_NON_NULL(Temp);
222   SHELL_FREE_NON_NULL(CodeType);
223   SHELL_FREE_NON_NULL(DataType);
224 
225   return RetVal;
226 }
227 
228 /**
229   Function to dump information about GOP.
230 
231   This will allocate the return buffer from boot services pool.
232 
233   @param[in] TheHandle      The handle that has LoadedImage installed.
234   @param[in] Verbose        TRUE for additional information, FALSE otherwise.
235 
236   @retval A poitner to a string containing the information.
237 **/
238 CHAR16*
239 EFIAPI
GraphicsOutputProtocolDumpInformation(IN CONST EFI_HANDLE TheHandle,IN CONST BOOLEAN Verbose)240 GraphicsOutputProtocolDumpInformation(
241   IN CONST EFI_HANDLE TheHandle,
242   IN CONST BOOLEAN    Verbose
243   )
244 {
245   EFI_GRAPHICS_OUTPUT_PROTOCOL          *GraphicsOutput;
246   EFI_STATUS                            Status;
247   CHAR16                                *RetVal;
248   CHAR16                                *Temp;
249   CHAR16                                *Fmt;
250   CHAR16                                *TempRetVal;
251   UINTN                                 GopInfoSize;
252   UINT32                                Mode;
253   EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *GopInfo;
254 
255   if (!Verbose) {
256     return (CatSPrint(NULL, L"GraphicsOutput"));
257   }
258 
259   HandleParsingHiiInit();
260 
261   Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_GOP_DUMP_MAIN), NULL);
262   if (Temp == NULL) {
263     return NULL;
264   }
265 
266   Status = gBS->OpenProtocol (
267                 TheHandle,
268                 &gEfiGraphicsOutputProtocolGuid,
269                 (VOID**)&GraphicsOutput,
270                 gImageHandle,
271                 NULL,
272                 EFI_OPEN_PROTOCOL_GET_PROTOCOL
273                );
274 
275   if (EFI_ERROR (Status)) {
276     SHELL_FREE_NON_NULL (Temp);
277     return NULL;
278   }
279 
280   Fmt = ConvertPixelFormat(GraphicsOutput->Mode->Info->PixelFormat);
281 
282   RetVal = CatSPrint(
283              NULL,
284              Temp,
285              GraphicsOutput->Mode->MaxMode,
286              GraphicsOutput->Mode->Mode,
287              GraphicsOutput->Mode->FrameBufferBase,
288              (UINT64)GraphicsOutput->Mode->FrameBufferSize,
289              (UINT64)GraphicsOutput->Mode->SizeOfInfo,
290              GraphicsOutput->Mode->Info->Version,
291              GraphicsOutput->Mode->Info->HorizontalResolution,
292              GraphicsOutput->Mode->Info->VerticalResolution,
293              Fmt,
294              GraphicsOutput->Mode->Info->PixelsPerScanLine,
295              GraphicsOutput->Mode->Info->PixelFormat!=PixelBitMask?0:GraphicsOutput->Mode->Info->PixelInformation.RedMask,
296              GraphicsOutput->Mode->Info->PixelFormat!=PixelBitMask?0:GraphicsOutput->Mode->Info->PixelInformation.GreenMask,
297              GraphicsOutput->Mode->Info->PixelFormat!=PixelBitMask?0:GraphicsOutput->Mode->Info->PixelInformation.BlueMask
298              );
299 
300   SHELL_FREE_NON_NULL (Temp);
301 
302   Temp = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN (STR_GOP_RES_LIST_MAIN), NULL);
303   if (Temp == NULL) {
304     SHELL_FREE_NON_NULL (RetVal);
305     goto EXIT;
306   }
307 
308   TempRetVal = CatSPrint (RetVal, Temp);
309   SHELL_FREE_NON_NULL (RetVal);
310   if (TempRetVal == NULL) {
311     goto EXIT;
312   }
313   RetVal = TempRetVal;
314   SHELL_FREE_NON_NULL (Temp);
315 
316   Temp = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN (STR_GOP_RES_LIST_ENTRY), NULL);
317   if (Temp == NULL) {
318     SHELL_FREE_NON_NULL (RetVal);
319     goto EXIT;
320   }
321 
322 
323   for (Mode = 0; Mode < GraphicsOutput->Mode->MaxMode; Mode++) {
324     Status = GraphicsOutput->QueryMode (
325                                GraphicsOutput,
326                                Mode,
327                                &GopInfoSize,
328                                &GopInfo
329                                );
330     if (EFI_ERROR (Status)) {
331       continue;
332     }
333 
334     TempRetVal = CatSPrint (
335                    RetVal,
336                    Temp,
337                    Mode,
338                    GopInfo->HorizontalResolution,
339                    GopInfo->VerticalResolution
340                    );
341 
342     SHELL_FREE_NON_NULL (GopInfo);
343     SHELL_FREE_NON_NULL (RetVal);
344     RetVal = TempRetVal;
345   }
346 
347 
348 EXIT:
349   SHELL_FREE_NON_NULL(Temp);
350   SHELL_FREE_NON_NULL(Fmt);
351 
352   return RetVal;
353 }
354 
355 /**
356   Function to dump information about EDID Discovered Protocol.
357 
358   This will allocate the return buffer from boot services pool.
359 
360   @param[in] TheHandle      The handle that has LoadedImage installed.
361   @param[in] Verbose        TRUE for additional information, FALSE otherwise.
362 
363   @retval A pointer to a string containing the information.
364 **/
365 CHAR16*
366 EFIAPI
EdidDiscoveredProtocolDumpInformation(IN CONST EFI_HANDLE TheHandle,IN CONST BOOLEAN Verbose)367 EdidDiscoveredProtocolDumpInformation (
368   IN CONST EFI_HANDLE TheHandle,
369   IN CONST BOOLEAN    Verbose
370   )
371 {
372   EFI_EDID_DISCOVERED_PROTOCOL          *EdidDiscovered;
373   EFI_STATUS                            Status;
374   CHAR16                                *RetVal;
375   CHAR16                                *Temp;
376   CHAR16                                *TempRetVal;
377 
378   if (!Verbose) {
379     return (CatSPrint (NULL, L"EDIDDiscovered"));
380   }
381 
382   Status = gBS->OpenProtocol (
383                   TheHandle,
384                   &gEfiEdidDiscoveredProtocolGuid,
385                   (VOID**)&EdidDiscovered,
386                   NULL,
387                   NULL,
388                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
389                   );
390 
391   if (EFI_ERROR (Status)) {
392     return NULL;
393   }
394 
395   Temp = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN (STR_EDID_DISCOVERED_MAIN), NULL);
396   if (Temp == NULL) {
397     return NULL;
398   }
399 
400   RetVal = CatSPrint (NULL, Temp, EdidDiscovered->SizeOfEdid);
401   SHELL_FREE_NON_NULL (Temp);
402 
403   if (EdidDiscovered->SizeOfEdid != 0) {
404     Temp = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN (STR_EDID_DISCOVERED_DATA), NULL);
405     if (Temp == NULL) {
406       SHELL_FREE_NON_NULL (RetVal);
407       return NULL;
408     }
409     TempRetVal = CatSPrint (RetVal, Temp);
410     SHELL_FREE_NON_NULL (RetVal);
411     RetVal = TempRetVal;
412 
413     TempRetVal = CatSDumpHex (RetVal, 7, 0, EdidDiscovered->SizeOfEdid, EdidDiscovered->Edid);
414     RetVal = TempRetVal;
415   }
416   return RetVal;
417 }
418 
419 /**
420   Function to dump information about EDID Active Protocol.
421 
422   This will allocate the return buffer from boot services pool.
423 
424   @param[in] TheHandle      The handle that has LoadedImage installed.
425   @param[in] Verbose        TRUE for additional information, FALSE otherwise.
426 
427   @retval A pointer to a string containing the information.
428 **/
429 CHAR16*
430 EFIAPI
EdidActiveProtocolDumpInformation(IN CONST EFI_HANDLE TheHandle,IN CONST BOOLEAN Verbose)431 EdidActiveProtocolDumpInformation (
432   IN CONST EFI_HANDLE TheHandle,
433   IN CONST BOOLEAN    Verbose
434   )
435 {
436   EFI_EDID_ACTIVE_PROTOCOL  *EdidActive;
437   EFI_STATUS                Status;
438   CHAR16                    *RetVal;
439   CHAR16                    *Temp;
440   CHAR16                    *TempRetVal;
441 
442   if (!Verbose) {
443     return (CatSPrint (NULL, L"EDIDActive"));
444   }
445 
446   Status = gBS->OpenProtocol (
447                   TheHandle,
448                   &gEfiEdidActiveProtocolGuid,
449                   (VOID**)&EdidActive,
450                   NULL,
451                   NULL,
452                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
453                   );
454 
455   if (EFI_ERROR (Status)) {
456     return NULL;
457   }
458 
459   Temp = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN (STR_EDID_ACTIVE_MAIN), NULL);
460   if (Temp == NULL) {
461     return NULL;
462   }
463 
464   RetVal = CatSPrint (NULL, Temp, EdidActive->SizeOfEdid);
465   SHELL_FREE_NON_NULL (Temp);
466 
467   if (EdidActive->SizeOfEdid != 0) {
468     Temp = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN (STR_EDID_ACTIVE_DATA), NULL);
469     if (Temp == NULL) {
470       SHELL_FREE_NON_NULL (RetVal);
471       return NULL;
472     }
473     TempRetVal = CatSPrint (RetVal, Temp);
474     SHELL_FREE_NON_NULL (RetVal);
475     RetVal = TempRetVal;
476 
477     TempRetVal = CatSDumpHex (RetVal, 7, 0, EdidActive->SizeOfEdid, EdidActive->Edid);
478     RetVal = TempRetVal;
479   }
480   return RetVal;
481 }
482 
483 /**
484   Function to dump information about PciRootBridgeIo.
485 
486   This will allocate the return buffer from boot services pool.
487 
488   @param[in] TheHandle      The handle that has PciRootBridgeIo installed.
489   @param[in] Verbose        TRUE for additional information, FALSE otherwise.
490 
491   @retval A poitner to a string containing the information.
492 **/
493 CHAR16*
494 EFIAPI
PciRootBridgeIoDumpInformation(IN CONST EFI_HANDLE TheHandle,IN CONST BOOLEAN Verbose)495 PciRootBridgeIoDumpInformation(
496   IN CONST EFI_HANDLE TheHandle,
497   IN CONST BOOLEAN    Verbose
498   )
499 {
500   EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL   *PciRootBridgeIo;
501   EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Configuration;
502   UINT64                            Supports;
503   UINT64                            Attributes;
504   CHAR16                            *Temp;
505   CHAR16                            *Temp2;
506   CHAR16                            *RetVal;
507   EFI_STATUS                        Status;
508 
509   RetVal  = NULL;
510 
511   if (!Verbose) {
512     return (CatSPrint(NULL, L"PciRootBridgeIo"));
513   }
514 
515   HandleParsingHiiInit();
516 
517   Status = gBS->HandleProtocol(
518     TheHandle,
519     &gEfiPciRootBridgeIoProtocolGuid,
520     (VOID**)&PciRootBridgeIo);
521 
522   if (EFI_ERROR(Status)) {
523     return NULL;
524   }
525 
526   Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_PH), NULL);
527   if (Temp == NULL) {
528     return NULL;
529   }
530   Temp2 = CatSPrint(L"\r\n", Temp, PciRootBridgeIo->ParentHandle);
531   FreePool(Temp);
532   RetVal = Temp2;
533   Temp2 = NULL;
534 
535   Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_SEG), NULL);
536   if (Temp == NULL) {
537     SHELL_FREE_NON_NULL(RetVal);
538     return NULL;
539   }
540   Temp2 = CatSPrint(RetVal, Temp, PciRootBridgeIo->SegmentNumber);
541   FreePool(Temp);
542   FreePool(RetVal);
543   RetVal = Temp2;
544   Temp2 = NULL;
545 
546   Supports   = 0;
547   Attributes = 0;
548   Status = PciRootBridgeIo->GetAttributes (PciRootBridgeIo, &Supports, &Attributes);
549   if (!EFI_ERROR(Status)) {
550     Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_ATT), NULL);
551     if (Temp == NULL) {
552       SHELL_FREE_NON_NULL(RetVal);
553       return NULL;
554     }
555     Temp2 = CatSPrint(RetVal, Temp, Attributes);
556     FreePool(Temp);
557     FreePool(RetVal);
558     RetVal = Temp2;
559     Temp2 = NULL;
560 
561     Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_SUPPORTS), NULL);
562     if (Temp == NULL) {
563       SHELL_FREE_NON_NULL(RetVal);
564       return NULL;
565     }
566     Temp2 = CatSPrint(RetVal, Temp, Supports);
567     FreePool(Temp);
568     FreePool(RetVal);
569     RetVal = Temp2;
570     Temp2 = NULL;
571   }
572 
573   Configuration   = NULL;
574   Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Configuration);
575   if (!EFI_ERROR(Status) && Configuration != NULL) {
576     Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_TITLE), NULL);
577     if (Temp == NULL) {
578       SHELL_FREE_NON_NULL(RetVal);
579       return NULL;
580     }
581     Temp2 = CatSPrint(RetVal, Temp, Supports);
582     FreePool(Temp);
583     FreePool(RetVal);
584     RetVal = Temp2;
585     Temp2 = NULL;
586     while (Configuration->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
587       Temp = NULL;
588       switch (Configuration->ResType) {
589       case ACPI_ADDRESS_SPACE_TYPE_MEM:
590         Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_MEM), NULL);
591         break;
592       case ACPI_ADDRESS_SPACE_TYPE_IO:
593         Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_IO), NULL);
594         break;
595       case ACPI_ADDRESS_SPACE_TYPE_BUS:
596         Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_BUS), NULL);
597         break;
598       }
599       if (Temp != NULL) {
600         Temp2 = CatSPrint(RetVal, L"%s", Temp);
601         FreePool(Temp);
602         FreePool(RetVal);
603         RetVal = Temp2;
604         Temp2 = NULL;
605       }
606 
607       Temp2 = CatSPrint(RetVal,
608         L"%H%02x    %016lx  %016lx  %02x%N\r\n",
609         Configuration->SpecificFlag,
610         Configuration->AddrRangeMin,
611         Configuration->AddrRangeMax,
612         Configuration->AddrSpaceGranularity
613         );
614       FreePool(RetVal);
615       RetVal = Temp2;
616       Temp2 = NULL;
617       Configuration++;
618     }
619   }
620   return (RetVal);
621 }
622 
623 /**
624   Function to dump information about SimpleTextOut.
625 
626   This will allocate the return buffer from boot services pool.
627 
628   @param[in] TheHandle      The handle that has SimpleTextOut installed.
629   @param[in] Verbose        TRUE for additional information, FALSE otherwise.
630 
631   @retval A poitner to a string containing the information.
632 **/
633 CHAR16*
634 EFIAPI
TxtOutProtocolDumpInformation(IN CONST EFI_HANDLE TheHandle,IN CONST BOOLEAN Verbose)635 TxtOutProtocolDumpInformation(
636   IN CONST EFI_HANDLE TheHandle,
637   IN CONST BOOLEAN    Verbose
638   )
639 {
640   EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Dev;
641   INTN                            Index;
642   UINTN                           Col;
643   UINTN                           Row;
644   EFI_STATUS                      Status;
645   CHAR16                          *RetVal;
646   UINTN                           Size;
647   CHAR16                          *Temp;
648   UINTN                           NewSize;
649 
650   if (!Verbose) {
651     return (NULL);
652   }
653 
654   HandleParsingHiiInit();
655 
656   RetVal  = NULL;
657   Size    = 0;
658 
659   Status = gBS->HandleProtocol(
660     TheHandle,
661     &gEfiSimpleTextOutProtocolGuid,
662     (VOID**)&Dev);
663 
664   ASSERT_EFI_ERROR(Status);
665   ASSERT (Dev != NULL && Dev->Mode != NULL);
666 
667   Size = (Dev->Mode->MaxMode + 1) * 80;
668   RetVal = AllocateZeroPool(Size);
669 
670   Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_TXT_OUT_DUMP_HEADER), NULL);
671   if (Temp != NULL) {
672     UnicodeSPrint(RetVal, Size, Temp, Dev, Dev->Mode->Attribute);
673     FreePool(Temp);
674   }
675 
676   //
677   // Dump TextOut Info
678   //
679   Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_TXT_OUT_DUMP_LINE), NULL);
680   for (Index = 0; Index < Dev->Mode->MaxMode; Index++) {
681     Status = Dev->QueryMode (Dev, Index, &Col, &Row);
682     NewSize = Size - StrSize(RetVal);
683     UnicodeSPrint(
684       RetVal + StrLen(RetVal),
685       NewSize,
686       Temp == NULL?L"":Temp,
687       Index == Dev->Mode->Mode ? L'*' : L' ',
688       Index,
689       !EFI_ERROR(Status)?(INTN)Col:-1,
690       !EFI_ERROR(Status)?(INTN)Row:-1
691      );
692   }
693   FreePool(Temp);
694   return (RetVal);
695 }
696 
697 STATIC CONST UINTN VersionStringSize = 60;
698 
699 /**
700   Function to dump information about EfiDriverSupportedEfiVersion protocol.
701 
702   This will allocate the return buffer from boot services pool.
703 
704   @param[in] TheHandle      The handle that has the protocol installed.
705   @param[in] Verbose        TRUE for additional information, FALSE otherwise.
706 
707   @retval A poitner to a string containing the information.
708 **/
709 CHAR16*
710 EFIAPI
DriverEfiVersionProtocolDumpInformation(IN CONST EFI_HANDLE TheHandle,IN CONST BOOLEAN Verbose)711 DriverEfiVersionProtocolDumpInformation(
712   IN CONST EFI_HANDLE TheHandle,
713   IN CONST BOOLEAN    Verbose
714   )
715 {
716   EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL *DriverEfiVersion;
717   EFI_STATUS                                Status;
718   CHAR16                                    *RetVal;
719 
720   Status = gBS->HandleProtocol(
721     TheHandle,
722     &gEfiDriverSupportedEfiVersionProtocolGuid,
723     (VOID**)&DriverEfiVersion);
724 
725   ASSERT_EFI_ERROR(Status);
726 
727   RetVal = AllocateZeroPool(VersionStringSize);
728   if (RetVal != NULL) {
729     UnicodeSPrint (RetVal, VersionStringSize, L"0x%08x", DriverEfiVersion->FirmwareVersion);
730   }
731   return (RetVal);
732 }
733 /**
734   Function to convert device path to string.
735 
736   This will allocate the return buffer from boot services pool.
737 
738   @param[in] DevPath        Pointer to device path instance.
739   @param[in] Verbose        TRUE for additional information, FALSE otherwise.
740   @param[in] Length         Maximum allowed text length of the device path.
741 
742   @retval A pointer to a string containing the information.
743 **/
744 CHAR16*
ConvertDevicePathToShortText(IN CONST EFI_DEVICE_PATH_PROTOCOL * DevPath,IN CONST BOOLEAN Verbose,IN CONST UINTN Length)745 ConvertDevicePathToShortText(
746   IN CONST EFI_DEVICE_PATH_PROTOCOL *DevPath,
747   IN CONST BOOLEAN                  Verbose,
748   IN CONST UINTN                    Length
749   )
750 {
751   CHAR16                            *Temp;
752   CHAR16                            *Temp2;
753   UINTN                             Size;
754 
755   //
756   // I cannot decide whether to allow shortcuts here (the second BOOLEAN on the next line)
757   //
758   Temp = ConvertDevicePathToText(DevPath, TRUE, TRUE);
759   if (!Verbose && Temp != NULL && StrLen(Temp) > Length) {
760     Temp2 = NULL;
761     Size  = 0;
762     Temp2 = StrnCatGrow(&Temp2, &Size, L"..", 0);
763     Temp2 = StrnCatGrow(&Temp2, &Size, Temp+(StrLen(Temp) - (Length - 2)), 0);
764     FreePool(Temp);
765     Temp = Temp2;
766   }
767   return (Temp);
768 }
769 
770 /**
771   Function to dump information about DevicePath protocol.
772 
773   This will allocate the return buffer from boot services pool.
774 
775   @param[in] TheHandle      The handle that has the protocol installed.
776   @param[in] Verbose        TRUE for additional information, FALSE otherwise.
777 
778   @retval A pointer to a string containing the information.
779 **/
780 CHAR16*
781 EFIAPI
DevicePathProtocolDumpInformation(IN CONST EFI_HANDLE TheHandle,IN CONST BOOLEAN Verbose)782 DevicePathProtocolDumpInformation(
783   IN CONST EFI_HANDLE TheHandle,
784   IN CONST BOOLEAN    Verbose
785   )
786 {
787   EFI_DEVICE_PATH_PROTOCOL          *DevPath;
788   CHAR16                            *Temp;
789   EFI_STATUS                        Status;
790   Temp = NULL;
791 
792   Status = gBS->OpenProtocol(TheHandle, &gEfiDevicePathProtocolGuid, (VOID**)&DevPath, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
793   if (!EFI_ERROR(Status)) {
794     Temp = ConvertDevicePathToShortText (DevPath, Verbose, 30);
795     gBS->CloseProtocol(TheHandle, &gEfiDevicePathProtocolGuid, gImageHandle, NULL);
796   }
797   return (Temp);
798 }
799 
800 /**
801   Function to dump information about LoadedImageDevicePath protocol.
802 
803   This will allocate the return buffer from boot services pool.
804 
805   @param[in] TheHandle      The handle that has the protocol installed.
806   @param[in] Verbose        TRUE for additional information, FALSE otherwise.
807 
808   @retval A pointer to a string containing the information.
809 **/
810 CHAR16*
811 EFIAPI
LoadedImageDevicePathProtocolDumpInformation(IN CONST EFI_HANDLE TheHandle,IN CONST BOOLEAN Verbose)812 LoadedImageDevicePathProtocolDumpInformation(
813   IN CONST EFI_HANDLE TheHandle,
814   IN CONST BOOLEAN    Verbose
815   )
816 {
817   EFI_DEVICE_PATH_PROTOCOL          *DevPath;
818   CHAR16                            *Temp;
819   EFI_STATUS                        Status;
820   Temp = NULL;
821 
822   Status = gBS->OpenProtocol(TheHandle, &gEfiLoadedImageDevicePathProtocolGuid, (VOID**)&DevPath, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
823   if (!EFI_ERROR(Status)) {
824     Temp = ConvertDevicePathToShortText (DevPath, Verbose, 30);
825     gBS->CloseProtocol(TheHandle, &gEfiDevicePathProtocolGuid, gImageHandle, NULL);
826   }
827   return (Temp);
828 }
829 
830 /**
831   Function to dump information about EfiAdapterInformation Protocol.
832 
833   @param[in] TheHandle      The handle that has the protocol installed.
834   @param[in] Verbose        TRUE for additional information, FALSE otherwise.
835 
836   @retval A pointer to a string containing the information.
837 **/
838 CHAR16*
839 EFIAPI
AdapterInformationDumpInformation(IN CONST EFI_HANDLE TheHandle,IN CONST BOOLEAN Verbose)840 AdapterInformationDumpInformation (
841   IN CONST EFI_HANDLE TheHandle,
842   IN CONST BOOLEAN    Verbose
843   )
844 {
845   EFI_STATUS                        Status;
846   EFI_ADAPTER_INFORMATION_PROTOCOL  *EfiAdptrInfoProtocol;
847   UINTN                             InfoTypesBufferCount;
848   UINTN                             GuidIndex;
849   EFI_GUID                          *InfoTypesBuffer;
850   CHAR16                            *GuidStr;
851   CHAR16                            *TempStr;
852   CHAR16                            *RetVal;
853   CHAR16                            *TempRetVal;
854   VOID                              *InformationBlock;
855   UINTN                             InformationBlockSize;
856 
857   if (!Verbose) {
858     return (CatSPrint(NULL, L"AdapterInfo"));
859   }
860 
861   InfoTypesBuffer   = NULL;
862   InformationBlock  = NULL;
863 
864 
865   Status = gBS->OpenProtocol (
866                   (EFI_HANDLE) (TheHandle),
867                   &gEfiAdapterInformationProtocolGuid,
868                   (VOID **) &EfiAdptrInfoProtocol,
869                   NULL,
870                   NULL,
871                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
872                   );
873 
874   if (EFI_ERROR (Status)) {
875     return NULL;
876   }
877 
878   //
879   // Get a list of supported information types for this instance of the protocol.
880   //
881   Status = EfiAdptrInfoProtocol->GetSupportedTypes (
882                                    EfiAdptrInfoProtocol,
883                                    &InfoTypesBuffer,
884                                    &InfoTypesBufferCount
885                                    );
886   RetVal = NULL;
887   if (EFI_ERROR (Status)) {
888     TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_GET_SUPP_TYPES_FAILED), NULL);
889     if (TempStr != NULL) {
890       RetVal = CatSPrint (NULL, TempStr, Status);
891     } else {
892       goto ERROR_EXIT;
893     }
894   } else {
895     TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_SUPP_TYPE_HEADER), NULL);
896     if (TempStr == NULL) {
897       goto ERROR_EXIT;
898     }
899     RetVal = CatSPrint (NULL, TempStr);
900     SHELL_FREE_NON_NULL (TempStr);
901 
902     for (GuidIndex = 0; GuidIndex < InfoTypesBufferCount; GuidIndex++) {
903       TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_GUID_NUMBER), NULL);
904       if (TempStr == NULL) {
905         goto ERROR_EXIT;
906       }
907       TempRetVal = CatSPrint (RetVal, TempStr, (GuidIndex + 1), &InfoTypesBuffer[GuidIndex]);
908       SHELL_FREE_NON_NULL (RetVal);
909       RetVal = TempRetVal;
910       SHELL_FREE_NON_NULL (TempStr);
911 
912       TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_GUID_STRING), NULL);
913       if (TempStr == NULL) {
914         goto ERROR_EXIT;
915       }
916 
917       if (CompareGuid (&InfoTypesBuffer[GuidIndex], &gEfiAdapterInfoMediaStateGuid)) {
918         TempRetVal = CatSPrint (RetVal, TempStr, L"gEfiAdapterInfoMediaStateGuid");
919         SHELL_FREE_NON_NULL (RetVal);
920         RetVal = TempRetVal;
921       } else if (CompareGuid (&InfoTypesBuffer[GuidIndex], &gEfiAdapterInfoNetworkBootGuid)) {
922         TempRetVal = CatSPrint (RetVal, TempStr, L"gEfiAdapterInfoNetworkBootGuid");
923         SHELL_FREE_NON_NULL (RetVal);
924         RetVal = TempRetVal;
925       } else if (CompareGuid (&InfoTypesBuffer[GuidIndex], &gEfiAdapterInfoSanMacAddressGuid)) {
926         TempRetVal = CatSPrint (RetVal, TempStr, L"gEfiAdapterInfoSanMacAddressGuid");
927         SHELL_FREE_NON_NULL (RetVal);
928         RetVal = TempRetVal;
929       } else if (CompareGuid (&InfoTypesBuffer[GuidIndex], &gEfiAdapterInfoUndiIpv6SupportGuid)) {
930         TempRetVal = CatSPrint (RetVal, TempStr, L"gEfiAdapterInfoUndiIpv6SupportGuid");
931         SHELL_FREE_NON_NULL (RetVal);
932         RetVal = TempRetVal;
933       } else {
934 
935         GuidStr = GetStringNameFromGuid (&InfoTypesBuffer[GuidIndex], NULL);
936 
937         if (GuidStr != NULL) {
938           if (StrCmp(GuidStr, L"UnknownDevice") == 0) {
939             TempRetVal = CatSPrint (RetVal, TempStr, L"UnknownInfoType");
940             SHELL_FREE_NON_NULL (RetVal);
941             RetVal = TempRetVal;
942 
943             SHELL_FREE_NON_NULL (TempStr);
944             SHELL_FREE_NON_NULL(GuidStr);
945             //
946             // So that we never have to pass this UnknownInfoType to the parsing function "GetInformation" service of AIP
947             //
948             continue;
949           } else {
950             TempRetVal = CatSPrint (RetVal, TempStr, GuidStr);
951             SHELL_FREE_NON_NULL (RetVal);
952             RetVal = TempRetVal;
953             SHELL_FREE_NON_NULL(GuidStr);
954           }
955         }
956       }
957 
958       SHELL_FREE_NON_NULL (TempStr);
959 
960       Status = EfiAdptrInfoProtocol->GetInformation (
961                                        EfiAdptrInfoProtocol,
962                                        &InfoTypesBuffer[GuidIndex],
963                                        &InformationBlock,
964                                        &InformationBlockSize
965                                        );
966 
967       if (EFI_ERROR (Status)) {
968         TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_GETINFO_FAILED), NULL);
969         if (TempStr == NULL) {
970           goto ERROR_EXIT;
971         }
972         TempRetVal = CatSPrint (RetVal, TempStr, Status);
973         SHELL_FREE_NON_NULL (RetVal);
974         RetVal = TempRetVal;
975       } else {
976         if (CompareGuid (&InfoTypesBuffer[GuidIndex], &gEfiAdapterInfoMediaStateGuid)) {
977           TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_MEDIA_STATE), NULL);
978           if (TempStr == NULL) {
979             goto ERROR_EXIT;
980           }
981           TempRetVal = CatSPrint (
982                          RetVal,
983                          TempStr,
984                          ((EFI_ADAPTER_INFO_MEDIA_STATE *)InformationBlock)->MediaState,
985                          ((EFI_ADAPTER_INFO_MEDIA_STATE *)InformationBlock)->MediaState
986                          );
987           SHELL_FREE_NON_NULL (RetVal);
988           RetVal = TempRetVal;
989         } else if (CompareGuid (&InfoTypesBuffer[GuidIndex], &gEfiAdapterInfoNetworkBootGuid)) {
990           TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_NETWORK_BOOT_INFO), NULL);
991           if (TempStr == NULL) {
992             goto ERROR_EXIT;
993           }
994           TempRetVal = CatSPrint (
995                          RetVal,
996                          TempStr,
997                          ((EFI_ADAPTER_INFO_NETWORK_BOOT *)InformationBlock)->iScsiIpv4BootCapablity,
998                          ((EFI_ADAPTER_INFO_NETWORK_BOOT *)InformationBlock)->iScsiIpv6BootCapablity,
999                          ((EFI_ADAPTER_INFO_NETWORK_BOOT *)InformationBlock)->FCoeBootCapablity,
1000                          ((EFI_ADAPTER_INFO_NETWORK_BOOT *)InformationBlock)->OffloadCapability,
1001                          ((EFI_ADAPTER_INFO_NETWORK_BOOT *)InformationBlock)->iScsiMpioCapability,
1002                          ((EFI_ADAPTER_INFO_NETWORK_BOOT *)InformationBlock)->iScsiIpv4Boot,
1003                          ((EFI_ADAPTER_INFO_NETWORK_BOOT *)InformationBlock)->iScsiIpv6Boot,
1004                          ((EFI_ADAPTER_INFO_NETWORK_BOOT *)InformationBlock)->FCoeBoot
1005                          );
1006           SHELL_FREE_NON_NULL (RetVal);
1007           RetVal = TempRetVal;
1008         } else if (CompareGuid (&InfoTypesBuffer[GuidIndex], &gEfiAdapterInfoSanMacAddressGuid) == TRUE) {
1009           TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_SAN_MAC_ADDRESS_INFO), NULL);
1010           if (TempStr == NULL) {
1011             goto ERROR_EXIT;
1012           }
1013           TempRetVal = CatSPrint (
1014                          RetVal,
1015                          TempStr,
1016                          ((EFI_ADAPTER_INFO_SAN_MAC_ADDRESS *)InformationBlock)->SanMacAddress.Addr[0],
1017                          ((EFI_ADAPTER_INFO_SAN_MAC_ADDRESS *)InformationBlock)->SanMacAddress.Addr[1],
1018                          ((EFI_ADAPTER_INFO_SAN_MAC_ADDRESS *)InformationBlock)->SanMacAddress.Addr[2],
1019                          ((EFI_ADAPTER_INFO_SAN_MAC_ADDRESS *)InformationBlock)->SanMacAddress.Addr[3],
1020                          ((EFI_ADAPTER_INFO_SAN_MAC_ADDRESS *)InformationBlock)->SanMacAddress.Addr[4],
1021                          ((EFI_ADAPTER_INFO_SAN_MAC_ADDRESS *)InformationBlock)->SanMacAddress.Addr[5]
1022                          );
1023           SHELL_FREE_NON_NULL (RetVal);
1024           RetVal = TempRetVal;
1025         } else if (CompareGuid (&InfoTypesBuffer[GuidIndex], &gEfiAdapterInfoUndiIpv6SupportGuid) == TRUE) {
1026           TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_UNDI_IPV6_INFO), NULL);
1027           if (TempStr == NULL) {
1028             goto ERROR_EXIT;
1029           }
1030 
1031           TempRetVal = CatSPrint (
1032                          RetVal,
1033                          TempStr,
1034                          ((EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT *)InformationBlock)->Ipv6Support
1035                          );
1036           SHELL_FREE_NON_NULL (RetVal);
1037           RetVal = TempRetVal;
1038         } else {
1039           TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_UNKNOWN_INFO_TYPE), NULL);
1040           if (TempStr == NULL) {
1041             goto ERROR_EXIT;
1042           }
1043           TempRetVal = CatSPrint (RetVal, TempStr, &InfoTypesBuffer[GuidIndex]);
1044           SHELL_FREE_NON_NULL (RetVal);
1045           RetVal = TempRetVal;
1046         }
1047       }
1048       SHELL_FREE_NON_NULL (TempStr);
1049       SHELL_FREE_NON_NULL (InformationBlock);
1050     }
1051   }
1052 
1053   SHELL_FREE_NON_NULL (InfoTypesBuffer);
1054   return RetVal;
1055 
1056 ERROR_EXIT:
1057   SHELL_FREE_NON_NULL (RetVal);
1058   SHELL_FREE_NON_NULL (InfoTypesBuffer);
1059   SHELL_FREE_NON_NULL (InformationBlock);
1060   return NULL;
1061 }
1062 
1063 /**
1064   Function to dump information about EFI_FIRMWARE_MANAGEMENT_PROTOCOL Protocol.
1065 
1066   @param[in] TheHandle      The handle that has the protocol installed.
1067   @param[in] Verbose        TRUE for additional information, FALSE otherwise.
1068 
1069   @retval A pointer to a string containing the information.
1070 **/
1071 CHAR16*
1072 EFIAPI
FirmwareManagementDumpInformation(IN CONST EFI_HANDLE TheHandle,IN CONST BOOLEAN Verbose)1073 FirmwareManagementDumpInformation (
1074   IN CONST EFI_HANDLE TheHandle,
1075   IN CONST BOOLEAN    Verbose
1076   )
1077 {
1078   EFI_STATUS                          Status;
1079   EFI_FIRMWARE_MANAGEMENT_PROTOCOL    *EfiFwMgmtProtocol;
1080   EFI_FIRMWARE_IMAGE_DESCRIPTOR       *ImageInfo;
1081   EFI_FIRMWARE_IMAGE_DESCRIPTOR_V1    *ImageInfoV1;
1082   EFI_FIRMWARE_IMAGE_DESCRIPTOR_V2    *ImageInfoV2;
1083   UINT64                              AttributeSetting;
1084   UINTN                               ImageInfoSize;
1085   UINTN                               DescriptorSize;
1086   UINT32                              DescriptorVersion;
1087   UINT32                              PackageVersion;
1088   UINT8                               DescriptorCount;
1089   UINT8                               Index;
1090   UINT8                               Index1;
1091   UINT8                               ImageCount;
1092   CHAR16                              *PackageVersionName;
1093   CHAR16                              *TempStr;
1094   CHAR16                              *RetVal;
1095   CHAR16                              *TempRetVal;
1096   CHAR16                              *AttributeSettingStr;
1097   BOOLEAN                             Found;
1098   BOOLEAN                             AttributeSupported;
1099 
1100   //
1101   // Initialize local variables
1102   //
1103   ImageCount             = 0;
1104   ImageInfoSize          = 1;
1105   AttributeSetting       = 0;
1106   Found                  = FALSE;
1107   AttributeSupported     = FALSE;
1108   ImageInfo              = NULL;
1109   ImageInfoV1            = NULL;
1110   ImageInfoV2            = NULL;
1111   PackageVersionName     = NULL;
1112   RetVal                 = NULL;
1113   TempRetVal             = NULL;
1114   TempStr                = NULL;
1115   AttributeSettingStr    = NULL;
1116 
1117   if (!Verbose) {
1118     return (CatSPrint(NULL, L"FirmwareManagement"));
1119   }
1120 
1121   Status = gBS->OpenProtocol (
1122                   (EFI_HANDLE) (TheHandle),
1123                   &gEfiFirmwareManagementProtocolGuid,
1124                   (VOID **) &EfiFwMgmtProtocol,
1125                   NULL,
1126                   NULL,
1127                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
1128                   );
1129 
1130   if (EFI_ERROR (Status)) {
1131     return NULL;
1132   }
1133 
1134   Status = EfiFwMgmtProtocol->GetImageInfo (
1135                                 EfiFwMgmtProtocol,
1136                                 &ImageInfoSize,
1137                                 ImageInfo,
1138                                 &DescriptorVersion,
1139                                 &DescriptorCount,
1140                                 &DescriptorSize,
1141                                 &PackageVersion,
1142                                 &PackageVersionName
1143                                 );
1144 
1145   if (Status == EFI_BUFFER_TOO_SMALL) {
1146     ImageInfo = AllocateZeroPool (ImageInfoSize);
1147 
1148     if (ImageInfo == NULL) {
1149       Status = EFI_OUT_OF_RESOURCES;
1150     } else {
1151       Status = EfiFwMgmtProtocol->GetImageInfo (
1152                                     EfiFwMgmtProtocol,
1153                                     &ImageInfoSize,
1154                                     ImageInfo,
1155                                     &DescriptorVersion,
1156                                     &DescriptorCount,
1157                                     &DescriptorSize,
1158                                     &PackageVersion,
1159                                     &PackageVersionName
1160                                     );
1161     }
1162   }
1163 
1164   if (EFI_ERROR (Status)) {
1165     goto ERROR_EXIT;
1166   }
1167 
1168   //
1169   // Decode Image Descriptor data only if its version is supported
1170   //
1171   if (DescriptorVersion <= EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION) {
1172 
1173     if (ImageInfo == NULL) {
1174       goto ERROR_EXIT;
1175     }
1176 
1177     ImageInfoV1 = (EFI_FIRMWARE_IMAGE_DESCRIPTOR_V1 *)ImageInfo;
1178     ImageInfoV2 = (EFI_FIRMWARE_IMAGE_DESCRIPTOR_V2 *)ImageInfo;
1179 
1180     //
1181     // Set ImageInfoSize in return buffer
1182     //
1183     TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_FMP_IMAGE_INFO_SIZE), NULL);
1184     if (TempStr == NULL) {
1185       goto ERROR_EXIT;
1186     }
1187     RetVal = CatSPrint (NULL, TempStr, ImageInfoSize);
1188     SHELL_FREE_NON_NULL (TempStr);
1189 
1190     //
1191     // Set DescriptorVersion in return buffer
1192     //
1193     TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_FMP_DESCRIPTOR_VERSION), NULL);
1194     if (TempStr == NULL) {
1195       goto ERROR_EXIT;
1196     }
1197     TempRetVal = CatSPrint (RetVal, TempStr, DescriptorVersion);
1198     SHELL_FREE_NON_NULL (RetVal);
1199     RetVal = TempRetVal;
1200     SHELL_FREE_NON_NULL (TempStr);
1201 
1202     //
1203     // Set DescriptorCount in return buffer
1204     //
1205     TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_FMP_DESCRIPTOR_COUNT), NULL);
1206     if (TempStr == NULL) {
1207       goto ERROR_EXIT;
1208     }
1209     TempRetVal = CatSPrint (RetVal, TempStr, DescriptorCount);
1210     SHELL_FREE_NON_NULL (RetVal);
1211     RetVal = TempRetVal;
1212     SHELL_FREE_NON_NULL (TempStr);
1213 
1214 
1215     //
1216     // Set DescriptorSize in return buffer
1217     //
1218     TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_FMP_DESCRIPTOR_SIZE), NULL);
1219     if (TempStr == NULL) {
1220       goto ERROR_EXIT;
1221     }
1222     TempRetVal = CatSPrint (RetVal, TempStr, DescriptorSize);
1223     SHELL_FREE_NON_NULL (RetVal);
1224     RetVal = TempRetVal;
1225     SHELL_FREE_NON_NULL (TempStr);
1226 
1227     //
1228     // Set PackageVersion in return buffer
1229     //
1230     TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_FMP_PACKAGE_VERSION), NULL);
1231     if (TempStr == NULL) {
1232       goto ERROR_EXIT;
1233     }
1234     TempRetVal = CatSPrint (RetVal, TempStr, PackageVersion);
1235     SHELL_FREE_NON_NULL (RetVal);
1236     RetVal = TempRetVal;
1237     SHELL_FREE_NON_NULL (TempStr);
1238 
1239     //
1240     // Set PackageVersionName in return buffer
1241     //
1242     TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_FMP_PACKAGE_VERSION_NAME), NULL);
1243     if (TempStr == NULL) {
1244       goto ERROR_EXIT;
1245     }
1246     TempRetVal = CatSPrint (RetVal, TempStr, PackageVersionName);
1247     SHELL_FREE_NON_NULL (RetVal);
1248     RetVal = TempRetVal;
1249     SHELL_FREE_NON_NULL (TempStr);
1250 
1251     for (Index = 0; Index < DescriptorCount; Index++) {
1252       //
1253       // First check if Attribute is supported
1254       // and generate a string for AttributeSetting field
1255       //
1256       SHELL_FREE_NON_NULL (AttributeSettingStr);
1257       AttributeSupported = FALSE;
1258       AttributeSetting   = 0;
1259       if (DescriptorVersion == EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION_V1) {
1260         if (ImageInfoV1[Index].AttributesSupported != 0x0) {
1261           AttributeSupported = TRUE;
1262           AttributeSetting   = ImageInfoV1[Index].AttributesSetting;
1263         }
1264       } else if (DescriptorVersion == EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION_V2) {
1265         if (ImageInfoV2[Index].AttributesSupported != 0x0) {
1266           AttributeSupported = TRUE;
1267           AttributeSetting   = ImageInfoV2[Index].AttributesSetting;
1268         }
1269       } else {
1270         if (ImageInfo[Index].AttributesSupported != 0x0) {
1271           AttributeSupported = TRUE;
1272           AttributeSetting   = ImageInfo[Index].AttributesSetting;
1273         }
1274       }
1275 
1276       if (!AttributeSupported) {
1277         AttributeSettingStr = CatSPrint (NULL, L"None");
1278       } else {
1279         AttributeSettingStr = CatSPrint (NULL, L"(");
1280 
1281         if ((AttributeSetting & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE) != 0x0) {
1282           TempRetVal = CatSPrint (AttributeSettingStr, L" IMAGE_ATTRIBUTE_IMAGE_UPDATABLE");
1283           SHELL_FREE_NON_NULL (AttributeSettingStr);
1284           AttributeSettingStr = TempRetVal;
1285         }
1286         if ((AttributeSetting & IMAGE_ATTRIBUTE_RESET_REQUIRED) != 0x0) {
1287           TempRetVal = CatSPrint (AttributeSettingStr, L" IMAGE_ATTRIBUTE_RESET_REQUIRED");
1288           SHELL_FREE_NON_NULL (AttributeSettingStr);
1289           AttributeSettingStr = TempRetVal;
1290         }
1291         if ((AttributeSetting & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED) != 0x0) {
1292           TempRetVal = CatSPrint (AttributeSettingStr, L" IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED");
1293           SHELL_FREE_NON_NULL (AttributeSettingStr);
1294           AttributeSettingStr = TempRetVal;
1295         }
1296         if ((AttributeSetting & IMAGE_ATTRIBUTE_IN_USE) != 0x0) {
1297           TempRetVal = CatSPrint (AttributeSettingStr, L" IMAGE_ATTRIBUTE_IN_USE");
1298           SHELL_FREE_NON_NULL (AttributeSettingStr);
1299           AttributeSettingStr = TempRetVal;
1300         }
1301         if ((AttributeSetting & IMAGE_ATTRIBUTE_UEFI_IMAGE) != 0x0) {
1302           TempRetVal = CatSPrint (AttributeSettingStr, L" IMAGE_ATTRIBUTE_UEFI_IMAGE");
1303           SHELL_FREE_NON_NULL (AttributeSettingStr);
1304           AttributeSettingStr = TempRetVal;
1305         }
1306         TempRetVal = CatSPrint (AttributeSettingStr, L" )");
1307         SHELL_FREE_NON_NULL (AttributeSettingStr);
1308         AttributeSettingStr = TempRetVal;
1309       }
1310 
1311       if (DescriptorVersion == EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION_V1) {
1312         if (ImageInfoV1[Index].ImageIndex != 0x0) {
1313           ImageCount++;
1314         }
1315 
1316         TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_FMP_IMAGE_DESCRIPTOR_INFO_V1), NULL);
1317         if (TempStr == NULL) {
1318           goto ERROR_EXIT;
1319         }
1320         TempRetVal = CatSPrint (
1321                        RetVal,
1322                        TempStr,
1323                        Index,
1324                        ImageInfoV1[Index].ImageIndex,
1325                        &ImageInfoV1[Index].ImageTypeId,
1326                        ImageInfoV1[Index].ImageId,
1327                        ImageInfoV1[Index].ImageIdName,
1328                        ImageInfoV1[Index].Version,
1329                        ImageInfoV1[Index].VersionName,
1330                        ImageInfoV1[Index].Size,
1331                        ImageInfoV1[Index].AttributesSupported,
1332                        AttributeSettingStr,
1333                        ImageInfoV1[Index].Compatibilities
1334                        );
1335         SHELL_FREE_NON_NULL (RetVal);
1336         RetVal = TempRetVal;
1337         SHELL_FREE_NON_NULL (TempStr);
1338       } else if (DescriptorVersion == EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION_V2) {
1339         if (ImageInfoV2[Index].ImageIndex != 0x0) {
1340           ImageCount++;
1341         }
1342 
1343         TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_FMP_IMAGE_DESCRIPTOR_INFO_V2), NULL);
1344         if (TempStr == NULL) {
1345           goto ERROR_EXIT;
1346         }
1347         TempRetVal = CatSPrint (
1348                        RetVal,
1349                        TempStr,
1350                        Index,
1351                        ImageInfoV2[Index].ImageIndex,
1352                        &ImageInfoV2[Index].ImageTypeId,
1353                        ImageInfoV2[Index].ImageId,
1354                        ImageInfoV2[Index].ImageIdName,
1355                        ImageInfoV2[Index].Version,
1356                        ImageInfoV2[Index].VersionName,
1357                        ImageInfoV2[Index].Size,
1358                        ImageInfoV2[Index].AttributesSupported,
1359                        AttributeSettingStr,
1360                        ImageInfoV2[Index].Compatibilities,
1361                        ImageInfoV2[Index].LowestSupportedImageVersion
1362                        );
1363         SHELL_FREE_NON_NULL (RetVal);
1364         RetVal = TempRetVal;
1365         SHELL_FREE_NON_NULL (TempStr);
1366       } else {
1367         if (ImageInfo[Index].ImageIndex != 0x0) {
1368           ImageCount++;
1369         }
1370 
1371         TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_FMP_IMAGE_DESCRIPTOR_INFO), NULL);
1372         if (TempStr == NULL) {
1373           goto ERROR_EXIT;
1374         }
1375         TempRetVal = CatSPrint (
1376                        RetVal,
1377                        TempStr,
1378                        Index,
1379                        ImageInfo[Index].ImageIndex,
1380                        &ImageInfo[Index].ImageTypeId,
1381                        ImageInfo[Index].ImageId,
1382                        ImageInfo[Index].ImageIdName,
1383                        ImageInfo[Index].Version,
1384                        ImageInfo[Index].VersionName,
1385                        ImageInfo[Index].Size,
1386                        ImageInfo[Index].AttributesSupported,
1387                        AttributeSettingStr,
1388                        ImageInfo[Index].Compatibilities,
1389                        ImageInfo[Index].LowestSupportedImageVersion,
1390                        ImageInfo[Index].LastAttemptVersion,
1391                        ImageInfo[Index].LastAttemptStatus,
1392                        ImageInfo[Index].HardwareInstance
1393                        );
1394         SHELL_FREE_NON_NULL (RetVal);
1395         RetVal = TempRetVal;
1396         SHELL_FREE_NON_NULL (TempStr);
1397       }
1398     }
1399   }
1400 
1401   if (ImageCount > 0) {
1402     for (Index=0; Index<DescriptorCount; Index++) {
1403       for (Index1=Index+1; Index1<DescriptorCount; Index1++) {
1404         if (DescriptorVersion == EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION_V1) {
1405           if (ImageInfoV1[Index].ImageId == ImageInfoV1[Index1].ImageId) {
1406             Found = TRUE;
1407             //
1408             // At least one match found indicating presense of non unique ImageId values so no more comparisons needed
1409             //
1410             goto ENDLOOP;
1411           }
1412         } else if (DescriptorVersion == EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION_V2) {
1413           if (ImageInfoV2[Index].ImageId == ImageInfoV2[Index1].ImageId) {
1414             Found = TRUE;
1415             //
1416             // At least one match found indicating presense of non unique ImageId values so no more comparisons needed
1417             //
1418             goto ENDLOOP;
1419           }
1420         } else {
1421           if (ImageInfo[Index].ImageId == ImageInfo[Index1].ImageId) {
1422             Found = TRUE;
1423             //
1424             // At least one match found indicating presense of non unique ImageId values so no more comparisons needed
1425             //
1426             goto ENDLOOP;
1427           }
1428         }
1429       }
1430     }
1431   }
1432 
1433 ENDLOOP:
1434   //
1435   // Check if ImageId with duplicate value was found
1436   //
1437   if (Found) {
1438     TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_FMP_IMAGEID_NON_UNIQUE), NULL);
1439     if (TempStr == NULL) {
1440       goto ERROR_EXIT;
1441     }
1442     TempRetVal = CatSPrint (RetVal, TempStr);
1443     SHELL_FREE_NON_NULL (RetVal);
1444     RetVal = TempRetVal;
1445     SHELL_FREE_NON_NULL (TempStr);
1446   }
1447 
1448   SHELL_FREE_NON_NULL (ImageInfo);
1449   SHELL_FREE_NON_NULL (PackageVersionName);
1450   SHELL_FREE_NON_NULL (AttributeSettingStr);
1451 
1452   return RetVal;
1453 
1454 ERROR_EXIT:
1455   SHELL_FREE_NON_NULL (RetVal);
1456   SHELL_FREE_NON_NULL (ImageInfo);
1457   SHELL_FREE_NON_NULL (PackageVersionName);
1458   SHELL_FREE_NON_NULL (AttributeSettingStr);
1459 
1460   return NULL;
1461 }
1462 
1463 //
1464 // Put the information on the NT32 protocol GUIDs here so we are not dependant on the Nt32Pkg
1465 //
1466 #define LOCAL_EFI_WIN_NT_THUNK_PROTOCOL_GUID \
1467   { \
1468     0x58c518b1, 0x76f3, 0x11d4, { 0xbc, 0xea, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \
1469   }
1470 
1471 #define LOCAL_EFI_WIN_NT_BUS_DRIVER_IO_PROTOCOL_GUID \
1472   { \
1473     0x96eb4ad6, 0xa32a, 0x11d4, { 0xbc, 0xfd, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \
1474   }
1475 
1476 #define LOCAL_EFI_WIN_NT_SERIAL_PORT_GUID \
1477   { \
1478     0xc95a93d, 0xa006, 0x11d4, { 0xbc, 0xfa, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \
1479   }
1480 STATIC CONST EFI_GUID WinNtThunkProtocolGuid = LOCAL_EFI_WIN_NT_THUNK_PROTOCOL_GUID;
1481 STATIC CONST EFI_GUID WinNtIoProtocolGuid    = LOCAL_EFI_WIN_NT_BUS_DRIVER_IO_PROTOCOL_GUID;
1482 STATIC CONST EFI_GUID WinNtSerialPortGuid    = LOCAL_EFI_WIN_NT_SERIAL_PORT_GUID;
1483 
1484 //
1485 // Deprecated protocols we dont want to link from IntelFrameworkModulePkg
1486 //
1487 #define LOCAL_EFI_ISA_IO_PROTOCOL_GUID \
1488   { \
1489   0x7ee2bd44, 0x3da0, 0x11d4, { 0x9a, 0x38, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
1490   }
1491 #define LOCAL_EFI_ISA_ACPI_PROTOCOL_GUID \
1492   { \
1493   0x64a892dc, 0x5561, 0x4536, { 0x92, 0xc7, 0x79, 0x9b, 0xfc, 0x18, 0x33, 0x55 } \
1494   }
1495 STATIC CONST EFI_GUID EfiIsaIoProtocolGuid = LOCAL_EFI_ISA_IO_PROTOCOL_GUID;
1496 STATIC CONST EFI_GUID EfiIsaAcpiProtocolGuid = LOCAL_EFI_ISA_ACPI_PROTOCOL_GUID;
1497 
1498 
1499 STATIC CONST GUID_INFO_BLOCK mGuidStringListNT[] = {
1500   {STRING_TOKEN(STR_WINNT_THUNK),           (EFI_GUID*)&WinNtThunkProtocolGuid,               NULL},
1501   {STRING_TOKEN(STR_WINNT_DRIVER_IO),       (EFI_GUID*)&WinNtIoProtocolGuid,                  NULL},
1502   {STRING_TOKEN(STR_WINNT_SERIAL_PORT),     (EFI_GUID*)&WinNtSerialPortGuid,                  NULL},
1503   {STRING_TOKEN(STR_UNKNOWN_DEVICE),        NULL,                                             NULL},
1504 };
1505 
1506 STATIC CONST GUID_INFO_BLOCK mGuidStringList[] = {
1507   {STRING_TOKEN(STR_LOADED_IMAGE),          &gEfiLoadedImageProtocolGuid,                     LoadedImageProtocolDumpInformation},
1508   {STRING_TOKEN(STR_DEVICE_PATH),           &gEfiDevicePathProtocolGuid,                      DevicePathProtocolDumpInformation},
1509   {STRING_TOKEN(STR_IMAGE_PATH),            &gEfiLoadedImageDevicePathProtocolGuid,           LoadedImageDevicePathProtocolDumpInformation},
1510   {STRING_TOKEN(STR_DEVICE_PATH_UTIL),      &gEfiDevicePathUtilitiesProtocolGuid,             NULL},
1511   {STRING_TOKEN(STR_DEVICE_PATH_TXT),       &gEfiDevicePathToTextProtocolGuid,                NULL},
1512   {STRING_TOKEN(STR_DEVICE_PATH_FTXT),      &gEfiDevicePathFromTextProtocolGuid,              NULL},
1513   {STRING_TOKEN(STR_DEVICE_PATH_PC),        &gEfiPcAnsiGuid,                                  NULL},
1514   {STRING_TOKEN(STR_DEVICE_PATH_VT100),     &gEfiVT100Guid,                                   NULL},
1515   {STRING_TOKEN(STR_DEVICE_PATH_VT100P),    &gEfiVT100PlusGuid,                               NULL},
1516   {STRING_TOKEN(STR_DEVICE_PATH_VTUTF8),    &gEfiVTUTF8Guid,                                  NULL},
1517   {STRING_TOKEN(STR_DRIVER_BINDING),        &gEfiDriverBindingProtocolGuid,                   NULL},
1518   {STRING_TOKEN(STR_PLATFORM_OVERRIDE),     &gEfiPlatformDriverOverrideProtocolGuid,          NULL},
1519   {STRING_TOKEN(STR_BUS_OVERRIDE),          &gEfiBusSpecificDriverOverrideProtocolGuid,       NULL},
1520   {STRING_TOKEN(STR_DRIVER_DIAG),           &gEfiDriverDiagnosticsProtocolGuid,               NULL},
1521   {STRING_TOKEN(STR_DRIVER_DIAG2),          &gEfiDriverDiagnostics2ProtocolGuid,              NULL},
1522   {STRING_TOKEN(STR_DRIVER_CN),             &gEfiComponentNameProtocolGuid,                   NULL},
1523   {STRING_TOKEN(STR_DRIVER_CN2),            &gEfiComponentName2ProtocolGuid,                  NULL},
1524   {STRING_TOKEN(STR_PLAT_DRV_CFG),          &gEfiPlatformToDriverConfigurationProtocolGuid,   NULL},
1525   {STRING_TOKEN(STR_DRIVER_VERSION),        &gEfiDriverSupportedEfiVersionProtocolGuid,       DriverEfiVersionProtocolDumpInformation},
1526   {STRING_TOKEN(STR_TXT_IN),                &gEfiSimpleTextInProtocolGuid,                    NULL},
1527   {STRING_TOKEN(STR_TXT_IN_EX),             &gEfiSimpleTextInputExProtocolGuid,               NULL},
1528   {STRING_TOKEN(STR_TXT_OUT),               &gEfiSimpleTextOutProtocolGuid,                   TxtOutProtocolDumpInformation},
1529   {STRING_TOKEN(STR_SIM_POINTER),           &gEfiSimplePointerProtocolGuid,                   NULL},
1530   {STRING_TOKEN(STR_ABS_POINTER),           &gEfiAbsolutePointerProtocolGuid,                 NULL},
1531   {STRING_TOKEN(STR_SERIAL_IO),             &gEfiSerialIoProtocolGuid,                        NULL},
1532   {STRING_TOKEN(STR_GRAPHICS_OUTPUT),       &gEfiGraphicsOutputProtocolGuid,                  GraphicsOutputProtocolDumpInformation},
1533   {STRING_TOKEN(STR_EDID_DISCOVERED),       &gEfiEdidDiscoveredProtocolGuid,                  EdidDiscoveredProtocolDumpInformation},
1534   {STRING_TOKEN(STR_EDID_ACTIVE),           &gEfiEdidActiveProtocolGuid,                      EdidActiveProtocolDumpInformation},
1535   {STRING_TOKEN(STR_EDID_OVERRIDE),         &gEfiEdidOverrideProtocolGuid,                    NULL},
1536   {STRING_TOKEN(STR_CON_IN),                &gEfiConsoleInDeviceGuid,                         NULL},
1537   {STRING_TOKEN(STR_CON_OUT),               &gEfiConsoleOutDeviceGuid,                        NULL},
1538   {STRING_TOKEN(STR_STD_ERR),               &gEfiStandardErrorDeviceGuid,                     NULL},
1539   {STRING_TOKEN(STR_LOAD_FILE),             &gEfiLoadFileProtocolGuid,                        NULL},
1540   {STRING_TOKEN(STR_LOAD_FILE2),            &gEfiLoadFile2ProtocolGuid,                       NULL},
1541   {STRING_TOKEN(STR_SIMPLE_FILE_SYS),       &gEfiSimpleFileSystemProtocolGuid,                NULL},
1542   {STRING_TOKEN(STR_TAPE_IO),               &gEfiTapeIoProtocolGuid,                          NULL},
1543   {STRING_TOKEN(STR_DISK_IO),               &gEfiDiskIoProtocolGuid,                          NULL},
1544   {STRING_TOKEN(STR_BLK_IO),                &gEfiBlockIoProtocolGuid,                         NULL},
1545   {STRING_TOKEN(STR_UC),                    &gEfiUnicodeCollationProtocolGuid,                NULL},
1546   {STRING_TOKEN(STR_UC2),                   &gEfiUnicodeCollation2ProtocolGuid,               NULL},
1547   {STRING_TOKEN(STR_PCIRB_IO),              &gEfiPciRootBridgeIoProtocolGuid,                 PciRootBridgeIoDumpInformation},
1548   {STRING_TOKEN(STR_PCI_IO),                &gEfiPciIoProtocolGuid,                           NULL},
1549   {STRING_TOKEN(STR_SCSI_PT),               &gEfiScsiPassThruProtocolGuid,                    NULL},
1550   {STRING_TOKEN(STR_SCSI_IO),               &gEfiScsiIoProtocolGuid,                          NULL},
1551   {STRING_TOKEN(STR_SCSI_PT_EXT),           &gEfiExtScsiPassThruProtocolGuid,                 NULL},
1552   {STRING_TOKEN(STR_ISCSI),                 &gEfiIScsiInitiatorNameProtocolGuid,              NULL},
1553   {STRING_TOKEN(STR_USB_IO),                &gEfiUsbIoProtocolGuid,                           NULL},
1554   {STRING_TOKEN(STR_USB_HC),                &gEfiUsbHcProtocolGuid,                           NULL},
1555   {STRING_TOKEN(STR_USB_HC2),               &gEfiUsb2HcProtocolGuid,                          NULL},
1556   {STRING_TOKEN(STR_DEBUG_SUPPORT),         &gEfiDebugSupportProtocolGuid,                    NULL},
1557   {STRING_TOKEN(STR_DEBUG_PORT),            &gEfiDebugPortProtocolGuid,                       NULL},
1558   {STRING_TOKEN(STR_DECOMPRESS),            &gEfiDecompressProtocolGuid,                      NULL},
1559   {STRING_TOKEN(STR_ACPI_TABLE),            &gEfiAcpiTableProtocolGuid,                       NULL},
1560   {STRING_TOKEN(STR_EBC_INTERPRETER),       &gEfiEbcProtocolGuid,                             NULL},
1561   {STRING_TOKEN(STR_SNP),                   &gEfiSimpleNetworkProtocolGuid,                   NULL},
1562   {STRING_TOKEN(STR_NII),                   &gEfiNetworkInterfaceIdentifierProtocolGuid,      NULL},
1563   {STRING_TOKEN(STR_NII_31),                &gEfiNetworkInterfaceIdentifierProtocolGuid_31,   NULL},
1564   {STRING_TOKEN(STR_PXE_BC),                &gEfiPxeBaseCodeProtocolGuid,                     NULL},
1565   {STRING_TOKEN(STR_PXE_CB),                &gEfiPxeBaseCodeCallbackProtocolGuid,             NULL},
1566   {STRING_TOKEN(STR_BIS),                   &gEfiBisProtocolGuid,                             NULL},
1567   {STRING_TOKEN(STR_MNP_SB),                &gEfiManagedNetworkServiceBindingProtocolGuid,    NULL},
1568   {STRING_TOKEN(STR_MNP),                   &gEfiManagedNetworkProtocolGuid,                  NULL},
1569   {STRING_TOKEN(STR_ARP_SB),                &gEfiArpServiceBindingProtocolGuid,               NULL},
1570   {STRING_TOKEN(STR_ARP),                   &gEfiArpProtocolGuid,                             NULL},
1571   {STRING_TOKEN(STR_DHCPV4_SB),             &gEfiDhcp4ServiceBindingProtocolGuid,             NULL},
1572   {STRING_TOKEN(STR_DHCPV4),                &gEfiDhcp4ProtocolGuid,                           NULL},
1573   {STRING_TOKEN(STR_TCPV4_SB),              &gEfiTcp4ServiceBindingProtocolGuid,              NULL},
1574   {STRING_TOKEN(STR_TCPV4),                 &gEfiTcp4ProtocolGuid,                            NULL},
1575   {STRING_TOKEN(STR_IPV4_SB),               &gEfiIp4ServiceBindingProtocolGuid,               NULL},
1576   {STRING_TOKEN(STR_IPV4),                  &gEfiIp4ProtocolGuid,                             NULL},
1577   {STRING_TOKEN(STR_IPV4_CFG),              &gEfiIp4ConfigProtocolGuid,                       NULL},
1578   {STRING_TOKEN(STR_IPV4_CFG2),             &gEfiIp4Config2ProtocolGuid,                      NULL},
1579   {STRING_TOKEN(STR_UDPV4_SB),              &gEfiUdp4ServiceBindingProtocolGuid,              NULL},
1580   {STRING_TOKEN(STR_UDPV4),                 &gEfiUdp4ProtocolGuid,                            NULL},
1581   {STRING_TOKEN(STR_MTFTPV4_SB),            &gEfiMtftp4ServiceBindingProtocolGuid,            NULL},
1582   {STRING_TOKEN(STR_MTFTPV4),               &gEfiMtftp4ProtocolGuid,                          NULL},
1583   {STRING_TOKEN(STR_AUTH_INFO),             &gEfiAuthenticationInfoProtocolGuid,              NULL},
1584   {STRING_TOKEN(STR_HASH_SB),               &gEfiHashServiceBindingProtocolGuid,              NULL},
1585   {STRING_TOKEN(STR_HASH),                  &gEfiHashProtocolGuid,                            NULL},
1586   {STRING_TOKEN(STR_HII_FONT),              &gEfiHiiFontProtocolGuid,                         NULL},
1587   {STRING_TOKEN(STR_HII_STRING),            &gEfiHiiStringProtocolGuid,                       NULL},
1588   {STRING_TOKEN(STR_HII_IMAGE),             &gEfiHiiImageProtocolGuid,                        NULL},
1589   {STRING_TOKEN(STR_HII_DATABASE),          &gEfiHiiDatabaseProtocolGuid,                     NULL},
1590   {STRING_TOKEN(STR_HII_CONFIG_ROUT),       &gEfiHiiConfigRoutingProtocolGuid,                NULL},
1591   {STRING_TOKEN(STR_HII_CONFIG_ACC),        &gEfiHiiConfigAccessProtocolGuid,                 NULL},
1592   {STRING_TOKEN(STR_HII_FORM_BROWSER2),     &gEfiFormBrowser2ProtocolGuid,                    NULL},
1593   {STRING_TOKEN(STR_DRIVER_FAM_OVERRIDE),   &gEfiDriverFamilyOverrideProtocolGuid,            NULL},
1594   {STRING_TOKEN(STR_PCD),                   &gPcdProtocolGuid,                                NULL},
1595   {STRING_TOKEN(STR_TCG),                   &gEfiTcgProtocolGuid,                             NULL},
1596   {STRING_TOKEN(STR_HII_PACKAGE_LIST),      &gEfiHiiPackageListProtocolGuid,                  NULL},
1597 
1598 //
1599 // the ones under this are deprecated by the current UEFI Spec, but may be found anyways...
1600 //
1601   {STRING_TOKEN(STR_SHELL_INTERFACE),       &gEfiShellInterfaceGuid,                          NULL},
1602   {STRING_TOKEN(STR_SHELL_ENV2),            &gEfiShellEnvironment2Guid,                       NULL},
1603   {STRING_TOKEN(STR_SHELL_ENV),             &gEfiShellEnvironment2Guid,                       NULL},
1604   {STRING_TOKEN(STR_DEVICE_IO),             &gEfiDeviceIoProtocolGuid,                        NULL},
1605   {STRING_TOKEN(STR_UGA_DRAW),              &gEfiUgaDrawProtocolGuid,                         NULL},
1606   {STRING_TOKEN(STR_UGA_IO),                &gEfiUgaIoProtocolGuid,                           NULL},
1607   {STRING_TOKEN(STR_ESP),                   &gEfiPartTypeSystemPartGuid,                      NULL},
1608   {STRING_TOKEN(STR_GPT_NBR),               &gEfiPartTypeLegacyMbrGuid,                       NULL},
1609   {STRING_TOKEN(STR_DRIVER_CONFIG),         &gEfiDriverConfigurationProtocolGuid,             NULL},
1610   {STRING_TOKEN(STR_DRIVER_CONFIG2),        &gEfiDriverConfiguration2ProtocolGuid,            NULL},
1611 
1612 //
1613 // these are using local (non-global) definitions to reduce package dependancy.
1614 //
1615   {STRING_TOKEN(STR_ISA_IO),                (EFI_GUID*)&EfiIsaIoProtocolGuid,                 NULL},
1616   {STRING_TOKEN(STR_ISA_ACPI),              (EFI_GUID*)&EfiIsaAcpiProtocolGuid,               NULL},
1617 
1618 //
1619 // the ones under this are GUID identified structs, not protocols
1620 //
1621   {STRING_TOKEN(STR_FILE_INFO),             &gEfiFileInfoGuid,                                NULL},
1622   {STRING_TOKEN(STR_FILE_SYS_INFO),         &gEfiFileSystemInfoGuid,                          NULL},
1623 
1624 //
1625 // the ones under this are misc GUIDS.
1626 //
1627   {STRING_TOKEN(STR_EFI_GLOBAL_VARIABLE),   &gEfiGlobalVariableGuid,                          NULL},
1628 
1629 //
1630 // UEFI 2.2
1631 //
1632   {STRING_TOKEN(STR_IP6_SB),                &gEfiIp6ServiceBindingProtocolGuid,               NULL},
1633   {STRING_TOKEN(STR_IP6),                   &gEfiIp6ProtocolGuid,                             NULL},
1634   {STRING_TOKEN(STR_IP6_CONFIG),            &gEfiIp6ConfigProtocolGuid,                       NULL},
1635   {STRING_TOKEN(STR_MTFTP6_SB),             &gEfiMtftp6ServiceBindingProtocolGuid,            NULL},
1636   {STRING_TOKEN(STR_MTFTP6),                &gEfiMtftp6ProtocolGuid,                          NULL},
1637   {STRING_TOKEN(STR_DHCP6_SB),              &gEfiDhcp6ServiceBindingProtocolGuid,             NULL},
1638   {STRING_TOKEN(STR_DHCP6),                 &gEfiDhcp6ProtocolGuid,                           NULL},
1639   {STRING_TOKEN(STR_UDP6_SB),               &gEfiUdp6ServiceBindingProtocolGuid,              NULL},
1640   {STRING_TOKEN(STR_UDP6),                  &gEfiUdp6ProtocolGuid,                            NULL},
1641   {STRING_TOKEN(STR_TCP6_SB),               &gEfiTcp6ServiceBindingProtocolGuid,              NULL},
1642   {STRING_TOKEN(STR_TCP6),                  &gEfiTcp6ProtocolGuid,                            NULL},
1643   {STRING_TOKEN(STR_VLAN_CONFIG),           &gEfiVlanConfigProtocolGuid,                      NULL},
1644   {STRING_TOKEN(STR_EAP),                   &gEfiEapProtocolGuid,                             NULL},
1645   {STRING_TOKEN(STR_EAP_MGMT),              &gEfiEapManagementProtocolGuid,                   NULL},
1646   {STRING_TOKEN(STR_FTP4_SB),               &gEfiFtp4ServiceBindingProtocolGuid,              NULL},
1647   {STRING_TOKEN(STR_FTP4),                  &gEfiFtp4ProtocolGuid,                            NULL},
1648   {STRING_TOKEN(STR_IP_SEC_CONFIG),         &gEfiIpSecConfigProtocolGuid,                     NULL},
1649   {STRING_TOKEN(STR_DH),                    &gEfiDriverHealthProtocolGuid,                    NULL},
1650   {STRING_TOKEN(STR_DEF_IMG_LOAD),          &gEfiDeferredImageLoadProtocolGuid,               NULL},
1651   {STRING_TOKEN(STR_USER_CRED),             &gEfiUserCredentialProtocolGuid,                  NULL},
1652   {STRING_TOKEN(STR_USER_MNGR),             &gEfiUserManagerProtocolGuid,                     NULL},
1653   {STRING_TOKEN(STR_ATA_PASS_THRU),         &gEfiAtaPassThruProtocolGuid,                     NULL},
1654 
1655 //
1656 // UEFI 2.3
1657 //
1658   {STRING_TOKEN(STR_FW_MGMT),               &gEfiFirmwareManagementProtocolGuid,              FirmwareManagementDumpInformation},
1659   {STRING_TOKEN(STR_IP_SEC),                &gEfiIpSecProtocolGuid,                           NULL},
1660   {STRING_TOKEN(STR_IP_SEC2),               &gEfiIpSec2ProtocolGuid,                          NULL},
1661 
1662 //
1663 // UEFI 2.3.1
1664 //
1665   {STRING_TOKEN(STR_KMS),                   &gEfiKmsProtocolGuid,                             NULL},
1666   {STRING_TOKEN(STR_BLK_IO2),               &gEfiBlockIo2ProtocolGuid,                        NULL},
1667   {STRING_TOKEN(STR_SSC),                   &gEfiStorageSecurityCommandProtocolGuid,          NULL},
1668   {STRING_TOKEN(STR_UCRED2),                &gEfiUserCredential2ProtocolGuid,                 NULL},
1669 
1670 //
1671 // UEFI 2.4
1672 //
1673   {STRING_TOKEN(STR_DISK_IO2),              &gEfiDiskIo2ProtocolGuid,                         NULL},
1674   {STRING_TOKEN(STR_ADAPTER_INFO),          &gEfiAdapterInformationProtocolGuid,              AdapterInformationDumpInformation},
1675 
1676 //
1677 // PI Spec ones
1678 //
1679   {STRING_TOKEN(STR_IDE_CONT_INIT),         &gEfiIdeControllerInitProtocolGuid,               NULL},
1680   {STRING_TOKEN(STR_DISK_INFO),             &gEfiDiskInfoProtocolGuid,                        NULL},
1681 
1682 //
1683 // PI Spec 1.0
1684 //
1685   {STRING_TOKEN(STR_BDS_ARCH),              &gEfiBdsArchProtocolGuid,                         NULL},
1686   {STRING_TOKEN(STR_CPU_ARCH),              &gEfiCpuArchProtocolGuid,                         NULL},
1687   {STRING_TOKEN(STR_MET_ARCH),              &gEfiMetronomeArchProtocolGuid,                   NULL},
1688   {STRING_TOKEN(STR_MON_ARCH),              &gEfiMonotonicCounterArchProtocolGuid,            NULL},
1689   {STRING_TOKEN(STR_RTC_ARCH),              &gEfiRealTimeClockArchProtocolGuid,               NULL},
1690   {STRING_TOKEN(STR_RESET_ARCH),            &gEfiResetArchProtocolGuid,                       NULL},
1691   {STRING_TOKEN(STR_RT_ARCH),               &gEfiRuntimeArchProtocolGuid,                     NULL},
1692   {STRING_TOKEN(STR_SEC_ARCH),              &gEfiSecurityArchProtocolGuid,                    NULL},
1693   {STRING_TOKEN(STR_TIMER_ARCH),            &gEfiTimerArchProtocolGuid,                       NULL},
1694   {STRING_TOKEN(STR_VAR_ARCH),              &gEfiVariableWriteArchProtocolGuid,               NULL},
1695   {STRING_TOKEN(STR_V_ARCH),                &gEfiVariableArchProtocolGuid,                    NULL},
1696   {STRING_TOKEN(STR_SECP),                  &gEfiSecurityPolicyProtocolGuid,                  NULL},
1697   {STRING_TOKEN(STR_WDT_ARCH),              &gEfiWatchdogTimerArchProtocolGuid,               NULL},
1698   {STRING_TOKEN(STR_SCR),                   &gEfiStatusCodeRuntimeProtocolGuid,               NULL},
1699   {STRING_TOKEN(STR_SMB_HC),                &gEfiSmbusHcProtocolGuid,                         NULL},
1700   {STRING_TOKEN(STR_FV_2),                  &gEfiFirmwareVolume2ProtocolGuid,                 NULL},
1701   {STRING_TOKEN(STR_FV_BLOCK),              &gEfiFirmwareVolumeBlockProtocolGuid,             NULL},
1702   {STRING_TOKEN(STR_CAP_ARCH),              &gEfiCapsuleArchProtocolGuid,                     NULL},
1703   {STRING_TOKEN(STR_MP_SERVICE),            &gEfiMpServiceProtocolGuid,                       NULL},
1704   {STRING_TOKEN(STR_HBRAP),                 &gEfiPciHostBridgeResourceAllocationProtocolGuid, NULL},
1705   {STRING_TOKEN(STR_PCIP),                  &gEfiPciPlatformProtocolGuid,                     NULL},
1706   {STRING_TOKEN(STR_PCIO),                  &gEfiPciOverrideProtocolGuid,                     NULL},
1707   {STRING_TOKEN(STR_PCIE),                  &gEfiPciEnumerationCompleteProtocolGuid,          NULL},
1708   {STRING_TOKEN(STR_IPCID),                 &gEfiIncompatiblePciDeviceSupportProtocolGuid,    NULL},
1709   {STRING_TOKEN(STR_PCIHPI),                &gEfiPciHotPlugInitProtocolGuid,                  NULL},
1710   {STRING_TOKEN(STR_PCIHPR),                &gEfiPciHotPlugRequestProtocolGuid,               NULL},
1711   {STRING_TOKEN(STR_SMBIOS),                &gEfiSmbiosProtocolGuid,                          NULL},
1712   {STRING_TOKEN(STR_S3_SAVE),               &gEfiS3SaveStateProtocolGuid,                     NULL},
1713   {STRING_TOKEN(STR_S3_S_SMM),              &gEfiS3SmmSaveStateProtocolGuid,                  NULL},
1714   {STRING_TOKEN(STR_RSC),                   &gEfiRscHandlerProtocolGuid,                      NULL},
1715   {STRING_TOKEN(STR_S_RSC),                 &gEfiSmmRscHandlerProtocolGuid,                   NULL},
1716   {STRING_TOKEN(STR_ACPI_SDT),              &gEfiAcpiSdtProtocolGuid,                         NULL},
1717   {STRING_TOKEN(STR_SIO),                   &gEfiSioProtocolGuid,                             NULL},
1718   {STRING_TOKEN(STR_S_CPU2),                &gEfiSmmCpuIo2ProtocolGuid,                       NULL},
1719   {STRING_TOKEN(STR_S_BASE2),               &gEfiSmmBase2ProtocolGuid,                        NULL},
1720   {STRING_TOKEN(STR_S_ACC_2),               &gEfiSmmAccess2ProtocolGuid,                      NULL},
1721   {STRING_TOKEN(STR_S_CON_2),               &gEfiSmmControl2ProtocolGuid,                     NULL},
1722   {STRING_TOKEN(STR_S_CONFIG),              &gEfiSmmConfigurationProtocolGuid,                NULL},
1723   {STRING_TOKEN(STR_S_RTL),                 &gEfiSmmReadyToLockProtocolGuid,                  NULL},
1724   {STRING_TOKEN(STR_DS_RTL),                &gEfiDxeSmmReadyToLockProtocolGuid,               NULL},
1725   {STRING_TOKEN(STR_S_COMM),                &gEfiSmmCommunicationProtocolGuid,                NULL},
1726   {STRING_TOKEN(STR_S_STAT),                &gEfiSmmStatusCodeProtocolGuid,                   NULL},
1727   {STRING_TOKEN(STR_S_CPU),                 &gEfiSmmCpuProtocolGuid,                          NULL},
1728   {STRING_TOKEN(STR_S_PCIRBIO),             &gEfiPciRootBridgeIoProtocolGuid,                 NULL},
1729   {STRING_TOKEN(STR_S_SWD),                 &gEfiSmmSwDispatch2ProtocolGuid,                  NULL},
1730   {STRING_TOKEN(STR_S_SXD),                 &gEfiSmmSxDispatch2ProtocolGuid,                  NULL},
1731   {STRING_TOKEN(STR_S_PTD2),                &gEfiSmmPeriodicTimerDispatch2ProtocolGuid,       NULL},
1732   {STRING_TOKEN(STR_S_UD2),                 &gEfiSmmUsbDispatch2ProtocolGuid,                 NULL},
1733   {STRING_TOKEN(STR_S_GD2),                 &gEfiSmmGpiDispatch2ProtocolGuid,                 NULL},
1734   {STRING_TOKEN(STR_S_SBD2),                &gEfiSmmStandbyButtonDispatch2ProtocolGuid,       NULL},
1735   {STRING_TOKEN(STR_S_PBD2),                &gEfiSmmPowerButtonDispatch2ProtocolGuid,         NULL},
1736   {STRING_TOKEN(STR_S_ITD2),                &gEfiSmmIoTrapDispatch2ProtocolGuid,              NULL},
1737   {STRING_TOKEN(STR_PCD),                   &gEfiPcdProtocolGuid,                             NULL},
1738   {STRING_TOKEN(STR_FVB2),                  &gEfiFirmwareVolumeBlock2ProtocolGuid,            NULL},
1739   {STRING_TOKEN(STR_CPUIO2),                &gEfiCpuIo2ProtocolGuid,                          NULL},
1740   {STRING_TOKEN(STR_LEGACY_R2),             &gEfiLegacyRegion2ProtocolGuid,                   NULL},
1741   {STRING_TOKEN(STR_SAL_MIP),               &gEfiSalMcaInitPmiProtocolGuid,                   NULL},
1742   {STRING_TOKEN(STR_ES_BS),                 &gEfiExtendedSalBootServiceProtocolGuid,          NULL},
1743   {STRING_TOKEN(STR_ES_BIO),                &gEfiExtendedSalBaseIoServicesProtocolGuid,       NULL},
1744   {STRING_TOKEN(STR_ES_STALL),              &gEfiExtendedSalStallServicesProtocolGuid,        NULL},
1745   {STRING_TOKEN(STR_ES_RTC),                &gEfiExtendedSalRtcServicesProtocolGuid,          NULL},
1746   {STRING_TOKEN(STR_ES_VS),                 &gEfiExtendedSalVariableServicesProtocolGuid,     NULL},
1747   {STRING_TOKEN(STR_ES_MTC),                &gEfiExtendedSalMtcServicesProtocolGuid,          NULL},
1748   {STRING_TOKEN(STR_ES_RESET),              &gEfiExtendedSalResetServicesProtocolGuid,        NULL},
1749   {STRING_TOKEN(STR_ES_SC),                 &gEfiExtendedSalStatusCodeServicesProtocolGuid,   NULL},
1750   {STRING_TOKEN(STR_ES_FBS),                &gEfiExtendedSalFvBlockServicesProtocolGuid,      NULL},
1751   {STRING_TOKEN(STR_ES_MP),                 &gEfiExtendedSalMpServicesProtocolGuid,           NULL},
1752   {STRING_TOKEN(STR_ES_PAL),                &gEfiExtendedSalPalServicesProtocolGuid,          NULL},
1753   {STRING_TOKEN(STR_ES_BASE),               &gEfiExtendedSalBaseServicesProtocolGuid,         NULL},
1754   {STRING_TOKEN(STR_ES_MCA),                &gEfiExtendedSalMcaServicesProtocolGuid,          NULL},
1755   {STRING_TOKEN(STR_ES_PCI),                &gEfiExtendedSalPciServicesProtocolGuid,          NULL},
1756   {STRING_TOKEN(STR_ES_CACHE),              &gEfiExtendedSalCacheServicesProtocolGuid,        NULL},
1757   {STRING_TOKEN(STR_ES_MCA_LOG),            &gEfiExtendedSalMcaLogServicesProtocolGuid,       NULL},
1758   {STRING_TOKEN(STR_S2ARCH),                &gEfiSecurity2ArchProtocolGuid,                   NULL},
1759   {STRING_TOKEN(STR_EODXE),                 &gEfiSmmEndOfDxeProtocolGuid,                     NULL},
1760   {STRING_TOKEN(STR_ISAHC),                 &gEfiIsaHcProtocolGuid,                           NULL},
1761   {STRING_TOKEN(STR_ISAHC_B),               &gEfiIsaHcServiceBindingProtocolGuid,             NULL},
1762   {STRING_TOKEN(STR_SIO_C),                 &gEfiSioControlProtocolGuid,                      NULL},
1763   {STRING_TOKEN(STR_GET_PCD),               &gEfiGetPcdInfoProtocolGuid,                      NULL},
1764   {STRING_TOKEN(STR_I2C_M),                 &gEfiI2cMasterProtocolGuid,                       NULL},
1765   {STRING_TOKEN(STR_I2CIO),                 &gEfiI2cIoProtocolGuid,                           NULL},
1766   {STRING_TOKEN(STR_I2CEN),                 &gEfiI2cEnumerateProtocolGuid,                    NULL},
1767   {STRING_TOKEN(STR_I2C_H),                 &gEfiI2cHostProtocolGuid,                         NULL},
1768   {STRING_TOKEN(STR_I2C_BCM),               &gEfiI2cBusConfigurationManagementProtocolGuid,   NULL},
1769   {STRING_TOKEN(STR_TREE),                  &gEfiTrEEProtocolGuid,                            NULL},
1770   {STRING_TOKEN(STR_TCG2),                  &gEfiTcg2ProtocolGuid,                            NULL},
1771   {STRING_TOKEN(STR_TIMESTAMP),             &gEfiTimestampProtocolGuid,                       NULL},
1772   {STRING_TOKEN(STR_RNG),                   &gEfiRngProtocolGuid,                             NULL},
1773   {STRING_TOKEN(STR_NVMEPT),                &gEfiNvmExpressPassThruProtocolGuid,              NULL},
1774   {STRING_TOKEN(STR_H2_SB),                 &gEfiHash2ServiceBindingProtocolGuid,             NULL},
1775   {STRING_TOKEN(STR_HASH2),                 &gEfiHash2ProtocolGuid,                           NULL},
1776   {STRING_TOKEN(STR_BIO_C),                 &gEfiBlockIoCryptoProtocolGuid,                   NULL},
1777   {STRING_TOKEN(STR_SCR),                   &gEfiSmartCardReaderProtocolGuid,                 NULL},
1778   {STRING_TOKEN(STR_SCE),                   &gEfiSmartCardEdgeProtocolGuid,                   NULL},
1779   {STRING_TOKEN(STR_USB_FIO),               &gEfiUsbFunctionIoProtocolGuid,                   NULL},
1780   {STRING_TOKEN(STR_BC_HC),                 &gEfiBluetoothHcProtocolGuid,                     NULL},
1781   {STRING_TOKEN(STR_BC_IO_SB),              &gEfiBluetoothIoServiceBindingProtocolGuid,       NULL},
1782   {STRING_TOKEN(STR_BC_IO),                 &gEfiBluetoothIoProtocolGuid,                     NULL},
1783   {STRING_TOKEN(STR_BC_C),                  &gEfiBluetoothConfigProtocolGuid,                 NULL},
1784   {STRING_TOKEN(STR_REG_EXP),               &gEfiRegularExpressionProtocolGuid,               NULL},
1785   {STRING_TOKEN(STR_B_MGR_P),               &gEfiBootManagerPolicyProtocolGuid,               NULL},
1786   {STRING_TOKEN(STR_CKH),                   &gEfiConfigKeywordHandlerProtocolGuid,            NULL},
1787   {STRING_TOKEN(STR_WIFI),                  &gEfiWiFiProtocolGuid,                            NULL},
1788   {STRING_TOKEN(STR_EAP_M),                 &gEfiEapManagement2ProtocolGuid,                  NULL},
1789   {STRING_TOKEN(STR_EAP_C),                 &gEfiEapConfigurationProtocolGuid,                NULL},
1790   {STRING_TOKEN(STR_PKCS7),                 &gEfiPkcs7VerifyProtocolGuid,                     NULL},
1791   {STRING_TOKEN(STR_NET_DNS4_SB),           &gEfiDns4ServiceBindingProtocolGuid,              NULL},
1792   {STRING_TOKEN(STR_NET_DNS4),              &gEfiDns4ProtocolGuid,                            NULL},
1793   {STRING_TOKEN(STR_NET_DNS6_SB),           &gEfiDns6ServiceBindingProtocolGuid,              NULL},
1794   {STRING_TOKEN(STR_NET_DNS6),              &gEfiDns6ProtocolGuid,                            NULL},
1795   {STRING_TOKEN(STR_NET_HTTP_SB),           &gEfiHttpServiceBindingProtocolGuid,              NULL},
1796   {STRING_TOKEN(STR_NET_HTTP),              &gEfiHttpProtocolGuid,                            NULL},
1797   {STRING_TOKEN(STR_NET_HTTP_U),            &gEfiHttpUtilitiesProtocolGuid,                   NULL},
1798   {STRING_TOKEN(STR_REST),                  &gEfiRestProtocolGuid,                            NULL},
1799 
1800 //
1801 // UEFI Shell Spec 2.0
1802 //
1803   {STRING_TOKEN(STR_SHELL_PARAMETERS),      &gEfiShellParametersProtocolGuid,                 NULL},
1804   {STRING_TOKEN(STR_SHELL),                 &gEfiShellProtocolGuid,                           NULL},
1805 
1806 //
1807 // UEFI Shell Spec 2.1
1808 //
1809   {STRING_TOKEN(STR_SHELL_DYNAMIC),         &gEfiShellDynamicCommandProtocolGuid,             NULL},
1810 
1811 //
1812 // Misc
1813 //
1814   {STRING_TOKEN(STR_PCDINFOPROT),           &gGetPcdInfoProtocolGuid,                         NULL},
1815 
1816 //
1817 // terminator
1818 //
1819   {STRING_TOKEN(STR_UNKNOWN_DEVICE),        NULL,                                             NULL},
1820 };
1821 
1822 /**
1823   Function to get the node for a protocol or struct from it's GUID.
1824 
1825   if Guid is NULL, then ASSERT.
1826 
1827   @param[in] Guid               The GUID to look for the name of.
1828 
1829   @return                       The node.
1830 **/
1831 CONST GUID_INFO_BLOCK *
InternalShellGetNodeFromGuid(IN CONST EFI_GUID * Guid)1832 InternalShellGetNodeFromGuid(
1833   IN CONST EFI_GUID* Guid
1834   )
1835 {
1836   CONST GUID_INFO_BLOCK *ListWalker;
1837   UINTN                 LoopCount;
1838 
1839   ASSERT(Guid != NULL);
1840 
1841   for (LoopCount = 0, ListWalker = GuidList; GuidList != NULL && LoopCount < GuidListCount; LoopCount++, ListWalker++) {
1842     if (CompareGuid(ListWalker->GuidId, Guid)) {
1843       return (ListWalker);
1844     }
1845   }
1846 
1847   if (PcdGetBool(PcdShellIncludeNtGuids)) {
1848     for (ListWalker = mGuidStringListNT ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {
1849       if (CompareGuid(ListWalker->GuidId, Guid)) {
1850         return (ListWalker);
1851       }
1852     }
1853   }
1854   for (ListWalker = mGuidStringList ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {
1855     if (CompareGuid(ListWalker->GuidId, Guid)) {
1856       return (ListWalker);
1857     }
1858   }
1859   return (NULL);
1860 }
1861 
1862 /**
1863 Function to add a new GUID/Name mapping.
1864 
1865 @param[in] Guid       The Guid
1866 @param[in] NameID     The STRING id of the HII string to use
1867 @param[in] DumpFunc   The pointer to the dump function
1868 
1869 
1870 @retval EFI_SUCCESS           The operation was sucessful
1871 @retval EFI_OUT_OF_RESOURCES  A memory allocation failed
1872 @retval EFI_INVALID_PARAMETER Guid NameId was invalid
1873 **/
1874 EFI_STATUS
InsertNewGuidNameMapping(IN CONST EFI_GUID * Guid,IN CONST EFI_STRING_ID NameID,IN CONST DUMP_PROTOCOL_INFO DumpFunc OPTIONAL)1875 InsertNewGuidNameMapping(
1876   IN CONST EFI_GUID           *Guid,
1877   IN CONST EFI_STRING_ID      NameID,
1878   IN CONST DUMP_PROTOCOL_INFO DumpFunc OPTIONAL
1879   )
1880 {
1881   ASSERT(Guid   != NULL);
1882   ASSERT(NameID != 0);
1883 
1884   GuidList = ReallocatePool(GuidListCount * sizeof(GUID_INFO_BLOCK), GuidListCount+1 * sizeof(GUID_INFO_BLOCK), GuidList);
1885   if (GuidList == NULL) {
1886     GuidListCount = 0;
1887     return (EFI_OUT_OF_RESOURCES);
1888   }
1889   GuidListCount++;
1890 
1891   GuidList[GuidListCount - 1].GuidId   = AllocateCopyPool(sizeof(EFI_GUID), Guid);
1892   GuidList[GuidListCount - 1].StringId = NameID;
1893   GuidList[GuidListCount - 1].DumpInfo = DumpFunc;
1894 
1895   if (GuidList[GuidListCount - 1].GuidId == NULL) {
1896     return (EFI_OUT_OF_RESOURCES);
1897   }
1898 
1899   return (EFI_SUCCESS);
1900 }
1901 
1902 /**
1903   Function to add a new GUID/Name mapping.
1904 
1905   This cannot overwrite an existing mapping.
1906 
1907   @param[in] Guid       The Guid
1908   @param[in] TheName    The Guid's name
1909   @param[in] Lang       RFC4646 language code list or NULL
1910 
1911   @retval EFI_SUCCESS           The operation was sucessful
1912   @retval EFI_ACCESS_DENIED     There was a duplicate
1913   @retval EFI_OUT_OF_RESOURCES  A memory allocation failed
1914   @retval EFI_INVALID_PARAMETER Guid or TheName was NULL
1915 **/
1916 EFI_STATUS
1917 EFIAPI
AddNewGuidNameMapping(IN CONST EFI_GUID * Guid,IN CONST CHAR16 * TheName,IN CONST CHAR8 * Lang OPTIONAL)1918 AddNewGuidNameMapping(
1919   IN CONST EFI_GUID *Guid,
1920   IN CONST CHAR16   *TheName,
1921   IN CONST CHAR8    *Lang OPTIONAL
1922   )
1923 {
1924   EFI_STRING_ID         NameID;
1925 
1926   HandleParsingHiiInit();
1927 
1928   if (Guid == NULL || TheName == NULL){
1929     return (EFI_INVALID_PARAMETER);
1930   }
1931 
1932   if ((InternalShellGetNodeFromGuid(Guid)) != NULL) {
1933     return (EFI_ACCESS_DENIED);
1934   }
1935 
1936   NameID = HiiSetString(mHandleParsingHiiHandle, 0, (CHAR16*)TheName, Lang);
1937   if (NameID == 0) {
1938     return (EFI_OUT_OF_RESOURCES);
1939   }
1940 
1941   return (InsertNewGuidNameMapping(Guid, NameID, NULL));
1942 }
1943 
1944 /**
1945   Function to get the name of a protocol or struct from it's GUID.
1946 
1947   if Guid is NULL, then ASSERT.
1948 
1949   @param[in] Guid               The GUID to look for the name of.
1950   @param[in] Lang               The language to use.
1951 
1952   @return                       pointer to string of the name.  The caller
1953                                 is responsible to free this memory.
1954 **/
1955 CHAR16*
1956 EFIAPI
GetStringNameFromGuid(IN CONST EFI_GUID * Guid,IN CONST CHAR8 * Lang OPTIONAL)1957 GetStringNameFromGuid(
1958   IN CONST EFI_GUID *Guid,
1959   IN CONST CHAR8    *Lang OPTIONAL
1960   )
1961 {
1962   CONST GUID_INFO_BLOCK *Id;
1963 
1964   HandleParsingHiiInit();
1965 
1966   Id = InternalShellGetNodeFromGuid(Guid);
1967   return (HiiGetString(mHandleParsingHiiHandle, Id==NULL?STRING_TOKEN(STR_UNKNOWN_DEVICE):Id->StringId, Lang));
1968 }
1969 
1970 /**
1971   Function to dump protocol information from a handle.
1972 
1973   This function will return a allocated string buffer containing the
1974   information.  The caller is responsible for freeing the memory.
1975 
1976   If Guid is NULL, ASSERT().
1977   If TheHandle is NULL, ASSERT().
1978 
1979   @param[in] TheHandle      The handle to dump information from.
1980   @param[in] Guid           The GUID of the protocol to dump.
1981   @param[in] Verbose        TRUE for extra info.  FALSE otherwise.
1982 
1983   @return                   The pointer to string.
1984   @retval NULL              An error was encountered.
1985 **/
1986 CHAR16*
1987 EFIAPI
GetProtocolInformationDump(IN CONST EFI_HANDLE TheHandle,IN CONST EFI_GUID * Guid,IN CONST BOOLEAN Verbose)1988 GetProtocolInformationDump(
1989   IN CONST EFI_HANDLE TheHandle,
1990   IN CONST EFI_GUID   *Guid,
1991   IN CONST BOOLEAN    Verbose
1992   )
1993 {
1994   CONST GUID_INFO_BLOCK *Id;
1995 
1996   ASSERT(TheHandle  != NULL);
1997   ASSERT(Guid       != NULL);
1998 
1999   if (TheHandle == NULL || Guid == NULL) {
2000     return (NULL);
2001   }
2002 
2003   Id = InternalShellGetNodeFromGuid(Guid);
2004   if (Id != NULL && Id->DumpInfo != NULL) {
2005     return (Id->DumpInfo(TheHandle, Verbose));
2006   }
2007   return (NULL);
2008 }
2009 
2010 /**
2011   Function to get the Guid for a protocol or struct based on it's string name.
2012 
2013   do not modify the returned Guid.
2014 
2015   @param[in] Name           The pointer to the string name.
2016   @param[in] Lang           The pointer to the language code.
2017   @param[out] Guid          The pointer to the Guid.
2018 
2019   @retval EFI_SUCCESS       The operation was sucessful.
2020 **/
2021 EFI_STATUS
2022 EFIAPI
GetGuidFromStringName(IN CONST CHAR16 * Name,IN CONST CHAR8 * Lang OPTIONAL,OUT EFI_GUID ** Guid)2023 GetGuidFromStringName(
2024   IN CONST CHAR16 *Name,
2025   IN CONST CHAR8  *Lang OPTIONAL,
2026   OUT EFI_GUID    **Guid
2027   )
2028 {
2029   CONST GUID_INFO_BLOCK  *ListWalker;
2030   CHAR16                     *String;
2031   UINTN                  LoopCount;
2032 
2033   HandleParsingHiiInit();
2034 
2035   ASSERT(Guid != NULL);
2036   if (Guid == NULL) {
2037     return (EFI_INVALID_PARAMETER);
2038   }
2039   *Guid = NULL;
2040 
2041   if (PcdGetBool(PcdShellIncludeNtGuids)) {
2042     for (ListWalker = mGuidStringListNT ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {
2043       String = HiiGetString(mHandleParsingHiiHandle, ListWalker->StringId, Lang);
2044       if (Name != NULL && String != NULL && StringNoCaseCompare (&Name, &String) == 0) {
2045         *Guid = ListWalker->GuidId;
2046       }
2047       SHELL_FREE_NON_NULL(String);
2048       if (*Guid != NULL) {
2049         return (EFI_SUCCESS);
2050       }
2051     }
2052   }
2053   for (ListWalker = mGuidStringList ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {
2054     String = HiiGetString(mHandleParsingHiiHandle, ListWalker->StringId, Lang);
2055     if (Name != NULL && String != NULL && StringNoCaseCompare (&Name, &String) == 0) {
2056       *Guid = ListWalker->GuidId;
2057     }
2058     SHELL_FREE_NON_NULL(String);
2059     if (*Guid != NULL) {
2060       return (EFI_SUCCESS);
2061     }
2062   }
2063 
2064   for (LoopCount = 0, ListWalker = GuidList; GuidList != NULL && LoopCount < GuidListCount; LoopCount++, ListWalker++) {
2065     String = HiiGetString(mHandleParsingHiiHandle, ListWalker->StringId, Lang);
2066     if (Name != NULL && String != NULL && StringNoCaseCompare (&Name, &String) == 0) {
2067       *Guid = ListWalker->GuidId;
2068     }
2069     SHELL_FREE_NON_NULL(String);
2070     if (*Guid != NULL) {
2071       return (EFI_SUCCESS);
2072     }
2073   }
2074 
2075   return (EFI_NOT_FOUND);
2076 }
2077 
2078 /**
2079   Get best support language for this driver.
2080 
2081   First base on the user input language  to search, second base on the current
2082   platform used language to search, third get the first language from the
2083   support language list. The caller need to free the buffer of the best language.
2084 
2085   @param[in] SupportedLanguages      The support languages for this driver.
2086   @param[in] InputLanguage           The user input language.
2087   @param[in] Iso639Language          Whether get language for ISO639.
2088 
2089   @return                            The best support language for this driver.
2090 **/
2091 CHAR8 *
2092 EFIAPI
GetBestLanguageForDriver(IN CONST CHAR8 * SupportedLanguages,IN CONST CHAR8 * InputLanguage,IN BOOLEAN Iso639Language)2093 GetBestLanguageForDriver (
2094   IN CONST CHAR8  *SupportedLanguages,
2095   IN CONST CHAR8  *InputLanguage,
2096   IN BOOLEAN      Iso639Language
2097   )
2098 {
2099   CHAR8                         *LanguageVariable;
2100   CHAR8                         *BestLanguage;
2101 
2102   GetVariable2 (Iso639Language ? L"Lang" : L"PlatformLang", &gEfiGlobalVariableGuid, (VOID**)&LanguageVariable, NULL);
2103 
2104   BestLanguage = GetBestLanguage(
2105                    SupportedLanguages,
2106                    Iso639Language,
2107                    (InputLanguage != NULL) ? InputLanguage : "",
2108                    (LanguageVariable != NULL) ? LanguageVariable : "",
2109                    SupportedLanguages,
2110                    NULL
2111                    );
2112 
2113   if (LanguageVariable != NULL) {
2114     FreePool (LanguageVariable);
2115   }
2116 
2117   return BestLanguage;
2118 }
2119 
2120 /**
2121   Function to retrieve the driver name (if possible) from the ComponentName or
2122   ComponentName2 protocol
2123 
2124   @param[in] TheHandle      The driver handle to get the name of.
2125   @param[in] Language       The language to use.
2126 
2127   @retval NULL              The name could not be found.
2128   @return                   A pointer to the string name.  Do not de-allocate the memory.
2129 **/
2130 CONST CHAR16*
2131 EFIAPI
GetStringNameFromHandle(IN CONST EFI_HANDLE TheHandle,IN CONST CHAR8 * Language)2132 GetStringNameFromHandle(
2133   IN CONST EFI_HANDLE TheHandle,
2134   IN CONST CHAR8      *Language
2135   )
2136 {
2137   EFI_COMPONENT_NAME2_PROTOCOL  *CompNameStruct;
2138   EFI_STATUS                    Status;
2139   CHAR16                        *RetVal;
2140   CHAR8                         *BestLang;
2141 
2142   BestLang = NULL;
2143 
2144   Status = gBS->OpenProtocol(
2145     TheHandle,
2146     &gEfiComponentName2ProtocolGuid,
2147     (VOID**)&CompNameStruct,
2148     gImageHandle,
2149     NULL,
2150     EFI_OPEN_PROTOCOL_GET_PROTOCOL);
2151   if (!EFI_ERROR(Status)) {
2152     BestLang = GetBestLanguageForDriver (CompNameStruct->SupportedLanguages, Language, FALSE);
2153     Status = CompNameStruct->GetDriverName(CompNameStruct, BestLang, &RetVal);
2154     if (BestLang != NULL) {
2155       FreePool (BestLang);
2156       BestLang = NULL;
2157     }
2158     if (!EFI_ERROR(Status)) {
2159       return (RetVal);
2160     }
2161   }
2162   Status = gBS->OpenProtocol(
2163     TheHandle,
2164     &gEfiComponentNameProtocolGuid,
2165     (VOID**)&CompNameStruct,
2166     gImageHandle,
2167     NULL,
2168     EFI_OPEN_PROTOCOL_GET_PROTOCOL);
2169   if (!EFI_ERROR(Status)) {
2170     BestLang = GetBestLanguageForDriver (CompNameStruct->SupportedLanguages, Language, FALSE);
2171     Status = CompNameStruct->GetDriverName(CompNameStruct, BestLang, &RetVal);
2172     if (BestLang != NULL) {
2173       FreePool (BestLang);
2174     }
2175     if (!EFI_ERROR(Status)) {
2176       return (RetVal);
2177     }
2178   }
2179   return (NULL);
2180 }
2181 
2182 /**
2183   Function to initialize the file global mHandleList object for use in
2184   vonverting handles to index and index to handle.
2185 
2186   @retval EFI_SUCCESS     The operation was successful.
2187 **/
2188 EFI_STATUS
InternalShellInitHandleList(VOID)2189 InternalShellInitHandleList(
2190   VOID
2191   )
2192 {
2193   EFI_STATUS   Status;
2194   EFI_HANDLE   *HandleBuffer;
2195   UINTN        HandleCount;
2196   HANDLE_LIST  *ListWalker;
2197 
2198   if (mHandleList.NextIndex != 0) {
2199     return EFI_SUCCESS;
2200   }
2201   InitializeListHead(&mHandleList.List.Link);
2202   mHandleList.NextIndex = 1;
2203   Status = gBS->LocateHandleBuffer (
2204                 AllHandles,
2205                 NULL,
2206                 NULL,
2207                 &HandleCount,
2208                 &HandleBuffer
2209                );
2210   ASSERT_EFI_ERROR(Status);
2211   if (EFI_ERROR(Status)) {
2212     return (Status);
2213   }
2214   for (mHandleList.NextIndex = 1 ; mHandleList.NextIndex <= HandleCount ; mHandleList.NextIndex++){
2215     ListWalker = AllocateZeroPool(sizeof(HANDLE_LIST));
2216     if (ListWalker != NULL) {
2217       ListWalker->TheHandle = HandleBuffer[mHandleList.NextIndex - 1];
2218       ListWalker->TheIndex = mHandleList.NextIndex;
2219       InsertTailList (&mHandleList.List.Link, &ListWalker->Link);
2220     }
2221   }
2222   FreePool(HandleBuffer);
2223   return (EFI_SUCCESS);
2224 }
2225 
2226 /**
2227   Function to retrieve the human-friendly index of a given handle.  If the handle
2228   does not have a index one will be automatically assigned.  The index value is valid
2229   until the termination of the shell application.
2230 
2231   @param[in] TheHandle    The handle to retrieve an index for.
2232 
2233   @retval 0               A memory allocation failed.
2234   @return                 The index of the handle.
2235 
2236 **/
2237 UINTN
2238 EFIAPI
ConvertHandleToHandleIndex(IN CONST EFI_HANDLE TheHandle)2239 ConvertHandleToHandleIndex(
2240   IN CONST EFI_HANDLE TheHandle
2241   )
2242 {
2243   EFI_STATUS   Status;
2244   EFI_GUID     **ProtocolBuffer;
2245   UINTN        ProtocolCount;
2246   HANDLE_LIST  *ListWalker;
2247 
2248   if (TheHandle == NULL) {
2249     return 0;
2250   }
2251 
2252   InternalShellInitHandleList();
2253 
2254   for (ListWalker = (HANDLE_LIST*)GetFirstNode(&mHandleList.List.Link)
2255     ;  !IsNull(&mHandleList.List.Link,&ListWalker->Link)
2256     ;  ListWalker = (HANDLE_LIST*)GetNextNode(&mHandleList.List.Link,&ListWalker->Link)
2257    ){
2258     if (ListWalker->TheHandle == TheHandle) {
2259       //
2260       // Verify that TheHandle is still present in the Handle Database
2261       //
2262       Status = gBS->ProtocolsPerHandle(TheHandle, &ProtocolBuffer, &ProtocolCount);
2263       if (EFI_ERROR (Status)) {
2264         //
2265         // TheHandle is not present in the Handle Database, so delete from the handle list
2266         //
2267         RemoveEntryList (&ListWalker->Link);
2268         return 0;
2269       }
2270       FreePool (ProtocolBuffer);
2271       return (ListWalker->TheIndex);
2272     }
2273   }
2274 
2275   //
2276   // Verify that TheHandle is valid handle
2277   //
2278   Status = gBS->ProtocolsPerHandle(TheHandle, &ProtocolBuffer, &ProtocolCount);
2279   if (EFI_ERROR (Status)) {
2280     //
2281     // TheHandle is not valid, so do not add to handle list
2282     //
2283     return 0;
2284   }
2285   FreePool (ProtocolBuffer);
2286 
2287   ListWalker = AllocateZeroPool(sizeof(HANDLE_LIST));
2288   if (ListWalker == NULL) {
2289     return 0;
2290   }
2291   ListWalker->TheHandle = TheHandle;
2292   ListWalker->TheIndex  = mHandleList.NextIndex++;
2293   InsertTailList(&mHandleList.List.Link,&ListWalker->Link);
2294   return (ListWalker->TheIndex);
2295 }
2296 
2297 
2298 
2299 /**
2300   Function to retrieve the EFI_HANDLE from the human-friendly index.
2301 
2302   @param[in] TheIndex     The index to retrieve the EFI_HANDLE for.
2303 
2304   @retval NULL            The index was invalid.
2305   @return                 The EFI_HANDLE that index represents.
2306 
2307 **/
2308 EFI_HANDLE
2309 EFIAPI
ConvertHandleIndexToHandle(IN CONST UINTN TheIndex)2310 ConvertHandleIndexToHandle(
2311   IN CONST UINTN TheIndex
2312   )
2313 {
2314   EFI_STATUS   Status;
2315   EFI_GUID     **ProtocolBuffer;
2316   UINTN        ProtocolCount;
2317   HANDLE_LIST *ListWalker;
2318 
2319   InternalShellInitHandleList();
2320 
2321   if (TheIndex >= mHandleList.NextIndex) {
2322     return NULL;
2323   }
2324 
2325   for (ListWalker = (HANDLE_LIST*)GetFirstNode(&mHandleList.List.Link)
2326     ;  !IsNull(&mHandleList.List.Link,&ListWalker->Link)
2327     ;  ListWalker = (HANDLE_LIST*)GetNextNode(&mHandleList.List.Link,&ListWalker->Link)
2328    ){
2329     if (ListWalker->TheIndex == TheIndex && ListWalker->TheHandle != NULL) {
2330       //
2331       // Verify that LinkWalker->TheHandle is valid handle
2332       //
2333       Status = gBS->ProtocolsPerHandle(ListWalker->TheHandle, &ProtocolBuffer, &ProtocolCount);
2334       if (EFI_ERROR (Status)) {
2335         //
2336         // TheHandle is not valid, so do not add to handle list
2337         //
2338         ListWalker->TheHandle = NULL;
2339       }
2340       return (ListWalker->TheHandle);
2341     }
2342   }
2343   return NULL;
2344 }
2345 
2346 /**
2347   Gets all the related EFI_HANDLEs based on the mask supplied.
2348 
2349   This function scans all EFI_HANDLES in the UEFI environment's handle database
2350   and returns the ones with the specified relationship (Mask) to the specified
2351   controller handle.
2352 
2353   If both DriverBindingHandle and ControllerHandle are NULL, then ASSERT.
2354   If MatchingHandleCount is NULL, then ASSERT.
2355 
2356   If MatchingHandleBuffer is not NULL upon a successful return the memory must be
2357   caller freed.
2358 
2359   @param[in] DriverBindingHandle    The handle with Driver Binding protocol on it.
2360   @param[in] ControllerHandle       The handle with Device Path protocol on it.
2361   @param[in] MatchingHandleCount    The pointer to UINTN that specifies the number of HANDLES in
2362                                     MatchingHandleBuffer.
2363   @param[out] MatchingHandleBuffer  On a successful return, a buffer of MatchingHandleCount
2364                                     EFI_HANDLEs with a terminating NULL EFI_HANDLE.
2365   @param[out] HandleType            An array of type information.
2366 
2367   @retval EFI_SUCCESS               The operation was successful, and any related handles
2368                                     are in MatchingHandleBuffer.
2369   @retval EFI_NOT_FOUND             No matching handles were found.
2370   @retval EFI_INVALID_PARAMETER     A parameter was invalid or out of range.
2371 **/
2372 EFI_STATUS
2373 EFIAPI
ParseHandleDatabaseByRelationshipWithType(IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL,IN CONST EFI_HANDLE ControllerHandle OPTIONAL,IN UINTN * HandleCount,OUT EFI_HANDLE ** HandleBuffer,OUT UINTN ** HandleType)2374 ParseHandleDatabaseByRelationshipWithType (
2375   IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL,
2376   IN CONST EFI_HANDLE ControllerHandle OPTIONAL,
2377   IN UINTN            *HandleCount,
2378   OUT EFI_HANDLE      **HandleBuffer,
2379   OUT UINTN           **HandleType
2380   )
2381 {
2382   EFI_STATUS                          Status;
2383   UINTN                               HandleIndex;
2384   EFI_GUID                            **ProtocolGuidArray;
2385   UINTN                               ArrayCount;
2386   UINTN                               ProtocolIndex;
2387   EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;
2388   UINTN                               OpenInfoCount;
2389   UINTN                               OpenInfoIndex;
2390   UINTN                               ChildIndex;
2391   INTN                                DriverBindingHandleIndex;
2392 
2393   ASSERT(HandleCount  != NULL);
2394   ASSERT(HandleBuffer != NULL);
2395   ASSERT(HandleType   != NULL);
2396   ASSERT(DriverBindingHandle != NULL || ControllerHandle != NULL);
2397 
2398   *HandleCount                  = 0;
2399   *HandleBuffer                 = NULL;
2400   *HandleType                   = NULL;
2401 
2402   //
2403   // Retrieve the list of all handles from the handle database
2404   //
2405   Status = gBS->LocateHandleBuffer (
2406                 AllHandles,
2407                 NULL,
2408                 NULL,
2409                 HandleCount,
2410                 HandleBuffer
2411                );
2412   if (EFI_ERROR (Status)) {
2413     return (Status);
2414   }
2415 
2416   *HandleType = AllocateZeroPool (*HandleCount * sizeof (UINTN));
2417   if (*HandleType == NULL) {
2418     SHELL_FREE_NON_NULL (*HandleBuffer);
2419     *HandleCount = 0;
2420     return EFI_OUT_OF_RESOURCES;
2421   }
2422 
2423   DriverBindingHandleIndex = -1;
2424   for (HandleIndex = 0; HandleIndex < *HandleCount; HandleIndex++) {
2425     if (DriverBindingHandle != NULL && (*HandleBuffer)[HandleIndex] == DriverBindingHandle) {
2426       DriverBindingHandleIndex = (INTN)HandleIndex;
2427     }
2428   }
2429 
2430   for (HandleIndex = 0; HandleIndex < *HandleCount; HandleIndex++) {
2431     //
2432     // Retrieve the list of all the protocols on each handle
2433     //
2434     Status = gBS->ProtocolsPerHandle (
2435                   (*HandleBuffer)[HandleIndex],
2436                   &ProtocolGuidArray,
2437                   &ArrayCount
2438                  );
2439     if (EFI_ERROR (Status)) {
2440       continue;
2441     }
2442 
2443     for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
2444 
2445       //
2446       // Set the bit describing what this handle has
2447       //
2448       if        (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiLoadedImageProtocolGuid)         ) {
2449         (*HandleType)[HandleIndex] |= (UINTN)HR_IMAGE_HANDLE;
2450       } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverBindingProtocolGuid)       ) {
2451         (*HandleType)[HandleIndex] |= (UINTN)HR_DRIVER_BINDING_HANDLE;
2452       } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverConfiguration2ProtocolGuid)) {
2453         (*HandleType)[HandleIndex] |= (UINTN)HR_DRIVER_CONFIGURATION_HANDLE;
2454       } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverConfigurationProtocolGuid) ) {
2455         (*HandleType)[HandleIndex] |= (UINTN)HR_DRIVER_CONFIGURATION_HANDLE;
2456       } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverDiagnostics2ProtocolGuid)  ) {
2457         (*HandleType)[HandleIndex] |= (UINTN)HR_DRIVER_DIAGNOSTICS_HANDLE;
2458       } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverDiagnosticsProtocolGuid)   ) {
2459         (*HandleType)[HandleIndex] |= (UINTN)HR_DRIVER_DIAGNOSTICS_HANDLE;
2460       } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentName2ProtocolGuid)      ) {
2461         (*HandleType)[HandleIndex] |= (UINTN)HR_COMPONENT_NAME_HANDLE;
2462       } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentNameProtocolGuid)       ) {
2463         (*HandleType)[HandleIndex] |= (UINTN)HR_COMPONENT_NAME_HANDLE;
2464       } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDevicePathProtocolGuid)          ) {
2465         (*HandleType)[HandleIndex] |= (UINTN)HR_DEVICE_HANDLE;
2466       }
2467       //
2468       // Retrieve the list of agents that have opened each protocol
2469       //
2470       Status = gBS->OpenProtocolInformation (
2471                       (*HandleBuffer)[HandleIndex],
2472                       ProtocolGuidArray[ProtocolIndex],
2473                       &OpenInfo,
2474                       &OpenInfoCount
2475                      );
2476       if (EFI_ERROR (Status)) {
2477         continue;
2478       }
2479 
2480       if (ControllerHandle == NULL) {
2481         //
2482         // ControllerHandle == NULL and DriverBindingHandle != NULL.
2483         // Return information on all the controller handles that the driver specified by DriverBindingHandle is managing
2484         //
2485         for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
2486           if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle && (OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
2487             (*HandleType)[HandleIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);
2488             if (DriverBindingHandleIndex != -1) {
2489               (*HandleType)[DriverBindingHandleIndex] |= (UINTN)HR_DEVICE_DRIVER;
2490             }
2491           }
2492           if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle && (OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
2493             (*HandleType)[HandleIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);
2494             if (DriverBindingHandleIndex != -1) {
2495               (*HandleType)[DriverBindingHandleIndex] |= (UINTN)(HR_BUS_DRIVER | HR_DEVICE_DRIVER);
2496             }
2497             for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
2498               if (OpenInfo[OpenInfoIndex].ControllerHandle == (*HandleBuffer)[ChildIndex]) {
2499                 (*HandleType)[ChildIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CHILD_HANDLE);
2500               }
2501             }
2502           }
2503         }
2504       }
2505       if (DriverBindingHandle == NULL && ControllerHandle != NULL) {
2506         if (ControllerHandle == (*HandleBuffer)[HandleIndex]) {
2507           (*HandleType)[HandleIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);
2508           for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
2509             if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
2510               for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
2511                 if (OpenInfo[OpenInfoIndex].AgentHandle == (*HandleBuffer)[ChildIndex]) {
2512                   (*HandleType)[ChildIndex] |= (UINTN)HR_DEVICE_DRIVER;
2513                 }
2514               }
2515             }
2516             if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
2517               for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
2518                 if (OpenInfo[OpenInfoIndex].AgentHandle == (*HandleBuffer)[ChildIndex]) {
2519                   (*HandleType)[ChildIndex] |= (UINTN)(HR_BUS_DRIVER | HR_DEVICE_DRIVER);
2520                 }
2521                 if (OpenInfo[OpenInfoIndex].ControllerHandle == (*HandleBuffer)[ChildIndex]) {
2522                   (*HandleType)[ChildIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CHILD_HANDLE);
2523                 }
2524               }
2525             }
2526           }
2527         } else {
2528           for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
2529             if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
2530               if (OpenInfo[OpenInfoIndex].ControllerHandle == ControllerHandle) {
2531                 (*HandleType)[HandleIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_PARENT_HANDLE);
2532               }
2533             }
2534           }
2535         }
2536       }
2537       if (DriverBindingHandle != NULL && ControllerHandle != NULL) {
2538         if (ControllerHandle == (*HandleBuffer)[HandleIndex]) {
2539           (*HandleType)[HandleIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);
2540           for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
2541             if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
2542               if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) {
2543                 if (DriverBindingHandleIndex != -1) {
2544                   (*HandleType)[DriverBindingHandleIndex] |= (UINTN)HR_DEVICE_DRIVER;
2545                 }
2546               }
2547             }
2548             if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
2549               if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) {
2550                 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
2551                   if (OpenInfo[OpenInfoIndex].ControllerHandle == (*HandleBuffer)[ChildIndex]) {
2552                     (*HandleType)[ChildIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CHILD_HANDLE);
2553                   }
2554                 }
2555               }
2556 
2557               for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
2558                 if (OpenInfo[OpenInfoIndex].AgentHandle == (*HandleBuffer)[ChildIndex]) {
2559                   (*HandleType)[ChildIndex] |= (UINTN)(HR_BUS_DRIVER | HR_DEVICE_DRIVER);
2560                 }
2561               }
2562             }
2563           }
2564         } else {
2565           for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
2566             if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
2567               if (OpenInfo[OpenInfoIndex].ControllerHandle == ControllerHandle) {
2568                 (*HandleType)[HandleIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_PARENT_HANDLE);
2569               }
2570             }
2571           }
2572         }
2573       }
2574       FreePool (OpenInfo);
2575     }
2576     FreePool (ProtocolGuidArray);
2577   }
2578   return EFI_SUCCESS;
2579 }
2580 
2581 /**
2582   Gets all the related EFI_HANDLEs based on the single EFI_HANDLE and the mask
2583   supplied.
2584 
2585   This function will scan all EFI_HANDLES in the UEFI environment's handle database
2586   and return all the ones with the specified relationship (Mask) to the specified
2587   controller handle.
2588 
2589   If both DriverBindingHandle and ControllerHandle are NULL, then ASSERT.
2590   If MatchingHandleCount is NULL, then ASSERT.
2591 
2592   If MatchingHandleBuffer is not NULL upon a sucessful return the memory must be
2593   caller freed.
2594 
2595   @param[in] DriverBindingHandle    Handle to a object with Driver Binding protocol
2596                                     on it.
2597   @param[in] ControllerHandle       Handle to a device with Device Path protocol on it.
2598   @param[in] Mask                   Mask of what relationship(s) is desired.
2599   @param[in] MatchingHandleCount    Poitner to UINTN specifying number of HANDLES in
2600                                     MatchingHandleBuffer.
2601   @param[out] MatchingHandleBuffer  On a sucessful return a buffer of MatchingHandleCount
2602                                     EFI_HANDLEs and a terminating NULL EFI_HANDLE.
2603 
2604   @retval EFI_SUCCESS               The operation was sucessful and any related handles
2605                                     are in MatchingHandleBuffer;
2606   @retval EFI_NOT_FOUND             No matching handles were found.
2607   @retval EFI_INVALID_PARAMETER     A parameter was invalid or out of range.
2608 **/
2609 EFI_STATUS
2610 EFIAPI
ParseHandleDatabaseByRelationship(IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL,IN CONST EFI_HANDLE ControllerHandle OPTIONAL,IN CONST UINTN Mask,IN UINTN * MatchingHandleCount,OUT EFI_HANDLE ** MatchingHandleBuffer OPTIONAL)2611 ParseHandleDatabaseByRelationship (
2612   IN CONST EFI_HANDLE       DriverBindingHandle OPTIONAL,
2613   IN CONST EFI_HANDLE       ControllerHandle OPTIONAL,
2614   IN CONST UINTN            Mask,
2615   IN UINTN                  *MatchingHandleCount,
2616   OUT EFI_HANDLE            **MatchingHandleBuffer OPTIONAL
2617   )
2618 {
2619   EFI_STATUS            Status;
2620   UINTN                 HandleCount;
2621   EFI_HANDLE            *HandleBuffer;
2622   UINTN                 *HandleType;
2623   UINTN                 HandleIndex;
2624 
2625   ASSERT(MatchingHandleCount != NULL);
2626   ASSERT(DriverBindingHandle != NULL || ControllerHandle != NULL);
2627 
2628   if ((Mask & HR_VALID_MASK) != Mask) {
2629     return (EFI_INVALID_PARAMETER);
2630   }
2631 
2632   if ((Mask & HR_CHILD_HANDLE) != 0 && DriverBindingHandle == NULL) {
2633     return (EFI_INVALID_PARAMETER);
2634   }
2635 
2636   *MatchingHandleCount = 0;
2637   if (MatchingHandleBuffer != NULL) {
2638     *MatchingHandleBuffer = NULL;
2639   }
2640 
2641   HandleBuffer  = NULL;
2642   HandleType    = NULL;
2643 
2644   Status = ParseHandleDatabaseByRelationshipWithType (
2645             DriverBindingHandle,
2646             ControllerHandle,
2647             &HandleCount,
2648             &HandleBuffer,
2649             &HandleType
2650            );
2651   if (!EFI_ERROR (Status)) {
2652     //
2653     // Count the number of handles that match the attributes in Mask
2654     //
2655     for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
2656       if ((HandleType[HandleIndex] & Mask) == Mask) {
2657         (*MatchingHandleCount)++;
2658       }
2659     }
2660     //
2661     // If no handles match the attributes in Mask then return EFI_NOT_FOUND
2662     //
2663     if (*MatchingHandleCount == 0) {
2664       Status = EFI_NOT_FOUND;
2665     } else {
2666 
2667       if (MatchingHandleBuffer == NULL) {
2668         //
2669         // Someone just wanted the count...
2670         //
2671         Status = EFI_SUCCESS;
2672       } else {
2673         //
2674         // Allocate a handle buffer for the number of handles that matched the attributes in Mask
2675         //
2676         *MatchingHandleBuffer = AllocateZeroPool ((*MatchingHandleCount +1)* sizeof (EFI_HANDLE));
2677         if (*MatchingHandleBuffer == NULL) {
2678           Status = EFI_OUT_OF_RESOURCES;
2679         } else {
2680           for (HandleIndex = 0, *MatchingHandleCount = 0
2681                ;  HandleIndex < HandleCount
2682                ;  HandleIndex++
2683                ) {
2684             //
2685             // Fill the allocated buffer with the handles that matched the attributes in Mask
2686             //
2687             if ((HandleType[HandleIndex] & Mask) == Mask) {
2688               (*MatchingHandleBuffer)[(*MatchingHandleCount)++] = HandleBuffer[HandleIndex];
2689             }
2690           }
2691 
2692           //
2693           // Make the last one NULL
2694           //
2695           (*MatchingHandleBuffer)[*MatchingHandleCount] = NULL;
2696 
2697           Status = EFI_SUCCESS;
2698         } // *MatchingHandleBuffer == NULL (ELSE)
2699       } // MacthingHandleBuffer == NULL (ELSE)
2700     } // *MatchingHandleCount  == 0 (ELSE)
2701   } // no error on ParseHandleDatabaseByRelationshipWithType
2702 
2703   if (HandleBuffer != NULL) {
2704     FreePool (HandleBuffer);
2705   }
2706 
2707   if (HandleType != NULL) {
2708     FreePool (HandleType);
2709   }
2710 
2711   ASSERT ((MatchingHandleBuffer == NULL) ||
2712           (*MatchingHandleCount == 0 && *MatchingHandleBuffer == NULL) ||
2713           (*MatchingHandleCount != 0 && *MatchingHandleBuffer != NULL));
2714   return Status;
2715 }
2716 
2717 /**
2718   Gets handles for any child controllers of the passed in controller.
2719 
2720   @param[in] ControllerHandle       The handle of the "parent controller"
2721   @param[out] MatchingHandleCount   Pointer to the number of handles in
2722                                     MatchingHandleBuffer on return.
2723   @param[out] MatchingHandleBuffer  Buffer containing handles on a successful
2724                                     return.
2725 
2726 
2727   @retval EFI_SUCCESS               The operation was sucessful.
2728 **/
2729 EFI_STATUS
2730 EFIAPI
ParseHandleDatabaseForChildControllers(IN CONST EFI_HANDLE ControllerHandle,OUT UINTN * MatchingHandleCount,OUT EFI_HANDLE ** MatchingHandleBuffer OPTIONAL)2731 ParseHandleDatabaseForChildControllers(
2732   IN CONST EFI_HANDLE       ControllerHandle,
2733   OUT UINTN                 *MatchingHandleCount,
2734   OUT EFI_HANDLE            **MatchingHandleBuffer OPTIONAL
2735   )
2736 {
2737   EFI_STATUS  Status;
2738   UINTN       HandleIndex;
2739   UINTN       DriverBindingHandleCount;
2740   EFI_HANDLE  *DriverBindingHandleBuffer;
2741   UINTN       DriverBindingHandleIndex;
2742   UINTN       ChildControllerHandleCount;
2743   EFI_HANDLE  *ChildControllerHandleBuffer;
2744   UINTN       ChildControllerHandleIndex;
2745   EFI_HANDLE  *HandleBufferForReturn;
2746 
2747   if (MatchingHandleCount == NULL) {
2748     return (EFI_INVALID_PARAMETER);
2749   }
2750   *MatchingHandleCount = 0;
2751 
2752   Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
2753             ControllerHandle,
2754             &DriverBindingHandleCount,
2755             &DriverBindingHandleBuffer
2756            );
2757   if (EFI_ERROR (Status)) {
2758     return Status;
2759   }
2760 
2761   //
2762   // Get a buffer big enough for all the controllers.
2763   //
2764   HandleBufferForReturn = GetHandleListByProtocol(NULL);
2765   if (HandleBufferForReturn == NULL) {
2766     FreePool (DriverBindingHandleBuffer);
2767     return (EFI_NOT_FOUND);
2768   }
2769 
2770   for (DriverBindingHandleIndex = 0; DriverBindingHandleIndex < DriverBindingHandleCount; DriverBindingHandleIndex++) {
2771     Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
2772               DriverBindingHandleBuffer[DriverBindingHandleIndex],
2773               ControllerHandle,
2774               &ChildControllerHandleCount,
2775               &ChildControllerHandleBuffer
2776              );
2777     if (EFI_ERROR (Status)) {
2778       continue;
2779     }
2780 
2781     for (ChildControllerHandleIndex = 0;
2782          ChildControllerHandleIndex < ChildControllerHandleCount;
2783          ChildControllerHandleIndex++
2784        ) {
2785       for (HandleIndex = 0; HandleIndex < *MatchingHandleCount; HandleIndex++) {
2786         if (HandleBufferForReturn[HandleIndex] == ChildControllerHandleBuffer[ChildControllerHandleIndex]) {
2787           break;
2788         }
2789       }
2790       if (HandleIndex >= *MatchingHandleCount) {
2791         HandleBufferForReturn[(*MatchingHandleCount)++] = ChildControllerHandleBuffer[ChildControllerHandleIndex];
2792       }
2793     }
2794 
2795     FreePool (ChildControllerHandleBuffer);
2796   }
2797 
2798   FreePool (DriverBindingHandleBuffer);
2799 
2800   if (MatchingHandleBuffer == NULL || *MatchingHandleCount == 0) {
2801     //
2802     // The caller is not interested in the actual handles, or we've found none.
2803     //
2804     FreePool (HandleBufferForReturn);
2805     HandleBufferForReturn = NULL;
2806   }
2807 
2808   if (MatchingHandleBuffer != NULL) {
2809     *MatchingHandleBuffer = HandleBufferForReturn;
2810   }
2811 
2812   ASSERT ((MatchingHandleBuffer == NULL) ||
2813           (*MatchingHandleCount == 0 && *MatchingHandleBuffer == NULL) ||
2814           (*MatchingHandleCount != 0 && *MatchingHandleBuffer != NULL));
2815 
2816   return (EFI_SUCCESS);
2817 }
2818 
2819 /**
2820   Appends 1 buffer to another buffer.  This will re-allocate the destination buffer
2821   if necessary to fit all of the data.
2822 
2823   If DestinationBuffer is NULL, then ASSERT().
2824 
2825   @param[in, out]  DestinationBuffer The pointer to the pointer to the buffer to append onto.
2826   @param[in, out]  DestinationSize   The pointer to the size of DestinationBuffer.
2827   @param[in]       SourceBuffer      The pointer to the buffer to append onto DestinationBuffer.
2828   @param[in]       SourceSize        The number of bytes of SourceBuffer to append.
2829 
2830   @retval NULL                      A memory allocation failed.
2831   @retval NULL                      A parameter was invalid.
2832   @return                           A pointer to (*DestinationBuffer).
2833 **/
2834 VOID*
BuffernCatGrow(IN OUT VOID ** DestinationBuffer,IN OUT UINTN * DestinationSize,IN VOID * SourceBuffer,IN UINTN SourceSize)2835 BuffernCatGrow (
2836   IN OUT VOID   **DestinationBuffer,
2837   IN OUT UINTN  *DestinationSize,
2838   IN     VOID   *SourceBuffer,
2839   IN     UINTN  SourceSize
2840   )
2841 {
2842   UINTN LocalDestinationSize;
2843   UINTN LocalDestinationFinalSize;
2844 
2845   ASSERT(DestinationBuffer != NULL);
2846 
2847   if (SourceSize == 0 || SourceBuffer == NULL) {
2848     return (*DestinationBuffer);
2849   }
2850 
2851   if (DestinationSize == NULL) {
2852     LocalDestinationSize = 0;
2853   } else {
2854     LocalDestinationSize = *DestinationSize;
2855   }
2856 
2857   LocalDestinationFinalSize = LocalDestinationSize + SourceSize;
2858 
2859   if (DestinationSize != NULL) {
2860     *DestinationSize = LocalDestinationSize;
2861   }
2862 
2863   if (LocalDestinationSize == 0) {
2864     // allcoate
2865     *DestinationBuffer = AllocateZeroPool(LocalDestinationFinalSize);
2866   } else {
2867     // reallocate
2868     *DestinationBuffer = ReallocatePool(LocalDestinationSize, LocalDestinationFinalSize, *DestinationBuffer);
2869   }
2870 
2871   ASSERT(*DestinationBuffer != NULL);
2872 
2873   // copy
2874   return (CopyMem(((UINT8*)(*DestinationBuffer)) + LocalDestinationSize, SourceBuffer, SourceSize));
2875 }
2876 
2877 /**
2878   Gets handles for any child devices produced by the passed in driver.
2879 
2880   @param[in] DriverHandle           The handle of the driver.
2881   @param[in] MatchingHandleCount    Pointer to the number of handles in
2882                                     MatchingHandleBuffer on return.
2883   @param[out] MatchingHandleBuffer  Buffer containing handles on a successful
2884                                     return.
2885   @retval EFI_SUCCESS               The operation was sucessful.
2886   @sa ParseHandleDatabaseByRelationship
2887 **/
2888 EFI_STATUS
2889 EFIAPI
ParseHandleDatabaseForChildDevices(IN CONST EFI_HANDLE DriverHandle,IN UINTN * MatchingHandleCount,OUT EFI_HANDLE ** MatchingHandleBuffer OPTIONAL)2890 ParseHandleDatabaseForChildDevices(
2891   IN CONST EFI_HANDLE       DriverHandle,
2892   IN UINTN                  *MatchingHandleCount,
2893   OUT EFI_HANDLE            **MatchingHandleBuffer OPTIONAL
2894   )
2895 {
2896   EFI_HANDLE      *Buffer;
2897   EFI_HANDLE      *Buffer2;
2898   UINTN           Count1;
2899   UINTN           Count2;
2900   UINTN           HandleIndex;
2901   EFI_STATUS      Status;
2902   UINTN           HandleBufferSize;
2903 
2904   ASSERT(MatchingHandleCount != NULL);
2905 
2906   HandleBufferSize      = 0;
2907   Buffer                = NULL;
2908   Buffer2               = NULL;
2909   *MatchingHandleCount  = 0;
2910 
2911   Status = PARSE_HANDLE_DATABASE_DEVICES (
2912             DriverHandle,
2913             &Count1,
2914             &Buffer
2915            );
2916   if (!EFI_ERROR (Status)) {
2917     for (HandleIndex = 0; HandleIndex < Count1; HandleIndex++) {
2918       //
2919       // now find the children
2920       //
2921       Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
2922                 DriverHandle,
2923                 Buffer[HandleIndex],
2924                 &Count2,
2925                 &Buffer2
2926                );
2927       if (EFI_ERROR(Status)) {
2928         break;
2929       }
2930       //
2931       // save out required and optional data elements
2932       //
2933       *MatchingHandleCount += Count2;
2934       if (MatchingHandleBuffer != NULL) {
2935         *MatchingHandleBuffer = BuffernCatGrow((VOID**)MatchingHandleBuffer, &HandleBufferSize, Buffer2, Count2 * sizeof(Buffer2[0]));
2936       }
2937 
2938       //
2939       // free the memory
2940       //
2941       if (Buffer2 != NULL) {
2942         FreePool(Buffer2);
2943       }
2944     }
2945   }
2946 
2947   if (Buffer != NULL) {
2948     FreePool(Buffer);
2949   }
2950   return (Status);
2951 }
2952 
2953 /**
2954   Function to get all handles that support a given protocol or all handles.
2955 
2956   @param[in] ProtocolGuid The guid of the protocol to get handles for.  If NULL
2957                           then the function will return all handles.
2958 
2959   @retval NULL            A memory allocation failed.
2960   @return                 A NULL terminated list of handles.
2961 **/
2962 EFI_HANDLE*
2963 EFIAPI
GetHandleListByProtocol(IN CONST EFI_GUID * ProtocolGuid OPTIONAL)2964 GetHandleListByProtocol (
2965   IN CONST EFI_GUID *ProtocolGuid OPTIONAL
2966   )
2967 {
2968   EFI_HANDLE          *HandleList;
2969   UINTN               Size;
2970   EFI_STATUS          Status;
2971 
2972   Size = 0;
2973   HandleList = NULL;
2974 
2975   //
2976   // We cannot use LocateHandleBuffer since we need that NULL item on the ends of the list!
2977   //
2978   if (ProtocolGuid == NULL) {
2979     Status = gBS->LocateHandle(AllHandles, NULL, NULL, &Size, HandleList);
2980     if (Status == EFI_BUFFER_TOO_SMALL) {
2981       HandleList = AllocateZeroPool(Size + sizeof(EFI_HANDLE));
2982       if (HandleList == NULL) {
2983         return (NULL);
2984       }
2985       Status = gBS->LocateHandle(AllHandles, NULL, NULL, &Size, HandleList);
2986       HandleList[Size/sizeof(EFI_HANDLE)] = NULL;
2987     }
2988   } else {
2989     Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)ProtocolGuid, NULL, &Size, HandleList);
2990     if (Status == EFI_BUFFER_TOO_SMALL) {
2991       HandleList = AllocateZeroPool(Size + sizeof(EFI_HANDLE));
2992       if (HandleList == NULL) {
2993         return (NULL);
2994       }
2995       Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)ProtocolGuid, NULL, &Size, HandleList);
2996       HandleList[Size/sizeof(EFI_HANDLE)] = NULL;
2997     }
2998   }
2999   if (EFI_ERROR(Status)) {
3000     if (HandleList != NULL) {
3001       FreePool(HandleList);
3002     }
3003     return (NULL);
3004   }
3005   return (HandleList);
3006 }
3007 
3008 /**
3009   Function to get all handles that support some protocols.
3010 
3011   @param[in] ProtocolGuids  A NULL terminated list of protocol GUIDs.
3012 
3013   @retval NULL              A memory allocation failed.
3014   @retval NULL              ProtocolGuids was NULL.
3015   @return                   A NULL terminated list of EFI_HANDLEs.
3016 **/
3017 EFI_HANDLE*
3018 EFIAPI
GetHandleListByProtocolList(IN CONST EFI_GUID ** ProtocolGuids)3019 GetHandleListByProtocolList (
3020   IN CONST EFI_GUID **ProtocolGuids
3021   )
3022 {
3023   EFI_HANDLE          *HandleList;
3024   UINTN               Size;
3025   UINTN               TotalSize;
3026   UINTN               TempSize;
3027   EFI_STATUS          Status;
3028   CONST EFI_GUID      **GuidWalker;
3029   EFI_HANDLE          *HandleWalker1;
3030   EFI_HANDLE          *HandleWalker2;
3031 
3032   Size        = 0;
3033   HandleList  = NULL;
3034   TotalSize   = sizeof(EFI_HANDLE);
3035 
3036   for (GuidWalker = ProtocolGuids ; GuidWalker != NULL && *GuidWalker != NULL ; GuidWalker++,Size = 0){
3037     Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)(*GuidWalker), NULL, &Size, NULL);
3038     if (Status == EFI_BUFFER_TOO_SMALL) {
3039       TotalSize += Size;
3040     }
3041   }
3042 
3043   //
3044   // No handles were found...
3045   //
3046   if (TotalSize == sizeof(EFI_HANDLE)) {
3047     return (NULL);
3048   }
3049 
3050   HandleList = AllocateZeroPool(TotalSize);
3051   if (HandleList == NULL) {
3052     return (NULL);
3053   }
3054 
3055   Size = 0;
3056   for (GuidWalker = ProtocolGuids ; GuidWalker != NULL && *GuidWalker != NULL ; GuidWalker++){
3057     TempSize = TotalSize - Size;
3058     Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)(*GuidWalker), NULL, &TempSize, HandleList+(Size/sizeof(EFI_HANDLE)));
3059 
3060     //
3061     // Allow for missing protocols... Only update the 'used' size upon success.
3062     //
3063     if (!EFI_ERROR(Status)) {
3064       Size += TempSize;
3065     }
3066   }
3067   ASSERT(HandleList[(TotalSize/sizeof(EFI_HANDLE))-1] == NULL);
3068 
3069   for (HandleWalker1 = HandleList ; HandleWalker1 != NULL && *HandleWalker1 != NULL ; HandleWalker1++) {
3070     for (HandleWalker2 = HandleWalker1 + 1; HandleWalker2 != NULL && *HandleWalker2 != NULL ; HandleWalker2++) {
3071       if (*HandleWalker1 == *HandleWalker2) {
3072         //
3073         // copy memory back 1 handle width.
3074         //
3075         CopyMem(HandleWalker2, HandleWalker2 + 1, TotalSize - ((HandleWalker2-HandleList+1)*sizeof(EFI_HANDLE)));
3076       }
3077     }
3078   }
3079 
3080   return (HandleList);
3081 }
3082