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