2016-09-27 30 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); 
} 

しかし、この方法を使用して、私はすべてのファイルシステムハンドルを通過し、各ボリュームを開くことができます私のファイルを開いてみてください。

しかし、私は自分のファイルへの完全なパスを与え、そのボリュームで開くことを望みます。

これはどのように達成できますか?


EDIT:

私はコメントで@Alexによって示唆されているように、ファイルを開くためのシェルAPIを使用してみました。 以下はそのコードです。しかし、それは関数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プロトコルのインスタンスは1つだけです。

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はそれをもう必要としません。

関連する問題