В итоге реализовал следующую функцию загрузки файла:
Код:
if (efiSysTable->BootServices->OpenProtocol(efiImageHandle, &loadedImageProtocol, (void**)&efiLoadedImage,
efiImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL) != EFI_SUCCESS) {
fatalError("failed to get LoadedImageProtocol");
}
if (efiSysTable->BootServices->OpenProtocol(efiLoadedImage->DeviceHandle, &simpleFileSystemProtocol, (void**)&efiFileIoInterface,
efiImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL) != EFI_SUCCESS) {
fatalError("failed to get SimpleFileSystemProtocol");
}
if (efiFileIoInterface->OpenVolume(efiFileIoInterface, &efiFileSystem) != EFI_SUCCESS) {
fatalError("failed to get FileProtocol");
}
...
int platform_loadFile(const char *fileName, void *buffer, int bufferSize) {
CHAR16 *fileNameUTF16 = makeUTF16(fileName);
if (fileNameUTF16 == NULL) return -1;
for (CHAR16 *chr = fileNameUTF16; *chr; chr++) {
if (*chr == '/') {
*chr = '\\';
}
}
EFI_FILE_HANDLE file;
int count = -1;
if (efiFileSystem->Open(efiFileSystem, &file, fileNameUTF16, EFI_FILE_MODE_READ, 0) == EFI_SUCCESS) {
UINTN infoSize = 0;
if (file->GetInfo(file, &fileInfoId, &infoSize, NULL) == EFI_BUFFER_TOO_SMALL) {
EFI_FILE_INFO *info = malloc(infoSize);
if (file->GetInfo(file, &fileInfoId, &infoSize, info) == EFI_SUCCESS) {
if (buffer && bufferSize) {
UINTN cnt = bufferSize;
if (file->Read(file, &cnt, buffer) == EFI_SUCCESS) {
count = cnt;
}
} else {
count = info->FileSize;
}
} else
free(info);
} else
file->Close(file);
}
free(fileNameUTF16);
return count;
}
Если не указывать буфер для загрузки, то можно узнать размер файла, затем выделить под него место и прочитать данные. Мне этого в принципе достаточно - гружу файл целиком, а потом в ОЗУ разбираюсь уже что загрузил.