123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792 |
- /** @file
- Support functions implementation for UEFI HTTP boot driver.
- Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
- (C) Copyright 2016 - 2020 Hewlett Packard Enterprise Development LP<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "HttpBootDxe.h"
- /**
- Get the Nic handle using any child handle in the IPv4 stack.
- @param[in] ControllerHandle Pointer to child handle over IPv4.
- @return NicHandle The pointer to the Nic handle.
- @return NULL Can't find the Nic handle.
- **/
- EFI_HANDLE
- HttpBootGetNicByIp4Children (
- IN EFI_HANDLE ControllerHandle
- )
- {
- EFI_HANDLE NicHandle;
- NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiHttpProtocolGuid);
- if (NicHandle == NULL) {
- NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp4ProtocolGuid);
- if (NicHandle == NULL) {
- return NULL;
- }
- }
- return NicHandle;
- }
- /**
- Get the Nic handle using any child handle in the IPv6 stack.
- @param[in] ControllerHandle Pointer to child handle over IPv6.
- @return NicHandle The pointer to the Nic handle.
- @return NULL Can't find the Nic handle.
- **/
- EFI_HANDLE
- HttpBootGetNicByIp6Children (
- IN EFI_HANDLE ControllerHandle
- )
- {
- EFI_HANDLE NicHandle;
- NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiHttpProtocolGuid);
- if (NicHandle == NULL) {
- NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp6ProtocolGuid);
- if (NicHandle == NULL) {
- return NULL;
- }
- }
- return NicHandle;
- }
- /**
- This function is to convert UINTN to ASCII string with the required formatting.
- @param[in] Number Numeric value to be converted.
- @param[in] Buffer The pointer to the buffer for ASCII string.
- @param[in] Length The length of the required format.
- **/
- VOID
- HttpBootUintnToAscDecWithFormat (
- IN UINTN Number,
- IN UINT8 *Buffer,
- IN INTN Length
- )
- {
- UINTN Remainder;
- for ( ; Length > 0; Length--) {
- Remainder = Number % 10;
- Number /= 10;
- Buffer[Length - 1] = (UINT8)('0' + Remainder);
- }
- }
- /**
- This function is to display the IPv4 address.
- @param[in] Ip The pointer to the IPv4 address.
- **/
- VOID
- HttpBootShowIp4Addr (
- IN EFI_IPv4_ADDRESS *Ip
- )
- {
- UINTN Index;
- for (Index = 0; Index < 4; Index++) {
- AsciiPrint ("%d", Ip->Addr[Index]);
- if (Index < 3) {
- AsciiPrint (".");
- }
- }
- }
- /**
- This function is to display the IPv6 address.
- @param[in] Ip The pointer to the IPv6 address.
- **/
- VOID
- HttpBootShowIp6Addr (
- IN EFI_IPv6_ADDRESS *Ip
- )
- {
- UINTN Index;
- for (Index = 0; Index < 16; Index++) {
- if (Ip->Addr[Index] != 0) {
- AsciiPrint ("%x", Ip->Addr[Index]);
- }
- Index++;
- if (Index > 15) {
- return;
- }
- if (((Ip->Addr[Index] & 0xf0) == 0) && (Ip->Addr[Index - 1] != 0)) {
- AsciiPrint ("0");
- }
- AsciiPrint ("%x", Ip->Addr[Index]);
- if (Index < 15) {
- AsciiPrint (":");
- }
- }
- }
- /**
- This function is to display the HTTP error status.
- @param[in] StatusCode The status code value in HTTP message.
- **/
- VOID
- HttpBootPrintErrorMessage (
- EFI_HTTP_STATUS_CODE StatusCode
- )
- {
- AsciiPrint ("\n");
- switch (StatusCode) {
- case HTTP_STATUS_300_MULTIPLE_CHOICES:
- AsciiPrint ("\n Redirection: 300 Multiple Choices");
- break;
- case HTTP_STATUS_301_MOVED_PERMANENTLY:
- AsciiPrint ("\n Redirection: 301 Moved Permanently");
- break;
- case HTTP_STATUS_302_FOUND:
- AsciiPrint ("\n Redirection: 302 Found");
- break;
- case HTTP_STATUS_303_SEE_OTHER:
- AsciiPrint ("\n Redirection: 303 See Other");
- break;
- case HTTP_STATUS_304_NOT_MODIFIED:
- AsciiPrint ("\n Redirection: 304 Not Modified");
- break;
- case HTTP_STATUS_305_USE_PROXY:
- AsciiPrint ("\n Redirection: 305 Use Proxy");
- break;
- case HTTP_STATUS_307_TEMPORARY_REDIRECT:
- AsciiPrint ("\n Redirection: 307 Temporary Redirect");
- break;
- case HTTP_STATUS_308_PERMANENT_REDIRECT:
- AsciiPrint ("\n Redirection: 308 Permanent Redirect");
- break;
- case HTTP_STATUS_400_BAD_REQUEST:
- AsciiPrint ("\n Client Error: 400 Bad Request");
- break;
- case HTTP_STATUS_401_UNAUTHORIZED:
- AsciiPrint ("\n Client Error: 401 Unauthorized");
- break;
- case HTTP_STATUS_402_PAYMENT_REQUIRED:
- AsciiPrint ("\n Client Error: 402 Payment Required");
- break;
- case HTTP_STATUS_403_FORBIDDEN:
- AsciiPrint ("\n Client Error: 403 Forbidden");
- break;
- case HTTP_STATUS_404_NOT_FOUND:
- AsciiPrint ("\n Client Error: 404 Not Found");
- break;
- case HTTP_STATUS_405_METHOD_NOT_ALLOWED:
- AsciiPrint ("\n Client Error: 405 Method Not Allowed");
- break;
- case HTTP_STATUS_406_NOT_ACCEPTABLE:
- AsciiPrint ("\n Client Error: 406 Not Acceptable");
- break;
- case HTTP_STATUS_407_PROXY_AUTHENTICATION_REQUIRED:
- AsciiPrint ("\n Client Error: 407 Proxy Authentication Required");
- break;
- case HTTP_STATUS_408_REQUEST_TIME_OUT:
- AsciiPrint ("\n Client Error: 408 Request Timeout");
- break;
- case HTTP_STATUS_409_CONFLICT:
- AsciiPrint ("\n Client Error: 409 Conflict");
- break;
- case HTTP_STATUS_410_GONE:
- AsciiPrint ("\n Client Error: 410 Gone");
- break;
- case HTTP_STATUS_411_LENGTH_REQUIRED:
- AsciiPrint ("\n Client Error: 411 Length Required");
- break;
- case HTTP_STATUS_412_PRECONDITION_FAILED:
- AsciiPrint ("\n Client Error: 412 Precondition Failed");
- break;
- case HTTP_STATUS_413_REQUEST_ENTITY_TOO_LARGE:
- AsciiPrint ("\n Client Error: 413 Request Entity Too Large");
- break;
- case HTTP_STATUS_414_REQUEST_URI_TOO_LARGE:
- AsciiPrint ("\n Client Error: 414 Request URI Too Long");
- break;
- case HTTP_STATUS_415_UNSUPPORTED_MEDIA_TYPE:
- AsciiPrint ("\n Client Error: 415 Unsupported Media Type");
- break;
- case HTTP_STATUS_416_REQUESTED_RANGE_NOT_SATISFIED:
- AsciiPrint ("\n Client Error: 416 Requested Range Not Satisfiable");
- break;
- case HTTP_STATUS_417_EXPECTATION_FAILED:
- AsciiPrint ("\n Client Error: 417 Expectation Failed");
- break;
- case HTTP_STATUS_500_INTERNAL_SERVER_ERROR:
- AsciiPrint ("\n Server Error: 500 Internal Server Error");
- break;
- case HTTP_STATUS_501_NOT_IMPLEMENTED:
- AsciiPrint ("\n Server Error: 501 Not Implemented");
- break;
- case HTTP_STATUS_502_BAD_GATEWAY:
- AsciiPrint ("\n Server Error: 502 Bad Gateway");
- break;
- case HTTP_STATUS_503_SERVICE_UNAVAILABLE:
- AsciiPrint ("\n Server Error: 503 Service Unavailable");
- break;
- case HTTP_STATUS_504_GATEWAY_TIME_OUT:
- AsciiPrint ("\n Server Error: 504 Gateway Timeout");
- break;
- case HTTP_STATUS_505_HTTP_VERSION_NOT_SUPPORTED:
- AsciiPrint ("\n Server Error: 505 HTTP Version Not Supported");
- break;
- default:;
- }
- }
- /**
- Notify the callback function when an event is triggered.
- @param[in] Event The triggered event.
- @param[in] Context The opaque parameter to the function.
- **/
- VOID
- EFIAPI
- HttpBootCommonNotify (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
- {
- *((BOOLEAN *)Context) = TRUE;
- }
- /**
- Retrieve the host address using the EFI_DNS6_PROTOCOL.
- @param[in] Private The pointer to the driver's private data.
- @param[in] HostName Pointer to buffer containing hostname.
- @param[out] IpAddress On output, pointer to buffer containing IPv6 address.
- @retval EFI_SUCCESS Operation succeeded.
- @retval EFI_DEVICE_ERROR An unexpected network error occurred.
- @retval Others Other errors as indicated.
- **/
- EFI_STATUS
- HttpBootDns (
- IN HTTP_BOOT_PRIVATE_DATA *Private,
- IN CHAR16 *HostName,
- OUT EFI_IPv6_ADDRESS *IpAddress
- )
- {
- EFI_STATUS Status;
- EFI_DNS6_PROTOCOL *Dns6;
- EFI_DNS6_CONFIG_DATA Dns6ConfigData;
- EFI_DNS6_COMPLETION_TOKEN Token;
- EFI_HANDLE Dns6Handle;
- EFI_IP6_CONFIG_PROTOCOL *Ip6Config;
- EFI_IPv6_ADDRESS *DnsServerList;
- UINTN DnsServerListCount;
- UINTN DataSize;
- BOOLEAN IsDone;
- DnsServerList = NULL;
- DnsServerListCount = 0;
- Dns6 = NULL;
- Dns6Handle = NULL;
- ZeroMem (&Token, sizeof (EFI_DNS6_COMPLETION_TOKEN));
- //
- // Get DNS server list from EFI IPv6 Configuration protocol.
- //
- Status = gBS->HandleProtocol (Private->Controller, &gEfiIp6ConfigProtocolGuid, (VOID **)&Ip6Config);
- if (!EFI_ERROR (Status)) {
- //
- // Get the required size.
- //
- DataSize = 0;
- Status = Ip6Config->GetData (Ip6Config, Ip6ConfigDataTypeDnsServer, &DataSize, NULL);
- if (Status == EFI_BUFFER_TOO_SMALL) {
- DnsServerList = AllocatePool (DataSize);
- if (DnsServerList == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- Status = Ip6Config->GetData (Ip6Config, Ip6ConfigDataTypeDnsServer, &DataSize, DnsServerList);
- if (EFI_ERROR (Status)) {
- FreePool (DnsServerList);
- DnsServerList = NULL;
- } else {
- DnsServerListCount = DataSize / sizeof (EFI_IPv6_ADDRESS);
- }
- }
- }
- //
- // Create a DNSv6 child instance and get the protocol.
- //
- Status = NetLibCreateServiceChild (
- Private->Controller,
- Private->Ip6Nic->ImageHandle,
- &gEfiDns6ServiceBindingProtocolGuid,
- &Dns6Handle
- );
- if (EFI_ERROR (Status)) {
- goto Exit;
- }
- Status = gBS->OpenProtocol (
- Dns6Handle,
- &gEfiDns6ProtocolGuid,
- (VOID **)&Dns6,
- Private->Ip6Nic->ImageHandle,
- Private->Controller,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
- if (EFI_ERROR (Status)) {
- goto Exit;
- }
- //
- // Configure DNS6 instance for the DNS server address and protocol.
- //
- ZeroMem (&Dns6ConfigData, sizeof (EFI_DNS6_CONFIG_DATA));
- Dns6ConfigData.DnsServerCount = (UINT32)DnsServerListCount;
- Dns6ConfigData.DnsServerList = DnsServerList;
- Dns6ConfigData.EnableDnsCache = TRUE;
- Dns6ConfigData.Protocol = EFI_IP_PROTO_UDP;
- IP6_COPY_ADDRESS (&Dns6ConfigData.StationIp, &Private->StationIp.v6);
- Status = Dns6->Configure (
- Dns6,
- &Dns6ConfigData
- );
- if (EFI_ERROR (Status)) {
- goto Exit;
- }
- Token.Status = EFI_NOT_READY;
- IsDone = FALSE;
- //
- // Create event to set the IsDone flag when name resolution is finished.
- //
- Status = gBS->CreateEvent (
- EVT_NOTIFY_SIGNAL,
- TPL_NOTIFY,
- HttpBootCommonNotify,
- &IsDone,
- &Token.Event
- );
- if (EFI_ERROR (Status)) {
- goto Exit;
- }
- //
- // Start asynchronous name resolution.
- //
- Status = Dns6->HostNameToIp (Dns6, HostName, &Token);
- if (EFI_ERROR (Status)) {
- goto Exit;
- }
- while (!IsDone) {
- Dns6->Poll (Dns6);
- }
- //
- // Name resolution is done, check result.
- //
- Status = Token.Status;
- if (!EFI_ERROR (Status)) {
- if (Token.RspData.H2AData == NULL) {
- Status = EFI_DEVICE_ERROR;
- goto Exit;
- }
- if ((Token.RspData.H2AData->IpCount == 0) || (Token.RspData.H2AData->IpList == NULL)) {
- Status = EFI_DEVICE_ERROR;
- goto Exit;
- }
- //
- // We just return the first IPv6 address from DNS protocol.
- //
- IP6_COPY_ADDRESS (IpAddress, Token.RspData.H2AData->IpList);
- Status = EFI_SUCCESS;
- }
- Exit:
- if (Token.Event != NULL) {
- gBS->CloseEvent (Token.Event);
- }
- if (Token.RspData.H2AData != NULL) {
- if (Token.RspData.H2AData->IpList != NULL) {
- FreePool (Token.RspData.H2AData->IpList);
- }
- FreePool (Token.RspData.H2AData);
- }
- if (Dns6 != NULL) {
- Dns6->Configure (Dns6, NULL);
- gBS->CloseProtocol (
- Dns6Handle,
- &gEfiDns6ProtocolGuid,
- Private->Ip6Nic->ImageHandle,
- Private->Controller
- );
- }
- if (Dns6Handle != NULL) {
- NetLibDestroyServiceChild (
- Private->Controller,
- Private->Ip6Nic->ImageHandle,
- &gEfiDns6ServiceBindingProtocolGuid,
- Dns6Handle
- );
- }
- if (DnsServerList != NULL) {
- FreePool (DnsServerList);
- }
- return Status;
- }
- /**
- This function checks the HTTP(S) URI scheme.
- @param[in] Uri The pointer to the URI string.
- @retval EFI_SUCCESS The URI scheme is valid.
- @retval EFI_INVALID_PARAMETER The URI scheme is not HTTP or HTTPS.
- @retval EFI_ACCESS_DENIED HTTP is disabled and the URI is HTTP.
- **/
- EFI_STATUS
- HttpBootCheckUriScheme (
- IN CHAR8 *Uri
- )
- {
- UINTN Index;
- EFI_STATUS Status;
- Status = EFI_SUCCESS;
- //
- // Convert the scheme to all lower case.
- //
- for (Index = 0; Index < AsciiStrLen (Uri); Index++) {
- if (Uri[Index] == ':') {
- break;
- }
- if ((Uri[Index] >= 'A') && (Uri[Index] <= 'Z')) {
- Uri[Index] -= (CHAR8)('A' - 'a');
- }
- }
- //
- // Return EFI_INVALID_PARAMETER if the URI is not HTTP or HTTPS.
- //
- if ((AsciiStrnCmp (Uri, "http://", 7) != 0) && (AsciiStrnCmp (Uri, "https://", 8) != 0)) {
- DEBUG ((DEBUG_ERROR, "HttpBootCheckUriScheme: Invalid Uri.\n"));
- return EFI_INVALID_PARAMETER;
- }
- //
- // HTTP is disabled, return EFI_ACCESS_DENIED if the URI is HTTP.
- //
- if (!PcdGetBool (PcdAllowHttpConnections) && (AsciiStrnCmp (Uri, "http://", 7) == 0)) {
- DEBUG ((DEBUG_ERROR, "HttpBootCheckUriScheme: HTTP is disabled.\n"));
- return EFI_ACCESS_DENIED;
- }
- return Status;
- }
- /**
- Get the URI address string from the input device path.
- Caller need to free the buffer in the UriAddress pointer.
- @param[in] FilePath Pointer to the device path which contains a URI device path node.
- @param[out] UriAddress The URI address string extract from the device path.
- @retval EFI_SUCCESS The URI string is returned.
- @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
- **/
- EFI_STATUS
- HttpBootParseFilePath (
- IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
- OUT CHAR8 **UriAddress
- )
- {
- EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
- URI_DEVICE_PATH *UriDevicePath;
- CHAR8 *Uri;
- UINTN UriStrLength;
- if (FilePath == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- *UriAddress = NULL;
- //
- // Extract the URI address from the FilePath
- //
- TempDevicePath = FilePath;
- while (!IsDevicePathEnd (TempDevicePath)) {
- if ((DevicePathType (TempDevicePath) == MESSAGING_DEVICE_PATH) &&
- (DevicePathSubType (TempDevicePath) == MSG_URI_DP))
- {
- UriDevicePath = (URI_DEVICE_PATH *)TempDevicePath;
- //
- // UEFI Spec doesn't require the URI to be a NULL-terminated string
- // So we allocate a new buffer and always append a '\0' to it.
- //
- UriStrLength = DevicePathNodeLength (UriDevicePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL);
- if (UriStrLength == 0) {
- //
- // return a NULL UriAddress if it's a empty URI device path node.
- //
- break;
- }
- Uri = AllocatePool (UriStrLength + 1);
- if (Uri == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- CopyMem (Uri, UriDevicePath->Uri, DevicePathNodeLength (UriDevicePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL));
- Uri[DevicePathNodeLength (UriDevicePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL)] = '\0';
- *UriAddress = Uri;
- }
- TempDevicePath = NextDevicePathNode (TempDevicePath);
- }
- 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 Unexpected 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
- // "application/vnd.efi-iso" -> CD/DVD Image
- // "application/vnd.efi-img" -> Virtual Disk 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;
- } else if (AsciiStriCmp (Header->FieldValue, HTTP_CONTENT_TYPE_APP_ISO) == 0) {
- *ImageType = ImageTypeVirtualCd;
- return EFI_SUCCESS;
- } else if (AsciiStriCmp (Header->FieldValue, HTTP_CONTENT_TYPE_APP_IMG) == 0) {
- *ImageType = ImageTypeVirtualDisk;
- 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 (AsciiStriCmp (FilePost, ".efi") == 0) {
- *ImageType = ImageTypeEfi;
- } else if (AsciiStriCmp (FilePost, ".iso") == 0) {
- *ImageType = ImageTypeVirtualCd;
- } else if (AsciiStriCmp (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 ((DEBUG_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 ((DEBUG_ERROR, "HTTP Boot: Failed to register RAM Disk - %r\n", Status));
- }
- return Status;
- }
- /**
- Indicate if the HTTP status code indicates a redirection.
- @param[in] StatusCode HTTP status code from server.
- @return TRUE if it's redirection.
- **/
- BOOLEAN
- HttpBootIsHttpRedirectStatusCode (
- IN EFI_HTTP_STATUS_CODE StatusCode
- )
- {
- if ((StatusCode == HTTP_STATUS_301_MOVED_PERMANENTLY) ||
- (StatusCode == HTTP_STATUS_302_FOUND) ||
- (StatusCode == HTTP_STATUS_307_TEMPORARY_REDIRECT) ||
- (StatusCode == HTTP_STATUS_308_PERMANENT_REDIRECT))
- {
- return TRUE;
- }
- return FALSE;
- }
|