/** @file\r
Helper functions for configuring or getting the parameters relating to HTTP Boot.\r
\r
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include "HttpBootDxe.h"\r
+#include <Library/UefiBootManagerLib.h>\r
\r
CHAR16 mHttpBootConfigStorageName[] = L"HTTP_BOOT_CONFIG_IFR_NVDATA";\r
\r
@param[in] UsingIpv6 Set to TRUE if creating boot option for IPv6.\r
@param[in] Description The description text of the boot option.\r
@param[in] Uri The URI string of the boot file.\r
- \r
+\r
@retval EFI_SUCCESS The boot option is created successfully.\r
@retval Others Failed to create new boot option.\r
\r
IN CHAR16 *Uri\r
)\r
{\r
- EFI_DEV_PATH *Node;\r
- EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;\r
- EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;\r
- UINTN Length;\r
- CHAR8 AsciiUri[URI_STR_MAX_SIZE];\r
- CHAR16 *CurrentOrder;\r
- EFI_STATUS Status;\r
- UINTN OrderCount;\r
- UINTN TargetLocation;\r
- BOOLEAN Found;\r
- UINT8 *TempByteBuffer;\r
- UINT8 *TempByteStart;\r
- UINTN DescSize;\r
- UINTN FilePathSize;\r
- CHAR16 OptionStr[10];\r
- UINT16 *NewOrder;\r
- UINTN Index;\r
-\r
- NewOrder = NULL;\r
- TempByteStart = NULL;\r
+ EFI_DEV_PATH *Node;\r
+ EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;\r
+ UINTN Length;\r
+ CHAR8 AsciiUri[URI_STR_MAX_SIZE];\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ EFI_BOOT_MANAGER_LOAD_OPTION NewOption;\r
+\r
NewDevicePath = NULL;\r
- NewOrder = NULL;\r
Node = NULL;\r
TmpDevicePath = NULL;\r
- CurrentOrder = NULL;\r
\r
if (StrLen (Description) == 0) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
//\r
- // Only accept http and https URI.\r
+ // Only accept empty URI, or http and https URI.\r
//\r
- if ((StrnCmp (Uri, L"http://", 7) != 0) && (StrnCmp (Uri, L"https://", 7) != 0)) {\r
+ if ((StrLen (Uri) != 0) && (StrnCmp (Uri, L"http://", 7) != 0) && (StrnCmp (Uri, L"https://", 8) != 0)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
- \r
+\r
//\r
// Create a new device path by appending the IP node and URI node to\r
// the driver's parent device path\r
//\r
// Update the URI node with the input boot file URI.\r
//\r
- UnicodeStrToAsciiStr (Uri, AsciiUri);\r
+ UnicodeStrToAsciiStrS (Uri, AsciiUri, sizeof (AsciiUri));\r
Length = sizeof (EFI_DEVICE_PATH_PROTOCOL) + AsciiStrSize (AsciiUri);\r
Node = AllocatePool (Length);\r
if (Node == NULL) {\r
}\r
\r
//\r
- // Get current "BootOrder" variable and find a free target.\r
- //\r
- Length = 0;\r
- Status = GetVariable2 (\r
- L"BootOrder",\r
- &gEfiGlobalVariableGuid,\r
- (VOID **)&CurrentOrder,\r
- &Length \r
- );\r
- if (EFI_ERROR (Status) && Status != EFI_NOT_FOUND) {\r
- goto ON_EXIT;\r
- }\r
- OrderCount = Length / sizeof (UINT16);\r
- Found = FALSE;\r
- for (TargetLocation=0; TargetLocation < 0xFFFF; TargetLocation++) {\r
- Found = TRUE;\r
- for (Index = 0; Index < OrderCount; Index++) {\r
- if (CurrentOrder[Index] == TargetLocation) {\r
- Found = FALSE;\r
- break;\r
- }\r
- }\r
- if (Found) {\r
- break;\r
- }\r
- }\r
-\r
- if (TargetLocation == 0xFFFF) {\r
- DEBUG ((EFI_D_ERROR, "Could not find unused target index.\n"));\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto ON_EXIT;\r
- } else {\r
- DEBUG ((EFI_D_INFO, "TargetIndex = %04x.\n", TargetLocation));\r
- }\r
- \r
+ // Add a new load option.\r
//\r
- // Construct and set the "Boot####" variable\r
- //\r
- DescSize = StrSize(Description);\r
- FilePathSize = GetDevicePathSize (NewDevicePath);\r
- TempByteBuffer = AllocateZeroPool(sizeof(EFI_LOAD_OPTION) + DescSize + FilePathSize);\r
- if (TempByteBuffer == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto ON_EXIT;\r
- }\r
-\r
- TempByteStart = TempByteBuffer;\r
- *((UINT32 *) TempByteBuffer) = LOAD_OPTION_ACTIVE; // Attributes\r
- TempByteBuffer += sizeof (UINT32);\r
-\r
- *((UINT16 *) TempByteBuffer) = (UINT16)FilePathSize; // FilePathListLength\r
- TempByteBuffer += sizeof (UINT16);\r
-\r
- CopyMem (TempByteBuffer, Description, DescSize);\r
- TempByteBuffer += DescSize;\r
- CopyMem (TempByteBuffer, NewDevicePath, FilePathSize);\r
-\r
- UnicodeSPrint (OptionStr, sizeof(OptionStr), L"%s%04x", L"Boot", TargetLocation);\r
- Status = gRT->SetVariable (\r
- OptionStr,\r
- &gEfiGlobalVariableGuid,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
- sizeof(UINT32) + sizeof(UINT16) + DescSize + FilePathSize,\r
- TempByteStart\r
- );\r
+ Status = EfiBootManagerInitializeLoadOption (\r
+ &NewOption,\r
+ LoadOptionNumberUnassigned,\r
+ LoadOptionTypeBoot,\r
+ LOAD_OPTION_ACTIVE,\r
+ Description,\r
+ NewDevicePath,\r
+ NULL,\r
+ 0\r
+ );\r
if (EFI_ERROR (Status)) {\r
goto ON_EXIT;\r
}\r
\r
- //\r
- // Insert into the order list and set "BootOrder" variable\r
- //\r
- NewOrder = AllocateZeroPool ((OrderCount + 1) * sizeof (UINT16));\r
- if (NewOrder == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto ON_EXIT;\r
- }\r
- CopyMem(NewOrder, CurrentOrder, OrderCount * sizeof(UINT16));\r
- NewOrder[OrderCount] = (UINT16) TargetLocation;\r
- Status = gRT->SetVariable (\r
- L"BootOrder",\r
- &gEfiGlobalVariableGuid,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
- ((OrderCount + 1) * sizeof (UINT16)),\r
- NewOrder\r
- );\r
- \r
+ Status = EfiBootManagerAddLoadOptionVariable (&NewOption, (UINTN) -1);\r
+ EfiBootManagerFreeLoadOption (&NewOption);\r
\r
ON_EXIT:\r
\r
- if (CurrentOrder != NULL) {\r
- FreePool (CurrentOrder);\r
- }\r
- if (NewOrder != NULL) {\r
- FreePool (NewOrder);\r
- }\r
- if (TempByteStart != NULL) {\r
- FreePool (TempByteStart);\r
- }\r
if (NewDevicePath != NULL) {\r
FreePool (NewDevicePath);\r
}\r
}\r
\r
/**\r
- \r
+\r
This function allows the caller to request the current\r
configuration for one or more named elements. The resulting\r
string is in <ConfigAltResp> format. Also, any and all alternative\r
to the most recent "&" before the first\r
failing name / value pair (or the beginning\r
of the string if the failure is in the first\r
- name / value pair) if the request was not successful. \r
+ name / value pair) if the request was not successful.\r
\r
@param[out] Results A null-terminated Unicode string in\r
<ConfigAltResp> format which has all values\r
would result in this type of\r
error. In this case, the\r
Progress parameter would be\r
- set to NULL. \r
+ set to NULL.\r
\r
@retval EFI_NOT_FOUND Routing data doesn't match any\r
known driver. Progress set to the\r
if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gHttpBootConfigGuid, mHttpBootConfigStorageName)) {\r
return EFI_NOT_FOUND;\r
}\r
- \r
+\r
ConfigRequestHdr = NULL;\r
ConfigRequest = NULL;\r
AllocatedRequest = FALSE;\r
ConfigRequestHdr = HiiConstructConfigHdr (&gHttpBootConfigGuid, mHttpBootConfigStorageName, CallbackInfo->ChildHandle);\r
Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
ConfigRequest = AllocateZeroPool (Size);\r
- ASSERT (ConfigRequest != NULL);\r
+ if (ConfigRequest == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
AllocatedRequest = TRUE;\r
UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
FreePool (ConfigRequestHdr);\r
Results,\r
Progress\r
);\r
- \r
+\r
//\r
// Free the allocated config request string.\r
//\r
}\r
\r
/**\r
- \r
+\r
This function applies changes in a driver's configuration.\r
Input is a Configuration, which has the routing data for this\r
driver followed by name / value configuration pairs. The driver\r
@param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
\r
@param[in] Configuration A null-terminated Unicode string in\r
- <ConfigString> format. \r
- \r
+ <ConfigString> format.\r
+\r
@param[out] Progress A pointer to a string filled in with the\r
offset of the most recent '&' before the\r
first failing name / value pair (or the\r
\r
@retval EFI_SUCCESS The results have been distributed or are\r
awaiting distribution.\r
- \r
+\r
@retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
parts of the results that must be\r
stored awaiting possible future\r
protocols.\r
- \r
+\r
@retval EFI_INVALID_PARAMETERS Passing in a NULL for the\r
Results parameter would result\r
in this type of error.\r
- \r
+\r
@retval EFI_NOT_FOUND Target for the specified routing data\r
was not found.\r
\r
\r
CallbackInfo = HTTP_BOOT_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);\r
Private = HTTP_BOOT_PRIVATE_DATA_FROM_CALLBACK_INFO (CallbackInfo);\r
- \r
+\r
BufferSize = sizeof (HTTP_BOOT_CONFIG_IFR_NVDATA);\r
ZeroMem (&CallbackInfo->HttpBootNvData, BufferSize);\r
\r
CallbackInfo->HttpBootNvData.Description,\r
CallbackInfo->HttpBootNvData.Uri\r
);\r
- \r
+\r
return EFI_SUCCESS;\r
}\r
\r
/**\r
- \r
+\r
This function is called to provide results data to the driver.\r
This data consists of a unique key that is used to identify\r
which data is either being passed back or being asked for.\r
@param[in] Action Specifies the type of action taken by the browser.\r
@param[in] QuestionId A unique value which is sent to the original\r
exporting driver so that it can identify the type\r
- of data to expect. The format of the data tends to \r
+ of data to expect. The format of the data tends to\r
vary based on the opcode that generated the callback.\r
@param[in] Type The type of value for the question.\r
@param[in, out] Value A pointer to the data being sent to the original\r
)\r
{\r
EFI_INPUT_KEY Key;\r
- UINTN Index;\r
CHAR16 *Uri;\r
+ UINTN UriLen;\r
+ CHAR8 *AsciiUri;\r
HTTP_BOOT_FORM_CALLBACK_INFO *CallbackInfo;\r
- \r
+ EFI_STATUS Status;\r
+\r
+ Uri = NULL;\r
+ UriLen = 0;\r
+ AsciiUri = NULL;\r
+ Status = EFI_SUCCESS;\r
+\r
if (This == NULL || Value == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
CallbackInfo = HTTP_BOOT_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);\r
- \r
+\r
if (Action != EFI_BROWSER_ACTION_CHANGING) {\r
return EFI_UNSUPPORTED;\r
}\r
- \r
+\r
switch (QuestionId) {\r
case KEY_INITIATOR_URI:\r
//\r
// Get user input URI string\r
//\r
Uri = HiiGetString (CallbackInfo->RegisteredHandle, Value->string, NULL);\r
- ASSERT (Uri != NULL);\r
- if (Uri == NULL) {\r
- return EFI_UNSUPPORTED;\r
+ if(Uri == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
}\r
\r
//\r
- // Convert the scheme to all lower case.\r
+ // The URI should be either an empty string (for corporate environment) ,or http(s) for home environment.\r
+ // Pop up a message box for the unsupported URI.\r
//\r
- for (Index = 0; Index < StrLen (Uri); Index++) {\r
- if (Uri[Index] == L':') {\r
- break;\r
+ if (StrLen (Uri) != 0) {\r
+ UriLen = StrLen (Uri) + 1;\r
+ AsciiUri = AllocateZeroPool (UriLen);\r
+ if (AsciiUri == NULL) {\r
+ FreePool (Uri);\r
+ return EFI_OUT_OF_RESOURCES;\r
}\r
- if (Uri[Index] >= L'A' && Uri[Index] <= L'Z') {\r
- Uri[Index] -= (CHAR16)(L'A' - L'a');\r
+\r
+ UnicodeStrToAsciiStrS (Uri, AsciiUri, UriLen);\r
+\r
+ Status = HttpBootCheckUriScheme (AsciiUri);\r
+\r
+ if (Status == EFI_INVALID_PARAMETER) {\r
+\r
+ DEBUG ((EFI_D_ERROR, "HttpBootFormCallback: %r.\n", Status));\r
+\r
+ CreatePopUp (\r
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+ &Key,\r
+ L"ERROR: Unsupported URI!",\r
+ L"Only supports HTTP and HTTPS",\r
+ NULL\r
+ );\r
+ } else if (Status == EFI_ACCESS_DENIED) {\r
+\r
+ DEBUG ((EFI_D_ERROR, "HttpBootFormCallback: %r.\n", Status));\r
+\r
+ CreatePopUp (\r
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+ &Key,\r
+ L"ERROR: Unsupported URI!",\r
+ L"HTTP is disabled",\r
+ NULL\r
+ );\r
}\r
}\r
\r
- //\r
- // Set the converted URI string back\r
- //\r
- HiiSetString (CallbackInfo->RegisteredHandle, Value->string, Uri, NULL);\r
+ if (Uri != NULL) {\r
+ FreePool (Uri);\r
+ }\r
\r
- //\r
- // We only accept http and https, pop up a message box for unsupported URI.\r
- //\r
- if ((StrnCmp (Uri, L"http://", 7) != 0) && (StrnCmp (Uri, L"https://", 7) != 0)) {\r
- CreatePopUp (\r
- EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
- &Key,\r
- L"ERROR: Unsupported URI!",\r
- L"Only supports HTTP and HTTPS",\r
- NULL\r
- );\r
+ if (AsciiUri != NULL) {\r
+ FreePool (AsciiUri);\r
}\r
\r
- FreePool (Uri);\r
break;\r
\r
default:\r
break;\r
}\r
\r
- return EFI_SUCCESS;\r
+ return Status;\r
}\r
\r
/**\r
if (CallbackInfo->Initilized) {\r
return EFI_SUCCESS;\r
}\r
- \r
+\r
CallbackInfo->Signature = HTTP_BOOT_FORM_CALLBACK_INFO_SIGNATURE;\r
\r
//\r
CallbackInfo->ConfigAccess.ExtractConfig = HttpBootFormExtractConfig;\r
CallbackInfo->ConfigAccess.RouteConfig = HttpBootFormRouteConfig;\r
CallbackInfo->ConfigAccess.Callback = HttpBootFormCallback;\r
- \r
+\r
//\r
// Install Device Path Protocol and Config Access protocol to driver handle.\r
//\r
Status = NetLibGetMacString (Private->Controller, NULL, &MacString);\r
if (!EFI_ERROR (Status)) {\r
OldMenuString = HiiGetString (\r
- CallbackInfo->RegisteredHandle, \r
- STRING_TOKEN (STR_HTTP_BOOT_CONFIG_FORM_HELP), \r
+ CallbackInfo->RegisteredHandle,\r
+ STRING_TOKEN (STR_HTTP_BOOT_CONFIG_FORM_HELP),\r
NULL\r
);\r
UnicodeSPrint (MenuString, 128, L"%s (MAC:%s)", OldMenuString, MacString);\r
HiiSetString (\r
- CallbackInfo->RegisteredHandle, \r
- STRING_TOKEN (STR_HTTP_BOOT_CONFIG_FORM_HELP), \r
- MenuString, \r
+ CallbackInfo->RegisteredHandle,\r
+ STRING_TOKEN (STR_HTTP_BOOT_CONFIG_FORM_HELP),\r
+ MenuString,\r
NULL\r
);\r
- \r
+\r
FreePool (MacString);\r
FreePool (OldMenuString);\r
\r
CallbackInfo->Initilized = TRUE;\r
return EFI_SUCCESS;\r
}\r
- \r
+\r
Error:\r
\r
HttpBootConfigFormUnload (Private);\r