Commit fa848a4048 ("NetworkPkg: Add URI configuration form to HTTP boot
driver") causes the build to fail with gcc:
> NetworkPkg/HttpBootDxe/HttpBootConfig.c: In function
>                                          'HttpBootAddBootOption':
> NetworkPkg/HttpBootDxe/HttpBootConfig.c:148:14:
> error: passing argument 3 of 'GetVariable2' from incompatible pointer
>        type [-Werror]
>               );
>               ^
> In file included from NetworkPkg/HttpBootDxe/HttpBootDxe.h:31:0,
>                  from NetworkPkg/HttpBootDxe/HttpBootConfig.c:15:
> MdePkg/Include/Library/UefiLib.h:708:1: note: expected 'void **' but
>                                         argument is of type 'CHAR16 **'
>  GetVariable2 (
>  ^
> cc1: all warnings being treated as errors
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Fu Siyuan <siyuan.fu@intel.com>
		
	
		
			
				
	
	
		
			724 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			724 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Helper functions for configuring or getting the parameters relating to HTTP Boot.
 | 
						|
 | 
						|
Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
 | 
						|
This program and the accompanying materials
 | 
						|
are licensed and made available under the terms and conditions of the BSD License
 | 
						|
which accompanies this distribution.  The full text of the license may be found at
 | 
						|
http://opensource.org/licenses/bsd-license.php
 | 
						|
 | 
						|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | 
						|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "HttpBootDxe.h"
 | 
						|
 | 
						|
CHAR16  mHttpBootConfigStorageName[]     = L"HTTP_BOOT_CONFIG_IFR_NVDATA";
 | 
						|
 | 
						|
/**
 | 
						|
  Add new boot option for HTTP boot.
 | 
						|
 | 
						|
  @param[in]  Private             Pointer to the driver private data.
 | 
						|
  @param[in]  UsingIpv6           Set to TRUE if creating boot option for IPv6.
 | 
						|
  @param[in]  Description         The description text of the boot option.
 | 
						|
  @param[in]  Uri                 The URI string of the boot file.
 | 
						|
  
 | 
						|
  @retval EFI_SUCCESS             The boot option is created successfully.
 | 
						|
  @retval Others                  Failed to create new boot option.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HttpBootAddBootOption (
 | 
						|
  IN   HTTP_BOOT_PRIVATE_DATA   *Private,
 | 
						|
  IN   BOOLEAN                  UsingIpv6,
 | 
						|
  IN   CHAR16                   *Description,
 | 
						|
  IN   CHAR16                   *Uri
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_DEV_PATH               *Node;
 | 
						|
  EFI_DEVICE_PATH_PROTOCOL   *TmpDevicePath;
 | 
						|
  EFI_DEVICE_PATH_PROTOCOL   *NewDevicePath;
 | 
						|
  UINTN                      Length;
 | 
						|
  CHAR8                      AsciiUri[URI_STR_MAX_SIZE];
 | 
						|
  CHAR16                     *CurrentOrder;
 | 
						|
  EFI_STATUS                 Status;
 | 
						|
  UINTN                      OrderCount;
 | 
						|
  UINTN                      TargetLocation;
 | 
						|
  BOOLEAN                    Found;
 | 
						|
  UINT8                      *TempByteBuffer;
 | 
						|
  UINT8                      *TempByteStart;
 | 
						|
  UINTN                      DescSize;
 | 
						|
  UINTN                      FilePathSize;
 | 
						|
  CHAR16                     OptionStr[10];
 | 
						|
  UINT16                     *NewOrder;
 | 
						|
  UINTN                      Index;
 | 
						|
 | 
						|
  NewOrder      = NULL;
 | 
						|
  TempByteStart = NULL;
 | 
						|
  NewDevicePath = NULL;
 | 
						|
  NewOrder      = NULL;
 | 
						|
  Node          = NULL;
 | 
						|
  TmpDevicePath = NULL;
 | 
						|
  CurrentOrder  = NULL;
 | 
						|
 | 
						|
  if (StrLen (Description) == 0) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Convert the scheme to all lower case.
 | 
						|
  //
 | 
						|
  for (Index = 0; Index < StrLen (Uri); Index++) {
 | 
						|
    if (Uri[Index] == L':') {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    if (Uri[Index] >= L'A' && Uri[Index] <= L'Z') {
 | 
						|
      Uri[Index] -= (CHAR16)(L'A' - L'a');
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Only accept http and https URI.
 | 
						|
  //
 | 
						|
  if ((StrnCmp (Uri, L"http://", 7) != 0) && (StrnCmp (Uri, L"https://", 7) != 0)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
  
 | 
						|
  //
 | 
						|
  // Create a new device path by appending the IP node and URI node to
 | 
						|
  // the driver's parent device path
 | 
						|
  //
 | 
						|
  if (!UsingIpv6) {
 | 
						|
    Node = AllocateZeroPool (sizeof (IPv4_DEVICE_PATH));
 | 
						|
    if (Node == NULL) {
 | 
						|
      Status = EFI_OUT_OF_RESOURCES;
 | 
						|
      goto ON_EXIT;
 | 
						|
    }
 | 
						|
    Node->Ipv4.Header.Type    = MESSAGING_DEVICE_PATH;
 | 
						|
    Node->Ipv4.Header.SubType = MSG_IPv4_DP;
 | 
						|
    SetDevicePathNodeLength (Node, sizeof (IPv4_DEVICE_PATH));
 | 
						|
  } else {
 | 
						|
    Node = AllocateZeroPool (sizeof (IPv6_DEVICE_PATH));
 | 
						|
    if (Node == NULL) {
 | 
						|
      Status = EFI_OUT_OF_RESOURCES;
 | 
						|
      goto ON_EXIT;
 | 
						|
    }
 | 
						|
    Node->Ipv6.Header.Type     = MESSAGING_DEVICE_PATH;
 | 
						|
    Node->Ipv6.Header.SubType  = MSG_IPv6_DP;
 | 
						|
    SetDevicePathNodeLength (Node, sizeof (IPv6_DEVICE_PATH));
 | 
						|
  }
 | 
						|
  TmpDevicePath = AppendDevicePathNode (Private->ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);
 | 
						|
  FreePool (Node);
 | 
						|
  if (TmpDevicePath == NULL) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Update the URI node with the input boot file URI.
 | 
						|
  //
 | 
						|
  UnicodeStrToAsciiStr (Uri, AsciiUri);
 | 
						|
  Length = sizeof (EFI_DEVICE_PATH_PROTOCOL) + AsciiStrSize (AsciiUri);
 | 
						|
  Node = AllocatePool (Length);
 | 
						|
  if (Node == NULL) {
 | 
						|
    Status = EFI_OUT_OF_RESOURCES;
 | 
						|
    FreePool (TmpDevicePath);
 | 
						|
    goto ON_EXIT;
 | 
						|
  }
 | 
						|
  Node->DevPath.Type    = MESSAGING_DEVICE_PATH;
 | 
						|
  Node->DevPath.SubType = MSG_URI_DP;
 | 
						|
  SetDevicePathNodeLength (Node, Length);
 | 
						|
  CopyMem ((UINT8*) Node + sizeof (EFI_DEVICE_PATH_PROTOCOL), AsciiUri, AsciiStrSize (AsciiUri));
 | 
						|
  NewDevicePath = AppendDevicePathNode (TmpDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);
 | 
						|
  FreePool (Node);
 | 
						|
  FreePool (TmpDevicePath);
 | 
						|
  if (NewDevicePath == NULL) {
 | 
						|
    Status = EFI_OUT_OF_RESOURCES;
 | 
						|
    goto ON_EXIT;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Get current "BootOrder" variable and find a free target.
 | 
						|
  //
 | 
						|
  Length = 0;
 | 
						|
  Status = GetVariable2 (
 | 
						|
             L"BootOrder",
 | 
						|
             &gEfiGlobalVariableGuid,
 | 
						|
             (VOID **)&CurrentOrder,
 | 
						|
             &Length 
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status) && Status != EFI_NOT_FOUND) {
 | 
						|
    goto ON_EXIT;
 | 
						|
  }
 | 
						|
  OrderCount = Length / sizeof (UINT16);
 | 
						|
  Found = FALSE;
 | 
						|
  for (TargetLocation=0; TargetLocation < 0xFFFF; TargetLocation++) {
 | 
						|
    Found = TRUE;
 | 
						|
    for (Index = 0; Index < OrderCount; Index++) {
 | 
						|
      if (CurrentOrder[Index] == TargetLocation) {
 | 
						|
        Found = FALSE;
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (Found) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (TargetLocation == 0xFFFF) {
 | 
						|
    DEBUG ((EFI_D_ERROR, "Could not find unused target index.\n"));
 | 
						|
    Status = EFI_OUT_OF_RESOURCES;
 | 
						|
    goto ON_EXIT;
 | 
						|
  } else {
 | 
						|
    DEBUG ((EFI_D_INFO, "TargetIndex = %04x.\n", TargetLocation));
 | 
						|
  }
 | 
						|
  
 | 
						|
  //
 | 
						|
  // Construct and set the "Boot####" variable
 | 
						|
  //
 | 
						|
  DescSize = StrSize(Description);
 | 
						|
  FilePathSize = GetDevicePathSize (NewDevicePath);
 | 
						|
  TempByteBuffer = AllocateZeroPool(sizeof(EFI_LOAD_OPTION) + DescSize + FilePathSize);
 | 
						|
  if (TempByteBuffer == NULL) {
 | 
						|
    Status = EFI_OUT_OF_RESOURCES;
 | 
						|
    goto ON_EXIT;
 | 
						|
  }
 | 
						|
 | 
						|
  TempByteStart = TempByteBuffer;
 | 
						|
  *((UINT32 *) TempByteBuffer) = LOAD_OPTION_ACTIVE;      // Attributes
 | 
						|
  TempByteBuffer += sizeof (UINT32);
 | 
						|
 | 
						|
  *((UINT16 *) TempByteBuffer) = (UINT16)FilePathSize;    // FilePathListLength
 | 
						|
  TempByteBuffer += sizeof (UINT16);
 | 
						|
 | 
						|
  CopyMem (TempByteBuffer, Description, DescSize);
 | 
						|
  TempByteBuffer += DescSize;
 | 
						|
  CopyMem (TempByteBuffer, NewDevicePath, FilePathSize);
 | 
						|
 | 
						|
  UnicodeSPrint (OptionStr, sizeof(OptionStr), L"%s%04x", L"Boot", TargetLocation);
 | 
						|
  Status = gRT->SetVariable (
 | 
						|
                  OptionStr,
 | 
						|
                  &gEfiGlobalVariableGuid,
 | 
						|
                  EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
 | 
						|
                  sizeof(UINT32) + sizeof(UINT16) + DescSize + FilePathSize,
 | 
						|
                  TempByteStart
 | 
						|
                  );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    goto ON_EXIT;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Insert into the order list and set "BootOrder" variable
 | 
						|
  //
 | 
						|
  NewOrder = AllocateZeroPool ((OrderCount + 1) * sizeof (UINT16));
 | 
						|
  if (NewOrder == NULL) {
 | 
						|
    Status = EFI_OUT_OF_RESOURCES;
 | 
						|
    goto ON_EXIT;
 | 
						|
  }
 | 
						|
  CopyMem(NewOrder, CurrentOrder, OrderCount * sizeof(UINT16));
 | 
						|
  NewOrder[OrderCount] = (UINT16) TargetLocation;
 | 
						|
  Status = gRT->SetVariable (
 | 
						|
                  L"BootOrder",
 | 
						|
                  &gEfiGlobalVariableGuid,
 | 
						|
                  EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
 | 
						|
                  ((OrderCount + 1) * sizeof (UINT16)),
 | 
						|
                  NewOrder
 | 
						|
                  );
 | 
						|
  
 | 
						|
 | 
						|
ON_EXIT:
 | 
						|
 | 
						|
  if (CurrentOrder != NULL) {
 | 
						|
    FreePool (CurrentOrder);
 | 
						|
  }
 | 
						|
  if (NewOrder != NULL) {
 | 
						|
    FreePool (NewOrder);
 | 
						|
  }
 | 
						|
  if (TempByteStart != NULL) {
 | 
						|
    FreePool (TempByteStart);
 | 
						|
  }
 | 
						|
  if (NewDevicePath != NULL) {
 | 
						|
    FreePool (NewDevicePath);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
   
 | 
						|
  This function allows the caller to request the current
 | 
						|
  configuration for one or more named elements. The resulting
 | 
						|
  string is in <ConfigAltResp> format. Also, any and all alternative
 | 
						|
  configuration strings shall be appended to the end of the
 | 
						|
  current configuration string. If they are, they must appear
 | 
						|
  after the current configuration. They must contain the same
 | 
						|
  routing (GUID, NAME, PATH) as the current configuration string.
 | 
						|
  They must have an additional description indicating the type of
 | 
						|
  alternative configuration the string represents,
 | 
						|
  "ALTCFG=<StringToken>". That <StringToken> (when
 | 
						|
  converted from Hex UNICODE to binary) is a reference to a
 | 
						|
  string in the associated string pack.
 | 
						|
 | 
						|
  @param[in]  This       Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
 | 
						|
 | 
						|
  @param[in]  Request    A null-terminated Unicode string in
 | 
						|
                         <ConfigRequest> format. Note that this
 | 
						|
                         includes the routing information as well as
 | 
						|
                         the configurable name / value pairs. It is
 | 
						|
                         invalid for this string to be in
 | 
						|
                         <MultiConfigRequest> format.
 | 
						|
 | 
						|
  @param[out] Progress   On return, points to a character in the
 | 
						|
                         Request string. Points to the string's null
 | 
						|
                         terminator if request was successful. Points
 | 
						|
                         to the most recent "&" before the first
 | 
						|
                         failing name / value pair (or the beginning
 | 
						|
                         of the string if the failure is in the first
 | 
						|
                         name / value pair) if the request was not successful.                        
 | 
						|
 | 
						|
  @param[out] Results    A null-terminated Unicode string in
 | 
						|
                         <ConfigAltResp> format which has all values
 | 
						|
                         filled in for the names in the Request string.
 | 
						|
                         String to be allocated by the called function.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The Results string is filled with the
 | 
						|
                                  values corresponding to all requested
 | 
						|
                                  names.
 | 
						|
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    Not enough memory to store the
 | 
						|
                                  parts of the results that must be
 | 
						|
                                  stored awaiting possible future
 | 
						|
                                  protocols.
 | 
						|
 | 
						|
  @retval EFI_INVALID_PARAMETER   For example, passing in a NULL
 | 
						|
                                  for the Request parameter
 | 
						|
                                  would result in this type of
 | 
						|
                                  error. In this case, the
 | 
						|
                                  Progress parameter would be
 | 
						|
                                  set to NULL. 
 | 
						|
 | 
						|
  @retval EFI_NOT_FOUND           Routing data doesn't match any
 | 
						|
                                  known driver. Progress set to the
 | 
						|
                                  first character in the routing header.
 | 
						|
                                  Note: There is no requirement that the
 | 
						|
                                  driver validate the routing data. It
 | 
						|
                                  must skip the <ConfigHdr> in order to
 | 
						|
                                  process the names.
 | 
						|
 | 
						|
  @retval EFI_INVALID_PARAMETER   Illegal syntax. Progress set
 | 
						|
                                  to most recent "&" before the
 | 
						|
                                  error or the beginning of the
 | 
						|
                                  string.
 | 
						|
 | 
						|
  @retval EFI_INVALID_PARAMETER   Unknown name. Progress points
 | 
						|
                                  to the & before the name in
 | 
						|
                                  question.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
HttpBootFormExtractConfig (
 | 
						|
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
 | 
						|
  IN  CONST EFI_STRING                       Request,
 | 
						|
  OUT EFI_STRING                             *Progress,
 | 
						|
  OUT EFI_STRING                             *Results
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                       Status;
 | 
						|
  UINTN                            BufferSize;
 | 
						|
  HTTP_BOOT_FORM_CALLBACK_INFO     *CallbackInfo;
 | 
						|
  EFI_STRING                       ConfigRequestHdr;
 | 
						|
  EFI_STRING                       ConfigRequest;
 | 
						|
  BOOLEAN                          AllocatedRequest;
 | 
						|
  UINTN                            Size;
 | 
						|
 | 
						|
  if (Progress == NULL || Results == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  *Progress = Request;
 | 
						|
  if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gHttpBootConfigGuid, mHttpBootConfigStorageName)) {
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
  
 | 
						|
  ConfigRequestHdr = NULL;
 | 
						|
  ConfigRequest    = NULL;
 | 
						|
  AllocatedRequest = FALSE;
 | 
						|
  Size             = 0;
 | 
						|
 | 
						|
  CallbackInfo = HTTP_BOOT_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);
 | 
						|
  //
 | 
						|
  // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
 | 
						|
  //
 | 
						|
  BufferSize = sizeof (HTTP_BOOT_CONFIG_IFR_NVDATA);
 | 
						|
  ZeroMem (&CallbackInfo->HttpBootNvData, BufferSize);
 | 
						|
 | 
						|
  ConfigRequest = Request;
 | 
						|
  if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
 | 
						|
    //
 | 
						|
    // Request has no request element, construct full request string.
 | 
						|
    // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
 | 
						|
    // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
 | 
						|
    //
 | 
						|
    ConfigRequestHdr = HiiConstructConfigHdr (&gHttpBootConfigGuid, mHttpBootConfigStorageName, CallbackInfo->ChildHandle);
 | 
						|
    Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
 | 
						|
    ConfigRequest = AllocateZeroPool (Size);
 | 
						|
    ASSERT (ConfigRequest != NULL);
 | 
						|
    AllocatedRequest = TRUE;
 | 
						|
    UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
 | 
						|
    FreePool (ConfigRequestHdr);
 | 
						|
  }
 | 
						|
 | 
						|
  Status = gHiiConfigRouting->BlockToConfig (
 | 
						|
                                gHiiConfigRouting,
 | 
						|
                                ConfigRequest,
 | 
						|
                                (UINT8 *) &CallbackInfo->HttpBootNvData,
 | 
						|
                                BufferSize,
 | 
						|
                                Results,
 | 
						|
                                Progress
 | 
						|
                                );
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
  
 | 
						|
  //
 | 
						|
  // Free the allocated config request string.
 | 
						|
  //
 | 
						|
  if (AllocatedRequest) {
 | 
						|
    FreePool (ConfigRequest);
 | 
						|
    ConfigRequest = NULL;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Set Progress string to the original request string.
 | 
						|
  //
 | 
						|
  if (Request == NULL) {
 | 
						|
    *Progress = NULL;
 | 
						|
  } else if (StrStr (Request, L"OFFSET") == NULL) {
 | 
						|
    *Progress = Request + StrLen (Request);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
   
 | 
						|
  This function applies changes in a driver's configuration.
 | 
						|
  Input is a Configuration, which has the routing data for this
 | 
						|
  driver followed by name / value configuration pairs. The driver
 | 
						|
  must apply those pairs to its configurable storage. If the
 | 
						|
  driver's configuration is stored in a linear block of data
 | 
						|
  and the driver's name / value pairs are in <BlockConfig>
 | 
						|
  format, it may use the ConfigToBlock helper function (above) to
 | 
						|
  simplify the job.
 | 
						|
 | 
						|
  @param[in]  This           Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
 | 
						|
 | 
						|
  @param[in]  Configuration  A null-terminated Unicode string in
 | 
						|
                             <ConfigString> format. 
 | 
						|
  
 | 
						|
  @param[out] Progress       A pointer to a string filled in with the
 | 
						|
                             offset of the most recent '&' before the
 | 
						|
                             first failing name / value pair (or the
 | 
						|
                             beginning of the string if the failure
 | 
						|
                             is in the first name / value pair) or
 | 
						|
                             the terminating NULL if all was
 | 
						|
                             successful.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The results have been distributed or are
 | 
						|
                                  awaiting distribution.
 | 
						|
  
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    Not enough memory to store the
 | 
						|
                                  parts of the results that must be
 | 
						|
                                  stored awaiting possible future
 | 
						|
                                  protocols.
 | 
						|
  
 | 
						|
  @retval EFI_INVALID_PARAMETERS  Passing in a NULL for the
 | 
						|
                                  Results parameter would result
 | 
						|
                                  in this type of error.
 | 
						|
  
 | 
						|
  @retval EFI_NOT_FOUND           Target for the specified routing data
 | 
						|
                                  was not found.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
HttpBootFormRouteConfig (
 | 
						|
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
 | 
						|
  IN  CONST EFI_STRING                       Configuration,
 | 
						|
  OUT EFI_STRING                             *Progress
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                       Status;
 | 
						|
  UINTN                            BufferSize;
 | 
						|
  HTTP_BOOT_FORM_CALLBACK_INFO     *CallbackInfo;
 | 
						|
  HTTP_BOOT_PRIVATE_DATA           *Private;
 | 
						|
 | 
						|
  if (Progress == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
  *Progress = Configuration;
 | 
						|
 | 
						|
  if (Configuration == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Check routing data in <ConfigHdr>.
 | 
						|
  // Note: there is no name for Name/Value storage, only GUID will be checked
 | 
						|
  //
 | 
						|
  if (!HiiIsConfigHdrMatch (Configuration, &gHttpBootConfigGuid, mHttpBootConfigStorageName)) {
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
  CallbackInfo = HTTP_BOOT_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);
 | 
						|
  Private      = HTTP_BOOT_PRIVATE_DATA_FROM_CALLBACK_INFO (CallbackInfo);
 | 
						|
  
 | 
						|
  BufferSize = sizeof (HTTP_BOOT_CONFIG_IFR_NVDATA);
 | 
						|
  ZeroMem (&CallbackInfo->HttpBootNvData, BufferSize);
 | 
						|
 | 
						|
  Status = gHiiConfigRouting->ConfigToBlock (
 | 
						|
                            gHiiConfigRouting,
 | 
						|
                            Configuration,
 | 
						|
                            (UINT8 *) &CallbackInfo->HttpBootNvData,
 | 
						|
                            &BufferSize,
 | 
						|
                            Progress
 | 
						|
                            );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Create a new boot option according to the configuration data.
 | 
						|
  //
 | 
						|
  Status = HttpBootAddBootOption (
 | 
						|
             Private,
 | 
						|
             (CallbackInfo->HttpBootNvData.IpVersion == HTTP_BOOT_IP_VERSION_6) ? TRUE : FALSE,
 | 
						|
             CallbackInfo->HttpBootNvData.Description,
 | 
						|
             CallbackInfo->HttpBootNvData.Uri
 | 
						|
             );
 | 
						|
  
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
   
 | 
						|
  This function is called to provide results data to the driver.
 | 
						|
  This data consists of a unique key that is used to identify
 | 
						|
  which data is either being passed back or being asked for.
 | 
						|
 | 
						|
  @param[in]       This          Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
 | 
						|
  @param[in]       Action        Specifies the type of action taken by the browser.
 | 
						|
  @param[in]       QuestionId    A unique value which is sent to the original
 | 
						|
                                 exporting driver so that it can identify the type
 | 
						|
                                 of data to expect. The format of the data tends to 
 | 
						|
                                 vary based on the opcode that generated the callback.
 | 
						|
  @param[in]       Type          The type of value for the question.
 | 
						|
  @param[in, out]  Value         A pointer to the data being sent to the original
 | 
						|
                                 exporting driver.
 | 
						|
  @param[out]      ActionRequest On return, points to the action requested by the
 | 
						|
                                 callback function.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS            The callback successfully handled the action.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the
 | 
						|
                                 variable and its data.
 | 
						|
  @retval EFI_DEVICE_ERROR       The variable could not be saved.
 | 
						|
  @retval EFI_UNSUPPORTED        The specified Action is not supported by the
 | 
						|
                                 callback.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
HttpBootFormCallback (
 | 
						|
  IN CONST  EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
 | 
						|
  IN        EFI_BROWSER_ACTION               Action,
 | 
						|
  IN        EFI_QUESTION_ID                  QuestionId,
 | 
						|
  IN        UINT8                            Type,
 | 
						|
  IN OUT    EFI_IFR_TYPE_VALUE               *Value,
 | 
						|
  OUT       EFI_BROWSER_ACTION_REQUEST       *ActionRequest
 | 
						|
  )
 | 
						|
{
 | 
						|
  return EFI_UNSUPPORTED;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Initialize the configuration form.
 | 
						|
 | 
						|
  @param[in]  Private             Pointer to the driver private data.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The configuration form is initialized.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HttpBootConfigFormInit (
 | 
						|
  IN HTTP_BOOT_PRIVATE_DATA     *Private
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                        Status;
 | 
						|
  HTTP_BOOT_FORM_CALLBACK_INFO      *CallbackInfo;
 | 
						|
  VENDOR_DEVICE_PATH                VendorDeviceNode;
 | 
						|
  EFI_SERVICE_BINDING_PROTOCOL      *HttpSb;
 | 
						|
  CHAR16                            *MacString;
 | 
						|
  CHAR16                            *OldMenuString;
 | 
						|
  CHAR16                            MenuString[128];
 | 
						|
 | 
						|
  CallbackInfo = &Private->CallbackInfo;
 | 
						|
 | 
						|
  if (CallbackInfo->Initilized) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
  
 | 
						|
  CallbackInfo->Signature = HTTP_BOOT_FORM_CALLBACK_INFO_SIGNATURE;
 | 
						|
 | 
						|
  //
 | 
						|
  // Construct device path node for EFI HII Config Access protocol,
 | 
						|
  // which consists of controller physical device path and one hardware
 | 
						|
  // vendor guid node.
 | 
						|
  //
 | 
						|
  ZeroMem (&VendorDeviceNode, sizeof (VENDOR_DEVICE_PATH));
 | 
						|
  VendorDeviceNode.Header.Type    = HARDWARE_DEVICE_PATH;
 | 
						|
  VendorDeviceNode.Header.SubType = HW_VENDOR_DP;
 | 
						|
  CopyGuid (&VendorDeviceNode.Guid, &gEfiCallerIdGuid);
 | 
						|
  SetDevicePathNodeLength (&VendorDeviceNode.Header, sizeof (VENDOR_DEVICE_PATH));
 | 
						|
  CallbackInfo->HiiVendorDevicePath = AppendDevicePathNode (
 | 
						|
                                        Private->ParentDevicePath,
 | 
						|
                                        (EFI_DEVICE_PATH_PROTOCOL *) &VendorDeviceNode
 | 
						|
                                        );
 | 
						|
  if (CallbackInfo->HiiVendorDevicePath == NULL) {
 | 
						|
    Status = EFI_OUT_OF_RESOURCES;
 | 
						|
    goto Error;
 | 
						|
  }
 | 
						|
 | 
						|
  CallbackInfo->ConfigAccess.ExtractConfig = HttpBootFormExtractConfig;
 | 
						|
  CallbackInfo->ConfigAccess.RouteConfig   = HttpBootFormRouteConfig;
 | 
						|
  CallbackInfo->ConfigAccess.Callback      = HttpBootFormCallback;
 | 
						|
  
 | 
						|
  //
 | 
						|
  // Install Device Path Protocol and Config Access protocol to driver handle.
 | 
						|
  //
 | 
						|
  Status = gBS->InstallMultipleProtocolInterfaces (
 | 
						|
                  &CallbackInfo->ChildHandle,
 | 
						|
                  &gEfiDevicePathProtocolGuid,
 | 
						|
                  CallbackInfo->HiiVendorDevicePath,
 | 
						|
                  &gEfiHiiConfigAccessProtocolGuid,
 | 
						|
                  &CallbackInfo->ConfigAccess,
 | 
						|
                  NULL
 | 
						|
                  );
 | 
						|
  if (!EFI_ERROR (Status)) {
 | 
						|
    //
 | 
						|
    // Open the Parent Handle for the child
 | 
						|
    //
 | 
						|
    Status = gBS->OpenProtocol (
 | 
						|
                    Private->Controller,
 | 
						|
                    &gEfiHttpServiceBindingProtocolGuid,
 | 
						|
                    (VOID **) &HttpSb,
 | 
						|
                    Private->Image,
 | 
						|
                    CallbackInfo->ChildHandle,
 | 
						|
                    EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
 | 
						|
                    );
 | 
						|
  }
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    goto Error;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Publish our HII data.
 | 
						|
  //
 | 
						|
  CallbackInfo->RegisteredHandle = HiiAddPackages (
 | 
						|
                                     &gHttpBootConfigGuid,
 | 
						|
                                     CallbackInfo->ChildHandle,
 | 
						|
                                     HttpBootDxeStrings,
 | 
						|
                                     HttpBootConfigVfrBin,
 | 
						|
                                     NULL
 | 
						|
                                     );
 | 
						|
  if (CallbackInfo->RegisteredHandle == NULL) {
 | 
						|
    Status = EFI_OUT_OF_RESOURCES;
 | 
						|
    goto Error;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Append MAC string in the menu help string
 | 
						|
  //
 | 
						|
  Status = NetLibGetMacString (Private->Controller, Private->Image, &MacString);
 | 
						|
  if (!EFI_ERROR (Status)) {
 | 
						|
    OldMenuString = HiiGetString (
 | 
						|
                      CallbackInfo->RegisteredHandle, 
 | 
						|
                      STRING_TOKEN (STR_HTTP_BOOT_CONFIG_FORM_HELP), 
 | 
						|
                      NULL
 | 
						|
                      );
 | 
						|
    UnicodeSPrint (MenuString, 128, L"%s (MAC:%s)", OldMenuString, MacString);
 | 
						|
    HiiSetString (
 | 
						|
      CallbackInfo->RegisteredHandle, 
 | 
						|
      STRING_TOKEN (STR_HTTP_BOOT_CONFIG_FORM_HELP), 
 | 
						|
      MenuString, 
 | 
						|
      NULL
 | 
						|
      );
 | 
						|
    
 | 
						|
    FreePool (MacString);
 | 
						|
    FreePool (OldMenuString);
 | 
						|
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
  
 | 
						|
Error:
 | 
						|
 | 
						|
  HttpBootConfigFormUnload (Private);
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Unload the configuration form, this includes: delete all the configuration
 | 
						|
  entries, uninstall the form callback protocol, and free the resources used.
 | 
						|
 | 
						|
  @param[in]  Private             Pointer to the driver private data.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The configuration form is unloaded.
 | 
						|
  @retval Others                  Failed to unload the form.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HttpBootConfigFormUnload (
 | 
						|
  IN HTTP_BOOT_PRIVATE_DATA     *Private
 | 
						|
  )
 | 
						|
{
 | 
						|
  HTTP_BOOT_FORM_CALLBACK_INFO      *CallbackInfo;
 | 
						|
 | 
						|
  CallbackInfo = &Private->CallbackInfo;
 | 
						|
  if (CallbackInfo->ChildHandle != NULL) {
 | 
						|
    //
 | 
						|
    // Close the child handle
 | 
						|
    //
 | 
						|
    gBS->CloseProtocol (
 | 
						|
           Private->Controller,
 | 
						|
           &gEfiHttpServiceBindingProtocolGuid,
 | 
						|
           Private->Image,
 | 
						|
           CallbackInfo->ChildHandle
 | 
						|
           );
 | 
						|
    
 | 
						|
    //
 | 
						|
    // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
 | 
						|
    //
 | 
						|
    gBS->UninstallMultipleProtocolInterfaces (
 | 
						|
           CallbackInfo->ChildHandle,
 | 
						|
           &gEfiDevicePathProtocolGuid,
 | 
						|
           CallbackInfo->HiiVendorDevicePath,
 | 
						|
           &gEfiHiiConfigAccessProtocolGuid,
 | 
						|
           &CallbackInfo->ConfigAccess,
 | 
						|
           NULL
 | 
						|
           );
 | 
						|
    CallbackInfo->ChildHandle = NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  if (CallbackInfo->HiiVendorDevicePath != NULL) {
 | 
						|
    FreePool (CallbackInfo->HiiVendorDevicePath);
 | 
						|
    CallbackInfo->HiiVendorDevicePath = NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  if (CallbackInfo->RegisteredHandle != NULL) {
 | 
						|
    //
 | 
						|
    // Remove HII package list
 | 
						|
    //
 | 
						|
    HiiRemovePackages (CallbackInfo->RegisteredHandle);
 | 
						|
    CallbackInfo->RegisteredHandle = NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 |