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。
通过观察输出信息与返回状态,即可确认文件是否以只读模式正确打开。