]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c
Update all the code to consume the ConvertDevicePathToText, ConvertDevicePathNodeToTe...
[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 - 2012, 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 current platform used language to search,Second base on the
782 default language to search. The caller need to free the buffer of the best
783 language.
784
785 @param[in] SupportedLanguages The support languages for this driver.
786 @param[in] Iso639Language Whether get language for ISO639.
787
788 @return The best support language for this driver.
789 **/
790 CHAR8 *
791 GetBestLanguageForDriver (
792 IN CONST CHAR8 *SupportedLanguages,
793 IN BOOLEAN Iso639Language
794 )
795 {
796 CHAR8 *LanguageVariable;
797 CHAR8 *BestLanguage;
798
799 LanguageVariable = GetVariable (Iso639Language ? L"Lang" : L"PlatformLang", &gEfiGlobalVariableGuid);
800
801 BestLanguage = GetBestLanguage(
802 SupportedLanguages,
803 Iso639Language,
804 (LanguageVariable != NULL) ? LanguageVariable : "",
805 Iso639Language ? "en" : "en-US",
806 NULL
807 );
808
809 if (LanguageVariable != NULL) {
810 FreePool (LanguageVariable);
811 }
812
813 return BestLanguage;
814 }
815
816 /**
817 Function to retrieve the driver name (if possible) from the ComponentName or
818 ComponentName2 protocol
819
820 @param[in] TheHandle The driver handle to get the name of.
821 @param[in] Language The language to use.
822
823 @retval NULL The name could not be found.
824 @return A pointer to the string name. Do not de-allocate the memory.
825 **/
826 CONST CHAR16*
827 EFIAPI
828 GetStringNameFromHandle(
829 IN CONST EFI_HANDLE TheHandle,
830 IN CONST CHAR8 *Language
831 )
832 {
833 EFI_COMPONENT_NAME2_PROTOCOL *CompNameStruct;
834 EFI_STATUS Status;
835 CHAR16 *RetVal;
836 CHAR8 *BestLang;
837
838 BestLang = NULL;
839
840 Status = gBS->OpenProtocol(
841 TheHandle,
842 &gEfiComponentName2ProtocolGuid,
843 (VOID**)&CompNameStruct,
844 gImageHandle,
845 NULL,
846 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
847 if (!EFI_ERROR(Status)) {
848 if (Language == NULL) {
849 BestLang = GetBestLanguageForDriver (CompNameStruct->SupportedLanguages, FALSE);
850 Language = BestLang;
851 }
852 Status = CompNameStruct->GetDriverName(CompNameStruct, (CHAR8*)Language, &RetVal);
853
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 if (Language == NULL) {
871 BestLang = GetBestLanguageForDriver (CompNameStruct->SupportedLanguages, FALSE);
872 Language = BestLang;
873 }
874 Status = CompNameStruct->GetDriverName(CompNameStruct, (CHAR8*)Language, &RetVal);
875
876 if (BestLang != NULL) {
877 FreePool (BestLang);
878 }
879 if (!EFI_ERROR(Status)) {
880 return (RetVal);
881 }
882 }
883 return (NULL);
884 }
885
886 /**
887 Function to initialize the file global mHandleList object for use in
888 vonverting handles to index and index to handle.
889
890 @retval EFI_SUCCESS The operation was successful.
891 **/
892 EFI_STATUS
893 EFIAPI
894 InternalShellInitHandleList(
895 VOID
896 )
897 {
898 EFI_STATUS Status;
899 EFI_HANDLE *HandleBuffer;
900 UINTN HandleCount;
901 HANDLE_LIST *ListWalker;
902
903 if (mHandleList.NextIndex != 0) {
904 return EFI_SUCCESS;
905 }
906 InitializeListHead(&mHandleList.List.Link);
907 mHandleList.NextIndex = 1;
908 Status = gBS->LocateHandleBuffer (
909 AllHandles,
910 NULL,
911 NULL,
912 &HandleCount,
913 &HandleBuffer
914 );
915 ASSERT_EFI_ERROR(Status);
916 if (EFI_ERROR(Status)) {
917 return (Status);
918 }
919 for (mHandleList.NextIndex = 1 ; mHandleList.NextIndex <= HandleCount ; mHandleList.NextIndex++){
920 ListWalker = AllocateZeroPool(sizeof(HANDLE_LIST));
921 ASSERT(ListWalker != NULL);
922 ListWalker->TheHandle = HandleBuffer[mHandleList.NextIndex-1];
923 ListWalker->TheIndex = mHandleList.NextIndex;
924 InsertTailList(&mHandleList.List.Link,&ListWalker->Link);
925 }
926 FreePool(HandleBuffer);
927 return (EFI_SUCCESS);
928 }
929
930 /**
931 Function to retrieve the human-friendly index of a given handle. If the handle
932 does not have a index one will be automatically assigned. The index value is valid
933 until the termination of the shell application.
934
935 @param[in] TheHandle The handle to retrieve an index for.
936
937 @retval 0 A memory allocation failed.
938 @return The index of the handle.
939
940 **/
941 UINTN
942 EFIAPI
943 ConvertHandleToHandleIndex(
944 IN CONST EFI_HANDLE TheHandle
945 )
946 {
947 EFI_STATUS Status;
948 EFI_GUID **ProtocolBuffer;
949 UINTN ProtocolCount;
950 HANDLE_LIST *ListWalker;
951
952 if (TheHandle == NULL) {
953 return 0;
954 }
955
956 InternalShellInitHandleList();
957
958 for (ListWalker = (HANDLE_LIST*)GetFirstNode(&mHandleList.List.Link)
959 ; !IsNull(&mHandleList.List.Link,&ListWalker->Link)
960 ; ListWalker = (HANDLE_LIST*)GetNextNode(&mHandleList.List.Link,&ListWalker->Link)
961 ){
962 if (ListWalker->TheHandle == TheHandle) {
963 //
964 // Verify that TheHandle is still present in the Handle Database
965 //
966 Status = gBS->ProtocolsPerHandle(TheHandle, &ProtocolBuffer, &ProtocolCount);
967 if (EFI_ERROR (Status)) {
968 //
969 // TheHandle is not present in the Handle Database, so delete from the handle list
970 //
971 RemoveEntryList (&ListWalker->Link);
972 return 0;
973 }
974 FreePool (ProtocolBuffer);
975 return (ListWalker->TheIndex);
976 }
977 }
978
979 //
980 // Verify that TheHandle is valid handle
981 //
982 Status = gBS->ProtocolsPerHandle(TheHandle, &ProtocolBuffer, &ProtocolCount);
983 if (EFI_ERROR (Status)) {
984 //
985 // TheHandle is not valid, so do not add to handle list
986 //
987 return 0;
988 }
989 FreePool (ProtocolBuffer);
990
991 ListWalker = AllocateZeroPool(sizeof(HANDLE_LIST));
992 ASSERT(ListWalker != NULL);
993 ListWalker->TheHandle = TheHandle;
994 ListWalker->TheIndex = mHandleList.NextIndex++;
995 InsertTailList(&mHandleList.List.Link,&ListWalker->Link);
996 return (ListWalker->TheIndex);
997 }
998
999
1000
1001 /**
1002 Function to retrieve the EFI_HANDLE from the human-friendly index.
1003
1004 @param[in] TheIndex The index to retrieve the EFI_HANDLE for.
1005
1006 @retval NULL The index was invalid.
1007 @return The EFI_HANDLE that index represents.
1008
1009 **/
1010 EFI_HANDLE
1011 EFIAPI
1012 ConvertHandleIndexToHandle(
1013 IN CONST UINTN TheIndex
1014 )
1015 {
1016 EFI_STATUS Status;
1017 EFI_GUID **ProtocolBuffer;
1018 UINTN ProtocolCount;
1019 HANDLE_LIST *ListWalker;
1020
1021 InternalShellInitHandleList();
1022
1023 if (TheIndex >= mHandleList.NextIndex) {
1024 return NULL;
1025 }
1026
1027 for (ListWalker = (HANDLE_LIST*)GetFirstNode(&mHandleList.List.Link)
1028 ; !IsNull(&mHandleList.List.Link,&ListWalker->Link)
1029 ; ListWalker = (HANDLE_LIST*)GetNextNode(&mHandleList.List.Link,&ListWalker->Link)
1030 ){
1031 if (ListWalker->TheIndex == TheIndex && ListWalker->TheHandle != NULL) {
1032 //
1033 // Verify that LinkWalker->TheHandle is valid handle
1034 //
1035 Status = gBS->ProtocolsPerHandle(ListWalker->TheHandle, &ProtocolBuffer, &ProtocolCount);
1036 if (EFI_ERROR (Status)) {
1037 //
1038 // TheHandle is not valid, so do not add to handle list
1039 //
1040 ListWalker->TheHandle = NULL;
1041 }
1042 return (ListWalker->TheHandle);
1043 }
1044 }
1045 return NULL;
1046 }
1047
1048 /**
1049 Gets all the related EFI_HANDLEs based on the mask supplied.
1050
1051 This function scans all EFI_HANDLES in the UEFI environment's handle database
1052 and returns the ones with the specified relationship (Mask) to the specified
1053 controller handle.
1054
1055 If both DriverBindingHandle and ControllerHandle are NULL, then ASSERT.
1056 If MatchingHandleCount is NULL, then ASSERT.
1057
1058 If MatchingHandleBuffer is not NULL upon a successful return the memory must be
1059 caller freed.
1060
1061 @param[in] DriverBindingHandle The handle with Driver Binding protocol on it.
1062 @param[in] ControllerHandle The handle with Device Path protocol on it.
1063 @param[in] MatchingHandleCount The pointer to UINTN that specifies the number of HANDLES in
1064 MatchingHandleBuffer.
1065 @param[out] MatchingHandleBuffer On a successful return, a buffer of MatchingHandleCount
1066 EFI_HANDLEs with a terminating NULL EFI_HANDLE.
1067 @param[out] HandleType An array of type information.
1068
1069 @retval EFI_SUCCESS The operation was successful, and any related handles
1070 are in MatchingHandleBuffer.
1071 @retval EFI_NOT_FOUND No matching handles were found.
1072 @retval EFI_INVALID_PARAMETER A parameter was invalid or out of range.
1073 **/
1074 EFI_STATUS
1075 EFIAPI
1076 ParseHandleDatabaseByRelationshipWithType (
1077 IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL,
1078 IN CONST EFI_HANDLE ControllerHandle OPTIONAL,
1079 IN UINTN *HandleCount,
1080 OUT EFI_HANDLE **HandleBuffer,
1081 OUT UINTN **HandleType
1082 )
1083 {
1084 EFI_STATUS Status;
1085 UINTN HandleIndex;
1086 EFI_GUID **ProtocolGuidArray;
1087 UINTN ArrayCount;
1088 UINTN ProtocolIndex;
1089 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;
1090 UINTN OpenInfoCount;
1091 UINTN OpenInfoIndex;
1092 UINTN ChildIndex;
1093 INTN DriverBindingHandleIndex;
1094
1095 ASSERT(HandleCount != NULL);
1096 ASSERT(HandleBuffer != NULL);
1097 ASSERT(HandleType != NULL);
1098 ASSERT(DriverBindingHandle != NULL || ControllerHandle != NULL);
1099
1100 *HandleCount = 0;
1101 *HandleBuffer = NULL;
1102 *HandleType = NULL;
1103
1104 //
1105 // Retrieve the list of all handles from the handle database
1106 //
1107 Status = gBS->LocateHandleBuffer (
1108 AllHandles,
1109 NULL,
1110 NULL,
1111 HandleCount,
1112 HandleBuffer
1113 );
1114 if (EFI_ERROR (Status)) {
1115 return (Status);
1116 }
1117
1118 *HandleType = AllocateZeroPool (*HandleCount * sizeof (UINTN));
1119 ASSERT(*HandleType != NULL);
1120
1121 DriverBindingHandleIndex = -1;
1122 for (HandleIndex = 0; HandleIndex < *HandleCount; HandleIndex++) {
1123 if (DriverBindingHandle != NULL && (*HandleBuffer)[HandleIndex] == DriverBindingHandle) {
1124 DriverBindingHandleIndex = (INTN)HandleIndex;
1125 }
1126 }
1127
1128 for (HandleIndex = 0; HandleIndex < *HandleCount; HandleIndex++) {
1129 //
1130 // Retrieve the list of all the protocols on each handle
1131 //
1132 Status = gBS->ProtocolsPerHandle (
1133 (*HandleBuffer)[HandleIndex],
1134 &ProtocolGuidArray,
1135 &ArrayCount
1136 );
1137 if (EFI_ERROR (Status)) {
1138 continue;
1139 }
1140
1141 for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
1142
1143 //
1144 // Set the bit describing what this handle has
1145 //
1146 if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiLoadedImageProtocolGuid) ) {
1147 (*HandleType)[HandleIndex] |= HR_IMAGE_HANDLE;
1148 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverBindingProtocolGuid) ) {
1149 (*HandleType)[HandleIndex] |= HR_DRIVER_BINDING_HANDLE;
1150 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverConfiguration2ProtocolGuid)) {
1151 (*HandleType)[HandleIndex] |= HR_DRIVER_CONFIGURATION_HANDLE;
1152 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverConfigurationProtocolGuid) ) {
1153 (*HandleType)[HandleIndex] |= HR_DRIVER_CONFIGURATION_HANDLE;
1154 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverDiagnostics2ProtocolGuid) ) {
1155 (*HandleType)[HandleIndex] |= HR_DRIVER_DIAGNOSTICS_HANDLE;
1156 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverDiagnosticsProtocolGuid) ) {
1157 (*HandleType)[HandleIndex] |= HR_DRIVER_DIAGNOSTICS_HANDLE;
1158 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentName2ProtocolGuid) ) {
1159 (*HandleType)[HandleIndex] |= HR_COMPONENT_NAME_HANDLE;
1160 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentNameProtocolGuid) ) {
1161 (*HandleType)[HandleIndex] |= HR_COMPONENT_NAME_HANDLE;
1162 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDevicePathProtocolGuid) ) {
1163 (*HandleType)[HandleIndex] |= HR_DEVICE_HANDLE;
1164 } else {
1165 DEBUG_CODE_BEGIN();
1166 ASSERT((*HandleType)[HandleIndex] == (*HandleType)[HandleIndex]);
1167 DEBUG_CODE_END();
1168 }
1169 //
1170 // Retrieve the list of agents that have opened each protocol
1171 //
1172 Status = gBS->OpenProtocolInformation (
1173 (*HandleBuffer)[HandleIndex],
1174 ProtocolGuidArray[ProtocolIndex],
1175 &OpenInfo,
1176 &OpenInfoCount
1177 );
1178 if (EFI_ERROR (Status)) {
1179 continue;
1180 }
1181
1182 if (ControllerHandle == NULL) {
1183 //
1184 // ControllerHandle == NULL and DriverBindingHandle != NULL.
1185 // Return information on all the controller handles that the driver specified by DriverBindingHandle is managing
1186 //
1187 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
1188 if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle && (OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
1189 (*HandleType)[HandleIndex] |= (HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);
1190 if (DriverBindingHandleIndex != -1) {
1191 (*HandleType)[DriverBindingHandleIndex] |= HR_DEVICE_DRIVER;
1192 }
1193 }
1194 if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle && (OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
1195 (*HandleType)[HandleIndex] |= (HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);
1196 if (DriverBindingHandleIndex != -1) {
1197 (*HandleType)[DriverBindingHandleIndex] |= (HR_BUS_DRIVER | HR_DEVICE_DRIVER);
1198 }
1199 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
1200 if (OpenInfo[OpenInfoIndex].ControllerHandle == (*HandleBuffer)[ChildIndex]) {
1201 (*HandleType)[ChildIndex] |= (HR_DEVICE_HANDLE | HR_CHILD_HANDLE);
1202 }
1203 }
1204 }
1205 }
1206 }
1207 if (DriverBindingHandle == NULL && ControllerHandle != NULL) {
1208 if (ControllerHandle == (*HandleBuffer)[HandleIndex]) {
1209 (*HandleType)[HandleIndex] |= (HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);
1210 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
1211 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
1212 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
1213 if (OpenInfo[OpenInfoIndex].AgentHandle == (*HandleBuffer)[ChildIndex]) {
1214 (*HandleType)[ChildIndex] |= HR_DEVICE_DRIVER;
1215 }
1216 }
1217 }
1218 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
1219 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
1220 if (OpenInfo[OpenInfoIndex].AgentHandle == (*HandleBuffer)[ChildIndex]) {
1221 (*HandleType)[ChildIndex] |= (HR_BUS_DRIVER | HR_DEVICE_DRIVER);
1222 }
1223 if (OpenInfo[OpenInfoIndex].ControllerHandle == (*HandleBuffer)[ChildIndex]) {
1224 (*HandleType)[ChildIndex] |= (HR_DEVICE_HANDLE | HR_CHILD_HANDLE);
1225 }
1226 }
1227 }
1228 }
1229 } else {
1230 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
1231 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
1232 if (OpenInfo[OpenInfoIndex].ControllerHandle == ControllerHandle) {
1233 (*HandleType)[HandleIndex] |= (HR_DEVICE_HANDLE | HR_PARENT_HANDLE);
1234 }
1235 }
1236 }
1237 }
1238 }
1239 if (DriverBindingHandle != NULL && ControllerHandle != NULL) {
1240 if (ControllerHandle == (*HandleBuffer)[HandleIndex]) {
1241 (*HandleType)[HandleIndex] |= (HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);
1242 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
1243 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
1244 if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) {
1245 if (DriverBindingHandleIndex != -1) {
1246 (*HandleType)[DriverBindingHandleIndex] |= HR_DEVICE_DRIVER;
1247 }
1248 }
1249 }
1250 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
1251 if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) {
1252 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
1253 if (OpenInfo[OpenInfoIndex].ControllerHandle == (*HandleBuffer)[ChildIndex]) {
1254 (*HandleType)[ChildIndex] |= (HR_DEVICE_HANDLE | HR_CHILD_HANDLE);
1255 }
1256 }
1257 }
1258
1259 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
1260 if (OpenInfo[OpenInfoIndex].AgentHandle == (*HandleBuffer)[ChildIndex]) {
1261 (*HandleType)[ChildIndex] |= (HR_BUS_DRIVER | HR_DEVICE_DRIVER);
1262 }
1263 }
1264 }
1265 }
1266 } else {
1267 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
1268 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
1269 if (OpenInfo[OpenInfoIndex].ControllerHandle == ControllerHandle) {
1270 (*HandleType)[HandleIndex] |= (HR_DEVICE_HANDLE | HR_PARENT_HANDLE);
1271 }
1272 }
1273 }
1274 }
1275 }
1276 FreePool (OpenInfo);
1277 }
1278 FreePool (ProtocolGuidArray);
1279 }
1280 return EFI_SUCCESS;
1281 }
1282
1283 /**
1284 Gets all the related EFI_HANDLEs based on the single EFI_HANDLE and the mask
1285 supplied.
1286
1287 This function will scan all EFI_HANDLES in the UEFI environment's handle database
1288 and return all the ones with the specified relationship (Mask) to the specified
1289 controller handle.
1290
1291 If both DriverBindingHandle and ControllerHandle are NULL, then ASSERT.
1292 If MatchingHandleCount is NULL, then ASSERT.
1293
1294 If MatchingHandleBuffer is not NULL upon a sucessful return the memory must be
1295 caller freed.
1296
1297 @param[in] DriverBindingHandle Handle to a object with Driver Binding protocol
1298 on it.
1299 @param[in] ControllerHandle Handle to a device with Device Path protocol on it.
1300 @param[in] Mask Mask of what relationship(s) is desired.
1301 @param[in] MatchingHandleCount Poitner to UINTN specifying number of HANDLES in
1302 MatchingHandleBuffer.
1303 @param[out] MatchingHandleBuffer On a sucessful return a buffer of MatchingHandleCount
1304 EFI_HANDLEs and a terminating NULL EFI_HANDLE.
1305
1306 @retval EFI_SUCCESS The operation was sucessful and any related handles
1307 are in MatchingHandleBuffer;
1308 @retval EFI_NOT_FOUND No matching handles were found.
1309 @retval EFI_INVALID_PARAMETER A parameter was invalid or out of range.
1310 **/
1311 EFI_STATUS
1312 EFIAPI
1313 ParseHandleDatabaseByRelationship (
1314 IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL,
1315 IN CONST EFI_HANDLE ControllerHandle OPTIONAL,
1316 IN CONST UINTN Mask,
1317 IN UINTN *MatchingHandleCount,
1318 OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL
1319 )
1320 {
1321 EFI_STATUS Status;
1322 UINTN HandleCount;
1323 EFI_HANDLE *HandleBuffer;
1324 UINTN *HandleType;
1325 UINTN HandleIndex;
1326
1327 ASSERT(MatchingHandleCount != NULL);
1328 ASSERT(DriverBindingHandle != NULL || ControllerHandle != NULL);
1329
1330 if ((Mask & HR_VALID_MASK) != Mask) {
1331 return (EFI_INVALID_PARAMETER);
1332 }
1333
1334 if ((Mask & HR_CHILD_HANDLE) != 0 && DriverBindingHandle == NULL) {
1335 return (EFI_INVALID_PARAMETER);
1336 }
1337
1338 *MatchingHandleCount = 0;
1339 if (MatchingHandleBuffer != NULL) {
1340 *MatchingHandleBuffer = NULL;
1341 }
1342
1343 HandleBuffer = NULL;
1344 HandleType = NULL;
1345
1346 Status = ParseHandleDatabaseByRelationshipWithType (
1347 DriverBindingHandle,
1348 ControllerHandle,
1349 &HandleCount,
1350 &HandleBuffer,
1351 &HandleType
1352 );
1353 if (!EFI_ERROR (Status)) {
1354 //
1355 // Count the number of handles that match the attributes in Mask
1356 //
1357 for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
1358 if ((HandleType[HandleIndex] & Mask) == Mask) {
1359 (*MatchingHandleCount)++;
1360 }
1361 }
1362 //
1363 // If no handles match the attributes in Mask then return EFI_NOT_FOUND
1364 //
1365 if (*MatchingHandleCount == 0) {
1366 Status = EFI_NOT_FOUND;
1367 } else {
1368
1369 if (MatchingHandleBuffer == NULL) {
1370 //
1371 // Someone just wanted the count...
1372 //
1373 Status = EFI_SUCCESS;
1374 } else {
1375 //
1376 // Allocate a handle buffer for the number of handles that matched the attributes in Mask
1377 //
1378 *MatchingHandleBuffer = AllocateZeroPool ((*MatchingHandleCount +1)* sizeof (EFI_HANDLE));
1379 ASSERT(*MatchingHandleBuffer != NULL);
1380
1381 for (HandleIndex = 0,*MatchingHandleCount = 0
1382 ; HandleIndex < HandleCount
1383 ; HandleIndex++
1384 ){
1385 //
1386 // Fill the allocated buffer with the handles that matched the attributes in Mask
1387 //
1388 if ((HandleType[HandleIndex] & Mask) == Mask) {
1389 (*MatchingHandleBuffer)[(*MatchingHandleCount)++] = HandleBuffer[HandleIndex];
1390 }
1391 }
1392
1393 //
1394 // Make the last one NULL
1395 //
1396 (*MatchingHandleBuffer)[*MatchingHandleCount] = NULL;
1397
1398 Status = EFI_SUCCESS;
1399 } // MacthingHandleBuffer == NULL (ELSE)
1400 } // *MatchingHandleCount == 0 (ELSE)
1401 } // no error on ParseHandleDatabaseByRelationshipWithType
1402
1403 if (HandleBuffer != NULL) {
1404 FreePool (HandleBuffer);
1405 }
1406
1407 if (HandleType != NULL) {
1408 FreePool (HandleType);
1409 }
1410
1411 return Status;
1412 }
1413
1414 /**
1415 Gets handles for any child controllers of the passed in controller.
1416
1417 @param[in] ControllerHandle The handle of the "parent controller"
1418 @param[in] MatchingHandleCount Pointer to the number of handles in
1419 MatchingHandleBuffer on return.
1420 @param[out] MatchingHandleBuffer Buffer containing handles on a successful
1421 return.
1422
1423
1424 @retval EFI_SUCCESS The operation was sucessful.
1425 **/
1426 EFI_STATUS
1427 EFIAPI
1428 ParseHandleDatabaseForChildControllers(
1429 IN CONST EFI_HANDLE ControllerHandle,
1430 IN UINTN *MatchingHandleCount,
1431 OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL
1432 )
1433 {
1434 EFI_STATUS Status;
1435 UINTN HandleIndex;
1436 UINTN DriverBindingHandleCount;
1437 EFI_HANDLE *DriverBindingHandleBuffer;
1438 UINTN DriverBindingHandleIndex;
1439 UINTN ChildControllerHandleCount;
1440 EFI_HANDLE *ChildControllerHandleBuffer;
1441 UINTN ChildControllerHandleIndex;
1442 EFI_HANDLE *HandleBufferForReturn;
1443
1444 if (MatchingHandleCount == NULL) {
1445 return (EFI_INVALID_PARAMETER);
1446 }
1447 *MatchingHandleCount = 0;
1448
1449 Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
1450 ControllerHandle,
1451 &DriverBindingHandleCount,
1452 &DriverBindingHandleBuffer
1453 );
1454 if (EFI_ERROR (Status)) {
1455 return Status;
1456 }
1457
1458 //
1459 // Get a buffer big enough for all the controllers.
1460 //
1461 HandleBufferForReturn = GetHandleListByProtocol(NULL);
1462 if (HandleBufferForReturn == NULL) {
1463 FreePool (DriverBindingHandleBuffer);
1464 return (EFI_NOT_FOUND);
1465 }
1466
1467 for (DriverBindingHandleIndex = 0; DriverBindingHandleIndex < DriverBindingHandleCount; DriverBindingHandleIndex++) {
1468 Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
1469 DriverBindingHandleBuffer[DriverBindingHandleIndex],
1470 ControllerHandle,
1471 &ChildControllerHandleCount,
1472 &ChildControllerHandleBuffer
1473 );
1474 if (EFI_ERROR (Status)) {
1475 continue;
1476 }
1477
1478 for (ChildControllerHandleIndex = 0;
1479 ChildControllerHandleIndex < ChildControllerHandleCount;
1480 ChildControllerHandleIndex++
1481 ) {
1482 for (HandleIndex = 0; HandleIndex < *MatchingHandleCount; HandleIndex++) {
1483 if (HandleBufferForReturn[HandleIndex] == ChildControllerHandleBuffer[ChildControllerHandleIndex]) {
1484 break;
1485 }
1486 }
1487 if (HandleIndex >= *MatchingHandleCount) {
1488 HandleBufferForReturn[(*MatchingHandleCount)++] = ChildControllerHandleBuffer[ChildControllerHandleIndex];
1489 }
1490 }
1491
1492 FreePool (ChildControllerHandleBuffer);
1493 }
1494
1495 FreePool (DriverBindingHandleBuffer);
1496
1497 if (MatchingHandleBuffer != NULL) {
1498 *MatchingHandleBuffer = HandleBufferForReturn;
1499 } else {
1500 FreePool(HandleBufferForReturn);
1501 }
1502
1503 return (EFI_SUCCESS);
1504 }
1505
1506 /**
1507 Appends 1 buffer to another buffer. This will re-allocate the destination buffer
1508 if necessary to fit all of the data.
1509
1510 If DestinationBuffer is NULL, then ASSERT().
1511
1512 @param[in, out] DestinationBuffer The pointer to the pointer to the buffer to append onto.
1513 @param[in, out] DestinationSize The pointer to the size of DestinationBuffer.
1514 @param[in] SourceBuffer The pointer to the buffer to append onto DestinationBuffer.
1515 @param[in] SourceSize The number of bytes of SourceBuffer to append.
1516
1517 @retval NULL A memory allocation failed.
1518 @retval NULL A parameter was invalid.
1519 @return A pointer to (*DestinationBuffer).
1520 **/
1521 VOID*
1522 EFIAPI
1523 BuffernCatGrow (
1524 IN OUT VOID **DestinationBuffer,
1525 IN OUT UINTN *DestinationSize,
1526 IN VOID *SourceBuffer,
1527 IN UINTN SourceSize
1528 )
1529 {
1530 UINTN LocalDestinationSize;
1531 UINTN LocalDestinationFinalSize;
1532
1533 ASSERT(DestinationBuffer != NULL);
1534
1535 if (SourceSize == 0 || SourceBuffer == NULL) {
1536 return (*DestinationBuffer);
1537 }
1538
1539 if (DestinationSize == NULL) {
1540 LocalDestinationSize = 0;
1541 } else {
1542 LocalDestinationSize = *DestinationSize;
1543 }
1544
1545 LocalDestinationFinalSize = LocalDestinationSize + SourceSize;
1546
1547 if (DestinationSize != NULL) {
1548 *DestinationSize = LocalDestinationSize;
1549 }
1550
1551 if (LocalDestinationSize == 0) {
1552 // allcoate
1553 *DestinationBuffer = AllocateZeroPool(LocalDestinationFinalSize);
1554 } else {
1555 // reallocate
1556 *DestinationBuffer = ReallocatePool(LocalDestinationSize, LocalDestinationFinalSize, *DestinationBuffer);
1557 }
1558
1559 ASSERT(*DestinationBuffer != NULL);
1560
1561 // copy
1562 return (CopyMem(((UINT8*)(*DestinationBuffer)) + LocalDestinationSize, SourceBuffer, SourceSize));
1563 }
1564
1565 /**
1566 Gets handles for any child devices produced by the passed in driver.
1567
1568 @param[in] DriverHandle The handle of the driver.
1569 @param[in] MatchingHandleCount Pointer to the number of handles in
1570 MatchingHandleBuffer on return.
1571 @param[out] MatchingHandleBuffer Buffer containing handles on a successful
1572 return.
1573 @retval EFI_SUCCESS The operation was sucessful.
1574 @sa ParseHandleDatabaseByRelationship
1575 **/
1576 EFI_STATUS
1577 EFIAPI
1578 ParseHandleDatabaseForChildDevices(
1579 IN CONST EFI_HANDLE DriverHandle,
1580 IN UINTN *MatchingHandleCount,
1581 OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL
1582 )
1583 {
1584 EFI_HANDLE *Buffer;
1585 EFI_HANDLE *Buffer2;
1586 UINTN Count1;
1587 UINTN Count2;
1588 UINTN HandleIndex;
1589 EFI_STATUS Status;
1590 UINTN HandleBufferSize;
1591
1592 ASSERT(MatchingHandleCount != NULL);
1593
1594 HandleBufferSize = 0;
1595 Buffer = NULL;
1596 Buffer2 = NULL;
1597 *MatchingHandleCount = 0;
1598
1599 Status = PARSE_HANDLE_DATABASE_DEVICES (
1600 DriverHandle,
1601 &Count1,
1602 &Buffer
1603 );
1604 if (!EFI_ERROR (Status)) {
1605 for (HandleIndex = 0; HandleIndex < Count1; HandleIndex++) {
1606 //
1607 // now find the children
1608 //
1609 Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
1610 DriverHandle,
1611 Buffer[HandleIndex],
1612 &Count2,
1613 &Buffer2
1614 );
1615 if (EFI_ERROR(Status)) {
1616 break;
1617 }
1618 //
1619 // save out required and optional data elements
1620 //
1621 *MatchingHandleCount += Count2;
1622 if (MatchingHandleBuffer != NULL) {
1623 *MatchingHandleBuffer = BuffernCatGrow((VOID**)MatchingHandleBuffer, &HandleBufferSize, Buffer2, Count2 * sizeof(Buffer2[0]));
1624 }
1625
1626 //
1627 // free the memory
1628 //
1629 if (Buffer2 != NULL) {
1630 FreePool(Buffer2);
1631 }
1632 }
1633 }
1634
1635 if (Buffer != NULL) {
1636 FreePool(Buffer);
1637 }
1638 return (Status);
1639 }
1640
1641 /**
1642 Function to get all handles that support a given protocol or all handles.
1643
1644 @param[in] ProtocolGuid The guid of the protocol to get handles for. If NULL
1645 then the function will return all handles.
1646
1647 @retval NULL A memory allocation failed.
1648 @return A NULL terminated list of handles.
1649 **/
1650 EFI_HANDLE*
1651 EFIAPI
1652 GetHandleListByProtocol (
1653 IN CONST EFI_GUID *ProtocolGuid OPTIONAL
1654 )
1655 {
1656 EFI_HANDLE *HandleList;
1657 UINTN Size;
1658 EFI_STATUS Status;
1659
1660 Size = 0;
1661 HandleList = NULL;
1662
1663 //
1664 // We cannot use LocateHandleBuffer since we need that NULL item on the ends of the list!
1665 //
1666 if (ProtocolGuid == NULL) {
1667 Status = gBS->LocateHandle(AllHandles, NULL, NULL, &Size, HandleList);
1668 if (Status == EFI_BUFFER_TOO_SMALL) {
1669 HandleList = AllocateZeroPool(Size + sizeof(EFI_HANDLE));
1670 if (HandleList == NULL) {
1671 return (NULL);
1672 }
1673 Status = gBS->LocateHandle(AllHandles, NULL, NULL, &Size, HandleList);
1674 HandleList[Size/sizeof(EFI_HANDLE)] = NULL;
1675 }
1676 } else {
1677 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)ProtocolGuid, NULL, &Size, HandleList);
1678 if (Status == EFI_BUFFER_TOO_SMALL) {
1679 HandleList = AllocateZeroPool(Size + sizeof(EFI_HANDLE));
1680 if (HandleList == NULL) {
1681 return (NULL);
1682 }
1683 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)ProtocolGuid, NULL, &Size, HandleList);
1684 HandleList[Size/sizeof(EFI_HANDLE)] = NULL;
1685 }
1686 }
1687 if (EFI_ERROR(Status)) {
1688 if (HandleList != NULL) {
1689 FreePool(HandleList);
1690 }
1691 return (NULL);
1692 }
1693 return (HandleList);
1694 }
1695
1696 /**
1697 Function to get all handles that support some protocols.
1698
1699 @param[in] ProtocolGuids A NULL terminated list of protocol GUIDs.
1700
1701 @retval NULL A memory allocation failed.
1702 @retval NULL ProtocolGuids was NULL.
1703 @return A NULL terminated list of EFI_HANDLEs.
1704 **/
1705 EFI_HANDLE*
1706 EFIAPI
1707 GetHandleListByProtocolList (
1708 IN CONST EFI_GUID **ProtocolGuids
1709 )
1710 {
1711 EFI_HANDLE *HandleList;
1712 UINTN Size;
1713 UINTN TotalSize;
1714 UINTN TempSize;
1715 EFI_STATUS Status;
1716 CONST EFI_GUID **GuidWalker;
1717 EFI_HANDLE *HandleWalker1;
1718 EFI_HANDLE *HandleWalker2;
1719
1720 Size = 0;
1721 HandleList = NULL;
1722 TotalSize = sizeof(EFI_HANDLE);
1723
1724 for (GuidWalker = ProtocolGuids ; GuidWalker != NULL && *GuidWalker != NULL ; GuidWalker++,Size = 0){
1725 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)(*GuidWalker), NULL, &Size, NULL);
1726 if (Status == EFI_BUFFER_TOO_SMALL) {
1727 TotalSize += Size;
1728 }
1729 }
1730
1731 //
1732 // No handles were found...
1733 //
1734 if (TotalSize == sizeof(EFI_HANDLE)) {
1735 return (NULL);
1736 }
1737
1738 HandleList = AllocateZeroPool(TotalSize);
1739 if (HandleList == NULL) {
1740 return (NULL);
1741 }
1742
1743 Size = 0;
1744 for (GuidWalker = ProtocolGuids ; GuidWalker != NULL && *GuidWalker != NULL ; GuidWalker++){
1745 TempSize = TotalSize - Size;
1746 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)(*GuidWalker), NULL, &TempSize, HandleList+(Size/sizeof(EFI_HANDLE)));
1747
1748 //
1749 // Allow for missing protocols... Only update the 'used' size upon success.
1750 //
1751 if (!EFI_ERROR(Status)) {
1752 Size += TempSize;
1753 }
1754 }
1755 ASSERT(HandleList[(TotalSize/sizeof(EFI_HANDLE))-1] == NULL);
1756
1757 for (HandleWalker1 = HandleList ; HandleWalker1 != NULL && *HandleWalker1 != NULL ; HandleWalker1++) {
1758 for (HandleWalker2 = HandleWalker1 + 1; HandleWalker2 != NULL && *HandleWalker2 != NULL ; HandleWalker2++) {
1759 if (*HandleWalker1 == *HandleWalker2) {
1760 //
1761 // copy memory back 1 handle width.
1762 //
1763 CopyMem(HandleWalker2, HandleWalker2 + 1, TotalSize - ((HandleWalker2-HandleList+1)*sizeof(EFI_HANDLE)));
1764 }
1765 }
1766 }
1767
1768 return (HandleList);
1769 }
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779