⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imagefile.c

📁 EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是EFI BIOS源代码中的与平台无关部分的代码
💻 C
📖 第 1 页 / 共 2 页
字号:
  Status = CoreDevicePathToInterface (
              &gEfiLoadFileProtocolGuid,
              &TempFilePath,
              (VOID*)&LoadFile,
              DeviceHandle
              );
  if (!EFI_ERROR (Status)) {
    //
    // Call LoadFile with the correct buffer size
    //
    while (CoreGrowBuffer (&Status, &ImageFileHandle->Source, ImageFileHandle->SourceSize)) {
      Status = LoadFile->LoadFile (
                           LoadFile,
                           TempFilePath,
                           BootPolicy,
                           &ImageFileHandle->SourceSize,
                           ImageFileHandle->Source
                           );
      //
      // If success or other error happens, stop loop
      //
      if (Status != EFI_BUFFER_TOO_SMALL) {
        break;
      }
    }

    if (!EFI_ERROR (Status) || Status == EFI_ALREADY_STARTED) {
      ImageFileHandle->FreeBuffer = TRUE;
      goto Done;
    }
  }

  //
  // Nothing else to try
  //
  DEBUG ((EFI_D_LOAD|EFI_D_WARN, "CoreOpenImageFile: Device did not support a known load protocol\n"));
  Status = EFI_NOT_FOUND;

Done:

  //
  // If the file was not accessed, clean up
  //
  if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
    if (ImageFileHandle->FreeBuffer) {
      //
      // Free the source buffer if we allocated it
      //
      CoreFreePool (ImageFileHandle->Source);
    }
  }

  return Status;
}



EFI_STATUS
EFIAPI
CoreReadImageFile (
  IN     VOID    *UserHandle,
  IN     UINTN   Offset,
  IN OUT UINTN   *ReadSize,
  OUT    VOID    *Buffer
  )
/*++

Routine Description:

  Read image file (specified by UserHandle) into user specified buffer with specified offset
  and length.

Arguments:

  UserHandle      - Image file handle
  
  Offset          - Offset to the source file
  
  ReadSize        - For input, pointer of size to read;
                    For output, pointer of size actually read.
  
  Buffer          - Buffer to write into

Returns:

  EFI_SUCCESS     - Successfully read the specified part of file into buffer.

--*/
{
  UINTN               EndPosition;
  IMAGE_FILE_HANDLE  *FHand;

  FHand = (IMAGE_FILE_HANDLE  *)UserHandle;
  ASSERT (FHand->Signature == IMAGE_FILE_HANDLE_SIGNATURE);

  //
  // Move data from our local copy of the file
  //
  EndPosition = Offset + *ReadSize;
  if (EndPosition > FHand->SourceSize) {
    *ReadSize = (UINT32)(FHand->SourceSize - Offset);
  }  
  if (Offset >= FHand->SourceSize) {
      *ReadSize = 0;
  }

  EfiCommonLibCopyMem (Buffer, (CHAR8 *)FHand->Source + Offset, *ReadSize);
  return EFI_SUCCESS;
}

EFI_STATUS
CoreDevicePathToInterface (
  IN EFI_GUID                     *Protocol,
  IN EFI_DEVICE_PATH_PROTOCOL     **FilePath,
  OUT VOID                        **Interface,
  OUT EFI_HANDLE                  *Handle
  )
/*++

Routine Description:

  Search a handle to a device on a specified device path that supports a specified protocol,
  interface of that protocol on that handle is another output.

Arguments:

  Protocol      - The protocol to search for
  
  FilePath      - The specified device path
  
  Interface     - Interface of the protocol on the handle
  
  Handle        - The handle to the device on the specified device path that supports the protocol.
  
Returns:

  Status code.

--*/
{
  EFI_STATUS                      Status;

  Status = CoreLocateDevicePath (Protocol, FilePath, Handle);
  if (!EFI_ERROR (Status)) {
    Status = CoreHandleProtocol (*Handle, Protocol, Interface);
  }
  return Status;
}


VOID
CoreDevicePathToFileName (
  IN  FILEPATH_DEVICE_PATH      *FilePath,
  OUT CHAR16                    **String
  )
/*++

Routine Description:

  Transfer a device's full path a string.

Arguments:

  FilePath      - Device path
  
  String        - The string represent the device's full path

Returns:

  None

--*/
{
  UINTN                     StringSize;
  FILEPATH_DEVICE_PATH      *FilePathNode;
  CHAR16                    *Str;

  *String = NULL;
  StringSize = 0;
  FilePathNode = FilePath;
  while (!IsDevicePathEnd (&FilePathNode->Header)) {

    //
    // For filesystem access each node should be a filepath component
    //
    if (DevicePathType (&FilePathNode->Header) != MEDIA_DEVICE_PATH ||
        DevicePathSubType (&FilePathNode->Header) != MEDIA_FILEPATH_DP) {

      return;
    }

    StringSize += EfiStrLen (FilePathNode->PathName);

    FilePathNode = (FILEPATH_DEVICE_PATH *) NextDevicePathNode (&FilePathNode->Header);
  }

  *String = CoreAllocateBootServicesPool (StringSize);
  if (*String == NULL) {
    return;
  }

  FilePathNode = FilePath;
  Str = *String;
  while (!IsDevicePathEnd (&FilePathNode->Header)) {
    EfiStrCat (Str, FilePathNode->PathName);
    FilePathNode = (FILEPATH_DEVICE_PATH *) NextDevicePathNode (&FilePathNode->Header);
  }
}


BOOLEAN
CoreGrowBuffer (
  IN OUT EFI_STATUS   *Status,
  IN OUT VOID         **Buffer,
  IN UINTN            BufferSize
  )
/*++

Routine Description:

    Helper function called as part of the code needed
    to allocate the proper sized buffer for various 
    EFI interfaces.

Arguments:

    Status      - Current status

    Buffer      - Current allocated buffer, or NULL

    BufferSize  - Current buffer size needed
    
Returns:
    
    TRUE - if the buffer was reallocated and the caller 
    should try the API again.

    FALSE - buffer could not be allocated and the caller
    should not try the API again.

--*/
{
  BOOLEAN         TryAgain;

  TryAgain = FALSE;
  //
  // If this is an initial request, buffer will be null with a new buffer size
  //
  if (*Buffer == NULL) {
    *Status = EFI_BUFFER_TOO_SMALL;
  }

  if (BufferSize == 0) {
    return TRUE;
  }

  //
  // If the status code is "buffer too small", resize the buffer
  //
      
  if (*Status == EFI_BUFFER_TOO_SMALL) {
    if (*Buffer != NULL) {
      CoreFreePool (*Buffer);
    }

    *Buffer = CoreAllocateBootServicesPool (BufferSize);
    if (*Buffer != NULL) {
      TryAgain = TRUE;
    } else {    
      *Status = EFI_OUT_OF_RESOURCES;
    } 
  }

  //
  // If there's an error, free the buffer
  //
  if ((!TryAgain) && (EFI_ERROR (*Status)) && (*Buffer)) {
    CoreFreePool (*Buffer);
    *Buffer = NULL;
  }

  return TryAgain;
}

⌨️ 快捷键说明

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