]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c
9e5164821747bb976c032c178d7eba5d2d3947a3
[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 - 2011, 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
17 EFI_HANDLE mHandleParsingHiiHandle;
18 HANDLE_INDEX_LIST mHandleList = {{{NULL,NULL},0,0},0};
19
20 /**
21 Constructor for the library.
22
23 @param[in] ImageHandle Ignored.
24 @param[in] SystemTable Ignored.
25
26 @retval EFI_SUCCESS The operation was successful.
27 **/
28 EFI_STATUS
29 EFIAPI
30 HandleParsingLibConstructor (
31 IN EFI_HANDLE ImageHandle,
32 IN EFI_SYSTEM_TABLE *SystemTable
33 )
34 {
35 mHandleParsingHiiHandle = HiiAddPackages (&gHandleParsingHiiGuid, gImageHandle, UefiHandleParsingLibStrings, NULL);
36 if (mHandleParsingHiiHandle == NULL) {
37 return (EFI_DEVICE_ERROR);
38 }
39
40 return (EFI_SUCCESS);
41 }
42
43 /**
44 Destructor for the library. free any resources.
45
46 @param[in] ImageHandle Ignored.
47 @param[in] SystemTable Ignored.
48
49 @retval EFI_SUCCESS The operation was successful.
50 **/
51 EFI_STATUS
52 EFIAPI
53 HandleParsingLibDestructor (
54 IN EFI_HANDLE ImageHandle,
55 IN EFI_SYSTEM_TABLE *SystemTable
56 )
57 {
58 if (mHandleParsingHiiHandle != NULL) {
59 HiiRemovePackages(mHandleParsingHiiHandle);
60 }
61 return (EFI_SUCCESS);
62 }
63
64 /*
65 CHAR16*
66 EFIAPI
67 LoadedImageProtocolDumpInformation(
68 IN CONST EFI_HANDLE TheHandle,
69 IN CONST BOOLEAN Verbose
70 )
71 {
72 EFI_LOADED_IMAGE_PROTOCOL *Image;
73 EFI_STATUS Status;
74 EFI_DEVICE_PATH_PROTOCOL *DevPath;
75 EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
76 VOID *Buffer;
77 UINTN BufferSize;
78 UINT32 AuthenticationStatus;
79 EFI_GUID *NameGuid;
80 EFI_FIRMWARE_VOLUME_PROTOCOL *FV;
81 EFI_FIRMWARE_VOLUME2_PROTOCOL *FV2;
82
83 FV = NULL;
84 FV2 = NULL;
85 Buffer = NULL;
86 BufferSize = 0;
87
88 Status = HandleProtocol (
89 TheHandle,
90 &gEfiLoadedImageProtocolGuid,
91 &Image);
92 ASSERT_EFI_ERROR(Status);
93
94 DevPath = UnpackDevicePath (Image->FilePath);
95
96 if (DevPath == NULL) {
97 return NULL;
98 }
99
100 DevPathNode = DevPath;
101
102 while (!IsDevicePathEnd (DevPathNode)) {
103 //
104 // Find the Fv File path
105 //
106 NameGuid = GetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)DevPathNode);
107 if (NameGuid != NULL) {
108 Status = BS->HandleProtocol (
109 Image->DeviceHandle,
110 &gEfiFirmwareVolumeProtocolGuid,
111 &FV
112 );
113 if (!EFI_ERROR (Status)) {
114 Status = FV->ReadSection (
115 FV,
116 NameGuid,
117 EFI_SECTION_USER_INTERFACE,
118 0,
119 &Buffer,
120 &BufferSize,
121 &AuthenticationStatus
122 );
123 if (!EFI_ERROR (Status)) {
124 break;
125 }
126
127 Buffer = NULL;
128 } else {
129 Status = BS->HandleProtocol (
130 Image->DeviceHandle,
131 &gEfiFirmwareVolume2ProtocolGuid,
132 &FV2
133 );
134 if (!EFI_ERROR (Status)) {
135 Status = FV2->ReadSection (
136 FV2,
137 NameGuid,
138 EFI_SECTION_USER_INTERFACE,
139 0,
140 &Buffer,
141 &BufferSize,
142 &AuthenticationStatus
143 );
144 if (!EFI_ERROR (Status)) {
145 break;
146 }
147
148 Buffer = NULL;
149 }
150 }
151 }
152 //
153 // Next device path node
154 //
155 DevPathNode = NextDevicePathNode (DevPathNode);
156 }
157
158 FreePool (DevPath);
159 return Buffer;
160 }
161 */
162
163 /**
164 Function to dump information about SimpleTextOut.
165
166 This will allocate the return buffer from boot services pool.
167
168 @param[in] TheHandle The handle that has SimpleTextOut installed.
169 @param[in] Verbose TRUE for additional information, FALSE otherwise.
170
171 @retval A poitner to a string containing the information.
172 **/
173 CHAR16*
174 EFIAPI
175 TxtOutProtocolDumpInformation(
176 IN CONST EFI_HANDLE TheHandle,
177 IN CONST BOOLEAN Verbose
178 )
179 {
180 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Dev;
181 INTN Index;
182 UINTN Col;
183 UINTN Row;
184 EFI_STATUS Status;
185 CHAR16 *RetVal;
186 UINTN Size;
187 CHAR16 *Temp;
188 UINTN NewSize;
189
190 if (!Verbose) {
191 return (NULL);
192 }
193
194 RetVal = NULL;
195 Size = 0;
196
197 Status = gBS->HandleProtocol(
198 TheHandle,
199 &gEfiSimpleTextOutProtocolGuid,
200 (VOID**)&Dev);
201
202 ASSERT_EFI_ERROR(Status);
203 ASSERT (Dev != NULL && Dev->Mode != NULL);
204
205 Size = (Dev->Mode->MaxMode + 1) * 80;
206 RetVal = AllocateZeroPool(Size);
207
208 Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_TXT_OUT_DUMP_HEADER), NULL);
209 if (Temp != NULL) {
210 UnicodeSPrint(RetVal, Size, Temp, Dev, Dev->Mode->Attribute);
211 FreePool(Temp);
212 }
213
214 //
215 // Dump TextOut Info
216 //
217 Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_TXT_OUT_DUMP_LINE), NULL);
218 for (Index = 0; Index < Dev->Mode->MaxMode; Index++) {
219 Status = Dev->QueryMode (Dev, Index, &Col, &Row);
220 NewSize = Size - StrSize(RetVal);
221 UnicodeSPrint(
222 RetVal + StrLen(RetVal),
223 NewSize,
224 Temp == NULL?L"":Temp,
225 Index == Dev->Mode->Mode ? L'*' : L' ',
226 Index,
227 !EFI_ERROR(Status)?Col:-1,
228 !EFI_ERROR(Status)?Row:-1
229 );
230 }
231 FreePool(Temp);
232 return (RetVal);
233 }
234
235 STATIC CONST UINTN VersionStringSize = 60;
236
237 /**
238 Function to dump information about EfiDriverSupportedEfiVersion protocol.
239
240 This will allocate the return buffer from boot services pool.
241
242 @param[in] TheHandle The handle that has the protocol installed.
243 @param[in] Verbose TRUE for additional information, FALSE otherwise.
244
245 @retval A poitner to a string containing the information.
246 **/
247 CHAR16*
248 EFIAPI
249 DriverEfiVersionProtocolDumpInformation(
250 IN CONST EFI_HANDLE TheHandle,
251 IN CONST BOOLEAN Verbose
252 )
253 {
254 EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL *DriverEfiVersion;
255 EFI_STATUS Status;
256 CHAR16 *RetVal;
257
258 Status = gBS->HandleProtocol(
259 TheHandle,
260 &gEfiDriverSupportedEfiVersionProtocolGuid,
261 (VOID**)&DriverEfiVersion);
262
263 ASSERT_EFI_ERROR(Status);
264
265 RetVal = AllocateZeroPool(VersionStringSize);
266 ASSERT(RetVal != NULL);
267 UnicodeSPrint(RetVal, VersionStringSize, L"0x%08x", DriverEfiVersion->FirmwareVersion);
268 return (RetVal);
269 }
270
271 /**
272 Function to dump information about DevicePath protocol.
273
274 This will allocate the return buffer from boot services pool.
275
276 @param[in] TheHandle The handle that has the protocol installed.
277 @param[in] Verbose TRUE for additional information, FALSE otherwise.
278
279 @retval A poitner to a string containing the information.
280 **/
281 CHAR16*
282 EFIAPI
283 DevicePathProtocolDumpInformation(
284 IN CONST EFI_HANDLE TheHandle,
285 IN CONST BOOLEAN Verbose
286 )
287 {
288 EFI_DEVICE_PATH_PROTOCOL *DevPath;
289 CHAR16 *Temp;
290 CHAR16 *Temp2;
291 EFI_STATUS Status;
292 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText;
293 Temp = NULL;
294
295 Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID**)&DevPathToText);
296 if (!EFI_ERROR(Status)) {
297 Status = gBS->OpenProtocol(TheHandle, &gEfiDevicePathProtocolGuid, (VOID**)&DevPath, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
298 if (!EFI_ERROR(Status)) {
299 //
300 // I cannot decide whether to allow shortcuts here (the second BOOLEAN on the next line)
301 //
302 Temp = DevPathToText->ConvertDevicePathToText(DevPath, TRUE, TRUE);
303 gBS->CloseProtocol(TheHandle, &gEfiDevicePathProtocolGuid, gImageHandle, NULL);
304 }
305 }
306 if (!Verbose && Temp != NULL && StrLen(Temp) > 30) {
307 Temp2 = NULL;
308 Temp2 = StrnCatGrow(&Temp2, NULL, Temp+(StrLen(Temp) - 30), 30);
309 FreePool(Temp);
310 Temp = Temp2;
311 }
312 return (Temp);
313 }
314
315 //
316 // Put the information on the NT32 protocol GUIDs here so we are not dependant on the Nt32Pkg
317 //
318 #define LOCAL_EFI_WIN_NT_THUNK_PROTOCOL_GUID \
319 { \
320 0x58c518b1, 0x76f3, 0x11d4, 0xbc, 0xea, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 \
321 }
322
323 #define LOCAL_EFI_WIN_NT_BUS_DRIVER_IO_PROTOCOL_GUID \
324 { \
325 0x96eb4ad6, 0xa32a, 0x11d4, 0xbc, 0xfd, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 \
326 }
327
328 #define LOCAL_EFI_WIN_NT_SERIAL_PORT_GUID \
329 { \
330 0xc95a93d, 0xa006, 0x11d4, 0xbc, 0xfa, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 \
331 }
332 STATIC CONST EFI_GUID WinNtThunkProtocolGuid = LOCAL_EFI_WIN_NT_THUNK_PROTOCOL_GUID;
333 STATIC CONST EFI_GUID WinNtIoProtocolGuid = LOCAL_EFI_WIN_NT_BUS_DRIVER_IO_PROTOCOL_GUID;
334 STATIC CONST EFI_GUID WinNtSerialPortGuid = LOCAL_EFI_WIN_NT_SERIAL_PORT_GUID;
335
336 STATIC CONST PROTOCOL_INFO_BLOCK mGuidStringListNT[] = {
337 {STRING_TOKEN(STR_WINNT_THUNK), (EFI_GUID*)&WinNtThunkProtocolGuid, NULL},
338 {STRING_TOKEN(STR_WINNT_DRIVER_IO), (EFI_GUID*)&WinNtIoProtocolGuid, NULL},
339 {STRING_TOKEN(STR_WINNT_SERIAL_PORT), (EFI_GUID*)&WinNtSerialPortGuid, NULL},
340 {STRING_TOKEN(STR_UNKNOWN_DEVICE), NULL, NULL},
341 };
342
343 STATIC CONST PROTOCOL_INFO_BLOCK mGuidStringList[] = {
344 {STRING_TOKEN(STR_LOADED_IMAGE), &gEfiLoadedImageProtocolGuid, NULL},
345 {STRING_TOKEN(STR_DEVICE_PATH), &gEfiDevicePathProtocolGuid, DevicePathProtocolDumpInformation},
346 {STRING_TOKEN(STR_IMAGE_PATH), &gEfiLoadedImageDevicePathProtocolGuid, DevicePathProtocolDumpInformation},
347 {STRING_TOKEN(STR_DEVICE_PATH_UTIL), &gEfiDevicePathUtilitiesProtocolGuid, NULL},
348 {STRING_TOKEN(STR_DEVICE_PATH_TXT), &gEfiDevicePathToTextProtocolGuid, NULL},
349 {STRING_TOKEN(STR_DEVICE_PATH_FTXT), &gEfiDevicePathFromTextProtocolGuid, NULL},
350 {STRING_TOKEN(STR_DEVICE_PATH_PC), &gEfiPcAnsiGuid, NULL},
351 {STRING_TOKEN(STR_DEVICE_PATH_VT100), &gEfiVT100Guid, NULL},
352 {STRING_TOKEN(STR_DEVICE_PATH_VT100P), &gEfiVT100PlusGuid, NULL},
353 {STRING_TOKEN(STR_DEVICE_PATH_VTUTF8), &gEfiVTUTF8Guid, NULL},
354 {STRING_TOKEN(STR_DRIVER_BINDING), &gEfiDriverBindingProtocolGuid, NULL},
355 {STRING_TOKEN(STR_PLATFORM_OVERRIDE), &gEfiPlatformDriverOverrideProtocolGuid, NULL},
356 {STRING_TOKEN(STR_BUS_OVERRIDE), &gEfiBusSpecificDriverOverrideProtocolGuid, NULL},
357 {STRING_TOKEN(STR_DRIVER_DIAG), &gEfiDriverDiagnosticsProtocolGuid, NULL},
358 {STRING_TOKEN(STR_DRIVER_DIAG2), &gEfiDriverDiagnostics2ProtocolGuid, NULL},
359 {STRING_TOKEN(STR_DRIVER_CN), &gEfiComponentNameProtocolGuid, NULL},
360 {STRING_TOKEN(STR_DRIVER_CN2), &gEfiComponentName2ProtocolGuid, NULL},
361 {STRING_TOKEN(STR_PLAT_DRV_CFG), &gEfiPlatformToDriverConfigurationProtocolGuid, NULL},
362 {STRING_TOKEN(STR_DRIVER_VERSION), &gEfiDriverSupportedEfiVersionProtocolGuid, DriverEfiVersionProtocolDumpInformation},
363 {STRING_TOKEN(STR_TXT_IN), &gEfiSimpleTextInProtocolGuid, NULL},
364 {STRING_TOKEN(STR_TXT_IN_EX), &gEfiSimpleTextInputExProtocolGuid, NULL},
365 {STRING_TOKEN(STR_TXT_OUT), &gEfiSimpleTextOutProtocolGuid, TxtOutProtocolDumpInformation},
366 {STRING_TOKEN(STR_SIM_POINTER), &gEfiSimplePointerProtocolGuid, NULL},
367 {STRING_TOKEN(STR_ABS_POINTER), &gEfiAbsolutePointerProtocolGuid, NULL},
368 {STRING_TOKEN(STR_SERIAL_IO), &gEfiSerialIoProtocolGuid, NULL},
369 {STRING_TOKEN(STR_GRAPHICS_OUTPUT), &gEfiGraphicsOutputProtocolGuid, NULL},
370 {STRING_TOKEN(STR_EDID_DISCOVERED), &gEfiEdidDiscoveredProtocolGuid, NULL},
371 {STRING_TOKEN(STR_EDID_ACTIVE), &gEfiEdidActiveProtocolGuid, NULL},
372 {STRING_TOKEN(STR_EDID_OVERRIDE), &gEfiEdidOverrideProtocolGuid, NULL},
373 {STRING_TOKEN(STR_CON_IN), &gEfiConsoleInDeviceGuid, NULL},
374 {STRING_TOKEN(STR_CON_OUT), &gEfiConsoleOutDeviceGuid, NULL},
375 {STRING_TOKEN(STR_STD_ERR), &gEfiStandardErrorDeviceGuid, NULL},
376 {STRING_TOKEN(STR_LOAD_FILE), &gEfiLoadFileProtocolGuid, NULL},
377 {STRING_TOKEN(STR_LOAD_FILE2), &gEfiLoadFile2ProtocolGuid, NULL},
378 {STRING_TOKEN(STR_SIMPLE_FILE_SYS), &gEfiSimpleFileSystemProtocolGuid, NULL},
379 {STRING_TOKEN(STR_FILE_INFO), &gEfiFileInfoGuid, NULL},
380 {STRING_TOKEN(STR_FILE_SYS_INFO), &gEfiFileSystemInfoGuid, NULL},
381 {STRING_TOKEN(STR_TAPE_IO), &gEfiTapeIoProtocolGuid, NULL},
382 {STRING_TOKEN(STR_DISK_IO), &gEfiDiskIoProtocolGuid, NULL},
383 {STRING_TOKEN(STR_BLK_IO), &gEfiBlockIoProtocolGuid, NULL},
384 {STRING_TOKEN(STR_UC), &gEfiUnicodeCollationProtocolGuid, NULL},
385 {STRING_TOKEN(STR_UC2), &gEfiUnicodeCollation2ProtocolGuid, NULL},
386 {STRING_TOKEN(STR_PCIRB_IO), &gEfiPciRootBridgeIoProtocolGuid, NULL},
387 {STRING_TOKEN(STR_PCI_IO), &gEfiPciIoProtocolGuid, NULL},
388 {STRING_TOKEN(STR_SCSI_PT), &gEfiScsiPassThruProtocolGuid, NULL},
389 {STRING_TOKEN(STR_SCSI_IO), &gEfiScsiIoProtocolGuid, NULL},
390 {STRING_TOKEN(STR_SCSI_PT_EXT), &gEfiExtScsiPassThruProtocolGuid, NULL},
391 {STRING_TOKEN(STR_ISCSI), &gEfiIScsiInitiatorNameProtocolGuid, NULL},
392 {STRING_TOKEN(STR_USB_IO), &gEfiUsbIoProtocolGuid, NULL},
393 {STRING_TOKEN(STR_USB_HC), &gEfiUsbHcProtocolGuid, NULL},
394 {STRING_TOKEN(STR_USB_HC2), &gEfiUsb2HcProtocolGuid, NULL},
395 {STRING_TOKEN(STR_DEBUG_SUPPORT), &gEfiDebugSupportProtocolGuid, NULL},
396 {STRING_TOKEN(STR_DEBUG_PORT), &gEfiDebugPortProtocolGuid, NULL},
397 {STRING_TOKEN(STR_DECOMPRESS), &gEfiDecompressProtocolGuid, NULL},
398 {STRING_TOKEN(STR_ACPI_TABLE), &gEfiAcpiTableProtocolGuid, NULL},
399 {STRING_TOKEN(STR_EBC_INTERPRETER), &gEfiEbcProtocolGuid, NULL},
400 {STRING_TOKEN(STR_SNP), &gEfiSimpleNetworkProtocolGuid, NULL},
401 {STRING_TOKEN(STR_NII), &gEfiNetworkInterfaceIdentifierProtocolGuid, NULL},
402 {STRING_TOKEN(STR_NII_31), &gEfiNetworkInterfaceIdentifierProtocolGuid_31, NULL},
403 {STRING_TOKEN(STR_PXE_BC), &gEfiPxeBaseCodeProtocolGuid, NULL},
404 {STRING_TOKEN(STR_PXE_CB), &gEfiPxeBaseCodeCallbackProtocolGuid, NULL},
405 {STRING_TOKEN(STR_BIS), &gEfiBisProtocolGuid, NULL},
406 {STRING_TOKEN(STR_MNP_SB), &gEfiManagedNetworkServiceBindingProtocolGuid, NULL},
407 {STRING_TOKEN(STR_MNP), &gEfiManagedNetworkProtocolGuid, NULL},
408 {STRING_TOKEN(STR_ARP_SB), &gEfiArpServiceBindingProtocolGuid, NULL},
409 {STRING_TOKEN(STR_ARP), &gEfiArpProtocolGuid, NULL},
410 {STRING_TOKEN(STR_DHCPV4_SB), &gEfiDhcp4ServiceBindingProtocolGuid, NULL},
411 {STRING_TOKEN(STR_DHCPV4), &gEfiDhcp4ProtocolGuid, NULL},
412 {STRING_TOKEN(STR_TCPV4_SB), &gEfiTcp4ServiceBindingProtocolGuid, NULL},
413 {STRING_TOKEN(STR_TCPV4), &gEfiTcp4ProtocolGuid, NULL},
414 {STRING_TOKEN(STR_IPV4_SB), &gEfiIp4ServiceBindingProtocolGuid, NULL},
415 {STRING_TOKEN(STR_IPV4), &gEfiIp4ProtocolGuid, NULL},
416 {STRING_TOKEN(STR_IPV4_CFG), &gEfiIp4ConfigProtocolGuid, NULL},
417 {STRING_TOKEN(STR_SHELL_PARAMETERS), &gEfiShellParametersProtocolGuid, NULL},
418 {STRING_TOKEN(STR_SHELL), &gEfiShellProtocolGuid, NULL},
419 {STRING_TOKEN(STR_EFI_GLOBAL_VARIABLE), &gEfiGlobalVariableGuid, NULL},
420 {STRING_TOKEN(STR_UDPV4_SB), &gEfiUdp4ServiceBindingProtocolGuid, NULL},
421 {STRING_TOKEN(STR_UDPV4), &gEfiUdp4ProtocolGuid, NULL},
422 {STRING_TOKEN(STR_MTFTPV4_SB), &gEfiMtftp4ServiceBindingProtocolGuid, NULL},
423 {STRING_TOKEN(STR_MTFTPV4), &gEfiMtftp4ProtocolGuid, NULL},
424 {STRING_TOKEN(STR_AUTH_INFO), &gEfiAuthenticationInfoProtocolGuid, NULL},
425 {STRING_TOKEN(STR_HASH_SB), &gEfiHashServiceBindingProtocolGuid, NULL},
426 {STRING_TOKEN(STR_HASH), &gEfiHashProtocolGuid, NULL},
427 {STRING_TOKEN(STR_HII_FONT), &gEfiHiiFontProtocolGuid, NULL},
428 {STRING_TOKEN(STR_HII_STRING), &gEfiHiiStringProtocolGuid, NULL},
429 {STRING_TOKEN(STR_HII_IMAGE), &gEfiHiiImageProtocolGuid, NULL},
430 {STRING_TOKEN(STR_HII_DATABASE), &gEfiHiiDatabaseProtocolGuid, NULL},
431 {STRING_TOKEN(STR_HII_CONFIG_ROUT), &gEfiHiiConfigRoutingProtocolGuid, NULL},
432 {STRING_TOKEN(STR_HII_CONFIG_ACC), &gEfiHiiConfigAccessProtocolGuid, NULL},
433 {STRING_TOKEN(STR_HII_FORM_BROWSER2), &gEfiFormBrowser2ProtocolGuid, NULL},
434 {STRING_TOKEN(STR_SHELL_INTERFACE), &gEfiShellInterfaceGuid, NULL},
435 {STRING_TOKEN(STR_SHELL_ENV2), &gEfiShellEnvironment2Guid, NULL},
436 {STRING_TOKEN(STR_SHELL_ENV), &gEfiShellEnvironment2Guid, NULL},
437 {STRING_TOKEN(STR_DEVICE_IO), &gEfiDeviceIoProtocolGuid, NULL},
438 {STRING_TOKEN(STR_UGA_DRAW), &gEfiUgaDrawProtocolGuid, NULL},
439 {STRING_TOKEN(STR_UGA_IO), &gEfiUgaIoProtocolGuid, NULL},
440 {STRING_TOKEN(STR_ESP), &gEfiPartTypeSystemPartGuid, NULL},
441 {STRING_TOKEN(STR_GPT_NBR), &gEfiPartTypeLegacyMbrGuid, NULL},
442 {STRING_TOKEN(STR_DRIVER_CONFIG), &gEfiDriverConfigurationProtocolGuid, NULL},
443 {STRING_TOKEN(STR_DRIVER_CONFIG2), &gEfiDriverConfiguration2ProtocolGuid, NULL},
444 {STRING_TOKEN(STR_UNKNOWN_DEVICE), NULL, NULL},
445 };
446
447 /**
448 Function to get the node for a protocol or struct from it's GUID.
449
450 if Guid is NULL, then ASSERT.
451
452 @param[in] Guid The GUID to look for the name of.
453
454 @return The node.
455 **/
456 CONST PROTOCOL_INFO_BLOCK *
457 EFIAPI
458 InternalShellGetNodeFromGuid(
459 IN CONST EFI_GUID* Guid
460 )
461 {
462 CONST PROTOCOL_INFO_BLOCK *ListWalker;
463
464 ASSERT(Guid != NULL);
465
466 if (PcdGetBool(PcdShellIncludeNtGuids)) {
467 for (ListWalker = mGuidStringListNT ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {
468 if (CompareGuid(ListWalker->GuidId, Guid)) {
469 return (ListWalker);
470 }
471 }
472 }
473 for (ListWalker = mGuidStringList ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {
474 if (CompareGuid(ListWalker->GuidId, Guid)) {
475 return (ListWalker);
476 }
477 }
478 return (ListWalker);
479 }
480
481 /**
482 Function to get the name of a protocol or struct from it's GUID.
483
484 if Guid is NULL, then ASSERT.
485
486 @param[in] Guid The GUID to look for the name of.
487 @param[in] Lang The language to use.
488
489 @return pointer to string of the name. The caller
490 is responsible to free this memory.
491 **/
492 CHAR16*
493 EFIAPI
494 GetStringNameFromGuid(
495 IN CONST EFI_GUID *Guid,
496 IN CONST CHAR8 *Lang OPTIONAL
497 )
498 {
499 CONST PROTOCOL_INFO_BLOCK *Id;
500
501 Id = InternalShellGetNodeFromGuid(Guid);
502 return (HiiGetString(mHandleParsingHiiHandle, Id->StringId, Lang));
503 }
504
505 /**
506 Function to dump protocol information from a handle.
507
508 This function will return a allocated string buffer containing the
509 information. The caller is responsible for freeing the memory.
510
511 If Guid is NULL, ASSERT().
512 If TheHandle is NULL, ASSERT().
513
514 @param[in] TheHandle The handle to dump information from.
515 @param[in] Guid The GUID of the protocol to dump.
516 @param[in] Verbose TRUE for extra info. FALSE otherwise.
517
518 @return The pointer to string.
519 @retval NULL An error was encountered.
520 **/
521 CHAR16*
522 EFIAPI
523 GetProtocolInformationDump(
524 IN CONST EFI_HANDLE TheHandle,
525 IN CONST EFI_GUID *Guid,
526 IN CONST BOOLEAN Verbose
527 )
528 {
529 CONST PROTOCOL_INFO_BLOCK *Id;
530
531 ASSERT(TheHandle != NULL);
532 ASSERT(Guid != NULL);
533
534 if (TheHandle == NULL || Guid == NULL) {
535 return (NULL);
536 }
537
538 Id = InternalShellGetNodeFromGuid(Guid);
539 if (Id != NULL && Id->DumpInfo != NULL) {
540 return (Id->DumpInfo(TheHandle, Verbose));
541 }
542 return (NULL);
543 }
544
545 /**
546 Function to get the Guid for a protocol or struct based on it's string name.
547
548 @param[in] Name The pointer to the string name.
549 @param[in] Lang The pointer to the language code.
550 @param[in] Guid The pointer to the Guid.
551
552 @retval EFI_SUCCESS The operation was sucessful.
553 **/
554 EFI_STATUS
555 EFIAPI
556 GetGuidFromStringName(
557 IN CONST CHAR16 *Name,
558 IN CONST CHAR8 *Lang OPTIONAL,
559 IN EFI_GUID **Guid
560 )
561 {
562 CONST PROTOCOL_INFO_BLOCK *ListWalker;
563 CHAR16 *String;
564
565 ASSERT(Guid != NULL);
566 if (Guid == NULL) {
567 return (EFI_INVALID_PARAMETER);
568 }
569 *Guid = NULL;
570
571 if (PcdGetBool(PcdShellIncludeNtGuids)) {
572 for (ListWalker = mGuidStringListNT ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {
573 String = HiiGetString(mHandleParsingHiiHandle, ListWalker->StringId, Lang);
574 if (Name != NULL && String != NULL && StrCmp(Name, String)==0) {
575 *Guid = ListWalker->GuidId;
576 }
577 SHELL_FREE_NON_NULL(String);
578 if (*Guid != NULL) {
579 return (EFI_SUCCESS);
580 }
581 }
582 }
583 for (ListWalker = mGuidStringList ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {
584 String = HiiGetString(mHandleParsingHiiHandle, ListWalker->StringId, Lang);
585 if (Name != NULL && String != NULL && StrCmp(Name, String)==0) {
586 *Guid = ListWalker->GuidId;
587 }
588 SHELL_FREE_NON_NULL(String);
589 if (*Guid != NULL) {
590 return (EFI_SUCCESS);
591 }
592 }
593 return (EFI_NOT_FOUND);
594 }
595
596 /**
597 Function to retrieve the driver name (if possible) from the ComponentName or
598 ComponentName2 protocol
599
600 @param[in] TheHandle The driver handle to get the name of.
601 @param[in] Language The language to use.
602
603 @retval NULL The name could not be found.
604 @return A pointer to the string name. Do not de-allocate the memory.
605 **/
606 CONST CHAR16*
607 EFIAPI
608 GetStringNameFromHandle(
609 IN CONST EFI_HANDLE TheHandle,
610 IN CONST CHAR8 *Language
611 )
612 {
613 EFI_COMPONENT_NAME2_PROTOCOL *CompNameStruct;
614 EFI_STATUS Status;
615 CHAR16 *RetVal;
616
617 Status = gBS->OpenProtocol(
618 TheHandle,
619 &gEfiComponentName2ProtocolGuid,
620 (VOID**)&CompNameStruct,
621 gImageHandle,
622 NULL,
623 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
624 if (!EFI_ERROR(Status)) {
625 Status = CompNameStruct->GetDriverName(CompNameStruct, (CHAR8*)Language, &RetVal);
626 if (!EFI_ERROR(Status)) {
627 return (RetVal);
628 }
629 }
630 Status = gBS->OpenProtocol(
631 TheHandle,
632 &gEfiComponentNameProtocolGuid,
633 (VOID**)&CompNameStruct,
634 gImageHandle,
635 NULL,
636 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
637 if (!EFI_ERROR(Status)) {
638 Status = CompNameStruct->GetDriverName(CompNameStruct, (CHAR8*)Language, &RetVal);
639 if (!EFI_ERROR(Status)) {
640 return (RetVal);
641 }
642 }
643 return (NULL);
644 }
645
646 /**
647 Function to initialize the file global mHandleList object for use in
648 vonverting handles to index and index to handle.
649
650 @retval EFI_SUCCESS The operation was successful.
651 **/
652 EFI_STATUS
653 EFIAPI
654 InternalShellInitHandleList(
655 VOID
656 )
657 {
658 EFI_STATUS Status;
659 EFI_HANDLE *HandleBuffer;
660 UINTN HandleCount;
661 HANDLE_LIST *ListWalker;
662
663 if (mHandleList.NextIndex != 0) {
664 return EFI_SUCCESS;
665 }
666 InitializeListHead(&mHandleList.List.Link);
667 mHandleList.NextIndex = 1;
668 Status = gBS->LocateHandleBuffer (
669 AllHandles,
670 NULL,
671 NULL,
672 &HandleCount,
673 &HandleBuffer
674 );
675 ASSERT_EFI_ERROR(Status);
676 if (EFI_ERROR(Status)) {
677 return (Status);
678 }
679 for (mHandleList.NextIndex = 1 ; mHandleList.NextIndex <= HandleCount ; mHandleList.NextIndex++){
680 ListWalker = AllocateZeroPool(sizeof(HANDLE_LIST));
681 ASSERT(ListWalker != NULL);
682 ListWalker->TheHandle = HandleBuffer[mHandleList.NextIndex-1];
683 ListWalker->TheIndex = mHandleList.NextIndex;
684 InsertTailList(&mHandleList.List.Link,&ListWalker->Link);
685 }
686 FreePool(HandleBuffer);
687 return (EFI_SUCCESS);
688 }
689
690 /**
691 Function to retrieve the human-friendly index of a given handle. If the handle
692 does not have a index one will be automatically assigned. The index value is valid
693 until the termination of the shell application.
694
695 @param[in] TheHandle The handle to retrieve an index for.
696
697 @retval 0 A memory allocation failed.
698 @return The index of the handle.
699
700 **/
701 UINTN
702 EFIAPI
703 ConvertHandleToHandleIndex(
704 IN CONST EFI_HANDLE TheHandle
705 )
706 {
707 HANDLE_LIST *ListWalker;
708 if (TheHandle == NULL) {
709 return 0;
710 }
711
712 InternalShellInitHandleList();
713
714 for (ListWalker = (HANDLE_LIST*)GetFirstNode(&mHandleList.List.Link)
715 ; !IsNull(&mHandleList.List.Link,&ListWalker->Link)
716 ; ListWalker = (HANDLE_LIST*)GetNextNode(&mHandleList.List.Link,&ListWalker->Link)
717 ){
718 if (ListWalker->TheHandle == TheHandle) {
719 return (ListWalker->TheIndex);
720 }
721 }
722 ListWalker = AllocateZeroPool(sizeof(HANDLE_LIST));
723 ASSERT(ListWalker != NULL);
724 ListWalker->TheHandle = TheHandle;
725 ListWalker->TheIndex = mHandleList.NextIndex++;
726 InsertTailList(&mHandleList.List.Link,&ListWalker->Link);
727 return (ListWalker->TheIndex);
728 }
729
730
731
732 /**
733 Function to retrieve the EFI_HANDLE from the human-friendly index.
734
735 @param[in] TheIndex The index to retrieve the EFI_HANDLE for.
736
737 @retval NULL The index was invalid.
738 @return The EFI_HANDLE that index represents.
739
740 **/
741 EFI_HANDLE
742 EFIAPI
743 ConvertHandleIndexToHandle(
744 IN CONST UINTN TheIndex
745 )
746 {
747 HANDLE_LIST *ListWalker;
748
749 InternalShellInitHandleList();
750
751 if (TheIndex >= mHandleList.NextIndex) {
752 return (NULL);
753 }
754
755 for (ListWalker = (HANDLE_LIST*)GetFirstNode(&mHandleList.List.Link)
756 ; !IsNull(&mHandleList.List.Link,&ListWalker->Link)
757 ; ListWalker = (HANDLE_LIST*)GetNextNode(&mHandleList.List.Link,&ListWalker->Link)
758 ){
759 if (ListWalker->TheIndex == TheIndex) {
760 return (ListWalker->TheHandle);
761 }
762 }
763 return (NULL);
764 }
765
766 /**
767 Gets all the related EFI_HANDLEs based on the mask supplied.
768
769 This function scans all EFI_HANDLES in the UEFI environment's handle database
770 and returns the ones with the specified relationship (Mask) to the specified
771 controller handle.
772
773 If both DriverBindingHandle and ControllerHandle are NULL, then ASSERT.
774 If MatchingHandleCount is NULL, then ASSERT.
775
776 If MatchingHandleBuffer is not NULL upon a successful return the memory must be
777 caller freed.
778
779 @param[in] DriverBindingHandle The handle with Driver Binding protocol on it.
780 @param[in] ControllerHandle The handle with Device Path protocol on it.
781 @param[in] MatchingHandleCount The pointer to UINTN that specifies the number of HANDLES in
782 MatchingHandleBuffer.
783 @param[out] MatchingHandleBuffer On a successful return, a buffer of MatchingHandleCount
784 EFI_HANDLEs with a terminating NULL EFI_HANDLE.
785 @param[out] HandleType An array of type information.
786
787 @retval EFI_SUCCESS The operation was successful, and any related handles
788 are in MatchingHandleBuffer.
789 @retval EFI_NOT_FOUND No matching handles were found.
790 @retval EFI_INVALID_PARAMETER A parameter was invalid or out of range.
791 **/
792 EFI_STATUS
793 EFIAPI
794 ParseHandleDatabaseByRelationshipWithType (
795 IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL,
796 IN CONST EFI_HANDLE ControllerHandle OPTIONAL,
797 IN UINTN *HandleCount,
798 OUT EFI_HANDLE **HandleBuffer,
799 OUT UINTN **HandleType
800 )
801 {
802 EFI_STATUS Status;
803 UINTN HandleIndex;
804 EFI_GUID **ProtocolGuidArray;
805 UINTN ArrayCount;
806 UINTN ProtocolIndex;
807 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;
808 UINTN OpenInfoCount;
809 UINTN OpenInfoIndex;
810 UINTN ChildIndex;
811
812 ASSERT(HandleCount != NULL);
813 ASSERT(HandleBuffer != NULL);
814 ASSERT(HandleType != NULL);
815 ASSERT(DriverBindingHandle != NULL || ControllerHandle != NULL);
816
817 *HandleCount = 0;
818 *HandleBuffer = NULL;
819 *HandleType = NULL;
820
821 //
822 // Retrieve the list of all handles from the handle database
823 //
824 Status = gBS->LocateHandleBuffer (
825 AllHandles,
826 NULL,
827 NULL,
828 HandleCount,
829 HandleBuffer
830 );
831 if (EFI_ERROR (Status)) {
832 return (Status);
833 }
834
835 *HandleType = AllocateZeroPool (*HandleCount * sizeof (UINTN));
836 ASSERT(*HandleType != NULL);
837
838 for (HandleIndex = 0; HandleIndex < *HandleCount; HandleIndex++) {
839 //
840 // Retrieve the list of all the protocols on each handle
841 //
842 Status = gBS->ProtocolsPerHandle (
843 (*HandleBuffer)[HandleIndex],
844 &ProtocolGuidArray,
845 &ArrayCount
846 );
847 if (!EFI_ERROR (Status)) {
848
849 for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
850
851 //
852 // Set the bit describing what this handle has
853 //
854 if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiLoadedImageProtocolGuid) ) {
855 (*HandleType)[HandleIndex] |= HR_IMAGE_HANDLE;
856 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverBindingProtocolGuid) ) {
857 (*HandleType)[HandleIndex] |= HR_DRIVER_BINDING_HANDLE;
858 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverConfiguration2ProtocolGuid)) {
859 (*HandleType)[HandleIndex] |= HR_DRIVER_CONFIGURATION_HANDLE;
860 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverConfigurationProtocolGuid) ) {
861 (*HandleType)[HandleIndex] |= HR_DRIVER_CONFIGURATION_HANDLE;
862 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverDiagnostics2ProtocolGuid) ) {
863 (*HandleType)[HandleIndex] |= HR_DRIVER_DIAGNOSTICS_HANDLE;
864 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverDiagnosticsProtocolGuid) ) {
865 (*HandleType)[HandleIndex] |= HR_DRIVER_DIAGNOSTICS_HANDLE;
866 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentName2ProtocolGuid) ) {
867 (*HandleType)[HandleIndex] |= HR_COMPONENT_NAME_HANDLE;
868 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentNameProtocolGuid) ) {
869 (*HandleType)[HandleIndex] |= HR_COMPONENT_NAME_HANDLE;
870 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDevicePathProtocolGuid) ) {
871 (*HandleType)[HandleIndex] |= HR_DEVICE_HANDLE;
872 } else {
873 DEBUG_CODE_BEGIN();
874 ASSERT((*HandleType)[HandleIndex] == (*HandleType)[HandleIndex]);
875 DEBUG_CODE_END();
876 }
877 //
878 // Retrieve the list of agents that have opened each protocol
879 //
880 Status = gBS->OpenProtocolInformation (
881 (*HandleBuffer)[HandleIndex],
882 ProtocolGuidArray[ProtocolIndex],
883 &OpenInfo,
884 &OpenInfoCount
885 );
886 if (!EFI_ERROR (Status)) {
887 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
888 if (DriverBindingHandle != NULL && OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) {
889 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) == EFI_OPEN_PROTOCOL_BY_DRIVER) {
890 (*HandleType)[HandleIndex] |= (HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);
891 }
892 if (ControllerHandle != NULL && (*HandleBuffer)[HandleIndex] == ControllerHandle) {
893 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {
894 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
895 if ((*HandleBuffer)[ChildIndex] == OpenInfo[OpenInfoIndex].ControllerHandle) {
896 (*HandleType)[ChildIndex] |= (HR_DEVICE_HANDLE | HR_CHILD_HANDLE);
897 }
898 }
899 }
900 }
901 }
902 if (DriverBindingHandle == NULL && OpenInfo[OpenInfoIndex].ControllerHandle == ControllerHandle) {
903 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) == EFI_OPEN_PROTOCOL_BY_DRIVER) {
904 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
905 if ((*HandleBuffer)[ChildIndex] == OpenInfo[OpenInfoIndex].AgentHandle) {
906 (*HandleType)[ChildIndex] |= HR_DEVICE_DRIVER;
907 }
908 }
909 }
910 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {
911 (*HandleType)[HandleIndex] |= HR_PARENT_HANDLE;
912 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
913 if ((*HandleBuffer)[ChildIndex] == OpenInfo[OpenInfoIndex].AgentHandle) {
914 (*HandleType)[ChildIndex] |= HR_BUS_DRIVER;
915 }
916 }
917 }
918 }
919 }
920
921 FreePool (OpenInfo);
922 }
923 }
924
925 FreePool (ProtocolGuidArray);
926 }
927 }
928
929 if (EFI_ERROR(Status)) {
930 if (*HandleType != NULL) {
931 FreePool (*HandleType);
932 }
933 if (*HandleBuffer != NULL) {
934 FreePool (*HandleBuffer);
935 }
936
937 *HandleCount = 0;
938 *HandleBuffer = NULL;
939 *HandleType = NULL;
940 }
941
942 return Status;
943 }
944
945 /**
946 Gets all the related EFI_HANDLEs based on the single EFI_HANDLE and the mask
947 supplied.
948
949 This function will scan all EFI_HANDLES in the UEFI environment's handle database
950 and return all the ones with the specified relationship (Mask) to the specified
951 controller handle.
952
953 If both DriverBindingHandle and ControllerHandle are NULL, then ASSERT.
954 If MatchingHandleCount is NULL, then ASSERT.
955
956 If MatchingHandleBuffer is not NULL upon a sucessful return the memory must be
957 caller freed.
958
959 @param[in] DriverBindingHandle Handle to a object with Driver Binding protocol
960 on it.
961 @param[in] ControllerHandle Handle to a device with Device Path protocol on it.
962 @param[in] Mask Mask of what relationship(s) is desired.
963 @param[in] MatchingHandleCount Poitner to UINTN specifying number of HANDLES in
964 MatchingHandleBuffer.
965 @param[out] MatchingHandleBuffer On a sucessful return a buffer of MatchingHandleCount
966 EFI_HANDLEs and a terminating NULL EFI_HANDLE.
967
968 @retval EFI_SUCCESS The operation was sucessful and any related handles
969 are in MatchingHandleBuffer;
970 @retval EFI_NOT_FOUND No matching handles were found.
971 @retval EFI_INVALID_PARAMETER A parameter was invalid or out of range.
972 **/
973 EFI_STATUS
974 EFIAPI
975 ParseHandleDatabaseByRelationship (
976 IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL,
977 IN CONST EFI_HANDLE ControllerHandle OPTIONAL,
978 IN CONST UINTN Mask,
979 IN UINTN *MatchingHandleCount,
980 OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL
981 )
982 {
983 EFI_STATUS Status;
984 UINTN HandleCount;
985 EFI_HANDLE *HandleBuffer;
986 UINTN *HandleType;
987 UINTN HandleIndex;
988
989 ASSERT(MatchingHandleCount != NULL);
990 ASSERT(DriverBindingHandle != NULL || ControllerHandle != NULL);
991
992 if ((Mask & HR_VALID_MASK) != Mask) {
993 return (EFI_INVALID_PARAMETER);
994 }
995
996 if ((Mask & HR_CHILD_HANDLE) != 0 && DriverBindingHandle == NULL) {
997 return (EFI_INVALID_PARAMETER);
998 }
999
1000 *MatchingHandleCount = 0;
1001 if (MatchingHandleBuffer != NULL) {
1002 *MatchingHandleBuffer = NULL;
1003 }
1004
1005 HandleBuffer = NULL;
1006 HandleType = NULL;
1007
1008 Status = ParseHandleDatabaseByRelationshipWithType (
1009 DriverBindingHandle,
1010 ControllerHandle,
1011 &HandleCount,
1012 &HandleBuffer,
1013 &HandleType
1014 );
1015 if (!EFI_ERROR (Status)) {
1016 //
1017 // Count the number of handles that match the attributes in Mask
1018 //
1019 for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
1020 if ((HandleType[HandleIndex] & Mask) == Mask) {
1021 (*MatchingHandleCount)++;
1022 }
1023 }
1024 //
1025 // If no handles match the attributes in Mask then return EFI_NOT_FOUND
1026 //
1027 if (*MatchingHandleCount == 0) {
1028 Status = EFI_NOT_FOUND;
1029 } else {
1030
1031 if (MatchingHandleBuffer == NULL) {
1032 //
1033 // Someone just wanted the count...
1034 //
1035 Status = EFI_SUCCESS;
1036 } else {
1037 //
1038 // Allocate a handle buffer for the number of handles that matched the attributes in Mask
1039 //
1040 *MatchingHandleBuffer = AllocateZeroPool ((*MatchingHandleCount +1)* sizeof (EFI_HANDLE));
1041 ASSERT(*MatchingHandleBuffer != NULL);
1042
1043 for (HandleIndex = 0,*MatchingHandleCount = 0
1044 ; HandleIndex < HandleCount
1045 ; HandleIndex++
1046 ){
1047 //
1048 // Fill the allocated buffer with the handles that matched the attributes in Mask
1049 //
1050 if ((HandleType[HandleIndex] & Mask) == Mask) {
1051 (*MatchingHandleBuffer)[(*MatchingHandleCount)++] = HandleBuffer[HandleIndex];
1052 }
1053 }
1054
1055 //
1056 // Make the last one NULL
1057 //
1058 (*MatchingHandleBuffer)[*MatchingHandleCount] = NULL;
1059
1060 Status = EFI_SUCCESS;
1061 } // MacthingHandleBuffer == NULL (ELSE)
1062 } // *MatchingHandleCount == 0 (ELSE)
1063 } // no error on ParseHandleDatabaseByRelationshipWithType
1064
1065 if (HandleBuffer != NULL) {
1066 FreePool (HandleBuffer);
1067 }
1068
1069 if (HandleType != NULL) {
1070 FreePool (HandleType);
1071 }
1072
1073 return Status;
1074 }
1075
1076 /**
1077 Gets handles for any child controllers of the passed in controller.
1078
1079 @param[in] ControllerHandle The handle of the "parent controller"
1080 @param[in] MatchingHandleCount Pointer to the number of handles in
1081 MatchingHandleBuffer on return.
1082 @param[out] MatchingHandleBuffer Buffer containing handles on a successful
1083 return.
1084
1085
1086 @retval EFI_SUCCESS The operation was sucessful.
1087 **/
1088 EFI_STATUS
1089 EFIAPI
1090 ParseHandleDatabaseForChildControllers(
1091 IN CONST EFI_HANDLE ControllerHandle,
1092 IN UINTN *MatchingHandleCount,
1093 OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL
1094 )
1095 {
1096 EFI_STATUS Status;
1097 // UINTN HandleIndex;
1098 UINTN DriverBindingHandleCount;
1099 EFI_HANDLE *DriverBindingHandleBuffer;
1100 UINTN DriverBindingHandleIndex;
1101 UINTN ChildControllerHandleCount;
1102 EFI_HANDLE *ChildControllerHandleBuffer;
1103 UINTN ChildControllerHandleIndex;
1104 // BOOLEAN Found;
1105 EFI_HANDLE *HandleBufferForReturn;
1106
1107 if (MatchingHandleCount == NULL) {
1108 return (EFI_INVALID_PARAMETER);
1109 }
1110 *MatchingHandleCount = 0;
1111
1112 Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
1113 ControllerHandle,
1114 &DriverBindingHandleCount,
1115 &DriverBindingHandleBuffer
1116 );
1117 if (EFI_ERROR (Status)) {
1118 return Status;
1119 }
1120
1121 //
1122 // Get a buffer big enough for all the controllers.
1123 //
1124 HandleBufferForReturn = GetHandleListByProtocol(&gEfiDevicePathProtocolGuid);
1125 if (HandleBufferForReturn == NULL) {
1126 FreePool (DriverBindingHandleBuffer);
1127 return (EFI_NOT_FOUND);
1128 }
1129
1130 for (DriverBindingHandleIndex = 0; DriverBindingHandleIndex < DriverBindingHandleCount; DriverBindingHandleIndex++) {
1131 Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
1132 DriverBindingHandleBuffer[DriverBindingHandleIndex],
1133 ControllerHandle,
1134 &ChildControllerHandleCount,
1135 &ChildControllerHandleBuffer
1136 );
1137 if (EFI_ERROR (Status)) {
1138 continue;
1139 }
1140
1141 for (ChildControllerHandleIndex = 0;
1142 ChildControllerHandleIndex < ChildControllerHandleCount;
1143 ChildControllerHandleIndex++
1144 ) {
1145 // Found = FALSE;
1146 HandleBufferForReturn[(*MatchingHandleCount)++] = ChildControllerHandleBuffer[ChildControllerHandleIndex];
1147 // for (HandleIndex = 0; HandleBufferForReturn[HandleIndex] != NULL; HandleIndex++) {
1148 // if (HandleBufferForReturn[HandleIndex] == ChildControllerHandleBuffer[ChildControllerHandleIndex]) {
1149 // Found = TRUE;
1150 // break;
1151 // }
1152 // }
1153
1154 // if (Found) {
1155 // HandleBufferForReturn[(*MatchingHandleCount)++] = ChildControllerHandleBuffer[ChildControllerHandleIndex];
1156 // }
1157 }
1158
1159 FreePool (ChildControllerHandleBuffer);
1160 }
1161
1162 FreePool (DriverBindingHandleBuffer);
1163
1164 if (MatchingHandleBuffer != NULL) {
1165 *MatchingHandleBuffer = HandleBufferForReturn;
1166 } else {
1167 FreePool(HandleBufferForReturn);
1168 }
1169
1170 return (EFI_SUCCESS);
1171 }
1172
1173 /**
1174 Appends 1 buffer to another buffer. This will re-allocate the destination buffer
1175 if necessary to fit all of the data.
1176
1177 If DestinationBuffer is NULL, then ASSERT().
1178
1179 @param[in, out] DestinationBuffer The pointer to the pointer to the buffer to append onto.
1180 @param[in, out] DestinationSize The pointer to the size of DestinationBuffer.
1181 @param[in] SourceBuffer The pointer to the buffer to append onto DestinationBuffer.
1182 @param[in] SourceSize The number of bytes of SourceBuffer to append.
1183
1184 @retval NULL A memory allocation failed.
1185 @retval NULL A parameter was invalid.
1186 @return A pointer to (*DestinationBuffer).
1187 **/
1188 VOID*
1189 EFIAPI
1190 BuffernCatGrow (
1191 IN OUT VOID **DestinationBuffer,
1192 IN OUT UINTN *DestinationSize,
1193 IN VOID *SourceBuffer,
1194 IN UINTN SourceSize
1195 )
1196 {
1197 UINTN LocalDestinationSize;
1198 UINTN LocalDestinationFinalSize;
1199
1200 ASSERT(DestinationBuffer != NULL);
1201
1202 if (SourceSize == 0 || SourceBuffer == NULL) {
1203 return (*DestinationBuffer);
1204 }
1205
1206 if (DestinationSize == NULL) {
1207 LocalDestinationSize = 0;
1208 } else {
1209 LocalDestinationSize = *DestinationSize;
1210 }
1211
1212 LocalDestinationFinalSize = LocalDestinationSize + SourceSize;
1213
1214 if (DestinationSize != NULL) {
1215 *DestinationSize = LocalDestinationSize;
1216 }
1217
1218 if (LocalDestinationSize == 0) {
1219 // allcoate
1220 *DestinationBuffer = AllocateZeroPool(LocalDestinationFinalSize);
1221 } else {
1222 // reallocate
1223 *DestinationBuffer = ReallocatePool(LocalDestinationSize, LocalDestinationFinalSize, *DestinationBuffer);
1224 }
1225
1226 ASSERT(*DestinationBuffer != NULL);
1227
1228 // copy
1229 return (CopyMem(((UINT8*)(*DestinationBuffer)) + LocalDestinationSize, SourceBuffer, SourceSize));
1230 }
1231
1232 /**
1233 Gets handles for any child devices produced by the passed in driver.
1234
1235 @param[in] DriverHandle The handle of the driver.
1236 @param[in] MatchingHandleCount Pointer to the number of handles in
1237 MatchingHandleBuffer on return.
1238 @param[out] MatchingHandleBuffer Buffer containing handles on a successful
1239 return.
1240 @retval EFI_SUCCESS The operation was sucessful.
1241 @sa ParseHandleDatabaseByRelationship
1242 **/
1243 EFI_STATUS
1244 EFIAPI
1245 ParseHandleDatabaseForChildDevices(
1246 IN CONST EFI_HANDLE DriverHandle,
1247 IN UINTN *MatchingHandleCount,
1248 OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL
1249 )
1250 {
1251 EFI_HANDLE *Buffer;
1252 EFI_HANDLE *Buffer2;
1253 UINTN Count1;
1254 UINTN Count2;
1255 UINTN HandleIndex;
1256 EFI_STATUS Status;
1257 UINTN HandleBufferSize;
1258
1259 ASSERT(MatchingHandleCount != NULL);
1260
1261 HandleBufferSize = 0;
1262 Buffer = NULL;
1263 Buffer2 = NULL;
1264 *MatchingHandleCount = 0;
1265
1266 Status = PARSE_HANDLE_DATABASE_DEVICES (
1267 DriverHandle,
1268 &Count1,
1269 &Buffer
1270 );
1271 if (!EFI_ERROR (Status)) {
1272 for (HandleIndex = 0; HandleIndex < Count1; HandleIndex++) {
1273 //
1274 // now find the children
1275 //
1276 Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
1277 DriverHandle,
1278 Buffer[HandleIndex],
1279 &Count2,
1280 &Buffer2
1281 );
1282 if (EFI_ERROR(Status)) {
1283 break;
1284 }
1285 //
1286 // save out required and optional data elements
1287 //
1288 *MatchingHandleCount += Count2;
1289 if (MatchingHandleBuffer != NULL) {
1290 *MatchingHandleBuffer = BuffernCatGrow((VOID**)MatchingHandleBuffer, &HandleBufferSize, Buffer2, Count2 * sizeof(Buffer2[0]));
1291 }
1292
1293 //
1294 // free the memory
1295 //
1296 if (Buffer2 != NULL) {
1297 FreePool(Buffer2);
1298 }
1299 }
1300 }
1301
1302 if (Buffer != NULL) {
1303 FreePool(Buffer);
1304 }
1305 return (Status);
1306 }
1307
1308 /**
1309 Function to get all handles that support a given protocol or all handles.
1310
1311 @param[in] ProtocolGuid The guid of the protocol to get handles for. If NULL
1312 then the function will return all handles.
1313
1314 @retval NULL A memory allocation failed.
1315 @return A NULL terminated list of handles.
1316 **/
1317 EFI_HANDLE*
1318 EFIAPI
1319 GetHandleListByProtocol (
1320 IN CONST EFI_GUID *ProtocolGuid OPTIONAL
1321 )
1322 {
1323 EFI_HANDLE *HandleList;
1324 UINTN Size;
1325 EFI_STATUS Status;
1326
1327 Size = 0;
1328 HandleList = NULL;
1329
1330 //
1331 // We cannot use LocateHandleBuffer since we need that NULL item on the ends of the list!
1332 //
1333 if (ProtocolGuid == NULL) {
1334 Status = gBS->LocateHandle(AllHandles, NULL, NULL, &Size, HandleList);
1335 if (Status == EFI_BUFFER_TOO_SMALL) {
1336 HandleList = AllocateZeroPool(Size + sizeof(EFI_HANDLE));
1337 if (HandleList == NULL) {
1338 return (NULL);
1339 }
1340 Status = gBS->LocateHandle(AllHandles, NULL, NULL, &Size, HandleList);
1341 HandleList[Size/sizeof(EFI_HANDLE)] = NULL;
1342 }
1343 } else {
1344 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)ProtocolGuid, NULL, &Size, HandleList);
1345 if (Status == EFI_BUFFER_TOO_SMALL) {
1346 HandleList = AllocateZeroPool(Size + sizeof(EFI_HANDLE));
1347 if (HandleList == NULL) {
1348 return (NULL);
1349 }
1350 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)ProtocolGuid, NULL, &Size, HandleList);
1351 HandleList[Size/sizeof(EFI_HANDLE)] = NULL;
1352 }
1353 }
1354 if (EFI_ERROR(Status)) {
1355 if (HandleList != NULL) {
1356 FreePool(HandleList);
1357 }
1358 return (NULL);
1359 }
1360 return (HandleList);
1361 }
1362
1363 /**
1364 Function to get all handles that support some protocols.
1365
1366 @param[in] ProtocolGuids A NULL terminated list of protocol GUIDs.
1367
1368 @retval NULL A memory allocation failed.
1369 @retval NULL ProtocolGuids was NULL.
1370 @return A NULL terminated list of EFI_HANDLEs.
1371 **/
1372 EFI_HANDLE*
1373 EFIAPI
1374 GetHandleListByProtocolList (
1375 IN CONST EFI_GUID **ProtocolGuids
1376 )
1377 {
1378 EFI_HANDLE *HandleList;
1379 UINTN Size;
1380 UINTN TotalSize;
1381 UINTN TempSize;
1382 EFI_STATUS Status;
1383 CONST EFI_GUID **GuidWalker;
1384 EFI_HANDLE *HandleWalker1;
1385 EFI_HANDLE *HandleWalker2;
1386
1387 Size = 0;
1388 HandleList = NULL;
1389 TotalSize = sizeof(EFI_HANDLE);
1390
1391 for (GuidWalker = ProtocolGuids ; GuidWalker != NULL && *GuidWalker != NULL ; GuidWalker++,Size = 0){
1392 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)(*GuidWalker), NULL, &Size, NULL);
1393 if (Status == EFI_BUFFER_TOO_SMALL) {
1394 TotalSize += Size;
1395 }
1396 }
1397
1398 //
1399 // No handles were found...
1400 //
1401 if (TotalSize == sizeof(EFI_HANDLE)) {
1402 return (NULL);
1403 }
1404
1405 HandleList = AllocateZeroPool(TotalSize);
1406 if (HandleList == NULL) {
1407 return (NULL);
1408 }
1409
1410 Size = 0;
1411 for (GuidWalker = ProtocolGuids ; GuidWalker != NULL && *GuidWalker != NULL ; GuidWalker++){
1412 TempSize = TotalSize - Size;
1413 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)(*GuidWalker), NULL, &TempSize, HandleList+(Size/sizeof(EFI_HANDLE)));
1414
1415 //
1416 // Allow for missing protocols... Only update the 'used' size upon success.
1417 //
1418 if (!EFI_ERROR(Status)) {
1419 Size += TempSize;
1420 }
1421 }
1422 ASSERT(HandleList[(TotalSize/sizeof(EFI_HANDLE))-1] == NULL);
1423
1424 for (HandleWalker1 = HandleList ; HandleWalker1 != NULL && *HandleWalker1 != NULL ; HandleWalker1++) {
1425 for (HandleWalker2 = HandleWalker1 + 1; HandleWalker2 != NULL && *HandleWalker2 != NULL ; HandleWalker2++) {
1426 if (*HandleWalker1 == *HandleWalker2) {
1427 //
1428 // copy memory back 1 handle width.
1429 //
1430 CopyMem(HandleWalker2, HandleWalker2 + 1, TotalSize - ((HandleWalker2-HandleList+1)*sizeof(EFI_HANDLE)));
1431 }
1432 }
1433 }
1434
1435 return (HandleList);
1436 }
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446