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