mirror of https://github.com/acidanthera/audk.git
NetworkPkg: Add RAM disk boot support to HTTP Boot driver.
This patch updates the HTTP Boot driver to support the download and boot a RAM disk image from HTTP server. The HTTP RAM disk boot is described in section 23.7 "HTTP Boot" in UEFI 2.6. HTTP server could provide either an UEFI image or a RAM disk image for the HTTP boot client to use. The RAM disk image must contain a UEFI compliant file system in it. HTTP boot driver will identify the image type either by the "Content-Type" entity header filed or by the file name extension as below: "application/efi" or *.efi -> EFI Image *.iso -> CD/DVD Image *.img -> Virtual Disk Image Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Fu Siyuan <siyuan.fu@intel.com> Reviewed-by: Ye Ting <ting.ye@intel.com> Reviewed-by: El-Haj-Mahmoud Samer <samer.el-haj-mahmoud@hpe.com>
This commit is contained in:
parent
64ee6ed72a
commit
587d204ccd
|
@ -570,6 +570,7 @@ HttpBootFreeCacheList (
|
|||
@param[out] Buffer The memory buffer to transfer the file to. IF Buffer is NULL,
|
||||
then the size of the requested file is returned in
|
||||
BufferSize.
|
||||
@param[out] ImageType The image type of the downloaded file.
|
||||
|
||||
@retval EFI_SUCCESS Successfully created.
|
||||
@retval Others Failed to create HttpIo.
|
||||
|
@ -580,7 +581,8 @@ HttpBootGetFileFromCache (
|
|||
IN HTTP_BOOT_PRIVATE_DATA *Private,
|
||||
IN CHAR16 *Uri,
|
||||
IN OUT UINTN *BufferSize,
|
||||
OUT UINT8 *Buffer
|
||||
OUT UINT8 *Buffer,
|
||||
OUT HTTP_BOOT_IMAGE_TYPE *ImageType
|
||||
)
|
||||
{
|
||||
LIST_ENTRY *Entry;
|
||||
|
@ -589,7 +591,7 @@ HttpBootGetFileFromCache (
|
|||
HTTP_BOOT_ENTITY_DATA *EntityData;
|
||||
UINTN CopyedSize;
|
||||
|
||||
if (Uri == NULL || BufferSize == 0 || Buffer == NULL) {
|
||||
if (Uri == NULL || BufferSize == 0 || Buffer == NULL || ImageType == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
@ -603,7 +605,12 @@ HttpBootGetFileFromCache (
|
|||
(StrCmp (Uri, Cache->RequestData->Url) == 0))
|
||||
{
|
||||
//
|
||||
// Hit cache, check buffer size.
|
||||
// Hit in cache, record image type.
|
||||
//
|
||||
*ImageType = Cache->ImageType;
|
||||
|
||||
//
|
||||
// Check buffer size.
|
||||
//
|
||||
if (*BufferSize < Cache->EntityLength) {
|
||||
*BufferSize = Cache->EntityLength;
|
||||
|
@ -712,6 +719,7 @@ HttpBootGetBootFileCallback (
|
|||
@param[out] Buffer The memory buffer to transfer the file to. IF Buffer is NULL,
|
||||
then the size of the requested file is returned in
|
||||
BufferSize.
|
||||
@param[out] ImageType The image type of the downloaded file.
|
||||
|
||||
@retval EFI_SUCCESS The file was loaded.
|
||||
@retval EFI_INVALID_PARAMETER BufferSize is NULL or Buffer Size is not NULL but Buffer is NULL.
|
||||
|
@ -727,7 +735,8 @@ HttpBootGetBootFile (
|
|||
IN HTTP_BOOT_PRIVATE_DATA *Private,
|
||||
IN BOOLEAN HeaderOnly,
|
||||
IN OUT UINTN *BufferSize,
|
||||
OUT UINT8 *Buffer
|
||||
OUT UINT8 *Buffer,
|
||||
OUT HTTP_BOOT_IMAGE_TYPE *ImageType
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
@ -750,7 +759,7 @@ HttpBootGetBootFile (
|
|||
ASSERT (Private != NULL);
|
||||
ASSERT (Private->HttpCreated);
|
||||
|
||||
if (BufferSize == NULL) {
|
||||
if (BufferSize == NULL || ImageType == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
@ -767,7 +776,7 @@ HttpBootGetBootFile (
|
|||
}
|
||||
AsciiStrToUnicodeStr (Private->BootFileUri, Url);
|
||||
if (!HeaderOnly) {
|
||||
Status = HttpBootGetFileFromCache (Private, Url, BufferSize, Buffer);
|
||||
Status = HttpBootGetFileFromCache (Private, Url, BufferSize, Buffer, ImageType);
|
||||
if (Status != EFI_NOT_FOUND) {
|
||||
FreePool (Url);
|
||||
return Status;
|
||||
|
@ -788,6 +797,7 @@ HttpBootGetBootFile (
|
|||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ERROR_1;
|
||||
}
|
||||
Cache->ImageType = ImageTypeMax;
|
||||
InitializeListHead (&Cache->EntityDataList);
|
||||
}
|
||||
|
||||
|
@ -918,11 +928,26 @@ HttpBootGetBootFile (
|
|||
goto ERROR_5;
|
||||
}
|
||||
|
||||
//
|
||||
// Check the image type according to server's response.
|
||||
//
|
||||
Status = HttpBootCheckImageType (
|
||||
Private->BootFileUri,
|
||||
Private->BootFileUriParser,
|
||||
ResponseData->HeaderCount,
|
||||
ResponseData->Headers,
|
||||
ImageType
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ERROR_5;
|
||||
}
|
||||
|
||||
//
|
||||
// 3.2 Cache the response header.
|
||||
//
|
||||
if (Cache != NULL) {
|
||||
Cache->ResponseData = ResponseData;
|
||||
Cache->ImageType = *ImageType;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -40,6 +40,7 @@ typedef struct {
|
|||
LIST_ENTRY Link; // Link to the CacheList in driver's private data.
|
||||
EFI_HTTP_REQUEST_DATA *RequestData;
|
||||
HTTP_IO_RESPONSE_DATA *ResponseData; // Not include any message-body data.
|
||||
HTTP_BOOT_IMAGE_TYPE ImageType;
|
||||
UINTN EntityLength;
|
||||
LIST_ENTRY EntityDataList; // Entity data (message-body)
|
||||
} HTTP_BOOT_CACHE_CONTENT;
|
||||
|
@ -105,6 +106,7 @@ HttpBootCreateHttpIo (
|
|||
@param[out] Buffer The memory buffer to transfer the file to. IF Buffer is NULL,
|
||||
then the size of the requested file is returned in
|
||||
BufferSize.
|
||||
@param[out] ImageType The image type of the downloaded file.
|
||||
|
||||
@retval EFI_SUCCESS The file was loaded.
|
||||
@retval EFI_INVALID_PARAMETER BufferSize is NULL or Buffer Size is not NULL but Buffer is NULL.
|
||||
|
@ -120,7 +122,8 @@ HttpBootGetBootFile (
|
|||
IN HTTP_BOOT_PRIVATE_DATA *Private,
|
||||
IN BOOLEAN HeaderOnly,
|
||||
IN OUT UINTN *BufferSize,
|
||||
OUT UINT8 *Buffer
|
||||
OUT UINT8 *Buffer,
|
||||
OUT HTTP_BOOT_IMAGE_TYPE *ImageType
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
|
@ -55,6 +55,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
#include <Protocol/Http.h>
|
||||
#include <Protocol/Ip4Config2.h>
|
||||
#include <Protocol/Ip6Config.h>
|
||||
#include <Protocol/RamDisk.h>
|
||||
//
|
||||
// Produced Protocols
|
||||
//
|
||||
|
@ -70,6 +71,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
//
|
||||
#define HTTP_BOOT_DXE_VERSION 0xa
|
||||
|
||||
//
|
||||
// Provisional Standard Media Types defined in
|
||||
// http://www.iana.org/assignments/provisional-standard-media-types/provisional-standard-media-types.xhtml
|
||||
//
|
||||
#define HTTP_CONTENT_TYPE_APP_EFI "application/efi"
|
||||
|
||||
//
|
||||
// Protocol instances
|
||||
//
|
||||
|
@ -83,6 +90,13 @@ extern EFI_COMPONENT_NAME_PROTOCOL gHttpBootDxeComponentName;
|
|||
typedef struct _HTTP_BOOT_PRIVATE_DATA HTTP_BOOT_PRIVATE_DATA;
|
||||
typedef struct _HTTP_BOOT_VIRTUAL_NIC HTTP_BOOT_VIRTUAL_NIC;
|
||||
|
||||
typedef enum {
|
||||
ImageTypeEfi,
|
||||
ImageTypeVirtualCd,
|
||||
ImageTypeVirtualDisk,
|
||||
ImageTypeMax
|
||||
} HTTP_BOOT_IMAGE_TYPE;
|
||||
|
||||
//
|
||||
// Include files with internal function prototypes
|
||||
//
|
||||
|
@ -166,6 +180,11 @@ struct _HTTP_BOOT_PRIVATE_DATA {
|
|||
EFI_IP_ADDRESS GatewayIp;
|
||||
EFI_IP_ADDRESS ServerIp;
|
||||
UINT16 Port;
|
||||
|
||||
//
|
||||
// The URI string attempt to download through HTTP, may point to
|
||||
// the memory in cached DHCP offer, or to the memory in FilePathUri.
|
||||
//
|
||||
CHAR8 *BootFileUri;
|
||||
VOID *BootFileUriParser;
|
||||
UINTN BootFileSize;
|
||||
|
|
|
@ -81,6 +81,7 @@
|
|||
gEfiIp6ProtocolGuid ## TO_START
|
||||
gEfiIp6ConfigProtocolGuid ## TO_START
|
||||
gEfiNetworkInterfaceIdentifierProtocolGuid_31 ## SOMETIMES_CONSUMES
|
||||
gEfiRamDiskProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEfiHiiConfigAccessProtocolGuid ## BY_START
|
||||
|
||||
[Guids]
|
||||
|
@ -89,6 +90,8 @@
|
|||
## SOMETIMES_PRODUCES ## GUID # HiiGetBrowserData mHttpBootConfigStorageName
|
||||
## SOMETIMES_CONSUMES ## HII
|
||||
gHttpBootConfigGuid
|
||||
gEfiVirtualCdGuid ## SOMETIMES_CONSUMES ## GUID
|
||||
gEfiVirtualDiskGuid ## SOMETIMES_CONSUMES ## GUID
|
||||
|
||||
[UserExtensions.TianoCore."ExtraFiles"]
|
||||
HttpBootDxeExtra.uni
|
||||
|
|
|
@ -17,6 +17,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
/**
|
||||
Enable the use of UEFI HTTP boot function.
|
||||
|
||||
If the driver has already been started but not satisfy the requirement (IP stack and
|
||||
specified boot file path), this function will stop the driver and start it again.
|
||||
|
||||
@param[in] Private The pointer to the driver's private data.
|
||||
@param[in] UsingIpv6 Specifies the type of IP addresses that are to be
|
||||
used during the session that is being started.
|
||||
|
@ -24,7 +27,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
@param[in] FilePath The device specific path of the file to load.
|
||||
|
||||
@retval EFI_SUCCESS HTTP boot was successfully enabled.
|
||||
@retval EFI_INVALID_PARAMETER Private is NULL.
|
||||
@retval EFI_INVALID_PARAMETER Private is NULL or FilePath is NULL.
|
||||
@retval EFI_INVALID_PARAMETER The FilePath doesn't contain a valid URI device path node.
|
||||
@retval EFI_ALREADY_STARTED The driver is already in started state.
|
||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources.
|
||||
|
||||
|
@ -38,13 +42,50 @@ HttpBootStart (
|
|||
{
|
||||
UINTN Index;
|
||||
EFI_STATUS Status;
|
||||
CHAR8 *Uri;
|
||||
|
||||
|
||||
if (Private == NULL || FilePath == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Check the URI in the input FilePath, in order to see whether it is
|
||||
// required to boot from a new specified boot file.
|
||||
//
|
||||
Status = HttpBootParseFilePath (FilePath, &Uri);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Check whether we need to stop and restart the HTTP boot driver.
|
||||
//
|
||||
if (Private->Started) {
|
||||
return EFI_ALREADY_STARTED;
|
||||
//
|
||||
// Restart is needed in 2 cases:
|
||||
// 1. Http boot driver has already been started but not on the required IP stack.
|
||||
// 2. The specified boot file URI in FilePath is different with the one we have
|
||||
// recorded before.
|
||||
//
|
||||
if ((UsingIpv6 != Private->UsingIpv6) ||
|
||||
((Uri != NULL) && (AsciiStrCmp (Private->BootFileUri, Uri) != 0))) {
|
||||
//
|
||||
// Restart is required, first stop then continue this start function.
|
||||
//
|
||||
Status = HttpBootStop (Private);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// Restart is not required.
|
||||
//
|
||||
if (Uri != NULL) {
|
||||
FreePool (Uri);
|
||||
}
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -55,17 +96,16 @@ HttpBootStart (
|
|||
} else if (!UsingIpv6 && Private->Ip4Nic != NULL) {
|
||||
Private->UsingIpv6 = FALSE;
|
||||
} else {
|
||||
if (Uri != NULL) {
|
||||
FreePool (Uri);
|
||||
}
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Check whether the URI address is specified.
|
||||
// Record the specified URI and prepare the URI parser if needed.
|
||||
//
|
||||
Status = HttpBootParseFilePath (FilePath, &Private->FilePathUri);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Private->FilePathUri = Uri;
|
||||
if (Private->FilePathUri != NULL) {
|
||||
Status = HttpParseUrl (
|
||||
Private->FilePathUri,
|
||||
|
@ -74,6 +114,7 @@ HttpBootStart (
|
|||
&Private->FilePathUriParser
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
FreePool (Private->FilePathUri);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
@ -101,7 +142,7 @@ HttpBootStart (
|
|||
return Status;
|
||||
}
|
||||
}
|
||||
Private->Started = TRUE;
|
||||
Private->Started = TRUE;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
@ -161,9 +202,11 @@ HttpBootDhcp (
|
|||
@param[in] Buffer The memory buffer to transfer the file to. If Buffer is NULL,
|
||||
then the size of the requested file is returned in
|
||||
BufferSize.
|
||||
@param[out] ImageType The image type of the downloaded file.
|
||||
|
||||
@retval EFI_SUCCESS Boot file was loaded successfully.
|
||||
@retval EFI_INVALID_PARAMETER Private is NULL.
|
||||
@retval EFI_INVALID_PARAMETER Private is NULL, or ImageType is NULL, or BufferSize is NULL.
|
||||
@retval EFI_INVALID_PARAMETER *BufferSize is not zero, and Buffer is NULL.
|
||||
@retval EFI_NOT_STARTED The driver is in stopped state.
|
||||
@retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the boot file. BufferSize has
|
||||
been updated with the size needed to complete the request.
|
||||
|
@ -175,12 +218,17 @@ EFI_STATUS
|
|||
HttpBootLoadFile (
|
||||
IN HTTP_BOOT_PRIVATE_DATA *Private,
|
||||
IN OUT UINTN *BufferSize,
|
||||
IN VOID *Buffer OPTIONAL
|
||||
IN VOID *Buffer, OPTIONAL
|
||||
OUT HTTP_BOOT_IMAGE_TYPE *ImageType
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (Private == NULL) {
|
||||
if (Private == NULL || ImageType == NULL || BufferSize == NULL ) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (*BufferSize != 0 && Buffer == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
@ -222,7 +270,8 @@ HttpBootLoadFile (
|
|||
Private,
|
||||
TRUE,
|
||||
&Private->BootFileSize,
|
||||
NULL
|
||||
NULL,
|
||||
ImageType
|
||||
);
|
||||
if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
|
||||
//
|
||||
|
@ -233,7 +282,8 @@ HttpBootLoadFile (
|
|||
Private,
|
||||
FALSE,
|
||||
&Private->BootFileSize,
|
||||
NULL
|
||||
NULL,
|
||||
ImageType
|
||||
);
|
||||
if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
|
||||
return Status;
|
||||
|
@ -253,7 +303,8 @@ HttpBootLoadFile (
|
|||
Private,
|
||||
FALSE,
|
||||
BufferSize,
|
||||
Buffer
|
||||
Buffer,
|
||||
ImageType
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -388,6 +439,7 @@ HttpBootDxeLoadFile (
|
|||
BOOLEAN MediaPresent;
|
||||
BOOLEAN UsingIpv6;
|
||||
EFI_STATUS Status;
|
||||
HTTP_BOOT_IMAGE_TYPE ImageType;
|
||||
|
||||
if (This == NULL || BufferSize == NULL || FilePath == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
@ -424,46 +476,34 @@ HttpBootDxeLoadFile (
|
|||
// Initialize HTTP boot.
|
||||
//
|
||||
Status = HttpBootStart (Private, UsingIpv6, FilePath);
|
||||
if (Status == EFI_ALREADY_STARTED) {
|
||||
//
|
||||
// Restart the HTTP boot driver in 2 cases:
|
||||
// 1. Http boot Driver has already been started but not on the required IP version.
|
||||
// 2. The required boot FilePath is different with the one we produced in the device path
|
||||
// protocol.
|
||||
//
|
||||
if ((UsingIpv6 != Private->UsingIpv6) || ((Private->FilePathUri != NULL) && (AsciiStrCmp (Private->BootFileUri, Private->FilePathUri) != 0))) {
|
||||
Status = HttpBootStop (Private);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = HttpBootStart (Private, UsingIpv6, FilePath);
|
||||
}
|
||||
}
|
||||
if (Status != EFI_SUCCESS && Status != EFI_ALREADY_STARTED) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Load the boot file.
|
||||
//
|
||||
if (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED) {
|
||||
Status = HttpBootLoadFile (Private, BufferSize, Buffer);
|
||||
ImageType = ImageTypeMax;
|
||||
Status = HttpBootLoadFile (Private, BufferSize, Buffer, &ImageType);
|
||||
if (EFI_ERROR (Status)) {
|
||||
if (Status == EFI_BUFFER_TOO_SMALL && (ImageType == ImageTypeVirtualCd || ImageType == ImageTypeVirtualDisk)) {
|
||||
Status = EFI_WARN_FILE_SYSTEM;
|
||||
} else if (Status != EFI_BUFFER_TOO_SMALL) {
|
||||
HttpBootStop (Private);
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (Status != EFI_SUCCESS && Status != EFI_BUFFER_TOO_SMALL) {
|
||||
HttpBootStop (Private);
|
||||
} else {
|
||||
if (!Private->UsingIpv6) {
|
||||
//
|
||||
// Stop and release the DHCP4 child.
|
||||
//
|
||||
Private->Dhcp4->Stop (Private->Dhcp4);
|
||||
Private->Dhcp4->Configure (Private->Dhcp4, NULL);
|
||||
} else {
|
||||
//
|
||||
// Stop and release the DHCP6 child.
|
||||
//
|
||||
Private->Dhcp6->Stop (Private->Dhcp6);
|
||||
Private->Dhcp6->Configure (Private->Dhcp6, NULL);
|
||||
//
|
||||
// Register the RAM Disk to the system if needed.
|
||||
//
|
||||
if (ImageType == ImageTypeVirtualCd || ImageType == ImageTypeVirtualDisk) {
|
||||
Status = HttpBootRegisterRamDisk (Private, *BufferSize, Buffer, ImageType);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = EFI_WARN_FILE_SYSTEM;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
|
|
@ -1007,3 +1007,145 @@ HttpBootParseFilePath (
|
|||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This function returns the image type according to server replied HTTP message
|
||||
and also the image's URI info.
|
||||
|
||||
@param[in] Uri The pointer to the image's URI string.
|
||||
@param[in] UriParser URI Parse result returned by NetHttpParseUrl().
|
||||
@param[in] HeaderCount Number of HTTP header structures in Headers list.
|
||||
@param[in] Headers Array containing list of HTTP headers.
|
||||
@param[out] ImageType The image type of the downloaded file.
|
||||
|
||||
@retval EFI_SUCCESS The image type is returned in ImageType.
|
||||
@retval EFI_INVALID_PARAMETER ImageType, Uri or UriParser is NULL.
|
||||
@retval EFI_INVALID_PARAMETER HeaderCount is not zero, and Headers is NULL.
|
||||
@retval EFI_NOT_FOUND Failed to identify the image type.
|
||||
@retval Others Unexpect error happened.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpBootCheckImageType (
|
||||
IN CHAR8 *Uri,
|
||||
IN VOID *UriParser,
|
||||
IN UINTN HeaderCount,
|
||||
IN EFI_HTTP_HEADER *Headers,
|
||||
OUT HTTP_BOOT_IMAGE_TYPE *ImageType
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HTTP_HEADER *Header;
|
||||
CHAR8 *FilePath;
|
||||
CHAR8 *FilePost;
|
||||
|
||||
if (Uri == NULL || UriParser == NULL || ImageType == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (HeaderCount != 0 && Headers == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Determine the image type by the HTTP Content-Type header field first.
|
||||
// "application/efi" -> EFI Image
|
||||
//
|
||||
Header = HttpFindHeader (HeaderCount, Headers, HTTP_HEADER_CONTENT_TYPE);
|
||||
if (Header != NULL) {
|
||||
if (AsciiStriCmp (Header->FieldValue, HTTP_CONTENT_TYPE_APP_EFI) == 0) {
|
||||
*ImageType = ImageTypeEfi;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Determine the image type by file extension:
|
||||
// *.efi -> EFI Image
|
||||
// *.iso -> CD/DVD Image
|
||||
// *.img -> Virtual Disk Image
|
||||
//
|
||||
Status = HttpUrlGetPath (
|
||||
Uri,
|
||||
UriParser,
|
||||
&FilePath
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
FilePost = FilePath + AsciiStrLen (FilePath) - 4;
|
||||
if (AsciiStrCmp (FilePost, ".efi") == 0) {
|
||||
*ImageType = ImageTypeEfi;
|
||||
} else if (AsciiStrCmp (FilePost, ".iso") == 0) {
|
||||
*ImageType = ImageTypeVirtualCd;
|
||||
} else if (AsciiStrCmp (FilePost, ".img") == 0) {
|
||||
*ImageType = ImageTypeVirtualDisk;
|
||||
} else {
|
||||
*ImageType = ImageTypeMax;
|
||||
}
|
||||
|
||||
FreePool (FilePath);
|
||||
|
||||
return (*ImageType < ImageTypeMax) ? EFI_SUCCESS : EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
This function register the RAM disk info to the system.
|
||||
|
||||
@param[in] Private The pointer to the driver's private data.
|
||||
@param[in] BufferSize The size of Buffer in bytes.
|
||||
@param[in] Buffer The base address of the RAM disk.
|
||||
@param[in] ImageType The image type of the file in Buffer.
|
||||
|
||||
@retval EFI_SUCCESS The RAM disk has been registered.
|
||||
@retval EFI_NOT_FOUND No RAM disk protocol instances were found.
|
||||
@retval EFI_UNSUPPORTED The ImageType is not supported.
|
||||
@retval Others Unexpected error happened.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpBootRegisterRamDisk (
|
||||
IN HTTP_BOOT_PRIVATE_DATA *Private,
|
||||
IN UINTN BufferSize,
|
||||
IN VOID *Buffer,
|
||||
IN HTTP_BOOT_IMAGE_TYPE ImageType
|
||||
)
|
||||
{
|
||||
EFI_RAM_DISK_PROTOCOL *RamDisk;
|
||||
EFI_STATUS Status;
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||
EFI_GUID *RamDiskType;
|
||||
|
||||
ASSERT (Private != NULL);
|
||||
ASSERT (Buffer != NULL);
|
||||
ASSERT (BufferSize != 0);
|
||||
|
||||
Status = gBS->LocateProtocol (&gEfiRamDiskProtocolGuid, NULL, (VOID**) &RamDisk);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_ERROR, "HTTP Boot: Couldn't find the RAM Disk protocol - %r\n", Status));
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (ImageType == ImageTypeVirtualCd) {
|
||||
RamDiskType = &gEfiVirtualCdGuid;
|
||||
} else if (ImageType == ImageTypeVirtualDisk) {
|
||||
RamDiskType = &gEfiVirtualDiskGuid;
|
||||
} else {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Status = RamDisk->Register (
|
||||
(UINTN)Buffer,
|
||||
(UINT64)BufferSize,
|
||||
RamDiskType,
|
||||
Private->UsingIpv6 ? Private->Ip6Nic->DevicePath : Private->Ip4Nic->DevicePath,
|
||||
&DevicePath
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_ERROR, "HTTP Boot: Failed to register RAM Disk - %r\n", Status));
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
|
|
@ -347,4 +347,51 @@ HttpBootParseFilePath (
|
|||
OUT CHAR8 **UriAddress
|
||||
);
|
||||
|
||||
/**
|
||||
This function returns the image type according to server replied HTTP message
|
||||
and also the image's URI info.
|
||||
|
||||
@param[in] Uri The pointer to the image's URI string.
|
||||
@param[in] UriParser URI Parse result returned by NetHttpParseUrl().
|
||||
@param[in] HeaderCount Number of HTTP header structures in Headers list.
|
||||
@param[in] Headers Array containing list of HTTP headers.
|
||||
@param[out] ImageType The image type of the downloaded file.
|
||||
|
||||
@retval EFI_SUCCESS The image type is returned in ImageType.
|
||||
@retval EFI_INVALID_PARAMETER ImageType, Uri or UriParser is NULL.
|
||||
@retval EFI_INVALID_PARAMETER HeaderCount is not zero, and Headers is NULL.
|
||||
@retval EFI_NOT_FOUND Failed to identify the image type.
|
||||
@retval Others Unexpect error happened.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpBootCheckImageType (
|
||||
IN CHAR8 *Uri,
|
||||
IN VOID *UriParser,
|
||||
IN UINTN HeaderCount,
|
||||
IN EFI_HTTP_HEADER *Headers,
|
||||
OUT HTTP_BOOT_IMAGE_TYPE *ImageType
|
||||
);
|
||||
|
||||
/**
|
||||
This function register the RAM disk info to the system.
|
||||
|
||||
@param[in] Private The pointer to the driver's private data.
|
||||
@param[in] BufferSize The size of Buffer in bytes.
|
||||
@param[in] Buffer The base address of the RAM disk.
|
||||
@param[in] ImageType The image type of the file in Buffer.
|
||||
|
||||
@retval EFI_SUCCESS The RAM disk has been registered.
|
||||
@retval EFI_NOT_FOUND No RAM disk protocol instances were found.
|
||||
@retval EFI_UNSUPPORTED The ImageType is not supported.
|
||||
@retval Others Unexpected error happened.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpBootRegisterRamDisk (
|
||||
IN HTTP_BOOT_PRIVATE_DATA *Private,
|
||||
IN UINTN BufferSize,
|
||||
IN VOID *Buffer,
|
||||
IN HTTP_BOOT_IMAGE_TYPE ImageType
|
||||
);
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue