如何通过UEFI中的完整路径打开文件 [英] How to open a file by it's full path in UEFI

查看:950
本文介绍了如何通过UEFI中的完整路径打开文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是UEFI的初学者。我试图从我的UEFI应用程序打开一个文件。文件的路径是

$ $ p $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ pre>

代码(借助这个答案< a>)

  efiStatus = bs-> LocateHandleBuffer(ByProtocol,
& sfspGuid,
NULL,
& handleCount,
&句柄); (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->打开(
root,
& token,
Lmyfolder \\myfile.txt,
EFI_FILE_MODE_READ,
EFI_FILE_READ_ONLY | EFI_FILE_HIDDEN | EFI_FILE_SYSTEM);

$ / code>

但是使用这种方法,我只能通过所有的文件系统句柄打开每个卷,然后尝试打开我的文件。

但我想给我的文件的完整路径,并在它的音量打开。


$

>

我试着用@Alex在注释中使用Shell API打开文件。
以下是代码。但它挂在函数 OpenFileByName



这段代码有什么错误? (argv [1]将是我的文件路径 fs1:\myfile.txt

  EFI_STATUS 
EFIAPI
main(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE * SystemTable

{

EFI_STATUS状态;
UINTN argc;
CHAR16 ** argv;
SHELL_FILE_HANDLE句柄;

status = get_args(& argc,& argv);
if(EFI_ERROR(status)){
Print(LERROR:Parsing command arguments arguments:%d\\\
,status);
返回状态;
}

if(argc <= 1){
打印(L无文件名打开\\\
);
return(EFI_UNSUPPORTED); //需要至少有一个参数


打印(LFile to open is:%s\\\
,argv [1]);

status = gEfiShellProtocol-> OpenFileByName(argv [1],& Handle,
EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE); (EFI_ERROR(status)){
Print(L\ nFile Open does not work%s \\\
,argv [1]);

if
return(status);
} else {
Print(L\\\
File Open工作%s\\\
,argv [1]);
gEfiShellProtocol-> CloseFile(Handle);
}

return EFI_SUCCESS;

$ / code>

即使我尝试 GetCurDir function。

 打印(LDir:%s \\\
,gEfiShellProtocol-> GetCurDir (空值));

任何指针都会有帮助。

解决方案

回答如何获得EFI_SHELL_PROTOCOL:
该过程基本上与任何Efi协议相同。首先,抓取接口的句柄:

  UINTN BufferSize; 
EFI_HANDLE *缓冲区;
Status = bs-> LocateHandle(ByProtocol,& gEfiShellProtocolGuid,NULL,& BufferSize,Buffer);

与正确大小的缓冲区分配和调用:

  Status = bs-> AllocatePool(EfiBootServicesData,BufferSize,& Buffer); 

Status = bs-> LocateHandle(ByProtocol,& gEfiShellProtocolGuid,NULL,& BufferSize,Buffer);

现在,您可以获取协议的句柄。请记住,这是EFI,可能会安装多个协议!这就是为什么我们必须遍历所有这些。但在这种情况下,最有可能只有一个SHELL协议的实例:

pre $ U $ $ $ $ $ $ $ UINTN HandleCounter; (HandleCounter = 0; HandleCounter<(BufferSize / sizeof(EFI_HANDLE)); HandleCounter ++)
{
Status = bs-> OpenProtocol(Buffer [HandleCounter],
& gEfiShellProtocolGuid,
(VOID **)& gEfiShellProtocol,
imageHandle,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL);

不要忘记检查每一步的状态!



当然不要忘记:

$ $ $ $ $ $ c $ bs-> FreePool(buffer);

至于协议本身,您不必关闭它。从2.31开始的EFI不再需要它。


I'm a beginner in UEFI. I'm trying to open a file from my UEFI application. The path of file is

fs1:/myfolder/myfile.txt

The code (With the help of this answer) :

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);
}

But using this method, I can only go through all the file system handles and open each volume and try opening my file.

But I want to give full path to my file and open it in it's volume.

How can I acheive this?


EDIT:

I tried using Shell APIs for opening the file as suggested by @Alex in comments. Below is the code. But it hangs in function OpenFileByName .

What is the mistake in this code? (argv[ 1 ] would be my file path 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;
}

And the code hangs even if I try GetCurDir function.

Print(L"Dir: %s \n",gEfiShellProtocol->GetCurDir(NULL));

Any pointers would be helpful.

解决方案

Answer to the comment how to get EFI_SHELL_PROTOCOL: The procedure is basically the same as for any Efi protocols. First, grab a handle to the interface:

UINTN BufferSize;
EFI_HANDLE* Buffer;
Status = bs->LocateHandle(ByProtocol, &gEfiShellProtocolGuid, NULL, &BufferSize, Buffer);

Than, allocate and recall with the buffer of the correct size:

    Status = bs->AllocatePool(EfiBootServicesData, BufferSize, &Buffer);

    Status = bs->LocateHandle(ByProtocol, &gEfiShellProtocolGuid, NULL, &BufferSize, Buffer);

Now, you can grab a handle to the protocol. Remember, it's EFI, there might be multiple protocols installed! That's why we have to iterate through all of them. But in this case most likely there will be just one instance of the SHELL protocol:

 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);

And don't forget to check Status for every step!

And of course don't forget:

bs->FreePool(buffer);

As for the protocol itself you don't have to close it. EFI starting from 2.31 doesn't require it anymore.

这篇关于如何通过UEFI中的完整路径打开文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆