TianoCore EDK2 master
Loading...
Searching...
No Matches
FmpDependencyCheckLib.c
Go to the documentation of this file.
1
11#include <PiDxe.h>
12#include <Library/BaseLib.h>
14#include <Library/DebugLib.h>
18#include <Library/UefiLib.h>
21#include <LastAttemptStatus.h>
23
40BOOLEAN
41EFIAPI
43 IN EFI_GUID ImageTypeId,
44 IN UINT32 Version,
45 IN EFI_FIRMWARE_IMAGE_DEP *Dependencies OPTIONAL,
46 IN UINT32 DependenciesSize,
47 OUT UINT32 *LastAttemptStatus OPTIONAL
48 )
49{
50 EFI_STATUS Status;
51 EFI_HANDLE *HandleBuffer;
52 UINTN Index;
54 UINTN ImageInfoSize;
55 UINT32 LocalLastAttemptStatus;
56 UINT32 *DescriptorVer;
57 UINT8 FmpImageInfoCount;
58 UINTN *DescriptorSize;
59 UINT32 PackageVersion;
60 CHAR16 *PackageVersionName;
61 UINTN NumberOfFmpInstance;
62 EFI_FIRMWARE_IMAGE_DESCRIPTOR **FmpImageInfoBuf;
64 UINTN FmpVersionsCount;
65 BOOLEAN IsSatisfied;
66
67 LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;
68 FmpImageInfoBuf = NULL;
69 DescriptorVer = NULL;
70 DescriptorSize = NULL;
71 NumberOfFmpInstance = 0;
72 FmpVersions = NULL;
73 FmpVersionsCount = 0;
74 IsSatisfied = TRUE;
75 PackageVersionName = NULL;
76
77 //
78 // Get ImageDescriptors of all FMP instances, and archive them for dependency evaluation.
79 //
80 Status = gBS->LocateHandleBuffer (
82 &gEfiFirmwareManagementProtocolGuid,
83 NULL,
84 &NumberOfFmpInstance,
85 &HandleBuffer
86 );
87 if (EFI_ERROR (Status)) {
88 DEBUG ((DEBUG_ERROR, "CheckFmpDependency: Get Firmware Management Protocol failed. (%r)", Status));
89 IsSatisfied = FALSE;
91 goto cleanup;
92 }
93
94 FmpImageInfoBuf = AllocateZeroPool (sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR *) * NumberOfFmpInstance);
95 if (FmpImageInfoBuf == NULL) {
96 IsSatisfied = FALSE;
97 LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_MEM_ALLOC_FMP_INFO_BUFFER_FAILED;
98 goto cleanup;
99 }
100
101 DescriptorVer = AllocateZeroPool (sizeof (UINT32) * NumberOfFmpInstance);
102 if (DescriptorVer == NULL ) {
103 IsSatisfied = FALSE;
104 LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_MEM_ALLOC_DESC_VER_BUFFER_FAILED;
105 goto cleanup;
106 }
107
108 DescriptorSize = AllocateZeroPool (sizeof (UINTN) * NumberOfFmpInstance);
109 if (DescriptorSize == NULL ) {
110 IsSatisfied = FALSE;
111 LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_MEM_ALLOC_DESC_SIZE_BUFFER_FAILED;
112 goto cleanup;
113 }
114
115 FmpVersions = AllocateZeroPool (sizeof (FMP_DEPEX_CHECK_VERSION_DATA) * NumberOfFmpInstance);
116 if (FmpVersions == NULL) {
117 IsSatisfied = FALSE;
118 LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_MEM_ALLOC_FMP_VER_BUFFER_FAILED;
119 goto cleanup;
120 }
121
122 for (Index = 0; Index < NumberOfFmpInstance; Index++) {
123 Status = gBS->HandleProtocol (
124 HandleBuffer[Index],
125 &gEfiFirmwareManagementProtocolGuid,
126 (VOID **)&Fmp
127 );
128 if (EFI_ERROR (Status)) {
129 continue;
130 }
131
132 ImageInfoSize = 0;
133 Status = Fmp->GetImageInfo (
134 Fmp,
135 &ImageInfoSize,
136 NULL,
137 NULL,
138 NULL,
139 NULL,
140 NULL,
141 NULL
142 );
143 if (Status != EFI_BUFFER_TOO_SMALL) {
144 continue;
145 }
146
147 FmpImageInfoBuf[Index] = AllocateZeroPool (ImageInfoSize);
148 if (FmpImageInfoBuf[Index] == NULL) {
149 continue;
150 }
151
152 Status = Fmp->GetImageInfo (
153 Fmp,
154 &ImageInfoSize, // ImageInfoSize
155 FmpImageInfoBuf[Index], // ImageInfo
156 &DescriptorVer[Index], // DescriptorVersion
157 &FmpImageInfoCount, // DescriptorCount
158 &DescriptorSize[Index], // DescriptorSize
159 &PackageVersion, // PackageVersion
160 &PackageVersionName // PackageVersionName
161 );
162 if (EFI_ERROR (Status)) {
163 FreePool (FmpImageInfoBuf[Index]);
164 FmpImageInfoBuf[Index] = NULL;
165 continue;
166 }
167
168 if (PackageVersionName != NULL) {
169 FreePool (PackageVersionName);
170 PackageVersionName = NULL;
171 }
172
173 CopyGuid (&FmpVersions[FmpVersionsCount].ImageTypeId, &FmpImageInfoBuf[Index]->ImageTypeId);
174 FmpVersions[FmpVersionsCount].Version = FmpImageInfoBuf[Index]->Version;
175 FmpVersionsCount++;
176 }
177
178 //
179 // Evaluate firmware image's depex, against the version of other Fmp instances.
180 //
181 if (Dependencies != NULL) {
182 IsSatisfied = EvaluateDependency (Dependencies, DependenciesSize, FmpVersions, FmpVersionsCount, &LocalLastAttemptStatus);
183 }
184
185 if (!IsSatisfied) {
186 DEBUG ((DEBUG_ERROR, "CheckFmpDependency: %g\'s dependency is not satisfied!\n", ImageTypeId));
187 goto cleanup;
188 }
189
190cleanup:
191 if (FmpImageInfoBuf != NULL) {
192 for (Index = 0; Index < NumberOfFmpInstance; Index++) {
193 if (FmpImageInfoBuf[Index] != NULL) {
194 FreePool (FmpImageInfoBuf[Index]);
195 }
196 }
197
198 FreePool (FmpImageInfoBuf);
199 }
200
201 if (DescriptorVer != NULL) {
202 FreePool (DescriptorVer);
203 }
204
205 if (DescriptorSize != NULL) {
206 FreePool (DescriptorSize);
207 }
208
209 if (FmpVersions != NULL) {
210 FreePool (FmpVersions);
211 }
212
213 if (LastAttemptStatus != NULL) {
214 *LastAttemptStatus = LocalLastAttemptStatus;
215 }
216
217 return IsSatisfied;
218}
UINT64 UINTN
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
Definition: MemLibGuid.c:39
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
BOOLEAN EFIAPI CheckFmpDependency(IN EFI_GUID ImageTypeId, IN UINT32 Version, IN EFI_FIRMWARE_IMAGE_DEP *Dependencies OPTIONAL, IN UINT32 DependenciesSize, OUT UINT32 *LastAttemptStatus OPTIONAL)
BOOLEAN EFIAPI EvaluateDependency(IN EFI_FIRMWARE_IMAGE_DEP *Dependencies, IN UINTN DependenciesSize, IN FMP_DEPEX_CHECK_VERSION_DATA *FmpVersions OPTIONAL, IN UINTN FmpVersionsCount, OUT UINT32 *LastAttemptStatus OPTIONAL)
@ LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_FMP_PROTOCOL_NOT_FOUND
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define LAST_ATTEMPT_STATUS_SUCCESS
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
EFI_BOOT_SERVICES * gBS
@ ByProtocol
Definition: UefiSpec.h:1518
Definition: Base.h:213