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