]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c
OvmfPkg/AcpiPlatformDxe: Fix Visual Studio build issues
[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)?Col:-1,
353 !EFI_ERROR(Status)?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 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText;
418 Temp = NULL;
419
420 Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID**)&DevPathToText);
421 if (!EFI_ERROR(Status)) {
422 Status = gBS->OpenProtocol(TheHandle, &gEfiDevicePathProtocolGuid, (VOID**)&DevPath, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
423 if (!EFI_ERROR(Status)) {
424 //
425 // I cannot decide whether to allow shortcuts here (the second BOOLEAN on the next line)
426 //
427 Temp = DevPathToText->ConvertDevicePathToText(DevPath, TRUE, TRUE);
428 gBS->CloseProtocol(TheHandle, &gEfiDevicePathProtocolGuid, gImageHandle, NULL);
429 }
430 }
431 if (!Verbose && Temp != NULL && StrLen(Temp) > 30) {
432 Temp2 = NULL;
433 Temp2 = StrnCatGrow(&Temp2, NULL, Temp+(StrLen(Temp) - 30), 30);
434 FreePool(Temp);
435 Temp = Temp2;
436 }
437 return (Temp);
438 }
439
440 //
441 // Put the information on the NT32 protocol GUIDs here so we are not dependant on the Nt32Pkg
442 //
443 #define LOCAL_EFI_WIN_NT_THUNK_PROTOCOL_GUID \
444 { \
445 0x58c518b1, 0x76f3, 0x11d4, 0xbc, 0xea, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 \
446 }
447
448 #define LOCAL_EFI_WIN_NT_BUS_DRIVER_IO_PROTOCOL_GUID \
449 { \
450 0x96eb4ad6, 0xa32a, 0x11d4, 0xbc, 0xfd, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 \
451 }
452
453 #define LOCAL_EFI_WIN_NT_SERIAL_PORT_GUID \
454 { \
455 0xc95a93d, 0xa006, 0x11d4, 0xbc, 0xfa, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 \
456 }
457 STATIC CONST EFI_GUID WinNtThunkProtocolGuid = LOCAL_EFI_WIN_NT_THUNK_PROTOCOL_GUID;
458 STATIC CONST EFI_GUID WinNtIoProtocolGuid = LOCAL_EFI_WIN_NT_BUS_DRIVER_IO_PROTOCOL_GUID;
459 STATIC CONST EFI_GUID WinNtSerialPortGuid = LOCAL_EFI_WIN_NT_SERIAL_PORT_GUID;
460
461 STATIC CONST GUID_INFO_BLOCK mGuidStringListNT[] = {
462 {STRING_TOKEN(STR_WINNT_THUNK), (EFI_GUID*)&WinNtThunkProtocolGuid, NULL},
463 {STRING_TOKEN(STR_WINNT_DRIVER_IO), (EFI_GUID*)&WinNtIoProtocolGuid, NULL},
464 {STRING_TOKEN(STR_WINNT_SERIAL_PORT), (EFI_GUID*)&WinNtSerialPortGuid, NULL},
465 {STRING_TOKEN(STR_UNKNOWN_DEVICE), NULL, NULL},
466 };
467
468 STATIC CONST GUID_INFO_BLOCK mGuidStringList[] = {
469 {STRING_TOKEN(STR_LOADED_IMAGE), &gEfiLoadedImageProtocolGuid, NULL},
470 {STRING_TOKEN(STR_DEVICE_PATH), &gEfiDevicePathProtocolGuid, DevicePathProtocolDumpInformation},
471 {STRING_TOKEN(STR_IMAGE_PATH), &gEfiLoadedImageDevicePathProtocolGuid, DevicePathProtocolDumpInformation},
472 {STRING_TOKEN(STR_DEVICE_PATH_UTIL), &gEfiDevicePathUtilitiesProtocolGuid, NULL},
473 {STRING_TOKEN(STR_DEVICE_PATH_TXT), &gEfiDevicePathToTextProtocolGuid, NULL},
474 {STRING_TOKEN(STR_DEVICE_PATH_FTXT), &gEfiDevicePathFromTextProtocolGuid, NULL},
475 {STRING_TOKEN(STR_DEVICE_PATH_PC), &gEfiPcAnsiGuid, NULL},
476 {STRING_TOKEN(STR_DEVICE_PATH_VT100), &gEfiVT100Guid, NULL},
477 {STRING_TOKEN(STR_DEVICE_PATH_VT100P), &gEfiVT100PlusGuid, NULL},
478 {STRING_TOKEN(STR_DEVICE_PATH_VTUTF8), &gEfiVTUTF8Guid, NULL},
479 {STRING_TOKEN(STR_DRIVER_BINDING), &gEfiDriverBindingProtocolGuid, NULL},
480 {STRING_TOKEN(STR_PLATFORM_OVERRIDE), &gEfiPlatformDriverOverrideProtocolGuid, NULL},
481 {STRING_TOKEN(STR_BUS_OVERRIDE), &gEfiBusSpecificDriverOverrideProtocolGuid, NULL},
482 {STRING_TOKEN(STR_DRIVER_DIAG), &gEfiDriverDiagnosticsProtocolGuid, NULL},
483 {STRING_TOKEN(STR_DRIVER_DIAG2), &gEfiDriverDiagnostics2ProtocolGuid, NULL},
484 {STRING_TOKEN(STR_DRIVER_CN), &gEfiComponentNameProtocolGuid, NULL},
485 {STRING_TOKEN(STR_DRIVER_CN2), &gEfiComponentName2ProtocolGuid, NULL},
486 {STRING_TOKEN(STR_PLAT_DRV_CFG), &gEfiPlatformToDriverConfigurationProtocolGuid, NULL},
487 {STRING_TOKEN(STR_DRIVER_VERSION), &gEfiDriverSupportedEfiVersionProtocolGuid, DriverEfiVersionProtocolDumpInformation},
488 {STRING_TOKEN(STR_TXT_IN), &gEfiSimpleTextInProtocolGuid, NULL},
489 {STRING_TOKEN(STR_TXT_IN_EX), &gEfiSimpleTextInputExProtocolGuid, NULL},
490 {STRING_TOKEN(STR_TXT_OUT), &gEfiSimpleTextOutProtocolGuid, TxtOutProtocolDumpInformation},
491 {STRING_TOKEN(STR_SIM_POINTER), &gEfiSimplePointerProtocolGuid, NULL},
492 {STRING_TOKEN(STR_ABS_POINTER), &gEfiAbsolutePointerProtocolGuid, NULL},
493 {STRING_TOKEN(STR_SERIAL_IO), &gEfiSerialIoProtocolGuid, NULL},
494 {STRING_TOKEN(STR_GRAPHICS_OUTPUT), &gEfiGraphicsOutputProtocolGuid, NULL},
495 {STRING_TOKEN(STR_EDID_DISCOVERED), &gEfiEdidDiscoveredProtocolGuid, NULL},
496 {STRING_TOKEN(STR_EDID_ACTIVE), &gEfiEdidActiveProtocolGuid, NULL},
497 {STRING_TOKEN(STR_EDID_OVERRIDE), &gEfiEdidOverrideProtocolGuid, NULL},
498 {STRING_TOKEN(STR_CON_IN), &gEfiConsoleInDeviceGuid, NULL},
499 {STRING_TOKEN(STR_CON_OUT), &gEfiConsoleOutDeviceGuid, NULL},
500 {STRING_TOKEN(STR_STD_ERR), &gEfiStandardErrorDeviceGuid, NULL},
501 {STRING_TOKEN(STR_LOAD_FILE), &gEfiLoadFileProtocolGuid, NULL},
502 {STRING_TOKEN(STR_LOAD_FILE2), &gEfiLoadFile2ProtocolGuid, NULL},
503 {STRING_TOKEN(STR_SIMPLE_FILE_SYS), &gEfiSimpleFileSystemProtocolGuid, NULL},
504 {STRING_TOKEN(STR_TAPE_IO), &gEfiTapeIoProtocolGuid, NULL},
505 {STRING_TOKEN(STR_DISK_IO), &gEfiDiskIoProtocolGuid, NULL},
506 {STRING_TOKEN(STR_BLK_IO), &gEfiBlockIoProtocolGuid, NULL},
507 {STRING_TOKEN(STR_UC), &gEfiUnicodeCollationProtocolGuid, NULL},
508 {STRING_TOKEN(STR_UC2), &gEfiUnicodeCollation2ProtocolGuid, NULL},
509 {STRING_TOKEN(STR_PCIRB_IO), &gEfiPciRootBridgeIoProtocolGuid, PciRootBridgeIoDumpInformation},
510 {STRING_TOKEN(STR_PCI_IO), &gEfiPciIoProtocolGuid, NULL},
511 {STRING_TOKEN(STR_SCSI_PT), &gEfiScsiPassThruProtocolGuid, NULL},
512 {STRING_TOKEN(STR_SCSI_IO), &gEfiScsiIoProtocolGuid, NULL},
513 {STRING_TOKEN(STR_SCSI_PT_EXT), &gEfiExtScsiPassThruProtocolGuid, NULL},
514 {STRING_TOKEN(STR_ISCSI), &gEfiIScsiInitiatorNameProtocolGuid, NULL},
515 {STRING_TOKEN(STR_USB_IO), &gEfiUsbIoProtocolGuid, NULL},
516 {STRING_TOKEN(STR_USB_HC), &gEfiUsbHcProtocolGuid, NULL},
517 {STRING_TOKEN(STR_USB_HC2), &gEfiUsb2HcProtocolGuid, NULL},
518 {STRING_TOKEN(STR_DEBUG_SUPPORT), &gEfiDebugSupportProtocolGuid, NULL},
519 {STRING_TOKEN(STR_DEBUG_PORT), &gEfiDebugPortProtocolGuid, NULL},
520 {STRING_TOKEN(STR_DECOMPRESS), &gEfiDecompressProtocolGuid, NULL},
521 {STRING_TOKEN(STR_ACPI_TABLE), &gEfiAcpiTableProtocolGuid, NULL},
522 {STRING_TOKEN(STR_EBC_INTERPRETER), &gEfiEbcProtocolGuid, NULL},
523 {STRING_TOKEN(STR_SNP), &gEfiSimpleNetworkProtocolGuid, NULL},
524 {STRING_TOKEN(STR_NII), &gEfiNetworkInterfaceIdentifierProtocolGuid, NULL},
525 {STRING_TOKEN(STR_NII_31), &gEfiNetworkInterfaceIdentifierProtocolGuid_31, NULL},
526 {STRING_TOKEN(STR_PXE_BC), &gEfiPxeBaseCodeProtocolGuid, NULL},
527 {STRING_TOKEN(STR_PXE_CB), &gEfiPxeBaseCodeCallbackProtocolGuid, NULL},
528 {STRING_TOKEN(STR_BIS), &gEfiBisProtocolGuid, NULL},
529 {STRING_TOKEN(STR_MNP_SB), &gEfiManagedNetworkServiceBindingProtocolGuid, NULL},
530 {STRING_TOKEN(STR_MNP), &gEfiManagedNetworkProtocolGuid, NULL},
531 {STRING_TOKEN(STR_ARP_SB), &gEfiArpServiceBindingProtocolGuid, NULL},
532 {STRING_TOKEN(STR_ARP), &gEfiArpProtocolGuid, NULL},
533 {STRING_TOKEN(STR_DHCPV4_SB), &gEfiDhcp4ServiceBindingProtocolGuid, NULL},
534 {STRING_TOKEN(STR_DHCPV4), &gEfiDhcp4ProtocolGuid, NULL},
535 {STRING_TOKEN(STR_TCPV4_SB), &gEfiTcp4ServiceBindingProtocolGuid, NULL},
536 {STRING_TOKEN(STR_TCPV4), &gEfiTcp4ProtocolGuid, NULL},
537 {STRING_TOKEN(STR_IPV4_SB), &gEfiIp4ServiceBindingProtocolGuid, NULL},
538 {STRING_TOKEN(STR_IPV4), &gEfiIp4ProtocolGuid, NULL},
539 {STRING_TOKEN(STR_IPV4_CFG), &gEfiIp4ConfigProtocolGuid, NULL},
540 {STRING_TOKEN(STR_SHELL_PARAMETERS), &gEfiShellParametersProtocolGuid, NULL},
541 {STRING_TOKEN(STR_SHELL), &gEfiShellProtocolGuid, NULL},
542 {STRING_TOKEN(STR_UDPV4_SB), &gEfiUdp4ServiceBindingProtocolGuid, NULL},
543 {STRING_TOKEN(STR_UDPV4), &gEfiUdp4ProtocolGuid, NULL},
544 {STRING_TOKEN(STR_MTFTPV4_SB), &gEfiMtftp4ServiceBindingProtocolGuid, NULL},
545 {STRING_TOKEN(STR_MTFTPV4), &gEfiMtftp4ProtocolGuid, NULL},
546 {STRING_TOKEN(STR_AUTH_INFO), &gEfiAuthenticationInfoProtocolGuid, NULL},
547 {STRING_TOKEN(STR_HASH_SB), &gEfiHashServiceBindingProtocolGuid, NULL},
548 {STRING_TOKEN(STR_HASH), &gEfiHashProtocolGuid, NULL},
549 {STRING_TOKEN(STR_HII_FONT), &gEfiHiiFontProtocolGuid, NULL},
550 {STRING_TOKEN(STR_HII_STRING), &gEfiHiiStringProtocolGuid, NULL},
551 {STRING_TOKEN(STR_HII_IMAGE), &gEfiHiiImageProtocolGuid, NULL},
552 {STRING_TOKEN(STR_HII_DATABASE), &gEfiHiiDatabaseProtocolGuid, NULL},
553 {STRING_TOKEN(STR_HII_CONFIG_ROUT), &gEfiHiiConfigRoutingProtocolGuid, NULL},
554 {STRING_TOKEN(STR_HII_CONFIG_ACC), &gEfiHiiConfigAccessProtocolGuid, NULL},
555 {STRING_TOKEN(STR_HII_FORM_BROWSER2), &gEfiFormBrowser2ProtocolGuid, NULL},
556 {STRING_TOKEN(STR_DRIVER_FAM_OVERRIDE), &gEfiDriverFamilyOverrideProtocolGuid, NULL},
557 {STRING_TOKEN(STR_PCD), &gPcdProtocolGuid, NULL},
558 {STRING_TOKEN(STR_TCG), &gEfiTcgProtocolGuid, NULL},
559 {STRING_TOKEN(STR_HII_PACKAGE_LIST), &gEfiHiiPackageListProtocolGuid, NULL},
560
561 //
562 // the ones under this are deprecated by the current UEFI Spec, but may be found anyways...
563 //
564 {STRING_TOKEN(STR_SHELL_INTERFACE), &gEfiShellInterfaceGuid, NULL},
565 {STRING_TOKEN(STR_SHELL_ENV2), &gEfiShellEnvironment2Guid, NULL},
566 {STRING_TOKEN(STR_SHELL_ENV), &gEfiShellEnvironment2Guid, NULL},
567 {STRING_TOKEN(STR_DEVICE_IO), &gEfiDeviceIoProtocolGuid, NULL},
568 {STRING_TOKEN(STR_UGA_DRAW), &gEfiUgaDrawProtocolGuid, NULL},
569 {STRING_TOKEN(STR_UGA_IO), &gEfiUgaIoProtocolGuid, NULL},
570 {STRING_TOKEN(STR_ESP), &gEfiPartTypeSystemPartGuid, NULL},
571 {STRING_TOKEN(STR_GPT_NBR), &gEfiPartTypeLegacyMbrGuid, NULL},
572 {STRING_TOKEN(STR_DRIVER_CONFIG), &gEfiDriverConfigurationProtocolGuid, NULL},
573 {STRING_TOKEN(STR_DRIVER_CONFIG2), &gEfiDriverConfiguration2ProtocolGuid, NULL},
574
575 //
576 // the ones under this are GUID identified structs, not protocols
577 //
578 {STRING_TOKEN(STR_FILE_INFO), &gEfiFileInfoGuid, NULL},
579 {STRING_TOKEN(STR_FILE_SYS_INFO), &gEfiFileSystemInfoGuid, NULL},
580
581 //
582 // the ones under this are misc GUIDS.
583 //
584 {STRING_TOKEN(STR_EFI_GLOBAL_VARIABLE), &gEfiGlobalVariableGuid, NULL},
585
586 //
587 // UEFI 2.2
588 //
589 {STRING_TOKEN(STR_IP6_SB), &gEfiIp6ServiceBindingProtocolGuid, NULL},
590 {STRING_TOKEN(STR_IP6), &gEfiIp6ProtocolGuid, NULL},
591 {STRING_TOKEN(STR_IP6_CONFIG), &gEfiIp6ConfigProtocolGuid, NULL},
592 {STRING_TOKEN(STR_MTFTP6_SB), &gEfiMtftp6ServiceBindingProtocolGuid, NULL},
593 {STRING_TOKEN(STR_MTFTP6), &gEfiMtftp6ProtocolGuid, NULL},
594 {STRING_TOKEN(STR_DHCP6_SB), &gEfiDhcp6ServiceBindingProtocolGuid, NULL},
595 {STRING_TOKEN(STR_DHCP6), &gEfiDhcp6ProtocolGuid, NULL},
596 {STRING_TOKEN(STR_UDP6_SB), &gEfiUdp6ServiceBindingProtocolGuid, NULL},
597 {STRING_TOKEN(STR_UDP6), &gEfiUdp6ProtocolGuid, NULL},
598 {STRING_TOKEN(STR_TCP6_SB), &gEfiTcp6ServiceBindingProtocolGuid, NULL},
599 {STRING_TOKEN(STR_TCP6), &gEfiTcp6ProtocolGuid, NULL},
600 {STRING_TOKEN(STR_VLAN_CONFIG), &gEfiVlanConfigProtocolGuid, NULL},
601 {STRING_TOKEN(STR_EAP), &gEfiEapProtocolGuid, NULL},
602 {STRING_TOKEN(STR_EAP_MGMT), &gEfiEapManagementProtocolGuid, NULL},
603 {STRING_TOKEN(STR_FTP4_SB), &gEfiFtp4ServiceBindingProtocolGuid, NULL},
604 {STRING_TOKEN(STR_FTP4), &gEfiFtp4ProtocolGuid, NULL},
605 {STRING_TOKEN(STR_IP_SEC_CONFIG), &gEfiIpSecConfigProtocolGuid, NULL},
606 {STRING_TOKEN(STR_DH), &gEfiDriverHealthProtocolGuid, NULL},
607 {STRING_TOKEN(STR_DEF_IMG_LOAD), &gEfiDeferredImageLoadProtocolGuid, NULL},
608 {STRING_TOKEN(STR_USER_CRED), &gEfiUserCredentialProtocolGuid, NULL},
609 {STRING_TOKEN(STR_USER_MNGR), &gEfiUserManagerProtocolGuid, NULL},
610 {STRING_TOKEN(STR_ATA_PASS_THRU), &gEfiAtaPassThruProtocolGuid, NULL},
611
612 //
613 // UEFI 2.3
614 //
615 {STRING_TOKEN(STR_FW_MGMT), &gEfiFirmwareManagementProtocolGuid, NULL},
616 {STRING_TOKEN(STR_IP_SEC), &gEfiIpSecProtocolGuid, NULL},
617 {STRING_TOKEN(STR_IP_SEC2), &gEfiIpSec2ProtocolGuid, NULL},
618
619 //
620 // UEFI 2.3.1
621 //
622 {STRING_TOKEN(STR_KMS), &gEfiKmsProtocolGuid, NULL},
623 {STRING_TOKEN(STR_BLK_IO2), &gEfiBlockIo2ProtocolGuid, NULL},
624 {STRING_TOKEN(STR_SSC), &gEfiStorageSecurityCommandProtocolGuid, NULL},
625 {STRING_TOKEN(STR_UC2), &gEfiUserCredential2ProtocolGuid, NULL},
626
627 //
628 // terminator
629 //
630 {STRING_TOKEN(STR_UNKNOWN_DEVICE), NULL, NULL},
631 };
632
633 /**
634 Function to get the node for a protocol or struct from it's GUID.
635
636 if Guid is NULL, then ASSERT.
637
638 @param[in] Guid The GUID to look for the name of.
639
640 @return The node.
641 **/
642 CONST GUID_INFO_BLOCK *
643 EFIAPI
644 InternalShellGetNodeFromGuid(
645 IN CONST EFI_GUID* Guid
646 )
647 {
648 CONST GUID_INFO_BLOCK *ListWalker;
649
650 ASSERT(Guid != NULL);
651
652 if (PcdGetBool(PcdShellIncludeNtGuids)) {
653 for (ListWalker = mGuidStringListNT ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {
654 if (CompareGuid(ListWalker->GuidId, Guid)) {
655 return (ListWalker);
656 }
657 }
658 }
659 for (ListWalker = mGuidStringList ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {
660 if (CompareGuid(ListWalker->GuidId, Guid)) {
661 return (ListWalker);
662 }
663 }
664 return (ListWalker);
665 }
666
667 /**
668 Function to get the name of a protocol or struct from it's GUID.
669
670 if Guid is NULL, then ASSERT.
671
672 @param[in] Guid The GUID to look for the name of.
673 @param[in] Lang The language to use.
674
675 @return pointer to string of the name. The caller
676 is responsible to free this memory.
677 **/
678 CHAR16*
679 EFIAPI
680 GetStringNameFromGuid(
681 IN CONST EFI_GUID *Guid,
682 IN CONST CHAR8 *Lang OPTIONAL
683 )
684 {
685 CONST GUID_INFO_BLOCK *Id;
686
687 Id = InternalShellGetNodeFromGuid(Guid);
688 return (HiiGetString(mHandleParsingHiiHandle, Id->StringId, Lang));
689 }
690
691 /**
692 Function to dump protocol information from a handle.
693
694 This function will return a allocated string buffer containing the
695 information. The caller is responsible for freeing the memory.
696
697 If Guid is NULL, ASSERT().
698 If TheHandle is NULL, ASSERT().
699
700 @param[in] TheHandle The handle to dump information from.
701 @param[in] Guid The GUID of the protocol to dump.
702 @param[in] Verbose TRUE for extra info. FALSE otherwise.
703
704 @return The pointer to string.
705 @retval NULL An error was encountered.
706 **/
707 CHAR16*
708 EFIAPI
709 GetProtocolInformationDump(
710 IN CONST EFI_HANDLE TheHandle,
711 IN CONST EFI_GUID *Guid,
712 IN CONST BOOLEAN Verbose
713 )
714 {
715 CONST GUID_INFO_BLOCK *Id;
716
717 ASSERT(TheHandle != NULL);
718 ASSERT(Guid != NULL);
719
720 if (TheHandle == NULL || Guid == NULL) {
721 return (NULL);
722 }
723
724 Id = InternalShellGetNodeFromGuid(Guid);
725 if (Id != NULL && Id->DumpInfo != NULL) {
726 return (Id->DumpInfo(TheHandle, Verbose));
727 }
728 return (NULL);
729 }
730
731 /**
732 Function to get the Guid for a protocol or struct based on it's string name.
733
734 @param[in] Name The pointer to the string name.
735 @param[in] Lang The pointer to the language code.
736 @param[in] Guid The pointer to the Guid.
737
738 @retval EFI_SUCCESS The operation was sucessful.
739 **/
740 EFI_STATUS
741 EFIAPI
742 GetGuidFromStringName(
743 IN CONST CHAR16 *Name,
744 IN CONST CHAR8 *Lang OPTIONAL,
745 IN EFI_GUID **Guid
746 )
747 {
748 CONST GUID_INFO_BLOCK *ListWalker;
749 CHAR16 *String;
750
751 ASSERT(Guid != NULL);
752 if (Guid == NULL) {
753 return (EFI_INVALID_PARAMETER);
754 }
755 *Guid = NULL;
756
757 if (PcdGetBool(PcdShellIncludeNtGuids)) {
758 for (ListWalker = mGuidStringListNT ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {
759 String = HiiGetString(mHandleParsingHiiHandle, ListWalker->StringId, Lang);
760 if (Name != NULL && String != NULL && StrCmp(Name, String)==0) {
761 *Guid = ListWalker->GuidId;
762 }
763 SHELL_FREE_NON_NULL(String);
764 if (*Guid != NULL) {
765 return (EFI_SUCCESS);
766 }
767 }
768 }
769 for (ListWalker = mGuidStringList ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {
770 String = HiiGetString(mHandleParsingHiiHandle, ListWalker->StringId, Lang);
771 if (Name != NULL && String != NULL && StrCmp(Name, String)==0) {
772 *Guid = ListWalker->GuidId;
773 }
774 SHELL_FREE_NON_NULL(String);
775 if (*Guid != NULL) {
776 return (EFI_SUCCESS);
777 }
778 }
779 return (EFI_NOT_FOUND);
780 }
781
782 /**
783 Function to retrieve the driver name (if possible) from the ComponentName or
784 ComponentName2 protocol
785
786 @param[in] TheHandle The driver handle to get the name of.
787 @param[in] Language The language to use.
788
789 @retval NULL The name could not be found.
790 @return A pointer to the string name. Do not de-allocate the memory.
791 **/
792 CONST CHAR16*
793 EFIAPI
794 GetStringNameFromHandle(
795 IN CONST EFI_HANDLE TheHandle,
796 IN CONST CHAR8 *Language
797 )
798 {
799 EFI_COMPONENT_NAME2_PROTOCOL *CompNameStruct;
800 EFI_STATUS Status;
801 CHAR16 *RetVal;
802
803 Status = gBS->OpenProtocol(
804 TheHandle,
805 &gEfiComponentName2ProtocolGuid,
806 (VOID**)&CompNameStruct,
807 gImageHandle,
808 NULL,
809 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
810 if (!EFI_ERROR(Status)) {
811 Status = CompNameStruct->GetDriverName(CompNameStruct, (CHAR8*)Language, &RetVal);
812 if (!EFI_ERROR(Status)) {
813 return (RetVal);
814 }
815 }
816 Status = gBS->OpenProtocol(
817 TheHandle,
818 &gEfiComponentNameProtocolGuid,
819 (VOID**)&CompNameStruct,
820 gImageHandle,
821 NULL,
822 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
823 if (!EFI_ERROR(Status)) {
824 Status = CompNameStruct->GetDriverName(CompNameStruct, (CHAR8*)Language, &RetVal);
825 if (!EFI_ERROR(Status)) {
826 return (RetVal);
827 }
828 }
829 return (NULL);
830 }
831
832 /**
833 Function to initialize the file global mHandleList object for use in
834 vonverting handles to index and index to handle.
835
836 @retval EFI_SUCCESS The operation was successful.
837 **/
838 EFI_STATUS
839 EFIAPI
840 InternalShellInitHandleList(
841 VOID
842 )
843 {
844 EFI_STATUS Status;
845 EFI_HANDLE *HandleBuffer;
846 UINTN HandleCount;
847 HANDLE_LIST *ListWalker;
848
849 if (mHandleList.NextIndex != 0) {
850 return EFI_SUCCESS;
851 }
852 InitializeListHead(&mHandleList.List.Link);
853 mHandleList.NextIndex = 1;
854 Status = gBS->LocateHandleBuffer (
855 AllHandles,
856 NULL,
857 NULL,
858 &HandleCount,
859 &HandleBuffer
860 );
861 ASSERT_EFI_ERROR(Status);
862 if (EFI_ERROR(Status)) {
863 return (Status);
864 }
865 for (mHandleList.NextIndex = 1 ; mHandleList.NextIndex <= HandleCount ; mHandleList.NextIndex++){
866 ListWalker = AllocateZeroPool(sizeof(HANDLE_LIST));
867 ASSERT(ListWalker != NULL);
868 ListWalker->TheHandle = HandleBuffer[mHandleList.NextIndex-1];
869 ListWalker->TheIndex = mHandleList.NextIndex;
870 InsertTailList(&mHandleList.List.Link,&ListWalker->Link);
871 }
872 FreePool(HandleBuffer);
873 return (EFI_SUCCESS);
874 }
875
876 /**
877 Function to retrieve the human-friendly index of a given handle. If the handle
878 does not have a index one will be automatically assigned. The index value is valid
879 until the termination of the shell application.
880
881 @param[in] TheHandle The handle to retrieve an index for.
882
883 @retval 0 A memory allocation failed.
884 @return The index of the handle.
885
886 **/
887 UINTN
888 EFIAPI
889 ConvertHandleToHandleIndex(
890 IN CONST EFI_HANDLE TheHandle
891 )
892 {
893 HANDLE_LIST *ListWalker;
894 if (TheHandle == NULL) {
895 return 0;
896 }
897
898 InternalShellInitHandleList();
899
900 for (ListWalker = (HANDLE_LIST*)GetFirstNode(&mHandleList.List.Link)
901 ; !IsNull(&mHandleList.List.Link,&ListWalker->Link)
902 ; ListWalker = (HANDLE_LIST*)GetNextNode(&mHandleList.List.Link,&ListWalker->Link)
903 ){
904 if (ListWalker->TheHandle == TheHandle) {
905 return (ListWalker->TheIndex);
906 }
907 }
908 ListWalker = AllocateZeroPool(sizeof(HANDLE_LIST));
909 ASSERT(ListWalker != NULL);
910 ListWalker->TheHandle = TheHandle;
911 ListWalker->TheIndex = mHandleList.NextIndex++;
912 InsertTailList(&mHandleList.List.Link,&ListWalker->Link);
913 return (ListWalker->TheIndex);
914 }
915
916
917
918 /**
919 Function to retrieve the EFI_HANDLE from the human-friendly index.
920
921 @param[in] TheIndex The index to retrieve the EFI_HANDLE for.
922
923 @retval NULL The index was invalid.
924 @return The EFI_HANDLE that index represents.
925
926 **/
927 EFI_HANDLE
928 EFIAPI
929 ConvertHandleIndexToHandle(
930 IN CONST UINTN TheIndex
931 )
932 {
933 HANDLE_LIST *ListWalker;
934
935 InternalShellInitHandleList();
936
937 if (TheIndex >= mHandleList.NextIndex) {
938 return (NULL);
939 }
940
941 for (ListWalker = (HANDLE_LIST*)GetFirstNode(&mHandleList.List.Link)
942 ; !IsNull(&mHandleList.List.Link,&ListWalker->Link)
943 ; ListWalker = (HANDLE_LIST*)GetNextNode(&mHandleList.List.Link,&ListWalker->Link)
944 ){
945 if (ListWalker->TheIndex == TheIndex) {
946 return (ListWalker->TheHandle);
947 }
948 }
949 return (NULL);
950 }
951
952 /**
953 Gets all the related EFI_HANDLEs based on the mask supplied.
954
955 This function scans all EFI_HANDLES in the UEFI environment's handle database
956 and returns the ones with the specified relationship (Mask) to the specified
957 controller handle.
958
959 If both DriverBindingHandle and ControllerHandle are NULL, then ASSERT.
960 If MatchingHandleCount is NULL, then ASSERT.
961
962 If MatchingHandleBuffer is not NULL upon a successful return the memory must be
963 caller freed.
964
965 @param[in] DriverBindingHandle The handle with Driver Binding protocol on it.
966 @param[in] ControllerHandle The handle with Device Path protocol on it.
967 @param[in] MatchingHandleCount The pointer to UINTN that specifies the number of HANDLES in
968 MatchingHandleBuffer.
969 @param[out] MatchingHandleBuffer On a successful return, a buffer of MatchingHandleCount
970 EFI_HANDLEs with a terminating NULL EFI_HANDLE.
971 @param[out] HandleType An array of type information.
972
973 @retval EFI_SUCCESS The operation was successful, and any related handles
974 are in MatchingHandleBuffer.
975 @retval EFI_NOT_FOUND No matching handles were found.
976 @retval EFI_INVALID_PARAMETER A parameter was invalid or out of range.
977 **/
978 EFI_STATUS
979 EFIAPI
980 ParseHandleDatabaseByRelationshipWithType (
981 IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL,
982 IN CONST EFI_HANDLE ControllerHandle OPTIONAL,
983 IN UINTN *HandleCount,
984 OUT EFI_HANDLE **HandleBuffer,
985 OUT UINTN **HandleType
986 )
987 {
988 EFI_STATUS Status;
989 UINTN HandleIndex;
990 EFI_GUID **ProtocolGuidArray;
991 UINTN ArrayCount;
992 UINTN ProtocolIndex;
993 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;
994 UINTN OpenInfoCount;
995 UINTN OpenInfoIndex;
996 UINTN ChildIndex;
997
998 ASSERT(HandleCount != NULL);
999 ASSERT(HandleBuffer != NULL);
1000 ASSERT(HandleType != NULL);
1001 ASSERT(DriverBindingHandle != NULL || ControllerHandle != NULL);
1002
1003 *HandleCount = 0;
1004 *HandleBuffer = NULL;
1005 *HandleType = NULL;
1006
1007 //
1008 // Retrieve the list of all handles from the handle database
1009 //
1010 Status = gBS->LocateHandleBuffer (
1011 AllHandles,
1012 NULL,
1013 NULL,
1014 HandleCount,
1015 HandleBuffer
1016 );
1017 if (EFI_ERROR (Status)) {
1018 return (Status);
1019 }
1020
1021 *HandleType = AllocateZeroPool (*HandleCount * sizeof (UINTN));
1022 ASSERT(*HandleType != NULL);
1023
1024 for (HandleIndex = 0; HandleIndex < *HandleCount; HandleIndex++) {
1025 //
1026 // Retrieve the list of all the protocols on each handle
1027 //
1028 Status = gBS->ProtocolsPerHandle (
1029 (*HandleBuffer)[HandleIndex],
1030 &ProtocolGuidArray,
1031 &ArrayCount
1032 );
1033 if (!EFI_ERROR (Status)) {
1034
1035 for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
1036
1037 //
1038 // Set the bit describing what this handle has
1039 //
1040 if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiLoadedImageProtocolGuid) ) {
1041 (*HandleType)[HandleIndex] |= HR_IMAGE_HANDLE;
1042 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverBindingProtocolGuid) ) {
1043 (*HandleType)[HandleIndex] |= HR_DRIVER_BINDING_HANDLE;
1044 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverConfiguration2ProtocolGuid)) {
1045 (*HandleType)[HandleIndex] |= HR_DRIVER_CONFIGURATION_HANDLE;
1046 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverConfigurationProtocolGuid) ) {
1047 (*HandleType)[HandleIndex] |= HR_DRIVER_CONFIGURATION_HANDLE;
1048 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverDiagnostics2ProtocolGuid) ) {
1049 (*HandleType)[HandleIndex] |= HR_DRIVER_DIAGNOSTICS_HANDLE;
1050 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverDiagnosticsProtocolGuid) ) {
1051 (*HandleType)[HandleIndex] |= HR_DRIVER_DIAGNOSTICS_HANDLE;
1052 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentName2ProtocolGuid) ) {
1053 (*HandleType)[HandleIndex] |= HR_COMPONENT_NAME_HANDLE;
1054 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentNameProtocolGuid) ) {
1055 (*HandleType)[HandleIndex] |= HR_COMPONENT_NAME_HANDLE;
1056 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDevicePathProtocolGuid) ) {
1057 (*HandleType)[HandleIndex] |= HR_DEVICE_HANDLE;
1058 } else {
1059 DEBUG_CODE_BEGIN();
1060 ASSERT((*HandleType)[HandleIndex] == (*HandleType)[HandleIndex]);
1061 DEBUG_CODE_END();
1062 }
1063 //
1064 // Retrieve the list of agents that have opened each protocol
1065 //
1066 Status = gBS->OpenProtocolInformation (
1067 (*HandleBuffer)[HandleIndex],
1068 ProtocolGuidArray[ProtocolIndex],
1069 &OpenInfo,
1070 &OpenInfoCount
1071 );
1072 if (!EFI_ERROR (Status)) {
1073 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
1074 if (DriverBindingHandle != NULL && OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) {
1075 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) == EFI_OPEN_PROTOCOL_BY_DRIVER) {
1076 (*HandleType)[HandleIndex] |= (HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);
1077 }
1078 if (ControllerHandle != NULL && (*HandleBuffer)[HandleIndex] == ControllerHandle) {
1079 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {
1080 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
1081 if ((*HandleBuffer)[ChildIndex] == OpenInfo[OpenInfoIndex].ControllerHandle) {
1082 (*HandleType)[ChildIndex] |= (HR_DEVICE_HANDLE | HR_CHILD_HANDLE);
1083 }
1084 }
1085 }
1086 }
1087 }
1088 if (DriverBindingHandle == NULL && OpenInfo[OpenInfoIndex].ControllerHandle == ControllerHandle) {
1089 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) == EFI_OPEN_PROTOCOL_BY_DRIVER) {
1090 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
1091 if ((*HandleBuffer)[ChildIndex] == OpenInfo[OpenInfoIndex].AgentHandle) {
1092 (*HandleType)[ChildIndex] |= HR_DEVICE_DRIVER;
1093 }
1094 }
1095 }
1096 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {
1097 (*HandleType)[HandleIndex] |= HR_PARENT_HANDLE;
1098 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
1099 if ((*HandleBuffer)[ChildIndex] == OpenInfo[OpenInfoIndex].AgentHandle) {
1100 (*HandleType)[ChildIndex] |= HR_BUS_DRIVER;
1101 }
1102 }
1103 }
1104 }
1105 }
1106
1107 FreePool (OpenInfo);
1108 }
1109 }
1110
1111 FreePool (ProtocolGuidArray);
1112 }
1113 }
1114
1115 if (EFI_ERROR(Status)) {
1116 if (*HandleType != NULL) {
1117 FreePool (*HandleType);
1118 }
1119 if (*HandleBuffer != NULL) {
1120 FreePool (*HandleBuffer);
1121 }
1122
1123 *HandleCount = 0;
1124 *HandleBuffer = NULL;
1125 *HandleType = NULL;
1126 }
1127
1128 return Status;
1129 }
1130
1131 /**
1132 Gets all the related EFI_HANDLEs based on the single EFI_HANDLE and the mask
1133 supplied.
1134
1135 This function will scan all EFI_HANDLES in the UEFI environment's handle database
1136 and return all the ones with the specified relationship (Mask) to the specified
1137 controller handle.
1138
1139 If both DriverBindingHandle and ControllerHandle are NULL, then ASSERT.
1140 If MatchingHandleCount is NULL, then ASSERT.
1141
1142 If MatchingHandleBuffer is not NULL upon a sucessful return the memory must be
1143 caller freed.
1144
1145 @param[in] DriverBindingHandle Handle to a object with Driver Binding protocol
1146 on it.
1147 @param[in] ControllerHandle Handle to a device with Device Path protocol on it.
1148 @param[in] Mask Mask of what relationship(s) is desired.
1149 @param[in] MatchingHandleCount Poitner to UINTN specifying number of HANDLES in
1150 MatchingHandleBuffer.
1151 @param[out] MatchingHandleBuffer On a sucessful return a buffer of MatchingHandleCount
1152 EFI_HANDLEs and a terminating NULL EFI_HANDLE.
1153
1154 @retval EFI_SUCCESS The operation was sucessful and any related handles
1155 are in MatchingHandleBuffer;
1156 @retval EFI_NOT_FOUND No matching handles were found.
1157 @retval EFI_INVALID_PARAMETER A parameter was invalid or out of range.
1158 **/
1159 EFI_STATUS
1160 EFIAPI
1161 ParseHandleDatabaseByRelationship (
1162 IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL,
1163 IN CONST EFI_HANDLE ControllerHandle OPTIONAL,
1164 IN CONST UINTN Mask,
1165 IN UINTN *MatchingHandleCount,
1166 OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL
1167 )
1168 {
1169 EFI_STATUS Status;
1170 UINTN HandleCount;
1171 EFI_HANDLE *HandleBuffer;
1172 UINTN *HandleType;
1173 UINTN HandleIndex;
1174
1175 ASSERT(MatchingHandleCount != NULL);
1176 ASSERT(DriverBindingHandle != NULL || ControllerHandle != NULL);
1177
1178 if ((Mask & HR_VALID_MASK) != Mask) {
1179 return (EFI_INVALID_PARAMETER);
1180 }
1181
1182 if ((Mask & HR_CHILD_HANDLE) != 0 && DriverBindingHandle == NULL) {
1183 return (EFI_INVALID_PARAMETER);
1184 }
1185
1186 *MatchingHandleCount = 0;
1187 if (MatchingHandleBuffer != NULL) {
1188 *MatchingHandleBuffer = NULL;
1189 }
1190
1191 HandleBuffer = NULL;
1192 HandleType = NULL;
1193
1194 Status = ParseHandleDatabaseByRelationshipWithType (
1195 DriverBindingHandle,
1196 ControllerHandle,
1197 &HandleCount,
1198 &HandleBuffer,
1199 &HandleType
1200 );
1201 if (!EFI_ERROR (Status)) {
1202 //
1203 // Count the number of handles that match the attributes in Mask
1204 //
1205 for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
1206 if ((HandleType[HandleIndex] & Mask) == Mask) {
1207 (*MatchingHandleCount)++;
1208 }
1209 }
1210 //
1211 // If no handles match the attributes in Mask then return EFI_NOT_FOUND
1212 //
1213 if (*MatchingHandleCount == 0) {
1214 Status = EFI_NOT_FOUND;
1215 } else {
1216
1217 if (MatchingHandleBuffer == NULL) {
1218 //
1219 // Someone just wanted the count...
1220 //
1221 Status = EFI_SUCCESS;
1222 } else {
1223 //
1224 // Allocate a handle buffer for the number of handles that matched the attributes in Mask
1225 //
1226 *MatchingHandleBuffer = AllocateZeroPool ((*MatchingHandleCount +1)* sizeof (EFI_HANDLE));
1227 ASSERT(*MatchingHandleBuffer != NULL);
1228
1229 for (HandleIndex = 0,*MatchingHandleCount = 0
1230 ; HandleIndex < HandleCount
1231 ; HandleIndex++
1232 ){
1233 //
1234 // Fill the allocated buffer with the handles that matched the attributes in Mask
1235 //
1236 if ((HandleType[HandleIndex] & Mask) == Mask) {
1237 (*MatchingHandleBuffer)[(*MatchingHandleCount)++] = HandleBuffer[HandleIndex];
1238 }
1239 }
1240
1241 //
1242 // Make the last one NULL
1243 //
1244 (*MatchingHandleBuffer)[*MatchingHandleCount] = NULL;
1245
1246 Status = EFI_SUCCESS;
1247 } // MacthingHandleBuffer == NULL (ELSE)
1248 } // *MatchingHandleCount == 0 (ELSE)
1249 } // no error on ParseHandleDatabaseByRelationshipWithType
1250
1251 if (HandleBuffer != NULL) {
1252 FreePool (HandleBuffer);
1253 }
1254
1255 if (HandleType != NULL) {
1256 FreePool (HandleType);
1257 }
1258
1259 return Status;
1260 }
1261
1262 /**
1263 Gets handles for any child controllers of the passed in controller.
1264
1265 @param[in] ControllerHandle The handle of the "parent controller"
1266 @param[in] MatchingHandleCount Pointer to the number of handles in
1267 MatchingHandleBuffer on return.
1268 @param[out] MatchingHandleBuffer Buffer containing handles on a successful
1269 return.
1270
1271
1272 @retval EFI_SUCCESS The operation was sucessful.
1273 **/
1274 EFI_STATUS
1275 EFIAPI
1276 ParseHandleDatabaseForChildControllers(
1277 IN CONST EFI_HANDLE ControllerHandle,
1278 IN UINTN *MatchingHandleCount,
1279 OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL
1280 )
1281 {
1282 EFI_STATUS Status;
1283 // UINTN HandleIndex;
1284 UINTN DriverBindingHandleCount;
1285 EFI_HANDLE *DriverBindingHandleBuffer;
1286 UINTN DriverBindingHandleIndex;
1287 UINTN ChildControllerHandleCount;
1288 EFI_HANDLE *ChildControllerHandleBuffer;
1289 UINTN ChildControllerHandleIndex;
1290 // BOOLEAN Found;
1291 EFI_HANDLE *HandleBufferForReturn;
1292
1293 if (MatchingHandleCount == NULL) {
1294 return (EFI_INVALID_PARAMETER);
1295 }
1296 *MatchingHandleCount = 0;
1297
1298 Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
1299 ControllerHandle,
1300 &DriverBindingHandleCount,
1301 &DriverBindingHandleBuffer
1302 );
1303 if (EFI_ERROR (Status)) {
1304 return Status;
1305 }
1306
1307 //
1308 // Get a buffer big enough for all the controllers.
1309 //
1310 HandleBufferForReturn = GetHandleListByProtocol(&gEfiDevicePathProtocolGuid);
1311 if (HandleBufferForReturn == NULL) {
1312 FreePool (DriverBindingHandleBuffer);
1313 return (EFI_NOT_FOUND);
1314 }
1315
1316 for (DriverBindingHandleIndex = 0; DriverBindingHandleIndex < DriverBindingHandleCount; DriverBindingHandleIndex++) {
1317 Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
1318 DriverBindingHandleBuffer[DriverBindingHandleIndex],
1319 ControllerHandle,
1320 &ChildControllerHandleCount,
1321 &ChildControllerHandleBuffer
1322 );
1323 if (EFI_ERROR (Status)) {
1324 continue;
1325 }
1326
1327 for (ChildControllerHandleIndex = 0;
1328 ChildControllerHandleIndex < ChildControllerHandleCount;
1329 ChildControllerHandleIndex++
1330 ) {
1331 // Found = FALSE;
1332 HandleBufferForReturn[(*MatchingHandleCount)++] = ChildControllerHandleBuffer[ChildControllerHandleIndex];
1333 // for (HandleIndex = 0; HandleBufferForReturn[HandleIndex] != NULL; HandleIndex++) {
1334 // if (HandleBufferForReturn[HandleIndex] == ChildControllerHandleBuffer[ChildControllerHandleIndex]) {
1335 // Found = TRUE;
1336 // break;
1337 // }
1338 // }
1339
1340 // if (Found) {
1341 // HandleBufferForReturn[(*MatchingHandleCount)++] = ChildControllerHandleBuffer[ChildControllerHandleIndex];
1342 // }
1343 }
1344
1345 FreePool (ChildControllerHandleBuffer);
1346 }
1347
1348 FreePool (DriverBindingHandleBuffer);
1349
1350 if (MatchingHandleBuffer != NULL) {
1351 *MatchingHandleBuffer = HandleBufferForReturn;
1352 } else {
1353 FreePool(HandleBufferForReturn);
1354 }
1355
1356 return (EFI_SUCCESS);
1357 }
1358
1359 /**
1360 Appends 1 buffer to another buffer. This will re-allocate the destination buffer
1361 if necessary to fit all of the data.
1362
1363 If DestinationBuffer is NULL, then ASSERT().
1364
1365 @param[in, out] DestinationBuffer The pointer to the pointer to the buffer to append onto.
1366 @param[in, out] DestinationSize The pointer to the size of DestinationBuffer.
1367 @param[in] SourceBuffer The pointer to the buffer to append onto DestinationBuffer.
1368 @param[in] SourceSize The number of bytes of SourceBuffer to append.
1369
1370 @retval NULL A memory allocation failed.
1371 @retval NULL A parameter was invalid.
1372 @return A pointer to (*DestinationBuffer).
1373 **/
1374 VOID*
1375 EFIAPI
1376 BuffernCatGrow (
1377 IN OUT VOID **DestinationBuffer,
1378 IN OUT UINTN *DestinationSize,
1379 IN VOID *SourceBuffer,
1380 IN UINTN SourceSize
1381 )
1382 {
1383 UINTN LocalDestinationSize;
1384 UINTN LocalDestinationFinalSize;
1385
1386 ASSERT(DestinationBuffer != NULL);
1387
1388 if (SourceSize == 0 || SourceBuffer == NULL) {
1389 return (*DestinationBuffer);
1390 }
1391
1392 if (DestinationSize == NULL) {
1393 LocalDestinationSize = 0;
1394 } else {
1395 LocalDestinationSize = *DestinationSize;
1396 }
1397
1398 LocalDestinationFinalSize = LocalDestinationSize + SourceSize;
1399
1400 if (DestinationSize != NULL) {
1401 *DestinationSize = LocalDestinationSize;
1402 }
1403
1404 if (LocalDestinationSize == 0) {
1405 // allcoate
1406 *DestinationBuffer = AllocateZeroPool(LocalDestinationFinalSize);
1407 } else {
1408 // reallocate
1409 *DestinationBuffer = ReallocatePool(LocalDestinationSize, LocalDestinationFinalSize, *DestinationBuffer);
1410 }
1411
1412 ASSERT(*DestinationBuffer != NULL);
1413
1414 // copy
1415 return (CopyMem(((UINT8*)(*DestinationBuffer)) + LocalDestinationSize, SourceBuffer, SourceSize));
1416 }
1417
1418 /**
1419 Gets handles for any child devices produced by the passed in driver.
1420
1421 @param[in] DriverHandle The handle of the driver.
1422 @param[in] MatchingHandleCount Pointer to the number of handles in
1423 MatchingHandleBuffer on return.
1424 @param[out] MatchingHandleBuffer Buffer containing handles on a successful
1425 return.
1426 @retval EFI_SUCCESS The operation was sucessful.
1427 @sa ParseHandleDatabaseByRelationship
1428 **/
1429 EFI_STATUS
1430 EFIAPI
1431 ParseHandleDatabaseForChildDevices(
1432 IN CONST EFI_HANDLE DriverHandle,
1433 IN UINTN *MatchingHandleCount,
1434 OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL
1435 )
1436 {
1437 EFI_HANDLE *Buffer;
1438 EFI_HANDLE *Buffer2;
1439 UINTN Count1;
1440 UINTN Count2;
1441 UINTN HandleIndex;
1442 EFI_STATUS Status;
1443 UINTN HandleBufferSize;
1444
1445 ASSERT(MatchingHandleCount != NULL);
1446
1447 HandleBufferSize = 0;
1448 Buffer = NULL;
1449 Buffer2 = NULL;
1450 *MatchingHandleCount = 0;
1451
1452 Status = PARSE_HANDLE_DATABASE_DEVICES (
1453 DriverHandle,
1454 &Count1,
1455 &Buffer
1456 );
1457 if (!EFI_ERROR (Status)) {
1458 for (HandleIndex = 0; HandleIndex < Count1; HandleIndex++) {
1459 //
1460 // now find the children
1461 //
1462 Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
1463 DriverHandle,
1464 Buffer[HandleIndex],
1465 &Count2,
1466 &Buffer2
1467 );
1468 if (EFI_ERROR(Status)) {
1469 break;
1470 }
1471 //
1472 // save out required and optional data elements
1473 //
1474 *MatchingHandleCount += Count2;
1475 if (MatchingHandleBuffer != NULL) {
1476 *MatchingHandleBuffer = BuffernCatGrow((VOID**)MatchingHandleBuffer, &HandleBufferSize, Buffer2, Count2 * sizeof(Buffer2[0]));
1477 }
1478
1479 //
1480 // free the memory
1481 //
1482 if (Buffer2 != NULL) {
1483 FreePool(Buffer2);
1484 }
1485 }
1486 }
1487
1488 if (Buffer != NULL) {
1489 FreePool(Buffer);
1490 }
1491 return (Status);
1492 }
1493
1494 /**
1495 Function to get all handles that support a given protocol or all handles.
1496
1497 @param[in] ProtocolGuid The guid of the protocol to get handles for. If NULL
1498 then the function will return all handles.
1499
1500 @retval NULL A memory allocation failed.
1501 @return A NULL terminated list of handles.
1502 **/
1503 EFI_HANDLE*
1504 EFIAPI
1505 GetHandleListByProtocol (
1506 IN CONST EFI_GUID *ProtocolGuid OPTIONAL
1507 )
1508 {
1509 EFI_HANDLE *HandleList;
1510 UINTN Size;
1511 EFI_STATUS Status;
1512
1513 Size = 0;
1514 HandleList = NULL;
1515
1516 //
1517 // We cannot use LocateHandleBuffer since we need that NULL item on the ends of the list!
1518 //
1519 if (ProtocolGuid == NULL) {
1520 Status = gBS->LocateHandle(AllHandles, NULL, NULL, &Size, HandleList);
1521 if (Status == EFI_BUFFER_TOO_SMALL) {
1522 HandleList = AllocateZeroPool(Size + sizeof(EFI_HANDLE));
1523 if (HandleList == NULL) {
1524 return (NULL);
1525 }
1526 Status = gBS->LocateHandle(AllHandles, NULL, NULL, &Size, HandleList);
1527 HandleList[Size/sizeof(EFI_HANDLE)] = NULL;
1528 }
1529 } else {
1530 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)ProtocolGuid, NULL, &Size, HandleList);
1531 if (Status == EFI_BUFFER_TOO_SMALL) {
1532 HandleList = AllocateZeroPool(Size + sizeof(EFI_HANDLE));
1533 if (HandleList == NULL) {
1534 return (NULL);
1535 }
1536 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)ProtocolGuid, NULL, &Size, HandleList);
1537 HandleList[Size/sizeof(EFI_HANDLE)] = NULL;
1538 }
1539 }
1540 if (EFI_ERROR(Status)) {
1541 if (HandleList != NULL) {
1542 FreePool(HandleList);
1543 }
1544 return (NULL);
1545 }
1546 return (HandleList);
1547 }
1548
1549 /**
1550 Function to get all handles that support some protocols.
1551
1552 @param[in] ProtocolGuids A NULL terminated list of protocol GUIDs.
1553
1554 @retval NULL A memory allocation failed.
1555 @retval NULL ProtocolGuids was NULL.
1556 @return A NULL terminated list of EFI_HANDLEs.
1557 **/
1558 EFI_HANDLE*
1559 EFIAPI
1560 GetHandleListByProtocolList (
1561 IN CONST EFI_GUID **ProtocolGuids
1562 )
1563 {
1564 EFI_HANDLE *HandleList;
1565 UINTN Size;
1566 UINTN TotalSize;
1567 UINTN TempSize;
1568 EFI_STATUS Status;
1569 CONST EFI_GUID **GuidWalker;
1570 EFI_HANDLE *HandleWalker1;
1571 EFI_HANDLE *HandleWalker2;
1572
1573 Size = 0;
1574 HandleList = NULL;
1575 TotalSize = sizeof(EFI_HANDLE);
1576
1577 for (GuidWalker = ProtocolGuids ; GuidWalker != NULL && *GuidWalker != NULL ; GuidWalker++,Size = 0){
1578 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)(*GuidWalker), NULL, &Size, NULL);
1579 if (Status == EFI_BUFFER_TOO_SMALL) {
1580 TotalSize += Size;
1581 }
1582 }
1583
1584 //
1585 // No handles were found...
1586 //
1587 if (TotalSize == sizeof(EFI_HANDLE)) {
1588 return (NULL);
1589 }
1590
1591 HandleList = AllocateZeroPool(TotalSize);
1592 if (HandleList == NULL) {
1593 return (NULL);
1594 }
1595
1596 Size = 0;
1597 for (GuidWalker = ProtocolGuids ; GuidWalker != NULL && *GuidWalker != NULL ; GuidWalker++){
1598 TempSize = TotalSize - Size;
1599 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)(*GuidWalker), NULL, &TempSize, HandleList+(Size/sizeof(EFI_HANDLE)));
1600
1601 //
1602 // Allow for missing protocols... Only update the 'used' size upon success.
1603 //
1604 if (!EFI_ERROR(Status)) {
1605 Size += TempSize;
1606 }
1607 }
1608 ASSERT(HandleList[(TotalSize/sizeof(EFI_HANDLE))-1] == NULL);
1609
1610 for (HandleWalker1 = HandleList ; HandleWalker1 != NULL && *HandleWalker1 != NULL ; HandleWalker1++) {
1611 for (HandleWalker2 = HandleWalker1 + 1; HandleWalker2 != NULL && *HandleWalker2 != NULL ; HandleWalker2++) {
1612 if (*HandleWalker1 == *HandleWalker2) {
1613 //
1614 // copy memory back 1 handle width.
1615 //
1616 CopyMem(HandleWalker2, HandleWalker2 + 1, TotalSize - ((HandleWalker2-HandleList+1)*sizeof(EFI_HANDLE)));
1617 }
1618 }
1619 }
1620
1621 return (HandleList);
1622 }
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632