2 Dump Capsule image information.
4 Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include <Library/BaseLib.h>
17 #include <Library/DebugLib.h>
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/MemoryAllocationLib.h>
20 #include <Library/UefiBootServicesTableLib.h>
21 #include <Library/UefiRuntimeServicesTableLib.h>
22 #include <Library/UefiLib.h>
23 #include <Library/PrintLib.h>
24 #include <Library/FileHandleLib.h>
25 #include <Library/SortLib.h>
26 #include <Library/UefiBootManagerLib.h>
27 #include <Library/DevicePathLib.h>
28 #include <Protocol/FirmwareManagement.h>
29 #include <Protocol/SimpleFileSystem.h>
30 #include <Protocol/Shell.h>
31 #include <Guid/ImageAuthentication.h>
32 #include <Guid/CapsuleReport.h>
33 #include <Guid/SystemResourceTable.h>
34 #include <Guid/FmpCapsule.h>
35 #include <Guid/CapsuleVendor.h>
36 #include <IndustryStandard/WindowsUxCapsule.h>
39 // (20 * (6+5+2))+1) unicode characters from EFI FAT spec (doubled for bytes)
41 #define MAX_FILE_NAME_SIZE 522
42 #define MAX_FILE_NAME_LEN (MAX_FILE_NAME_SIZE / sizeof(CHAR16))
47 @param[in] FileName The file to be read.
48 @param[out] BufferSize The file buffer size
49 @param[out] Buffer The file buffer
51 @retval EFI_SUCCESS Read file successfully
52 @retval EFI_NOT_FOUND File not found
57 OUT UINTN
*BufferSize
,
64 @param[in] FileName The file to be written.
65 @param[in] BufferSize The file buffer size
66 @param[in] Buffer The file buffer
68 @retval EFI_SUCCESS Write file successfully
80 @return Pointer to shell protocol.
89 Get SimpleFileSystem from boot option file path.
91 @param[in] DevicePath The file path of boot option
92 @param[out] FullPath The full device path of boot device
93 @param[out] Fs The file system within EfiSysPartition
95 @retval EFI_SUCCESS Get file system successfully
96 @retval EFI_NOT_FOUND No valid file system found
97 @retval others Get file system failed
102 GetEfiSysPartitionFromBootOptionFilePath (
103 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
104 OUT EFI_DEVICE_PATH_PROTOCOL
**FullPath
,
105 OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**Fs
109 Validate if it is valid capsule header
111 This function assumes the caller provided correct CapsuleHeader pointer
114 This function validates the fields in EFI_CAPSULE_HEADER.
116 @param[in] CapsuleHeader Points to a capsule header.
117 @param[in] CapsuleSize Size of the whole capsule image.
121 IsValidCapsuleHeader (
122 IN EFI_CAPSULE_HEADER
*CapsuleHeader
,
123 IN UINT64 CapsuleSize
127 Dump UX capsule information.
129 @param[in] CapsuleHeader The UX capsule header
133 IN EFI_CAPSULE_HEADER
*CapsuleHeader
136 EFI_DISPLAY_CAPSULE
*DisplayCapsule
;
137 DisplayCapsule
= (EFI_DISPLAY_CAPSULE
*)CapsuleHeader
;
138 Print(L
"[UxCapusule]\n");
139 Print(L
"CapsuleHeader:\n");
140 Print(L
" CapsuleGuid - %g\n", &DisplayCapsule
->CapsuleHeader
.CapsuleGuid
);
141 Print(L
" HeaderSize - 0x%x\n", DisplayCapsule
->CapsuleHeader
.HeaderSize
);
142 Print(L
" Flags - 0x%x\n", DisplayCapsule
->CapsuleHeader
.Flags
);
143 Print(L
" CapsuleImageSize - 0x%x\n", DisplayCapsule
->CapsuleHeader
.CapsuleImageSize
);
144 Print(L
"ImagePayload:\n");
145 Print(L
" Version - 0x%x\n", DisplayCapsule
->ImagePayload
.Version
);
146 Print(L
" Checksum - 0x%x\n", DisplayCapsule
->ImagePayload
.Checksum
);
147 Print(L
" ImageType - 0x%x\n", DisplayCapsule
->ImagePayload
.ImageType
);
148 Print(L
" Mode - 0x%x\n", DisplayCapsule
->ImagePayload
.Mode
);
149 Print(L
" OffsetX - 0x%x\n", DisplayCapsule
->ImagePayload
.OffsetX
);
150 Print(L
" OffsetY - 0x%x\n", DisplayCapsule
->ImagePayload
.OffsetY
);
155 Dump a non-nested FMP capsule.
157 @param[in] CapsuleHeader A pointer to CapsuleHeader
161 IN EFI_CAPSULE_HEADER
*CapsuleHeader
164 EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER
*FmpCapsuleHeader
;
165 UINT64
*ItemOffsetList
;
168 EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER
*FmpImageHeader
;
170 Print(L
"[FmpCapsule]\n");
171 Print(L
"CapsuleHeader:\n");
172 Print(L
" CapsuleGuid - %g\n", &CapsuleHeader
->CapsuleGuid
);
173 Print(L
" HeaderSize - 0x%x\n", CapsuleHeader
->HeaderSize
);
174 Print(L
" Flags - 0x%x\n", CapsuleHeader
->Flags
);
175 Print(L
" CapsuleImageSize - 0x%x\n", CapsuleHeader
->CapsuleImageSize
);
177 FmpCapsuleHeader
= (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER
*)((UINT8
*)CapsuleHeader
+ CapsuleHeader
->HeaderSize
);
178 ItemOffsetList
= (UINT64
*)(FmpCapsuleHeader
+ 1);
179 Print(L
"FmpHeader:\n");
180 Print(L
" Version - 0x%x\n", FmpCapsuleHeader
->Version
);
181 Print(L
" EmbeddedDriverCount - 0x%x\n", FmpCapsuleHeader
->EmbeddedDriverCount
);
182 Print(L
" PayloadItemCount - 0x%x\n", FmpCapsuleHeader
->PayloadItemCount
);
183 Count
= FmpCapsuleHeader
->EmbeddedDriverCount
+ FmpCapsuleHeader
->PayloadItemCount
;
184 for (Index
= 0; Index
< Count
; Index
++) {
185 Print(L
" Offset[%d] - 0x%x\n", Index
, ItemOffsetList
[Index
]);
188 for (Index
= FmpCapsuleHeader
->EmbeddedDriverCount
; Index
< Count
; Index
++) {
189 Print(L
"FmpPayload[%d] ImageHeader:\n", Index
);
190 FmpImageHeader
= (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER
*)((UINT8
*)FmpCapsuleHeader
+ ItemOffsetList
[Index
]);
191 Print(L
" Version - 0x%x\n", FmpImageHeader
->Version
);
192 Print(L
" UpdateImageTypeId - %g\n", &FmpImageHeader
->UpdateImageTypeId
);
193 Print(L
" UpdateImageIndex - 0x%x\n", FmpImageHeader
->UpdateImageIndex
);
194 Print(L
" UpdateImageSize - 0x%x\n", FmpImageHeader
->UpdateImageSize
);
195 Print(L
" UpdateVendorCodeSize - 0x%x\n", FmpImageHeader
->UpdateVendorCodeSize
);
196 if (FmpImageHeader
->Version
>= EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION
) {
197 Print(L
" UpdateHardwareInstance - 0x%lx\n", FmpImageHeader
->UpdateHardwareInstance
);
203 Return if there is a FMP header below capsule header.
205 @param[in] CapsuleHeader A pointer to EFI_CAPSULE_HEADER
207 @retval TRUE There is a FMP header below capsule header.
208 @retval FALSE There is not a FMP header below capsule header
212 IN EFI_CAPSULE_HEADER
*CapsuleHeader
216 EFI_SYSTEM_RESOURCE_TABLE
*Esrt
;
217 EFI_SYSTEM_RESOURCE_ENTRY
*EsrtEntry
;
219 BOOLEAN EsrtGuidFound
;
220 EFI_CAPSULE_HEADER
*NestedCapsuleHeader
;
221 UINTN NestedCapsuleSize
;
226 EsrtGuidFound
= FALSE
;
227 Status
= EfiGetSystemConfigurationTable(&gEfiSystemResourceTableGuid
, (VOID
**)&Esrt
);
228 if (!EFI_ERROR(Status
)) {
229 ASSERT (Esrt
!= NULL
);
230 EsrtEntry
= (VOID
*)(Esrt
+ 1);
231 for (Index
= 0; Index
< Esrt
->FwResourceCount
; Index
++, EsrtEntry
++) {
232 if (CompareGuid(&EsrtEntry
->FwClass
, &CapsuleHeader
->CapsuleGuid
)) {
233 EsrtGuidFound
= TRUE
;
239 if (!EsrtGuidFound
) {
244 // Check nested capsule header
245 // FMP GUID after ESRT one
247 NestedCapsuleHeader
= (EFI_CAPSULE_HEADER
*)((UINT8
*)CapsuleHeader
+ CapsuleHeader
->HeaderSize
);
248 NestedCapsuleSize
= (UINTN
)CapsuleHeader
+ CapsuleHeader
->CapsuleImageSize
- (UINTN
)NestedCapsuleHeader
;
249 if (NestedCapsuleSize
< sizeof(EFI_CAPSULE_HEADER
)) {
252 if (!CompareGuid(&NestedCapsuleHeader
->CapsuleGuid
, &gEfiFmpCapsuleGuid
)) {
259 Dump capsule information
261 @param[in] CapsuleName The name of the capsule image.
263 @retval EFI_SUCCESS The capsule information is dumped.
264 @retval EFI_UNSUPPORTED Input parameter is not valid.
268 IN CHAR16
*CapsuleName
273 EFI_CAPSULE_HEADER
*CapsuleHeader
;
277 Status
= ReadFileToBuffer(CapsuleName
, &FileSize
, &Buffer
);
278 if (EFI_ERROR(Status
)) {
279 Print(L
"CapsuleApp: Capsule (%s) is not found.\n", CapsuleName
);
282 if (!IsValidCapsuleHeader (Buffer
, FileSize
)) {
283 Print(L
"CapsuleApp: Capsule image (%s) is not a valid capsule.\n", CapsuleName
);
284 Status
= EFI_INVALID_PARAMETER
;
288 CapsuleHeader
= Buffer
;
289 if (CompareGuid(&CapsuleHeader
->CapsuleGuid
, &gWindowsUxCapsuleGuid
)) {
290 DumpUxCapsule(CapsuleHeader
);
291 Status
= EFI_SUCCESS
;
295 if (CompareGuid(&CapsuleHeader
->CapsuleGuid
, &gEfiFmpCapsuleGuid
)) {
296 DumpFmpCapsule(CapsuleHeader
);
298 if (IsNestedFmpCapsule(CapsuleHeader
)) {
299 Print(L
"[NestedCapusule]\n");
300 Print(L
"CapsuleHeader:\n");
301 Print(L
" CapsuleGuid - %g\n", &CapsuleHeader
->CapsuleGuid
);
302 Print(L
" HeaderSize - 0x%x\n", CapsuleHeader
->HeaderSize
);
303 Print(L
" Flags - 0x%x\n", CapsuleHeader
->Flags
);
304 Print(L
" CapsuleImageSize - 0x%x\n", CapsuleHeader
->CapsuleImageSize
);
305 DumpFmpCapsule((EFI_CAPSULE_HEADER
*)((UINTN
)CapsuleHeader
+ CapsuleHeader
->HeaderSize
));
309 if (Buffer
!= NULL
) {
316 Dump capsule status variable.
318 @retval EFI_SUCCESS The capsule status variable is dumped.
319 @retval EFI_UNSUPPORTED Input parameter is not valid.
322 DumpCapsuleStatusVariable (
328 CHAR16 CapsuleVarName
[20];
330 EFI_CAPSULE_RESULT_VARIABLE_HEADER
*CapsuleResult
;
331 EFI_CAPSULE_RESULT_VARIABLE_FMP
*CapsuleResultFmp
;
332 UINTN CapsuleFileNameSize
;
333 CHAR16 CapsuleIndexData
[12];
334 CHAR16
*CapsuleIndex
;
335 CHAR16
*CapsuleFileName
;
336 CHAR16
*CapsuleTarget
;
338 Status
= GetVariable2(
340 &gEfiCapsuleReportGuid
,
341 (VOID
**)&CapsuleIndex
,
344 if (!EFI_ERROR(Status
)) {
345 ASSERT (CapsuleIndex
!= NULL
);
346 CopyMem(CapsuleIndexData
, CapsuleIndex
, 11 * sizeof(CHAR16
));
347 CapsuleIndexData
[11] = 0;
348 Print(L
"CapsuleMax - %s\n", CapsuleIndexData
);
349 FreePool(CapsuleIndex
);
351 Status
= GetVariable2(
353 &gEfiCapsuleReportGuid
,
354 (VOID
**)&CapsuleIndex
,
357 if (!EFI_ERROR(Status
)) {
358 ASSERT (CapsuleIndex
!= NULL
);
359 CopyMem(CapsuleIndexData
, CapsuleIndex
, 11 * sizeof(CHAR16
));
360 CapsuleIndexData
[11] = 0;
361 Print(L
"CapsuleLast - %s\n", CapsuleIndexData
);
362 FreePool(CapsuleIndex
);
366 StrCpyS (CapsuleVarName
, sizeof(CapsuleVarName
)/sizeof(CapsuleVarName
[0]), L
"Capsule");
367 TempVarName
= CapsuleVarName
+ StrLen (CapsuleVarName
);
371 UnicodeSPrint (TempVarName
, 5 * sizeof(CHAR16
), L
"%04x", Index
);
373 Status
= GetVariable2 (
375 &gEfiCapsuleReportGuid
,
376 (VOID
**) &CapsuleResult
,
379 if (Status
== EFI_NOT_FOUND
) {
381 } else if (EFI_ERROR(Status
)) {
384 ASSERT (CapsuleResult
!= NULL
);
387 // display capsule process status
389 if (CapsuleResult
->VariableTotalSize
>= sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER
)) {
390 Print (L
"CapsuleName: %s\n", CapsuleVarName
);
391 Print (L
" Capsule Guid: %g\n", &CapsuleResult
->CapsuleGuid
);
392 Print (L
" Capsule ProcessedTime: %t\n", &CapsuleResult
->CapsuleProcessed
);
393 Print (L
" Capsule Status: %r\n", CapsuleResult
->CapsuleStatus
);
396 if (CompareGuid(&CapsuleResult
->CapsuleGuid
, &gEfiFmpCapsuleGuid
)) {
397 if (CapsuleResult
->VariableTotalSize
>= sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER
) + sizeof(EFI_CAPSULE_RESULT_VARIABLE_FMP
) + sizeof(CHAR16
) * 2) {
398 CapsuleResultFmp
= (EFI_CAPSULE_RESULT_VARIABLE_FMP
*)(CapsuleResult
+ 1);
399 Print(L
" Capsule FMP Version: 0x%x\n", CapsuleResultFmp
->Version
);
400 Print(L
" Capsule FMP PayloadIndex: 0x%x\n", CapsuleResultFmp
->PayloadIndex
);
401 Print(L
" Capsule FMP UpdateImageIndex: 0x%x\n", CapsuleResultFmp
->UpdateImageIndex
);
402 Print(L
" Capsule FMP UpdateImageTypeId: %g\n", &CapsuleResultFmp
->UpdateImageTypeId
);
403 CapsuleFileName
= (CHAR16
*)(CapsuleResultFmp
+ 1);
404 Print(L
" Capsule FMP CapsuleFileName: \"%s\"\n", CapsuleFileName
);
405 CapsuleFileNameSize
= StrSize(CapsuleFileName
);
406 CapsuleTarget
= (CHAR16
*)((UINTN
)CapsuleFileName
+ CapsuleFileNameSize
);
407 Print(L
" Capsule FMP CapsuleTarget: \"%s\"\n", CapsuleTarget
);
411 FreePool(CapsuleResult
);
414 if (Index
> 0xFFFF) {
422 CHAR8
*mFwTypeString
[] = {
429 CHAR8
*mLastAttemptStatusString
[] = {
431 "Error: Unsuccessful",
432 "Error: Insufficient Resources",
433 "Error: Incorrect Version",
434 "Error: Invalid Format",
436 "Error: Power Event AC",
437 "Error: Power Event Battery",
441 Convert FwType to a string.
443 @param[in] FwType FwType in ESRT
445 @return a string for FwType.
452 if (FwType
< sizeof(mFwTypeString
) / sizeof(mFwTypeString
[0])) {
453 return mFwTypeString
[FwType
];
460 Convert LastAttemptStatus to a string.
462 @param[in] LastAttemptStatus LastAttemptStatus in FMP or ESRT
464 @return a string for LastAttemptStatus.
467 LastAttemptStatusToString (
468 IN UINT32 LastAttemptStatus
471 if (LastAttemptStatus
< sizeof(mLastAttemptStatusString
) / sizeof(mLastAttemptStatusString
[0])) {
472 return mLastAttemptStatusString
[LastAttemptStatus
];
474 return "Error: Unknown";
481 @param[in] EsrtEntry ESRT entry
485 IN EFI_SYSTEM_RESOURCE_ENTRY
*EsrtEntry
488 Print(L
" FwClass - %g\n", &EsrtEntry
->FwClass
);
489 Print(L
" FwType - 0x%x (%a)\n", EsrtEntry
->FwType
, FwTypeToString(EsrtEntry
->FwType
));
490 Print(L
" FwVersion - 0x%x\n", EsrtEntry
->FwVersion
);
491 Print(L
" LowestSupportedFwVersion - 0x%x\n", EsrtEntry
->LowestSupportedFwVersion
);
492 Print(L
" CapsuleFlags - 0x%x\n", EsrtEntry
->CapsuleFlags
);
493 Print(L
" LastAttemptVersion - 0x%x\n", EsrtEntry
->LastAttemptVersion
);
494 Print(L
" LastAttemptStatus - 0x%x (%a)\n", EsrtEntry
->LastAttemptStatus
, LastAttemptStatusToString(EsrtEntry
->LastAttemptStatus
));
500 @param[in] Esrt ESRT table
504 IN EFI_SYSTEM_RESOURCE_TABLE
*Esrt
508 EFI_SYSTEM_RESOURCE_ENTRY
*EsrtEntry
;
514 Print(L
"EFI_SYSTEM_RESOURCE_TABLE:\n");
515 Print(L
"FwResourceCount - 0x%x\n", Esrt
->FwResourceCount
);
516 Print(L
"FwResourceCountMax - 0x%x\n", Esrt
->FwResourceCountMax
);
517 Print(L
"FwResourceVersion - 0x%lx\n", Esrt
->FwResourceVersion
);
519 EsrtEntry
= (VOID
*)(Esrt
+ 1);
520 for (Index
= 0; Index
< Esrt
->FwResourceCount
; Index
++) {
521 Print(L
"EFI_SYSTEM_RESOURCE_ENTRY (%d):\n", Index
);
522 DumpEsrtEntry(EsrtEntry
);
536 EFI_SYSTEM_RESOURCE_TABLE
*Esrt
;
538 Print(L
"##############\n");
539 Print(L
"# ESRT TABLE #\n");
540 Print(L
"##############\n");
542 Status
= EfiGetSystemConfigurationTable (&gEfiSystemResourceTableGuid
, (VOID
**)&Esrt
);
543 if (EFI_ERROR(Status
)) {
544 Print(L
"ESRT - %r\n", Status
);
553 Dump capsule information from CapsuleHeader
555 @param[in] CapsuleHeader The CapsuleHeader of the capsule image.
557 @retval EFI_SUCCESS The capsule information is dumped.
561 DumpCapsuleFromBuffer (
562 IN EFI_CAPSULE_HEADER
*CapsuleHeader
565 if (CompareGuid (&CapsuleHeader
->CapsuleGuid
, &gWindowsUxCapsuleGuid
)) {
566 DumpUxCapsule (CapsuleHeader
);
570 if (CompareGuid (&CapsuleHeader
->CapsuleGuid
, &gEfiFmpCapsuleGuid
)) {
571 DumpFmpCapsule (CapsuleHeader
);
573 if (IsNestedFmpCapsule (CapsuleHeader
)) {
574 Print (L
"[NestedCapusule]\n");
575 Print (L
"CapsuleHeader:\n");
576 Print (L
" CapsuleGuid - %g\n", &CapsuleHeader
->CapsuleGuid
);
577 Print (L
" HeaderSize - 0x%x\n", CapsuleHeader
->HeaderSize
);
578 Print (L
" Flags - 0x%x\n", CapsuleHeader
->Flags
);
579 Print (L
" CapsuleImageSize - 0x%x\n", CapsuleHeader
->CapsuleImageSize
);
580 DumpFmpCapsule ((EFI_CAPSULE_HEADER
*)((UINTN
)CapsuleHeader
+ CapsuleHeader
->HeaderSize
));
587 This routine is called to upper case given unicode string.
589 @param[in] Str String to upper case
591 @retval upper cased string after process
602 for (Cptr
= Str
; *Cptr
!= L
'\0'; Cptr
++) {
603 if (L
'a' <= *Cptr
&& *Cptr
<= L
'z') {
604 *Cptr
= *Cptr
- L
'a' + L
'A';
612 This routine is used to return substring before period '.' or '\0'
613 Caller should respsonsible of substr space allocation & free
615 @param[in] Str String to check
616 @param[out] SubStr First part of string before period or '\0'
617 @param[out] SubStrLen Length of first part of string
622 GetSubStringBeforePeriod (
629 for (Index
= 0; Str
[Index
] != L
'.' && Str
[Index
] != L
'\0'; Index
++) {
630 SubStr
[Index
] = Str
[Index
];
633 SubStr
[Index
] = L
'\0';
638 This routine pad the string in tail with input character.
640 @param[in] StrBuf Str buffer to be padded, should be enough room for
641 @param[in] PadLen Expected padding length
642 @param[in] Character Character used to pad
655 for (Index
= 0; StrBuf
[Index
] != L
'\0'; Index
++);
658 StrBuf
[Index
] = Character
;
663 StrBuf
[Index
] = L
'\0';
667 This routine find the offset of the last period '.' of string. if No period exists
668 function FileNameExtension is set to L'\0'
670 @param[in] FileName File name to split between last period
671 @param[out] FileNameFirst First FileName before last period
672 @param[out] FileNameExtension FileName after last period
677 SplitFileNameExtension (
679 OUT CHAR16
*FileNameFirst
,
680 OUT CHAR16
*FileNameExtension
686 StringLen
= StrLen(FileName
);
687 for (Index
= StringLen
; Index
> 0 && FileName
[Index
] != L
'.'; Index
--);
690 // No period exists. No FileName Extension
692 if (Index
== 0 && FileName
[Index
] != L
'.') {
693 FileNameExtension
[0] = L
'\0';
696 StrCpyS (FileNameExtension
, MAX_FILE_NAME_LEN
, &FileName
[Index
+1]);
700 // Copy First file name
702 StrnCpyS (FileNameFirst
, MAX_FILE_NAME_LEN
, FileName
, Index
);
703 FileNameFirst
[Index
] = L
'\0';
707 The function is called by PerformQuickSort to sort file name in alphabet.
709 @param[in] Left The pointer to first buffer.
710 @param[in] Right The pointer to second buffer.
712 @retval 0 Buffer1 equal to Buffer2.
713 @return <0 Buffer1 is less than Buffer2.
714 @return >0 Buffer1 is greater than Buffer2.
719 CompareFileNameInAlphabet (
724 EFI_FILE_INFO
*FileInfo1
;
725 EFI_FILE_INFO
*FileInfo2
;
726 CHAR16 FileName1
[MAX_FILE_NAME_SIZE
];
727 CHAR16 FileExtension1
[MAX_FILE_NAME_SIZE
];
728 CHAR16 FileName2
[MAX_FILE_NAME_SIZE
];
729 CHAR16 FileExtension2
[MAX_FILE_NAME_SIZE
];
730 CHAR16 TempSubStr1
[MAX_FILE_NAME_SIZE
];
731 CHAR16 TempSubStr2
[MAX_FILE_NAME_SIZE
];
734 INTN SubStrCmpResult
;
736 FileInfo1
= (EFI_FILE_INFO
*) (*(UINTN
*)Left
);
737 FileInfo2
= (EFI_FILE_INFO
*) (*(UINTN
*)Right
);
739 SplitFileNameExtension (FileInfo1
->FileName
, FileName1
, FileExtension1
);
740 SplitFileNameExtension (FileInfo2
->FileName
, FileName2
, FileExtension2
);
742 UpperCaseString (FileName1
);
743 UpperCaseString (FileName2
);
745 GetSubStringBeforePeriod (FileName1
, TempSubStr1
, &SubStrLen1
);
746 GetSubStringBeforePeriod (FileName2
, TempSubStr2
, &SubStrLen2
);
748 if (SubStrLen1
> SubStrLen2
) {
750 // Substr in NewFileName is longer. Pad tail with SPACE
752 PadStrInTail (TempSubStr2
, SubStrLen1
- SubStrLen2
, L
' ');
753 } else if (SubStrLen1
< SubStrLen2
){
755 // Substr in ListedFileName is longer. Pad tail with SPACE
757 PadStrInTail (TempSubStr1
, SubStrLen2
- SubStrLen1
, L
' ');
760 SubStrCmpResult
= StrnCmp (TempSubStr1
, TempSubStr2
, MAX_FILE_NAME_LEN
);
761 if (SubStrCmpResult
!= 0) {
762 return SubStrCmpResult
;
765 UpperCaseString (FileExtension1
);
766 UpperCaseString (FileExtension2
);
768 return StrnCmp (FileExtension1
, FileExtension2
, MAX_FILE_NAME_LEN
);
772 Dump capsule information from disk.
774 @param[in] Fs The device path of disk.
775 @param[in] DumpCapsuleInfo The flag to indicate whether to dump the capsule inforomation.
777 @retval EFI_SUCCESS The capsule information is dumped.
781 DumpCapsuleFromDisk (
782 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Fs
,
783 IN BOOLEAN DumpCapsuleInfo
789 EFI_FILE
*FileHandle
;
793 EFI_FILE_INFO
**FileInfoBuffer
;
794 EFI_FILE_INFO
*FileInfo
;
801 FileInfoBuffer
= NULL
;
806 Status
= Fs
->OpenVolume (Fs
, &Root
);
807 if (EFI_ERROR (Status
)) {
808 Print (L
"Cannot open volume. Status = %r\n", Status
);
812 Status
= Root
->Open (Root
, &DirHandle
, EFI_CAPSULE_FILE_DIRECTORY
, EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
, 0);
813 if (EFI_ERROR (Status
)) {
814 Print (L
"Cannot open %s. Status = %r\n", EFI_CAPSULE_FILE_DIRECTORY
, Status
);
819 // Get file count first
822 Status
= FileHandleFindFirstFile (DirHandle
, &FileInfo
);
823 if (EFI_ERROR (Status
) || FileInfo
== NULL
) {
824 Print (L
"Get File Info Fail. Status = %r\n", Status
);
828 if ((FileInfo
->Attribute
& (EFI_FILE_SYSTEM
| EFI_FILE_ARCHIVE
)) != 0) {
832 Status
= FileHandleFindNextFile (DirHandle
, FileInfo
, &NoFile
);
833 if (EFI_ERROR (Status
)) {
834 Print (L
"Get Next File Fail. Status = %r\n", Status
);
839 if (FileCount
== 0) {
840 Print (L
"Error: No capsule file found!\n");
841 Status
= EFI_NOT_FOUND
;
845 FileInfoBuffer
= AllocateZeroPool (sizeof (FileInfo
) * FileCount
);
846 if (FileInfoBuffer
== NULL
) {
847 Status
= EFI_OUT_OF_RESOURCES
;
856 Status
= FileHandleFindFirstFile (DirHandle
, &FileInfo
);
857 if (EFI_ERROR (Status
) || FileInfo
== NULL
) {
858 Print (L
"Get File Info Fail. Status = %r\n", Status
);
862 if ((FileInfo
->Attribute
& (EFI_FILE_SYSTEM
| EFI_FILE_ARCHIVE
)) != 0) {
863 FileInfoBuffer
[Index
++] = AllocateCopyPool ((UINTN
)FileInfo
->Size
, FileInfo
);
866 Status
= FileHandleFindNextFile (DirHandle
, FileInfo
, &NoFile
);
867 if (EFI_ERROR (Status
)) {
868 Print (L
"Get Next File Fail. Status = %r\n", Status
);
874 // Sort FileInfoBuffer by alphabet order
880 (SORT_COMPARE
) CompareFileNameInAlphabet
883 Print (L
"The capsules will be performed by following order:\n");
885 for (Index
= 0; Index
< FileCount
; Index
++) {
886 Print (L
" %d.%s\n", Index
+ 1, FileInfoBuffer
[Index
]->FileName
);
889 if (!DumpCapsuleInfo
) {
890 Status
= EFI_SUCCESS
;
894 Print(L
"The infomation of the capsules:\n");
896 for (Index
= 0; Index
< FileCount
; Index
++) {
898 Status
= DirHandle
->Open (DirHandle
, &FileHandle
, FileInfoBuffer
[Index
]->FileName
, EFI_FILE_MODE_READ
, 0);
899 if (EFI_ERROR (Status
)) {
903 Status
= FileHandleGetSize (FileHandle
, (UINT64
*) &FileSize
);
904 if (EFI_ERROR (Status
)) {
905 Print (L
"Cannot read file %s. Status = %r\n", FileInfoBuffer
[Index
]->FileName
, Status
);
906 FileHandleClose (FileHandle
);
910 FileBuffer
= AllocatePool (FileSize
);
911 if (FileBuffer
== NULL
) {
912 Status
= EFI_OUT_OF_RESOURCES
;
916 Status
= FileHandleRead (FileHandle
, &FileSize
, FileBuffer
);
917 if (EFI_ERROR (Status
)) {
918 Print (L
"Cannot read file %s. Status = %r\n", FileInfoBuffer
[Index
]->FileName
, Status
);
919 FileHandleClose (FileHandle
);
920 FreePool (FileBuffer
);
924 Print (L
"**************************\n");
925 Print (L
" %d.%s:\n", Index
+ 1, FileInfoBuffer
[Index
]->FileName
);
926 Print (L
"**************************\n");
927 DumpCapsuleFromBuffer ((EFI_CAPSULE_HEADER
*) FileBuffer
);
928 FileHandleClose (FileHandle
);
929 FreePool (FileBuffer
);
933 if (FileInfoBuffer
!= NULL
) {
934 for (Index
= 0; Index
< FileCount
; Index
++) {
935 if (FileInfoBuffer
[Index
] != NULL
) {
936 FreePool (FileInfoBuffer
[Index
]);
939 FreePool (FileInfoBuffer
);
946 Dump capsule inforomation form Gather list.
948 @param[in] BlockDescriptors The block descriptors for the capsule images
949 @param[in] DumpCapsuleInfo The flag to indicate whether to dump the capsule inforomation.
953 DumpBlockDescriptors (
954 IN EFI_CAPSULE_BLOCK_DESCRIPTOR
*BlockDescriptors
,
955 IN BOOLEAN DumpCapsuleInfo
958 EFI_CAPSULE_BLOCK_DESCRIPTOR
*TempBlockPtr
;
960 TempBlockPtr
= BlockDescriptors
;
963 if (TempBlockPtr
->Length
!= 0) {
964 if (DumpCapsuleInfo
) {
965 Print(L
"******************************************************\n");
967 Print(L
"Capsule data starts at 0x%08x with size 0x%08x\n", TempBlockPtr
->Union
.DataBlock
, TempBlockPtr
->Length
);
968 if (DumpCapsuleInfo
) {
969 Print(L
"******************************************************\n");
970 DumpCapsuleFromBuffer ((EFI_CAPSULE_HEADER
*) (UINTN
) TempBlockPtr
->Union
.DataBlock
);
974 if (TempBlockPtr
->Union
.ContinuationPointer
== (UINTN
)NULL
) {
977 TempBlockPtr
= (EFI_CAPSULE_BLOCK_DESCRIPTOR
*) (UINTN
) TempBlockPtr
->Union
.ContinuationPointer
;
984 Dump Provisioned Capsule.
986 @param[in] DumpCapsuleInfo The flag to indicate whether to dump the capsule inforomation.
990 DumpProvisionedCapsule (
991 IN BOOLEAN DumpCapsuleInfo
995 CHAR16 CapsuleVarName
[30];
998 EFI_PHYSICAL_ADDRESS
*CapsuleDataPtr64
;
1000 CHAR16 BootOptionName
[20];
1001 EFI_BOOT_MANAGER_LOAD_OPTION BootNextOptionEntry
;
1002 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1003 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Fs
;
1004 EFI_SHELL_PROTOCOL
*ShellProtocol
;
1007 CapsuleDataPtr64
= NULL
;
1010 ShellProtocol
= GetShellProtocol ();
1011 if (ShellProtocol
== NULL
) {
1012 Print (L
"Get Shell Protocol Fail\n");
1017 // Dump capsule provisioned on Memory
1019 Print (L
"#########################\n");
1020 Print (L
"### Capsule on Memory ###\n");
1021 Print (L
"#########################\n");
1022 StrCpyS (CapsuleVarName
, sizeof(CapsuleVarName
)/sizeof(CHAR16
), EFI_CAPSULE_VARIABLE_NAME
);
1023 TempVarName
= CapsuleVarName
+ StrLen (CapsuleVarName
);
1026 UnicodeValueToStringS (
1028 sizeof (CapsuleVarName
) - ((UINTN
)TempVarName
- (UINTN
)CapsuleVarName
),
1035 Status
= GetVariable2 (
1037 &gEfiCapsuleVendorGuid
,
1038 (VOID
**) &CapsuleDataPtr64
,
1041 if (EFI_ERROR (Status
) || CapsuleDataPtr64
== NULL
) {
1043 Print (L
"No data.\n");
1049 Print (L
"Capsule Description at 0x%08x\n", *CapsuleDataPtr64
);
1050 DumpBlockDescriptors ((EFI_CAPSULE_BLOCK_DESCRIPTOR
*) (UINTN
) *CapsuleDataPtr64
, DumpCapsuleInfo
);
1054 // Dump capsule provisioned on Disk
1056 Print (L
"#########################\n");
1057 Print (L
"### Capsule on Disk #####\n");
1058 Print (L
"#########################\n");
1059 Status
= GetVariable2 (
1061 &gEfiGlobalVariableGuid
,
1062 (VOID
**) &BootNext
,
1065 if (EFI_ERROR (Status
) || BootNext
== NULL
) {
1066 Print (L
"Get BootNext Variable Fail. Status = %r\n", Status
);
1068 UnicodeSPrint (BootOptionName
, sizeof (BootOptionName
), L
"Boot%04x", *BootNext
);
1069 Status
= EfiBootManagerVariableToLoadOption (BootOptionName
, &BootNextOptionEntry
);
1070 if (!EFI_ERROR (Status
)) {
1072 // Display description and device path
1074 GetEfiSysPartitionFromBootOptionFilePath (BootNextOptionEntry
.FilePath
, &DevicePath
, &Fs
);
1075 if(!EFI_ERROR (Status
)) {
1076 Print (L
"Capsules are provisioned on BootOption: %s\n", BootNextOptionEntry
.Description
);
1077 Print (L
" %s %s\n", ShellProtocol
->GetMapFromDevicePath (&DevicePath
), ConvertDevicePathToText(DevicePath
, TRUE
, TRUE
));
1078 DumpCapsuleFromDisk (Fs
, DumpCapsuleInfo
);
1085 Dump FMP information.
1087 @param[in] ImageInfoSize The size of ImageInfo, in bytes.
1088 @param[in] ImageInfo A pointer to EFI_FIRMWARE_IMAGE_DESCRIPTOR.
1089 @param[in] DescriptorVersion The version of EFI_FIRMWARE_IMAGE_DESCRIPTOR.
1090 @param[in] DescriptorCount The count of EFI_FIRMWARE_IMAGE_DESCRIPTOR.
1091 @param[in] DescriptorSize The size of an individual EFI_FIRMWARE_IMAGE_DESCRIPTOR, in bytes.
1092 @param[in] PackageVersion The version of package.
1093 @param[in] PackageVersionName The version name of package.
1097 IN UINTN ImageInfoSize
,
1098 IN EFI_FIRMWARE_IMAGE_DESCRIPTOR
*ImageInfo
,
1099 IN UINT32 DescriptorVersion
,
1100 IN UINT8 DescriptorCount
,
1101 IN UINTN DescriptorSize
,
1102 IN UINT32 PackageVersion
,
1103 IN CHAR16
*PackageVersionName
1106 EFI_FIRMWARE_IMAGE_DESCRIPTOR
*CurrentImageInfo
;
1109 Print(L
" DescriptorVersion - 0x%x\n", DescriptorVersion
);
1110 Print(L
" DescriptorCount - 0x%x\n", DescriptorCount
);
1111 Print(L
" DescriptorSize - 0x%x\n", DescriptorSize
);
1112 Print(L
" PackageVersion - 0x%x\n", PackageVersion
);
1113 Print(L
" PackageVersionName - \"%s\"\n", PackageVersionName
);
1114 CurrentImageInfo
= ImageInfo
;
1115 for (Index
= 0; Index
< DescriptorCount
; Index
++) {
1116 Print(L
" ImageDescriptor (%d)\n", Index
);
1117 Print(L
" ImageIndex - 0x%x\n", CurrentImageInfo
->ImageIndex
);
1118 Print(L
" ImageTypeId - %g\n", &CurrentImageInfo
->ImageTypeId
);
1119 Print(L
" ImageId - 0x%lx\n", CurrentImageInfo
->ImageId
);
1120 Print(L
" ImageIdName - \"%s\"\n", CurrentImageInfo
->ImageIdName
);
1121 Print(L
" Version - 0x%x\n", CurrentImageInfo
->Version
);
1122 Print(L
" VersionName - \"%s\"\n", CurrentImageInfo
->VersionName
);
1123 Print(L
" Size - 0x%x\n", CurrentImageInfo
->Size
);
1124 Print(L
" AttributesSupported - 0x%lx\n", CurrentImageInfo
->AttributesSupported
);
1125 Print(L
" IMAGE_UPDATABLE - 0x%lx\n", CurrentImageInfo
->AttributesSupported
& IMAGE_ATTRIBUTE_IMAGE_UPDATABLE
);
1126 Print(L
" RESET_REQUIRED - 0x%lx\n", CurrentImageInfo
->AttributesSupported
& IMAGE_ATTRIBUTE_RESET_REQUIRED
);
1127 Print(L
" AUTHENTICATION_REQUIRED - 0x%lx\n", CurrentImageInfo
->AttributesSupported
& IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED
);
1128 Print(L
" IN_USE - 0x%lx\n", CurrentImageInfo
->AttributesSupported
& IMAGE_ATTRIBUTE_IN_USE
);
1129 Print(L
" UEFI_IMAGE - 0x%lx\n", CurrentImageInfo
->AttributesSupported
& IMAGE_ATTRIBUTE_UEFI_IMAGE
);
1130 Print(L
" AttributesSetting - 0x%lx\n", CurrentImageInfo
->AttributesSetting
);
1131 Print(L
" IMAGE_UPDATABLE - 0x%lx\n", CurrentImageInfo
->AttributesSetting
& IMAGE_ATTRIBUTE_IMAGE_UPDATABLE
);
1132 Print(L
" RESET_REQUIRED - 0x%lx\n", CurrentImageInfo
->AttributesSetting
& IMAGE_ATTRIBUTE_RESET_REQUIRED
);
1133 Print(L
" AUTHENTICATION_REQUIRED - 0x%lx\n", CurrentImageInfo
->AttributesSetting
& IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED
);
1134 Print(L
" IN_USE - 0x%lx\n", CurrentImageInfo
->AttributesSetting
& IMAGE_ATTRIBUTE_IN_USE
);
1135 Print(L
" UEFI_IMAGE - 0x%lx\n", CurrentImageInfo
->AttributesSetting
& IMAGE_ATTRIBUTE_UEFI_IMAGE
);
1136 Print(L
" Compatibilities - 0x%lx\n", CurrentImageInfo
->Compatibilities
);
1137 Print(L
" COMPATIB_CHECK_SUPPORTED - 0x%lx\n", CurrentImageInfo
->Compatibilities
& IMAGE_COMPATIBILITY_CHECK_SUPPORTED
);
1138 if (DescriptorVersion
> 1) {
1139 Print(L
" LowestSupportedImageVersion - 0x%x\n", CurrentImageInfo
->LowestSupportedImageVersion
);
1140 if (DescriptorVersion
> 2) {
1141 Print(L
" LastAttemptVersion - 0x%x\n", CurrentImageInfo
->LastAttemptVersion
);
1142 Print(L
" LastAttemptStatus - 0x%x (%a)\n", CurrentImageInfo
->LastAttemptStatus
, LastAttemptStatusToString(CurrentImageInfo
->LastAttemptStatus
));
1143 Print(L
" HardwareInstance - 0x%lx\n", CurrentImageInfo
->HardwareInstance
);
1147 // Use DescriptorSize to move ImageInfo Pointer to stay compatible with different ImageInfo version
1149 CurrentImageInfo
= (EFI_FIRMWARE_IMAGE_DESCRIPTOR
*)((UINT8
*)CurrentImageInfo
+ DescriptorSize
);
1154 Dump FMP package information.
1156 @param[in] PackageVersion The version of package.
1157 @param[in] PackageVersionName The version name of package.
1158 @param[in] PackageVersionNameMaxLen The maximum length of PackageVersionName.
1159 @param[in] AttributesSupported Package attributes that are supported by this device.
1160 @param[in] AttributesSetting Package attributes.
1163 DumpFmpPackageInfo (
1164 IN UINT32 PackageVersion
,
1165 IN CHAR16
*PackageVersionName
,
1166 IN UINT32 PackageVersionNameMaxLen
,
1167 IN UINT64 AttributesSupported
,
1168 IN UINT64 AttributesSetting
1171 Print(L
" PackageVersion - 0x%x\n", PackageVersion
);
1172 Print(L
" PackageVersionName - \"%s\"\n", PackageVersionName
);
1173 Print(L
" PackageVersionNameMaxLen - 0x%x\n", PackageVersionNameMaxLen
);
1174 Print(L
" AttributesSupported - 0x%lx\n", AttributesSupported
);
1175 Print(L
" IMAGE_UPDATABLE - 0x%lx\n", AttributesSupported
& IMAGE_ATTRIBUTE_IMAGE_UPDATABLE
);
1176 Print(L
" RESET_REQUIRED - 0x%lx\n", AttributesSupported
& IMAGE_ATTRIBUTE_RESET_REQUIRED
);
1177 Print(L
" AUTHENTICATION_REQUIRED - 0x%lx\n", AttributesSupported
& IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED
);
1178 Print(L
" AttributesSetting - 0x%lx\n", AttributesSetting
);
1179 Print(L
" IMAGE_UPDATABLE - 0x%lx\n", AttributesSetting
& IMAGE_ATTRIBUTE_IMAGE_UPDATABLE
);
1180 Print(L
" RESET_REQUIRED - 0x%lx\n", AttributesSetting
& IMAGE_ATTRIBUTE_RESET_REQUIRED
);
1181 Print(L
" AUTHENTICATION_REQUIRED - 0x%lx\n", AttributesSetting
& IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED
);
1185 Dump FMP protocol info.
1193 EFI_FIRMWARE_MANAGEMENT_PROTOCOL
*Fmp
;
1194 EFI_HANDLE
*HandleBuffer
;
1195 UINTN NumberOfHandles
;
1197 EFI_FIRMWARE_IMAGE_DESCRIPTOR
*FmpImageInfoBuf
;
1198 UINTN ImageInfoSize
;
1199 UINT32 FmpImageInfoDescriptorVer
;
1200 UINT8 FmpImageInfoCount
;
1201 UINTN DescriptorSize
;
1202 UINT32 PackageVersion
;
1203 CHAR16
*PackageVersionName
;
1204 UINT32 PackageVersionNameMaxLen
;
1205 UINT64 AttributesSupported
;
1206 UINT64 AttributesSetting
;
1208 Print(L
"############\n");
1209 Print(L
"# FMP DATA #\n");
1210 Print(L
"############\n");
1211 Status
= gBS
->LocateHandleBuffer (
1213 &gEfiFirmwareManagementProtocolGuid
,
1218 if (EFI_ERROR(Status
)) {
1219 Print(L
"FMP protocol - %r\n", EFI_NOT_FOUND
);
1223 for (Index
= 0; Index
< NumberOfHandles
; Index
++) {
1224 Status
= gBS
->HandleProtocol(
1225 HandleBuffer
[Index
],
1226 &gEfiFirmwareManagementProtocolGuid
,
1229 if (EFI_ERROR(Status
)) {
1234 Status
= Fmp
->GetImageInfo (
1244 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1248 FmpImageInfoBuf
= NULL
;
1249 FmpImageInfoBuf
= AllocateZeroPool (ImageInfoSize
);
1250 if (FmpImageInfoBuf
== NULL
) {
1251 Status
= EFI_OUT_OF_RESOURCES
;
1255 PackageVersionName
= NULL
;
1256 Status
= Fmp
->GetImageInfo (
1258 &ImageInfoSize
, // ImageInfoSize
1259 FmpImageInfoBuf
, // ImageInfo
1260 &FmpImageInfoDescriptorVer
, // DescriptorVersion
1261 &FmpImageInfoCount
, // DescriptorCount
1262 &DescriptorSize
, // DescriptorSize
1263 &PackageVersion
, // PackageVersion
1264 &PackageVersionName
// PackageVersionName
1268 // If FMP GetInformation interface failed, skip this resource
1270 if (EFI_ERROR(Status
)) {
1271 Print(L
"FMP (%d) ImageInfo - %r\n", Index
, Status
);
1272 FreePool(FmpImageInfoBuf
);
1276 Print(L
"FMP (%d) ImageInfo:\n", Index
);
1278 ImageInfoSize
, // ImageInfoSize
1279 FmpImageInfoBuf
, // ImageInfo
1280 FmpImageInfoDescriptorVer
, // DescriptorVersion
1281 FmpImageInfoCount
, // DescriptorCount
1282 DescriptorSize
, // DescriptorSize
1283 PackageVersion
, // PackageVersion
1284 PackageVersionName
// PackageVersionName
1287 if (PackageVersionName
!= NULL
) {
1288 FreePool(PackageVersionName
);
1290 FreePool(FmpImageInfoBuf
);
1295 PackageVersionName
= NULL
;
1296 Status
= Fmp
->GetPackageInfo (
1298 &PackageVersion
, // PackageVersion
1299 &PackageVersionName
, // PackageVersionName
1300 &PackageVersionNameMaxLen
, // PackageVersionNameMaxLen
1301 &AttributesSupported
, // AttributesSupported
1302 &AttributesSetting
// AttributesSetting
1304 if (EFI_ERROR(Status
)) {
1305 Print(L
"FMP (%d) PackageInfo - %r\n", Index
, Status
);
1307 Print(L
"FMP (%d) ImageInfo:\n", Index
);
1309 PackageVersion
, // PackageVersion
1310 PackageVersionName
, // PackageVersionName
1311 PackageVersionNameMaxLen
, // PackageVersionNameMaxLen
1312 AttributesSupported
, // AttributesSupported
1313 AttributesSetting
// AttributesSetting
1316 if (PackageVersionName
!= NULL
) {
1317 FreePool(PackageVersionName
);
1324 FreePool(HandleBuffer
);
1328 Check if the ImageInfo includes the ImageTypeId.
1330 @param[in] ImageInfo A pointer to EFI_FIRMWARE_IMAGE_DESCRIPTOR.
1331 @param[in] DescriptorCount The count of EFI_FIRMWARE_IMAGE_DESCRIPTOR.
1332 @param[in] DescriptorSize The size of an individual EFI_FIRMWARE_IMAGE_DESCRIPTOR, in bytes.
1333 @param[in] ImageTypeId A unique GUID identifying the firmware image type.
1335 @return TRUE This ImageInfo includes the ImageTypeId
1336 @return FALSE This ImageInfo does not include the ImageTypeId
1339 IsThisFmpImageInfo (
1340 IN EFI_FIRMWARE_IMAGE_DESCRIPTOR
*ImageInfo
,
1341 IN UINT8 DescriptorCount
,
1342 IN UINTN DescriptorSize
,
1343 IN EFI_GUID
*ImageTypeId
1346 EFI_FIRMWARE_IMAGE_DESCRIPTOR
*CurrentImageInfo
;
1349 CurrentImageInfo
= ImageInfo
;
1350 for (Index
= 0; Index
< DescriptorCount
; Index
++) {
1351 if (CompareGuid (&CurrentImageInfo
->ImageTypeId
, ImageTypeId
)) {
1354 CurrentImageInfo
= (EFI_FIRMWARE_IMAGE_DESCRIPTOR
*)((UINT8
*)CurrentImageInfo
+ DescriptorSize
);
1360 return the FMP whoes ImageInfo includes the ImageTypeId.
1362 @param[in] ImageTypeId A unique GUID identifying the firmware image type.
1364 @return The FMP whoes ImageInfo includes the ImageTypeId
1366 EFI_FIRMWARE_MANAGEMENT_PROTOCOL
*
1367 FindFmpFromImageTypeId (
1368 IN EFI_GUID
*ImageTypeId
1372 EFI_FIRMWARE_MANAGEMENT_PROTOCOL
*Fmp
;
1373 EFI_FIRMWARE_MANAGEMENT_PROTOCOL
*TargetFmp
;
1374 EFI_HANDLE
*HandleBuffer
;
1375 UINTN NumberOfHandles
;
1377 EFI_FIRMWARE_IMAGE_DESCRIPTOR
*FmpImageInfoBuf
;
1378 UINTN ImageInfoSize
;
1379 UINT32 FmpImageInfoDescriptorVer
;
1380 UINT8 FmpImageInfoCount
;
1381 UINTN DescriptorSize
;
1382 UINT32 PackageVersion
;
1383 CHAR16
*PackageVersionName
;
1385 Status
= gBS
->LocateHandleBuffer (
1387 &gEfiFirmwareManagementProtocolGuid
,
1392 if (EFI_ERROR(Status
)) {
1393 Print(L
"FMP protocol - %r\n", EFI_NOT_FOUND
);
1398 for (Index
= 0; Index
< NumberOfHandles
; Index
++) {
1399 Status
= gBS
->HandleProtocol(
1400 HandleBuffer
[Index
],
1401 &gEfiFirmwareManagementProtocolGuid
,
1404 if (EFI_ERROR(Status
)) {
1409 Status
= Fmp
->GetImageInfo (
1419 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1423 FmpImageInfoBuf
= NULL
;
1424 FmpImageInfoBuf
= AllocateZeroPool (ImageInfoSize
);
1425 if (FmpImageInfoBuf
== NULL
) {
1426 FreePool(HandleBuffer
);
1427 Print(L
"Out of resource\n");
1431 PackageVersionName
= NULL
;
1432 Status
= Fmp
->GetImageInfo (
1434 &ImageInfoSize
, // ImageInfoSize
1435 FmpImageInfoBuf
, // ImageInfo
1436 &FmpImageInfoDescriptorVer
, // DescriptorVersion
1437 &FmpImageInfoCount
, // DescriptorCount
1438 &DescriptorSize
, // DescriptorSize
1439 &PackageVersion
, // PackageVersion
1440 &PackageVersionName
// PackageVersionName
1444 // If FMP GetInformation interface failed, skip this resource
1446 if (EFI_ERROR(Status
)) {
1447 FreePool(FmpImageInfoBuf
);
1451 if (PackageVersionName
!= NULL
) {
1452 FreePool(PackageVersionName
);
1455 if (IsThisFmpImageInfo (FmpImageInfoBuf
, FmpImageInfoCount
, DescriptorSize
, ImageTypeId
)) {
1458 FreePool(FmpImageInfoBuf
);
1459 if (TargetFmp
!= NULL
) {
1463 FreePool(HandleBuffer
);
1468 Dump FMP image data.
1470 @param[in] ImageTypeId The ImageTypeId of the FMP image.
1471 It is used to identify the FMP protocol.
1472 @param[in] ImageIndex The ImageIndex of the FMP image.
1473 It is the input parameter for FMP->GetImage().
1474 @param[in] ImageName The file name to hold the output FMP image.
1478 IN EFI_GUID
*ImageTypeId
,
1479 IN UINTN ImageIndex
,
1480 IN CHAR16
*ImageName
1484 EFI_FIRMWARE_MANAGEMENT_PROTOCOL
*Fmp
;
1488 Fmp
= FindFmpFromImageTypeId (ImageTypeId
);
1490 Print(L
"No FMP include ImageTypeId %g\n", ImageTypeId
);
1494 if (ImageIndex
> 0xFF) {
1495 Print(L
"ImageIndex 0x%x too big\n", ImageIndex
);
1501 Status
= Fmp
->GetImage (Fmp
, (UINT8
)ImageIndex
, Image
, &ImageSize
);
1502 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1503 Print(L
"Fmp->GetImage - %r\n", Status
);
1507 Image
= AllocatePool (ImageSize
);
1508 if (Image
== NULL
) {
1509 Print(L
"Allocate FmpImage 0x%x - %r\n", ImageSize
, EFI_OUT_OF_RESOURCES
);
1513 Status
= Fmp
->GetImage (Fmp
, (UINT8
)ImageIndex
, Image
, &ImageSize
);
1514 if (EFI_ERROR(Status
)) {
1515 Print(L
"Fmp->GetImage - %r\n", Status
);
1519 Status
= WriteFileFromBuffer(ImageName
, ImageSize
, Image
);
1520 Print(L
"CapsuleApp: Dump %g ImageIndex (0x%x) to %s %r\n", ImageTypeId
, ImageIndex
, ImageName
, Status
);