コード例 #1
0
ファイル: ConfigAccess.c プロジェクト: AshleyDeSimone/edk2
/**
  Build the EFI_IFR_DATA_ARRAY which will be used to pass to 
  EFI_FORM_CALLBACK_PROTOCOL.Callback. Check definition of EFI_IFR_DATA_ARRAY
  for details.

  ASSERT if the Question Type is not EFI_IFR_TYPE_NUM_SIZE_* or EFI_IFR_TYPE_STRING.
  
   @param ConfigAccess     Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL
   @param QuestionId       The Question ID.
   @param Type             The Question Type.
   @param Value            The Question Value.
   @param NvMapAllocated   On output indicates if a buffer is allocated for NvMap.
   
   @return A pointer to EFI_IFR_DATA_ARRAY. The caller must free this buffer allocated.
**/   
EFI_IFR_DATA_ARRAY *
CreateIfrDataArray (
  IN    CONFIG_ACCESS_PRIVATE         *ConfigAccess,
  IN    EFI_QUESTION_ID               QuestionId,
  IN    UINT8                         Type,
  IN    EFI_IFR_TYPE_VALUE            *Value,
  OUT   BOOLEAN                       *NvMapAllocated
  )
{
  EFI_IFR_DATA_ARRAY                *IfrDataArray;
  EFI_IFR_DATA_ENTRY                *IfrDataEntry;
  UINTN                             BrowserDataSize;
  FORMSET_STORAGE                   *BufferStorage;
  UINTN                             Size;
  EFI_STRING                        String;
  FORM_BROWSER_STATEMENT            *Statement;

  *NvMapAllocated = FALSE;

  String = NULL;

  switch (Type) {
    case EFI_IFR_TYPE_NUM_SIZE_8:
    case EFI_IFR_TYPE_NUM_SIZE_16:
    case EFI_IFR_TYPE_NUM_SIZE_32:
    case EFI_IFR_TYPE_NUM_SIZE_64:
    case EFI_IFR_TYPE_BOOLEAN:
      Size = sizeof (*Value);
      break;

    case EFI_IFR_TYPE_STRING:
      if (Value->string == 0) {
        Size = 0;
      } else {
        String = HiiGetString (ConfigAccess->ThunkContext->UefiHiiHandle, Value->string, NULL);
        ASSERT (String != NULL);

        Size = StrSize (String);
      }
      break;

    case EFI_IFR_TYPE_ACTION:
    case EFI_IFR_TYPE_UNDEFINED:
      Size = 0;
      break;
      
    default:
      ASSERT (FALSE);
      Size = 0;
      break;
  }

  IfrDataArray = AllocateZeroPool (sizeof (EFI_IFR_DATA_ARRAY) + sizeof (EFI_IFR_DATA_ENTRY) + Size);
  ASSERT (IfrDataArray != NULL);
  IfrDataArray->EntryCount = 1;
  IfrDataEntry             = (EFI_IFR_DATA_ENTRY *) (IfrDataArray + 1);

  Statement = GetStorageFromQuestionId (ConfigAccess->ThunkContext->FormSet, QuestionId);

  if (Statement == NULL || Statement->Storage == NULL) {
    //
    // The QuestionId is not associated with a Buffer Storage.
    // Try to get the first Buffer Storage then.
    //
    BufferStorage = GetFirstStorageOfFormSet (ConfigAccess->ThunkContext->FormSet);
  } else {
    BufferStorage        = Statement->Storage;
    IfrDataEntry->OpCode = Statement->Operand;
  }
  
  if (BufferStorage != NULL) {
    BrowserDataSize      = BufferStorage->Size;
    IfrDataEntry->Length = (UINT8) (sizeof (EFI_IFR_DATA_ENTRY) + Size);

    if (ConfigAccess->ThunkContext->NvMapOverride == NULL) {
      *NvMapAllocated = TRUE;
      IfrDataArray->NvRamMap = AllocateZeroPool (BrowserDataSize);
    } else {
      *NvMapAllocated = FALSE;
      IfrDataArray->NvRamMap = ConfigAccess->ThunkContext->NvMapOverride;
    }
    
    ASSERT (HiiGetBrowserData (&BufferStorage->Guid, BufferStorage->Name, BrowserDataSize, (UINT8 *) IfrDataArray->NvRamMap));

    switch (Type) {
      case EFI_IFR_TYPE_NUM_SIZE_8:
      case EFI_IFR_TYPE_NUM_SIZE_16:
      case EFI_IFR_TYPE_NUM_SIZE_32:
      case EFI_IFR_TYPE_NUM_SIZE_64:
      case EFI_IFR_TYPE_BOOLEAN:
        CopyMem (&IfrDataEntry->Data, &(Value->u8), sizeof (*Value));
        break;

      case EFI_IFR_TYPE_STRING:
        if (Size != 0) {
          ASSERT (String != NULL);
          StrCpy ((CHAR16 *) &IfrDataEntry->Data, String);
          FreePool (String);
        }
        break;

      case EFI_IFR_TYPE_ACTION:
      case EFI_IFR_TYPE_UNDEFINED:
        break;

      default:
        ASSERT (FALSE);
        break;
    }

    //
    // Need to fiil in the information for the rest of field for EFI_IFR_DATA_ENTRY.
    // It seems that no implementation is found to use other fields. Leave them uninitialized for now.
    //
    //UINT8   OpCode;           // Likely a string, numeric, or one-of
    //UINT8   Length;           // Length of the EFI_IFR_DATA_ENTRY packet
    //UINT16  Flags;            // Flags settings to determine what behavior is desired from the browser after the callback
    //VOID    *Data;            // The data in the form based on the op-code type - this is not a pointer to the data, the data follows immediately
    // If the OpCode is a OneOf or Numeric type - Data is a UINT16 value
    // If the OpCode is a String type - Data is a CHAR16[x] type
    // If the OpCode is a Checkbox type - Data is a UINT8 value
    // If the OpCode is a NV Access type - Data is a FRAMEWORK_EFI_IFR_NV_DATA structure
  }

  return IfrDataArray;
}
コード例 #2
0
ファイル: FileExplorer.c プロジェクト: ronnychevalier/edk2
/**
  This function processes the results of changes in configuration.
  When user select a interactive opcode, this callback will be triggered.
  Based on the Question(QuestionId) that triggers the callback, the corresponding
  actions is performed. It handles:

  1) the addition of boot option.
  2) the addition of driver option.
  3) exit from file browser
  4) update of file content if a dir is selected.
  5) boot the file if a file is selected in "boot from file"


  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param Action          Specifies the type of action taken by the browser.
  @param QuestionId      A unique value which is sent to the original exporting driver
                         so that it can identify the type of data to expect.
  @param Type            The type of value for the question.
  @param Value           A pointer to the data being sent to the original exporting driver.
  @param 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.
  @retval  EFI_INVALID_PARAMETER If paramter Value or ActionRequest is NULL.
**/
EFI_STATUS
EFIAPI
FileExplorerCallback (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
  IN  EFI_BROWSER_ACTION                     Action,
  IN  EFI_QUESTION_ID                        QuestionId,
  IN  UINT8                                  Type,
  IN  EFI_IFR_TYPE_VALUE                     *Value,
  OUT EFI_BROWSER_ACTION_REQUEST             *ActionRequest
  )
{
  BMM_CALLBACK_DATA     *Private;
  FILE_EXPLORER_NV_DATA *NvRamMap;
  EFI_STATUS            Status;

  if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {
    //
    // Do nothing for other UEFI Action. Only do call back when data is changed.
    //
    return EFI_UNSUPPORTED;
  }

  Status         = EFI_SUCCESS;
  Private        = FE_CALLBACK_DATA_FROM_THIS (This);
  *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;

  //
  // Retrieve uncommitted data from Form Browser
  //
  NvRamMap = &Private->FeFakeNvData;
  HiiGetBrowserData (&mFileExplorerGuid, mFileExplorerStorageName, sizeof (FILE_EXPLORER_NV_DATA), (UINT8 *) NvRamMap);

  if (Action == EFI_BROWSER_ACTION_CHANGED) {
    if ((Value == NULL) || (ActionRequest == NULL)) {
      return EFI_INVALID_PARAMETER;
    }
    
    if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_BOOT || QuestionId == KEY_VALUE_SAVE_AND_EXIT_DRIVER) {
      //
      // Apply changes and exit formset
      //
      if (FileExplorerStateAddBootOption == Private->FeCurrentState) {
        Status = Var_UpdateBootOption (Private, NvRamMap);
        if (EFI_ERROR (Status)) {
          return Status;
        }

        BOpt_GetBootOptions (Private);
        CreateMenuStringToken (Private, Private->FeHiiHandle, &BootOptionMenu);
      } else if (FileExplorerStateAddDriverOptionState == Private->FeCurrentState) {
        Status = Var_UpdateDriverOption (
                  Private,
                  Private->FeHiiHandle,
                  NvRamMap->DescriptionData,
                  NvRamMap->OptionalData,
                  NvRamMap->ForceReconnect
                  );
        if (EFI_ERROR (Status)) {
          return Status;
        }

        BOpt_GetDriverOptions (Private);
        CreateMenuStringToken (Private, Private->FeHiiHandle, &DriverOptionMenu);
      }

      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
    } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_BOOT || QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_DRIVER) {
      //
      // Discard changes and exit formset
      //
      NvRamMap->OptionalData[0]     = 0x0000;
      NvRamMap->DescriptionData[0]  = 0x0000;
      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
    } else if (QuestionId < FILE_OPTION_OFFSET) {
      //
      // Exit File Explorer formset
      //
      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
    }
  } else if (Action == EFI_BROWSER_ACTION_CHANGING) {
    if (Value == NULL) {
      return EFI_INVALID_PARAMETER;
    }
    
    if (QuestionId >= FILE_OPTION_OFFSET) {
      UpdateFileExplorer (Private, QuestionId);
    }
  }

  return Status;
}
コード例 #3
0
ファイル: VlanConfigImpl.c プロジェクト: ChenFanFnst/edk2
/**
  This function processes the results of changes in configuration.

  @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.
  @param[in]  Type               The type of value for the question.
  @param[in]  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
VlanCallback (
  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL      *This,
  IN     EFI_BROWSER_ACTION                    Action,
  IN     EFI_QUESTION_ID                       QuestionId,
  IN     UINT8                                 Type,
  IN     EFI_IFR_TYPE_VALUE                    *Value,
     OUT EFI_BROWSER_ACTION_REQUEST            *ActionRequest
  )
{
  VLAN_CONFIG_PRIVATE_DATA  *PrivateData;
  VLAN_CONFIGURATION        *Configuration;
  EFI_VLAN_CONFIG_PROTOCOL  *VlanConfig;
  UINTN                     Index;
  EFI_HANDLE                VlanHandle;

  PrivateData = VLAN_CONFIG_PRIVATE_DATA_FROM_THIS (This);

  if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) || (Action == EFI_BROWSER_ACTION_FORM_CLOSE)) {
    return EFI_SUCCESS;
  }

  if ((Action != EFI_BROWSER_ACTION_CHANGED) && (Action != EFI_BROWSER_ACTION_CHANGING)) {
    //
    // All other action return unsupported.
    //
    return EFI_UNSUPPORTED;
  }

  //
  // Get Browser data
  //
  Configuration = AllocateZeroPool (sizeof (VLAN_CONFIGURATION));
  ASSERT (Configuration != NULL);
  HiiGetBrowserData (&gVlanConfigFormSetGuid, mVlanStorageName, sizeof (VLAN_CONFIGURATION), (UINT8 *) Configuration);

  VlanConfig = PrivateData->VlanConfig;

  if (Action == EFI_BROWSER_ACTION_CHANGED) {
    switch (QuestionId) {
    case VLAN_ADD_QUESTION_ID:
      //
      // Add a VLAN
      //
      VlanConfig->Set (VlanConfig, Configuration->VlanId, Configuration->Priority);
      VlanUpdateForm (PrivateData);

      //
      // Connect the newly created VLAN device
      //
      VlanHandle = NetLibGetVlanHandle (PrivateData->ControllerHandle, Configuration->VlanId);
      if (VlanHandle == NULL) {
        //
        // There may be no child handle created for VLAN ID 0, connect the parent handle
        //
        VlanHandle = PrivateData->ControllerHandle;
      }
      gBS->ConnectController (VlanHandle, NULL, NULL, TRUE);

      //
      // Clear UI data
      //
      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
      Configuration->VlanId = 0;
      Configuration->Priority = 0;
      break;

    case VLAN_REMOVE_QUESTION_ID:
      //
      // Remove VLAN
      //
      ASSERT (PrivateData->NumberOfVlan <= MAX_VLAN_NUMBER);
      for (Index = 0; Index < PrivateData->NumberOfVlan; Index++) {
        if (Configuration->VlanList[Index] != 0) {
          //
          // Checkbox is selected, need remove this VLAN
          //
          VlanConfig->Remove (VlanConfig, PrivateData->VlanId[Index]);
        }
      }

      VlanUpdateForm (PrivateData);
      if (PrivateData->NumberOfVlan == 0) {
        //
        // No VLAN device now, connect the physical NIC handle.
        // Note: PrivateData->NumberOfVlan has been updated by VlanUpdateForm()
        //
        gBS->ConnectController (PrivateData->ControllerHandle, NULL, NULL, TRUE);
      }

      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
      ZeroMem (Configuration->VlanList, MAX_VLAN_NUMBER);
      break;

    default:
      break;
    }
  } else if (Action == EFI_BROWSER_ACTION_CHANGING) {
    switch (QuestionId) {
    case VLAN_UPDATE_QUESTION_ID:
      //
      // Update current VLAN list into Form.
      //
      VlanUpdateForm (PrivateData);
      break;

    default:
      break;
    }
  }
  
  HiiSetBrowserData (&gVlanConfigFormSetGuid, mVlanStorageName, sizeof (VLAN_CONFIGURATION), (UINT8 *) Configuration, NULL);
  FreePool (Configuration);
  return EFI_SUCCESS;
}
コード例 #4
0
ファイル: FileExplorer.c プロジェクト: bhanug/virtualbox
/**
  This function processes the results of changes in configuration.
  When user select a interactive opcode, this callback will be triggered.
  Based on the Question(QuestionId) that triggers the callback, the corresponding
  actions is performed. It handles:

  1) the addition of boot option.
  2) the addition of driver option.
  3) exit from file browser
  4) update of file content if a dir is selected.
  5) boot the file if a file is selected in "boot from file"


  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param Action          Specifies the type of action taken by the browser.
  @param QuestionId      A unique value which is sent to the original exporting driver
                         so that it can identify the type of data to expect.
  @param Type            The type of value for the question.
  @param Value           A pointer to the data being sent to the original exporting driver.
  @param 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.
  @retval  EFI_INVALID_PARAMETER If paramter Value or ActionRequest is NULL.
**/
EFI_STATUS
EFIAPI
FileExplorerCallback (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
  IN  EFI_BROWSER_ACTION                     Action,
  IN  EFI_QUESTION_ID                        QuestionId,
  IN  UINT8                                  Type,
  IN  EFI_IFR_TYPE_VALUE                     *Value,
  OUT EFI_BROWSER_ACTION_REQUEST             *ActionRequest
  )
{
  BMM_CALLBACK_DATA     *Private;
  FILE_EXPLORER_NV_DATA *NvRamMap;
  EFI_STATUS            Status;

  if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {
    //
    // All other action return unsupported.
    //
    return EFI_UNSUPPORTED;
  }

  Status         = EFI_SUCCESS;
  Private        = FE_CALLBACK_DATA_FROM_THIS (This);

  //
  // Retrieve uncommitted data from Form Browser
  //
  NvRamMap = &Private->FeFakeNvData;
  HiiGetBrowserData (&gFileExploreFormSetGuid, mFileExplorerStorageName, sizeof (FILE_EXPLORER_NV_DATA), (UINT8 *) NvRamMap);

  if (Action == EFI_BROWSER_ACTION_CHANGED) {
    if ((Value == NULL) || (ActionRequest == NULL)) {
      return EFI_INVALID_PARAMETER;
    }

    if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_BOOT) {
      NvRamMap->BootOptionChanged = FALSE;
      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
    } else if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_DRIVER) {
      NvRamMap->DriverOptionChanged = FALSE;
      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
    } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_DRIVER) {
      //
      // Discard changes and exit formset
      //
      NvRamMap->DriverOptionalData[0]     = 0x0000;
      NvRamMap->DriverDescriptionData[0]  = 0x0000;
      NvRamMap->DriverOptionChanged = FALSE;
      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
    } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_BOOT) {
      //
      // Discard changes and exit formset
      //
      NvRamMap->BootOptionalData[0]     = 0x0000;
      NvRamMap->BootDescriptionData[0]  = 0x0000;
      NvRamMap->BootOptionChanged = FALSE;
      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
    } else if (QuestionId == KEY_VALUE_BOOT_DESCRIPTION || QuestionId == KEY_VALUE_BOOT_OPTION) {
      NvRamMap->BootOptionChanged = TRUE;
    } else if (QuestionId == KEY_VALUE_DRIVER_DESCRIPTION || QuestionId == KEY_VALUE_DRIVER_OPTION) {
      NvRamMap->DriverOptionChanged = TRUE;
    } else if (QuestionId < FILE_OPTION_OFFSET) {
      //
      // Exit File Explorer formset
      //
      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
    } else if (QuestionId >= FILE_OPTION_OFFSET && QuestionId < FILE_OPTION_GOTO_OFFSET) {
      //
      // Update forms may return TRUE or FALSE, need to check here.
      //
      if (UpdateFileExplorer (Private, QuestionId)) {
        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
      }
    }
  } else if (Action == EFI_BROWSER_ACTION_CHANGING) {
    if (Value == NULL) {
      return EFI_INVALID_PARAMETER;
    }

    if (QuestionId >= FILE_OPTION_GOTO_OFFSET) {
      //
      // function will always return FALSE, no need to check here.
      //
      UpdateFileExplorer (Private, QuestionId);
    }
  }

  //
  // Pass changed uncommitted data back to Form Browser
  //
  HiiSetBrowserData (&gFileExploreFormSetGuid, mFileExplorerStorageName, sizeof (FILE_EXPLORER_NV_DATA), (UINT8 *) NvRamMap, NULL);

  return Status;
}
コード例 #5
0
ファイル: LegacyBootMaintUi.c プロジェクト: FrozenXZeus/edk2
/**
  Adjust question value when one question value has been changed.

  @param QuestionId    The question id for the value changed question.
  @param Value         The value for the changed question.

**/
VOID
AdjustOptionValue (
  IN  UINT16                                 QuestionId,
  IN  EFI_IFR_TYPE_VALUE                     *Value
  )
{
  UINTN                       Number;
  BBS_TYPE                    BbsType;
  LEGACY_DEV_ORDER_ENTRY      *DevOrder;
  UINT16                      *Default;
  LEGACY_BOOT_NV_DATA         *CurrentNVMap;
  UINT16                      *CurrentVal;
  UINTN                       Index;
  UINTN                       Index2;
  UINTN                       Index3;
  UINTN                       NewValuePos;
  UINTN                       OldValue;
  UINTN                       NewValue;
  UINT8                       *DisMap;
  UINTN                       Pos;
  UINTN                       Bit;

  Number = 0;
  BbsType = BBS_UNKNOWN;
  CurrentVal = 0;
  DevOrder = NULL;
  Default = NULL;
  NewValue = 0;
  NewValuePos = 0;

  //
  // Update Select FD/HD/CD/NET/BEV Order Form
  //
  ASSERT ((QuestionId >= LEGACY_FD_QUESTION_ID) && (QuestionId < LEGACY_BEV_QUESTION_ID + MAX_MENU_NUMBER));

  CurrentNVMap = &mLegacyBootOptionPrivate->MaintainMapData->CurrentNvData;
  HiiGetBrowserData (&mLegacyBootOptionGuid, mLegacyBootStorageName, sizeof (LEGACY_BOOT_NV_DATA), (UINT8 *) CurrentNVMap);
  DisMap  = mLegacyBootOptionPrivate->MaintainMapData->DisableMap;

  if (QuestionId >= LEGACY_FD_QUESTION_ID && QuestionId < LEGACY_FD_QUESTION_ID + MAX_MENU_NUMBER) {
    Number      = (UINT16) LegacyFDMenu.MenuNumber;
    BbsType     = BBS_FLOPPY;
    CurrentVal  = CurrentNVMap->LegacyFD;
    Default     = mLegacyBootOptionPrivate->MaintainMapData->LastTimeNvData.LegacyFD;
  } else if (QuestionId >= LEGACY_HD_QUESTION_ID && QuestionId < LEGACY_HD_QUESTION_ID + MAX_MENU_NUMBER) {
    Number      = (UINT16) LegacyHDMenu.MenuNumber;
    BbsType     = BBS_HARDDISK;
    CurrentVal  = CurrentNVMap->LegacyHD;
    Default     = mLegacyBootOptionPrivate->MaintainMapData->LastTimeNvData.LegacyHD;
  } else if (QuestionId >= LEGACY_CD_QUESTION_ID && QuestionId < LEGACY_CD_QUESTION_ID + MAX_MENU_NUMBER) {
    Number      = (UINT16) LegacyCDMenu.MenuNumber;
    BbsType     = BBS_CDROM;
    CurrentVal  = CurrentNVMap->LegacyCD;
    Default     = mLegacyBootOptionPrivate->MaintainMapData->LastTimeNvData.LegacyCD;
  } else if (QuestionId >= LEGACY_NET_QUESTION_ID && QuestionId < LEGACY_NET_QUESTION_ID + MAX_MENU_NUMBER) {
    Number      = (UINT16) LegacyNETMenu.MenuNumber;
    BbsType     = BBS_EMBED_NETWORK;
    CurrentVal  = CurrentNVMap->LegacyNET;
    Default     = mLegacyBootOptionPrivate->MaintainMapData->LastTimeNvData.LegacyNET;
  } else if (QuestionId >= LEGACY_BEV_QUESTION_ID && QuestionId < LEGACY_BEV_QUESTION_ID + MAX_MENU_NUMBER) {
    Number      = (UINT16) LegacyBEVMenu.MenuNumber;
    BbsType     = BBS_BEV_DEVICE;
    CurrentVal  = CurrentNVMap->LegacyBEV;
    Default     = mLegacyBootOptionPrivate->MaintainMapData->LastTimeNvData.LegacyBEV;
  }
  
  //
  //  First, find the different position
  //  if there is change, it should be only one
  //
  for (Index = 0; Index < Number; Index++) {
    if (CurrentVal[Index] != Default[Index]) {
      OldValue  = Default[Index];
      NewValue  = CurrentVal[Index];
      break;
    }
  }

  if (Index != Number) {
    //
    // there is change, now process
    //
    if (0xFF == NewValue) {
      //
      // This item will be disable
      // Just move the items behind this forward to overlap it
      //
      Pos = OldValue / 8;
      Bit = 7 - (OldValue % 8);
      DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));
      for (Index2 = Index; Index2 < Number - 1; Index2++) {
        CurrentVal[Index2] = CurrentVal[Index2 + 1];
      }

      CurrentVal[Index2] = 0xFF;
    } else {
      for (Index2 = 0; Index2 < Number; Index2++) {
        if (Index2 == Index) {
          continue;
        }

        if (Default[Index2] == NewValue) {
          //
          // If NewValue is in OldLegacyDev array
          // remember its old position
          //
          NewValuePos = Index2;
          break;
        }
      }

      if (Index2 != Number) {
        //
        // We will change current item to an existing item
        // (It's hard to describe here, please read code, it's like a cycle-moving)
        //
        for (Index2 = NewValuePos; Index2 != Index;) {
          if (NewValuePos < Index) {
            CurrentVal[Index2] = Default[Index2 + 1];
            Index2++;
          } else {
            CurrentVal[Index2] = Default[Index2 - 1];
            Index2--;
          }
        }
      } else {
        //
        // If NewValue is not in OldlegacyDev array, we are changing to a disabled item
        // so we should modify DisMap to reflect the change
        //
        Pos = NewValue / 8;
        Bit = 7 - (NewValue % 8);
        DisMap[Pos] = (UINT8) (DisMap[Pos] & (~ (UINT8) (1 << Bit)));
        if (0xFF != OldValue) {
          //
          // Because NewValue is a item that was disabled before
          // so after changing the OldValue should be disabled
          // actually we are doing a swap of enable-disable states of two items
          //
          Pos = OldValue / 8;
          Bit = 7 - (OldValue % 8);
          DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));
        }
      }
    }
    //
    // To prevent DISABLE appears in the middle of the list
    // we should perform a re-ordering
    //
    Index3 = Index;
    Index = 0;
    while (Index < Number) {
      if (0xFF != CurrentVal[Index]) {
        Index++;
        continue;
      }

      Index2 = Index;
      Index2++;
      while (Index2 < Number) {
        if (0xFF != CurrentVal[Index2]) {
          break;
        }

        Index2++;
      }

      if (Index2 < Number) {
        CurrentVal[Index]   = CurrentVal[Index2];
        CurrentVal[Index2]  = 0xFF;
      }

      Index++;
    }

    //
    // Return correct question value.
    //
    Value->u16 = CurrentVal[Index3];
    CopyMem (Default, CurrentVal, sizeof (UINT16) * Number);
  }

  //
  // Pass changed uncommitted data back to Form Browser
  //
  HiiSetBrowserData (&mLegacyBootOptionGuid, mLegacyBootStorageName, sizeof (LEGACY_BOOT_NV_DATA), (UINT8 *) CurrentNVMap, NULL);
}
コード例 #6
0
/**
  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 enerated the callback.
  @param[in]  Type               The type of value for the question.
  @param[in]  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.Currently not implemented.
  @retval EFI_INVALID_PARAMETERS Passing in wrong parameter.
  @retval Others                 Other errors as indicated.
**/
EFI_STATUS
EFIAPI
Ip4FormCallback (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
  IN  EFI_BROWSER_ACTION                     Action,
  IN  EFI_QUESTION_ID                        QuestionId,
  IN  UINT8                                  Type,
  IN  EFI_IFR_TYPE_VALUE                     *Value,
  OUT EFI_BROWSER_ACTION_REQUEST             *ActionRequest
  )
{
  IP4_CONFIG_INSTANCE       *Ip4ConfigInstance;
  CHAR8                     Ip4String[IP4_STR_MAX_SIZE];
  IP4_CONFIG_IFR_NVDATA     *IfrFormNvData;
  EFI_IP_ADDRESS            HostIp;
  EFI_IP_ADDRESS            SubnetMask;
  EFI_IP_ADDRESS            Gateway;
  EFI_STATUS                Status;
  EFI_INPUT_KEY             Key;

  Ip4ConfigInstance = IP4_CONFIG_INSTANCE_FROM_CONFIG_ACCESS (This);

  IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG_IFR_NVDATA));
  if (IfrFormNvData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Retrive uncommitted data from Browser
  //
  if (!HiiGetBrowserData (&mNicIp4ConfigNvDataGuid, EFI_NIC_IP4_CONFIG_VARIABLE, sizeof (IP4_CONFIG_IFR_NVDATA), (UINT8 *) IfrFormNvData)) {
    FreePool (IfrFormNvData);
    return EFI_NOT_FOUND;
  }

  Status = EFI_SUCCESS;

  switch (QuestionId) {

  case KEY_ENABLE:
    if (IfrFormNvData->Configure == 0) {
      Ip4ConfigInstance->Ip4ConfigCallbackInfo.Configured = FALSE;
    } else {
      Ip4ConfigInstance->Ip4ConfigCallbackInfo.Configured = TRUE;
    }
    break;

  case KEY_DHCP_ENABLE:
    if (IfrFormNvData->DhcpEnable == 0) {
      Ip4ConfigInstance->Ip4ConfigCallbackInfo.DhcpEnabled = FALSE;
    } else {
      Ip4ConfigInstance->Ip4ConfigCallbackInfo.DhcpEnabled = TRUE;
    }

    break;

  case KEY_LOCAL_IP:
    UnicodeStrToAsciiStr (IfrFormNvData->StationAddress, Ip4String);
    Status = Ip4AsciiStrToIp (Ip4String, &HostIp.v4);
    if (EFI_ERROR (Status) || !NetIp4IsUnicast (NTOHL (HostIp.Addr[0]), 0)) {
      CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL);
      Status = EFI_INVALID_PARAMETER;
    } else {
      CopyMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.LocalIp, &HostIp.v4, sizeof (HostIp.v4));
    }

    break;

  case KEY_SUBNET_MASK:
    UnicodeStrToAsciiStr (IfrFormNvData->SubnetMask, Ip4String);
    Status = Ip4AsciiStrToIp (Ip4String, &SubnetMask.v4);
    if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) {
      CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid SubnetMask!", NULL);
      Status = EFI_INVALID_PARAMETER;
    } else {
      CopyMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.SubnetMask, &SubnetMask.v4, sizeof (SubnetMask.v4));
    }

    break;

  case KEY_GATE_WAY:
    UnicodeStrToAsciiStr (IfrFormNvData->GatewayAddress, Ip4String);
    Status = Ip4AsciiStrToIp (Ip4String, &Gateway.v4);
    if (EFI_ERROR (Status) || ((Gateway.Addr[0] != 0) && !NetIp4IsUnicast (NTOHL (Gateway.Addr[0]), 0))) {
      CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Gateway!", NULL);
      Status = EFI_INVALID_PARAMETER;
    } else {
      CopyMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.Gateway, &Gateway.v4, sizeof (Gateway.v4));
    }

    break;

  case KEY_SAVE_CHANGES:

    Status = Ip4ConfigConvertIfrNvDataToDeviceConfigData (Ip4ConfigInstance);

    *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;

    break;

  default:

    break;
  }

  if (!EFI_ERROR (Status)) {
    //
    // Pass changed uncommitted data back to Form Browser
    //
    HiiSetBrowserData (&gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE, sizeof (IP4_CONFIG_IFR_NVDATA), (UINT8 *) IfrFormNvData, NULL);
  }

  FreePool (IfrFormNvData);

  return Status;
}
コード例 #7
0
/**
  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 enerated the callback.
  @param[in]  Type               The type of value for the question.
  @param[in]  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.Currently not implemented.
  @retval EFI_INVALID_PARAMETERS Passing in wrong parameter.
  @retval Others                 Other errors as indicated.

**/
EFI_STATUS
EFIAPI
Ip4FormCallback (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
  IN  EFI_BROWSER_ACTION                     Action,
  IN  EFI_QUESTION_ID                        QuestionId,
  IN  UINT8                                  Type,
  IN  EFI_IFR_TYPE_VALUE                     *Value,
  OUT EFI_BROWSER_ACTION_REQUEST             *ActionRequest
  )
{
  EFI_STATUS                Status;
  IP4_CONFIG2_INSTANCE      *Instance;
  IP4_CONFIG2_IFR_NVDATA    *IfrFormNvData;
  IP4_FORM_CALLBACK_INFO    *Private;

  EFI_IP_ADDRESS            StationAddress;
  EFI_IP_ADDRESS            SubnetMask;
  EFI_IP_ADDRESS            Gateway;
  IP4_ADDR                  Ip;
  EFI_IPv4_ADDRESS          *DnsAddress;
  UINTN                     DnsCount;
  UINTN                     Index;
  EFI_INPUT_KEY             Key;

  IfrFormNvData = NULL;
  DnsCount      = 0;
  DnsAddress    = NULL;

  if (Action == EFI_BROWSER_ACTION_CHANGED) {
    Private = IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS(This);
    Instance = IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK(Private);

    IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG2_IFR_NVDATA));
    if (IfrFormNvData == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    //
    // Retrieve uncommitted data from Browser
    //
    if (!HiiGetBrowserData (&gIp4Config2NvDataGuid, mIp4Config2StorageName, sizeof (IP4_CONFIG2_IFR_NVDATA), (UINT8 *) IfrFormNvData)) {
      FreePool (IfrFormNvData);
      return EFI_NOT_FOUND;
    }

    Status = EFI_SUCCESS;

    switch (QuestionId) {
    case KEY_LOCAL_IP:
      Status = Ip4Config2StrToIp (IfrFormNvData->StationAddress, &StationAddress.v4);
      if (EFI_ERROR (Status) || IP4_IS_UNSPECIFIED (NTOHL (StationAddress.Addr[0])) || IP4_IS_LOCAL_BROADCAST (NTOHL (StationAddress.Addr[0]))) {
        CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL);
        Status = EFI_INVALID_PARAMETER;
      }
      break;

    case KEY_SUBNET_MASK:
      Status = Ip4Config2StrToIp (IfrFormNvData->SubnetMask, &SubnetMask.v4);
      if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) {
        CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Subnet Mask!", NULL);
        Status = EFI_INVALID_PARAMETER;
      }
      break;

    case KEY_GATE_WAY:
      Status = Ip4Config2StrToIp (IfrFormNvData->GatewayAddress, &Gateway.v4);
      if (EFI_ERROR (Status) || IP4_IS_LOCAL_BROADCAST(NTOHL(Gateway.Addr[0]))) {
        CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Gateway!", NULL);
        Status = EFI_INVALID_PARAMETER;
      }
      break;

    case KEY_DNS:
      Status = Ip4Config2StrToIpList (IfrFormNvData->DnsAddress, &DnsAddress, &DnsCount);
      if (!EFI_ERROR (Status) && DnsCount > 0) {
        for (Index = 0; Index < DnsCount; Index ++) {
          CopyMem (&Ip, &DnsAddress[Index], sizeof (IP4_ADDR));
          if (IP4_IS_UNSPECIFIED (NTOHL (Ip)) || IP4_IS_LOCAL_BROADCAST (NTOHL (Ip))) {
            CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Dns Server!", NULL);
            Status = EFI_INVALID_PARAMETER;
            break;
          }
        }
      } else {
        if (EFI_ERROR (Status)) {
          CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Dns Server!", NULL);
        }
      }

      if(DnsAddress != NULL) {
        FreePool(DnsAddress);
      }
      break;

    case KEY_SAVE_CHANGES:
      Status = Ip4Config2ConvertIfrNvDataToConfigNvData (IfrFormNvData, Instance);
      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
      break;

    default:
      break;
    }

    FreePool (IfrFormNvData);

    return Status;
  }

  //
  // All other action return unsupported.
  //
  return EFI_UNSUPPORTED;
}
コード例 #8
0
ファイル: BootMaint.c プロジェクト: Cutty/edk2
/**
  This function processes the results of changes in configuration.


  @param This               Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param Action             Specifies the type of action taken by the browser.
  @param QuestionId         A unique value which is sent to the original exporting driver
                            so that it can identify the type of data to expect.
  @param Type               The type of value for the question.
  @param Value              A pointer to the data being sent to the original exporting driver.
  @param 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.
  @retval EFI_INVALID_PARAMETER The parameter of Value or ActionRequest is invalid.
**/
EFI_STATUS
EFIAPI
BootMaintCallback (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL         *This,
  IN        EFI_BROWSER_ACTION                     Action,
  IN        EFI_QUESTION_ID                        QuestionId,
  IN        UINT8                                  Type,
  IN        EFI_IFR_TYPE_VALUE                     *Value,
  OUT       EFI_BROWSER_ACTION_REQUEST             *ActionRequest
  )
{
  BMM_CALLBACK_DATA *Private;
  BM_MENU_ENTRY     *NewMenuEntry;
  BMM_FAKE_NV_DATA  *CurrentFakeNVMap;
  EFI_STATUS        Status;
  UINTN             OldValue;
  UINTN             NewValue;
  UINTN             Number;
  UINTN             Pos;
  UINTN             Bit;
  UINT16            NewValuePos;
  UINT16            Index3;  
  UINT16            Index2;
  UINT16            Index;
  UINT8             *OldLegacyDev;
  UINT8             *NewLegacyDev;
  UINT8             *DisMap;

  if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {    
    //
    // All other action return unsupported.
    //
    return EFI_UNSUPPORTED;
  }
  
  Status       = EFI_SUCCESS;
  OldValue     = 0;
  NewValue     = 0;
  Number       = 0;
  OldLegacyDev = NULL;
  NewLegacyDev = NULL;
  NewValuePos  = 0;
  DisMap       = NULL;

  Private      = BMM_CALLBACK_DATA_FROM_THIS (This);
  //
  // Retrive uncommitted data from Form Browser
  //
  CurrentFakeNVMap = &Private->BmmFakeNvData;
  HiiGetBrowserData (&gBootMaintFormSetGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap);
  if (Action == EFI_BROWSER_ACTION_CHANGING) {
    if (Value == NULL) {
      return EFI_INVALID_PARAMETER;
    }
    
    UpdatePageId (Private, QuestionId);

    //
    // need to be subtituded.
    //
    // Update Select FD/HD/CD/NET/BEV Order Form
    //
    if ((QuestionId >= LEGACY_FD_QUESTION_ID) && (QuestionId < LEGACY_BEV_QUESTION_ID + MAX_MENU_NUMBER)) {

      DisMap  = Private->BmmOldFakeNVData.DisableMap;

      if (QuestionId >= LEGACY_FD_QUESTION_ID && QuestionId < LEGACY_FD_QUESTION_ID + MAX_MENU_NUMBER) {
        Number        = (UINT16) LegacyFDMenu.MenuNumber;
        OldLegacyDev  = Private->BmmOldFakeNVData.LegacyFD;
        NewLegacyDev  = CurrentFakeNVMap->LegacyFD;
      } else if (QuestionId >= LEGACY_HD_QUESTION_ID && QuestionId < LEGACY_HD_QUESTION_ID + MAX_MENU_NUMBER) {
        Number        = (UINT16) LegacyHDMenu.MenuNumber;
        OldLegacyDev  = Private->BmmOldFakeNVData.LegacyHD;
        NewLegacyDev  = CurrentFakeNVMap->LegacyHD;
      } else if (QuestionId >= LEGACY_CD_QUESTION_ID && QuestionId < LEGACY_CD_QUESTION_ID + MAX_MENU_NUMBER) {
        Number        = (UINT16) LegacyCDMenu.MenuNumber;
        OldLegacyDev  = Private->BmmOldFakeNVData.LegacyCD;
        NewLegacyDev  = CurrentFakeNVMap->LegacyCD;
      } else if (QuestionId >= LEGACY_NET_QUESTION_ID && QuestionId < LEGACY_NET_QUESTION_ID + MAX_MENU_NUMBER) {
        Number        = (UINT16) LegacyNETMenu.MenuNumber;
        OldLegacyDev  = Private->BmmOldFakeNVData.LegacyNET;
        NewLegacyDev  = CurrentFakeNVMap->LegacyNET;
      } else if (QuestionId >= LEGACY_BEV_QUESTION_ID && QuestionId < LEGACY_BEV_QUESTION_ID + MAX_MENU_NUMBER) {
        Number        = (UINT16) LegacyBEVMenu.MenuNumber;
        OldLegacyDev  = Private->BmmOldFakeNVData.LegacyBEV;
        NewLegacyDev  = CurrentFakeNVMap->LegacyBEV;
      }
      //
      //  First, find the different position
      //  if there is change, it should be only one
      //
      for (Index = 0; Index < Number; Index++) {
        if (OldLegacyDev[Index] != NewLegacyDev[Index]) {
          OldValue  = OldLegacyDev[Index];
          NewValue  = NewLegacyDev[Index];
          break;
        }
      }

      if (Index != Number) {
        //
        // there is change, now process
        //
        if (0xFF == NewValue) {
          //
          // This item will be disable
          // Just move the items behind this forward to overlap it
          //
          Pos = OldValue / 8;
          Bit = 7 - (OldValue % 8);
          DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));
          for (Index2 = Index; Index2 < Number - 1; Index2++) {
            NewLegacyDev[Index2] = NewLegacyDev[Index2 + 1];
          }

          NewLegacyDev[Index2] = 0xFF;
        } else {
          for (Index2 = 0; Index2 < Number; Index2++) {
            if (Index2 == Index) {
              continue;
            }

            if (OldLegacyDev[Index2] == NewValue) {
              //
              // If NewValue is in OldLegacyDev array
              // remember its old position
              //
              NewValuePos = Index2;
              break;
            }
          }

          if (Index2 != Number) {
            //
            // We will change current item to an existing item
            // (It's hard to describe here, please read code, it's like a cycle-moving)
            //
            for (Index2 = NewValuePos; Index2 != Index;) {
              if (NewValuePos < Index) {
                NewLegacyDev[Index2] = OldLegacyDev[Index2 + 1];
                Index2++;
              } else {
                NewLegacyDev[Index2] = OldLegacyDev[Index2 - 1];
                Index2--;
              }
            }
          } else {
            //
            // If NewValue is not in OldlegacyDev array, we are changing to a disabled item
            // so we should modify DisMap to reflect the change
            //
            Pos = NewValue / 8;
            Bit = 7 - (NewValue % 8);
            DisMap[Pos] = (UINT8) (DisMap[Pos] & (~ (UINT8) (1 << Bit)));
            if (0xFF != OldValue) {
              //
              // Because NewValue is a item that was disabled before
              // so after changing the OldValue should be disabled
              // actually we are doing a swap of enable-disable states of two items
              //
              Pos = OldValue / 8;
              Bit = 7 - (OldValue % 8);
              DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));
            }
          }
        }
        //
        // To prevent DISABLE appears in the middle of the list
        // we should perform a re-ordering
        //
        Index3 = Index;
        Index = 0;
        while (Index < Number) {
          if (0xFF != NewLegacyDev[Index]) {
            Index++;
            continue;
          }

          Index2 = Index;
          Index2++;
          while (Index2 < Number) {
            if (0xFF != NewLegacyDev[Index2]) {
              break;
            }

            Index2++;
          }

          if (Index2 < Number) {
            NewLegacyDev[Index]   = NewLegacyDev[Index2];
            NewLegacyDev[Index2]  = 0xFF;
          }

          Index++;
        }

        CopyMem (
          OldLegacyDev,
          NewLegacyDev,
          Number
          );

        //
        //  Return correct question value.
        //
        Value->u8 = NewLegacyDev[Index3];
      }
    }

    if (QuestionId < FILE_OPTION_OFFSET) {
      if (QuestionId < CONFIG_OPTION_OFFSET) {
        switch (QuestionId) {
        case KEY_VALUE_BOOT_FROM_FILE:
          Private->FeCurrentState = FileExplorerStateBootFromFile;
          break;

        case FORM_BOOT_ADD_ID:
          Private->FeCurrentState = FileExplorerStateAddBootOption;
          break;

        case FORM_DRV_ADD_FILE_ID:
          Private->FeCurrentState = FileExplorerStateAddDriverOptionState;
          break;

        case FORM_DRV_ADD_HANDLE_ID:
          CleanUpPage (FORM_DRV_ADD_HANDLE_ID, Private);
          UpdateDrvAddHandlePage (Private);
          break;

        case FORM_BOOT_DEL_ID:
          CleanUpPage (FORM_BOOT_DEL_ID, Private);
          UpdateBootDelPage (Private);
          break;

        case FORM_BOOT_CHG_ID:
        case FORM_DRV_CHG_ID:
          UpdatePageBody (QuestionId, Private);
          break;

        case FORM_DRV_DEL_ID:
          CleanUpPage (FORM_DRV_DEL_ID, Private);
          UpdateDrvDelPage (Private);
          break;

        case FORM_BOOT_NEXT_ID:
          CleanUpPage (FORM_BOOT_NEXT_ID, Private);
          UpdateBootNextPage (Private);
          break;

        case FORM_TIME_OUT_ID:
          CleanUpPage (FORM_TIME_OUT_ID, Private);
          UpdateTimeOutPage (Private);
          break;

        case FORM_CON_IN_ID:
        case FORM_CON_OUT_ID:
        case FORM_CON_ERR_ID:
          UpdatePageBody (QuestionId, Private);
          break;

        case FORM_CON_MODE_ID:
          CleanUpPage (FORM_CON_MODE_ID, Private);
          UpdateConModePage (Private);
          break;

        case FORM_CON_COM_ID:
          CleanUpPage (FORM_CON_COM_ID, Private);
          UpdateConCOMPage (Private);
          break;

        case FORM_SET_FD_ORDER_ID:
        case FORM_SET_HD_ORDER_ID:
        case FORM_SET_CD_ORDER_ID:
        case FORM_SET_NET_ORDER_ID:
        case FORM_SET_BEV_ORDER_ID:
          CleanUpPage (QuestionId, Private);
          UpdateSetLegacyDeviceOrderPage (QuestionId, Private);
          break;

        default:
          break;
        }
      } else if ((QuestionId >= TERMINAL_OPTION_OFFSET) && (QuestionId < CONSOLE_OPTION_OFFSET)) {
        Index2                    = (UINT16) (QuestionId - TERMINAL_OPTION_OFFSET);
        Private->CurrentTerminal  = Index2;

        CleanUpPage (FORM_CON_COM_SETUP_ID, Private);
        UpdateTerminalPage (Private);

      } else if (QuestionId >= HANDLE_OPTION_OFFSET) {
        Index2                  = (UINT16) (QuestionId - HANDLE_OPTION_OFFSET);

        NewMenuEntry            = BOpt_GetMenuEntry (&DriverMenu, Index2);
        ASSERT (NewMenuEntry != NULL);
        Private->HandleContext  = (BM_HANDLE_CONTEXT *) NewMenuEntry->VariableContext;

        CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID, Private);

        Private->MenuEntry                  = NewMenuEntry;
        Private->LoadContext->FilePathList  = Private->HandleContext->DevicePath;

        UpdateDriverAddHandleDescPage (Private);
      }
    }
  } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
    if ((Value == NULL) || (ActionRequest == NULL)) {
      return EFI_INVALID_PARAMETER;
    }
    
    switch (QuestionId) {
    case KEY_VALUE_SAVE_AND_EXIT:
    case KEY_VALUE_NO_SAVE_AND_EXIT:
      if (QuestionId == KEY_VALUE_SAVE_AND_EXIT) {
        Status = ApplyChangeHandler (Private, CurrentFakeNVMap, Private->BmmPreviousPageId);
        if (EFI_ERROR (Status)) {
          return Status;
        }
      } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT) {
        DiscardChangeHandler (Private, CurrentFakeNVMap);
      }

      //
      // Tell browser not to ask for confirmation of changes,
      // since we have already applied or discarded.
      //
      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
      break;  

    case FORM_RESET:
      gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
      return EFI_UNSUPPORTED;

    default:
      break;
    }
  }

  //
  // Pass changed uncommitted data back to Form Browser
  //
  HiiSetBrowserData (&gBootMaintFormSetGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap, NULL);
  return EFI_SUCCESS;
}
コード例 #9
0
ファイル: BootMaint.c プロジェクト: FrozenXZeus/edk2
/**
  This function processes the results of changes in configuration.


  @param This               Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param Action             Specifies the type of action taken by the browser.
  @param QuestionId         A unique value which is sent to the original exporting driver
                            so that it can identify the type of data to expect.
  @param Type               The type of value for the question.
  @param Value              A pointer to the data being sent to the original exporting driver.
  @param 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.
  @retval EFI_INVALID_PARAMETER The parameter of Value or ActionRequest is invalid.
**/
EFI_STATUS
EFIAPI
BootMaintCallback (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL         *This,
  IN        EFI_BROWSER_ACTION                     Action,
  IN        EFI_QUESTION_ID                        QuestionId,
  IN        UINT8                                  Type,
  IN        EFI_IFR_TYPE_VALUE                     *Value,
  OUT       EFI_BROWSER_ACTION_REQUEST             *ActionRequest
  )
{
  BMM_CALLBACK_DATA *Private;
  BM_MENU_ENTRY     *NewMenuEntry;
  BMM_FAKE_NV_DATA  *CurrentFakeNVMap;
  EFI_STATUS        Status;
  UINTN             OldValue;
  UINTN             NewValue;
  UINTN             Number;
  UINTN             Index;

  //
  //Chech whether exit from FileExplorer and reenter BM,if yes,reclaim string depositories
  //
  if (Action == EFI_BROWSER_ACTION_FORM_OPEN){
    if(mEnterFileExplorer ){
      ReclaimStringDepository();
      mEnterFileExplorer = FALSE;
    }
  }

  if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {
    //
    // Do nothing for other UEFI Action. Only do call back when data is changed.
    //
    return EFI_UNSUPPORTED;
  }

  OldValue       = 0;
  NewValue       = 0;
  Number         = 0;

  Private        = BMM_CALLBACK_DATA_FROM_THIS (This);

  //
  // Retrive uncommitted data from Form Browser
  //
  CurrentFakeNVMap = &Private->BmmFakeNvData;
  HiiGetBrowserData (&mBootMaintGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap);

  if (Action == EFI_BROWSER_ACTION_CHANGING) {
    if (Value == NULL) {
      return EFI_INVALID_PARAMETER;
    }
    
    UpdatePageId (Private, QuestionId);

    if (QuestionId < FILE_OPTION_OFFSET) {
      if (QuestionId < CONFIG_OPTION_OFFSET) {
        switch (QuestionId) {
        case FORM_BOOT_ADD_ID:
          // Leave Bm and enter FileExplorer.
          Private->FeCurrentState = FileExplorerStateAddBootOption;
          Private->FeDisplayContext = FileExplorerDisplayUnknown;
          ReclaimStringDepository (); 
          UpdateFileExplorer(Private, 0);
          mEnterFileExplorer = TRUE;
          break;

        case FORM_DRV_ADD_FILE_ID:
          // Leave Bm and enter FileExplorer.
          Private->FeCurrentState = FileExplorerStateAddDriverOptionState;
          Private->FeDisplayContext = FileExplorerDisplayUnknown;
          ReclaimStringDepository ();
          UpdateFileExplorer(Private, 0);
          mEnterFileExplorer = TRUE;
          break;

        case FORM_DRV_ADD_HANDLE_ID:
          CleanUpPage (FORM_DRV_ADD_HANDLE_ID, Private);
          UpdateDrvAddHandlePage (Private);
          break;

        case FORM_BOOT_DEL_ID:
          CleanUpPage (FORM_BOOT_DEL_ID, Private);
          UpdateBootDelPage (Private);
          break;

        case FORM_BOOT_CHG_ID:
        case FORM_DRV_CHG_ID:
          UpdatePageBody (QuestionId, Private);
          break;

        case FORM_DRV_DEL_ID:
          CleanUpPage (FORM_DRV_DEL_ID, Private);
          UpdateDrvDelPage (Private);
          break;

        case FORM_BOOT_NEXT_ID:
          CleanUpPage (FORM_BOOT_NEXT_ID, Private);
          UpdateBootNextPage (Private);
          break;

        case FORM_TIME_OUT_ID:
          CleanUpPage (FORM_TIME_OUT_ID, Private);
          UpdateTimeOutPage (Private);
          break;

        case FORM_CON_IN_ID:
        case FORM_CON_OUT_ID:
        case FORM_CON_ERR_ID:
          UpdatePageBody (QuestionId, Private);
          break;

        case FORM_CON_MODE_ID:
          CleanUpPage (FORM_CON_MODE_ID, Private);
          UpdateConModePage (Private);
          break;

        case FORM_CON_COM_ID:
          CleanUpPage (FORM_CON_COM_ID, Private);
          UpdateConCOMPage (Private);
          break;

        default:
          break;
        }
      } else if ((QuestionId >= TERMINAL_OPTION_OFFSET) && (QuestionId < CONSOLE_OPTION_OFFSET)) {
        Index                  = (UINT16) (QuestionId - TERMINAL_OPTION_OFFSET);
        Private->CurrentTerminal  = Index;

        CleanUpPage (FORM_CON_COM_SETUP_ID, Private);
        UpdateTerminalPage (Private);

      } else if (QuestionId >= HANDLE_OPTION_OFFSET) {
        Index                  = (UINT16) (QuestionId - HANDLE_OPTION_OFFSET);

        NewMenuEntry            = BOpt_GetMenuEntry (&DriverMenu, Index);
        ASSERT (NewMenuEntry != NULL);
        Private->HandleContext  = (BM_HANDLE_CONTEXT *) NewMenuEntry->VariableContext;

        CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID, Private);

        Private->MenuEntry                  = NewMenuEntry;
        Private->LoadContext->FilePathList  = Private->HandleContext->DevicePath;

        UpdateDriverAddHandleDescPage (Private);
      }
    }
    if (QuestionId == KEY_VALUE_BOOT_FROM_FILE){
      // Leave Bm and enter FileExplorer.
      Private->FeCurrentState = FileExplorerStateBootFromFile;
      Private->FeDisplayContext = FileExplorerDisplayUnknown;
      ReclaimStringDepository ();
      UpdateFileExplorer(Private, 0);
      mEnterFileExplorer = TRUE;
    }
  } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
    if ((Value == NULL) || (ActionRequest == NULL)) {
      return EFI_INVALID_PARAMETER;
    }

    switch (QuestionId) {
    case KEY_VALUE_SAVE_AND_EXIT:
    case KEY_VALUE_NO_SAVE_AND_EXIT:
      if (QuestionId == KEY_VALUE_SAVE_AND_EXIT) {
        Status = ApplyChangeHandler (Private, CurrentFakeNVMap, Private->BmmPreviousPageId);
        if (EFI_ERROR (Status)) {
          return Status;
        }
      } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT) {
        DiscardChangeHandler (Private, CurrentFakeNVMap);
      }

      //
      // Tell browser not to ask for confirmation of changes,
      // since we have already applied or discarded.
      //
      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;

      break;
 
    case FORM_RESET:
      gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
      return EFI_UNSUPPORTED;

    default:
      break;
    }
  }

  //
  // Pass changed uncommitted data back to Form Browser
  //
  HiiSetBrowserData (&mBootMaintGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap, NULL);

  return EFI_SUCCESS;
}
コード例 #10
0
ファイル: BootMaintenance.c プロジェクト: agileinsider/edk2
/**
  This function processes the results of changes in configuration.


  @param This               Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param Action             Specifies the type of action taken by the browser.
  @param QuestionId         A unique value which is sent to the original exporting driver
                            so that it can identify the type of data to expect.
  @param Type               The type of value for the question.
  @param Value              A pointer to the data being sent to the original exporting driver.
  @param 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.
  @retval EFI_INVALID_PARAMETER The parameter of Value or ActionRequest is invalid.
**/
EFI_STATUS
EFIAPI
BootMaintCallback (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL         *This,
  IN        EFI_BROWSER_ACTION                     Action,
  IN        EFI_QUESTION_ID                        QuestionId,
  IN        UINT8                                  Type,
  IN        EFI_IFR_TYPE_VALUE                     *Value,
  OUT       EFI_BROWSER_ACTION_REQUEST             *ActionRequest
  )
{
  BMM_CALLBACK_DATA *Private;
  BM_MENU_ENTRY     *NewMenuEntry;
  BMM_FAKE_NV_DATA  *CurrentFakeNVMap;
  UINTN             Index;
  EFI_DEVICE_PATH_PROTOCOL * File;

  if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {
    //
    // Do nothing for other UEFI Action. Only do call back when data is changed.
    //
    return EFI_UNSUPPORTED;
  }

  Private        = BMM_CALLBACK_DATA_FROM_THIS (This);
  //
  // Retrive uncommitted data from Form Browser
  //
  CurrentFakeNVMap = &Private->BmmFakeNvData;
  HiiGetBrowserData (&mBootMaintGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap);

  if (Action == EFI_BROWSER_ACTION_CHANGING) {
    if (Value == NULL) {
      return EFI_INVALID_PARAMETER;
    }
    
    UpdatePageId (Private, QuestionId);

    if (QuestionId < FILE_OPTION_OFFSET) {
      if (QuestionId < CONFIG_OPTION_OFFSET) {
        switch (QuestionId) {
        case FORM_BOOT_ADD_ID:
          // Leave BMM and enter FileExplorer. 
          ChooseFile (NULL, L".efi", CreateBootOptionFromFile, &File);
          break;

        case FORM_DRV_ADD_FILE_ID:
          // Leave BMM and enter FileExplorer.
          ChooseFile (NULL, L".efi", CreateDriverOptionFromFile, &File);
          break;

        case FORM_DRV_ADD_HANDLE_ID:
          CleanUpPage (FORM_DRV_ADD_HANDLE_ID, Private);
          UpdateDrvAddHandlePage (Private);
          break;

        case FORM_BOOT_DEL_ID:
          CleanUpPage (FORM_BOOT_DEL_ID, Private);
          UpdateBootDelPage (Private);
          break;

        case FORM_BOOT_CHG_ID:
        case FORM_DRV_CHG_ID:
          UpdatePageBody (QuestionId, Private);
          break;

        case FORM_DRV_DEL_ID:
          CleanUpPage (FORM_DRV_DEL_ID, Private);
          UpdateDrvDelPage (Private);
          break;

        case FORM_CON_IN_ID:
        case FORM_CON_OUT_ID:
        case FORM_CON_ERR_ID:
          UpdatePageBody (QuestionId, Private);
          break;

        case FORM_CON_MODE_ID:
          CleanUpPage (FORM_CON_MODE_ID, Private);
          UpdateConModePage (Private);
          break;

        case FORM_CON_COM_ID:
          CleanUpPage (FORM_CON_COM_ID, Private);
          UpdateConCOMPage (Private);
          break;

        default:
          break;
        }
      } else if ((QuestionId >= TERMINAL_OPTION_OFFSET) && (QuestionId < CONSOLE_OPTION_OFFSET)) {
        Index                  = (UINT16) (QuestionId - TERMINAL_OPTION_OFFSET);
        Private->CurrentTerminal  = Index;

        CleanUpPage (FORM_CON_COM_SETUP_ID, Private);
        UpdateTerminalPage (Private);

      } else if (QuestionId >= HANDLE_OPTION_OFFSET) {
        Index                  = (UINT16) (QuestionId - HANDLE_OPTION_OFFSET);

        NewMenuEntry            = BOpt_GetMenuEntry (&DriverMenu, Index);
        ASSERT (NewMenuEntry != NULL);
        Private->HandleContext  = (BM_HANDLE_CONTEXT *) NewMenuEntry->VariableContext;

        CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID, Private);

        Private->MenuEntry                  = NewMenuEntry;
        Private->LoadContext->FilePathList  = Private->HandleContext->DevicePath;

        UpdateDriverAddHandleDescPage (Private);
      }
    }
    if (QuestionId == KEY_VALUE_BOOT_FROM_FILE){
      // Leave BMM and enter FileExplorer.
      ChooseFile (NULL, L".efi", BootFromFile, &File);
    }
  } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
    if ((Value == NULL) || (ActionRequest == NULL)) {
      return EFI_INVALID_PARAMETER;
    }
   
    if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_BOOT) {
      CurrentFakeNVMap->BootOptionChanged = FALSE;
      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
    } else if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_DRIVER) {
      CurrentFakeNVMap->DriverOptionChanged = FALSE;
      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
    } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_DRIVER) {
      //
      // Discard changes and exit formset
      //
      CurrentFakeNVMap->DriverOptionalData[0]     = 0x0000;
      CurrentFakeNVMap->DriverDescriptionData[0]  = 0x0000;
      CurrentFakeNVMap->DriverOptionChanged = FALSE;
      CurrentFakeNVMap->ForceReconnect      = TRUE;
      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
    } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_BOOT) {
      //
      // Discard changes and exit formset
      //
      CurrentFakeNVMap->BootOptionalData[0]     = 0x0000;
      CurrentFakeNVMap->BootDescriptionData[0]  = 0x0000;
      CurrentFakeNVMap->BootOptionChanged = FALSE;
      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
    } else if (QuestionId == KEY_VALUE_BOOT_DESCRIPTION || QuestionId == KEY_VALUE_BOOT_OPTION) {
      CurrentFakeNVMap->BootOptionChanged = TRUE;
    } else if (QuestionId == KEY_VALUE_DRIVER_DESCRIPTION || QuestionId == KEY_VALUE_DRIVER_OPTION) {
      CurrentFakeNVMap->DriverOptionChanged = TRUE;
    } 

    if ((QuestionId >= BOOT_OPTION_DEL_QUESTION_ID) && (QuestionId < BOOT_OPTION_DEL_QUESTION_ID + MAX_MENU_NUMBER)) {
      if (Value->b){
        //
        // Means user try to delete this boot option but not press F10 or "Commit Changes and Exit" menu.
        //
        CurrentFakeNVMap->BootOptionDelMark[QuestionId - BOOT_OPTION_DEL_QUESTION_ID] = TRUE;
      } else {
        //
        // Means user remove the old check status.
        //
        CurrentFakeNVMap->BootOptionDelMark[QuestionId - BOOT_OPTION_DEL_QUESTION_ID] = FALSE;
      }
    } else if ((QuestionId >= DRIVER_OPTION_DEL_QUESTION_ID) && (QuestionId < DRIVER_OPTION_DEL_QUESTION_ID + MAX_MENU_NUMBER)) {
      if (Value->b){
        CurrentFakeNVMap->DriverOptionDelMark[QuestionId - DRIVER_OPTION_DEL_QUESTION_ID] = TRUE;
      } else {
        CurrentFakeNVMap->DriverOptionDelMark[QuestionId - DRIVER_OPTION_DEL_QUESTION_ID] = FALSE;
      }
    } else {
      switch (QuestionId) {
      case KEY_VALUE_SAVE_AND_EXIT:
      case KEY_VALUE_NO_SAVE_AND_EXIT:
        if (QuestionId == KEY_VALUE_SAVE_AND_EXIT) {
          *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
        } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT) {
          DiscardChangeHandler (Private, CurrentFakeNVMap);
          *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
        }

        break;

      case FORM_RESET:
        gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
        return EFI_UNSUPPORTED;

      default:
        break;
      }
    }
  }

  //
  // Pass changed uncommitted data back to Form Browser
  //
  HiiSetBrowserData (&mBootMaintGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap, NULL);

  return EFI_SUCCESS;
}