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