How to open a file by it's full path in UEFI

自闭症网瘾萝莉.ら 提交于 2019-12-10 15:39:46

问题


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.


回答1:


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.



来源:https://stackoverflow.com/questions/39719771/how-to-open-a-file-by-its-full-path-in-uefi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!