]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Application/CapsuleApp/CapsuleDump.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Application / CapsuleApp / CapsuleDump.c
CommitLineData
592bad04
JY
1/** @file\r
2 Dump Capsule image information.\r
3\r
d9c91974 4 Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
592bad04
JY
6\r
7**/\r
8\r
8165570e 9#include "CapsuleApp.h"\r
97473291 10\r
fb57c30b
SZ
11/**\r
12 Validate if it is valid capsule header\r
13\r
14 This function assumes the caller provided correct CapsuleHeader pointer\r
15 and CapsuleSize.\r
16\r
17 This function validates the fields in EFI_CAPSULE_HEADER.\r
18\r
19 @param[in] CapsuleHeader Points to a capsule header.\r
20 @param[in] CapsuleSize Size of the whole capsule image.\r
21\r
22**/\r
23BOOLEAN\r
24IsValidCapsuleHeader (\r
1436aea4
MK
25 IN EFI_CAPSULE_HEADER *CapsuleHeader,\r
26 IN UINT64 CapsuleSize\r
fb57c30b
SZ
27 );\r
28\r
592bad04
JY
29/**\r
30 Dump UX capsule information.\r
31\r
32 @param[in] CapsuleHeader The UX capsule header\r
33**/\r
34VOID\r
35DumpUxCapsule (\r
36 IN EFI_CAPSULE_HEADER *CapsuleHeader\r
37 )\r
38{\r
1436aea4
MK
39 EFI_DISPLAY_CAPSULE *DisplayCapsule;\r
40\r
592bad04 41 DisplayCapsule = (EFI_DISPLAY_CAPSULE *)CapsuleHeader;\r
1436aea4
MK
42 Print (L"[UxCapsule]\n");\r
43 Print (L"CapsuleHeader:\n");\r
44 Print (L" CapsuleGuid - %g\n", &DisplayCapsule->CapsuleHeader.CapsuleGuid);\r
45 Print (L" HeaderSize - 0x%x\n", DisplayCapsule->CapsuleHeader.HeaderSize);\r
46 Print (L" Flags - 0x%x\n", DisplayCapsule->CapsuleHeader.Flags);\r
47 Print (L" CapsuleImageSize - 0x%x\n", DisplayCapsule->CapsuleHeader.CapsuleImageSize);\r
48 Print (L"ImagePayload:\n");\r
49 Print (L" Version - 0x%x\n", DisplayCapsule->ImagePayload.Version);\r
50 Print (L" Checksum - 0x%x\n", DisplayCapsule->ImagePayload.Checksum);\r
51 Print (L" ImageType - 0x%x\n", DisplayCapsule->ImagePayload.ImageType);\r
52 Print (L" Mode - 0x%x\n", DisplayCapsule->ImagePayload.Mode);\r
53 Print (L" OffsetX - 0x%x\n", DisplayCapsule->ImagePayload.OffsetX);\r
54 Print (L" OffsetY - 0x%x\n", DisplayCapsule->ImagePayload.OffsetY);\r
592bad04
JY
55}\r
56\r
592bad04
JY
57/**\r
58 Dump a non-nested FMP capsule.\r
59\r
60 @param[in] CapsuleHeader A pointer to CapsuleHeader\r
61**/\r
62VOID\r
63DumpFmpCapsule (\r
64 IN EFI_CAPSULE_HEADER *CapsuleHeader\r
65 )\r
66{\r
67 EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *FmpCapsuleHeader;\r
68 UINT64 *ItemOffsetList;\r
69 UINTN Index;\r
70 UINTN Count;\r
71 EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *FmpImageHeader;\r
72\r
1436aea4
MK
73 Print (L"[FmpCapsule]\n");\r
74 Print (L"CapsuleHeader:\n");\r
75 Print (L" CapsuleGuid - %g\n", &CapsuleHeader->CapsuleGuid);\r
76 Print (L" HeaderSize - 0x%x\n", CapsuleHeader->HeaderSize);\r
77 Print (L" Flags - 0x%x\n", CapsuleHeader->Flags);\r
78 Print (L" CapsuleImageSize - 0x%x\n", CapsuleHeader->CapsuleImageSize);\r
592bad04
JY
79\r
80 FmpCapsuleHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);\r
1436aea4
MK
81 ItemOffsetList = (UINT64 *)(FmpCapsuleHeader + 1);\r
82 Print (L"FmpHeader:\n");\r
83 Print (L" Version - 0x%x\n", FmpCapsuleHeader->Version);\r
84 Print (L" EmbeddedDriverCount - 0x%x\n", FmpCapsuleHeader->EmbeddedDriverCount);\r
85 Print (L" PayloadItemCount - 0x%x\n", FmpCapsuleHeader->PayloadItemCount);\r
592bad04
JY
86 Count = FmpCapsuleHeader->EmbeddedDriverCount + FmpCapsuleHeader->PayloadItemCount;\r
87 for (Index = 0; Index < Count; Index++) {\r
1436aea4 88 Print (L" Offset[%d] - 0x%x\n", Index, ItemOffsetList[Index]);\r
592bad04
JY
89 }\r
90\r
91 for (Index = FmpCapsuleHeader->EmbeddedDriverCount; Index < Count; Index++) {\r
1436aea4 92 Print (L"FmpPayload[%d] ImageHeader:\n", Index);\r
592bad04 93 FmpImageHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *)((UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index]);\r
1436aea4
MK
94 Print (L" Version - 0x%x\n", FmpImageHeader->Version);\r
95 Print (L" UpdateImageTypeId - %g\n", &FmpImageHeader->UpdateImageTypeId);\r
96 Print (L" UpdateImageIndex - 0x%x\n", FmpImageHeader->UpdateImageIndex);\r
97 Print (L" UpdateImageSize - 0x%x\n", FmpImageHeader->UpdateImageSize);\r
98 Print (L" UpdateVendorCodeSize - 0x%x\n", FmpImageHeader->UpdateVendorCodeSize);\r
5a4b24b8 99 if (FmpImageHeader->Version >= 2) {\r
1436aea4 100 Print (L" UpdateHardwareInstance - 0x%lx\n", FmpImageHeader->UpdateHardwareInstance);\r
5a4b24b8 101 if (FmpImageHeader->Version >= EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) {\r
1436aea4 102 Print (L" ImageCapsuleSupport - 0x%lx\n", FmpImageHeader->ImageCapsuleSupport);\r
5a4b24b8 103 }\r
592bad04
JY
104 }\r
105 }\r
106}\r
107\r
108/**\r
109 Return if there is a FMP header below capsule header.\r
110\r
111 @param[in] CapsuleHeader A pointer to EFI_CAPSULE_HEADER\r
112\r
113 @retval TRUE There is a FMP header below capsule header.\r
114 @retval FALSE There is not a FMP header below capsule header\r
115**/\r
116BOOLEAN\r
117IsNestedFmpCapsule (\r
1436aea4 118 IN EFI_CAPSULE_HEADER *CapsuleHeader\r
592bad04
JY
119 )\r
120{\r
121 EFI_STATUS Status;\r
122 EFI_SYSTEM_RESOURCE_TABLE *Esrt;\r
123 EFI_SYSTEM_RESOURCE_ENTRY *EsrtEntry;\r
124 UINTN Index;\r
125 BOOLEAN EsrtGuidFound;\r
126 EFI_CAPSULE_HEADER *NestedCapsuleHeader;\r
127 UINTN NestedCapsuleSize;\r
128\r
129 //\r
130 // Check ESRT\r
131 //\r
132 EsrtGuidFound = FALSE;\r
1436aea4
MK
133 Status = EfiGetSystemConfigurationTable (&gEfiSystemResourceTableGuid, (VOID **)&Esrt);\r
134 if (!EFI_ERROR (Status)) {\r
592bad04
JY
135 ASSERT (Esrt != NULL);\r
136 EsrtEntry = (VOID *)(Esrt + 1);\r
137 for (Index = 0; Index < Esrt->FwResourceCount; Index++, EsrtEntry++) {\r
1436aea4 138 if (CompareGuid (&EsrtEntry->FwClass, &CapsuleHeader->CapsuleGuid)) {\r
592bad04
JY
139 EsrtGuidFound = TRUE;\r
140 break;\r
141 }\r
142 }\r
143 }\r
144\r
145 if (!EsrtGuidFound) {\r
146 return FALSE;\r
147 }\r
148\r
149 //\r
150 // Check nested capsule header\r
151 // FMP GUID after ESRT one\r
152 //\r
153 NestedCapsuleHeader = (EFI_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);\r
1436aea4
MK
154 NestedCapsuleSize = (UINTN)CapsuleHeader + CapsuleHeader->CapsuleImageSize- (UINTN)NestedCapsuleHeader;\r
155 if (NestedCapsuleSize < sizeof (EFI_CAPSULE_HEADER)) {\r
592bad04
JY
156 return FALSE;\r
157 }\r
1436aea4
MK
158\r
159 if (!CompareGuid (&NestedCapsuleHeader->CapsuleGuid, &gEfiFmpCapsuleGuid)) {\r
592bad04
JY
160 return FALSE;\r
161 }\r
1436aea4 162\r
592bad04
JY
163 return TRUE;\r
164}\r
165\r
166/**\r
167 Dump capsule information\r
168\r
169 @param[in] CapsuleName The name of the capsule image.\r
170\r
171 @retval EFI_SUCCESS The capsule information is dumped.\r
172 @retval EFI_UNSUPPORTED Input parameter is not valid.\r
173**/\r
174EFI_STATUS\r
175DumpCapsule (\r
1436aea4 176 IN CHAR16 *CapsuleName\r
592bad04
JY
177 )\r
178{\r
1436aea4
MK
179 VOID *Buffer;\r
180 UINTN FileSize;\r
181 EFI_CAPSULE_HEADER *CapsuleHeader;\r
182 EFI_STATUS Status;\r
592bad04 183\r
2e3032b4 184 Buffer = NULL;\r
1436aea4
MK
185 Status = ReadFileToBuffer (CapsuleName, &FileSize, &Buffer);\r
186 if (EFI_ERROR (Status)) {\r
187 Print (L"CapsuleApp: Capsule (%s) is not found.\n", CapsuleName);\r
592bad04
JY
188 goto Done;\r
189 }\r
1436aea4 190\r
fb57c30b 191 if (!IsValidCapsuleHeader (Buffer, FileSize)) {\r
1436aea4 192 Print (L"CapsuleApp: Capsule image (%s) is not a valid capsule.\n", CapsuleName);\r
fb57c30b
SZ
193 Status = EFI_INVALID_PARAMETER;\r
194 goto Done;\r
195 }\r
592bad04
JY
196\r
197 CapsuleHeader = Buffer;\r
1436aea4
MK
198 if (CompareGuid (&CapsuleHeader->CapsuleGuid, &gWindowsUxCapsuleGuid)) {\r
199 DumpUxCapsule (CapsuleHeader);\r
592bad04
JY
200 Status = EFI_SUCCESS;\r
201 goto Done;\r
202 }\r
203\r
1436aea4
MK
204 if (CompareGuid (&CapsuleHeader->CapsuleGuid, &gEfiFmpCapsuleGuid)) {\r
205 DumpFmpCapsule (CapsuleHeader);\r
592bad04 206 }\r
1436aea4
MK
207\r
208 if (IsNestedFmpCapsule (CapsuleHeader)) {\r
209 Print (L"[NestedCapsule]\n");\r
210 Print (L"CapsuleHeader:\n");\r
211 Print (L" CapsuleGuid - %g\n", &CapsuleHeader->CapsuleGuid);\r
212 Print (L" HeaderSize - 0x%x\n", CapsuleHeader->HeaderSize);\r
213 Print (L" Flags - 0x%x\n", CapsuleHeader->Flags);\r
214 Print (L" CapsuleImageSize - 0x%x\n", CapsuleHeader->CapsuleImageSize);\r
215 DumpFmpCapsule ((EFI_CAPSULE_HEADER *)((UINTN)CapsuleHeader + CapsuleHeader->HeaderSize));\r
592bad04
JY
216 }\r
217\r
218Done:\r
2e3032b4 219 if (Buffer != NULL) {\r
1436aea4 220 FreePool (Buffer);\r
2e3032b4 221 }\r
1436aea4 222\r
592bad04
JY
223 return Status;\r
224}\r
225\r
226/**\r
227 Dump capsule status variable.\r
228\r
229 @retval EFI_SUCCESS The capsule status variable is dumped.\r
230 @retval EFI_UNSUPPORTED Input parameter is not valid.\r
231**/\r
232EFI_STATUS\r
8b03c82d 233DumpCapsuleStatusVariable (\r
592bad04
JY
234 VOID\r
235 )\r
236{\r
237 EFI_STATUS Status;\r
238 UINT32 Index;\r
239 CHAR16 CapsuleVarName[20];\r
240 CHAR16 *TempVarName;\r
241 EFI_CAPSULE_RESULT_VARIABLE_HEADER *CapsuleResult;\r
242 EFI_CAPSULE_RESULT_VARIABLE_FMP *CapsuleResultFmp;\r
243 UINTN CapsuleFileNameSize;\r
244 CHAR16 CapsuleIndexData[12];\r
245 CHAR16 *CapsuleIndex;\r
de5209d5
JY
246 CHAR16 *CapsuleFileName;\r
247 CHAR16 *CapsuleTarget;\r
592bad04 248\r
1436aea4 249 Status = GetVariable2 (\r
592bad04
JY
250 L"CapsuleMax",\r
251 &gEfiCapsuleReportGuid,\r
252 (VOID **)&CapsuleIndex,\r
253 NULL\r
254 );\r
1436aea4 255 if (!EFI_ERROR (Status)) {\r
a522ad7c 256 ASSERT (CapsuleIndex != NULL);\r
1436aea4 257 CopyMem (CapsuleIndexData, CapsuleIndex, 11 * sizeof (CHAR16));\r
592bad04 258 CapsuleIndexData[11] = 0;\r
1436aea4
MK
259 Print (L"CapsuleMax - %s\n", CapsuleIndexData);\r
260 FreePool (CapsuleIndex);\r
592bad04 261 }\r
1436aea4
MK
262\r
263 Status = GetVariable2 (\r
592bad04
JY
264 L"CapsuleLast",\r
265 &gEfiCapsuleReportGuid,\r
266 (VOID **)&CapsuleIndex,\r
267 NULL\r
268 );\r
1436aea4 269 if (!EFI_ERROR (Status)) {\r
a522ad7c 270 ASSERT (CapsuleIndex != NULL);\r
1436aea4 271 CopyMem (CapsuleIndexData, CapsuleIndex, 11 * sizeof (CHAR16));\r
592bad04 272 CapsuleIndexData[11] = 0;\r
1436aea4
MK
273 Print (L"CapsuleLast - %s\n", CapsuleIndexData);\r
274 FreePool (CapsuleIndex);\r
592bad04
JY
275 }\r
276\r
1436aea4 277 StrCpyS (CapsuleVarName, sizeof (CapsuleVarName)/sizeof (CapsuleVarName[0]), L"Capsule");\r
592bad04 278 TempVarName = CapsuleVarName + StrLen (CapsuleVarName);\r
1436aea4 279 Index = 0;\r
592bad04
JY
280\r
281 while (TRUE) {\r
1436aea4 282 UnicodeSPrint (TempVarName, 5 * sizeof (CHAR16), L"%04x", Index);\r
592bad04
JY
283\r
284 Status = GetVariable2 (\r
285 CapsuleVarName,\r
286 &gEfiCapsuleReportGuid,\r
1436aea4 287 (VOID **)&CapsuleResult,\r
592bad04
JY
288 NULL\r
289 );\r
290 if (Status == EFI_NOT_FOUND) {\r
291 break;\r
1436aea4 292 } else if (EFI_ERROR (Status)) {\r
592bad04
JY
293 continue;\r
294 }\r
1436aea4 295\r
592bad04
JY
296 ASSERT (CapsuleResult != NULL);\r
297\r
298 //\r
299 // display capsule process status\r
300 //\r
1436aea4 301 if (CapsuleResult->VariableTotalSize >= sizeof (EFI_CAPSULE_RESULT_VARIABLE_HEADER)) {\r
592bad04
JY
302 Print (L"CapsuleName: %s\n", CapsuleVarName);\r
303 Print (L" Capsule Guid: %g\n", &CapsuleResult->CapsuleGuid);\r
304 Print (L" Capsule ProcessedTime: %t\n", &CapsuleResult->CapsuleProcessed);\r
305 Print (L" Capsule Status: %r\n", CapsuleResult->CapsuleStatus);\r
306 }\r
307\r
1436aea4
MK
308 if (CompareGuid (&CapsuleResult->CapsuleGuid, &gEfiFmpCapsuleGuid)) {\r
309 if (CapsuleResult->VariableTotalSize >= sizeof (EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof (EFI_CAPSULE_RESULT_VARIABLE_FMP) + sizeof (CHAR16) * 2) {\r
592bad04 310 CapsuleResultFmp = (EFI_CAPSULE_RESULT_VARIABLE_FMP *)(CapsuleResult + 1);\r
1436aea4
MK
311 Print (L" Capsule FMP Version: 0x%x\n", CapsuleResultFmp->Version);\r
312 Print (L" Capsule FMP PayloadIndex: 0x%x\n", CapsuleResultFmp->PayloadIndex);\r
313 Print (L" Capsule FMP UpdateImageIndex: 0x%x\n", CapsuleResultFmp->UpdateImageIndex);\r
314 Print (L" Capsule FMP UpdateImageTypeId: %g\n", &CapsuleResultFmp->UpdateImageTypeId);\r
de5209d5 315 CapsuleFileName = (CHAR16 *)(CapsuleResultFmp + 1);\r
1436aea4
MK
316 Print (L" Capsule FMP CapsuleFileName: \"%s\"\n", CapsuleFileName);\r
317 CapsuleFileNameSize = StrSize (CapsuleFileName);\r
318 CapsuleTarget = (CHAR16 *)((UINTN)CapsuleFileName + CapsuleFileNameSize);\r
319 Print (L" Capsule FMP CapsuleTarget: \"%s\"\n", CapsuleTarget);\r
592bad04
JY
320 }\r
321 }\r
322\r
1436aea4 323 FreePool (CapsuleResult);\r
592bad04
JY
324\r
325 Index++;\r
326 if (Index > 0xFFFF) {\r
327 break;\r
328 }\r
329 }\r
330\r
331 return EFI_SUCCESS;\r
332}\r
333\r
1436aea4 334CHAR8 *mFwTypeString[] = {\r
592bad04
JY
335 "Unknown",\r
336 "SystemFirmware",\r
337 "DeviceFirmware",\r
338 "UefiDriver",\r
339};\r
340\r
1436aea4 341CHAR8 *mLastAttemptStatusString[] = {\r
592bad04
JY
342 "Success",\r
343 "Error: Unsuccessful",\r
344 "Error: Insufficient Resources",\r
345 "Error: Incorrect Version",\r
346 "Error: Invalid Format",\r
347 "Error: Auth Error",\r
348 "Error: Power Event AC",\r
349 "Error: Power Event Battery",\r
d9c91974 350 "Error: Unsatisfied Dependencies",\r
592bad04
JY
351};\r
352\r
353/**\r
354 Convert FwType to a string.\r
355\r
356 @param[in] FwType FwType in ESRT\r
357\r
358 @return a string for FwType.\r
359**/\r
360CHAR8 *\r
361FwTypeToString (\r
362 IN UINT32 FwType\r
363 )\r
364{\r
1436aea4 365 if (FwType < sizeof (mFwTypeString) / sizeof (mFwTypeString[0])) {\r
592bad04
JY
366 return mFwTypeString[FwType];\r
367 } else {\r
368 return "Invalid";\r
369 }\r
370}\r
371\r
372/**\r
373 Convert LastAttemptStatus to a string.\r
374\r
375 @param[in] LastAttemptStatus LastAttemptStatus in FMP or ESRT\r
376\r
377 @return a string for LastAttemptStatus.\r
378**/\r
379CHAR8 *\r
380LastAttemptStatusToString (\r
381 IN UINT32 LastAttemptStatus\r
382 )\r
383{\r
1436aea4 384 if (LastAttemptStatus < sizeof (mLastAttemptStatusString) / sizeof (mLastAttemptStatusString[0])) {\r
592bad04
JY
385 return mLastAttemptStatusString[LastAttemptStatus];\r
386 } else {\r
387 return "Error: Unknown";\r
388 }\r
389}\r
390\r
391/**\r
392 Dump ESRT entry.\r
393\r
394 @param[in] EsrtEntry ESRT entry\r
395**/\r
396VOID\r
397DumpEsrtEntry (\r
398 IN EFI_SYSTEM_RESOURCE_ENTRY *EsrtEntry\r
399 )\r
400{\r
1436aea4
MK
401 Print (L" FwClass - %g\n", &EsrtEntry->FwClass);\r
402 Print (L" FwType - 0x%x (%a)\n", EsrtEntry->FwType, FwTypeToString (EsrtEntry->FwType));\r
403 Print (L" FwVersion - 0x%x\n", EsrtEntry->FwVersion);\r
404 Print (L" LowestSupportedFwVersion - 0x%x\n", EsrtEntry->LowestSupportedFwVersion);\r
405 Print (L" CapsuleFlags - 0x%x\n", EsrtEntry->CapsuleFlags);\r
406 Print (L" LastAttemptVersion - 0x%x\n", EsrtEntry->LastAttemptVersion);\r
407 Print (L" LastAttemptStatus - 0x%x (%a)\n", EsrtEntry->LastAttemptStatus, LastAttemptStatusToString (EsrtEntry->LastAttemptStatus));\r
592bad04
JY
408}\r
409\r
410/**\r
411 Dump ESRT table.\r
412\r
413 @param[in] Esrt ESRT table\r
414**/\r
415VOID\r
416DumpEsrt (\r
417 IN EFI_SYSTEM_RESOURCE_TABLE *Esrt\r
418 )\r
419{\r
420 UINTN Index;\r
421 EFI_SYSTEM_RESOURCE_ENTRY *EsrtEntry;\r
422\r
423 if (Esrt == NULL) {\r
1436aea4 424 return;\r
592bad04
JY
425 }\r
426\r
1436aea4
MK
427 Print (L"EFI_SYSTEM_RESOURCE_TABLE:\n");\r
428 Print (L"FwResourceCount - 0x%x\n", Esrt->FwResourceCount);\r
429 Print (L"FwResourceCountMax - 0x%x\n", Esrt->FwResourceCountMax);\r
430 Print (L"FwResourceVersion - 0x%lx\n", Esrt->FwResourceVersion);\r
592bad04
JY
431\r
432 EsrtEntry = (VOID *)(Esrt + 1);\r
433 for (Index = 0; Index < Esrt->FwResourceCount; Index++) {\r
1436aea4
MK
434 Print (L"EFI_SYSTEM_RESOURCE_ENTRY (%d):\n", Index);\r
435 DumpEsrtEntry (EsrtEntry);\r
592bad04
JY
436 EsrtEntry++;\r
437 }\r
438}\r
439\r
440/**\r
441 Dump ESRT info.\r
442**/\r
443VOID\r
444DumpEsrtData (\r
445 VOID\r
446 )\r
447{\r
448 EFI_STATUS Status;\r
449 EFI_SYSTEM_RESOURCE_TABLE *Esrt;\r
450\r
1436aea4
MK
451 Print (L"##############\n");\r
452 Print (L"# ESRT TABLE #\n");\r
453 Print (L"##############\n");\r
592bad04
JY
454\r
455 Status = EfiGetSystemConfigurationTable (&gEfiSystemResourceTableGuid, (VOID **)&Esrt);\r
1436aea4
MK
456 if (EFI_ERROR (Status)) {\r
457 Print (L"ESRT - %r\n", Status);\r
592bad04
JY
458 return;\r
459 }\r
592bad04 460\r
1436aea4
MK
461 DumpEsrt (Esrt);\r
462 Print (L"\n");\r
463}\r
97473291
CC
464\r
465/**\r
466 Dump capsule information from CapsuleHeader\r
467\r
468 @param[in] CapsuleHeader The CapsuleHeader of the capsule image.\r
469\r
470 @retval EFI_SUCCESS The capsule information is dumped.\r
471\r
472**/\r
473EFI_STATUS\r
474DumpCapsuleFromBuffer (\r
1436aea4 475 IN EFI_CAPSULE_HEADER *CapsuleHeader\r
97473291
CC
476 )\r
477{\r
478 if (CompareGuid (&CapsuleHeader->CapsuleGuid, &gWindowsUxCapsuleGuid)) {\r
479 DumpUxCapsule (CapsuleHeader);\r
480 return EFI_SUCCESS;\r
481 }\r
482\r
483 if (CompareGuid (&CapsuleHeader->CapsuleGuid, &gEfiFmpCapsuleGuid)) {\r
484 DumpFmpCapsule (CapsuleHeader);\r
485 }\r
1436aea4 486\r
97473291
CC
487 if (IsNestedFmpCapsule (CapsuleHeader)) {\r
488 Print (L"[NestedCapusule]\n");\r
489 Print (L"CapsuleHeader:\n");\r
490 Print (L" CapsuleGuid - %g\n", &CapsuleHeader->CapsuleGuid);\r
491 Print (L" HeaderSize - 0x%x\n", CapsuleHeader->HeaderSize);\r
492 Print (L" Flags - 0x%x\n", CapsuleHeader->Flags);\r
493 Print (L" CapsuleImageSize - 0x%x\n", CapsuleHeader->CapsuleImageSize);\r
494 DumpFmpCapsule ((EFI_CAPSULE_HEADER *)((UINTN)CapsuleHeader + CapsuleHeader->HeaderSize));\r
495 }\r
496\r
497 return EFI_SUCCESS;\r
498}\r
499\r
500/**\r
501 This routine is called to upper case given unicode string.\r
502\r
503 @param[in] Str String to upper case\r
504\r
505 @retval upper cased string after process\r
506\r
507**/\r
508STATIC\r
509CHAR16 *\r
510UpperCaseString (\r
1436aea4 511 IN CHAR16 *Str\r
97473291
CC
512 )\r
513{\r
514 CHAR16 *Cptr;\r
515\r
516 for (Cptr = Str; *Cptr != L'\0'; Cptr++) {\r
1436aea4 517 if ((L'a' <= *Cptr) && (*Cptr <= L'z')) {\r
97473291
CC
518 *Cptr = *Cptr - L'a' + L'A';\r
519 }\r
520 }\r
521\r
522 return Str;\r
523}\r
524\r
525/**\r
526 This routine is used to return substring before period '.' or '\0'\r
527 Caller should respsonsible of substr space allocation & free\r
528\r
529 @param[in] Str String to check\r
530 @param[out] SubStr First part of string before period or '\0'\r
531 @param[out] SubStrLen Length of first part of string\r
532\r
533**/\r
534STATIC\r
535VOID\r
536GetSubStringBeforePeriod (\r
1436aea4
MK
537 IN CHAR16 *Str,\r
538 OUT CHAR16 *SubStr,\r
539 OUT UINTN *SubStrLen\r
97473291
CC
540 )\r
541{\r
1436aea4
MK
542 UINTN Index;\r
543\r
97473291
CC
544 for (Index = 0; Str[Index] != L'.' && Str[Index] != L'\0'; Index++) {\r
545 SubStr[Index] = Str[Index];\r
546 }\r
547\r
548 SubStr[Index] = L'\0';\r
1436aea4 549 *SubStrLen = Index;\r
97473291
CC
550}\r
551\r
552/**\r
553 This routine pad the string in tail with input character.\r
554\r
555 @param[in] StrBuf Str buffer to be padded, should be enough room for\r
556 @param[in] PadLen Expected padding length\r
557 @param[in] Character Character used to pad\r
558\r
559**/\r
560STATIC\r
561VOID\r
562PadStrInTail (\r
1436aea4
MK
563 IN CHAR16 *StrBuf,\r
564 IN UINTN PadLen,\r
565 IN CHAR16 Character\r
97473291
CC
566 )\r
567{\r
1436aea4 568 UINTN Index;\r
97473291 569\r
1436aea4
MK
570 for (Index = 0; StrBuf[Index] != L'\0'; Index++) {\r
571 }\r
97473291 572\r
1436aea4 573 while (PadLen != 0) {\r
97473291
CC
574 StrBuf[Index] = Character;\r
575 Index++;\r
576 PadLen--;\r
577 }\r
578\r
579 StrBuf[Index] = L'\0';\r
580}\r
581\r
582/**\r
583 This routine find the offset of the last period '.' of string. if No period exists\r
584 function FileNameExtension is set to L'\0'\r
585\r
586 @param[in] FileName File name to split between last period\r
587 @param[out] FileNameFirst First FileName before last period\r
588 @param[out] FileNameExtension FileName after last period\r
589\r
590**/\r
591STATIC\r
592VOID\r
593SplitFileNameExtension (\r
594 IN CHAR16 *FileName,\r
595 OUT CHAR16 *FileNameFirst,\r
596 OUT CHAR16 *FileNameExtension\r
597 )\r
598{\r
1436aea4
MK
599 UINTN Index;\r
600 UINTN StringLen;\r
97473291 601\r
1436aea4
MK
602 StringLen = StrLen (FileName);\r
603 for (Index = StringLen; Index > 0 && FileName[Index] != L'.'; Index--) {\r
604 }\r
97473291
CC
605\r
606 //\r
607 // No period exists. No FileName Extension\r
608 //\r
1436aea4 609 if ((Index == 0) && (FileName[Index] != L'.')) {\r
97473291 610 FileNameExtension[0] = L'\0';\r
1436aea4 611 Index = StringLen;\r
97473291
CC
612 } else {\r
613 StrCpyS (FileNameExtension, MAX_FILE_NAME_LEN, &FileName[Index+1]);\r
614 }\r
615\r
616 //\r
617 // Copy First file name\r
618 //\r
619 StrnCpyS (FileNameFirst, MAX_FILE_NAME_LEN, FileName, Index);\r
620 FileNameFirst[Index] = L'\0';\r
621}\r
622\r
623/**\r
624 The function is called by PerformQuickSort to sort file name in alphabet.\r
625\r
626 @param[in] Left The pointer to first buffer.\r
627 @param[in] Right The pointer to second buffer.\r
628\r
629 @retval 0 Buffer1 equal to Buffer2.\r
630 @return <0 Buffer1 is less than Buffer2.\r
631 @return >0 Buffer1 is greater than Buffer2.\r
632\r
633**/\r
634INTN\r
97473291 635CompareFileNameInAlphabet (\r
1436aea4
MK
636 IN VOID *Left,\r
637 IN VOID *Right\r
97473291
CC
638 )\r
639{\r
640 EFI_FILE_INFO *FileInfo1;\r
641 EFI_FILE_INFO *FileInfo2;\r
642 CHAR16 FileName1[MAX_FILE_NAME_SIZE];\r
643 CHAR16 FileExtension1[MAX_FILE_NAME_SIZE];\r
644 CHAR16 FileName2[MAX_FILE_NAME_SIZE];\r
645 CHAR16 FileExtension2[MAX_FILE_NAME_SIZE];\r
646 CHAR16 TempSubStr1[MAX_FILE_NAME_SIZE];\r
647 CHAR16 TempSubStr2[MAX_FILE_NAME_SIZE];\r
648 UINTN SubStrLen1;\r
649 UINTN SubStrLen2;\r
650 INTN SubStrCmpResult;\r
651\r
1436aea4
MK
652 FileInfo1 = (EFI_FILE_INFO *)(*(UINTN *)Left);\r
653 FileInfo2 = (EFI_FILE_INFO *)(*(UINTN *)Right);\r
97473291
CC
654\r
655 SplitFileNameExtension (FileInfo1->FileName, FileName1, FileExtension1);\r
656 SplitFileNameExtension (FileInfo2->FileName, FileName2, FileExtension2);\r
657\r
658 UpperCaseString (FileName1);\r
659 UpperCaseString (FileName2);\r
660\r
661 GetSubStringBeforePeriod (FileName1, TempSubStr1, &SubStrLen1);\r
662 GetSubStringBeforePeriod (FileName2, TempSubStr2, &SubStrLen2);\r
663\r
664 if (SubStrLen1 > SubStrLen2) {\r
665 //\r
666 // Substr in NewFileName is longer. Pad tail with SPACE\r
667 //\r
668 PadStrInTail (TempSubStr2, SubStrLen1 - SubStrLen2, L' ');\r
1436aea4 669 } else if (SubStrLen1 < SubStrLen2) {\r
97473291
CC
670 //\r
671 // Substr in ListedFileName is longer. Pad tail with SPACE\r
672 //\r
673 PadStrInTail (TempSubStr1, SubStrLen2 - SubStrLen1, L' ');\r
674 }\r
675\r
676 SubStrCmpResult = StrnCmp (TempSubStr1, TempSubStr2, MAX_FILE_NAME_LEN);\r
677 if (SubStrCmpResult != 0) {\r
678 return SubStrCmpResult;\r
679 }\r
680\r
681 UpperCaseString (FileExtension1);\r
682 UpperCaseString (FileExtension2);\r
683\r
684 return StrnCmp (FileExtension1, FileExtension2, MAX_FILE_NAME_LEN);\r
685}\r
686\r
687/**\r
688 Dump capsule information from disk.\r
689\r
690 @param[in] Fs The device path of disk.\r
691 @param[in] DumpCapsuleInfo The flag to indicate whether to dump the capsule inforomation.\r
692\r
693 @retval EFI_SUCCESS The capsule information is dumped.\r
694\r
695**/\r
696EFI_STATUS\r
697DumpCapsuleFromDisk (\r
1436aea4
MK
698 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs,\r
699 IN BOOLEAN DumpCapsuleInfo\r
97473291
CC
700 )\r
701{\r
1436aea4
MK
702 EFI_STATUS Status;\r
703 EFI_FILE *Root;\r
704 EFI_FILE *DirHandle;\r
705 EFI_FILE *FileHandle;\r
706 UINTN Index;\r
707 UINTN FileSize;\r
708 VOID *FileBuffer;\r
709 EFI_FILE_INFO **FileInfoBuffer;\r
710 EFI_FILE_INFO *FileInfo;\r
711 UINTN FileCount;\r
712 BOOLEAN NoFile;\r
713\r
714 DirHandle = NULL;\r
715 FileHandle = NULL;\r
716 Index = 0;\r
717 FileInfoBuffer = NULL;\r
718 FileInfo = NULL;\r
719 FileCount = 0;\r
720 NoFile = FALSE;\r
97473291
CC
721\r
722 Status = Fs->OpenVolume (Fs, &Root);\r
723 if (EFI_ERROR (Status)) {\r
724 Print (L"Cannot open volume. Status = %r\n", Status);\r
325ad622 725 goto Done;\r
97473291
CC
726 }\r
727\r
1436aea4 728 Status = Root->Open (Root, &DirHandle, EFI_CAPSULE_FILE_DIRECTORY, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0);\r
97473291
CC
729 if (EFI_ERROR (Status)) {\r
730 Print (L"Cannot open %s. Status = %r\n", EFI_CAPSULE_FILE_DIRECTORY, Status);\r
325ad622 731 goto Done;\r
97473291
CC
732 }\r
733\r
734 //\r
735 // Get file count first\r
736 //\r
8165570e 737 Status = FileHandleFindFirstFile (DirHandle, &FileInfo);\r
325ad622 738 do {\r
1436aea4 739 if (EFI_ERROR (Status) || (FileInfo == NULL)) {\r
325ad622
CC
740 Print (L"Get File Info Fail. Status = %r\n", Status);\r
741 goto Done;\r
97473291 742 }\r
325ad622
CC
743\r
744 if ((FileInfo->Attribute & (EFI_FILE_SYSTEM | EFI_FILE_ARCHIVE)) != 0) {\r
745 FileCount++;\r
746 }\r
747\r
748 Status = FileHandleFindNextFile (DirHandle, FileInfo, &NoFile);\r
749 if (EFI_ERROR (Status)) {\r
750 Print (L"Get Next File Fail. Status = %r\n", Status);\r
751 goto Done;\r
752 }\r
753 } while (!NoFile);\r
97473291
CC
754\r
755 if (FileCount == 0) {\r
756 Print (L"Error: No capsule file found!\n");\r
325ad622
CC
757 Status = EFI_NOT_FOUND;\r
758 goto Done;\r
97473291
CC
759 }\r
760\r
325ad622
CC
761 FileInfoBuffer = AllocateZeroPool (sizeof (FileInfo) * FileCount);\r
762 if (FileInfoBuffer == NULL) {\r
763 Status = EFI_OUT_OF_RESOURCES;\r
764 goto Done;\r
765 }\r
1436aea4 766\r
97473291
CC
767 NoFile = FALSE;\r
768\r
769 //\r
770 // Get all file info\r
771 //\r
8165570e 772 Status = FileHandleFindFirstFile (DirHandle, &FileInfo);\r
325ad622 773 do {\r
1436aea4 774 if (EFI_ERROR (Status) || (FileInfo == NULL)) {\r
325ad622
CC
775 Print (L"Get File Info Fail. Status = %r\n", Status);\r
776 goto Done;\r
777 }\r
778\r
779 if ((FileInfo->Attribute & (EFI_FILE_SYSTEM | EFI_FILE_ARCHIVE)) != 0) {\r
780 FileInfoBuffer[Index++] = AllocateCopyPool ((UINTN)FileInfo->Size, FileInfo);\r
97473291 781 }\r
325ad622
CC
782\r
783 Status = FileHandleFindNextFile (DirHandle, FileInfo, &NoFile);\r
784 if (EFI_ERROR (Status)) {\r
785 Print (L"Get Next File Fail. Status = %r\n", Status);\r
786 goto Done;\r
787 }\r
788 } while (!NoFile);\r
97473291
CC
789\r
790 //\r
791 // Sort FileInfoBuffer by alphabet order\r
792 //\r
793 PerformQuickSort (\r
794 FileInfoBuffer,\r
795 FileCount,\r
796 sizeof (FileInfo),\r
1436aea4 797 (SORT_COMPARE)CompareFileNameInAlphabet\r
97473291
CC
798 );\r
799\r
800 Print (L"The capsules will be performed by following order:\n");\r
801\r
802 for (Index = 0; Index < FileCount; Index++) {\r
803 Print (L" %d.%s\n", Index + 1, FileInfoBuffer[Index]->FileName);\r
804 }\r
805\r
806 if (!DumpCapsuleInfo) {\r
325ad622
CC
807 Status = EFI_SUCCESS;\r
808 goto Done;\r
97473291
CC
809 }\r
810\r
1436aea4 811 Print (L"The infomation of the capsules:\n");\r
97473291
CC
812\r
813 for (Index = 0; Index < FileCount; Index++) {\r
814 FileHandle = NULL;\r
1436aea4 815 Status = DirHandle->Open (DirHandle, &FileHandle, FileInfoBuffer[Index]->FileName, EFI_FILE_MODE_READ, 0);\r
97473291 816 if (EFI_ERROR (Status)) {\r
325ad622 817 goto Done;\r
97473291
CC
818 }\r
819\r
1436aea4 820 Status = FileHandleGetSize (FileHandle, (UINT64 *)&FileSize);\r
97473291
CC
821 if (EFI_ERROR (Status)) {\r
822 Print (L"Cannot read file %s. Status = %r\n", FileInfoBuffer[Index]->FileName, Status);\r
823 FileHandleClose (FileHandle);\r
325ad622 824 goto Done;\r
97473291
CC
825 }\r
826\r
827 FileBuffer = AllocatePool (FileSize);\r
828 if (FileBuffer == NULL) {\r
325ad622
CC
829 Status = EFI_OUT_OF_RESOURCES;\r
830 goto Done;\r
97473291
CC
831 }\r
832\r
833 Status = FileHandleRead (FileHandle, &FileSize, FileBuffer);\r
834 if (EFI_ERROR (Status)) {\r
835 Print (L"Cannot read file %s. Status = %r\n", FileInfoBuffer[Index]->FileName, Status);\r
97473291 836 FileHandleClose (FileHandle);\r
325ad622
CC
837 FreePool (FileBuffer);\r
838 goto Done;\r
97473291
CC
839 }\r
840\r
841 Print (L"**************************\n");\r
842 Print (L" %d.%s:\n", Index + 1, FileInfoBuffer[Index]->FileName);\r
843 Print (L"**************************\n");\r
1436aea4 844 DumpCapsuleFromBuffer ((EFI_CAPSULE_HEADER *)FileBuffer);\r
97473291
CC
845 FileHandleClose (FileHandle);\r
846 FreePool (FileBuffer);\r
847 }\r
848\r
325ad622
CC
849Done:\r
850 if (FileInfoBuffer != NULL) {\r
851 for (Index = 0; Index < FileCount; Index++) {\r
852 if (FileInfoBuffer[Index] != NULL) {\r
853 FreePool (FileInfoBuffer[Index]);\r
854 }\r
855 }\r
1436aea4 856\r
325ad622
CC
857 FreePool (FileInfoBuffer);\r
858 }\r
859\r
860 return Status;\r
97473291
CC
861}\r
862\r
863/**\r
864 Dump capsule inforomation form Gather list.\r
865\r
866 @param[in] BlockDescriptors The block descriptors for the capsule images\r
867 @param[in] DumpCapsuleInfo The flag to indicate whether to dump the capsule inforomation.\r
868\r
869**/\r
870VOID\r
871DumpBlockDescriptors (\r
1436aea4
MK
872 IN EFI_CAPSULE_BLOCK_DESCRIPTOR *BlockDescriptors,\r
873 IN BOOLEAN DumpCapsuleInfo\r
97473291
CC
874 )\r
875{\r
1436aea4 876 EFI_CAPSULE_BLOCK_DESCRIPTOR *TempBlockPtr;\r
97473291
CC
877\r
878 TempBlockPtr = BlockDescriptors;\r
879\r
880 while (TRUE) {\r
881 if (TempBlockPtr->Length != 0) {\r
882 if (DumpCapsuleInfo) {\r
1436aea4 883 Print (L"******************************************************\n");\r
97473291 884 }\r
1436aea4
MK
885\r
886 Print (L"Capsule data starts at 0x%08x with size 0x%08x\n", TempBlockPtr->Union.DataBlock, TempBlockPtr->Length);\r
97473291 887 if (DumpCapsuleInfo) {\r
1436aea4
MK
888 Print (L"******************************************************\n");\r
889 DumpCapsuleFromBuffer ((EFI_CAPSULE_HEADER *)(UINTN)TempBlockPtr->Union.DataBlock);\r
97473291 890 }\r
1436aea4 891\r
97473291
CC
892 TempBlockPtr += 1;\r
893 } else {\r
894 if (TempBlockPtr->Union.ContinuationPointer == (UINTN)NULL) {\r
895 break;\r
896 } else {\r
1436aea4 897 TempBlockPtr = (EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)TempBlockPtr->Union.ContinuationPointer;\r
97473291
CC
898 }\r
899 }\r
900 }\r
901}\r
902\r
903/**\r
904 Dump Provisioned Capsule.\r
905\r
906 @param[in] DumpCapsuleInfo The flag to indicate whether to dump the capsule inforomation.\r
907\r
908**/\r
909VOID\r
910DumpProvisionedCapsule (\r
1436aea4 911 IN BOOLEAN DumpCapsuleInfo\r
97473291
CC
912 )\r
913{\r
1436aea4
MK
914 EFI_STATUS Status;\r
915 CHAR16 CapsuleVarName[30];\r
916 CHAR16 *TempVarName;\r
917 UINTN Index;\r
918 EFI_PHYSICAL_ADDRESS *CapsuleDataPtr64;\r
919 UINT16 *BootNext;\r
920 CHAR16 BootOptionName[20];\r
921 EFI_BOOT_MANAGER_LOAD_OPTION BootNextOptionEntry;\r
922 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
923 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs;\r
924 EFI_SHELL_PROTOCOL *ShellProtocol;\r
925\r
926 Index = 0;\r
927 CapsuleDataPtr64 = NULL;\r
928 BootNext = NULL;\r
1a35dd72
CC
929\r
930 ShellProtocol = GetShellProtocol ();\r
931 if (ShellProtocol == NULL) {\r
932 Print (L"Get Shell Protocol Fail\n");\r
1436aea4 933 return;\r
1a35dd72 934 }\r
97473291
CC
935\r
936 //\r
937 // Dump capsule provisioned on Memory\r
938 //\r
939 Print (L"#########################\n");\r
940 Print (L"### Capsule on Memory ###\n");\r
941 Print (L"#########################\n");\r
1436aea4 942 StrCpyS (CapsuleVarName, sizeof (CapsuleVarName)/sizeof (CHAR16), EFI_CAPSULE_VARIABLE_NAME);\r
97473291
CC
943 TempVarName = CapsuleVarName + StrLen (CapsuleVarName);\r
944 while (TRUE) {\r
945 if (Index > 0) {\r
946 UnicodeValueToStringS (\r
947 TempVarName,\r
948 sizeof (CapsuleVarName) - ((UINTN)TempVarName - (UINTN)CapsuleVarName),\r
949 0,\r
950 Index,\r
951 0\r
952 );\r
953 }\r
954\r
955 Status = GetVariable2 (\r
1436aea4
MK
956 CapsuleVarName,\r
957 &gEfiCapsuleVendorGuid,\r
958 (VOID **)&CapsuleDataPtr64,\r
959 NULL\r
960 );\r
961 if (EFI_ERROR (Status) || (CapsuleDataPtr64 == NULL)) {\r
97473291
CC
962 if (Index == 0) {\r
963 Print (L"No data.\n");\r
964 }\r
1436aea4 965\r
97473291 966 break;\r
97473291 967 }\r
1a35dd72
CC
968\r
969 Index++;\r
970 Print (L"Capsule Description at 0x%08x\n", *CapsuleDataPtr64);\r
1436aea4 971 DumpBlockDescriptors ((EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)*CapsuleDataPtr64, DumpCapsuleInfo);\r
97473291
CC
972 }\r
973\r
974 //\r
975 // Dump capsule provisioned on Disk\r
976 //\r
977 Print (L"#########################\n");\r
978 Print (L"### Capsule on Disk #####\n");\r
979 Print (L"#########################\n");\r
980 Status = GetVariable2 (\r
981 L"BootNext",\r
982 &gEfiGlobalVariableGuid,\r
1436aea4 983 (VOID **)&BootNext,\r
97473291 984 NULL\r
1436aea4
MK
985 );\r
986 if (EFI_ERROR (Status) || (BootNext == NULL)) {\r
1a35dd72
CC
987 Print (L"Get BootNext Variable Fail. Status = %r\n", Status);\r
988 } else {\r
97473291
CC
989 UnicodeSPrint (BootOptionName, sizeof (BootOptionName), L"Boot%04x", *BootNext);\r
990 Status = EfiBootManagerVariableToLoadOption (BootOptionName, &BootNextOptionEntry);\r
991 if (!EFI_ERROR (Status)) {\r
992 //\r
993 // Display description and device path\r
994 //\r
995 GetEfiSysPartitionFromBootOptionFilePath (BootNextOptionEntry.FilePath, &DevicePath, &Fs);\r
1436aea4 996 if (!EFI_ERROR (Status)) {\r
97473291 997 Print (L"Capsules are provisioned on BootOption: %s\n", BootNextOptionEntry.Description);\r
1436aea4 998 Print (L" %s %s\n", ShellProtocol->GetMapFromDevicePath (&DevicePath), ConvertDevicePathToText (DevicePath, TRUE, TRUE));\r
97473291
CC
999 DumpCapsuleFromDisk (Fs, DumpCapsuleInfo);\r
1000 }\r
1001 }\r
1002 }\r
1003}\r
1004\r
592bad04
JY
1005/**\r
1006 Dump FMP information.\r
1007\r
1008 @param[in] ImageInfoSize The size of ImageInfo, in bytes.\r
1009 @param[in] ImageInfo A pointer to EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
1010 @param[in] DescriptorVersion The version of EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
1011 @param[in] DescriptorCount The count of EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
1012 @param[in] DescriptorSize The size of an individual EFI_FIRMWARE_IMAGE_DESCRIPTOR, in bytes.\r
1013 @param[in] PackageVersion The version of package.\r
1014 @param[in] PackageVersionName The version name of package.\r
1015**/\r
1016VOID\r
1017DumpFmpImageInfo (\r
1436aea4
MK
1018 IN UINTN ImageInfoSize,\r
1019 IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageInfo,\r
1020 IN UINT32 DescriptorVersion,\r
1021 IN UINT8 DescriptorCount,\r
1022 IN UINTN DescriptorSize,\r
1023 IN UINT32 PackageVersion,\r
1024 IN CHAR16 *PackageVersionName\r
592bad04
JY
1025 )\r
1026{\r
1436aea4
MK
1027 EFI_FIRMWARE_IMAGE_DESCRIPTOR *CurrentImageInfo;\r
1028 UINTN Index;\r
1029 UINTN Index2;\r
1030\r
1031 Print (L" DescriptorVersion - 0x%x\n", DescriptorVersion);\r
1032 Print (L" DescriptorCount - 0x%x\n", DescriptorCount);\r
1033 Print (L" DescriptorSize - 0x%x\n", DescriptorSize);\r
1034 Print (L" PackageVersion - 0x%x\n", PackageVersion);\r
1035 Print (L" PackageVersionName - \"%s\"\n", PackageVersionName);\r
592bad04
JY
1036 CurrentImageInfo = ImageInfo;\r
1037 for (Index = 0; Index < DescriptorCount; Index++) {\r
1436aea4
MK
1038 Print (L" ImageDescriptor (%d)\n", Index);\r
1039 Print (L" ImageIndex - 0x%x\n", CurrentImageInfo->ImageIndex);\r
1040 Print (L" ImageTypeId - %g\n", &CurrentImageInfo->ImageTypeId);\r
1041 Print (L" ImageId - 0x%lx\n", CurrentImageInfo->ImageId);\r
1042 Print (L" ImageIdName - \"%s\"\n", CurrentImageInfo->ImageIdName);\r
1043 Print (L" Version - 0x%x\n", CurrentImageInfo->Version);\r
1044 Print (L" VersionName - \"%s\"\n", CurrentImageInfo->VersionName);\r
1045 Print (L" Size - 0x%x\n", CurrentImageInfo->Size);\r
1046 Print (L" AttributesSupported - 0x%lx\n", CurrentImageInfo->AttributesSupported);\r
1047 Print (L" IMAGE_UPDATABLE - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);\r
1048 Print (L" RESET_REQUIRED - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_RESET_REQUIRED);\r
1049 Print (L" AUTHENTICATION_REQUIRED - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);\r
1050 Print (L" IN_USE - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_IN_USE);\r
1051 Print (L" UEFI_IMAGE - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_UEFI_IMAGE);\r
1052 Print (L" AttributesSetting - 0x%lx\n", CurrentImageInfo->AttributesSetting);\r
1053 Print (L" IMAGE_UPDATABLE - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);\r
1054 Print (L" RESET_REQUIRED - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_RESET_REQUIRED);\r
1055 Print (L" AUTHENTICATION_REQUIRED - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);\r
1056 Print (L" IN_USE - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_IN_USE);\r
1057 Print (L" UEFI_IMAGE - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_UEFI_IMAGE);\r
1058 Print (L" Compatibilities - 0x%lx\n", CurrentImageInfo->Compatibilities);\r
1059 Print (L" COMPATIB_CHECK_SUPPORTED - 0x%lx\n", CurrentImageInfo->Compatibilities & IMAGE_COMPATIBILITY_CHECK_SUPPORTED);\r
592bad04 1060 if (DescriptorVersion > 1) {\r
1436aea4 1061 Print (L" LowestSupportedImageVersion - 0x%x\n", CurrentImageInfo->LowestSupportedImageVersion);\r
592bad04 1062 if (DescriptorVersion > 2) {\r
1436aea4
MK
1063 Print (L" LastAttemptVersion - 0x%x\n", CurrentImageInfo->LastAttemptVersion);\r
1064 Print (L" LastAttemptStatus - 0x%x (%a)\n", CurrentImageInfo->LastAttemptStatus, LastAttemptStatusToString (CurrentImageInfo->LastAttemptStatus));\r
1065 Print (L" HardwareInstance - 0x%lx\n", CurrentImageInfo->HardwareInstance);\r
d9c91974 1066 if (DescriptorVersion > 3) {\r
1436aea4 1067 Print (L" Dependencies - ");\r
d9c91974 1068 if (CurrentImageInfo->Dependencies == NULL) {\r
1436aea4 1069 Print (L"NULL\n");\r
d9c91974
WX
1070 } else {\r
1071 Index2 = 0;\r
1072 do {\r
1436aea4
MK
1073 Print (L"%02x ", CurrentImageInfo->Dependencies->Dependencies[Index2]);\r
1074 } while (CurrentImageInfo->Dependencies->Dependencies[Index2++] != EFI_FMP_DEP_END);\r
1075\r
1076 Print (L"\n");\r
d9c91974
WX
1077 }\r
1078 }\r
592bad04
JY
1079 }\r
1080 }\r
1436aea4 1081\r
592bad04
JY
1082 //\r
1083 // Use DescriptorSize to move ImageInfo Pointer to stay compatible with different ImageInfo version\r
1084 //\r
1085 CurrentImageInfo = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)((UINT8 *)CurrentImageInfo + DescriptorSize);\r
1086 }\r
1087}\r
1088\r
1089/**\r
1090 Dump FMP package information.\r
1091\r
1092 @param[in] PackageVersion The version of package.\r
1093 @param[in] PackageVersionName The version name of package.\r
1094 @param[in] PackageVersionNameMaxLen The maximum length of PackageVersionName.\r
1095 @param[in] AttributesSupported Package attributes that are supported by this device.\r
1096 @param[in] AttributesSetting Package attributes.\r
1097**/\r
1098VOID\r
1099DumpFmpPackageInfo (\r
1436aea4
MK
1100 IN UINT32 PackageVersion,\r
1101 IN CHAR16 *PackageVersionName,\r
1102 IN UINT32 PackageVersionNameMaxLen,\r
1103 IN UINT64 AttributesSupported,\r
1104 IN UINT64 AttributesSetting\r
592bad04
JY
1105 )\r
1106{\r
1436aea4
MK
1107 Print (L" PackageVersion - 0x%x\n", PackageVersion);\r
1108 Print (L" PackageVersionName - \"%s\"\n", PackageVersionName);\r
1109 Print (L" PackageVersionNameMaxLen - 0x%x\n", PackageVersionNameMaxLen);\r
1110 Print (L" AttributesSupported - 0x%lx\n", AttributesSupported);\r
1111 Print (L" IMAGE_UPDATABLE - 0x%lx\n", AttributesSupported & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);\r
1112 Print (L" RESET_REQUIRED - 0x%lx\n", AttributesSupported & IMAGE_ATTRIBUTE_RESET_REQUIRED);\r
1113 Print (L" AUTHENTICATION_REQUIRED - 0x%lx\n", AttributesSupported & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);\r
1114 Print (L" AttributesSetting - 0x%lx\n", AttributesSetting);\r
1115 Print (L" IMAGE_UPDATABLE - 0x%lx\n", AttributesSetting & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);\r
1116 Print (L" RESET_REQUIRED - 0x%lx\n", AttributesSetting & IMAGE_ATTRIBUTE_RESET_REQUIRED);\r
1117 Print (L" AUTHENTICATION_REQUIRED - 0x%lx\n", AttributesSetting & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);\r
592bad04
JY
1118}\r
1119\r
1120/**\r
1121 Dump FMP protocol info.\r
1122**/\r
1123VOID\r
1124DumpFmpData (\r
1125 VOID\r
1126 )\r
1127{\r
1436aea4
MK
1128 EFI_STATUS Status;\r
1129 EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;\r
1130 EFI_HANDLE *HandleBuffer;\r
1131 UINTN NumberOfHandles;\r
1132 UINTN Index;\r
1133 EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf;\r
1134 UINTN ImageInfoSize;\r
1135 UINT32 FmpImageInfoDescriptorVer;\r
1136 UINT8 FmpImageInfoCount;\r
1137 UINTN DescriptorSize;\r
1138 UINT32 PackageVersion;\r
1139 CHAR16 *PackageVersionName;\r
1140 UINT32 PackageVersionNameMaxLen;\r
1141 UINT64 AttributesSupported;\r
1142 UINT64 AttributesSetting;\r
1143\r
1144 Print (L"############\n");\r
1145 Print (L"# FMP DATA #\n");\r
1146 Print (L"############\n");\r
592bad04
JY
1147 Status = gBS->LocateHandleBuffer (\r
1148 ByProtocol,\r
1149 &gEfiFirmwareManagementProtocolGuid,\r
1150 NULL,\r
1151 &NumberOfHandles,\r
1152 &HandleBuffer\r
1153 );\r
1436aea4
MK
1154 if (EFI_ERROR (Status)) {\r
1155 Print (L"FMP protocol - %r\n", EFI_NOT_FOUND);\r
592bad04
JY
1156 return;\r
1157 }\r
1158\r
1159 for (Index = 0; Index < NumberOfHandles; Index++) {\r
1436aea4 1160 Status = gBS->HandleProtocol (\r
592bad04
JY
1161 HandleBuffer[Index],\r
1162 &gEfiFirmwareManagementProtocolGuid,\r
1163 (VOID **)&Fmp\r
1164 );\r
1436aea4 1165 if (EFI_ERROR (Status)) {\r
592bad04
JY
1166 continue;\r
1167 }\r
1168\r
1169 ImageInfoSize = 0;\r
1436aea4
MK
1170 Status = Fmp->GetImageInfo (\r
1171 Fmp,\r
1172 &ImageInfoSize,\r
1173 NULL,\r
1174 NULL,\r
1175 NULL,\r
1176 NULL,\r
1177 NULL,\r
1178 NULL\r
1179 );\r
592bad04
JY
1180 if (Status != EFI_BUFFER_TOO_SMALL) {\r
1181 continue;\r
1182 }\r
1183\r
1184 FmpImageInfoBuf = NULL;\r
1185 FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);\r
1186 if (FmpImageInfoBuf == NULL) {\r
1187 Status = EFI_OUT_OF_RESOURCES;\r
1188 goto EXIT;\r
1189 }\r
1190\r
1191 PackageVersionName = NULL;\r
1436aea4
MK
1192 Status = Fmp->GetImageInfo (\r
1193 Fmp,\r
1194 &ImageInfoSize, // ImageInfoSize\r
1195 FmpImageInfoBuf, // ImageInfo\r
1196 &FmpImageInfoDescriptorVer, // DescriptorVersion\r
1197 &FmpImageInfoCount, // DescriptorCount\r
1198 &DescriptorSize, // DescriptorSize\r
1199 &PackageVersion, // PackageVersion\r
1200 &PackageVersionName // PackageVersionName\r
1201 );\r
592bad04
JY
1202\r
1203 //\r
1204 // If FMP GetInformation interface failed, skip this resource\r
1205 //\r
1436aea4
MK
1206 if (EFI_ERROR (Status)) {\r
1207 Print (L"FMP (%d) ImageInfo - %r\n", Index, Status);\r
1208 FreePool (FmpImageInfoBuf);\r
592bad04
JY
1209 continue;\r
1210 }\r
1211\r
1436aea4
MK
1212 Print (L"FMP (%d) ImageInfo:\n", Index);\r
1213 DumpFmpImageInfo (\r
592bad04
JY
1214 ImageInfoSize, // ImageInfoSize\r
1215 FmpImageInfoBuf, // ImageInfo\r
1216 FmpImageInfoDescriptorVer, // DescriptorVersion\r
1217 FmpImageInfoCount, // DescriptorCount\r
1218 DescriptorSize, // DescriptorSize\r
1219 PackageVersion, // PackageVersion\r
1220 PackageVersionName // PackageVersionName\r
1221 );\r
1222\r
1223 if (PackageVersionName != NULL) {\r
1436aea4 1224 FreePool (PackageVersionName);\r
592bad04 1225 }\r
1436aea4
MK
1226\r
1227 FreePool (FmpImageInfoBuf);\r
592bad04
JY
1228\r
1229 //\r
1230 // Get package info\r
1231 //\r
1232 PackageVersionName = NULL;\r
1436aea4
MK
1233 Status = Fmp->GetPackageInfo (\r
1234 Fmp,\r
1235 &PackageVersion, // PackageVersion\r
1236 &PackageVersionName, // PackageVersionName\r
1237 &PackageVersionNameMaxLen, // PackageVersionNameMaxLen\r
1238 &AttributesSupported, // AttributesSupported\r
1239 &AttributesSetting // AttributesSetting\r
1240 );\r
1241 if (EFI_ERROR (Status)) {\r
1242 Print (L"FMP (%d) PackageInfo - %r\n", Index, Status);\r
592bad04 1243 } else {\r
1436aea4
MK
1244 Print (L"FMP (%d) ImageInfo:\n", Index);\r
1245 DumpFmpPackageInfo (\r
592bad04
JY
1246 PackageVersion, // PackageVersion\r
1247 PackageVersionName, // PackageVersionName\r
1248 PackageVersionNameMaxLen, // PackageVersionNameMaxLen\r
1249 AttributesSupported, // AttributesSupported\r
1250 AttributesSetting // AttributesSetting\r
1251 );\r
1252\r
1253 if (PackageVersionName != NULL) {\r
1436aea4 1254 FreePool (PackageVersionName);\r
592bad04
JY
1255 }\r
1256 }\r
1257 }\r
1436aea4
MK
1258\r
1259 Print (L"\n");\r
592bad04
JY
1260\r
1261EXIT:\r
1436aea4 1262 FreePool (HandleBuffer);\r
592bad04 1263}\r
1e09ec09
JY
1264\r
1265/**\r
1266 Check if the ImageInfo includes the ImageTypeId.\r
1267\r
1268 @param[in] ImageInfo A pointer to EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
1269 @param[in] DescriptorCount The count of EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
1270 @param[in] DescriptorSize The size of an individual EFI_FIRMWARE_IMAGE_DESCRIPTOR, in bytes.\r
1271 @param[in] ImageTypeId A unique GUID identifying the firmware image type.\r
1272\r
1273 @return TRUE This ImageInfo includes the ImageTypeId\r
1274 @return FALSE This ImageInfo does not include the ImageTypeId\r
1275**/\r
1276BOOLEAN\r
1277IsThisFmpImageInfo (\r
1436aea4
MK
1278 IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageInfo,\r
1279 IN UINT8 DescriptorCount,\r
1280 IN UINTN DescriptorSize,\r
1281 IN EFI_GUID *ImageTypeId\r
1e09ec09
JY
1282 )\r
1283{\r
1436aea4
MK
1284 EFI_FIRMWARE_IMAGE_DESCRIPTOR *CurrentImageInfo;\r
1285 UINTN Index;\r
1e09ec09
JY
1286\r
1287 CurrentImageInfo = ImageInfo;\r
1288 for (Index = 0; Index < DescriptorCount; Index++) {\r
1289 if (CompareGuid (&CurrentImageInfo->ImageTypeId, ImageTypeId)) {\r
1290 return TRUE;\r
1291 }\r
1436aea4 1292\r
1e09ec09
JY
1293 CurrentImageInfo = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)((UINT8 *)CurrentImageInfo + DescriptorSize);\r
1294 }\r
1436aea4 1295\r
1e09ec09
JY
1296 return FALSE;\r
1297}\r
1298\r
1299/**\r
1300 return the FMP whoes ImageInfo includes the ImageTypeId.\r
1301\r
1302 @param[in] ImageTypeId A unique GUID identifying the firmware image type.\r
1303\r
1304 @return The FMP whoes ImageInfo includes the ImageTypeId\r
1305**/\r
1306EFI_FIRMWARE_MANAGEMENT_PROTOCOL *\r
1307FindFmpFromImageTypeId (\r
1308 IN EFI_GUID *ImageTypeId\r
1309 )\r
1310{\r
1436aea4
MK
1311 EFI_STATUS Status;\r
1312 EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;\r
1313 EFI_FIRMWARE_MANAGEMENT_PROTOCOL *TargetFmp;\r
1314 EFI_HANDLE *HandleBuffer;\r
1315 UINTN NumberOfHandles;\r
1316 UINTN Index;\r
1317 EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf;\r
1318 UINTN ImageInfoSize;\r
1319 UINT32 FmpImageInfoDescriptorVer;\r
1320 UINT8 FmpImageInfoCount;\r
1321 UINTN DescriptorSize;\r
1322 UINT32 PackageVersion;\r
1323 CHAR16 *PackageVersionName;\r
1e09ec09
JY
1324\r
1325 Status = gBS->LocateHandleBuffer (\r
1326 ByProtocol,\r
1327 &gEfiFirmwareManagementProtocolGuid,\r
1328 NULL,\r
1329 &NumberOfHandles,\r
1330 &HandleBuffer\r
1331 );\r
1436aea4
MK
1332 if (EFI_ERROR (Status)) {\r
1333 Print (L"FMP protocol - %r\n", EFI_NOT_FOUND);\r
1e09ec09
JY
1334 return NULL;\r
1335 }\r
1336\r
1337 TargetFmp = NULL;\r
1338 for (Index = 0; Index < NumberOfHandles; Index++) {\r
1436aea4 1339 Status = gBS->HandleProtocol (\r
1e09ec09
JY
1340 HandleBuffer[Index],\r
1341 &gEfiFirmwareManagementProtocolGuid,\r
1342 (VOID **)&Fmp\r
1343 );\r
1436aea4 1344 if (EFI_ERROR (Status)) {\r
1e09ec09
JY
1345 continue;\r
1346 }\r
1347\r
1348 ImageInfoSize = 0;\r
1436aea4
MK
1349 Status = Fmp->GetImageInfo (\r
1350 Fmp,\r
1351 &ImageInfoSize,\r
1352 NULL,\r
1353 NULL,\r
1354 NULL,\r
1355 NULL,\r
1356 NULL,\r
1357 NULL\r
1358 );\r
1e09ec09
JY
1359 if (Status != EFI_BUFFER_TOO_SMALL) {\r
1360 continue;\r
1361 }\r
1362\r
1363 FmpImageInfoBuf = NULL;\r
1364 FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);\r
1365 if (FmpImageInfoBuf == NULL) {\r
1436aea4
MK
1366 FreePool (HandleBuffer);\r
1367 Print (L"Out of resource\n");\r
1e09ec09
JY
1368 return NULL;\r
1369 }\r
1370\r
1371 PackageVersionName = NULL;\r
1436aea4
MK
1372 Status = Fmp->GetImageInfo (\r
1373 Fmp,\r
1374 &ImageInfoSize, // ImageInfoSize\r
1375 FmpImageInfoBuf, // ImageInfo\r
1376 &FmpImageInfoDescriptorVer, // DescriptorVersion\r
1377 &FmpImageInfoCount, // DescriptorCount\r
1378 &DescriptorSize, // DescriptorSize\r
1379 &PackageVersion, // PackageVersion\r
1380 &PackageVersionName // PackageVersionName\r
1381 );\r
1e09ec09
JY
1382\r
1383 //\r
1384 // If FMP GetInformation interface failed, skip this resource\r
1385 //\r
1436aea4
MK
1386 if (EFI_ERROR (Status)) {\r
1387 FreePool (FmpImageInfoBuf);\r
1e09ec09
JY
1388 continue;\r
1389 }\r
1390\r
1391 if (PackageVersionName != NULL) {\r
1436aea4 1392 FreePool (PackageVersionName);\r
1e09ec09
JY
1393 }\r
1394\r
1395 if (IsThisFmpImageInfo (FmpImageInfoBuf, FmpImageInfoCount, DescriptorSize, ImageTypeId)) {\r
1396 TargetFmp = Fmp;\r
1397 }\r
1436aea4
MK
1398\r
1399 FreePool (FmpImageInfoBuf);\r
1e09ec09
JY
1400 if (TargetFmp != NULL) {\r
1401 break;\r
1402 }\r
1403 }\r
1436aea4
MK
1404\r
1405 FreePool (HandleBuffer);\r
1e09ec09
JY
1406 return TargetFmp;\r
1407}\r
1408\r
1409/**\r
1410 Dump FMP image data.\r
1411\r
1412 @param[in] ImageTypeId The ImageTypeId of the FMP image.\r
1413 It is used to identify the FMP protocol.\r
1414 @param[in] ImageIndex The ImageIndex of the FMP image.\r
1415 It is the input parameter for FMP->GetImage().\r
1416 @param[in] ImageName The file name to hold the output FMP image.\r
1417**/\r
1418VOID\r
1419DumpFmpImage (\r
1420 IN EFI_GUID *ImageTypeId,\r
1421 IN UINTN ImageIndex,\r
1422 IN CHAR16 *ImageName\r
1423 )\r
1424{\r
1436aea4
MK
1425 EFI_STATUS Status;\r
1426 EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;\r
1427 VOID *Image;\r
1428 UINTN ImageSize;\r
1e09ec09
JY
1429\r
1430 Fmp = FindFmpFromImageTypeId (ImageTypeId);\r
1431 if (Fmp == NULL) {\r
1436aea4
MK
1432 Print (L"No FMP include ImageTypeId %g\n", ImageTypeId);\r
1433 return;\r
1e09ec09
JY
1434 }\r
1435\r
1436 if (ImageIndex > 0xFF) {\r
1436aea4
MK
1437 Print (L"ImageIndex 0x%x too big\n", ImageIndex);\r
1438 return;\r
1e09ec09
JY
1439 }\r
1440\r
1436aea4 1441 Image = Fmp;\r
1e09ec09 1442 ImageSize = 0;\r
1436aea4 1443 Status = Fmp->GetImage (Fmp, (UINT8)ImageIndex, Image, &ImageSize);\r
1e09ec09 1444 if (Status != EFI_BUFFER_TOO_SMALL) {\r
1436aea4
MK
1445 Print (L"Fmp->GetImage - %r\n", Status);\r
1446 return;\r
1e09ec09
JY
1447 }\r
1448\r
1449 Image = AllocatePool (ImageSize);\r
1450 if (Image == NULL) {\r
1436aea4
MK
1451 Print (L"Allocate FmpImage 0x%x - %r\n", ImageSize, EFI_OUT_OF_RESOURCES);\r
1452 return;\r
1e09ec09
JY
1453 }\r
1454\r
1455 Status = Fmp->GetImage (Fmp, (UINT8)ImageIndex, Image, &ImageSize);\r
1436aea4
MK
1456 if (EFI_ERROR (Status)) {\r
1457 Print (L"Fmp->GetImage - %r\n", Status);\r
1458 return;\r
1e09ec09
JY
1459 }\r
1460\r
1436aea4
MK
1461 Status = WriteFileFromBuffer (ImageName, ImageSize, Image);\r
1462 Print (L"CapsuleApp: Dump %g ImageIndex (0x%x) to %s %r\n", ImageTypeId, ImageIndex, ImageName, Status);\r
1e09ec09 1463\r
d4d91167
SZ
1464 FreePool (Image);\r
1465\r
1436aea4 1466 return;\r
1e09ec09 1467}\r