Пример #1
0
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;
}
Пример #2
0
/*++
 * @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;
}
Пример #3
0
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;
}