TianoCore EDK2 master
Loading...
Searching...
No Matches
FwVolRead.c
Go to the documentation of this file.
1
9#include "DxeMain.h"
10#include "FwVolDriver.h"
11
32UINT8 mFvAttributes[] = { 0, 4, 7, 9, 10, 12, 15, 16 };
33UINT8 mFvAttributes2[] = { 17, 18, 19, 20, 21, 22, 23, 24 };
34
45 IN EFI_FFS_FILE_ATTRIBUTES FfsAttributes
46 )
47{
48 UINT8 DataAlignment;
49 EFI_FV_FILE_ATTRIBUTES FileAttribute;
50
51 DataAlignment = (UINT8)((FfsAttributes & FFS_ATTRIB_DATA_ALIGNMENT) >> 3);
52 ASSERT (DataAlignment < 8);
53
54 if ((FfsAttributes & FFS_ATTRIB_DATA_ALIGNMENT_2) != 0) {
55 FileAttribute = (EFI_FV_FILE_ATTRIBUTES)mFvAttributes2[DataAlignment];
56 } else {
57 FileAttribute = (EFI_FV_FILE_ATTRIBUTES)mFvAttributes[DataAlignment];
58 }
59
60 if ((FfsAttributes & FFS_ATTRIB_FIXED) == FFS_ATTRIB_FIXED) {
61 FileAttribute |= EFI_FV_FILE_ATTRIB_FIXED;
62 }
63
64 return FileAttribute;
65}
66
114EFIAPI
117 IN OUT VOID *Key,
118 IN OUT EFI_FV_FILETYPE *FileType,
119 OUT EFI_GUID *NameGuid,
120 OUT EFI_FV_FILE_ATTRIBUTES *Attributes,
121 OUT UINTN *Size
122 )
123{
124 EFI_STATUS Status;
125 FV_DEVICE *FvDevice;
126 EFI_FV_ATTRIBUTES FvAttributes;
127 EFI_FFS_FILE_HEADER *FfsFileHeader;
128 UINTN *KeyValue;
129 LIST_ENTRY *Link;
130 FFS_FILE_LIST_ENTRY *FfsFileEntry;
131
132 FvDevice = FV_DEVICE_FROM_THIS (This);
133
134 Status = FvGetVolumeAttributes (This, &FvAttributes);
135 if (EFI_ERROR (Status)) {
136 return Status;
137 }
138
139 //
140 // Check if read operation is enabled
141 //
142 if ((FvAttributes & EFI_FV2_READ_STATUS) == 0) {
143 return EFI_ACCESS_DENIED;
144 }
145
146 if (*FileType > EFI_FV_FILETYPE_MM_CORE_STANDALONE) {
147 //
148 // File type needs to be in 0 - 0x0F
149 //
150 return EFI_NOT_FOUND;
151 }
152
153 KeyValue = (UINTN *)Key;
154 for ( ; ;) {
155 if (*KeyValue == 0) {
156 //
157 // Search for 1st matching file
158 //
159 Link = &FvDevice->FfsFileListHeader;
160 } else {
161 //
162 // Key is pointer to FFsFileEntry, so get next one
163 //
164 Link = (LIST_ENTRY *)(*KeyValue);
165 }
166
167 if (Link->ForwardLink == &FvDevice->FfsFileListHeader) {
168 //
169 // Next is end of list so we did not find data
170 //
171 return EFI_NOT_FOUND;
172 }
173
174 FfsFileEntry = (FFS_FILE_LIST_ENTRY *)Link->ForwardLink;
175 FfsFileHeader = (EFI_FFS_FILE_HEADER *)FfsFileEntry->FfsHeader;
176
177 //
178 // remember the key
179 //
180 *KeyValue = (UINTN)FfsFileEntry;
181
182 if (FfsFileHeader->Type == EFI_FV_FILETYPE_FFS_PAD) {
183 //
184 // we ignore pad files
185 //
186 continue;
187 }
188
189 if (*FileType == EFI_FV_FILETYPE_ALL) {
190 //
191 // Process all file types so we have a match
192 //
193 break;
194 }
195
196 if (*FileType == FfsFileHeader->Type) {
197 //
198 // Found a matching file type
199 //
200 break;
201 }
202 }
203
204 //
205 // Return FileType, NameGuid, and Attributes
206 //
207 *FileType = FfsFileHeader->Type;
208 CopyGuid (NameGuid, &FfsFileHeader->Name);
209 *Attributes = FfsAttributes2FvFileAttributes (FfsFileHeader->Attributes);
210 if ((FvDevice->FwVolHeader->Attributes & EFI_FVB2_MEMORY_MAPPED) == EFI_FVB2_MEMORY_MAPPED) {
211 *Attributes |= EFI_FV_FILE_ATTRIB_MEMORY_MAPPED;
212 }
213
214 //
215 // we need to substract the header size
216 //
217 if (IS_FFS_FILE2 (FfsFileHeader)) {
218 *Size = FFS_FILE2_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER2);
219 } else {
220 *Size = FFS_FILE_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER);
221 }
222
223 return EFI_SUCCESS;
224}
225
267EFIAPI
270 IN CONST EFI_GUID *NameGuid,
271 IN OUT VOID **Buffer,
272 IN OUT UINTN *BufferSize,
273 OUT EFI_FV_FILETYPE *FoundType,
274 OUT EFI_FV_FILE_ATTRIBUTES *FileAttributes,
275 OUT UINT32 *AuthenticationStatus
276 )
277{
278 EFI_STATUS Status;
279 FV_DEVICE *FvDevice;
280 EFI_GUID SearchNameGuid;
281 EFI_FV_FILETYPE LocalFoundType;
282 EFI_FV_FILE_ATTRIBUTES LocalAttributes;
283 UINTN FileSize;
284 UINT8 *SrcPtr;
285 EFI_FFS_FILE_HEADER *FfsHeader;
286 UINTN InputBufferSize;
287 UINTN WholeFileSize;
288
289 if (NameGuid == NULL) {
290 return EFI_INVALID_PARAMETER;
291 }
292
293 FvDevice = FV_DEVICE_FROM_THIS (This);
294
295 //
296 // Keep looking until we find the matching NameGuid.
297 // The Key is really a FfsFileEntry
298 //
299 FvDevice->LastKey = 0;
300 do {
301 LocalFoundType = 0;
302 Status = FvGetNextFile (
303 This,
304 &FvDevice->LastKey,
305 &LocalFoundType,
306 &SearchNameGuid,
307 &LocalAttributes,
308 &FileSize
309 );
310 if (EFI_ERROR (Status)) {
311 return EFI_NOT_FOUND;
312 }
313 } while (!CompareGuid (&SearchNameGuid, NameGuid));
314
315 //
316 // Get a pointer to the header
317 //
318 FfsHeader = FvDevice->LastKey->FfsHeader;
319 if (FvDevice->IsMemoryMapped) {
320 //
321 // Memory mapped FV has not been cached, so here is to cache by file.
322 //
323 if (!FvDevice->LastKey->FileCached) {
324 //
325 // Cache FFS file to memory buffer.
326 //
327 WholeFileSize = IS_FFS_FILE2 (FfsHeader) ? FFS_FILE2_SIZE (FfsHeader) : FFS_FILE_SIZE (FfsHeader);
328 FfsHeader = AllocateCopyPool (WholeFileSize, FfsHeader);
329 if (FfsHeader == NULL) {
330 return EFI_OUT_OF_RESOURCES;
331 }
332
333 //
334 // Let FfsHeader in FfsFileEntry point to the cached file buffer.
335 //
336 FvDevice->LastKey->FfsHeader = FfsHeader;
337 FvDevice->LastKey->FileCached = TRUE;
338 }
339 }
340
341 //
342 // Remember callers buffer size
343 //
344 InputBufferSize = *BufferSize;
345
346 //
347 // Calculate return values
348 //
349 *FoundType = FfsHeader->Type;
350 *FileAttributes = FfsAttributes2FvFileAttributes (FfsHeader->Attributes);
351 if ((FvDevice->FwVolHeader->Attributes & EFI_FVB2_MEMORY_MAPPED) == EFI_FVB2_MEMORY_MAPPED) {
352 *FileAttributes |= EFI_FV_FILE_ATTRIB_MEMORY_MAPPED;
353 }
354
355 //
356 // Inherit the authentication status.
357 //
358 *AuthenticationStatus = FvDevice->AuthenticationStatus;
359 *BufferSize = FileSize;
360
361 if (Buffer == NULL) {
362 //
363 // If Buffer is NULL, we only want to get the information collected so far
364 //
365 return EFI_SUCCESS;
366 }
367
368 //
369 // Skip over file header
370 //
371 if (IS_FFS_FILE2 (FfsHeader)) {
372 SrcPtr = ((UINT8 *)FfsHeader) + sizeof (EFI_FFS_FILE_HEADER2);
373 } else {
374 SrcPtr = ((UINT8 *)FfsHeader) + sizeof (EFI_FFS_FILE_HEADER);
375 }
376
377 Status = EFI_SUCCESS;
378 if (*Buffer == NULL) {
379 //
380 // Caller passed in a pointer so allocate buffer for them
381 //
382 *Buffer = AllocatePool (FileSize);
383 if (*Buffer == NULL) {
384 return EFI_OUT_OF_RESOURCES;
385 }
386 } else if (FileSize > InputBufferSize) {
387 //
388 // Callers buffer was not big enough
389 //
390 Status = EFI_WARN_BUFFER_TOO_SMALL;
391 FileSize = InputBufferSize;
392 }
393
394 //
395 // Copy data into callers buffer
396 //
397 CopyMem (*Buffer, SrcPtr, FileSize);
398
399 return Status;
400}
401
431EFIAPI
434 IN CONST EFI_GUID *NameGuid,
435 IN EFI_SECTION_TYPE SectionType,
436 IN UINTN SectionInstance,
437 IN OUT VOID **Buffer,
438 IN OUT UINTN *BufferSize,
439 OUT UINT32 *AuthenticationStatus
440 )
441{
442 EFI_STATUS Status;
443 FV_DEVICE *FvDevice;
444 EFI_FV_FILETYPE FileType;
445 EFI_FV_FILE_ATTRIBUTES FileAttributes;
446 UINTN FileSize;
447 UINT8 *FileBuffer;
448 FFS_FILE_LIST_ENTRY *FfsEntry;
449
450 if ((NameGuid == NULL) || (Buffer == NULL)) {
451 return EFI_INVALID_PARAMETER;
452 }
453
454 FvDevice = FV_DEVICE_FROM_THIS (This);
455
456 //
457 // Read the file
458 //
459 Status = FvReadFile (
460 This,
461 NameGuid,
462 NULL,
463 &FileSize,
464 &FileType,
465 &FileAttributes,
466 AuthenticationStatus
467 );
468 //
469 // Get the last key used by our call to FvReadFile as it is the FfsEntry for this file.
470 //
471 FfsEntry = (FFS_FILE_LIST_ENTRY *)FvDevice->LastKey;
472
473 if (EFI_ERROR (Status)) {
474 return Status;
475 }
476
477 if (IS_FFS_FILE2 (FfsEntry->FfsHeader)) {
478 FileBuffer = ((UINT8 *)FfsEntry->FfsHeader) + sizeof (EFI_FFS_FILE_HEADER2);
479 } else {
480 FileBuffer = ((UINT8 *)FfsEntry->FfsHeader) + sizeof (EFI_FFS_FILE_HEADER);
481 }
482
483 //
484 // Check to see that the file actually HAS sections before we go any further.
485 //
486 if (FileType == EFI_FV_FILETYPE_RAW) {
487 Status = EFI_NOT_FOUND;
488 goto Done;
489 }
490
491 //
492 // Use FfsEntry to cache Section Extraction Protocol Information
493 //
494 if (FfsEntry->StreamHandle == 0) {
495 Status = OpenSectionStream (
496 FileSize,
497 FileBuffer,
498 &FfsEntry->StreamHandle
499 );
500 if (EFI_ERROR (Status)) {
501 goto Done;
502 }
503 }
504
505 //
506 // If SectionType == 0 We need the whole section stream
507 //
508 Status = GetSection (
509 FfsEntry->StreamHandle,
510 (SectionType == 0) ? NULL : &SectionType,
511 NULL,
512 (SectionType == 0) ? 0 : SectionInstance,
513 Buffer,
514 BufferSize,
515 AuthenticationStatus,
516 FvDevice->IsFfs3Fv
517 );
518
519 if (!EFI_ERROR (Status)) {
520 //
521 // Inherit the authentication status.
522 //
523 *AuthenticationStatus |= FvDevice->AuthenticationStatus;
524 }
525
526 //
527 // Close of stream defered to close of FfsHeader list to allow SEP to cache data
528 //
529
530Done:
531 return Status;
532}
UINT64 UINTN
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
Definition: MemLibGuid.c:39
EFI_STATUS EFIAPI GetSection(IN UINTN SectionStreamHandle, IN EFI_SECTION_TYPE *SectionType, IN EFI_GUID *SectionDefinitionGuid, IN UINTN SectionInstance, IN VOID **Buffer, IN OUT UINTN *BufferSize, OUT UINT32 *AuthenticationStatus, IN BOOLEAN IsFfs3Fv)
EFI_STATUS EFIAPI OpenSectionStream(IN UINTN SectionStreamLength, IN VOID *SectionStream, OUT UINTN *SectionStreamHandle)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
UINT64 EFI_FV_ATTRIBUTES
EFI_STATUS EFIAPI FvGetVolumeAttributes(IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, OUT EFI_FV_ATTRIBUTES *Attributes)
Definition: FwVolAttrib.c:24
EFI_STATUS EFIAPI FvReadFile(IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, IN CONST EFI_GUID *NameGuid, IN OUT VOID **Buffer, IN OUT UINTN *BufferSize, OUT EFI_FV_FILETYPE *FoundType, OUT EFI_FV_FILE_ATTRIBUTES *FileAttributes, OUT UINT32 *AuthenticationStatus)
Definition: FwVolRead.c:268
UINT8 mFvAttributes[]
Definition: FwVolRead.c:32
EFI_FV_FILE_ATTRIBUTES FfsAttributes2FvFileAttributes(IN EFI_FFS_FILE_ATTRIBUTES FfsAttributes)
Definition: FwVolRead.c:44
EFI_STATUS EFIAPI FvGetNextFile(IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, IN OUT VOID *Key, IN OUT EFI_FV_FILETYPE *FileType, OUT EFI_GUID *NameGuid, OUT EFI_FV_FILE_ATTRIBUTES *Attributes, OUT UINTN *Size)
Definition: FwVolRead.c:115
EFI_STATUS EFIAPI FvReadFileSection(IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, IN CONST EFI_GUID *NameGuid, IN EFI_SECTION_TYPE SectionType, IN UINTN SectionInstance, IN OUT VOID **Buffer, IN OUT UINTN *BufferSize, OUT UINT32 *AuthenticationStatus)
Definition: FwVolRead.c:432
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define EFI_FV_FILETYPE_ALL
#define FFS_FILE_SIZE(FfsFileHeaderPtr)
UINT32 EFI_FV_FILE_ATTRIBUTES
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_FV_FILETYPE Type
EFI_FFS_FILE_ATTRIBUTES Attributes
EFI_FVB_ATTRIBUTES_2 Attributes
Definition: Base.h:213