fvlib.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 785 行 · 第 1/2 页

C
785
字号
/*++

Copyright (c) 2004 - 2006, Intel Corporation                                                         
All rights reserved. This program and the accompanying materials                          
are licensed and made available under the terms and conditions of the BSD License         
which accompanies this distribution.  The full text of the license may be found at        
http://opensource.org/licenses/bsd-license.php                                            
                                                                                          
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

Module Name:

  FvLib.c

Abstract:

  These functions assist in parsing and manipulating a Firmware Volume.

--*/

//
// Include files
//
#include "FvLib.h"
#include "CommonLib.h"
#include "EfiUtilityMsgs.h"

#include EFI_GUID_DEFINITION (FirmwareFileSystem)

//
// Module global variables
//
EFI_FIRMWARE_VOLUME_HEADER  *mFvHeader  = NULL;
UINT32                      mFvLength   = 0;

//
// External function implementations
//
EFI_STATUS
InitializeFvLib (
  IN VOID                         *Fv,
  IN UINT32                       FvLength
  )
/*++

Routine Description:

  This initializes the FV lib with a pointer to the FV and length.  It does not
  verify the FV in any way.

Arguments:

  Fv            Buffer containing the FV.
  FvLength      Length of the FV
    
Returns:
 
  EFI_SUCCESS             Function Completed successfully.
  EFI_INVALID_PARAMETER   A required parameter was NULL.

--*/
{
  //
  // Verify input arguments
  //
  if (Fv == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  mFvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) Fv;
  mFvLength = FvLength;

  return EFI_SUCCESS;
}

EFI_STATUS
GetFvHeader (
  OUT EFI_FIRMWARE_VOLUME_HEADER  **FvHeader,
  OUT UINT32                      *FvLength
  )
/*++

Routine Description:

  This function returns a pointer to the current FV and the size.

Arguments:

  FvHeader      Pointer to the FV buffer.
  FvLength      Length of the FV
    
Returns:
 
  EFI_SUCCESS             Function Completed successfully.
  EFI_INVALID_PARAMETER   A required parameter was NULL.
  EFI_ABORTED             The library needs to be initialized.

--*/
{
  //
  // Verify library has been initialized.
  //
  if (mFvHeader == NULL || mFvLength == 0) {
    return EFI_ABORTED;
  }
  //
  // Verify input arguments
  //
  if (FvHeader == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  *FvHeader = mFvHeader;
  return EFI_SUCCESS;
}

EFI_STATUS
GetNextFile (
  IN EFI_FFS_FILE_HEADER          *CurrentFile,
  OUT EFI_FFS_FILE_HEADER         **NextFile
  )
/*++

Routine Description:

  This function returns the next file.  If the current file is NULL, it returns
  the first file in the FV.  If the function returns EFI_SUCCESS and the file 
  pointer is NULL, then there are no more files in the FV.

Arguments:

  CurrentFile   Pointer to the current file, must be within the current FV.
  NextFile      Pointer to the next file in the FV.
    
Returns:
 
  EFI_SUCCESS             Function completed successfully.
  EFI_INVALID_PARAMETER   A required parameter was NULL or is out of range.
  EFI_ABORTED             The library needs to be initialized.

--*/
{
  EFI_STATUS  Status;

  //
  // Verify library has been initialized.
  //
  if (mFvHeader == NULL || mFvLength == 0) {
    return EFI_ABORTED;
  }
  //
  // Verify input arguments
  //
  if (NextFile == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  //
  // Verify FV header
  //
  Status = VerifyFv (mFvHeader);
  if (EFI_ERROR (Status)) {
    return EFI_ABORTED;
  }
  //
  // Get first file
  //
  if (CurrentFile == NULL) {
    CurrentFile = (EFI_FFS_FILE_HEADER *) ((UINTN) mFvHeader + mFvHeader->HeaderLength);

    //
    // Verify file is valid
    //
    Status = VerifyFfsFile (CurrentFile);
    if (EFI_ERROR (Status)) {
      //
      // no files in this FV
      //
      *NextFile = NULL;
      return EFI_SUCCESS;
    } else {
      //
      // Verify file is in this FV.
      //
      if ((UINTN) CurrentFile + GetLength (CurrentFile->Size) > (UINTN) mFvHeader + mFvLength) {
        *NextFile = NULL;
        return EFI_SUCCESS;
      }

      *NextFile = CurrentFile;
      return EFI_SUCCESS;
    }
  }
  //
  // Verify current file is in range
  //
  if (((UINTN) CurrentFile < (UINTN) mFvHeader + mFvHeader->HeaderLength) ||
      ((UINTN) CurrentFile + GetLength (CurrentFile->Size) > (UINTN) mFvHeader + mFvLength)
     ) {
    return EFI_INVALID_PARAMETER;
  }
  //
  // Get next file, compensate for 8 byte alignment if necessary.
  //
  *NextFile = (EFI_FFS_FILE_HEADER *) (((UINTN) CurrentFile + GetLength (CurrentFile->Size) + 0x07) & (-1 << 3));

  //
  // Verify file is in this FV.
  //
  if (((UINTN) *NextFile + sizeof (EFI_FFS_FILE_HEADER) >= (UINTN) mFvHeader + mFvLength) ||
      ((UINTN) *NextFile + GetLength ((*NextFile)->Size) > (UINTN) mFvHeader + mFvLength)
     ) {
    *NextFile = NULL;
    return EFI_SUCCESS;
  }
  //
  // Verify file is valid
  //
  Status = VerifyFfsFile (*NextFile);
  if (EFI_ERROR (Status)) {
    //
    // no more files in this FV
    //
    *NextFile = NULL;
    return EFI_SUCCESS;
  }

  return EFI_SUCCESS;
}

EFI_STATUS
GetFileByName (
  IN EFI_GUID                     *FileName,
  OUT EFI_FFS_FILE_HEADER         **File
  )
/*++

Routine Description:

  Find a file by name.  The function will return NULL if the file is not found.

Arguments:

  FileName    The GUID file name of the file to search for.
  File        Return pointer.  In the case of an error, contents are undefined.

Returns:

  EFI_SUCCESS             The function completed successfully.
  EFI_ABORTED             An error was encountered.
  EFI_INVALID_PARAMETER   One of the parameters was NULL.

--*/
{
  EFI_FFS_FILE_HEADER *CurrentFile;
  EFI_STATUS          Status;

  //
  // Verify library has been initialized.
  //
  if (mFvHeader == NULL || mFvLength == 0) {
    return EFI_ABORTED;
  }
  //
  // Verify input parameters
  //
  if (FileName == NULL || File == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  //
  // Verify FV header
  //
  Status = VerifyFv (mFvHeader);
  if (EFI_ERROR (Status)) {
    return EFI_ABORTED;
  }
  //
  // Get the first file
  //
  Status = GetNextFile (NULL, &CurrentFile);
  if (EFI_ERROR (Status)) {
    Error (NULL, 0, 0, "error parsing the FV", NULL);
    return EFI_ABORTED;
  }
  //
  // Loop as long as we have a valid file
  //
  while (CurrentFile) {
    if (!CompareGuid (&CurrentFile->Name, FileName)) {
      *File = CurrentFile;
      return EFI_SUCCESS;
    }

    Status = GetNextFile (CurrentFile, &CurrentFile);
    if (EFI_ERROR (Status)) {
      Error (NULL, 0, 0, "error parsing the FV", NULL);
      return EFI_ABORTED;
    }
  }
  //
  // File not found in this FV.
  //
  *File = NULL;
  return EFI_SUCCESS;
}

EFI_STATUS
GetFileByType (
  IN EFI_FV_FILETYPE              FileType,
  IN UINTN                        Instance,
  OUT EFI_FFS_FILE_HEADER         **File
  )
/*++

Routine Description:

  Find a file by type and instance.  An instance of 1 is the first instance.
  The function will return NULL if a matching file cannot be found.
  File type EFI_FV_FILETYPE_ALL means any file type is valid.

Arguments:

  FileType    Type of file to search for.
  Instance    Instace of the file type to return.
  File        Return pointer.  In the case of an error, contents are undefined.

Returns:

  EFI_SUCCESS             The function completed successfully.
  EFI_ABORTED             An error was encountered.
  EFI_INVALID_PARAMETER   One of the parameters was NULL.

--*/
{
  EFI_FFS_FILE_HEADER *CurrentFile;
  EFI_STATUS          Status;
  UINTN               FileCount;

  //
  // Verify library has been initialized.
  //
  if (mFvHeader == NULL || mFvLength == 0) {
    return EFI_ABORTED;
  }
  //
  // Verify input parameters
  //
  if (File == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  //
  // Verify FV header
  //
  Status = VerifyFv (mFvHeader);
  if (EFI_ERROR (Status)) {
    return EFI_ABORTED;
  }
  //
  // Initialize the number of matching files found.
  //
  FileCount = 0;

  //
  // Get the first file
  //
  Status = GetNextFile (NULL, &CurrentFile);
  if (EFI_ERROR (Status)) {
    Error (NULL, 0, 0, "error parsing FV", NULL);
    return EFI_ABORTED;
  }
  //
  // Loop as long as we have a valid file
  //
  while (CurrentFile) {
    if (FileType == EFI_FV_FILETYPE_ALL || CurrentFile->Type == FileType) {
      FileCount++;
    }

    if (FileCount == Instance) {
      *File = CurrentFile;
      return EFI_SUCCESS;
    }

    Status = GetNextFile (CurrentFile, &CurrentFile);
    if (EFI_ERROR (Status)) {
      Error (NULL, 0, 0, "error parsing the FV", NULL);
      return EFI_ABORTED;
    }
  }

  *File = NULL;
  return EFI_SUCCESS;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?