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