uefi创建文件、文件夹导致文件夹中某个文件丢失

    uefi创建文件的时候如果路径中有某一级目录不存在会报错,所以要创建文件夹以满足目录的要求,如果只是创建路径中不存在的目录不会有问题,但是如果写个循环依次创建每一级文件夹,就会创建原来就已经存在的文件夹,这个时候就会出现文件系统解析的问题,可能导致文件丢失

#define PARTITION_HANDLE                       EFI_HANDLE

#define FILE_MODE_READ                         0x0000000000000001ULL
#define FILE_MODE_WRITE                        0x0000000000000002ULL
#define FILE_MODE_CREATE                       0x8000000000000000ULL

//这三个属性对应的值在uefi中有提供

CHAR16* StrChr16(const CHAR16* src,INT16 chr)
{
    CHAR16* tmp = (CHAR16*)src;


    if(NULL == src)
    {
        return NULL;
    }


    while((*tmp != 0) && (*(tmp++) != chr));


    if(*tmp == 0)
    {
        tmp = NULL;
    }
    else
    {
        --tmp;
    }


    return tmp;
}



/**
判断是否能找到指定目录
**/

EFI_BASE_RET
EfiIsDirFound(
  IN PARTITION_HANDLE      Handle,
  IN CHAR16                *Path)
{
    EFI_STATUS                        Status;
    EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Sfs;
    FILE_HANDLE              *Root;
    FILE_HANDLE              *pFile;


    //打开文件系统协议
    Status = gBS->HandleProtocol(
                Handle,
                &gEfiSimpleFileSystemProtocolGuid,
                (VOID**)&Sfs);


    if(EFI_ERROR(Status))
    {
        return EFI_BASE_DEVICE_UNSUPPORTED;
    }
    Status = Sfs->OpenVolume(Sfs, &Root);
    if(EFI_ERROR(Status))
    {
        return EFI_BASE_MEDIA_OPEN_ERROR;
    }


    //打开文件
    Status = Root->Open(Root, &pFile, Path, EFI_FILE_MODE_READ, EFI_FILE_DIRECTORY);
    if( !EFI_ERROR(Status) )
    {
        pFile->Close(pFile);
        return EFI_BASE_SUCCESS;
    }


    if ( EFI_ACCESS_DENIED == Status )
    {
        return EFI_BASE_FILE_ACCESS_DENIED;
    }


    return EFI_BASE_NOT_FOUND;
}


/**
根据分区句柄和文件相对路径获取文件句柄
**/

EFI_BASE_RET EfiOpenFile(
    IN PARTITION_HANDLE Handle,
    IN CHAR16*Path,
    IN UINT64 OpenMode,
    OUT FILE_HANDLE**ppFile )
{
    EFI_STATUS                       Status;
    EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *Sfs;
    FILE_HANDLE                      *Root;
    CHAR16                           TmpPath[260];


    StrCpy(TmpPath, Path);
    //打开文件系统协议
    Status = gBS->HandleProtocol(
                    Handle,
                    &gEfiSimpleFileSystemProtocolGuid,
                    (VOID**)&Sfs);


    if(EFI_ERROR(Status))
    {
        return EFI_BASE_DEVICE_UNSUPPORTED;
    }
    Status = Sfs->OpenVolume(Sfs, &Root);
    if(EFI_ERROR(Status))
    {
        return EFI_BASE_MEDIA_OPEN_ERROR;
    }


    //打开文件夹
    if(0x0 != (OpenMode & FILE_MODE_CREATE))
    {
        CHAR16 *tmp = TmpPath;


        while((L'\\' == *tmp) || (L' ' == *tmp))
        {
            ++tmp;
        }


        while(NULL != (tmp = StrChr16(tmp,L'\\')))
        {
            *tmp = L'\0';


            if(EFI_BASE_SUCCESS != EfiIsDirFound(Handle, TmpPath))
            {
                Status = Root->Open(
                    Root,
                    ppFile,
                    TmpPath,
                    FILE_MODE_READ | FILE_MODE_WRITE | FILE_MODE_CREATE, EFI_FILE_DIRECTORY);


                if (EFI_ERROR(Status))
                {
                    return EFI_BASE_FILE_CREATE_ERROR;
                }


                (*ppFile)->Close(*ppFile);
            }

            *tmp = L'\\';
            ++tmp;
        }
    }


    //打开文件
    Status = Root->Open(Root, ppFile, TmpPath, OpenMode, 0);
    if(!EFI_ERROR(Status))
    {
        return EFI_BASE_SUCCESS;
    }


    return EFI_BASE_FILE_OPEN_ERROR;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值