我想在UEFI中列出根目录的内容,但没有找到任何协议;因此,我想打印目录文件的内容,但EFI_FILE_PROTOCOL
无法读取目录文件。我唯一能做的另一件事是读取包含该信息的磁盘扇区,但EFI_BLOCK_IO_PROTOCOL
返回0x02
。
这是代码:
#include <efi.h>
#include <efilib.h>
EFI_STATUS
efi_main(EFI_HANDLE Image, EFI_SYSTEM_TABLE* Systab)
{
EFI_LOADED_IMAGE_PROTOCOL* LoadedImage;
EFI_BLOCK_IO_PROTOCOL* BlockIO;
UINT16* Buffer;
EFI_STATUS Status;
InitializeLib(Image, Systab);
Status = uefi_call_wrapper(BS->HandleProtocol, 3,
Image,
&gEfiLoadedImageProtocolGuid,
&LoadedImage);
if(Status != EFI_SUCCESS) {
Print(L"HandleProtocol() failed [0]n");
}
Status = uefi_call_wrapper(BS->HandleProtocol, 3,
LoadedImage->DeviceHandle,
&gEfiBlockIoProtocolGuid,
&BlockIO);
if(Status != EFI_SUCCESS) {
Print(L"HandleProtocol() failed [1]n");
}
Status = uefi_call_wrapper(BlockIO->ReadBlocks, 5,
BlockIO,
BlockIO->Media->MediaId,
(EFI_LBA)1,
BlockIO->Media->BlockSize,
Buffer);
if(Status != EFI_SUCCESS) {
Print(L"Failed to read disk with code 0x%xn", Status);
}
else for(int i = 0; i < 512; i++) {
Print(L"%c", (CHAR8)Buffer[i]);
}
return EFI_SUCCESS;
}
你能认出我做错了什么吗?
UINT16* Buffer;
这是什么?一个未初始化的指针!您将其传递给ReadBlocks()
,然后会出现错误。你的Buffer
应该这样定义:
UINT8 Buffer[512];
顺便说一下,在目录中列出文件的正确方法是使用EFI_FILE_PROTOCOL.Read()
。UEFI规范规定:
如果这是一个目录,函数会读取文件当前位置的目录条目,并返回
Buffer
中的条目。如果Buffer
不足以容纳当前目录条目,则返回EFI_BUFFER_TOO_SMALL
,并且不更新当前文件位置。CCD_ 10被设置为读取条目所需的缓冲器的大小。成功后,当前位置将更新到下一个目录条目。如果没有更多的目录条目,读取将返回一个零长度的缓冲区。EFI_FILE_INFO
是作为目录条目返回的结构。
这是代码示例(忽略错误处理(
#include <efi.h>
#include <efilib.h>
#define FILE_BUFFER_SIZE 4096
EFI_STATUS efi_main(EFI_HANDLE *ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
InitializeLib(ImageHandle, SystemTable);
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
EFI_FILE_PROTOCOL *RootDir;
UINT8 Buffer[FILE_BUFFER_SIZE];
UINTN BufferSize;
EFI_FILE_INFO *FileInfo;
// clear screen
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
// open the filesystem
uefi_call_wrapper(BS->LocateProtocol, 3, &FileSystemProtocol, NULL, &FileSystem);
// open the root directory
uefi_call_wrapper(FileSystem->OpenVolume, 2, FileSystem, &RootDir);
while (TRUE) {
BufferSize = sizeof(Buffer);
// read one directory entry
uefi_call_wrapper(RootDir->Read, 3, RootDir, &BufferSize, Buffer);
// stop reading when there are no more entries
if (BufferSize == 0) {
break;
}
// cast and print the filename
FileInfo = (EFI_FILE_INFO *)Buffer;
Print(L"%sn", FileInfo->FileName);
}
// close the root directory
uefi_call_wrapper(RootDir->Close, 1, RootDir);
Pause();
return EFI_SUCCESS;
}