uefi无法在我的机器卷上创建文件

时间:2015-08-24 10:13:23

标签: filesystems drivers uefi

我正在编写一个适用于efi环境的应用程序(例如,可以从EFI shell运行)。 我的问题是我无法在我的机器卷上创建任何文件。我在WMVare和使用ntfs的真机上测试它,甚至在带有hfs +的mac上测试它(得到驱动程序frim http://efi.akeo.ie/)。我可以阅读所有内容,但是当我尝试编写时,我得到了错误代码8(EFI_WRITE_PROTECTED)。

有没有办法避免这种保护?也许我应该更深入地使用块设备而不是文件系统(不是真的想这样做)?

我的代码。驱动程序加载(我认为它工作正常,仅适用于该情况):

Print(L"\nLoading NTFS Driver... ");
Status = BS->LocateHandleBuffer(ByProtocol, &FileSystemProtocol, NULL, &NumHandles, &Handle);
if (EFI_ERROR(Status)) 
{
    PrintStatusError(Status, L"\n  Failed to list file systems");
    goto exit;
}

for (i = 0; i < NumHandles; i++) 
{
    // Look for our NTFS driver. Note: the path MUST be specified using backslashes!
    DevicePath = FileDevicePath(Handle[i], DriverPath);
    if (DevicePath == NULL)
        continue;

    // Attempt to load the driver. If that fails, it means we weren't on the right partition
    Status = BS->LoadImage(FALSE, ImageHandle, DevicePath, NULL, 0, &DriverHandle);
    SafeFree(DevicePath);
    if (EFI_ERROR(Status))
        continue;

    // Load was a success - attempt to start the driver
    Status = BS->StartImage(DriverHandle, NULL, NULL);
    if (EFI_ERROR(Status)) 
    {
        PrintStatusError(Status, L"\n  Driver did not start");
        goto exit;
    }
    Print(L"LOADED");
    break;
}
SafeFree(Handle);
if (i >= NumHandles) 
{
    Print(L"\n  Failed to locate driver. Please check that '%s' exists on the FAT partition", DriverPath);
    Status = EFI_NOT_FOUND;
    goto exit;
}

文件读/写:

// Now enumerate all disk handles again
Status = BS->LocateHandleBuffer(ByProtocol, &DiskIoProtocol, NULL, &NumHandles, &Handle);
if (EFI_ERROR(Status)) 
{
    PrintStatusError(Status, L"\n  Failed to list disks");
    goto exit;
}

// Go through the partitions and find the NTFS one
for (i = 0; i < NumHandles; i++)
{
    dev_path = DevicePathFromHandle(Handle[i]);
    Print(L"\nVolume [%d]: ", i);

    // Calling ConnectController() on a handle starts all the drivers that can service it
    Status = BS->ConnectController(Handle[i], NULL, NULL, TRUE);
    if (Status == EFI_SUCCESS)
    {
        Print(L"Driver connected! ");
    }

    // Open the the volume
    Status = BS->HandleProtocol(Handle[i], &FileSystemProtocol, (VOID**)&Volume);
    if (EFI_ERROR(Status))
    {
        PrintStatusError(Status, L"\n  Could not find volume");
        continue;
    }

    // Open the root directory
    Root = NULL;
    Status = Volume->OpenVolume(Volume, &Root);
    if ((EFI_ERROR(Status)) || (Root == NULL))
    {
        PrintStatusError(Status, L"\n  Could not open Root directory");
        continue;
    }

    Status = Root->Open(Root, &FileHandle, L"bb.txt", EFI_FILE_MODE_READ, 0);
    Print(L"\n  Read %d", Status);
    if (Status == EFI_SUCCESS)
    {
        UINTN fsize = 5;
        char fdata[5];
        Status = FileHandle->Read(FileHandle, &fsize, fdata);
        fdata[4] = 0;
        Print(L" %d [%x%x%x%x] ", Status, fdata[0], fdata[1], fdata[2], fdata[3]);
        FileHandle->Close(FileHandle);
    }

    Status = Root->Open(Root, &FileHandle, L"aa.txt", EFI_FILE_MODE_CREATE | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, 0);
    Print(L"  Create %d", Status);
    if (Status == EFI_SUCCESS)
    {
        UINTN fsize = 4;
        Status = FileHandle->Write(FileHandle, &fsize, file_content);
        Print(L"    Wr %d", Status);
        Status = FileHandle->Flush(FileHandle);
        Print(L"    Fl %d", Status);
        Status = FileHandle->Close(FileHandle);
        Print(L"    Cl %d", Status);
    }
}

&lt; ----------------经过一番调查------------------------ &GT;

事实证明,我们对机器文件系统唯一能做的就是改变现有的文件内容。似乎这是没有研究的唯一可能的方式。但是,它仍然不容易做到:

我有“EFI_FILE * fileHandle”变量,可以读取我预先创建的文件。如何找到相应的LBA(或DiskIO的偏移量)?

我查看了EFI源(来自AMI bios源),发现在EFI_FILE结构后面放置了隐藏数据:

    typedef struct _FILE_HANDLE_INSTANCE {

    EFI_FILE_PROTOCOL FileHandle;                       // Should be the first entry in the structure
    EFI_STATUS HandleInstanceStatus;
    FILE_HANDLE *pFH;
    UINT64 OpenMode;                            // Open Modes
    UINT64 Position;                            //
    UINT32 CurrentCluster;                      // will point to sector number where the position is pointing currently
    UINT32 CurrentClusterOffset;                        // will point to sector number where the position is pointing currently
    BOOLEAN MEDIA_NOT_VALID;                    // Will be true if for any reason current instances cannot use the volume Eg: Change in Media
    DLINK ViFILink;                             // This link is for the DLIST OpenFIs in the VOLUME_INFO
    } FILE_HANDLE_INSTANCE;

他们就这样操作:

void example_read_inside_efi(EFI_FILE *FileHandle, ...)
{
FILE_HANDLE_INSTANCE    *fhi = (FILE_HANDLE_INSTANCE *)FileHandle;
...

但是当我尝试读取该结构时,这个结构似乎没有正确的字段值(f.e.FILE_HANDLE指针无效)。我不知道接下来该怎么做。没有想法..

所以,问题是:如果我有有效的EFI_FILE指针,我怎样才能找到相应的LBA(或磁盘IO的偏移量)?

0 个答案:

没有答案