]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Application/CapsuleApp/CapsuleDump.c
MdeModulePkg CapsuleApp: Check Buffer against NULL before freeing it
[mirror_edk2.git] / MdeModulePkg / Application / CapsuleApp / CapsuleDump.c
CommitLineData
592bad04
JY
1/** @file\r
2 Dump Capsule image information.\r
3\r
2e3032b4 4 Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
592bad04
JY
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include <PiDxe.h>\r
16#include <Library/BaseLib.h>\r
17#include <Library/DebugLib.h>\r
18#include <Library/BaseMemoryLib.h>\r
19#include <Library/MemoryAllocationLib.h>\r
20#include <Library/UefiBootServicesTableLib.h>\r
21#include <Library/UefiRuntimeServicesTableLib.h>\r
22#include <Library/UefiLib.h>\r
23#include <Library/PrintLib.h>\r
24#include <Protocol/FirmwareManagement.h>\r
25#include <Guid/ImageAuthentication.h>\r
26#include <Guid/CapsuleReport.h>\r
27#include <Guid/SystemResourceTable.h>\r
28#include <Guid/FmpCapsule.h>\r
29#include <IndustryStandard/WindowsUxCapsule.h>\r
30\r
31/**\r
32 Read a file.\r
33\r
11ee1bc9
DB
34 @param[in] FileName The file to be read.\r
35 @param[out] BufferSize The file buffer size\r
36 @param[out] Buffer The file buffer\r
592bad04
JY
37\r
38 @retval EFI_SUCCESS Read file successfully\r
39 @retval EFI_NOT_FOUND File not found\r
40**/\r
41EFI_STATUS\r
42ReadFileToBuffer (\r
43 IN CHAR16 *FileName,\r
44 OUT UINTN *BufferSize,\r
45 OUT VOID **Buffer\r
46 );\r
47\r
1e09ec09
JY
48/**\r
49 Write a file.\r
50\r
51 @param[in] FileName The file to be written.\r
52 @param[in] BufferSize The file buffer size\r
53 @param[in] Buffer The file buffer\r
54\r
55 @retval EFI_SUCCESS Write file successfully\r
56**/\r
57EFI_STATUS\r
58WriteFileFromBuffer (\r
59 IN CHAR16 *FileName,\r
60 IN UINTN BufferSize,\r
61 IN VOID *Buffer\r
62 );\r
63\r
592bad04
JY
64/**\r
65 Dump UX capsule information.\r
66\r
67 @param[in] CapsuleHeader The UX capsule header\r
68**/\r
69VOID\r
70DumpUxCapsule (\r
71 IN EFI_CAPSULE_HEADER *CapsuleHeader\r
72 )\r
73{\r
74 EFI_DISPLAY_CAPSULE *DisplayCapsule;\r
75 DisplayCapsule = (EFI_DISPLAY_CAPSULE *)CapsuleHeader;\r
76 Print(L"[UxCapusule]\n");\r
77 Print(L"CapsuleHeader:\n");\r
78 Print(L" CapsuleGuid - %g\n", &DisplayCapsule->CapsuleHeader.CapsuleGuid);\r
79 Print(L" HeaderSize - 0x%x\n", DisplayCapsule->CapsuleHeader.HeaderSize);\r
80 Print(L" Flags - 0x%x\n", DisplayCapsule->CapsuleHeader.Flags);\r
81 Print(L" CapsuleImageSize - 0x%x\n", DisplayCapsule->CapsuleHeader.CapsuleImageSize);\r
82 Print(L"ImagePayload:\n");\r
83 Print(L" Version - 0x%x\n", DisplayCapsule->ImagePayload.Version);\r
84 Print(L" Checksum - 0x%x\n", DisplayCapsule->ImagePayload.Checksum);\r
85 Print(L" ImageType - 0x%x\n", DisplayCapsule->ImagePayload.ImageType);\r
86 Print(L" Mode - 0x%x\n", DisplayCapsule->ImagePayload.Mode);\r
87 Print(L" OffsetX - 0x%x\n", DisplayCapsule->ImagePayload.OffsetX);\r
88 Print(L" OffsetY - 0x%x\n", DisplayCapsule->ImagePayload.OffsetY);\r
89}\r
90\r
91/**\r
92 Dump FMP image authentication information.\r
93\r
94 @param[in] Image The FMP capsule image\r
95 @param[in] ImageSize The size of the FMP capsule image in bytes.\r
96\r
97 @return the size of FMP authentication.\r
98**/\r
99UINTN\r
100DumpImageAuthentication (\r
101 IN VOID *Image,\r
102 IN UINTN ImageSize\r
103 )\r
104{\r
105 EFI_FIRMWARE_IMAGE_AUTHENTICATION *ImageAuthentication;\r
106\r
107 ImageAuthentication = Image;\r
108 if (CompareGuid(&ImageAuthentication->AuthInfo.CertType, &gEfiCertPkcs7Guid) ||\r
109 CompareGuid(&ImageAuthentication->AuthInfo.CertType, &gEfiCertTypeRsa2048Sha256Guid)) {\r
110 Print(L"[ImageAuthentication]\n");\r
111 Print(L" MonotonicCount - 0x%lx\n", ImageAuthentication->MonotonicCount);\r
112 Print(L"WIN_CERTIFICATE:\n");\r
113 Print(L" dwLength - 0x%x\n", ImageAuthentication->AuthInfo.Hdr.dwLength);\r
114 Print(L" wRevision - 0x%x\n", ImageAuthentication->AuthInfo.Hdr.wRevision);\r
115 Print(L" wCertificateType - 0x%x\n", ImageAuthentication->AuthInfo.Hdr.wCertificateType);\r
116 Print(L" CertType - %g\n", &ImageAuthentication->AuthInfo.CertType);\r
117 return sizeof(ImageAuthentication->MonotonicCount) + ImageAuthentication->AuthInfo.Hdr.dwLength;\r
118 } else {\r
119 return 0;\r
120 }\r
121}\r
122\r
123/**\r
124 Dump a non-nested FMP capsule.\r
125\r
126 @param[in] CapsuleHeader A pointer to CapsuleHeader\r
127**/\r
128VOID\r
129DumpFmpCapsule (\r
130 IN EFI_CAPSULE_HEADER *CapsuleHeader\r
131 )\r
132{\r
133 EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *FmpCapsuleHeader;\r
134 UINT64 *ItemOffsetList;\r
135 UINTN Index;\r
136 UINTN Count;\r
137 EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *FmpImageHeader;\r
138\r
139 Print(L"[FmpCapusule]\n");\r
140 Print(L"CapsuleHeader:\n");\r
141 Print(L" CapsuleGuid - %g\n", &CapsuleHeader->CapsuleGuid);\r
142 Print(L" HeaderSize - 0x%x\n", CapsuleHeader->HeaderSize);\r
143 Print(L" Flags - 0x%x\n", CapsuleHeader->Flags);\r
144 Print(L" CapsuleImageSize - 0x%x\n", CapsuleHeader->CapsuleImageSize);\r
145\r
146 FmpCapsuleHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);\r
147 ItemOffsetList = (UINT64 *)(FmpCapsuleHeader + 1);\r
148 Print(L"FmpHeader:\n");\r
149 Print(L" Version - 0x%x\n", FmpCapsuleHeader->Version);\r
150 Print(L" EmbeddedDriverCount - 0x%x\n", FmpCapsuleHeader->EmbeddedDriverCount);\r
151 Print(L" PayloadItemCount - 0x%x\n", FmpCapsuleHeader->PayloadItemCount);\r
152 Count = FmpCapsuleHeader->EmbeddedDriverCount + FmpCapsuleHeader->PayloadItemCount;\r
153 for (Index = 0; Index < Count; Index++) {\r
154 Print(L" Offset[%d] - 0x%x\n", Index, ItemOffsetList[Index]);\r
155 }\r
156\r
157 for (Index = FmpCapsuleHeader->EmbeddedDriverCount; Index < Count; Index++) {\r
158 Print(L"FmpPayload[%d] ImageHeader:\n", Index);\r
159 FmpImageHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *)((UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index]);\r
160 Print(L" Version - 0x%x\n", FmpImageHeader->Version);\r
161 Print(L" UpdateImageTypeId - %g\n", &FmpImageHeader->UpdateImageTypeId);\r
162 Print(L" UpdateImageIndex - 0x%x\n", FmpImageHeader->UpdateImageIndex);\r
163 Print(L" UpdateImageSize - 0x%x\n", FmpImageHeader->UpdateImageSize);\r
164 Print(L" UpdateVendorCodeSize - 0x%x\n", FmpImageHeader->UpdateVendorCodeSize);\r
165 if (FmpImageHeader->Version >= EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) {\r
166 Print(L" UpdateHardwareInstance - 0x%lx\n", FmpImageHeader->UpdateHardwareInstance);\r
167 }\r
168 }\r
169}\r
170\r
171/**\r
172 Return if there is a FMP header below capsule header.\r
173\r
174 @param[in] CapsuleHeader A pointer to EFI_CAPSULE_HEADER\r
175\r
176 @retval TRUE There is a FMP header below capsule header.\r
177 @retval FALSE There is not a FMP header below capsule header\r
178**/\r
179BOOLEAN\r
180IsNestedFmpCapsule (\r
181 IN EFI_CAPSULE_HEADER *CapsuleHeader\r
182 )\r
183{\r
184 EFI_STATUS Status;\r
185 EFI_SYSTEM_RESOURCE_TABLE *Esrt;\r
186 EFI_SYSTEM_RESOURCE_ENTRY *EsrtEntry;\r
187 UINTN Index;\r
188 BOOLEAN EsrtGuidFound;\r
189 EFI_CAPSULE_HEADER *NestedCapsuleHeader;\r
190 UINTN NestedCapsuleSize;\r
191\r
192 //\r
193 // Check ESRT\r
194 //\r
195 EsrtGuidFound = FALSE;\r
196 Status = EfiGetSystemConfigurationTable(&gEfiSystemResourceTableGuid, (VOID **)&Esrt);\r
197 if (!EFI_ERROR(Status)) {\r
198 ASSERT (Esrt != NULL);\r
199 EsrtEntry = (VOID *)(Esrt + 1);\r
200 for (Index = 0; Index < Esrt->FwResourceCount; Index++, EsrtEntry++) {\r
201 if (CompareGuid(&EsrtEntry->FwClass, &CapsuleHeader->CapsuleGuid)) {\r
202 EsrtGuidFound = TRUE;\r
203 break;\r
204 }\r
205 }\r
206 }\r
207\r
208 if (!EsrtGuidFound) {\r
209 return FALSE;\r
210 }\r
211\r
212 //\r
213 // Check nested capsule header\r
214 // FMP GUID after ESRT one\r
215 //\r
216 NestedCapsuleHeader = (EFI_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);\r
217 NestedCapsuleSize = (UINTN)CapsuleHeader + CapsuleHeader->HeaderSize - (UINTN)NestedCapsuleHeader;\r
218 if (NestedCapsuleSize < sizeof(EFI_CAPSULE_HEADER)) {\r
219 return FALSE;\r
220 }\r
221 if (!CompareGuid(&NestedCapsuleHeader->CapsuleGuid, &gEfiFmpCapsuleGuid)) {\r
222 return FALSE;\r
223 }\r
224 return TRUE;\r
225}\r
226\r
227/**\r
228 Dump capsule information\r
229\r
230 @param[in] CapsuleName The name of the capsule image.\r
231\r
232 @retval EFI_SUCCESS The capsule information is dumped.\r
233 @retval EFI_UNSUPPORTED Input parameter is not valid.\r
234**/\r
235EFI_STATUS\r
236DumpCapsule (\r
237 IN CHAR16 *CapsuleName\r
238 )\r
239{\r
240 VOID *Buffer;\r
241 UINTN FileSize;\r
242 EFI_CAPSULE_HEADER *CapsuleHeader;\r
243 EFI_STATUS Status;\r
244\r
2e3032b4 245 Buffer = NULL;\r
592bad04
JY
246 Status = ReadFileToBuffer(CapsuleName, &FileSize, &Buffer);\r
247 if (EFI_ERROR(Status)) {\r
248 Print(L"CapsuleApp: Capsule (%s) is not found.\n", CapsuleName);\r
249 goto Done;\r
250 }\r
251\r
252 CapsuleHeader = Buffer;\r
253 if (CompareGuid(&CapsuleHeader->CapsuleGuid, &gWindowsUxCapsuleGuid)) {\r
254 DumpUxCapsule(CapsuleHeader);\r
255 Status = EFI_SUCCESS;\r
256 goto Done;\r
257 }\r
258\r
259 if (CompareGuid(&CapsuleHeader->CapsuleGuid, &gEfiFmpCapsuleGuid)) {\r
260 DumpFmpCapsule(CapsuleHeader);\r
261 }\r
262 if (IsNestedFmpCapsule(CapsuleHeader)) {\r
263 Print(L"[NestedCapusule]\n");\r
264 Print(L"CapsuleHeader:\n");\r
265 Print(L" CapsuleGuid - %g\n", &CapsuleHeader->CapsuleGuid);\r
266 Print(L" HeaderSize - 0x%x\n", CapsuleHeader->HeaderSize);\r
267 Print(L" Flags - 0x%x\n", CapsuleHeader->Flags);\r
268 Print(L" CapsuleImageSize - 0x%x\n", CapsuleHeader->CapsuleImageSize);\r
269 DumpFmpCapsule((EFI_CAPSULE_HEADER *)((UINTN)CapsuleHeader + CapsuleHeader->HeaderSize));\r
270 }\r
271\r
272Done:\r
2e3032b4
SZ
273 if (Buffer != NULL) {\r
274 FreePool(Buffer);\r
275 }\r
592bad04
JY
276 return Status;\r
277}\r
278\r
279/**\r
280 Dump capsule status variable.\r
281\r
282 @retval EFI_SUCCESS The capsule status variable is dumped.\r
283 @retval EFI_UNSUPPORTED Input parameter is not valid.\r
284**/\r
285EFI_STATUS\r
286DmpCapsuleStatusVariable (\r
287 VOID\r
288 )\r
289{\r
290 EFI_STATUS Status;\r
291 UINT32 Index;\r
292 CHAR16 CapsuleVarName[20];\r
293 CHAR16 *TempVarName;\r
294 EFI_CAPSULE_RESULT_VARIABLE_HEADER *CapsuleResult;\r
295 EFI_CAPSULE_RESULT_VARIABLE_FMP *CapsuleResultFmp;\r
296 UINTN CapsuleFileNameSize;\r
297 CHAR16 CapsuleIndexData[12];\r
298 CHAR16 *CapsuleIndex;\r
de5209d5
JY
299 CHAR16 *CapsuleFileName;\r
300 CHAR16 *CapsuleTarget;\r
592bad04
JY
301\r
302 Status = GetVariable2(\r
303 L"CapsuleMax",\r
304 &gEfiCapsuleReportGuid,\r
305 (VOID **)&CapsuleIndex,\r
306 NULL\r
307 );\r
308 if (!EFI_ERROR(Status)) {\r
a522ad7c 309 ASSERT (CapsuleIndex != NULL);\r
592bad04
JY
310 CopyMem(CapsuleIndexData, CapsuleIndex, 11 * sizeof(CHAR16));\r
311 CapsuleIndexData[11] = 0;\r
312 Print(L"CapsuleMax - %s\n", CapsuleIndexData);\r
313 FreePool(CapsuleIndex);\r
314 }\r
315 Status = GetVariable2(\r
316 L"CapsuleLast",\r
317 &gEfiCapsuleReportGuid,\r
318 (VOID **)&CapsuleIndex,\r
319 NULL\r
320 );\r
321 if (!EFI_ERROR(Status)) {\r
a522ad7c 322 ASSERT (CapsuleIndex != NULL);\r
592bad04
JY
323 CopyMem(CapsuleIndexData, CapsuleIndex, 11 * sizeof(CHAR16));\r
324 CapsuleIndexData[11] = 0;\r
325 Print(L"CapsuleLast - %s\n", CapsuleIndexData);\r
326 FreePool(CapsuleIndex);\r
327 }\r
328\r
329\r
330 StrCpyS (CapsuleVarName, sizeof(CapsuleVarName)/sizeof(CapsuleVarName[0]), L"Capsule");\r
331 TempVarName = CapsuleVarName + StrLen (CapsuleVarName);\r
332 Index = 0;\r
333\r
334 while (TRUE) {\r
335 UnicodeSPrint (TempVarName, 5 * sizeof(CHAR16), L"%04x", Index);\r
336\r
337 Status = GetVariable2 (\r
338 CapsuleVarName,\r
339 &gEfiCapsuleReportGuid,\r
340 (VOID **) &CapsuleResult,\r
341 NULL\r
342 );\r
343 if (Status == EFI_NOT_FOUND) {\r
344 break;\r
345 } else if (EFI_ERROR(Status)) {\r
346 continue;\r
347 }\r
348 ASSERT (CapsuleResult != NULL);\r
349\r
350 //\r
351 // display capsule process status\r
352 //\r
353 if (CapsuleResult->VariableTotalSize >= sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER)) {\r
354 Print (L"CapsuleName: %s\n", CapsuleVarName);\r
355 Print (L" Capsule Guid: %g\n", &CapsuleResult->CapsuleGuid);\r
356 Print (L" Capsule ProcessedTime: %t\n", &CapsuleResult->CapsuleProcessed);\r
357 Print (L" Capsule Status: %r\n", CapsuleResult->CapsuleStatus);\r
358 }\r
359\r
360 if (CompareGuid(&CapsuleResult->CapsuleGuid, &gEfiFmpCapsuleGuid)) {\r
de5209d5 361 if (CapsuleResult->VariableTotalSize >= sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof(EFI_CAPSULE_RESULT_VARIABLE_FMP) + sizeof(CHAR16) * 2) {\r
592bad04
JY
362 CapsuleResultFmp = (EFI_CAPSULE_RESULT_VARIABLE_FMP *)(CapsuleResult + 1);\r
363 Print(L" Capsule FMP Version: 0x%x\n", CapsuleResultFmp->Version);\r
364 Print(L" Capsule FMP PayloadIndex: 0x%x\n", CapsuleResultFmp->PayloadIndex);\r
365 Print(L" Capsule FMP UpdateImageIndex: 0x%x\n", CapsuleResultFmp->UpdateImageIndex);\r
366 Print(L" Capsule FMP UpdateImageTypeId: %g\n", &CapsuleResultFmp->UpdateImageTypeId);\r
de5209d5
JY
367 CapsuleFileName = (CHAR16 *)(CapsuleResultFmp + 1);\r
368 Print(L" Capsule FMP CapsuleFileName: \"%s\"\n", CapsuleFileName);\r
369 CapsuleFileNameSize = StrSize(CapsuleFileName);\r
370 CapsuleTarget = (CHAR16 *)((UINTN)CapsuleFileName + CapsuleFileNameSize);\r
371 Print(L" Capsule FMP CapsuleTarget: \"%s\"\n", CapsuleTarget);\r
592bad04
JY
372 }\r
373 }\r
374\r
375 FreePool(CapsuleResult);\r
376\r
377 Index++;\r
378 if (Index > 0xFFFF) {\r
379 break;\r
380 }\r
381 }\r
382\r
383 return EFI_SUCCESS;\r
384}\r
385\r
386CHAR8 *mFwTypeString[] = {\r
387 "Unknown",\r
388 "SystemFirmware",\r
389 "DeviceFirmware",\r
390 "UefiDriver",\r
391};\r
392\r
393CHAR8 *mLastAttemptStatusString[] = {\r
394 "Success",\r
395 "Error: Unsuccessful",\r
396 "Error: Insufficient Resources",\r
397 "Error: Incorrect Version",\r
398 "Error: Invalid Format",\r
399 "Error: Auth Error",\r
400 "Error: Power Event AC",\r
401 "Error: Power Event Battery",\r
402};\r
403\r
404/**\r
405 Convert FwType to a string.\r
406\r
407 @param[in] FwType FwType in ESRT\r
408\r
409 @return a string for FwType.\r
410**/\r
411CHAR8 *\r
412FwTypeToString (\r
413 IN UINT32 FwType\r
414 )\r
415{\r
416 if (FwType < sizeof(mFwTypeString) / sizeof(mFwTypeString[0])) {\r
417 return mFwTypeString[FwType];\r
418 } else {\r
419 return "Invalid";\r
420 }\r
421}\r
422\r
423/**\r
424 Convert LastAttemptStatus to a string.\r
425\r
426 @param[in] LastAttemptStatus LastAttemptStatus in FMP or ESRT\r
427\r
428 @return a string for LastAttemptStatus.\r
429**/\r
430CHAR8 *\r
431LastAttemptStatusToString (\r
432 IN UINT32 LastAttemptStatus\r
433 )\r
434{\r
435 if (LastAttemptStatus < sizeof(mLastAttemptStatusString) / sizeof(mLastAttemptStatusString[0])) {\r
436 return mLastAttemptStatusString[LastAttemptStatus];\r
437 } else {\r
438 return "Error: Unknown";\r
439 }\r
440}\r
441\r
442/**\r
443 Dump ESRT entry.\r
444\r
445 @param[in] EsrtEntry ESRT entry\r
446**/\r
447VOID\r
448DumpEsrtEntry (\r
449 IN EFI_SYSTEM_RESOURCE_ENTRY *EsrtEntry\r
450 )\r
451{\r
452 Print(L" FwClass - %g\n", &EsrtEntry->FwClass);\r
453 Print(L" FwType - 0x%x (%a)\n", EsrtEntry->FwType, FwTypeToString(EsrtEntry->FwType));\r
454 Print(L" FwVersion - 0x%x\n", EsrtEntry->FwVersion);\r
455 Print(L" LowestSupportedFwVersion - 0x%x\n", EsrtEntry->LowestSupportedFwVersion);\r
456 Print(L" CapsuleFlags - 0x%x\n", EsrtEntry->CapsuleFlags);\r
457 Print(L" PERSIST_ACROSS_RESET - 0x%x\n", EsrtEntry->CapsuleFlags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET);\r
458 Print(L" POPULATE_SYSTEM_TABLE - 0x%x\n", EsrtEntry->CapsuleFlags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE);\r
459 Print(L" INITIATE_RESET - 0x%x\n", EsrtEntry->CapsuleFlags & CAPSULE_FLAGS_INITIATE_RESET);\r
460 Print(L" LastAttemptVersion - 0x%x\n", EsrtEntry->LastAttemptVersion);\r
461 Print(L" LastAttemptStatus - 0x%x (%a)\n", EsrtEntry->LastAttemptStatus, LastAttemptStatusToString(EsrtEntry->LastAttemptStatus));\r
462}\r
463\r
464/**\r
465 Dump ESRT table.\r
466\r
467 @param[in] Esrt ESRT table\r
468**/\r
469VOID\r
470DumpEsrt (\r
471 IN EFI_SYSTEM_RESOURCE_TABLE *Esrt\r
472 )\r
473{\r
474 UINTN Index;\r
475 EFI_SYSTEM_RESOURCE_ENTRY *EsrtEntry;\r
476\r
477 if (Esrt == NULL) {\r
478 return ;\r
479 }\r
480\r
481 Print(L"EFI_SYSTEM_RESOURCE_TABLE:\n");\r
482 Print(L"FwResourceCount - 0x%x\n", Esrt->FwResourceCount);\r
483 Print(L"FwResourceCountMax - 0x%x\n", Esrt->FwResourceCountMax);\r
484 Print(L"FwResourceVersion - 0x%lx\n", Esrt->FwResourceVersion);\r
485\r
486 EsrtEntry = (VOID *)(Esrt + 1);\r
487 for (Index = 0; Index < Esrt->FwResourceCount; Index++) {\r
488 Print(L"EFI_SYSTEM_RESOURCE_ENTRY (%d):\n", Index);\r
489 DumpEsrtEntry(EsrtEntry);\r
490 EsrtEntry++;\r
491 }\r
492}\r
493\r
494/**\r
495 Dump ESRT info.\r
496**/\r
497VOID\r
498DumpEsrtData (\r
499 VOID\r
500 )\r
501{\r
502 EFI_STATUS Status;\r
503 EFI_SYSTEM_RESOURCE_TABLE *Esrt;\r
504\r
505 Print(L"##############\n");\r
506 Print(L"# ESRT TABLE #\n");\r
507 Print(L"##############\n");\r
508\r
509 Status = EfiGetSystemConfigurationTable (&gEfiSystemResourceTableGuid, (VOID **)&Esrt);\r
510 if (EFI_ERROR(Status)) {\r
511 Print(L"ESRT - %r\n", Status);\r
512 return;\r
513 }\r
514 DumpEsrt(Esrt);\r
515 Print(L"\n");\r
516}\r
517\r
518/**\r
519 Dump FMP information.\r
520\r
521 @param[in] ImageInfoSize The size of ImageInfo, in bytes.\r
522 @param[in] ImageInfo A pointer to EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
523 @param[in] DescriptorVersion The version of EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
524 @param[in] DescriptorCount The count of EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
525 @param[in] DescriptorSize The size of an individual EFI_FIRMWARE_IMAGE_DESCRIPTOR, in bytes.\r
526 @param[in] PackageVersion The version of package.\r
527 @param[in] PackageVersionName The version name of package.\r
528**/\r
529VOID\r
530DumpFmpImageInfo (\r
531 IN UINTN ImageInfoSize,\r
532 IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageInfo,\r
533 IN UINT32 DescriptorVersion,\r
534 IN UINT8 DescriptorCount,\r
535 IN UINTN DescriptorSize,\r
536 IN UINT32 PackageVersion,\r
537 IN CHAR16 *PackageVersionName\r
538 )\r
539{\r
540 EFI_FIRMWARE_IMAGE_DESCRIPTOR *CurrentImageInfo;\r
541 UINTN Index;\r
542\r
543 Print(L" DescriptorVersion - 0x%x\n", DescriptorVersion);\r
544 Print(L" DescriptorCount - 0x%x\n", DescriptorCount);\r
545 Print(L" DescriptorSize - 0x%x\n", DescriptorSize);\r
546 Print(L" PackageVersion - 0x%x\n", PackageVersion);\r
547 Print(L" PackageVersionName - \"%s\"\n", PackageVersionName);\r
548 CurrentImageInfo = ImageInfo;\r
549 for (Index = 0; Index < DescriptorCount; Index++) {\r
550 Print(L" ImageDescriptor (%d)\n", Index);\r
551 Print(L" ImageIndex - 0x%x\n", CurrentImageInfo->ImageIndex);\r
552 Print(L" ImageTypeId - %g\n", &CurrentImageInfo->ImageTypeId);\r
553 Print(L" ImageId - 0x%lx\n", CurrentImageInfo->ImageId);\r
554 Print(L" ImageIdName - \"%s\"\n", CurrentImageInfo->ImageIdName);\r
555 Print(L" Version - 0x%x\n", CurrentImageInfo->Version);\r
556 Print(L" VersionName - \"%s\"\n", CurrentImageInfo->VersionName);\r
557 Print(L" Size - 0x%x\n", CurrentImageInfo->Size);\r
558 Print(L" AttributesSupported - 0x%lx\n", CurrentImageInfo->AttributesSupported);\r
559 Print(L" IMAGE_UPDATABLE - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);\r
560 Print(L" RESET_REQUIRED - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_RESET_REQUIRED);\r
561 Print(L" AUTHENTICATION_REQUIRED - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);\r
562 Print(L" IN_USE - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_IN_USE);\r
563 Print(L" UEFI_IMAGE - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_UEFI_IMAGE);\r
564 Print(L" AttributesSetting - 0x%lx\n", CurrentImageInfo->AttributesSetting);\r
565 Print(L" IMAGE_UPDATABLE - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);\r
566 Print(L" RESET_REQUIRED - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_RESET_REQUIRED);\r
567 Print(L" AUTHENTICATION_REQUIRED - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);\r
568 Print(L" IN_USE - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_IN_USE);\r
569 Print(L" UEFI_IMAGE - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_UEFI_IMAGE);\r
570 Print(L" Compatibilities - 0x%lx\n", CurrentImageInfo->Compatibilities);\r
571 Print(L" COMPATIB_CHECK_SUPPORTED - 0x%lx\n", CurrentImageInfo->Compatibilities & IMAGE_COMPATIBILITY_CHECK_SUPPORTED);\r
572 if (DescriptorVersion > 1) {\r
573 Print(L" LowestSupportedImageVersion - 0x%x\n", CurrentImageInfo->LowestSupportedImageVersion);\r
574 if (DescriptorVersion > 2) {\r
575 Print(L" LastAttemptVersion - 0x%x\n", CurrentImageInfo->LastAttemptVersion);\r
576 Print(L" LastAttemptStatus - 0x%x (%a)\n", CurrentImageInfo->LastAttemptStatus, LastAttemptStatusToString(CurrentImageInfo->LastAttemptStatus));\r
577 Print(L" HardwareInstance - 0x%lx\n", CurrentImageInfo->HardwareInstance);\r
578 }\r
579 }\r
580 //\r
581 // Use DescriptorSize to move ImageInfo Pointer to stay compatible with different ImageInfo version\r
582 //\r
583 CurrentImageInfo = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)((UINT8 *)CurrentImageInfo + DescriptorSize);\r
584 }\r
585}\r
586\r
587/**\r
588 Dump FMP package information.\r
589\r
590 @param[in] PackageVersion The version of package.\r
591 @param[in] PackageVersionName The version name of package.\r
592 @param[in] PackageVersionNameMaxLen The maximum length of PackageVersionName.\r
593 @param[in] AttributesSupported Package attributes that are supported by this device.\r
594 @param[in] AttributesSetting Package attributes.\r
595**/\r
596VOID\r
597DumpFmpPackageInfo (\r
598 IN UINT32 PackageVersion,\r
599 IN CHAR16 *PackageVersionName,\r
600 IN UINT32 PackageVersionNameMaxLen,\r
601 IN UINT64 AttributesSupported,\r
602 IN UINT64 AttributesSetting\r
603 )\r
604{\r
605 Print(L" PackageVersion - 0x%x\n", PackageVersion);\r
606 Print(L" PackageVersionName - \"%s\"\n", PackageVersionName);\r
607 Print(L" PackageVersionNameMaxLen - 0x%x\n", PackageVersionNameMaxLen);\r
608 Print(L" AttributesSupported - 0x%lx\n", AttributesSupported);\r
609 Print(L" IMAGE_UPDATABLE - 0x%lx\n", AttributesSupported & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);\r
610 Print(L" RESET_REQUIRED - 0x%lx\n", AttributesSupported & IMAGE_ATTRIBUTE_RESET_REQUIRED);\r
611 Print(L" AUTHENTICATION_REQUIRED - 0x%lx\n", AttributesSupported & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);\r
612 Print(L" AttributesSetting - 0x%lx\n", AttributesSetting);\r
613 Print(L" IMAGE_UPDATABLE - 0x%lx\n", AttributesSetting & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);\r
614 Print(L" RESET_REQUIRED - 0x%lx\n", AttributesSetting & IMAGE_ATTRIBUTE_RESET_REQUIRED);\r
615 Print(L" AUTHENTICATION_REQUIRED - 0x%lx\n", AttributesSetting & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);\r
616}\r
617\r
618/**\r
619 Dump FMP protocol info.\r
620**/\r
621VOID\r
622DumpFmpData (\r
623 VOID\r
624 )\r
625{\r
626 EFI_STATUS Status;\r
627 EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;\r
628 EFI_HANDLE *HandleBuffer;\r
629 UINTN NumberOfHandles;\r
630 UINTN Index;\r
631 EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf;\r
632 UINTN ImageInfoSize;\r
633 UINT32 FmpImageInfoDescriptorVer;\r
634 UINT8 FmpImageInfoCount;\r
635 UINTN DescriptorSize;\r
636 UINT32 PackageVersion;\r
637 CHAR16 *PackageVersionName;\r
638 UINT32 PackageVersionNameMaxLen;\r
639 UINT64 AttributesSupported;\r
640 UINT64 AttributesSetting;\r
641\r
642 Print(L"############\n");\r
643 Print(L"# FMP DATA #\n");\r
644 Print(L"############\n");\r
645 Status = gBS->LocateHandleBuffer (\r
646 ByProtocol,\r
647 &gEfiFirmwareManagementProtocolGuid,\r
648 NULL,\r
649 &NumberOfHandles,\r
650 &HandleBuffer\r
651 );\r
652 if (EFI_ERROR(Status)) {\r
653 Print(L"FMP protocol - %r\n", EFI_NOT_FOUND);\r
654 return;\r
655 }\r
656\r
657 for (Index = 0; Index < NumberOfHandles; Index++) {\r
658 Status = gBS->HandleProtocol(\r
659 HandleBuffer[Index],\r
660 &gEfiFirmwareManagementProtocolGuid,\r
661 (VOID **)&Fmp\r
662 );\r
663 if (EFI_ERROR(Status)) {\r
664 continue;\r
665 }\r
666\r
667 ImageInfoSize = 0;\r
668 Status = Fmp->GetImageInfo (\r
669 Fmp,\r
670 &ImageInfoSize,\r
671 NULL,\r
672 NULL,\r
673 NULL,\r
674 NULL,\r
675 NULL,\r
676 NULL\r
677 );\r
678 if (Status != EFI_BUFFER_TOO_SMALL) {\r
679 continue;\r
680 }\r
681\r
682 FmpImageInfoBuf = NULL;\r
683 FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);\r
684 if (FmpImageInfoBuf == NULL) {\r
685 Status = EFI_OUT_OF_RESOURCES;\r
686 goto EXIT;\r
687 }\r
688\r
689 PackageVersionName = NULL;\r
690 Status = Fmp->GetImageInfo (\r
691 Fmp,\r
692 &ImageInfoSize, // ImageInfoSize\r
693 FmpImageInfoBuf, // ImageInfo\r
694 &FmpImageInfoDescriptorVer, // DescriptorVersion\r
695 &FmpImageInfoCount, // DescriptorCount\r
696 &DescriptorSize, // DescriptorSize\r
697 &PackageVersion, // PackageVersion\r
698 &PackageVersionName // PackageVersionName\r
699 );\r
700\r
701 //\r
702 // If FMP GetInformation interface failed, skip this resource\r
703 //\r
704 if (EFI_ERROR(Status)) {\r
705 Print(L"FMP (%d) ImageInfo - %r\n", Index, Status);\r
706 FreePool(FmpImageInfoBuf);\r
707 continue;\r
708 }\r
709\r
710 Print(L"FMP (%d) ImageInfo:\n", Index);\r
711 DumpFmpImageInfo(\r
712 ImageInfoSize, // ImageInfoSize\r
713 FmpImageInfoBuf, // ImageInfo\r
714 FmpImageInfoDescriptorVer, // DescriptorVersion\r
715 FmpImageInfoCount, // DescriptorCount\r
716 DescriptorSize, // DescriptorSize\r
717 PackageVersion, // PackageVersion\r
718 PackageVersionName // PackageVersionName\r
719 );\r
720\r
721 if (PackageVersionName != NULL) {\r
722 FreePool(PackageVersionName);\r
723 }\r
724 FreePool(FmpImageInfoBuf);\r
725\r
726 //\r
727 // Get package info\r
728 //\r
729 PackageVersionName = NULL;\r
730 Status = Fmp->GetPackageInfo (\r
731 Fmp,\r
732 &PackageVersion, // PackageVersion\r
733 &PackageVersionName, // PackageVersionName\r
734 &PackageVersionNameMaxLen, // PackageVersionNameMaxLen\r
735 &AttributesSupported, // AttributesSupported\r
736 &AttributesSetting // AttributesSetting\r
737 );\r
738 if (EFI_ERROR(Status)) {\r
739 Print(L"FMP (%d) PackageInfo - %r\n", Index, Status);\r
740 } else {\r
741 Print(L"FMP (%d) ImageInfo:\n", Index);\r
742 DumpFmpPackageInfo(\r
743 PackageVersion, // PackageVersion\r
744 PackageVersionName, // PackageVersionName\r
745 PackageVersionNameMaxLen, // PackageVersionNameMaxLen\r
746 AttributesSupported, // AttributesSupported\r
747 AttributesSetting // AttributesSetting\r
748 );\r
749\r
750 if (PackageVersionName != NULL) {\r
751 FreePool(PackageVersionName);\r
752 }\r
753 }\r
754 }\r
755 Print(L"\n");\r
756\r
757EXIT:\r
758 FreePool(HandleBuffer);\r
759}\r
1e09ec09
JY
760\r
761/**\r
762 Check if the ImageInfo includes the ImageTypeId.\r
763\r
764 @param[in] ImageInfo A pointer to EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
765 @param[in] DescriptorCount The count of EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
766 @param[in] DescriptorSize The size of an individual EFI_FIRMWARE_IMAGE_DESCRIPTOR, in bytes.\r
767 @param[in] ImageTypeId A unique GUID identifying the firmware image type.\r
768\r
769 @return TRUE This ImageInfo includes the ImageTypeId\r
770 @return FALSE This ImageInfo does not include the ImageTypeId\r
771**/\r
772BOOLEAN\r
773IsThisFmpImageInfo (\r
774 IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageInfo,\r
775 IN UINT8 DescriptorCount,\r
776 IN UINTN DescriptorSize,\r
777 IN EFI_GUID *ImageTypeId\r
778 )\r
779{\r
780 EFI_FIRMWARE_IMAGE_DESCRIPTOR *CurrentImageInfo;\r
781 UINTN Index;\r
782\r
783 CurrentImageInfo = ImageInfo;\r
784 for (Index = 0; Index < DescriptorCount; Index++) {\r
785 if (CompareGuid (&CurrentImageInfo->ImageTypeId, ImageTypeId)) {\r
786 return TRUE;\r
787 }\r
788 CurrentImageInfo = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)((UINT8 *)CurrentImageInfo + DescriptorSize);\r
789 }\r
790 return FALSE;\r
791}\r
792\r
793/**\r
794 return the FMP whoes ImageInfo includes the ImageTypeId.\r
795\r
796 @param[in] ImageTypeId A unique GUID identifying the firmware image type.\r
797\r
798 @return The FMP whoes ImageInfo includes the ImageTypeId\r
799**/\r
800EFI_FIRMWARE_MANAGEMENT_PROTOCOL *\r
801FindFmpFromImageTypeId (\r
802 IN EFI_GUID *ImageTypeId\r
803 )\r
804{\r
805 EFI_STATUS Status;\r
806 EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;\r
807 EFI_FIRMWARE_MANAGEMENT_PROTOCOL *TargetFmp;\r
808 EFI_HANDLE *HandleBuffer;\r
809 UINTN NumberOfHandles;\r
810 UINTN Index;\r
811 EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf;\r
812 UINTN ImageInfoSize;\r
813 UINT32 FmpImageInfoDescriptorVer;\r
814 UINT8 FmpImageInfoCount;\r
815 UINTN DescriptorSize;\r
816 UINT32 PackageVersion;\r
817 CHAR16 *PackageVersionName;\r
818\r
819 Status = gBS->LocateHandleBuffer (\r
820 ByProtocol,\r
821 &gEfiFirmwareManagementProtocolGuid,\r
822 NULL,\r
823 &NumberOfHandles,\r
824 &HandleBuffer\r
825 );\r
826 if (EFI_ERROR(Status)) {\r
827 Print(L"FMP protocol - %r\n", EFI_NOT_FOUND);\r
828 return NULL;\r
829 }\r
830\r
831 TargetFmp = NULL;\r
832 for (Index = 0; Index < NumberOfHandles; Index++) {\r
833 Status = gBS->HandleProtocol(\r
834 HandleBuffer[Index],\r
835 &gEfiFirmwareManagementProtocolGuid,\r
836 (VOID **)&Fmp\r
837 );\r
838 if (EFI_ERROR(Status)) {\r
839 continue;\r
840 }\r
841\r
842 ImageInfoSize = 0;\r
843 Status = Fmp->GetImageInfo (\r
844 Fmp,\r
845 &ImageInfoSize,\r
846 NULL,\r
847 NULL,\r
848 NULL,\r
849 NULL,\r
850 NULL,\r
851 NULL\r
852 );\r
853 if (Status != EFI_BUFFER_TOO_SMALL) {\r
854 continue;\r
855 }\r
856\r
857 FmpImageInfoBuf = NULL;\r
858 FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);\r
859 if (FmpImageInfoBuf == NULL) {\r
860 FreePool(HandleBuffer);\r
861 Print(L"Out of resource\n");\r
862 return NULL;\r
863 }\r
864\r
865 PackageVersionName = NULL;\r
866 Status = Fmp->GetImageInfo (\r
867 Fmp,\r
868 &ImageInfoSize, // ImageInfoSize\r
869 FmpImageInfoBuf, // ImageInfo\r
870 &FmpImageInfoDescriptorVer, // DescriptorVersion\r
871 &FmpImageInfoCount, // DescriptorCount\r
872 &DescriptorSize, // DescriptorSize\r
873 &PackageVersion, // PackageVersion\r
874 &PackageVersionName // PackageVersionName\r
875 );\r
876\r
877 //\r
878 // If FMP GetInformation interface failed, skip this resource\r
879 //\r
880 if (EFI_ERROR(Status)) {\r
881 FreePool(FmpImageInfoBuf);\r
882 continue;\r
883 }\r
884\r
885 if (PackageVersionName != NULL) {\r
886 FreePool(PackageVersionName);\r
887 }\r
888\r
889 if (IsThisFmpImageInfo (FmpImageInfoBuf, FmpImageInfoCount, DescriptorSize, ImageTypeId)) {\r
890 TargetFmp = Fmp;\r
891 }\r
892 FreePool(FmpImageInfoBuf);\r
893 if (TargetFmp != NULL) {\r
894 break;\r
895 }\r
896 }\r
897 FreePool(HandleBuffer);\r
898 return TargetFmp;\r
899}\r
900\r
901/**\r
902 Dump FMP image data.\r
903\r
904 @param[in] ImageTypeId The ImageTypeId of the FMP image.\r
905 It is used to identify the FMP protocol.\r
906 @param[in] ImageIndex The ImageIndex of the FMP image.\r
907 It is the input parameter for FMP->GetImage().\r
908 @param[in] ImageName The file name to hold the output FMP image.\r
909**/\r
910VOID\r
911DumpFmpImage (\r
912 IN EFI_GUID *ImageTypeId,\r
913 IN UINTN ImageIndex,\r
914 IN CHAR16 *ImageName\r
915 )\r
916{\r
917 EFI_STATUS Status;\r
918 EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;\r
919 VOID *Image;\r
920 UINTN ImageSize;\r
921\r
922 Fmp = FindFmpFromImageTypeId (ImageTypeId);\r
923 if (Fmp == NULL) {\r
924 Print(L"No FMP include ImageTypeId %g\n", ImageTypeId);\r
925 return ;\r
926 }\r
927\r
928 if (ImageIndex > 0xFF) {\r
929 Print(L"ImageIndex 0x%x too big\n", ImageIndex);\r
930 return ;\r
931 }\r
932\r
933 Image = Fmp;\r
934 ImageSize = 0;\r
935 Status = Fmp->GetImage (Fmp, (UINT8)ImageIndex, Image, &ImageSize);\r
936 if (Status != EFI_BUFFER_TOO_SMALL) {\r
937 Print(L"Fmp->GetImage - %r\n", Status);\r
938 return ;\r
939 }\r
940\r
941 Image = AllocatePool (ImageSize);\r
942 if (Image == NULL) {\r
943 Print(L"Allocate FmpImage 0x%x - %r\n", ImageSize, EFI_OUT_OF_RESOURCES);\r
944 return ;\r
945 }\r
946\r
947 Status = Fmp->GetImage (Fmp, (UINT8)ImageIndex, Image, &ImageSize);\r
948 if (EFI_ERROR(Status)) {\r
949 Print(L"Fmp->GetImage - %r\n", Status);\r
950 return ;\r
951 }\r
952\r
953 Status = WriteFileFromBuffer(ImageName, ImageSize, Image);\r
954 Print(L"CapsuleApp: Dump %g ImageIndex (0x%x) to %s %r\n", ImageTypeId, ImageIndex, ImageName, Status);\r
955\r
956 return ;\r
957}\r