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