Kes*_* GN 4 filesystems file uefi
我是UEFI的初学者。我正在尝试从UEFI应用程序打开文件。文件的路径是
fs1:/myfolder/myfile.txt
Run Code Online (Sandbox Code Playgroud)
代码(借助此答案):
efiStatus = bs->LocateHandleBuffer(ByProtocol,
&sfspGuid,
NULL,
&handleCount,
&handles);
for (index = 0; index < (int)handleCount; ++ index)
{
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* fs = NULL;
efiStatus = bs->HandleProtocol(
handles[index],
&sfspGuid,
(void**)&fs);
EFI_FILE_PROTOCOL* root = NULL;
...
efiStatus = fs->OpenVolume(fs, &root);
EFI_FILE_PROTOCOL* token = NULL;
efiStatus = root->Open(
root,
&token,
L"myfolder\\myfile.txt",
EFI_FILE_MODE_READ,
EFI_FILE_READ_ONLY | EFI_FILE_HIDDEN | EFI_FILE_SYSTEM);
}
Run Code Online (Sandbox Code Playgroud)
但是使用这种方法,我只能浏览所有文件系统句柄并打开每个卷,然后尝试打开我的文件。
但我想提供文件的完整路径并在其卷中打开它。
我该如何实现?
编辑:
我尝试使用Shell API按照@Alex在注释中的建议打开文件。下面是代码。但是它挂了功能OpenFileByName。
这段代码有什么错误?(argv [1]是我的文件路径fs1:\myfile.txt)
EFI_STATUS
EFIAPI
main (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS status;
UINTN argc;
CHAR16 **argv;
SHELL_FILE_HANDLE Handle;
status = get_args(&argc, &argv);
if (EFI_ERROR(status)) {
Print(L"ERROR: Parsing command line arguments: %d\n", status);
return status;
}
if (argc <= 1){
Print(L"No file name to open\n");
return (EFI_UNSUPPORTED); //need to have at least one parameter
}
Print(L"File to open is: %s\n", argv[1]);
status = gEfiShellProtocol->OpenFileByName (argv[1], &Handle,
EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE);
if (EFI_ERROR(status)) {
Print(L"\nFile Open did not work %s\n", argv[1]);
return (status);
}else{
Print(L"\nFile Open worked %s\n", argv[1]);
gEfiShellProtocol->CloseFile(Handle);
}
return EFI_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
即使我尝试执行GetCurDir功能,代码也会挂起。
Print(L"Dir: %s \n",gEfiShellProtocol->GetCurDir(NULL));
Run Code Online (Sandbox Code Playgroud)
任何指针都会有所帮助。
对评论的答案,如何获得EFI_SHELL_PROTOCOL:该过程基本上与任何Efi协议相同。首先,抓住接口的句柄:
UINTN BufferSize;
EFI_HANDLE* Buffer;
Status = bs->LocateHandle(ByProtocol, &gEfiShellProtocolGuid, NULL, &BufferSize, Buffer);
Run Code Online (Sandbox Code Playgroud)
然后,使用正确大小的缓冲区分配和调用:
Status = bs->AllocatePool(EfiBootServicesData, BufferSize, &Buffer);
Status = bs->LocateHandle(ByProtocol, &gEfiShellProtocolGuid, NULL, &BufferSize, Buffer);
Run Code Online (Sandbox Code Playgroud)
现在,您可以抓住协议的句柄。记住,这是EFI,可能安装了多个协议!这就是为什么我们必须遍历所有这些。但是在这种情况下,最有可能只有一个SHELL协议实例:
UINTN HandleCounter;
for (HandleCounter = 0 ; HandleCounter < (BufferSize/sizeof(EFI_HANDLE)) ; HandleCounter++)
{
Status = bs->OpenProtocol(Buffer[HandleCounter],
&gEfiShellProtocolGuid,
(VOID**)&gEfiShellProtocol,
imageHandle,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
Run Code Online (Sandbox Code Playgroud)
并且不要忘记检查每一步的状态!
当然,不要忘记:
bs->FreePool(buffer);
Run Code Online (Sandbox Code Playgroud)
至于协议本身,您不必关闭它。从2.31开始的EFI不再需要它。
| 归档时间: |
|
| 查看次数: |
2329 次 |
| 最近记录: |