UEFI 基础教程 (十) - FileIO 简单使用

一、 编写源代码
  1. 编写UEFI Application
    代码C:\edkii\OvmfPkg\MyHelloWorldFileIO\MyHelloWorldFileIO.c,
EFI_STATUS OpenShellProtocol( EFI_SHELL_PROTOCOL            **gEfiShellProtocol )
{
    EFI_STATUS                      Status;
    Status = gBS->OpenProtocol(
            gImageHandle,
            &gEfiShellProtocolGuid,
            (VOID **)gEfiShellProtocol,
            gImageHandle,
            NULL,
            EFI_OPEN_PROTOCOL_GET_PROTOCOL
            );
    if (EFI_ERROR(Status)) {
    //
    // Search for the shell protocol
    //
        Status = gBS->LocateProtocol(
                &gEfiShellProtocolGuid,
                NULL,
                (VOID **)gEfiShellProtocol
                );
        if (EFI_ERROR(Status)) {
            gEfiShellProtocol = NULL;
        }
  }
  return Status;
}

INTN
EFIAPI
ShellAppMain( UINTN Argc, CHAR16 **Argv)
{ 
  CHAR16 * OldLogFileName = NULL;
  CHAR16  *LineBuff = NULL;
  CHAR16  NewFileName[128] = {0};
  CHAR16 * ArrayBuffer  = NULL;
  EFI_STATUS Status ;
  SHELL_FILE_HANDLE FileHandle;
  UINTN Index = 0;
  UINTN WbufSize = 0;
  UINTN FileSize = 0;
  UINTN i = 0;
  UINTN StartIndex = 0;
  CHAR8 *Ptr = NULL;
  
  if (Argc <= 1){
    Print(L"Please input file name!\n");
    return (-1);
  }
  OldLogFileName = Argv[1];
  Print(L"The Old file name is %s!\n",OldLogFileName);
  
  EFI_SHELL_PROTOCOL            *gEfiShellProtocol;
  Status = OpenShellProtocol(&gEfiShellProtocol);
  Status = gEfiShellProtocol->OpenFileByName((CONST CHAR16*)OldLogFileName, &FileHandle, EFI_FILE_MODE_READ); 
  if (EFI_ERROR(Status)){
    Print(L"Please Input Valid Filename!\n");
    return (-1);
  }
  StrnCpyS(NewFileName,128,OldLogFileName,StrLen(OldLogFileName)-4);
  StrCatS(NewFileName,128,L"_New.txt");
  Print(L"New FileName is %s\n",NewFileName);
  
  //删除同名的文件
  gEfiShellProtocol->DeleteFileByName(NewFileName);
  
  //获取文件实际大小
  Status = gEfiShellProtocol->GetFileSize(FileHandle,&FileSize);
  if (EFI_ERROR (Status)) {
    gEfiShellProtocol->CloseFile (FileHandle);
    return Status;
  }
  Print (L"File FileSize is %d!\n",FileSize);
  
  if (FileSize < 0){
    Print (L"File cotent is empty!\n");
    return (-1);
  }
  
  FileSize += 1;
  
  //根据文件大小申请对应大小的内存
  Status = gBS -> AllocatePool (EfiReservedMemoryType, FileSize , &ArrayBuffer);
  Status = gBS -> AllocatePool (EfiReservedMemoryType, FileSize , &LineBuff);
  
  BZero(ArrayBuffer,FileSize);
  BZero(LineBuff,FileSize);
  Status = gEfiShellProtocol->ReadFile(FileHandle, &FileSize ,ArrayBuffer); 
  
  if (EFI_ERROR(Status)){
    Print(L"Read Filename Error!\n");
    return (-1);
  }
  
  //创建新的文件句柄
  Status = gEfiShellProtocol->CreateFile((CONST CHAR16*)NewFileName,0 ,&FileHandle); 
  if (EFI_ERROR(Status)){
    Print(L"Create Filename %s Fail!\n",NewFileName);
    return (-1);
  }
  
  //读取的文件内容写入新建文件
  WbufSize = FileSize;
  Status = gEfiShellProtocol->WriteFile(FileHandle,&WbufSize,ArrayBuffer);
  
  //关闭文件句柄
  Status = gEfiShellProtocol->CloseFile(FileHandle);
  
  Ptr = (CHAR8 * )ArrayBuffer;
  for (i = 0 ; i < FileSize ; i ++ ){
    if (Ptr[i] == '\n'){
    Ptr[i] = '\0';  
    Ascii2UnicodeString(Ptr + StartIndex, LineBuff);
    StartIndex = i + 1;
    
    Index += 1;
    //按行输出
    Print(L"Line %d: %S!\n",Index,LineBuff);
    BZero(LineBuff,FileSize);
    }
  }
  
  return (0);
}
二、 编译生成EFI文件

运行edksetup.bat编译整个OvmfPkg Package

三、 运行 UEFI APP MyHelloWorldFileIO.efi
  1. 拷贝 C:\edkii\Build\OvmfX64\DEBUG_VS2013x86\FV\OVMF.fdC:\qemu;拷贝C:\edkii\Build\OvmfX64\DEBUG_VS2013x86\X64\OvmfPkg\MyHelloWorldFileIO\MyHelloWorldFileIO\OUTPUT\MyHelloWorldFileIO.efi 到 虚拟盘HDD_BOOT.img
  2. 执行etup-qemu-x64.bat , 然后在UEFI SHELL 中执行 MyHelloWorldFileIO.efi,结果如下,
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传在这里插入图片描述
四、 小结

文件操作是UEFI中一个比较重要的功能,本文利用EFI_SHELL_PROTOCOL实现对文件的读取,并写入新建文件,然后按行输出到Console.这里需要注意的是,若是读取ASCII文件输出终端需要今日能够ASCII与Unicode转换工作。

FileIO DEMO源码

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值