EFI_STATUS EFIAPI OvrHandleProtocol( IN EFI_HANDLE Handle, IN EFI_GUID *Protocol, OUT VOID **Interface ) { EFI_STATUS Status; Status = gOrgBS.HandleProtocol(Handle, Protocol, Interface); PRINT("->HandleProtocol(%p, %s, %p) = %r\n", Handle, GuidStr(Protocol), *Interface, Status); return Status; }
/*++ * @name EfiInitCreateInputParametersEx * * The EfiInitCreateInputParametersEx routine converts UEFI entrypoint * parameters to the ones expected by Windows Boot Applications * * @param ImageHandle * UEFI Image Handle for the current loaded application. * * @param SystemTable * Pointer to the UEFI System Table. * * @return A PBOOT_APPLICATION_PARAMETER_BLOCK structure containing the data * from UEFI, translated to the Boot Library-compatible format. * *--*/ PBOOT_APPLICATION_PARAMETER_BLOCK EfiInitCreateInputParametersEx ( _In_ EFI_HANDLE ImageHandle, _In_ EFI_SYSTEM_TABLE *SystemTable ) { EFI_BOOT_SERVICES* BootServices; EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; EFI_DEVICE_PATH_PROTOCOL *DevicePath; PBL_FIRMWARE_DESCRIPTOR FirmwareData; PBL_RETURN_ARGUMENTS ReturnArguments; ULONG FirmwareOffset, ConsumedSize; PBL_DEVICE_DESCRIPTOR AppDevice; EFI_STATUS Status; /* Initialize the header with the signature and version */ EfiInitScratch.Signature[0] = BOOT_APPLICATION_SIGNATURE_1; EfiInitScratch.Signature[1] = BOOT_APPLICATION_SIGNATURE_2; EfiInitScratch.Version = BOOT_APPLICATION_VERSION; /* Set the image type to x86 */ EfiInitScratch.ImageType = EFI_IMAGE_MACHINE_IA32; /* Set the translation type to physical */ EfiInitScratch.MemoryTranslationType = BOOT_MEMORY_TRANSLATION_TYPE_PHYSICAL; /* Indicate that the data was converted from EFI */ BlpApplicationFlags |= BL_APPLICATION_FLAG_CONVERTED_FROM_EFI; /* Grab the loaded image protocol, which has our base and size */ BootServices = SystemTable->BootServices; Status = BootServices->HandleProtocol(ImageHandle, &EfiLoadedImageProtocol, (VOID**)&LoadedImage); if (Status != EFI_SUCCESS) { return NULL; } /* Capture it in the boot application parameters */ EfiInitScratch.ImageBase = (ULONG_PTR)LoadedImage->ImageBase; EfiInitScratch.ImageSize = (ULONG)LoadedImage->ImageSize; /* Now grab our device path protocol, so we can convert the path later on */ Status = BootServices->HandleProtocol(LoadedImage->DeviceHandle, &EfiDevicePathProtocol, (VOID**)&DevicePath); if (Status != EFI_SUCCESS) { return NULL; } /* The built-in boot memory data comes right after our block */ EfiInitScratch.MemoryDataOffset = FIELD_OFFSET(BOOT_APPLICATION_PARAMETER_BLOCK_SCRATCH, BootMemoryData); /* Build the boot memory data structure, with 1 descriptor */ EfiInitScratch.BootMemoryData.Version = BL_MEMORY_DATA_VERSION; EfiInitScratch.BootMemoryData.MdListOffset = FIELD_OFFSET(BOOT_APPLICATION_PARAMETER_BLOCK_SCRATCH, MemEntry) - EfiInitScratch.MemoryDataOffset; EfiInitScratch.BootMemoryData.DescriptorSize = sizeof(BL_MEMORY_DESCRIPTOR); EfiInitScratch.BootMemoryData.DescriptorCount = 1; EfiInitScratch.BootMemoryData.DescriptorOffset = FIELD_OFFSET(BL_MEMORY_DESCRIPTOR, BasePage); /* Build the memory entry descriptor for this image itself */ EfiInitScratch.MemEntry.Flags = BlMemoryWriteBack; EfiInitScratch.MemEntry.Type = BlLoaderMemory; EfiInitScratch.MemEntry.BasePage = EfiInitScratch.ImageBase >> PAGE_SHIFT; EfiInitScratch.MemEntry.PageCount = ALIGN_UP_BY(EfiInitScratch.ImageSize, PAGE_SIZE) >> PAGE_SHIFT; /* The built-in application entry comes right after the memory descriptor*/ EfiInitScratch.AppEntryOffset = FIELD_OFFSET(BOOT_APPLICATION_PARAMETER_BLOCK_SCRATCH, AppEntry); /* Go and build it */ EfiInitpCreateApplicationEntry(SystemTable, (PBL_APPLICATION_ENTRY)&EfiInitScratch.AppEntry, sizeof(EfiInitScratch.AppEntry), DevicePath, LoadedImage->FilePath, LoadedImage->LoadOptions, LoadedImage->LoadOptionsSize, EfiInitScratch.MemEntry.PageCount, &ConsumedSize, &AppDevice); /* Boot device information comes right after the application entry */ EfiInitScratch.BootDeviceOffset = ConsumedSize + EfiInitScratch.AppEntryOffset; /* Check if we have a boot device */ if (AppDevice != NULL) { /* We do -- copy it */ RtlCopyMemory(EfiInitScratch.AppEntry + ConsumedSize, AppDevice, AppDevice->Size); /* Firmware data follows right after the boot device entry */ FirmwareOffset = AppDevice->Size + EfiInitScratch.BootDeviceOffset; } else { /* We do not, so zero out the space where a full boot device structure would fit */ RtlZeroMemory(EfiInitScratch.AppEntry + ConsumedSize, sizeof(BL_DEVICE_DESCRIPTOR)); /* And start the firmware data past that */ FirmwareOffset = EfiInitScratch.BootDeviceOffset + sizeof(BL_DEVICE_DESCRIPTOR); } /* Set the computed firmware data offset */ EfiInitScratch.FirmwareParametersOffset = FirmwareOffset; /* Fill out the firmware data that's there */ FirmwareData = (PVOID)((ULONG_PTR)&EfiInitScratch + EfiInitScratch.FirmwareParametersOffset); FirmwareData->Version = BL_FIRMWARE_DESCRIPTOR_VERSION; FirmwareData->ImageHandle = ImageHandle; FirmwareData->SystemTable = SystemTable; /* Finally, set the return argument offset */ EfiInitScratch.ReturnArgumentsOffset = FirmwareOffset + sizeof(BL_FIRMWARE_DESCRIPTOR); /* And fill out the return argument data */ ReturnArguments = (PVOID)((ULONG_PTR)&EfiInitScratch + EfiInitScratch.ReturnArgumentsOffset); ReturnArguments->Version = BL_RETURN_ARGUMENTS_VERSION; /* We're done, compute the final size and return the block */ EfiInitScratch.Size = EfiInitScratch.ReturnArgumentsOffset + sizeof(BL_RETURN_ARGUMENTS); return (PBOOT_APPLICATION_PARAMETER_BLOCK)&EfiInitScratch; }
EFI_STATUS LoadFile(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE* systab, CHAR16* filename, VOID** dataPtr, UINTN* size, EFI_DEVICE_PATH_PROTOCOL** dev_path) { EFI_GUID LoadedImageProtocolGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; EFI_GUID FileInfoGuid = EFI_FILE_INFO_ID; EFI_GUID FileSystemGuid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; EFI_STATUS res; EFI_BOOT_SERVICES* BS = systab->BootServices; //get image info EFI_LOADED_IMAGE_PROTOCOL* img_proto; res = BS->HandleProtocol(ImageHandle, &LoadedImageProtocolGuid, (void**) &img_proto); if (res) { ErrorPrint(L"Failed to get image protocol. (Error %d)\r\n", res); return EFI_LOAD_ERROR ; } EFI_HANDLE img_device_handle = img_proto->DeviceHandle; //Get filesystem protocol from device EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* fs_proto; res = BS->HandleProtocol(img_device_handle, &FileSystemGuid, (VOID**) &fs_proto); if (res) { ErrorPrint(L"Failed to get file system protocol. (Error %d)\r\n", res); return EFI_LOAD_ERROR ; } //open volume EFI_FILE_PROTOCOL* volume; res = fs_proto->OpenVolume(fs_proto, &volume); if (res) { ErrorPrint(L"Failed to open file volume. (Error %d)\r\n", res); return EFI_LOAD_ERROR ; } //open file EFI_FILE_PROTOCOL* file; res = volume->Open(volume, &file, filename, EFI_FILE_MODE_READ, 0); if (res) { //don't print error here //ErrorPrint(L"Failed to open file '%s'. (Error %d)\r\n", filename, res); return EFI_NOT_FOUND ; } //get file info, two try process EFI_FILE_INFO* file_info = NULL; UINTN file_info_size = 0; res = file->GetInfo(file, &FileInfoGuid, &file_info_size, NULL ); if (res != EFI_BUFFER_TOO_SMALL ) { ErrorPrint(L"Failed to stat file '%s'. (Error %d)\r\n", filename, res); return EFI_NOT_FOUND ; } res = BS->AllocatePool(EfiLoaderData, file_info_size, (void**) &file_info); if (res) { ErrorPrint(L"Failed to allocate file info memory. (Error %d)\r\n", res); return EFI_OUT_OF_RESOURCES ; } res = file->GetInfo(file, &FileInfoGuid, &file_info_size, (void*) file_info); if (res) { BS->FreePool(file_info); ErrorPrint(L"Failed to stat file '%s'. (Error %d)\r\n", filename, res); return EFI_NOT_FOUND ; } if (dev_path != NULL ) { *dev_path = FileDevicePath(img_device_handle, filename); } UINT64 file_size = file_info->FileSize; BS->FreePool(file_info); file_info = NULL; void* data = NULL; res = BS->AllocatePool(EfiLoaderData, file_size, (void**) &data); if (res) { ErrorPrint(L"Failed to allocate file data memory. (Error %d)\r\n", res); return EFI_OUT_OF_RESOURCES ; } //read the file res = file->Read(file, &file_size, (void*) data); if (res) { BS->FreePool(data); ErrorPrint(L"Failed to read file '%s'. (Error %d)\r\n", filename, res); return EFI_NOT_FOUND ; } //close the file file->Close(file); volume->Close(volume); //set the pointer and data size *dataPtr = data; *size = file_size; //return success return EFI_SUCCESS; }