4. 打开现有文件

任务目标

在UEFI环境中,以只读模式打开一个已存在的文件,并检查EFI_FILE_PROTOCOL.Open()返回的状态码,确认文件是否成功打开。

核心实现

以下代码演示了在FAT文件系统根目录下打开名为test.txt的现有文件。使用EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.OpenVolume()获取根目录句柄,然后调用Open()以只读模式打开目标文件。

#include <Uefi.h>
#include <Protocol/SimpleFileSystem.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>

EFI_STATUS
OpenExistingFile (
  VOID
  )
{
  EFI_STATUS                    Status;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
  EFI_FILE_PROTOCOL             *RootDir;
  EFI_FILE_PROTOCOL             *FileHandle;
  EFI_HANDLE                    *HandleBuffer;
  UINTN                         HandleCount;
  UINTN                         Index;

  // 1. 定位支持 SimpleFileSystem 协议的分区设备
  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiSimpleFileSystemProtocolGuid,
                  NULL,
                  &HandleCount,
                  &HandleBuffer
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  // 2. 使用第一个找到的文件系统设备
  Status = gBS->HandleProtocol (
                  HandleBuffer[0],
                  &gEfiSimpleFileSystemProtocolGuid,
                  (VOID **)&FileSystem
                  );
  if (EFI_ERROR (Status)) {
    FreePool (HandleBuffer);
    return Status;
  }

  // 3. 打开卷根目录
  Status = FileSystem->OpenVolume (FileSystem, &RootDir);
  if (EFI_ERROR (Status)) {
    FreePool (HandleBuffer);
    return Status;
  }

  // 4. 以只读模式打开现有文件
  Status = RootDir->Open (
                      RootDir,
                      &FileHandle,
                      L"test.txt",
                      EFI_FILE_MODE_READ,
                      0
                      );
  if (EFI_ERROR (Status)) {
    Print (L"打开文件失败,状态码: %r\n", Status);
    RootDir->Close (RootDir);
    FreePool (HandleBuffer);
    return Status;
  }

  // 5. 打开成功,输出确认信息
  Print (L"文件 test.txt 以只读模式打开成功\n");

  // 6. 关闭文件与根目录,释放资源
  FileHandle->Close (FileHandle);
  RootDir->Close (RootDir);
  FreePool (HandleBuffer);

  return EFI_SUCCESS;
}

关键说明

  • 打开模式:EFI_FILE_MODE_READ表示只读访问。若文件不存在,Open()返回EFI_NOT_FOUND。
  • 属性参数:最后一个参数0表示不创建新文件(仅在EFI_FILE_MODE_CREATE时有效)。
  • 状态检查:通过EFI_ERROR()宏判断返回值,任何非成功状态均表示打开失败。

编译与运行

将该函数加入UEFI应用入口UefiMain,使用EDK2构建环境编译。在UEFI Shell中运行生成的.efi文件,需确保当前分区根目录下存在test.txt文件。

验证方法

  • 成功场景:在FAT分区根目录放置test.txt,运行程序后输出“文件 test.txt 以只读模式打开成功”。
  • 失败场景:删除test.txt后运行,输出“打开文件失败,状态码: Not Found”,且返回码为EFI_NOT_FOUND。

通过观察输出信息与返回状态,即可确认文件是否以只读模式正确打开。