2016-09-27 283 views
2

我是UEFI的初學者。我試圖從我的UEFI應用程序打開一個文件。文件的路徑是如何在UEFI中以完整路徑打開文件

fs1:/myfolder/myfile.txt 

代碼(隨着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); 
} 

但是,使用這種方法,我只能去通過所有的文件系統處理,並打開每個卷並嘗試打開我的文件。

但我想給我的文件的完整路徑,並打開它的音量。

我該如何實現這個目標?


編輯:

我使用殼牌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; 
} 

和代碼掛起即使我嘗試GetCurDir功能。

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

任何指針都會有幫助。

+0

我可以看到另一種方式做到這一點。所以,在UEFI中,一切都是句柄,因此文件沒有區別。您可以嘗試爲該特定文件創建/構建設備路徑,然後使用該設備路徑打開句柄。基本上,您可以克隆控制器的現有設備路徑,然後爲您的文件添加特定的節點。我認爲這可能有效。 – Alex

+0

作爲參考,我會考慮EDK Shell的實現! – Alex

+0

查看EFI_SHELL_PROTOCOL的EFI_SHELL_OPEN_FILE_BY_NAME – Alex

回答

3

回答評論如何獲得EFI_SHELL_PROTOCOL: 該過程基本上與任何Efi協議相同。首先,抓取到接口:

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

比,分配和使用正確大小的緩衝區回憶:

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

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

現在,你可以抓住的句柄協議。請記住,它是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); 

而且不要忘記檢查狀態的每一步!

當然不要忘了:

bs->FreePool(buffer); 

至於協議本身不必將其關閉。從2.31開始的EFI不再需要它了。

相關問題