]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c
ShellPkg: Fixes for timezone handling and 'date -sfo'
[mirror_edk2.git] / ShellPkg / Library / UefiHandleParsingLib / UefiHandleParsingLib.c
1 /** @file
2 Provides interface to advanced shell functionality for parsing both handle and protocol database.
3
4 Copyright (c) 2013 - 2014, Hewlett-Packard Development Company, L.P.
5 Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16 #include "UefiHandleParsingLib.h"
17 #include "IndustryStandard/Acpi10.h"
18
19 EFI_HANDLE mHandleParsingHiiHandle;
20 HANDLE_INDEX_LIST mHandleList = {{{NULL,NULL},0,0},0};
21 GUID_INFO_BLOCK *GuidList;
22 UINTN GuidListCount;
23 /**
24 Function to translate the EFI_MEMORY_TYPE into a string.
25
26 @param[in] Memory The memory type.
27
28 @retval A string representation of the type allocated from BS Pool.
29 **/
30 CHAR16*
31 EFIAPI
32 ConvertMemoryType (
33 IN CONST EFI_MEMORY_TYPE Memory
34 )
35 {
36 CHAR16 *RetVal;
37 RetVal = NULL;
38
39 switch (Memory) {
40 case EfiReservedMemoryType: StrnCatGrow(&RetVal, NULL, L"EfiReservedMemoryType", 0); break;
41 case EfiLoaderCode: StrnCatGrow(&RetVal, NULL, L"EfiLoaderCode", 0); break;
42 case EfiLoaderData: StrnCatGrow(&RetVal, NULL, L"EfiLoaderData", 0); break;
43 case EfiBootServicesCode: StrnCatGrow(&RetVal, NULL, L"EfiBootServicesCode", 0); break;
44 case EfiBootServicesData: StrnCatGrow(&RetVal, NULL, L"EfiBootServicesData", 0); break;
45 case EfiRuntimeServicesCode: StrnCatGrow(&RetVal, NULL, L"EfiRuntimeServicesCode", 0); break;
46 case EfiRuntimeServicesData: StrnCatGrow(&RetVal, NULL, L"EfiRuntimeServicesData", 0); break;
47 case EfiConventionalMemory: StrnCatGrow(&RetVal, NULL, L"EfiConventionalMemory", 0); break;
48 case EfiUnusableMemory: StrnCatGrow(&RetVal, NULL, L"EfiUnusableMemory", 0); break;
49 case EfiACPIReclaimMemory: StrnCatGrow(&RetVal, NULL, L"EfiACPIReclaimMemory", 0); break;
50 case EfiACPIMemoryNVS: StrnCatGrow(&RetVal, NULL, L"EfiACPIMemoryNVS", 0); break;
51 case EfiMemoryMappedIO: StrnCatGrow(&RetVal, NULL, L"EfiMemoryMappedIO", 0); break;
52 case EfiMemoryMappedIOPortSpace: StrnCatGrow(&RetVal, NULL, L"EfiMemoryMappedIOPortSpace", 0); break;
53 case EfiPalCode: StrnCatGrow(&RetVal, NULL, L"EfiPalCode", 0); break;
54 case EfiMaxMemoryType: StrnCatGrow(&RetVal, NULL, L"EfiMaxMemoryType", 0); break;
55 default: ASSERT(FALSE);
56 }
57 return (RetVal);
58 }
59
60 /**
61 Function to translate the EFI_GRAPHICS_PIXEL_FORMAT into a string.
62
63 @param[in] Fmt The format type.
64
65 @retval A string representation of the type allocated from BS Pool.
66 **/
67 CHAR16*
68 EFIAPI
69 ConvertPixelFormat (
70 IN CONST EFI_GRAPHICS_PIXEL_FORMAT Fmt
71 )
72 {
73 CHAR16 *RetVal;
74 RetVal = NULL;
75
76 switch (Fmt) {
77 case PixelRedGreenBlueReserved8BitPerColor: StrnCatGrow(&RetVal, NULL, L"PixelRedGreenBlueReserved8BitPerColor", 0); break;
78 case PixelBlueGreenRedReserved8BitPerColor: StrnCatGrow(&RetVal, NULL, L"PixelBlueGreenRedReserved8BitPerColor", 0); break;
79 case PixelBitMask: StrnCatGrow(&RetVal, NULL, L"PixelBitMask", 0); break;
80 case PixelBltOnly: StrnCatGrow(&RetVal, NULL, L"PixelBltOnly", 0); break;
81 case PixelFormatMax: StrnCatGrow(&RetVal, NULL, L"PixelFormatMax", 0); break;
82 default: ASSERT(FALSE);
83 }
84 return (RetVal);
85 }
86
87 /**
88 Constructor for the library.
89
90 @param[in] ImageHandle Ignored.
91 @param[in] SystemTable Ignored.
92
93 @retval EFI_SUCCESS The operation was successful.
94 **/
95 EFI_STATUS
96 EFIAPI
97 HandleParsingLibConstructor (
98 IN EFI_HANDLE ImageHandle,
99 IN EFI_SYSTEM_TABLE *SystemTable
100 )
101 {
102 GuidListCount = 0;
103 GuidList = NULL;
104
105 mHandleParsingHiiHandle = HiiAddPackages (&gHandleParsingHiiGuid, gImageHandle, UefiHandleParsingLibStrings, NULL);
106 if (mHandleParsingHiiHandle == NULL) {
107 return (EFI_DEVICE_ERROR);
108 }
109
110 return (EFI_SUCCESS);
111 }
112
113 /**
114 Destructor for the library. free any resources.
115
116 @param[in] ImageHandle Ignored.
117 @param[in] SystemTable Ignored.
118
119 @retval EFI_SUCCESS The operation was successful.
120 **/
121 EFI_STATUS
122 EFIAPI
123 HandleParsingLibDestructor (
124 IN EFI_HANDLE ImageHandle,
125 IN EFI_SYSTEM_TABLE *SystemTable
126 )
127 {
128 UINTN LoopCount;
129
130 for (LoopCount = 0; GuidList != NULL && LoopCount < GuidListCount; LoopCount++) {
131 SHELL_FREE_NON_NULL(GuidList[LoopCount].GuidId);
132 }
133
134 SHELL_FREE_NON_NULL(GuidList);
135 if (mHandleParsingHiiHandle != NULL) {
136 HiiRemovePackages(mHandleParsingHiiHandle);
137 }
138 return (EFI_SUCCESS);
139 }
140
141 /**
142 Function to dump information about LoadedImage.
143
144 This will allocate the return buffer from boot services pool.
145
146 @param[in] TheHandle The handle that has LoadedImage installed.
147 @param[in] Verbose TRUE for additional information, FALSE otherwise.
148
149 @retval A poitner to a string containing the information.
150 **/
151 CHAR16*
152 EFIAPI
153 LoadedImageProtocolDumpInformation(
154 IN CONST EFI_HANDLE TheHandle,
155 IN CONST BOOLEAN Verbose
156 )
157 {
158 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
159 EFI_STATUS Status;
160 CHAR16 *RetVal;
161 CHAR16 *Temp;
162 CHAR16 *CodeType;
163 CHAR16 *DataType;
164
165 if (!Verbose) {
166 return (CatSPrint(NULL, L"LoadedImage"));
167 }
168
169 Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_LI_DUMP_MAIN), NULL);
170 RetVal = AllocateZeroPool (PcdGet16 (PcdShellPrintBufferSize));
171 if (Temp == NULL || RetVal == NULL) {
172 SHELL_FREE_NON_NULL(Temp);
173 SHELL_FREE_NON_NULL(RetVal);
174 return NULL;
175 }
176
177 Status = gBS->OpenProtocol (
178 TheHandle,
179 &gEfiLoadedImageProtocolGuid,
180 (VOID**)&LoadedImage,
181 gImageHandle,
182 NULL,
183 EFI_OPEN_PROTOCOL_GET_PROTOCOL
184 );
185
186 if (EFI_ERROR (Status)) {
187 SHELL_FREE_NON_NULL (Temp);
188 SHELL_FREE_NON_NULL (RetVal);
189 return NULL;
190 }
191
192 DataType = ConvertMemoryType(LoadedImage->ImageDataType);
193 CodeType = ConvertMemoryType(LoadedImage->ImageCodeType);
194
195 RetVal = CatSPrint(RetVal,
196 Temp,
197 LoadedImage->Revision,
198 LoadedImage->ParentHandle,
199 LoadedImage->SystemTable,
200 LoadedImage->DeviceHandle,
201 LoadedImage->FilePath,
202 LoadedImage->LoadOptionsSize,
203 LoadedImage->LoadOptions,
204 LoadedImage->ImageBase,
205 LoadedImage->ImageSize,
206 CodeType,
207 DataType,
208 LoadedImage->Unload);
209
210
211 SHELL_FREE_NON_NULL(Temp);
212 SHELL_FREE_NON_NULL(CodeType);
213 SHELL_FREE_NON_NULL(DataType);
214
215 return RetVal;
216 }
217
218 /**
219 Function to dump information about GOP.
220
221 This will allocate the return buffer from boot services pool.
222
223 @param[in] TheHandle The handle that has LoadedImage installed.
224 @param[in] Verbose TRUE for additional information, FALSE otherwise.
225
226 @retval A poitner to a string containing the information.
227 **/
228 CHAR16*
229 EFIAPI
230 GraphicsOutputProtocolDumpInformation(
231 IN CONST EFI_HANDLE TheHandle,
232 IN CONST BOOLEAN Verbose
233 )
234 {
235 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
236 EFI_STATUS Status;
237 CHAR16 *RetVal;
238 CHAR16 *Temp;
239 CHAR16 *Fmt;
240
241 if (!Verbose) {
242 return (CatSPrint(NULL, L"GraphicsOutput"));
243 }
244
245 Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_GOP_DUMP_MAIN), NULL);
246 RetVal = AllocateZeroPool (PcdGet16 (PcdShellPrintBufferSize));
247 if (Temp == NULL || RetVal == NULL) {
248 SHELL_FREE_NON_NULL(Temp);
249 SHELL_FREE_NON_NULL(RetVal);
250 return NULL;
251 }
252
253 Status = gBS->OpenProtocol (
254 TheHandle,
255 &gEfiGraphicsOutputProtocolGuid,
256 (VOID**)&GraphicsOutput,
257 gImageHandle,
258 NULL,
259 EFI_OPEN_PROTOCOL_GET_PROTOCOL
260 );
261
262 if (EFI_ERROR (Status)) {
263 SHELL_FREE_NON_NULL (Temp);
264 SHELL_FREE_NON_NULL (RetVal);
265 return NULL;
266 }
267
268 Fmt = ConvertPixelFormat(GraphicsOutput->Mode->Info->PixelFormat);
269
270 RetVal = CatSPrint(RetVal,
271 Temp,
272 GraphicsOutput->Mode->MaxMode,
273 GraphicsOutput->Mode->Mode,
274 GraphicsOutput->Mode->FrameBufferBase,
275 (UINT64)GraphicsOutput->Mode->FrameBufferSize,
276 (UINT64)GraphicsOutput->Mode->SizeOfInfo,
277 GraphicsOutput->Mode->Info->Version,
278 GraphicsOutput->Mode->Info->HorizontalResolution,
279 GraphicsOutput->Mode->Info->VerticalResolution,
280 Fmt,
281 GraphicsOutput->Mode->Info->PixelsPerScanLine,
282 GraphicsOutput->Mode->Info->PixelFormat!=PixelBitMask?0:GraphicsOutput->Mode->Info->PixelInformation.RedMask,
283 GraphicsOutput->Mode->Info->PixelFormat!=PixelBitMask?0:GraphicsOutput->Mode->Info->PixelInformation.GreenMask,
284 GraphicsOutput->Mode->Info->PixelFormat!=PixelBitMask?0:GraphicsOutput->Mode->Info->PixelInformation.BlueMask
285 );
286
287 SHELL_FREE_NON_NULL(Temp);
288 SHELL_FREE_NON_NULL(Fmt);
289
290 return RetVal;
291 }
292
293 /**
294 Function to dump information about PciRootBridgeIo.
295
296 This will allocate the return buffer from boot services pool.
297
298 @param[in] TheHandle The handle that has PciRootBridgeIo installed.
299 @param[in] Verbose TRUE for additional information, FALSE otherwise.
300
301 @retval A poitner to a string containing the information.
302 **/
303 CHAR16*
304 EFIAPI
305 PciRootBridgeIoDumpInformation(
306 IN CONST EFI_HANDLE TheHandle,
307 IN CONST BOOLEAN Verbose
308 )
309 {
310 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
311 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Configuration;
312 UINT64 Supports;
313 UINT64 Attributes;
314 CHAR16 *Temp;
315 CHAR16 *Temp2;
316 CHAR16 *RetVal;
317 EFI_STATUS Status;
318
319 RetVal = NULL;
320
321 if (!Verbose) {
322 return (CatSPrint(NULL, L"PciRootBridgeIo"));
323 }
324
325 Status = gBS->HandleProtocol(
326 TheHandle,
327 &gEfiPciRootBridgeIoProtocolGuid,
328 (VOID**)&PciRootBridgeIo);
329
330 if (EFI_ERROR(Status)) {
331 return NULL;
332 }
333
334 Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_PH), NULL);
335 ASSERT (Temp != NULL);
336 Temp2 = CatSPrint(L"\r\n", Temp, PciRootBridgeIo->ParentHandle);
337 FreePool(Temp);
338 RetVal = Temp2;
339 Temp2 = NULL;
340
341 Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_SEG), NULL);
342 ASSERT (Temp != NULL);
343 Temp2 = CatSPrint(RetVal, Temp, PciRootBridgeIo->SegmentNumber);
344 FreePool(Temp);
345 FreePool(RetVal);
346 RetVal = Temp2;
347 Temp2 = NULL;
348
349 Supports = 0;
350 Attributes = 0;
351 Status = PciRootBridgeIo->GetAttributes (PciRootBridgeIo, &Supports, &Attributes);
352 if (!EFI_ERROR(Status)) {
353 Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_ATT), NULL);
354 ASSERT (Temp != NULL);
355 Temp2 = CatSPrint(RetVal, Temp, Attributes);
356 FreePool(Temp);
357 FreePool(RetVal);
358 RetVal = Temp2;
359 Temp2 = NULL;
360
361 Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_SUPPORTS), NULL);
362 ASSERT (Temp != NULL);
363 Temp2 = CatSPrint(RetVal, Temp, Supports);
364 FreePool(Temp);
365 FreePool(RetVal);
366 RetVal = Temp2;
367 Temp2 = NULL;
368 }
369
370 Configuration = NULL;
371 Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Configuration);
372 if (!EFI_ERROR(Status) && Configuration != NULL) {
373 Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_TITLE), NULL);
374 ASSERT (Temp != NULL);
375 Temp2 = CatSPrint(RetVal, Temp, Supports);
376 FreePool(Temp);
377 FreePool(RetVal);
378 RetVal = Temp2;
379 Temp2 = NULL;
380 while (Configuration->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
381 Temp = NULL;
382 switch (Configuration->ResType) {
383 case ACPI_ADDRESS_SPACE_TYPE_MEM:
384 Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_MEM), NULL);
385 break;
386 case ACPI_ADDRESS_SPACE_TYPE_IO:
387 Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_IO), NULL);
388 break;
389 case ACPI_ADDRESS_SPACE_TYPE_BUS:
390 Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_BUS), NULL);
391 break;
392 }
393 if (Temp != NULL) {
394 Temp2 = CatSPrint(RetVal, L"%s", Temp);
395 FreePool(Temp);
396 FreePool(RetVal);
397 RetVal = Temp2;
398 Temp2 = NULL;
399 }
400
401 Temp2 = CatSPrint(RetVal,
402 L"%H%02x %016lx %016lx %02x%N\r\n",
403 Configuration->SpecificFlag,
404 Configuration->AddrRangeMin,
405 Configuration->AddrRangeMax,
406 Configuration->AddrSpaceGranularity
407 );
408 FreePool(RetVal);
409 RetVal = Temp2;
410 Temp2 = NULL;
411 Configuration++;
412 }
413 }
414 return (RetVal);
415 }
416
417 /**
418 Function to dump information about SimpleTextOut.
419
420 This will allocate the return buffer from boot services pool.
421
422 @param[in] TheHandle The handle that has SimpleTextOut installed.
423 @param[in] Verbose TRUE for additional information, FALSE otherwise.
424
425 @retval A poitner to a string containing the information.
426 **/
427 CHAR16*
428 EFIAPI
429 TxtOutProtocolDumpInformation(
430 IN CONST EFI_HANDLE TheHandle,
431 IN CONST BOOLEAN Verbose
432 )
433 {
434 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Dev;
435 INTN Index;
436 UINTN Col;
437 UINTN Row;
438 EFI_STATUS Status;
439 CHAR16 *RetVal;
440 UINTN Size;
441 CHAR16 *Temp;
442 UINTN NewSize;
443
444 if (!Verbose) {
445 return (NULL);
446 }
447
448 RetVal = NULL;
449 Size = 0;
450
451 Status = gBS->HandleProtocol(
452 TheHandle,
453 &gEfiSimpleTextOutProtocolGuid,
454 (VOID**)&Dev);
455
456 ASSERT_EFI_ERROR(Status);
457 ASSERT (Dev != NULL && Dev->Mode != NULL);
458
459 Size = (Dev->Mode->MaxMode + 1) * 80;
460 RetVal = AllocateZeroPool(Size);
461
462 Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_TXT_OUT_DUMP_HEADER), NULL);
463 if (Temp != NULL) {
464 UnicodeSPrint(RetVal, Size, Temp, Dev, Dev->Mode->Attribute);
465 FreePool(Temp);
466 }
467
468 //
469 // Dump TextOut Info
470 //
471 Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_TXT_OUT_DUMP_LINE), NULL);
472 for (Index = 0; Index < Dev->Mode->MaxMode; Index++) {
473 Status = Dev->QueryMode (Dev, Index, &Col, &Row);
474 NewSize = Size - StrSize(RetVal);
475 UnicodeSPrint(
476 RetVal + StrLen(RetVal),
477 NewSize,
478 Temp == NULL?L"":Temp,
479 Index == Dev->Mode->Mode ? L'*' : L' ',
480 Index,
481 !EFI_ERROR(Status)?(INTN)Col:-1,
482 !EFI_ERROR(Status)?(INTN)Row:-1
483 );
484 }
485 FreePool(Temp);
486 return (RetVal);
487 }
488
489 STATIC CONST UINTN VersionStringSize = 60;
490
491 /**
492 Function to dump information about EfiDriverSupportedEfiVersion protocol.
493
494 This will allocate the return buffer from boot services pool.
495
496 @param[in] TheHandle The handle that has the protocol installed.
497 @param[in] Verbose TRUE for additional information, FALSE otherwise.
498
499 @retval A poitner to a string containing the information.
500 **/
501 CHAR16*
502 EFIAPI
503 DriverEfiVersionProtocolDumpInformation(
504 IN CONST EFI_HANDLE TheHandle,
505 IN CONST BOOLEAN Verbose
506 )
507 {
508 EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL *DriverEfiVersion;
509 EFI_STATUS Status;
510 CHAR16 *RetVal;
511
512 Status = gBS->HandleProtocol(
513 TheHandle,
514 &gEfiDriverSupportedEfiVersionProtocolGuid,
515 (VOID**)&DriverEfiVersion);
516
517 ASSERT_EFI_ERROR(Status);
518
519 RetVal = AllocateZeroPool(VersionStringSize);
520 ASSERT(RetVal != NULL);
521 UnicodeSPrint(RetVal, VersionStringSize, L"0x%08x", DriverEfiVersion->FirmwareVersion);
522 return (RetVal);
523 }
524
525 /**
526 Function to dump information about DevicePath protocol.
527
528 This will allocate the return buffer from boot services pool.
529
530 @param[in] TheHandle The handle that has the protocol installed.
531 @param[in] Verbose TRUE for additional information, FALSE otherwise.
532
533 @retval A poitner to a string containing the information.
534 **/
535 CHAR16*
536 EFIAPI
537 DevicePathProtocolDumpInformation(
538 IN CONST EFI_HANDLE TheHandle,
539 IN CONST BOOLEAN Verbose
540 )
541 {
542 EFI_DEVICE_PATH_PROTOCOL *DevPath;
543 CHAR16 *Temp;
544 CHAR16 *Temp2;
545 EFI_STATUS Status;
546 Temp = NULL;
547
548 Status = gBS->OpenProtocol(TheHandle, &gEfiDevicePathProtocolGuid, (VOID**)&DevPath, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
549 if (!EFI_ERROR(Status)) {
550 //
551 // I cannot decide whether to allow shortcuts here (the second BOOLEAN on the next line)
552 //
553 Temp = ConvertDevicePathToText(DevPath, TRUE, TRUE);
554 gBS->CloseProtocol(TheHandle, &gEfiDevicePathProtocolGuid, gImageHandle, NULL);
555 }
556 if (!Verbose && Temp != NULL && StrLen(Temp) > 30) {
557 Temp2 = NULL;
558 Temp2 = StrnCatGrow(&Temp2, NULL, Temp+(StrLen(Temp) - 30), 30);
559 FreePool(Temp);
560 Temp = Temp2;
561 }
562 return (Temp);
563 }
564
565 //
566 // Put the information on the NT32 protocol GUIDs here so we are not dependant on the Nt32Pkg
567 //
568 #define LOCAL_EFI_WIN_NT_THUNK_PROTOCOL_GUID \
569 { \
570 0x58c518b1, 0x76f3, 0x11d4, { 0xbc, 0xea, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \
571 }
572
573 #define LOCAL_EFI_WIN_NT_BUS_DRIVER_IO_PROTOCOL_GUID \
574 { \
575 0x96eb4ad6, 0xa32a, 0x11d4, { 0xbc, 0xfd, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \
576 }
577
578 #define LOCAL_EFI_WIN_NT_SERIAL_PORT_GUID \
579 { \
580 0xc95a93d, 0xa006, 0x11d4, { 0xbc, 0xfa, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \
581 }
582 STATIC CONST EFI_GUID WinNtThunkProtocolGuid = LOCAL_EFI_WIN_NT_THUNK_PROTOCOL_GUID;
583 STATIC CONST EFI_GUID WinNtIoProtocolGuid = LOCAL_EFI_WIN_NT_BUS_DRIVER_IO_PROTOCOL_GUID;
584 STATIC CONST EFI_GUID WinNtSerialPortGuid = LOCAL_EFI_WIN_NT_SERIAL_PORT_GUID;
585
586 STATIC CONST GUID_INFO_BLOCK mGuidStringListNT[] = {
587 {STRING_TOKEN(STR_WINNT_THUNK), (EFI_GUID*)&WinNtThunkProtocolGuid, NULL},
588 {STRING_TOKEN(STR_WINNT_DRIVER_IO), (EFI_GUID*)&WinNtIoProtocolGuid, NULL},
589 {STRING_TOKEN(STR_WINNT_SERIAL_PORT), (EFI_GUID*)&WinNtSerialPortGuid, NULL},
590 {STRING_TOKEN(STR_UNKNOWN_DEVICE), NULL, NULL},
591 };
592
593 STATIC CONST GUID_INFO_BLOCK mGuidStringList[] = {
594 {STRING_TOKEN(STR_LOADED_IMAGE), &gEfiLoadedImageProtocolGuid, LoadedImageProtocolDumpInformation},
595 {STRING_TOKEN(STR_DEVICE_PATH), &gEfiDevicePathProtocolGuid, DevicePathProtocolDumpInformation},
596 {STRING_TOKEN(STR_IMAGE_PATH), &gEfiLoadedImageDevicePathProtocolGuid, DevicePathProtocolDumpInformation},
597 {STRING_TOKEN(STR_DEVICE_PATH_UTIL), &gEfiDevicePathUtilitiesProtocolGuid, NULL},
598 {STRING_TOKEN(STR_DEVICE_PATH_TXT), &gEfiDevicePathToTextProtocolGuid, NULL},
599 {STRING_TOKEN(STR_DEVICE_PATH_FTXT), &gEfiDevicePathFromTextProtocolGuid, NULL},
600 {STRING_TOKEN(STR_DEVICE_PATH_PC), &gEfiPcAnsiGuid, NULL},
601 {STRING_TOKEN(STR_DEVICE_PATH_VT100), &gEfiVT100Guid, NULL},
602 {STRING_TOKEN(STR_DEVICE_PATH_VT100P), &gEfiVT100PlusGuid, NULL},
603 {STRING_TOKEN(STR_DEVICE_PATH_VTUTF8), &gEfiVTUTF8Guid, NULL},
604 {STRING_TOKEN(STR_DRIVER_BINDING), &gEfiDriverBindingProtocolGuid, NULL},
605 {STRING_TOKEN(STR_PLATFORM_OVERRIDE), &gEfiPlatformDriverOverrideProtocolGuid, NULL},
606 {STRING_TOKEN(STR_BUS_OVERRIDE), &gEfiBusSpecificDriverOverrideProtocolGuid, NULL},
607 {STRING_TOKEN(STR_DRIVER_DIAG), &gEfiDriverDiagnosticsProtocolGuid, NULL},
608 {STRING_TOKEN(STR_DRIVER_DIAG2), &gEfiDriverDiagnostics2ProtocolGuid, NULL},
609 {STRING_TOKEN(STR_DRIVER_CN), &gEfiComponentNameProtocolGuid, NULL},
610 {STRING_TOKEN(STR_DRIVER_CN2), &gEfiComponentName2ProtocolGuid, NULL},
611 {STRING_TOKEN(STR_PLAT_DRV_CFG), &gEfiPlatformToDriverConfigurationProtocolGuid, NULL},
612 {STRING_TOKEN(STR_DRIVER_VERSION), &gEfiDriverSupportedEfiVersionProtocolGuid, DriverEfiVersionProtocolDumpInformation},
613 {STRING_TOKEN(STR_TXT_IN), &gEfiSimpleTextInProtocolGuid, NULL},
614 {STRING_TOKEN(STR_TXT_IN_EX), &gEfiSimpleTextInputExProtocolGuid, NULL},
615 {STRING_TOKEN(STR_TXT_OUT), &gEfiSimpleTextOutProtocolGuid, TxtOutProtocolDumpInformation},
616 {STRING_TOKEN(STR_SIM_POINTER), &gEfiSimplePointerProtocolGuid, NULL},
617 {STRING_TOKEN(STR_ABS_POINTER), &gEfiAbsolutePointerProtocolGuid, NULL},
618 {STRING_TOKEN(STR_SERIAL_IO), &gEfiSerialIoProtocolGuid, NULL},
619 {STRING_TOKEN(STR_GRAPHICS_OUTPUT), &gEfiGraphicsOutputProtocolGuid, GraphicsOutputProtocolDumpInformation},
620 {STRING_TOKEN(STR_EDID_DISCOVERED), &gEfiEdidDiscoveredProtocolGuid, NULL},
621 {STRING_TOKEN(STR_EDID_ACTIVE), &gEfiEdidActiveProtocolGuid, NULL},
622 {STRING_TOKEN(STR_EDID_OVERRIDE), &gEfiEdidOverrideProtocolGuid, NULL},
623 {STRING_TOKEN(STR_CON_IN), &gEfiConsoleInDeviceGuid, NULL},
624 {STRING_TOKEN(STR_CON_OUT), &gEfiConsoleOutDeviceGuid, NULL},
625 {STRING_TOKEN(STR_STD_ERR), &gEfiStandardErrorDeviceGuid, NULL},
626 {STRING_TOKEN(STR_LOAD_FILE), &gEfiLoadFileProtocolGuid, NULL},
627 {STRING_TOKEN(STR_LOAD_FILE2), &gEfiLoadFile2ProtocolGuid, NULL},
628 {STRING_TOKEN(STR_SIMPLE_FILE_SYS), &gEfiSimpleFileSystemProtocolGuid, NULL},
629 {STRING_TOKEN(STR_TAPE_IO), &gEfiTapeIoProtocolGuid, NULL},
630 {STRING_TOKEN(STR_DISK_IO), &gEfiDiskIoProtocolGuid, NULL},
631 {STRING_TOKEN(STR_BLK_IO), &gEfiBlockIoProtocolGuid, NULL},
632 {STRING_TOKEN(STR_UC), &gEfiUnicodeCollationProtocolGuid, NULL},
633 {STRING_TOKEN(STR_UC2), &gEfiUnicodeCollation2ProtocolGuid, NULL},
634 {STRING_TOKEN(STR_PCIRB_IO), &gEfiPciRootBridgeIoProtocolGuid, PciRootBridgeIoDumpInformation},
635 {STRING_TOKEN(STR_PCI_IO), &gEfiPciIoProtocolGuid, NULL},
636 {STRING_TOKEN(STR_SCSI_PT), &gEfiScsiPassThruProtocolGuid, NULL},
637 {STRING_TOKEN(STR_SCSI_IO), &gEfiScsiIoProtocolGuid, NULL},
638 {STRING_TOKEN(STR_SCSI_PT_EXT), &gEfiExtScsiPassThruProtocolGuid, NULL},
639 {STRING_TOKEN(STR_ISCSI), &gEfiIScsiInitiatorNameProtocolGuid, NULL},
640 {STRING_TOKEN(STR_USB_IO), &gEfiUsbIoProtocolGuid, NULL},
641 {STRING_TOKEN(STR_USB_HC), &gEfiUsbHcProtocolGuid, NULL},
642 {STRING_TOKEN(STR_USB_HC2), &gEfiUsb2HcProtocolGuid, NULL},
643 {STRING_TOKEN(STR_DEBUG_SUPPORT), &gEfiDebugSupportProtocolGuid, NULL},
644 {STRING_TOKEN(STR_DEBUG_PORT), &gEfiDebugPortProtocolGuid, NULL},
645 {STRING_TOKEN(STR_DECOMPRESS), &gEfiDecompressProtocolGuid, NULL},
646 {STRING_TOKEN(STR_ACPI_TABLE), &gEfiAcpiTableProtocolGuid, NULL},
647 {STRING_TOKEN(STR_EBC_INTERPRETER), &gEfiEbcProtocolGuid, NULL},
648 {STRING_TOKEN(STR_SNP), &gEfiSimpleNetworkProtocolGuid, NULL},
649 {STRING_TOKEN(STR_NII), &gEfiNetworkInterfaceIdentifierProtocolGuid, NULL},
650 {STRING_TOKEN(STR_NII_31), &gEfiNetworkInterfaceIdentifierProtocolGuid_31, NULL},
651 {STRING_TOKEN(STR_PXE_BC), &gEfiPxeBaseCodeProtocolGuid, NULL},
652 {STRING_TOKEN(STR_PXE_CB), &gEfiPxeBaseCodeCallbackProtocolGuid, NULL},
653 {STRING_TOKEN(STR_BIS), &gEfiBisProtocolGuid, NULL},
654 {STRING_TOKEN(STR_MNP_SB), &gEfiManagedNetworkServiceBindingProtocolGuid, NULL},
655 {STRING_TOKEN(STR_MNP), &gEfiManagedNetworkProtocolGuid, NULL},
656 {STRING_TOKEN(STR_ARP_SB), &gEfiArpServiceBindingProtocolGuid, NULL},
657 {STRING_TOKEN(STR_ARP), &gEfiArpProtocolGuid, NULL},
658 {STRING_TOKEN(STR_DHCPV4_SB), &gEfiDhcp4ServiceBindingProtocolGuid, NULL},
659 {STRING_TOKEN(STR_DHCPV4), &gEfiDhcp4ProtocolGuid, NULL},
660 {STRING_TOKEN(STR_TCPV4_SB), &gEfiTcp4ServiceBindingProtocolGuid, NULL},
661 {STRING_TOKEN(STR_TCPV4), &gEfiTcp4ProtocolGuid, NULL},
662 {STRING_TOKEN(STR_IPV4_SB), &gEfiIp4ServiceBindingProtocolGuid, NULL},
663 {STRING_TOKEN(STR_IPV4), &gEfiIp4ProtocolGuid, NULL},
664 {STRING_TOKEN(STR_IPV4_CFG), &gEfiIp4ConfigProtocolGuid, NULL},
665 {STRING_TOKEN(STR_UDPV4_SB), &gEfiUdp4ServiceBindingProtocolGuid, NULL},
666 {STRING_TOKEN(STR_UDPV4), &gEfiUdp4ProtocolGuid, NULL},
667 {STRING_TOKEN(STR_MTFTPV4_SB), &gEfiMtftp4ServiceBindingProtocolGuid, NULL},
668 {STRING_TOKEN(STR_MTFTPV4), &gEfiMtftp4ProtocolGuid, NULL},
669 {STRING_TOKEN(STR_AUTH_INFO), &gEfiAuthenticationInfoProtocolGuid, NULL},
670 {STRING_TOKEN(STR_HASH_SB), &gEfiHashServiceBindingProtocolGuid, NULL},
671 {STRING_TOKEN(STR_HASH), &gEfiHashProtocolGuid, NULL},
672 {STRING_TOKEN(STR_HII_FONT), &gEfiHiiFontProtocolGuid, NULL},
673 {STRING_TOKEN(STR_HII_STRING), &gEfiHiiStringProtocolGuid, NULL},
674 {STRING_TOKEN(STR_HII_IMAGE), &gEfiHiiImageProtocolGuid, NULL},
675 {STRING_TOKEN(STR_HII_DATABASE), &gEfiHiiDatabaseProtocolGuid, NULL},
676 {STRING_TOKEN(STR_HII_CONFIG_ROUT), &gEfiHiiConfigRoutingProtocolGuid, NULL},
677 {STRING_TOKEN(STR_HII_CONFIG_ACC), &gEfiHiiConfigAccessProtocolGuid, NULL},
678 {STRING_TOKEN(STR_HII_FORM_BROWSER2), &gEfiFormBrowser2ProtocolGuid, NULL},
679 {STRING_TOKEN(STR_DRIVER_FAM_OVERRIDE), &gEfiDriverFamilyOverrideProtocolGuid, NULL},
680 {STRING_TOKEN(STR_PCD), &gPcdProtocolGuid, NULL},
681 {STRING_TOKEN(STR_TCG), &gEfiTcgProtocolGuid, NULL},
682 {STRING_TOKEN(STR_HII_PACKAGE_LIST), &gEfiHiiPackageListProtocolGuid, NULL},
683
684 //
685 // the ones under this are deprecated by the current UEFI Spec, but may be found anyways...
686 //
687 {STRING_TOKEN(STR_SHELL_INTERFACE), &gEfiShellInterfaceGuid, NULL},
688 {STRING_TOKEN(STR_SHELL_ENV2), &gEfiShellEnvironment2Guid, NULL},
689 {STRING_TOKEN(STR_SHELL_ENV), &gEfiShellEnvironment2Guid, NULL},
690 {STRING_TOKEN(STR_DEVICE_IO), &gEfiDeviceIoProtocolGuid, NULL},
691 {STRING_TOKEN(STR_UGA_DRAW), &gEfiUgaDrawProtocolGuid, NULL},
692 {STRING_TOKEN(STR_UGA_IO), &gEfiUgaIoProtocolGuid, NULL},
693 {STRING_TOKEN(STR_ESP), &gEfiPartTypeSystemPartGuid, NULL},
694 {STRING_TOKEN(STR_GPT_NBR), &gEfiPartTypeLegacyMbrGuid, NULL},
695 {STRING_TOKEN(STR_DRIVER_CONFIG), &gEfiDriverConfigurationProtocolGuid, NULL},
696 {STRING_TOKEN(STR_DRIVER_CONFIG2), &gEfiDriverConfiguration2ProtocolGuid, NULL},
697
698 //
699 // the ones under this are GUID identified structs, not protocols
700 //
701 {STRING_TOKEN(STR_FILE_INFO), &gEfiFileInfoGuid, NULL},
702 {STRING_TOKEN(STR_FILE_SYS_INFO), &gEfiFileSystemInfoGuid, NULL},
703
704 //
705 // the ones under this are misc GUIDS.
706 //
707 {STRING_TOKEN(STR_EFI_GLOBAL_VARIABLE), &gEfiGlobalVariableGuid, NULL},
708
709 //
710 // UEFI 2.2
711 //
712 {STRING_TOKEN(STR_IP6_SB), &gEfiIp6ServiceBindingProtocolGuid, NULL},
713 {STRING_TOKEN(STR_IP6), &gEfiIp6ProtocolGuid, NULL},
714 {STRING_TOKEN(STR_IP6_CONFIG), &gEfiIp6ConfigProtocolGuid, NULL},
715 {STRING_TOKEN(STR_MTFTP6_SB), &gEfiMtftp6ServiceBindingProtocolGuid, NULL},
716 {STRING_TOKEN(STR_MTFTP6), &gEfiMtftp6ProtocolGuid, NULL},
717 {STRING_TOKEN(STR_DHCP6_SB), &gEfiDhcp6ServiceBindingProtocolGuid, NULL},
718 {STRING_TOKEN(STR_DHCP6), &gEfiDhcp6ProtocolGuid, NULL},
719 {STRING_TOKEN(STR_UDP6_SB), &gEfiUdp6ServiceBindingProtocolGuid, NULL},
720 {STRING_TOKEN(STR_UDP6), &gEfiUdp6ProtocolGuid, NULL},
721 {STRING_TOKEN(STR_TCP6_SB), &gEfiTcp6ServiceBindingProtocolGuid, NULL},
722 {STRING_TOKEN(STR_TCP6), &gEfiTcp6ProtocolGuid, NULL},
723 {STRING_TOKEN(STR_VLAN_CONFIG), &gEfiVlanConfigProtocolGuid, NULL},
724 {STRING_TOKEN(STR_EAP), &gEfiEapProtocolGuid, NULL},
725 {STRING_TOKEN(STR_EAP_MGMT), &gEfiEapManagementProtocolGuid, NULL},
726 {STRING_TOKEN(STR_FTP4_SB), &gEfiFtp4ServiceBindingProtocolGuid, NULL},
727 {STRING_TOKEN(STR_FTP4), &gEfiFtp4ProtocolGuid, NULL},
728 {STRING_TOKEN(STR_IP_SEC_CONFIG), &gEfiIpSecConfigProtocolGuid, NULL},
729 {STRING_TOKEN(STR_DH), &gEfiDriverHealthProtocolGuid, NULL},
730 {STRING_TOKEN(STR_DEF_IMG_LOAD), &gEfiDeferredImageLoadProtocolGuid, NULL},
731 {STRING_TOKEN(STR_USER_CRED), &gEfiUserCredentialProtocolGuid, NULL},
732 {STRING_TOKEN(STR_USER_MNGR), &gEfiUserManagerProtocolGuid, NULL},
733 {STRING_TOKEN(STR_ATA_PASS_THRU), &gEfiAtaPassThruProtocolGuid, NULL},
734
735 //
736 // UEFI 2.3
737 //
738 {STRING_TOKEN(STR_FW_MGMT), &gEfiFirmwareManagementProtocolGuid, NULL},
739 {STRING_TOKEN(STR_IP_SEC), &gEfiIpSecProtocolGuid, NULL},
740 {STRING_TOKEN(STR_IP_SEC2), &gEfiIpSec2ProtocolGuid, NULL},
741
742 //
743 // UEFI 2.3.1
744 //
745 {STRING_TOKEN(STR_KMS), &gEfiKmsProtocolGuid, NULL},
746 {STRING_TOKEN(STR_BLK_IO2), &gEfiBlockIo2ProtocolGuid, NULL},
747 {STRING_TOKEN(STR_SSC), &gEfiStorageSecurityCommandProtocolGuid, NULL},
748 {STRING_TOKEN(STR_UCRED2), &gEfiUserCredential2ProtocolGuid, NULL},
749
750 //
751 // UEFI 2.4
752 //
753 {STRING_TOKEN(STR_DISK_IO2), &gEfiDiskIo2ProtocolGuid, NULL},
754 {STRING_TOKEN(STR_ADAPTER_INFO), &gEfiAdapterInformationProtocolGuid, NULL},
755
756 //
757 // PI Spec ones
758 //
759 {STRING_TOKEN(STR_IDE_CONT_INIT), &gEfiIdeControllerInitProtocolGuid, NULL},
760
761 //
762 // UEFI Shell Spec 2.0
763 //
764 {STRING_TOKEN(STR_SHELL_PARAMETERS), &gEfiShellParametersProtocolGuid, NULL},
765 {STRING_TOKEN(STR_SHELL), &gEfiShellProtocolGuid, NULL},
766
767 //
768 // UEFI Shell Spec 2.1
769 //
770 {STRING_TOKEN(STR_SHELL_DYNAMIC), &gEfiShellDynamicCommandProtocolGuid, NULL},
771
772 //
773 // terminator
774 //
775 {STRING_TOKEN(STR_UNKNOWN_DEVICE), NULL, NULL},
776 };
777
778 /**
779 Function to get the node for a protocol or struct from it's GUID.
780
781 if Guid is NULL, then ASSERT.
782
783 @param[in] Guid The GUID to look for the name of.
784
785 @return The node.
786 **/
787 CONST GUID_INFO_BLOCK *
788 EFIAPI
789 InternalShellGetNodeFromGuid(
790 IN CONST EFI_GUID* Guid
791 )
792 {
793 CONST GUID_INFO_BLOCK *ListWalker;
794 UINTN LoopCount;
795
796 ASSERT(Guid != NULL);
797
798 for (LoopCount = 0, ListWalker = GuidList; GuidList != NULL && LoopCount < GuidListCount; LoopCount++, ListWalker++) {
799 if (CompareGuid(ListWalker->GuidId, Guid)) {
800 return (ListWalker);
801 }
802 }
803
804 if (PcdGetBool(PcdShellIncludeNtGuids)) {
805 for (ListWalker = mGuidStringListNT ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {
806 if (CompareGuid(ListWalker->GuidId, Guid)) {
807 return (ListWalker);
808 }
809 }
810 }
811 for (ListWalker = mGuidStringList ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {
812 if (CompareGuid(ListWalker->GuidId, Guid)) {
813 return (ListWalker);
814 }
815 }
816 return (NULL);
817 }
818
819 /**
820 Function to add a new GUID/Name mapping.
821
822 @param[in] Guid The Guid
823 @param[in] NameID The STRING id of the HII string to use
824 @param[in] DumpFunc The pointer to the dump function
825
826
827 @retval EFI_SUCCESS The operation was sucessful
828 @retval EFI_OUT_OF_RESOURCES A memory allocation failed
829 @retval EFI_INVALID_PARAMETER Guid NameId was invalid
830 **/
831 STATIC
832 EFI_STATUS
833 EFIAPI
834 InsertNewGuidNameMapping(
835 IN CONST EFI_GUID *Guid,
836 IN CONST EFI_STRING_ID NameID,
837 IN CONST DUMP_PROTOCOL_INFO DumpFunc OPTIONAL
838 )
839 {
840 ASSERT(Guid != NULL);
841 ASSERT(NameID != 0);
842
843 GuidList = ReallocatePool(GuidListCount * sizeof(GUID_INFO_BLOCK), GuidListCount+1 * sizeof(GUID_INFO_BLOCK), GuidList);
844 if (GuidList == NULL) {
845 GuidListCount = 0;
846 return (EFI_OUT_OF_RESOURCES);
847 }
848 GuidListCount++;
849
850 GuidList[GuidListCount - 1].GuidId = AllocateCopyPool(sizeof(EFI_GUID), Guid);
851 GuidList[GuidListCount - 1].StringId = NameID;
852 GuidList[GuidListCount - 1].DumpInfo = DumpFunc;
853
854 if (GuidList[GuidListCount - 1].GuidId == NULL) {
855 return (EFI_OUT_OF_RESOURCES);
856 }
857
858 return (EFI_SUCCESS);
859 }
860
861 /**
862 Function to add a new GUID/Name mapping.
863
864 This cannot overwrite an existing mapping.
865
866 @param[in] Guid The Guid
867 @param[in] TheName The Guid's name
868 @param[in] Lang RFC4646 language code list or NULL
869
870 @retval EFI_SUCCESS The operation was sucessful
871 @retval EFI_ACCESS_DENIED There was a duplicate
872 @retval EFI_OUT_OF_RESOURCES A memory allocation failed
873 @retval EFI_INVALID_PARAMETER Guid or TheName was NULL
874 **/
875 EFI_STATUS
876 EFIAPI
877 AddNewGuidNameMapping(
878 IN CONST EFI_GUID *Guid,
879 IN CONST CHAR16 *TheName,
880 IN CONST CHAR8 *Lang OPTIONAL
881 )
882 {
883 CONST GUID_INFO_BLOCK *Temp;
884 EFI_STRING_ID NameID;
885
886 if (Guid == NULL || TheName == NULL){
887 return (EFI_INVALID_PARAMETER);
888 }
889
890 if ((Temp = InternalShellGetNodeFromGuid(Guid)) != NULL) {
891 return (EFI_ACCESS_DENIED);
892 }
893
894 NameID = HiiSetString(mHandleParsingHiiHandle, 0, (CHAR16*)TheName, Lang);
895 if (NameID == 0) {
896 return (EFI_OUT_OF_RESOURCES);
897 }
898
899 return (InsertNewGuidNameMapping(Guid, NameID, NULL));
900 }
901
902 /**
903 Function to get the name of a protocol or struct from it's GUID.
904
905 if Guid is NULL, then ASSERT.
906
907 @param[in] Guid The GUID to look for the name of.
908 @param[in] Lang The language to use.
909
910 @return pointer to string of the name. The caller
911 is responsible to free this memory.
912 **/
913 CHAR16*
914 EFIAPI
915 GetStringNameFromGuid(
916 IN CONST EFI_GUID *Guid,
917 IN CONST CHAR8 *Lang OPTIONAL
918 )
919 {
920 CONST GUID_INFO_BLOCK *Id;
921
922 Id = InternalShellGetNodeFromGuid(Guid);
923 return (HiiGetString(mHandleParsingHiiHandle, Id==NULL?STRING_TOKEN(STR_UNKNOWN_DEVICE):Id->StringId, Lang));
924 }
925
926 /**
927 Function to dump protocol information from a handle.
928
929 This function will return a allocated string buffer containing the
930 information. The caller is responsible for freeing the memory.
931
932 If Guid is NULL, ASSERT().
933 If TheHandle is NULL, ASSERT().
934
935 @param[in] TheHandle The handle to dump information from.
936 @param[in] Guid The GUID of the protocol to dump.
937 @param[in] Verbose TRUE for extra info. FALSE otherwise.
938
939 @return The pointer to string.
940 @retval NULL An error was encountered.
941 **/
942 CHAR16*
943 EFIAPI
944 GetProtocolInformationDump(
945 IN CONST EFI_HANDLE TheHandle,
946 IN CONST EFI_GUID *Guid,
947 IN CONST BOOLEAN Verbose
948 )
949 {
950 CONST GUID_INFO_BLOCK *Id;
951
952 ASSERT(TheHandle != NULL);
953 ASSERT(Guid != NULL);
954
955 if (TheHandle == NULL || Guid == NULL) {
956 return (NULL);
957 }
958
959 Id = InternalShellGetNodeFromGuid(Guid);
960 if (Id != NULL && Id->DumpInfo != NULL) {
961 return (Id->DumpInfo(TheHandle, Verbose));
962 }
963 return (NULL);
964 }
965
966 /**
967 Function to get the Guid for a protocol or struct based on it's string name.
968
969 do not modify the returned Guid.
970
971 @param[in] Name The pointer to the string name.
972 @param[in] Lang The pointer to the language code.
973 @param[out] Guid The pointer to the Guid.
974
975 @retval EFI_SUCCESS The operation was sucessful.
976 **/
977 EFI_STATUS
978 EFIAPI
979 GetGuidFromStringName(
980 IN CONST CHAR16 *Name,
981 IN CONST CHAR8 *Lang OPTIONAL,
982 OUT EFI_GUID **Guid
983 )
984 {
985 CONST GUID_INFO_BLOCK *ListWalker;
986 CHAR16 *String;
987 UINTN LoopCount;
988
989 ASSERT(Guid != NULL);
990 if (Guid == NULL) {
991 return (EFI_INVALID_PARAMETER);
992 }
993 *Guid = NULL;
994
995 if (PcdGetBool(PcdShellIncludeNtGuids)) {
996 for (ListWalker = mGuidStringListNT ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {
997 String = HiiGetString(mHandleParsingHiiHandle, ListWalker->StringId, Lang);
998 if (Name != NULL && String != NULL && StringNoCaseCompare (&Name, &String) == 0) {
999 *Guid = ListWalker->GuidId;
1000 }
1001 SHELL_FREE_NON_NULL(String);
1002 if (*Guid != NULL) {
1003 return (EFI_SUCCESS);
1004 }
1005 }
1006 }
1007 for (ListWalker = mGuidStringList ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {
1008 String = HiiGetString(mHandleParsingHiiHandle, ListWalker->StringId, Lang);
1009 if (Name != NULL && String != NULL && StringNoCaseCompare (&Name, &String) == 0) {
1010 *Guid = ListWalker->GuidId;
1011 }
1012 SHELL_FREE_NON_NULL(String);
1013 if (*Guid != NULL) {
1014 return (EFI_SUCCESS);
1015 }
1016 }
1017
1018 for (LoopCount = 0, ListWalker = GuidList; GuidList != NULL && LoopCount < GuidListCount; LoopCount++, ListWalker++) {
1019 String = HiiGetString(mHandleParsingHiiHandle, ListWalker->StringId, Lang);
1020 if (Name != NULL && String != NULL && StringNoCaseCompare (&Name, &String) == 0) {
1021 *Guid = ListWalker->GuidId;
1022 }
1023 SHELL_FREE_NON_NULL(String);
1024 if (*Guid != NULL) {
1025 return (EFI_SUCCESS);
1026 }
1027 }
1028
1029 return (EFI_NOT_FOUND);
1030 }
1031
1032 /**
1033 Get best support language for this driver.
1034
1035 First base on the user input language to search, second base on the current
1036 platform used language to search, third get the first language from the
1037 support language list. The caller need to free the buffer of the best language.
1038
1039 @param[in] SupportedLanguages The support languages for this driver.
1040 @param[in] InputLanguage The user input language.
1041 @param[in] Iso639Language Whether get language for ISO639.
1042
1043 @return The best support language for this driver.
1044 **/
1045 CHAR8 *
1046 EFIAPI
1047 GetBestLanguageForDriver (
1048 IN CONST CHAR8 *SupportedLanguages,
1049 IN CONST CHAR8 *InputLanguage,
1050 IN BOOLEAN Iso639Language
1051 )
1052 {
1053 CHAR8 *LanguageVariable;
1054 CHAR8 *BestLanguage;
1055
1056 LanguageVariable = GetVariable (Iso639Language ? L"Lang" : L"PlatformLang", &gEfiGlobalVariableGuid);
1057
1058 BestLanguage = GetBestLanguage(
1059 SupportedLanguages,
1060 Iso639Language,
1061 (InputLanguage != NULL) ? InputLanguage : "",
1062 (LanguageVariable != NULL) ? LanguageVariable : "",
1063 SupportedLanguages,
1064 NULL
1065 );
1066
1067 if (LanguageVariable != NULL) {
1068 FreePool (LanguageVariable);
1069 }
1070
1071 return BestLanguage;
1072 }
1073
1074 /**
1075 Function to retrieve the driver name (if possible) from the ComponentName or
1076 ComponentName2 protocol
1077
1078 @param[in] TheHandle The driver handle to get the name of.
1079 @param[in] Language The language to use.
1080
1081 @retval NULL The name could not be found.
1082 @return A pointer to the string name. Do not de-allocate the memory.
1083 **/
1084 CONST CHAR16*
1085 EFIAPI
1086 GetStringNameFromHandle(
1087 IN CONST EFI_HANDLE TheHandle,
1088 IN CONST CHAR8 *Language
1089 )
1090 {
1091 EFI_COMPONENT_NAME2_PROTOCOL *CompNameStruct;
1092 EFI_STATUS Status;
1093 CHAR16 *RetVal;
1094 CHAR8 *BestLang;
1095
1096 BestLang = NULL;
1097
1098 Status = gBS->OpenProtocol(
1099 TheHandle,
1100 &gEfiComponentName2ProtocolGuid,
1101 (VOID**)&CompNameStruct,
1102 gImageHandle,
1103 NULL,
1104 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
1105 if (!EFI_ERROR(Status)) {
1106 BestLang = GetBestLanguageForDriver (CompNameStruct->SupportedLanguages, Language, FALSE);
1107 Status = CompNameStruct->GetDriverName(CompNameStruct, BestLang, &RetVal);
1108 if (BestLang != NULL) {
1109 FreePool (BestLang);
1110 BestLang = NULL;
1111 }
1112 if (!EFI_ERROR(Status)) {
1113 return (RetVal);
1114 }
1115 }
1116 Status = gBS->OpenProtocol(
1117 TheHandle,
1118 &gEfiComponentNameProtocolGuid,
1119 (VOID**)&CompNameStruct,
1120 gImageHandle,
1121 NULL,
1122 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
1123 if (!EFI_ERROR(Status)) {
1124 BestLang = GetBestLanguageForDriver (CompNameStruct->SupportedLanguages, Language, FALSE);
1125 Status = CompNameStruct->GetDriverName(CompNameStruct, BestLang, &RetVal);
1126 if (BestLang != NULL) {
1127 FreePool (BestLang);
1128 }
1129 if (!EFI_ERROR(Status)) {
1130 return (RetVal);
1131 }
1132 }
1133 return (NULL);
1134 }
1135
1136 /**
1137 Function to initialize the file global mHandleList object for use in
1138 vonverting handles to index and index to handle.
1139
1140 @retval EFI_SUCCESS The operation was successful.
1141 **/
1142 EFI_STATUS
1143 EFIAPI
1144 InternalShellInitHandleList(
1145 VOID
1146 )
1147 {
1148 EFI_STATUS Status;
1149 EFI_HANDLE *HandleBuffer;
1150 UINTN HandleCount;
1151 HANDLE_LIST *ListWalker;
1152
1153 if (mHandleList.NextIndex != 0) {
1154 return EFI_SUCCESS;
1155 }
1156 InitializeListHead(&mHandleList.List.Link);
1157 mHandleList.NextIndex = 1;
1158 Status = gBS->LocateHandleBuffer (
1159 AllHandles,
1160 NULL,
1161 NULL,
1162 &HandleCount,
1163 &HandleBuffer
1164 );
1165 ASSERT_EFI_ERROR(Status);
1166 if (EFI_ERROR(Status)) {
1167 return (Status);
1168 }
1169 for (mHandleList.NextIndex = 1 ; mHandleList.NextIndex <= HandleCount ; mHandleList.NextIndex++){
1170 ListWalker = AllocateZeroPool(sizeof(HANDLE_LIST));
1171 ASSERT(ListWalker != NULL);
1172 ListWalker->TheHandle = HandleBuffer[mHandleList.NextIndex-1];
1173 ListWalker->TheIndex = mHandleList.NextIndex;
1174 InsertTailList(&mHandleList.List.Link,&ListWalker->Link);
1175 }
1176 FreePool(HandleBuffer);
1177 return (EFI_SUCCESS);
1178 }
1179
1180 /**
1181 Function to retrieve the human-friendly index of a given handle. If the handle
1182 does not have a index one will be automatically assigned. The index value is valid
1183 until the termination of the shell application.
1184
1185 @param[in] TheHandle The handle to retrieve an index for.
1186
1187 @retval 0 A memory allocation failed.
1188 @return The index of the handle.
1189
1190 **/
1191 UINTN
1192 EFIAPI
1193 ConvertHandleToHandleIndex(
1194 IN CONST EFI_HANDLE TheHandle
1195 )
1196 {
1197 EFI_STATUS Status;
1198 EFI_GUID **ProtocolBuffer;
1199 UINTN ProtocolCount;
1200 HANDLE_LIST *ListWalker;
1201
1202 if (TheHandle == NULL) {
1203 return 0;
1204 }
1205
1206 InternalShellInitHandleList();
1207
1208 for (ListWalker = (HANDLE_LIST*)GetFirstNode(&mHandleList.List.Link)
1209 ; !IsNull(&mHandleList.List.Link,&ListWalker->Link)
1210 ; ListWalker = (HANDLE_LIST*)GetNextNode(&mHandleList.List.Link,&ListWalker->Link)
1211 ){
1212 if (ListWalker->TheHandle == TheHandle) {
1213 //
1214 // Verify that TheHandle is still present in the Handle Database
1215 //
1216 Status = gBS->ProtocolsPerHandle(TheHandle, &ProtocolBuffer, &ProtocolCount);
1217 if (EFI_ERROR (Status)) {
1218 //
1219 // TheHandle is not present in the Handle Database, so delete from the handle list
1220 //
1221 RemoveEntryList (&ListWalker->Link);
1222 return 0;
1223 }
1224 FreePool (ProtocolBuffer);
1225 return (ListWalker->TheIndex);
1226 }
1227 }
1228
1229 //
1230 // Verify that TheHandle is valid handle
1231 //
1232 Status = gBS->ProtocolsPerHandle(TheHandle, &ProtocolBuffer, &ProtocolCount);
1233 if (EFI_ERROR (Status)) {
1234 //
1235 // TheHandle is not valid, so do not add to handle list
1236 //
1237 return 0;
1238 }
1239 FreePool (ProtocolBuffer);
1240
1241 ListWalker = AllocateZeroPool(sizeof(HANDLE_LIST));
1242 ASSERT(ListWalker != NULL);
1243 ListWalker->TheHandle = TheHandle;
1244 ListWalker->TheIndex = mHandleList.NextIndex++;
1245 InsertTailList(&mHandleList.List.Link,&ListWalker->Link);
1246 return (ListWalker->TheIndex);
1247 }
1248
1249
1250
1251 /**
1252 Function to retrieve the EFI_HANDLE from the human-friendly index.
1253
1254 @param[in] TheIndex The index to retrieve the EFI_HANDLE for.
1255
1256 @retval NULL The index was invalid.
1257 @return The EFI_HANDLE that index represents.
1258
1259 **/
1260 EFI_HANDLE
1261 EFIAPI
1262 ConvertHandleIndexToHandle(
1263 IN CONST UINTN TheIndex
1264 )
1265 {
1266 EFI_STATUS Status;
1267 EFI_GUID **ProtocolBuffer;
1268 UINTN ProtocolCount;
1269 HANDLE_LIST *ListWalker;
1270
1271 InternalShellInitHandleList();
1272
1273 if (TheIndex >= mHandleList.NextIndex) {
1274 return NULL;
1275 }
1276
1277 for (ListWalker = (HANDLE_LIST*)GetFirstNode(&mHandleList.List.Link)
1278 ; !IsNull(&mHandleList.List.Link,&ListWalker->Link)
1279 ; ListWalker = (HANDLE_LIST*)GetNextNode(&mHandleList.List.Link,&ListWalker->Link)
1280 ){
1281 if (ListWalker->TheIndex == TheIndex && ListWalker->TheHandle != NULL) {
1282 //
1283 // Verify that LinkWalker->TheHandle is valid handle
1284 //
1285 Status = gBS->ProtocolsPerHandle(ListWalker->TheHandle, &ProtocolBuffer, &ProtocolCount);
1286 if (EFI_ERROR (Status)) {
1287 //
1288 // TheHandle is not valid, so do not add to handle list
1289 //
1290 ListWalker->TheHandle = NULL;
1291 }
1292 return (ListWalker->TheHandle);
1293 }
1294 }
1295 return NULL;
1296 }
1297
1298 /**
1299 Gets all the related EFI_HANDLEs based on the mask supplied.
1300
1301 This function scans all EFI_HANDLES in the UEFI environment's handle database
1302 and returns the ones with the specified relationship (Mask) to the specified
1303 controller handle.
1304
1305 If both DriverBindingHandle and ControllerHandle are NULL, then ASSERT.
1306 If MatchingHandleCount is NULL, then ASSERT.
1307
1308 If MatchingHandleBuffer is not NULL upon a successful return the memory must be
1309 caller freed.
1310
1311 @param[in] DriverBindingHandle The handle with Driver Binding protocol on it.
1312 @param[in] ControllerHandle The handle with Device Path protocol on it.
1313 @param[in] MatchingHandleCount The pointer to UINTN that specifies the number of HANDLES in
1314 MatchingHandleBuffer.
1315 @param[out] MatchingHandleBuffer On a successful return, a buffer of MatchingHandleCount
1316 EFI_HANDLEs with a terminating NULL EFI_HANDLE.
1317 @param[out] HandleType An array of type information.
1318
1319 @retval EFI_SUCCESS The operation was successful, and any related handles
1320 are in MatchingHandleBuffer.
1321 @retval EFI_NOT_FOUND No matching handles were found.
1322 @retval EFI_INVALID_PARAMETER A parameter was invalid or out of range.
1323 **/
1324 EFI_STATUS
1325 EFIAPI
1326 ParseHandleDatabaseByRelationshipWithType (
1327 IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL,
1328 IN CONST EFI_HANDLE ControllerHandle OPTIONAL,
1329 IN UINTN *HandleCount,
1330 OUT EFI_HANDLE **HandleBuffer,
1331 OUT UINTN **HandleType
1332 )
1333 {
1334 EFI_STATUS Status;
1335 UINTN HandleIndex;
1336 EFI_GUID **ProtocolGuidArray;
1337 UINTN ArrayCount;
1338 UINTN ProtocolIndex;
1339 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;
1340 UINTN OpenInfoCount;
1341 UINTN OpenInfoIndex;
1342 UINTN ChildIndex;
1343 INTN DriverBindingHandleIndex;
1344
1345 ASSERT(HandleCount != NULL);
1346 ASSERT(HandleBuffer != NULL);
1347 ASSERT(HandleType != NULL);
1348 ASSERT(DriverBindingHandle != NULL || ControllerHandle != NULL);
1349
1350 *HandleCount = 0;
1351 *HandleBuffer = NULL;
1352 *HandleType = NULL;
1353
1354 //
1355 // Retrieve the list of all handles from the handle database
1356 //
1357 Status = gBS->LocateHandleBuffer (
1358 AllHandles,
1359 NULL,
1360 NULL,
1361 HandleCount,
1362 HandleBuffer
1363 );
1364 if (EFI_ERROR (Status)) {
1365 return (Status);
1366 }
1367
1368 *HandleType = AllocateZeroPool (*HandleCount * sizeof (UINTN));
1369 ASSERT(*HandleType != NULL);
1370
1371 DriverBindingHandleIndex = -1;
1372 for (HandleIndex = 0; HandleIndex < *HandleCount; HandleIndex++) {
1373 if (DriverBindingHandle != NULL && (*HandleBuffer)[HandleIndex] == DriverBindingHandle) {
1374 DriverBindingHandleIndex = (INTN)HandleIndex;
1375 }
1376 }
1377
1378 for (HandleIndex = 0; HandleIndex < *HandleCount; HandleIndex++) {
1379 //
1380 // Retrieve the list of all the protocols on each handle
1381 //
1382 Status = gBS->ProtocolsPerHandle (
1383 (*HandleBuffer)[HandleIndex],
1384 &ProtocolGuidArray,
1385 &ArrayCount
1386 );
1387 if (EFI_ERROR (Status)) {
1388 continue;
1389 }
1390
1391 for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
1392
1393 //
1394 // Set the bit describing what this handle has
1395 //
1396 if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiLoadedImageProtocolGuid) ) {
1397 (*HandleType)[HandleIndex] |= (UINTN)HR_IMAGE_HANDLE;
1398 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverBindingProtocolGuid) ) {
1399 (*HandleType)[HandleIndex] |= (UINTN)HR_DRIVER_BINDING_HANDLE;
1400 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverConfiguration2ProtocolGuid)) {
1401 (*HandleType)[HandleIndex] |= (UINTN)HR_DRIVER_CONFIGURATION_HANDLE;
1402 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverConfigurationProtocolGuid) ) {
1403 (*HandleType)[HandleIndex] |= (UINTN)HR_DRIVER_CONFIGURATION_HANDLE;
1404 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverDiagnostics2ProtocolGuid) ) {
1405 (*HandleType)[HandleIndex] |= (UINTN)HR_DRIVER_DIAGNOSTICS_HANDLE;
1406 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverDiagnosticsProtocolGuid) ) {
1407 (*HandleType)[HandleIndex] |= (UINTN)HR_DRIVER_DIAGNOSTICS_HANDLE;
1408 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentName2ProtocolGuid) ) {
1409 (*HandleType)[HandleIndex] |= (UINTN)HR_COMPONENT_NAME_HANDLE;
1410 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentNameProtocolGuid) ) {
1411 (*HandleType)[HandleIndex] |= (UINTN)HR_COMPONENT_NAME_HANDLE;
1412 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDevicePathProtocolGuid) ) {
1413 (*HandleType)[HandleIndex] |= (UINTN)HR_DEVICE_HANDLE;
1414 } else {
1415 DEBUG_CODE_BEGIN();
1416 ASSERT((*HandleType)[HandleIndex] == (*HandleType)[HandleIndex]);
1417 DEBUG_CODE_END();
1418 }
1419 //
1420 // Retrieve the list of agents that have opened each protocol
1421 //
1422 Status = gBS->OpenProtocolInformation (
1423 (*HandleBuffer)[HandleIndex],
1424 ProtocolGuidArray[ProtocolIndex],
1425 &OpenInfo,
1426 &OpenInfoCount
1427 );
1428 if (EFI_ERROR (Status)) {
1429 continue;
1430 }
1431
1432 if (ControllerHandle == NULL) {
1433 //
1434 // ControllerHandle == NULL and DriverBindingHandle != NULL.
1435 // Return information on all the controller handles that the driver specified by DriverBindingHandle is managing
1436 //
1437 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
1438 if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle && (OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
1439 (*HandleType)[HandleIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);
1440 if (DriverBindingHandleIndex != -1) {
1441 (*HandleType)[DriverBindingHandleIndex] |= (UINTN)HR_DEVICE_DRIVER;
1442 }
1443 }
1444 if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle && (OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
1445 (*HandleType)[HandleIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);
1446 if (DriverBindingHandleIndex != -1) {
1447 (*HandleType)[DriverBindingHandleIndex] |= (UINTN)(HR_BUS_DRIVER | HR_DEVICE_DRIVER);
1448 }
1449 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
1450 if (OpenInfo[OpenInfoIndex].ControllerHandle == (*HandleBuffer)[ChildIndex]) {
1451 (*HandleType)[ChildIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CHILD_HANDLE);
1452 }
1453 }
1454 }
1455 }
1456 }
1457 if (DriverBindingHandle == NULL && ControllerHandle != NULL) {
1458 if (ControllerHandle == (*HandleBuffer)[HandleIndex]) {
1459 (*HandleType)[HandleIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);
1460 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
1461 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
1462 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
1463 if (OpenInfo[OpenInfoIndex].AgentHandle == (*HandleBuffer)[ChildIndex]) {
1464 (*HandleType)[ChildIndex] |= (UINTN)HR_DEVICE_DRIVER;
1465 }
1466 }
1467 }
1468 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
1469 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
1470 if (OpenInfo[OpenInfoIndex].AgentHandle == (*HandleBuffer)[ChildIndex]) {
1471 (*HandleType)[ChildIndex] |= (UINTN)(HR_BUS_DRIVER | HR_DEVICE_DRIVER);
1472 }
1473 if (OpenInfo[OpenInfoIndex].ControllerHandle == (*HandleBuffer)[ChildIndex]) {
1474 (*HandleType)[ChildIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CHILD_HANDLE);
1475 }
1476 }
1477 }
1478 }
1479 } else {
1480 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
1481 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
1482 if (OpenInfo[OpenInfoIndex].ControllerHandle == ControllerHandle) {
1483 (*HandleType)[HandleIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_PARENT_HANDLE);
1484 }
1485 }
1486 }
1487 }
1488 }
1489 if (DriverBindingHandle != NULL && ControllerHandle != NULL) {
1490 if (ControllerHandle == (*HandleBuffer)[HandleIndex]) {
1491 (*HandleType)[HandleIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);
1492 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
1493 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
1494 if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) {
1495 if (DriverBindingHandleIndex != -1) {
1496 (*HandleType)[DriverBindingHandleIndex] |= (UINTN)HR_DEVICE_DRIVER;
1497 }
1498 }
1499 }
1500 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
1501 if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) {
1502 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
1503 if (OpenInfo[OpenInfoIndex].ControllerHandle == (*HandleBuffer)[ChildIndex]) {
1504 (*HandleType)[ChildIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CHILD_HANDLE);
1505 }
1506 }
1507 }
1508
1509 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
1510 if (OpenInfo[OpenInfoIndex].AgentHandle == (*HandleBuffer)[ChildIndex]) {
1511 (*HandleType)[ChildIndex] |= (UINTN)(HR_BUS_DRIVER | HR_DEVICE_DRIVER);
1512 }
1513 }
1514 }
1515 }
1516 } else {
1517 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
1518 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
1519 if (OpenInfo[OpenInfoIndex].ControllerHandle == ControllerHandle) {
1520 (*HandleType)[HandleIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_PARENT_HANDLE);
1521 }
1522 }
1523 }
1524 }
1525 }
1526 FreePool (OpenInfo);
1527 }
1528 FreePool (ProtocolGuidArray);
1529 }
1530 return EFI_SUCCESS;
1531 }
1532
1533 /**
1534 Gets all the related EFI_HANDLEs based on the single EFI_HANDLE and the mask
1535 supplied.
1536
1537 This function will scan all EFI_HANDLES in the UEFI environment's handle database
1538 and return all the ones with the specified relationship (Mask) to the specified
1539 controller handle.
1540
1541 If both DriverBindingHandle and ControllerHandle are NULL, then ASSERT.
1542 If MatchingHandleCount is NULL, then ASSERT.
1543
1544 If MatchingHandleBuffer is not NULL upon a sucessful return the memory must be
1545 caller freed.
1546
1547 @param[in] DriverBindingHandle Handle to a object with Driver Binding protocol
1548 on it.
1549 @param[in] ControllerHandle Handle to a device with Device Path protocol on it.
1550 @param[in] Mask Mask of what relationship(s) is desired.
1551 @param[in] MatchingHandleCount Poitner to UINTN specifying number of HANDLES in
1552 MatchingHandleBuffer.
1553 @param[out] MatchingHandleBuffer On a sucessful return a buffer of MatchingHandleCount
1554 EFI_HANDLEs and a terminating NULL EFI_HANDLE.
1555
1556 @retval EFI_SUCCESS The operation was sucessful and any related handles
1557 are in MatchingHandleBuffer;
1558 @retval EFI_NOT_FOUND No matching handles were found.
1559 @retval EFI_INVALID_PARAMETER A parameter was invalid or out of range.
1560 **/
1561 EFI_STATUS
1562 EFIAPI
1563 ParseHandleDatabaseByRelationship (
1564 IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL,
1565 IN CONST EFI_HANDLE ControllerHandle OPTIONAL,
1566 IN CONST UINTN Mask,
1567 IN UINTN *MatchingHandleCount,
1568 OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL
1569 )
1570 {
1571 EFI_STATUS Status;
1572 UINTN HandleCount;
1573 EFI_HANDLE *HandleBuffer;
1574 UINTN *HandleType;
1575 UINTN HandleIndex;
1576
1577 ASSERT(MatchingHandleCount != NULL);
1578 ASSERT(DriverBindingHandle != NULL || ControllerHandle != NULL);
1579
1580 if ((Mask & HR_VALID_MASK) != Mask) {
1581 return (EFI_INVALID_PARAMETER);
1582 }
1583
1584 if ((Mask & HR_CHILD_HANDLE) != 0 && DriverBindingHandle == NULL) {
1585 return (EFI_INVALID_PARAMETER);
1586 }
1587
1588 *MatchingHandleCount = 0;
1589 if (MatchingHandleBuffer != NULL) {
1590 *MatchingHandleBuffer = NULL;
1591 }
1592
1593 HandleBuffer = NULL;
1594 HandleType = NULL;
1595
1596 Status = ParseHandleDatabaseByRelationshipWithType (
1597 DriverBindingHandle,
1598 ControllerHandle,
1599 &HandleCount,
1600 &HandleBuffer,
1601 &HandleType
1602 );
1603 if (!EFI_ERROR (Status)) {
1604 //
1605 // Count the number of handles that match the attributes in Mask
1606 //
1607 for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
1608 if ((HandleType[HandleIndex] & Mask) == Mask) {
1609 (*MatchingHandleCount)++;
1610 }
1611 }
1612 //
1613 // If no handles match the attributes in Mask then return EFI_NOT_FOUND
1614 //
1615 if (*MatchingHandleCount == 0) {
1616 Status = EFI_NOT_FOUND;
1617 } else {
1618
1619 if (MatchingHandleBuffer == NULL) {
1620 //
1621 // Someone just wanted the count...
1622 //
1623 Status = EFI_SUCCESS;
1624 } else {
1625 //
1626 // Allocate a handle buffer for the number of handles that matched the attributes in Mask
1627 //
1628 *MatchingHandleBuffer = AllocateZeroPool ((*MatchingHandleCount +1)* sizeof (EFI_HANDLE));
1629 ASSERT(*MatchingHandleBuffer != NULL);
1630
1631 for (HandleIndex = 0,*MatchingHandleCount = 0
1632 ; HandleIndex < HandleCount
1633 ; HandleIndex++
1634 ){
1635 //
1636 // Fill the allocated buffer with the handles that matched the attributes in Mask
1637 //
1638 if ((HandleType[HandleIndex] & Mask) == Mask) {
1639 (*MatchingHandleBuffer)[(*MatchingHandleCount)++] = HandleBuffer[HandleIndex];
1640 }
1641 }
1642
1643 //
1644 // Make the last one NULL
1645 //
1646 (*MatchingHandleBuffer)[*MatchingHandleCount] = NULL;
1647
1648 Status = EFI_SUCCESS;
1649 } // MacthingHandleBuffer == NULL (ELSE)
1650 } // *MatchingHandleCount == 0 (ELSE)
1651 } // no error on ParseHandleDatabaseByRelationshipWithType
1652
1653 if (HandleBuffer != NULL) {
1654 FreePool (HandleBuffer);
1655 }
1656
1657 if (HandleType != NULL) {
1658 FreePool (HandleType);
1659 }
1660
1661 return Status;
1662 }
1663
1664 /**
1665 Gets handles for any child controllers of the passed in controller.
1666
1667 @param[in] ControllerHandle The handle of the "parent controller"
1668 @param[in] MatchingHandleCount Pointer to the number of handles in
1669 MatchingHandleBuffer on return.
1670 @param[out] MatchingHandleBuffer Buffer containing handles on a successful
1671 return.
1672
1673
1674 @retval EFI_SUCCESS The operation was sucessful.
1675 **/
1676 EFI_STATUS
1677 EFIAPI
1678 ParseHandleDatabaseForChildControllers(
1679 IN CONST EFI_HANDLE ControllerHandle,
1680 IN UINTN *MatchingHandleCount,
1681 OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL
1682 )
1683 {
1684 EFI_STATUS Status;
1685 UINTN HandleIndex;
1686 UINTN DriverBindingHandleCount;
1687 EFI_HANDLE *DriverBindingHandleBuffer;
1688 UINTN DriverBindingHandleIndex;
1689 UINTN ChildControllerHandleCount;
1690 EFI_HANDLE *ChildControllerHandleBuffer;
1691 UINTN ChildControllerHandleIndex;
1692 EFI_HANDLE *HandleBufferForReturn;
1693
1694 if (MatchingHandleCount == NULL) {
1695 return (EFI_INVALID_PARAMETER);
1696 }
1697 *MatchingHandleCount = 0;
1698
1699 Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
1700 ControllerHandle,
1701 &DriverBindingHandleCount,
1702 &DriverBindingHandleBuffer
1703 );
1704 if (EFI_ERROR (Status)) {
1705 return Status;
1706 }
1707
1708 //
1709 // Get a buffer big enough for all the controllers.
1710 //
1711 HandleBufferForReturn = GetHandleListByProtocol(NULL);
1712 if (HandleBufferForReturn == NULL) {
1713 FreePool (DriverBindingHandleBuffer);
1714 return (EFI_NOT_FOUND);
1715 }
1716
1717 for (DriverBindingHandleIndex = 0; DriverBindingHandleIndex < DriverBindingHandleCount; DriverBindingHandleIndex++) {
1718 Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
1719 DriverBindingHandleBuffer[DriverBindingHandleIndex],
1720 ControllerHandle,
1721 &ChildControllerHandleCount,
1722 &ChildControllerHandleBuffer
1723 );
1724 if (EFI_ERROR (Status)) {
1725 continue;
1726 }
1727
1728 for (ChildControllerHandleIndex = 0;
1729 ChildControllerHandleIndex < ChildControllerHandleCount;
1730 ChildControllerHandleIndex++
1731 ) {
1732 for (HandleIndex = 0; HandleIndex < *MatchingHandleCount; HandleIndex++) {
1733 if (HandleBufferForReturn[HandleIndex] == ChildControllerHandleBuffer[ChildControllerHandleIndex]) {
1734 break;
1735 }
1736 }
1737 if (HandleIndex >= *MatchingHandleCount) {
1738 HandleBufferForReturn[(*MatchingHandleCount)++] = ChildControllerHandleBuffer[ChildControllerHandleIndex];
1739 }
1740 }
1741
1742 FreePool (ChildControllerHandleBuffer);
1743 }
1744
1745 FreePool (DriverBindingHandleBuffer);
1746
1747 if (MatchingHandleBuffer != NULL) {
1748 *MatchingHandleBuffer = HandleBufferForReturn;
1749 } else {
1750 FreePool(HandleBufferForReturn);
1751 }
1752
1753 return (EFI_SUCCESS);
1754 }
1755
1756 /**
1757 Appends 1 buffer to another buffer. This will re-allocate the destination buffer
1758 if necessary to fit all of the data.
1759
1760 If DestinationBuffer is NULL, then ASSERT().
1761
1762 @param[in, out] DestinationBuffer The pointer to the pointer to the buffer to append onto.
1763 @param[in, out] DestinationSize The pointer to the size of DestinationBuffer.
1764 @param[in] SourceBuffer The pointer to the buffer to append onto DestinationBuffer.
1765 @param[in] SourceSize The number of bytes of SourceBuffer to append.
1766
1767 @retval NULL A memory allocation failed.
1768 @retval NULL A parameter was invalid.
1769 @return A pointer to (*DestinationBuffer).
1770 **/
1771 VOID*
1772 EFIAPI
1773 BuffernCatGrow (
1774 IN OUT VOID **DestinationBuffer,
1775 IN OUT UINTN *DestinationSize,
1776 IN VOID *SourceBuffer,
1777 IN UINTN SourceSize
1778 )
1779 {
1780 UINTN LocalDestinationSize;
1781 UINTN LocalDestinationFinalSize;
1782
1783 ASSERT(DestinationBuffer != NULL);
1784
1785 if (SourceSize == 0 || SourceBuffer == NULL) {
1786 return (*DestinationBuffer);
1787 }
1788
1789 if (DestinationSize == NULL) {
1790 LocalDestinationSize = 0;
1791 } else {
1792 LocalDestinationSize = *DestinationSize;
1793 }
1794
1795 LocalDestinationFinalSize = LocalDestinationSize + SourceSize;
1796
1797 if (DestinationSize != NULL) {
1798 *DestinationSize = LocalDestinationSize;
1799 }
1800
1801 if (LocalDestinationSize == 0) {
1802 // allcoate
1803 *DestinationBuffer = AllocateZeroPool(LocalDestinationFinalSize);
1804 } else {
1805 // reallocate
1806 *DestinationBuffer = ReallocatePool(LocalDestinationSize, LocalDestinationFinalSize, *DestinationBuffer);
1807 }
1808
1809 ASSERT(*DestinationBuffer != NULL);
1810
1811 // copy
1812 return (CopyMem(((UINT8*)(*DestinationBuffer)) + LocalDestinationSize, SourceBuffer, SourceSize));
1813 }
1814
1815 /**
1816 Gets handles for any child devices produced by the passed in driver.
1817
1818 @param[in] DriverHandle The handle of the driver.
1819 @param[in] MatchingHandleCount Pointer to the number of handles in
1820 MatchingHandleBuffer on return.
1821 @param[out] MatchingHandleBuffer Buffer containing handles on a successful
1822 return.
1823 @retval EFI_SUCCESS The operation was sucessful.
1824 @sa ParseHandleDatabaseByRelationship
1825 **/
1826 EFI_STATUS
1827 EFIAPI
1828 ParseHandleDatabaseForChildDevices(
1829 IN CONST EFI_HANDLE DriverHandle,
1830 IN UINTN *MatchingHandleCount,
1831 OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL
1832 )
1833 {
1834 EFI_HANDLE *Buffer;
1835 EFI_HANDLE *Buffer2;
1836 UINTN Count1;
1837 UINTN Count2;
1838 UINTN HandleIndex;
1839 EFI_STATUS Status;
1840 UINTN HandleBufferSize;
1841
1842 ASSERT(MatchingHandleCount != NULL);
1843
1844 HandleBufferSize = 0;
1845 Buffer = NULL;
1846 Buffer2 = NULL;
1847 *MatchingHandleCount = 0;
1848
1849 Status = PARSE_HANDLE_DATABASE_DEVICES (
1850 DriverHandle,
1851 &Count1,
1852 &Buffer
1853 );
1854 if (!EFI_ERROR (Status)) {
1855 for (HandleIndex = 0; HandleIndex < Count1; HandleIndex++) {
1856 //
1857 // now find the children
1858 //
1859 Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
1860 DriverHandle,
1861 Buffer[HandleIndex],
1862 &Count2,
1863 &Buffer2
1864 );
1865 if (EFI_ERROR(Status)) {
1866 break;
1867 }
1868 //
1869 // save out required and optional data elements
1870 //
1871 *MatchingHandleCount += Count2;
1872 if (MatchingHandleBuffer != NULL) {
1873 *MatchingHandleBuffer = BuffernCatGrow((VOID**)MatchingHandleBuffer, &HandleBufferSize, Buffer2, Count2 * sizeof(Buffer2[0]));
1874 }
1875
1876 //
1877 // free the memory
1878 //
1879 if (Buffer2 != NULL) {
1880 FreePool(Buffer2);
1881 }
1882 }
1883 }
1884
1885 if (Buffer != NULL) {
1886 FreePool(Buffer);
1887 }
1888 return (Status);
1889 }
1890
1891 /**
1892 Function to get all handles that support a given protocol or all handles.
1893
1894 @param[in] ProtocolGuid The guid of the protocol to get handles for. If NULL
1895 then the function will return all handles.
1896
1897 @retval NULL A memory allocation failed.
1898 @return A NULL terminated list of handles.
1899 **/
1900 EFI_HANDLE*
1901 EFIAPI
1902 GetHandleListByProtocol (
1903 IN CONST EFI_GUID *ProtocolGuid OPTIONAL
1904 )
1905 {
1906 EFI_HANDLE *HandleList;
1907 UINTN Size;
1908 EFI_STATUS Status;
1909
1910 Size = 0;
1911 HandleList = NULL;
1912
1913 //
1914 // We cannot use LocateHandleBuffer since we need that NULL item on the ends of the list!
1915 //
1916 if (ProtocolGuid == NULL) {
1917 Status = gBS->LocateHandle(AllHandles, NULL, NULL, &Size, HandleList);
1918 if (Status == EFI_BUFFER_TOO_SMALL) {
1919 HandleList = AllocateZeroPool(Size + sizeof(EFI_HANDLE));
1920 if (HandleList == NULL) {
1921 return (NULL);
1922 }
1923 Status = gBS->LocateHandle(AllHandles, NULL, NULL, &Size, HandleList);
1924 HandleList[Size/sizeof(EFI_HANDLE)] = NULL;
1925 }
1926 } else {
1927 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)ProtocolGuid, NULL, &Size, HandleList);
1928 if (Status == EFI_BUFFER_TOO_SMALL) {
1929 HandleList = AllocateZeroPool(Size + sizeof(EFI_HANDLE));
1930 if (HandleList == NULL) {
1931 return (NULL);
1932 }
1933 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)ProtocolGuid, NULL, &Size, HandleList);
1934 HandleList[Size/sizeof(EFI_HANDLE)] = NULL;
1935 }
1936 }
1937 if (EFI_ERROR(Status)) {
1938 if (HandleList != NULL) {
1939 FreePool(HandleList);
1940 }
1941 return (NULL);
1942 }
1943 return (HandleList);
1944 }
1945
1946 /**
1947 Function to get all handles that support some protocols.
1948
1949 @param[in] ProtocolGuids A NULL terminated list of protocol GUIDs.
1950
1951 @retval NULL A memory allocation failed.
1952 @retval NULL ProtocolGuids was NULL.
1953 @return A NULL terminated list of EFI_HANDLEs.
1954 **/
1955 EFI_HANDLE*
1956 EFIAPI
1957 GetHandleListByProtocolList (
1958 IN CONST EFI_GUID **ProtocolGuids
1959 )
1960 {
1961 EFI_HANDLE *HandleList;
1962 UINTN Size;
1963 UINTN TotalSize;
1964 UINTN TempSize;
1965 EFI_STATUS Status;
1966 CONST EFI_GUID **GuidWalker;
1967 EFI_HANDLE *HandleWalker1;
1968 EFI_HANDLE *HandleWalker2;
1969
1970 Size = 0;
1971 HandleList = NULL;
1972 TotalSize = sizeof(EFI_HANDLE);
1973
1974 for (GuidWalker = ProtocolGuids ; GuidWalker != NULL && *GuidWalker != NULL ; GuidWalker++,Size = 0){
1975 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)(*GuidWalker), NULL, &Size, NULL);
1976 if (Status == EFI_BUFFER_TOO_SMALL) {
1977 TotalSize += Size;
1978 }
1979 }
1980
1981 //
1982 // No handles were found...
1983 //
1984 if (TotalSize == sizeof(EFI_HANDLE)) {
1985 return (NULL);
1986 }
1987
1988 HandleList = AllocateZeroPool(TotalSize);
1989 if (HandleList == NULL) {
1990 return (NULL);
1991 }
1992
1993 Size = 0;
1994 for (GuidWalker = ProtocolGuids ; GuidWalker != NULL && *GuidWalker != NULL ; GuidWalker++){
1995 TempSize = TotalSize - Size;
1996 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)(*GuidWalker), NULL, &TempSize, HandleList+(Size/sizeof(EFI_HANDLE)));
1997
1998 //
1999 // Allow for missing protocols... Only update the 'used' size upon success.
2000 //
2001 if (!EFI_ERROR(Status)) {
2002 Size += TempSize;
2003 }
2004 }
2005 ASSERT(HandleList[(TotalSize/sizeof(EFI_HANDLE))-1] == NULL);
2006
2007 for (HandleWalker1 = HandleList ; HandleWalker1 != NULL && *HandleWalker1 != NULL ; HandleWalker1++) {
2008 for (HandleWalker2 = HandleWalker1 + 1; HandleWalker2 != NULL && *HandleWalker2 != NULL ; HandleWalker2++) {
2009 if (*HandleWalker1 == *HandleWalker2) {
2010 //
2011 // copy memory back 1 handle width.
2012 //
2013 CopyMem(HandleWalker2, HandleWalker2 + 1, TotalSize - ((HandleWalker2-HandleList+1)*sizeof(EFI_HANDLE)));
2014 }
2015 }
2016 }
2017
2018 return (HandleList);
2019 }
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029