我正在编写一个适用于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的偏移量)?