/**\r
Read a file.\r
\r
- @param[in] FileName The file to be read.\r
- @param[in] BufferSize The file buffer size\r
- @param[in] Buffer The file buffer\r
+ @param[in] FileName The file to be read.\r
+ @param[out] BufferSize The file buffer size\r
+ @param[out] Buffer The file buffer\r
\r
@retval EFI_SUCCESS Read file successfully\r
@retval EFI_NOT_FOUND File not found\r
OUT VOID **Buffer\r
);\r
\r
+/**\r
+ Write a file.\r
+\r
+ @param[in] FileName The file to be written.\r
+ @param[in] BufferSize The file buffer size\r
+ @param[in] Buffer The file buffer\r
+\r
+ @retval EFI_SUCCESS Write file successfully\r
+**/\r
+EFI_STATUS\r
+WriteFileFromBuffer (\r
+ IN CHAR16 *FileName,\r
+ IN UINTN BufferSize,\r
+ IN VOID *Buffer\r
+ );\r
+\r
/**\r
Dump UX capsule information.\r
\r
UINTN CapsuleFileNameSize;\r
CHAR16 CapsuleIndexData[12];\r
CHAR16 *CapsuleIndex;\r
+ CHAR16 *CapsuleFileName;\r
+ CHAR16 *CapsuleTarget;\r
\r
Status = GetVariable2(\r
L"CapsuleMax",\r
NULL\r
);\r
if (!EFI_ERROR(Status)) {\r
+ ASSERT (CapsuleIndex != NULL);\r
CopyMem(CapsuleIndexData, CapsuleIndex, 11 * sizeof(CHAR16));\r
CapsuleIndexData[11] = 0;\r
Print(L"CapsuleMax - %s\n", CapsuleIndexData);\r
NULL\r
);\r
if (!EFI_ERROR(Status)) {\r
+ ASSERT (CapsuleIndex != NULL);\r
CopyMem(CapsuleIndexData, CapsuleIndex, 11 * sizeof(CHAR16));\r
CapsuleIndexData[11] = 0;\r
Print(L"CapsuleLast - %s\n", CapsuleIndexData);\r
}\r
\r
if (CompareGuid(&CapsuleResult->CapsuleGuid, &gEfiFmpCapsuleGuid)) {\r
- if (CapsuleResult->VariableTotalSize >= sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof(EFI_CAPSULE_RESULT_VARIABLE_FMP)) {\r
+ if (CapsuleResult->VariableTotalSize >= sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof(EFI_CAPSULE_RESULT_VARIABLE_FMP) + sizeof(CHAR16) * 2) {\r
CapsuleResultFmp = (EFI_CAPSULE_RESULT_VARIABLE_FMP *)(CapsuleResult + 1);\r
Print(L" Capsule FMP Version: 0x%x\n", CapsuleResultFmp->Version);\r
Print(L" Capsule FMP PayloadIndex: 0x%x\n", CapsuleResultFmp->PayloadIndex);\r
Print(L" Capsule FMP UpdateImageIndex: 0x%x\n", CapsuleResultFmp->UpdateImageIndex);\r
Print(L" Capsule FMP UpdateImageTypeId: %g\n", &CapsuleResultFmp->UpdateImageTypeId);\r
- if (CapsuleResult->VariableTotalSize > sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof(EFI_CAPSULE_RESULT_VARIABLE_FMP)) {\r
- Print(L" Capsule FMP CapsuleFileName: %s\n", (CapsuleResultFmp + 1));\r
- CapsuleFileNameSize = StrSize((CHAR16 *)(CapsuleResultFmp + 1));\r
- if (CapsuleResult->VariableTotalSize > sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof(EFI_CAPSULE_RESULT_VARIABLE_FMP) + CapsuleFileNameSize) {\r
- Print(L" Capsule FMP CapsuleTarget: %s\n", (UINT8 *)(CapsuleResultFmp + 1) + CapsuleFileNameSize);\r
- }\r
- }\r
+ CapsuleFileName = (CHAR16 *)(CapsuleResultFmp + 1);\r
+ Print(L" Capsule FMP CapsuleFileName: \"%s\"\n", CapsuleFileName);\r
+ CapsuleFileNameSize = StrSize(CapsuleFileName);\r
+ CapsuleTarget = (CHAR16 *)((UINTN)CapsuleFileName + CapsuleFileNameSize);\r
+ Print(L" Capsule FMP CapsuleTarget: \"%s\"\n", CapsuleTarget);\r
}\r
}\r
\r
EXIT:\r
FreePool(HandleBuffer);\r
}\r
+\r
+/**\r
+ Check if the ImageInfo includes the ImageTypeId.\r
+\r
+ @param[in] ImageInfo A pointer to EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
+ @param[in] DescriptorCount The count of EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
+ @param[in] DescriptorSize The size of an individual EFI_FIRMWARE_IMAGE_DESCRIPTOR, in bytes.\r
+ @param[in] ImageTypeId A unique GUID identifying the firmware image type.\r
+\r
+ @return TRUE This ImageInfo includes the ImageTypeId\r
+ @return FALSE This ImageInfo does not include the ImageTypeId\r
+**/\r
+BOOLEAN\r
+IsThisFmpImageInfo (\r
+ IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageInfo,\r
+ IN UINT8 DescriptorCount,\r
+ IN UINTN DescriptorSize,\r
+ IN EFI_GUID *ImageTypeId\r
+ )\r
+{\r
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR *CurrentImageInfo;\r
+ UINTN Index;\r
+\r
+ CurrentImageInfo = ImageInfo;\r
+ for (Index = 0; Index < DescriptorCount; Index++) {\r
+ if (CompareGuid (&CurrentImageInfo->ImageTypeId, ImageTypeId)) {\r
+ return TRUE;\r
+ }\r
+ CurrentImageInfo = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)((UINT8 *)CurrentImageInfo + DescriptorSize);\r
+ }\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ return the FMP whoes ImageInfo includes the ImageTypeId.\r
+\r
+ @param[in] ImageTypeId A unique GUID identifying the firmware image type.\r
+\r
+ @return The FMP whoes ImageInfo includes the ImageTypeId\r
+**/\r
+EFI_FIRMWARE_MANAGEMENT_PROTOCOL *\r
+FindFmpFromImageTypeId (\r
+ IN EFI_GUID *ImageTypeId\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;\r
+ EFI_FIRMWARE_MANAGEMENT_PROTOCOL *TargetFmp;\r
+ EFI_HANDLE *HandleBuffer;\r
+ UINTN NumberOfHandles;\r
+ UINTN Index;\r
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf;\r
+ UINTN ImageInfoSize;\r
+ UINT32 FmpImageInfoDescriptorVer;\r
+ UINT8 FmpImageInfoCount;\r
+ UINTN DescriptorSize;\r
+ UINT32 PackageVersion;\r
+ CHAR16 *PackageVersionName;\r
+\r
+ Status = gBS->LocateHandleBuffer (\r
+ ByProtocol,\r
+ &gEfiFirmwareManagementProtocolGuid,\r
+ NULL,\r
+ &NumberOfHandles,\r
+ &HandleBuffer\r
+ );\r
+ if (EFI_ERROR(Status)) {\r
+ Print(L"FMP protocol - %r\n", EFI_NOT_FOUND);\r
+ return NULL;\r
+ }\r
+\r
+ TargetFmp = NULL;\r
+ for (Index = 0; Index < NumberOfHandles; Index++) {\r
+ Status = gBS->HandleProtocol(\r
+ HandleBuffer[Index],\r
+ &gEfiFirmwareManagementProtocolGuid,\r
+ (VOID **)&Fmp\r
+ );\r
+ if (EFI_ERROR(Status)) {\r
+ continue;\r
+ }\r
+\r
+ ImageInfoSize = 0;\r
+ Status = Fmp->GetImageInfo (\r
+ Fmp,\r
+ &ImageInfoSize,\r
+ NULL,\r
+ NULL,\r
+ NULL,\r
+ NULL,\r
+ NULL,\r
+ NULL\r
+ );\r
+ if (Status != EFI_BUFFER_TOO_SMALL) {\r
+ continue;\r
+ }\r
+\r
+ FmpImageInfoBuf = NULL;\r
+ FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);\r
+ if (FmpImageInfoBuf == NULL) {\r
+ FreePool(HandleBuffer);\r
+ Print(L"Out of resource\n");\r
+ return NULL;\r
+ }\r
+\r
+ PackageVersionName = NULL;\r
+ Status = Fmp->GetImageInfo (\r
+ Fmp,\r
+ &ImageInfoSize, // ImageInfoSize\r
+ FmpImageInfoBuf, // ImageInfo\r
+ &FmpImageInfoDescriptorVer, // DescriptorVersion\r
+ &FmpImageInfoCount, // DescriptorCount\r
+ &DescriptorSize, // DescriptorSize\r
+ &PackageVersion, // PackageVersion\r
+ &PackageVersionName // PackageVersionName\r
+ );\r
+\r
+ //\r
+ // If FMP GetInformation interface failed, skip this resource\r
+ //\r
+ if (EFI_ERROR(Status)) {\r
+ FreePool(FmpImageInfoBuf);\r
+ continue;\r
+ }\r
+\r
+ if (PackageVersionName != NULL) {\r
+ FreePool(PackageVersionName);\r
+ }\r
+\r
+ if (IsThisFmpImageInfo (FmpImageInfoBuf, FmpImageInfoCount, DescriptorSize, ImageTypeId)) {\r
+ TargetFmp = Fmp;\r
+ }\r
+ FreePool(FmpImageInfoBuf);\r
+ if (TargetFmp != NULL) {\r
+ break;\r
+ }\r
+ }\r
+ FreePool(HandleBuffer);\r
+ return TargetFmp;\r
+}\r
+\r
+/**\r
+ Dump FMP image data.\r
+\r
+ @param[in] ImageTypeId The ImageTypeId of the FMP image.\r
+ It is used to identify the FMP protocol.\r
+ @param[in] ImageIndex The ImageIndex of the FMP image.\r
+ It is the input parameter for FMP->GetImage().\r
+ @param[in] ImageName The file name to hold the output FMP image.\r
+**/\r
+VOID\r
+DumpFmpImage (\r
+ IN EFI_GUID *ImageTypeId,\r
+ IN UINTN ImageIndex,\r
+ IN CHAR16 *ImageName\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;\r
+ VOID *Image;\r
+ UINTN ImageSize;\r
+\r
+ Fmp = FindFmpFromImageTypeId (ImageTypeId);\r
+ if (Fmp == NULL) {\r
+ Print(L"No FMP include ImageTypeId %g\n", ImageTypeId);\r
+ return ;\r
+ }\r
+\r
+ if (ImageIndex > 0xFF) {\r
+ Print(L"ImageIndex 0x%x too big\n", ImageIndex);\r
+ return ;\r
+ }\r
+\r
+ Image = Fmp;\r
+ ImageSize = 0;\r
+ Status = Fmp->GetImage (Fmp, (UINT8)ImageIndex, Image, &ImageSize);\r
+ if (Status != EFI_BUFFER_TOO_SMALL) {\r
+ Print(L"Fmp->GetImage - %r\n", Status);\r
+ return ;\r
+ }\r
+\r
+ Image = AllocatePool (ImageSize);\r
+ if (Image == NULL) {\r
+ Print(L"Allocate FmpImage 0x%x - %r\n", ImageSize, EFI_OUT_OF_RESOURCES);\r
+ return ;\r
+ }\r
+\r
+ Status = Fmp->GetImage (Fmp, (UINT8)ImageIndex, Image, &ImageSize);\r
+ if (EFI_ERROR(Status)) {\r
+ Print(L"Fmp->GetImage - %r\n", Status);\r
+ return ;\r
+ }\r
+\r
+ Status = WriteFileFromBuffer(ImageName, ImageSize, Image);\r
+ Print(L"CapsuleApp: Dump %g ImageIndex (0x%x) to %s %r\n", ImageTypeId, ImageIndex, ImageName, Status);\r
+\r
+ return ;\r
+}\r