]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/Common/FvLib.c
Sync BaseTool trunk (version r2610) into EDKII BaseTools.
[mirror_edk2.git] / BaseTools / Source / C / Common / FvLib.c
1 /** @file
2
3 Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 FvLib.c
15
16 Abstract:
17
18 These functions assist in parsing and manipulating a Firmware Volume.
19
20 **/
21
22 //
23 // Include files
24 //
25 #include "FvLib.h"
26 #include "CommonLib.h"
27 #include "EfiUtilityMsgs.h"
28
29 //
30 // Module global variables
31 //
32 EFI_FIRMWARE_VOLUME_HEADER *mFvHeader = NULL;
33 UINT32 mFvLength = 0;
34
35 //
36 // External function implementations
37 //
38 EFI_STATUS
39 InitializeFvLib (
40 IN VOID *Fv,
41 IN UINT32 FvLength
42 )
43 /*++
44
45 Routine Description:
46
47 This initializes the FV lib with a pointer to the FV and length. It does not
48 verify the FV in any way.
49
50 Arguments:
51
52 Fv Buffer containing the FV.
53 FvLength Length of the FV
54
55 Returns:
56
57 EFI_SUCCESS Function Completed successfully.
58 EFI_INVALID_PARAMETER A required parameter was NULL.
59
60 --*/
61 {
62 //
63 // Verify input arguments
64 //
65 if (Fv == NULL) {
66 return EFI_INVALID_PARAMETER;
67 }
68
69 mFvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) Fv;
70 mFvLength = FvLength;
71
72 return EFI_SUCCESS;
73 }
74
75 EFI_STATUS
76 GetFvHeader (
77 OUT EFI_FIRMWARE_VOLUME_HEADER **FvHeader,
78 OUT UINT32 *FvLength
79 )
80 /*++
81
82 Routine Description:
83
84 This function returns a pointer to the current FV and the size.
85
86 Arguments:
87
88 FvHeader Pointer to the FV buffer.
89 FvLength Length of the FV
90
91 Returns:
92
93 EFI_SUCCESS Function Completed successfully.
94 EFI_INVALID_PARAMETER A required parameter was NULL.
95 EFI_ABORTED The library needs to be initialized.
96
97 --*/
98 {
99 //
100 // Verify library has been initialized.
101 //
102 if (mFvHeader == NULL || mFvLength == 0) {
103 return EFI_ABORTED;
104 }
105 //
106 // Verify input arguments
107 //
108 if (FvHeader == NULL) {
109 return EFI_INVALID_PARAMETER;
110 }
111
112 *FvHeader = mFvHeader;
113 *FvLength = mFvLength;
114 return EFI_SUCCESS;
115 }
116
117 EFI_STATUS
118 GetNextFile (
119 IN EFI_FFS_FILE_HEADER *CurrentFile,
120 OUT EFI_FFS_FILE_HEADER **NextFile
121 )
122 /*++
123
124 Routine Description:
125
126 This function returns the next file. If the current file is NULL, it returns
127 the first file in the FV. If the function returns EFI_SUCCESS and the file
128 pointer is NULL, then there are no more files in the FV.
129
130 Arguments:
131
132 CurrentFile Pointer to the current file, must be within the current FV.
133 NextFile Pointer to the next file in the FV.
134
135 Returns:
136
137 EFI_SUCCESS Function completed successfully.
138 EFI_INVALID_PARAMETER A required parameter was NULL or is out of range.
139 EFI_ABORTED The library needs to be initialized.
140
141 --*/
142 {
143 EFI_STATUS Status;
144
145 //
146 // Verify library has been initialized.
147 //
148 if (mFvHeader == NULL || mFvLength == 0) {
149 return EFI_ABORTED;
150 }
151 //
152 // Verify input arguments
153 //
154 if (NextFile == NULL) {
155 return EFI_INVALID_PARAMETER;
156 }
157 //
158 // Verify FV header
159 //
160 Status = VerifyFv (mFvHeader);
161 if (EFI_ERROR (Status)) {
162 return EFI_ABORTED;
163 }
164 //
165 // Get first file
166 //
167 if (CurrentFile == NULL) {
168 CurrentFile = (EFI_FFS_FILE_HEADER *) ((UINTN) mFvHeader + mFvHeader->HeaderLength);
169
170 //
171 // Verify file is valid
172 //
173 Status = VerifyFfsFile (CurrentFile);
174 if (EFI_ERROR (Status)) {
175 //
176 // no files in this FV
177 //
178 *NextFile = NULL;
179 return EFI_SUCCESS;
180 } else {
181 //
182 // Verify file is in this FV.
183 //
184 if ((UINTN) CurrentFile + GetFfsFileLength(CurrentFile) > (UINTN) mFvHeader + mFvLength) {
185 *NextFile = NULL;
186 return EFI_SUCCESS;
187 }
188
189 *NextFile = CurrentFile;
190 return EFI_SUCCESS;
191 }
192 }
193 //
194 // Verify current file is in range
195 //
196 if (((UINTN) CurrentFile < (UINTN) mFvHeader + mFvHeader->HeaderLength) ||
197 ((UINTN) CurrentFile + GetFfsFileLength(CurrentFile) > (UINTN) mFvHeader + mFvLength)
198 ) {
199 return EFI_INVALID_PARAMETER;
200 }
201 //
202 // Get next file, compensate for 8 byte alignment if necessary.
203 //
204 *NextFile = (EFI_FFS_FILE_HEADER *) ((((UINTN) CurrentFile - (UINTN) mFvHeader + GetFfsFileLength(CurrentFile) + 0x07) & (-1 << 3)) + (UINT8 *) mFvHeader);
205
206 //
207 // Verify file is in this FV.
208 //
209 if (((UINTN) *NextFile + GetFfsHeaderLength(*NextFile) >= (UINTN) mFvHeader + mFvLength) ||
210 ((UINTN) *NextFile + GetFfsFileLength (*NextFile) > (UINTN) mFvHeader + mFvLength)
211 ) {
212 *NextFile = NULL;
213 return EFI_SUCCESS;
214 }
215 //
216 // Verify file is valid
217 //
218 Status = VerifyFfsFile (*NextFile);
219 if (EFI_ERROR (Status)) {
220 //
221 // no more files in this FV
222 //
223 *NextFile = NULL;
224 return EFI_SUCCESS;
225 }
226
227 return EFI_SUCCESS;
228 }
229
230 EFI_STATUS
231 GetFileByName (
232 IN EFI_GUID *FileName,
233 OUT EFI_FFS_FILE_HEADER **File
234 )
235 /*++
236
237 Routine Description:
238
239 Find a file by name. The function will return NULL if the file is not found.
240
241 Arguments:
242
243 FileName The GUID file name of the file to search for.
244 File Return pointer. In the case of an error, contents are undefined.
245
246 Returns:
247
248 EFI_SUCCESS The function completed successfully.
249 EFI_ABORTED An error was encountered.
250 EFI_INVALID_PARAMETER One of the parameters was NULL.
251
252 --*/
253 {
254 EFI_FFS_FILE_HEADER *CurrentFile;
255 EFI_STATUS Status;
256 CHAR8 FileGuidString[80];
257
258 //
259 // Verify library has been initialized.
260 //
261 if (mFvHeader == NULL || mFvLength == 0) {
262 return EFI_ABORTED;
263 }
264 //
265 // Verify input parameters
266 //
267 if (FileName == NULL || File == NULL) {
268 return EFI_INVALID_PARAMETER;
269 }
270 //
271 // File Guid String Name
272 //
273 PrintGuidToBuffer (FileName, (UINT8 *)FileGuidString, sizeof (FileGuidString), TRUE);
274 //
275 // Verify FV header
276 //
277 Status = VerifyFv (mFvHeader);
278 if (EFI_ERROR (Status)) {
279 return EFI_ABORTED;
280 }
281 //
282 // Get the first file
283 //
284 Status = GetNextFile (NULL, &CurrentFile);
285 if (EFI_ERROR (Status)) {
286 Error (NULL, 0, 0003, "error parsing FV image", "FFS file with Guid %s can't be found", FileGuidString);
287 return EFI_ABORTED;
288 }
289 //
290 // Loop as long as we have a valid file
291 //
292 while (CurrentFile) {
293 if (!CompareGuid (&CurrentFile->Name, FileName)) {
294 *File = CurrentFile;
295 return EFI_SUCCESS;
296 }
297
298 Status = GetNextFile (CurrentFile, &CurrentFile);
299 if (EFI_ERROR (Status)) {
300 Error (NULL, 0, 0003, "error parsing FV image", "FFS file with Guid %s can't be found", FileGuidString);
301 return EFI_ABORTED;
302 }
303 }
304 //
305 // File not found in this FV.
306 //
307 *File = NULL;
308 return EFI_SUCCESS;
309 }
310
311 EFI_STATUS
312 GetFileByType (
313 IN EFI_FV_FILETYPE FileType,
314 IN UINTN Instance,
315 OUT EFI_FFS_FILE_HEADER **File
316 )
317 /*++
318
319 Routine Description:
320
321 Find a file by type and instance. An instance of 1 is the first instance.
322 The function will return NULL if a matching file cannot be found.
323 File type EFI_FV_FILETYPE_ALL means any file type is valid.
324
325 Arguments:
326
327 FileType Type of file to search for.
328 Instance Instace of the file type to return.
329 File Return pointer. In the case of an error, contents are undefined.
330
331 Returns:
332
333 EFI_SUCCESS The function completed successfully.
334 EFI_ABORTED An error was encountered.
335 EFI_INVALID_PARAMETER One of the parameters was NULL.
336
337 --*/
338 {
339 EFI_FFS_FILE_HEADER *CurrentFile;
340 EFI_STATUS Status;
341 UINTN FileCount;
342
343 //
344 // Verify library has been initialized.
345 //
346 if (mFvHeader == NULL || mFvLength == 0) {
347 return EFI_ABORTED;
348 }
349 //
350 // Verify input parameters
351 //
352 if (File == NULL) {
353 return EFI_INVALID_PARAMETER;
354 }
355 //
356 // Verify FV header
357 //
358 Status = VerifyFv (mFvHeader);
359 if (EFI_ERROR (Status)) {
360 return EFI_ABORTED;
361 }
362 //
363 // Initialize the number of matching files found.
364 //
365 FileCount = 0;
366
367 //
368 // Get the first file
369 //
370 Status = GetNextFile (NULL, &CurrentFile);
371 if (EFI_ERROR (Status)) {
372 Error (NULL, 0, 0003, "error parsing FV image", "FFS file with FileType 0x%x can't be found", FileType);
373 return EFI_ABORTED;
374 }
375 //
376 // Loop as long as we have a valid file
377 //
378 while (CurrentFile) {
379 if (FileType == EFI_FV_FILETYPE_ALL || CurrentFile->Type == FileType) {
380 FileCount++;
381 }
382
383 if (FileCount == Instance) {
384 *File = CurrentFile;
385 return EFI_SUCCESS;
386 }
387
388 Status = GetNextFile (CurrentFile, &CurrentFile);
389 if (EFI_ERROR (Status)) {
390 Error (NULL, 0, 0003, "error parsing FV image", "FFS file with FileType 0x%x can't be found", FileType);
391 return EFI_ABORTED;
392 }
393 }
394
395 *File = NULL;
396 return EFI_SUCCESS;
397 }
398
399 EFI_STATUS
400 SearchSectionByType (
401 IN EFI_FILE_SECTION_POINTER FirstSection,
402 IN UINT8 *SearchEnd,
403 IN EFI_SECTION_TYPE SectionType,
404 IN OUT UINTN *StartIndex,
405 IN UINTN Instance,
406 OUT EFI_FILE_SECTION_POINTER *Section
407 )
408 /*++
409
410 Routine Description:
411
412 Helper function to search a sequence of sections from the section pointed
413 by FirstSection to SearchEnd for the Instance-th section of type SectionType.
414 The current counter is saved in StartIndex and when the section is found, it's
415 saved in Section. GUID-defined sections, if special processing is not required,
416 are searched recursively in a depth-first manner.
417
418 Arguments:
419
420 FirstSection The first section to start searching from.
421 SearchEnd The end address to stop search.
422 SectionType The type of section to search.
423 StartIndex The current counter is saved.
424 Instance The requested n-th section number.
425 Section The found section returned.
426
427 Returns:
428
429 EFI_SUCCESS The function completed successfully.
430 EFI_NOT_FOUND The section is not found.
431 --*/
432 {
433 EFI_FILE_SECTION_POINTER CurrentSection;
434 EFI_FILE_SECTION_POINTER InnerSection;
435 EFI_STATUS Status;
436 UINTN SectionSize;
437 UINT16 GuidSecAttr;
438 UINT16 GuidDataOffset;
439
440 GuidSecAttr = 0;
441 GuidDataOffset = 0;
442 CurrentSection = FirstSection;
443
444 while ((UINTN) CurrentSection.CommonHeader < (UINTN) SearchEnd) {
445 if (CurrentSection.CommonHeader->Type == SectionType) {
446 (*StartIndex)++;
447 }
448
449 if (*StartIndex == Instance) {
450 *Section = CurrentSection;
451 return EFI_SUCCESS;
452 }
453 //
454 // If the requesting section is not GUID-defined and
455 // we find a GUID-defined section that doesn't need
456 // special processing, go ahead to search the requesting
457 // section inside the GUID-defined section.
458 //
459 if (CurrentSection.CommonHeader->Type == EFI_SECTION_GUID_DEFINED) {
460 if (GetLength(CurrentSection.CommonHeader->Size) == 0xffffff) {
461 GuidSecAttr = CurrentSection.GuidDefinedSection2->Attributes;
462 GuidDataOffset = CurrentSection.GuidDefinedSection2->DataOffset;
463 } else {
464 GuidSecAttr = CurrentSection.GuidDefinedSection->Attributes;
465 GuidDataOffset = CurrentSection.GuidDefinedSection->DataOffset;
466 }
467 }
468 if (SectionType != EFI_SECTION_GUID_DEFINED &&
469 CurrentSection.CommonHeader->Type == EFI_SECTION_GUID_DEFINED &&
470 !(GuidSecAttr & EFI_GUIDED_SECTION_PROCESSING_REQUIRED)) {
471 InnerSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *)
472 ((UINTN) CurrentSection.CommonHeader + GuidDataOffset);
473 SectionSize = GetSectionFileLength(CurrentSection.CommonHeader);
474 Status = SearchSectionByType (
475 InnerSection,
476 (UINT8 *) ((UINTN) CurrentSection.CommonHeader + SectionSize),
477 SectionType,
478 StartIndex,
479 Instance,
480 Section
481 );
482 if (!EFI_ERROR (Status)) {
483 return EFI_SUCCESS;
484 }
485 }
486 //
487 // Find next section (including compensating for alignment issues.
488 //
489 CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((((UINTN) CurrentSection.CommonHeader) + GetSectionFileLength(CurrentSection.CommonHeader) + 0x03) & (-1 << 2));
490 }
491
492 return EFI_NOT_FOUND;
493 }
494
495 EFI_STATUS
496 GetSectionByType (
497 IN EFI_FFS_FILE_HEADER *File,
498 IN EFI_SECTION_TYPE SectionType,
499 IN UINTN Instance,
500 OUT EFI_FILE_SECTION_POINTER *Section
501 )
502 /*++
503
504 Routine Description:
505
506 Find a section in a file by type and instance. An instance of 1 is the first
507 instance. The function will return NULL if a matching section cannot be found.
508 GUID-defined sections, if special processing is not needed, are handled in a
509 depth-first manner.
510
511 Arguments:
512
513 File The file to search.
514 SectionType Type of file to search for.
515 Instance Instace of the section to return.
516 Section Return pointer. In the case of an error, contents are undefined.
517
518 Returns:
519
520 EFI_SUCCESS The function completed successfully.
521 EFI_ABORTED An error was encountered.
522 EFI_INVALID_PARAMETER One of the parameters was NULL.
523 EFI_NOT_FOUND No found.
524 --*/
525 {
526 EFI_FILE_SECTION_POINTER CurrentSection;
527 EFI_STATUS Status;
528 UINTN SectionCount;
529
530 //
531 // Verify input parameters
532 //
533 if (File == NULL || Instance == 0) {
534 return EFI_INVALID_PARAMETER;
535 }
536 //
537 // Verify FFS header
538 //
539 Status = VerifyFfsFile (File);
540 if (EFI_ERROR (Status)) {
541 Error (NULL, 0, 0006, "invalid FFS file", NULL);
542 return EFI_ABORTED;
543 }
544 //
545 // Initialize the number of matching sections found.
546 //
547 SectionCount = 0;
548
549 //
550 // Get the first section
551 //
552 CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) File + GetFfsHeaderLength(File));
553
554 //
555 // Depth-first manner to find section file.
556 //
557 Status = SearchSectionByType (
558 CurrentSection,
559 (UINT8 *) ((UINTN) File + GetFfsFileLength (File)),
560 SectionType,
561 &SectionCount,
562 Instance,
563 Section
564 );
565
566 if (!EFI_ERROR (Status)) {
567 return EFI_SUCCESS;
568 } else {
569 //
570 // Section not found
571 //
572 (*Section).Code16Section = NULL;
573 return EFI_NOT_FOUND;
574 }
575 }
576 //
577 // will not parse compressed sections
578 //
579 EFI_STATUS
580 VerifyFv (
581 IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader
582 )
583 /*++
584
585 Routine Description:
586
587 Verify the current pointer points to a valid FV header.
588
589 Arguments:
590
591 FvHeader Pointer to an alleged FV file.
592
593 Returns:
594
595 EFI_SUCCESS The FV header is valid.
596 EFI_VOLUME_CORRUPTED The FV header is not valid.
597 EFI_INVALID_PARAMETER A required parameter was NULL.
598 EFI_ABORTED Operation aborted.
599
600 --*/
601 {
602 UINT16 Checksum;
603
604 //
605 // Verify input parameters
606 //
607 if (FvHeader == NULL) {
608 return EFI_INVALID_PARAMETER;
609 }
610
611 if (FvHeader->Signature != EFI_FVH_SIGNATURE) {
612 Error (NULL, 0, 0006, "invalid FV header signature", NULL);
613 return EFI_VOLUME_CORRUPTED;
614 }
615 //
616 // Verify header checksum
617 //
618 Checksum = CalculateSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
619
620 if (Checksum != 0) {
621 Error (NULL, 0, 0006, "invalid FV header checksum", NULL);
622 return EFI_ABORTED;
623 }
624
625 return EFI_SUCCESS;
626 }
627
628 EFI_STATUS
629 VerifyFfsFile (
630 IN EFI_FFS_FILE_HEADER *FfsHeader
631 )
632 /*++
633
634 Routine Description:
635
636 Verify the current pointer points to a FFS file header.
637
638 Arguments:
639
640 FfsHeader Pointer to an alleged FFS file.
641
642 Returns:
643
644 EFI_SUCCESS The Ffs header is valid.
645 EFI_NOT_FOUND This "file" is the beginning of free space.
646 EFI_VOLUME_CORRUPTED The Ffs header is not valid.
647 EFI_ABORTED The erase polarity is not known.
648
649 --*/
650 {
651 BOOLEAN ErasePolarity;
652 EFI_STATUS Status;
653 EFI_FFS_FILE_HEADER2 BlankHeader;
654 UINT8 Checksum;
655 UINT32 FileLength;
656 UINT8 SavedChecksum;
657 UINT8 SavedState;
658 UINT8 FileGuidString[80];
659 UINT32 FfsHeaderSize;
660
661 //
662 // Verify library has been initialized.
663 //
664 if (mFvHeader == NULL || mFvLength == 0) {
665 return EFI_ABORTED;
666 }
667 //
668 // Verify FV header
669 //
670 Status = VerifyFv (mFvHeader);
671 if (EFI_ERROR (Status)) {
672 return EFI_ABORTED;
673 }
674 //
675 // Get the erase polarity.
676 //
677 Status = GetErasePolarity (&ErasePolarity);
678 if (EFI_ERROR (Status)) {
679 return EFI_ABORTED;
680 }
681
682 FfsHeaderSize = GetFfsHeaderLength(FfsHeader);
683 //
684 // Check if we have free space
685 //
686 if (ErasePolarity) {
687 memset (&BlankHeader, -1, FfsHeaderSize);
688 } else {
689 memset (&BlankHeader, 0, FfsHeaderSize);
690 }
691
692 if (memcmp (&BlankHeader, FfsHeader, FfsHeaderSize) == 0) {
693 return EFI_NOT_FOUND;
694 }
695 //
696 // Convert the GUID to a string so we can at least report which file
697 // if we find an error.
698 //
699 PrintGuidToBuffer (&FfsHeader->Name, FileGuidString, sizeof (FileGuidString), TRUE);
700 //
701 // Verify file header checksum
702 //
703 SavedState = FfsHeader->State;
704 FfsHeader->State = 0;
705 SavedChecksum = FfsHeader->IntegrityCheck.Checksum.File;
706 FfsHeader->IntegrityCheck.Checksum.File = 0;
707 Checksum = CalculateSum8 ((UINT8 *) FfsHeader, FfsHeaderSize);
708 FfsHeader->State = SavedState;
709 FfsHeader->IntegrityCheck.Checksum.File = SavedChecksum;
710 if (Checksum != 0) {
711 Error (NULL, 0, 0006, "invalid FFS file header checksum", "Ffs file with Guid %s", FileGuidString);
712 return EFI_ABORTED;
713 }
714 //
715 // Verify file checksum
716 //
717 if (FfsHeader->Attributes & FFS_ATTRIB_CHECKSUM) {
718 //
719 // Verify file data checksum
720 //
721 FileLength = GetFfsFileLength (FfsHeader);
722 Checksum = CalculateSum8 ((UINT8 *) ((UINT8 *)FfsHeader + FfsHeaderSize), FileLength - FfsHeaderSize);
723 Checksum = Checksum + FfsHeader->IntegrityCheck.Checksum.File;
724 if (Checksum != 0) {
725 Error (NULL, 0, 0006, "invalid FFS file checksum", "Ffs file with Guid %s", FileGuidString);
726 return EFI_ABORTED;
727 }
728 } else {
729 //
730 // File does not have a checksum
731 // Verify contents are 0xAA as spec'd
732 //
733 if (FfsHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) {
734 Error (NULL, 0, 0006, "invalid fixed FFS file header checksum", "Ffs file with Guid %s", FileGuidString);
735 return EFI_ABORTED;
736 }
737 }
738
739 return EFI_SUCCESS;
740 }
741
742 UINT32
743 GetFfsHeaderLength(
744 IN EFI_FFS_FILE_HEADER *FfsHeader
745 )
746 {
747 if (FfsHeader == NULL) {
748 return 0;
749 }
750 if (FfsHeader->Attributes & FFS_ATTRIB_LARGE_FILE) {
751 return sizeof(EFI_FFS_FILE_HEADER2);
752 }
753 return sizeof(EFI_FFS_FILE_HEADER);
754 }
755
756 UINT32
757 GetSectionHeaderLength(
758 IN EFI_COMMON_SECTION_HEADER *SectionHeader
759 )
760 {
761 if (SectionHeader == NULL) {
762 return 0;
763 }
764 if (GetLength(SectionHeader->Size) == 0xffffff) {
765 return sizeof(EFI_COMMON_SECTION_HEADER2);
766 }
767 return sizeof(EFI_COMMON_SECTION_HEADER);
768 }
769
770 UINT32
771 GetFfsFileLength (
772 EFI_FFS_FILE_HEADER *FfsHeader
773 )
774 /*++
775
776 Routine Description:
777
778 Get FFS file length including FFS header.
779
780 Arguments:
781
782 FfsHeader Pointer to EFI_FFS_FILE_HEADER.
783
784 Returns:
785
786 UINT32 Length of FFS file header.
787
788 --*/
789 {
790 if (FfsHeader == NULL) {
791 return 0;
792 }
793 if (FfsHeader->Attributes & FFS_ATTRIB_LARGE_FILE) {
794 return ((EFI_FFS_FILE_HEADER2 *)FfsHeader)->ExtendedSize;
795 } else {
796 return GetLength(FfsHeader->Size);
797 }
798 }
799
800 UINT32
801 GetSectionFileLength (
802 EFI_COMMON_SECTION_HEADER *SectionHeader
803 )
804 {
805 UINT32 Length;
806 if (SectionHeader == NULL) {
807 return 0;
808 }
809 Length = GetLength(SectionHeader->Size);
810 if (Length == 0xffffff) {
811 Length = ((EFI_COMMON_SECTION_HEADER2 *)SectionHeader)->ExtendedSize;
812 }
813 return Length;
814 }
815
816 UINT32
817 GetLength (
818 UINT8 *ThreeByteLength
819 )
820 /*++
821
822 Routine Description:
823
824 Converts a three byte length value into a UINT32.
825
826 Arguments:
827
828 ThreeByteLength Pointer to the first of the 3 byte length.
829
830 Returns:
831
832 UINT32 Size of the section
833
834 --*/
835 {
836 UINT32 Length;
837
838 if (ThreeByteLength == NULL) {
839 return 0;
840 }
841
842 Length = *((UINT32 *) ThreeByteLength);
843 Length = Length & 0x00FFFFFF;
844
845 return Length;
846 }
847
848 EFI_STATUS
849 GetErasePolarity (
850 OUT BOOLEAN *ErasePolarity
851 )
852 /*++
853
854 Routine Description:
855
856 This function returns with the FV erase polarity. If the erase polarity
857 for a bit is 1, the function return TRUE.
858
859 Arguments:
860
861 ErasePolarity A pointer to the erase polarity.
862
863 Returns:
864
865 EFI_SUCCESS The function completed successfully.
866 EFI_INVALID_PARAMETER One of the input parameters was invalid.
867 EFI_ABORTED Operation aborted.
868
869 --*/
870 {
871 EFI_STATUS Status;
872
873 //
874 // Verify library has been initialized.
875 //
876 if (mFvHeader == NULL || mFvLength == 0) {
877 return EFI_ABORTED;
878 }
879 //
880 // Verify FV header
881 //
882 Status = VerifyFv (mFvHeader);
883 if (EFI_ERROR (Status)) {
884 return EFI_ABORTED;
885 }
886 //
887 // Verify input parameters.
888 //
889 if (ErasePolarity == NULL) {
890 return EFI_INVALID_PARAMETER;
891 }
892
893 if (mFvHeader->Attributes & EFI_FVB2_ERASE_POLARITY) {
894 *ErasePolarity = TRUE;
895 } else {
896 *ErasePolarity = FALSE;
897 }
898
899 return EFI_SUCCESS;
900 }
901
902 UINT8
903 GetFileState (
904 IN BOOLEAN ErasePolarity,
905 IN EFI_FFS_FILE_HEADER *FfsHeader
906 )
907 /*++
908
909 Routine Description:
910
911 This function returns a the highest state bit in the FFS that is set.
912 It in no way validate the FFS file.
913
914 Arguments:
915
916 ErasePolarity The erase polarity for the file state bits.
917 FfsHeader Pointer to a FFS file.
918
919 Returns:
920
921 UINT8 The hightest set state of the file.
922
923 --*/
924 {
925 UINT8 FileState;
926 UINT8 HighestBit;
927
928 FileState = FfsHeader->State;
929
930 if (ErasePolarity) {
931 FileState = (UINT8)~FileState;
932 }
933
934 HighestBit = 0x80;
935 while (HighestBit != 0 && (HighestBit & FileState) == 0) {
936 HighestBit >>= 1;
937 }
938
939 return HighestBit;
940 }