コード例 #1
1
ファイル: BootManager.c プロジェクト: wensunshine/VisualUefi
/**
  This function invokes Boot Manager. If all devices have not a chance to be connected,
  the connect all will be triggered. It then enumerate all boot options. If 
  a boot option from the Boot Manager page is selected, Boot Manager will boot
  from this boot option.
  
**/
VOID
UpdateBootManager (
  VOID
  )
{
  UINTN                         Index;
  EFI_BOOT_MANAGER_LOAD_OPTION  *BootOption;
  UINTN                         BootOptionCount;
  EFI_STRING_ID                 Token;
  CHAR16                        *HelpString;
  EFI_STRING_ID                 HelpToken;
  UINT16                        *TempStr;
  EFI_HII_HANDLE                HiiHandle;
  UINTN                         TempSize;
  VOID                          *StartOpCodeHandle;
  VOID                          *EndOpCodeHandle;
  EFI_IFR_GUID_LABEL            *StartLabel;
  EFI_IFR_GUID_LABEL            *EndLabel;
  UINT16                        DeviceType;
  BOOLEAN                       IsLegacyOption;
  BOOLEAN                       NeedEndOp;
  UINTN                         MaxLen;

  DeviceType = (UINT16) -1;

  EfiBootManagerConnectAll ();

  //
  // for better user experience
  // 1. User changes HD configuration (e.g.: unplug HDD), here we have a chance to remove the HDD boot option
  // 2. User enables/disables UEFI PXE, here we have a chance to add/remove EFI Network boot option
  //
  EfiBootManagerRefreshAllBootOption ();

  //
  // BdsDxe doesn't group the legacy boot options for the same device type
  // It's UI's choice.
  //
  GroupMultipleLegacyBootOption4SameType ();

  BootOption = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);

  HiiHandle = gBootManagerPrivate.HiiHandle;

  //
  // Allocate space for creation of UpdateData Buffer
  //
  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (StartOpCodeHandle != NULL);

  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (EndOpCodeHandle != NULL);

  //
  // Create Hii Extend Label OpCode as the start opcode
  //
  StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  StartLabel->Number       = LABEL_BOOT_OPTION;

  //
  // Create Hii Extend Label OpCode as the end opcode
  //
  EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  EndLabel->Number       = LABEL_BOOT_OPTION_END;
  mKeyInput = 0;
  NeedEndOp = FALSE;
  for (Index = 0; Index < BootOptionCount; Index++) {
    //
    // At this stage we are creating a menu entry, thus the Keys are reproduceable
    //
    mKeyInput++;

    //
    // Don't display the hidden/inactive boot option
    //
    if (((BootOption[Index].Attributes & LOAD_OPTION_HIDDEN) != 0) || ((BootOption[Index].Attributes & LOAD_OPTION_ACTIVE) == 0)) {
      continue;
    }

    //
    // Group the legacy boot option in the sub title created dynamically
    //
    IsLegacyOption = (BOOLEAN) (
                       (DevicePathType (BootOption[Index].FilePath) == BBS_DEVICE_PATH) &&
                       (DevicePathSubType (BootOption[Index].FilePath) == BBS_BBS_DP)
                       );

    if (!IsLegacyOption && NeedEndOp) {
      NeedEndOp = FALSE;
      HiiCreateEndOpCode (StartOpCodeHandle);
    }
    
    if (IsLegacyOption && DeviceType != ((BBS_BBS_DEVICE_PATH *) BootOption[Index].FilePath)->DeviceType) {
      if (NeedEndOp) {
        HiiCreateEndOpCode (StartOpCodeHandle);
      }

      DeviceType = ((BBS_BBS_DEVICE_PATH *) BootOption[Index].FilePath)->DeviceType;
      Token      = HiiSetString (
                     HiiHandle,
                     0,
                     mDeviceTypeStr[
                       MIN (DeviceType & 0xF, sizeof (mDeviceTypeStr) / sizeof (mDeviceTypeStr[0]) - 1)
                       ],
                     NULL
                     );
      HiiCreateSubTitleOpCode (StartOpCodeHandle, Token, 0, 0, 1);
      NeedEndOp = TRUE;
    }

    ASSERT (BootOption[Index].Description != NULL);

    Token = HiiSetString (HiiHandle, 0, BootOption[Index].Description, NULL);

    TempStr = BmDevicePathToStr (BootOption[Index].FilePath);
    TempSize = StrSize (TempStr);
    HelpString = AllocateZeroPool (TempSize + StrSize (L"Device Path : "));
    MaxLen = (TempSize + StrSize (L"Device Path : "))/sizeof(CHAR16);
    ASSERT (HelpString != NULL);
    StrCatS (HelpString, MaxLen, L"Device Path : ");
    StrCatS (HelpString, MaxLen, TempStr);

    HelpToken = HiiSetString (HiiHandle, 0, HelpString, NULL);

    HiiCreateActionOpCode (
      StartOpCodeHandle,
      mKeyInput,
      Token,
      HelpToken,
      EFI_IFR_FLAG_CALLBACK,
      0
      );
  }

  if (NeedEndOp) {
    HiiCreateEndOpCode (StartOpCodeHandle);
  }

  HiiUpdateForm (
    HiiHandle,
    &mBootManagerGuid,
    BOOT_MANAGER_FORM_ID,
    StartOpCodeHandle,
    EndOpCodeHandle
    );

  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);

  EfiBootManagerFreeLoadOptions (BootOption, BootOptionCount);
}
コード例 #2
0
ファイル: OpcodeCreation.c プロジェクト: EvanLloyd/tianocore
/**
  Create UEFI HII Text Opcode from a Framework HII Text Opcode.

  @param UefiUpdateDataHandle  The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
  @param FwOpcode              The input Framework Opcode.

  @retval NULL   There is not enough space left in Buffer to add the opcode.
  @retval Other  A pointer to the created opcode.
  
**/
UINT8 *
F2UCreateTextOpCode (
  IN OUT   VOID                        *UefiUpdateDataHandle,
  IN CONST FRAMEWORK_EFI_IFR_TEXT      *FwOpcode
  )
{
  EFI_IFR_TEXT      UTextOpCode;

  if ((FwOpcode->Flags & EFI_IFR_FLAG_INTERACTIVE) == 0) {
    ZeroMem (&UTextOpCode, sizeof(UTextOpCode));
    
    UTextOpCode.Header.OpCode = EFI_IFR_TEXT_OP;
    UTextOpCode.Header.Length = (UINT8) sizeof (EFI_IFR_TEXT);

    UTextOpCode.Statement.Help   = FwOpcode->Help;

    UTextOpCode.Statement.Prompt = FwOpcode->Text;
    UTextOpCode.TextTwo          = FwOpcode->TextTwo;
    
    return HiiCreateRawOpCodes (UefiUpdateDataHandle, (UINT8 *) &UTextOpCode, sizeof(UTextOpCode));
  } else {
    //
    // Iteractive Text Opcode is EFI_IFR_ACTION
    //
    return HiiCreateActionOpCode (UefiUpdateDataHandle, FwOpcode->Key, FwOpcode->Text, FwOpcode->Help, EFI_IFR_FLAG_CALLBACK, 0);
  }
}
コード例 #3
0
ファイル: UpdatePage.c プロジェクト: AshleyDeSimone/edk2
/**
  Create the "Apply changes" and "Discard changes" tags. And
  ensure user can return to the main page.

  @param CallbackData    The BMM context data.

**/
VOID
UpdatePageEnd (
  IN BMM_CALLBACK_DATA                *CallbackData
  )
{
  //
  // Create the "Apply changes" and "Discard changes" tags.
  //
  if (CallbackData->BmmAskSaveOrNot) {
    HiiCreateSubTitleOpCode (
      mStartOpCodeHandle,
      STRING_TOKEN (STR_NULL_STRING),
      0,
      0,
      0
      );

    HiiCreateActionOpCode (
      mStartOpCodeHandle,
      KEY_VALUE_SAVE_AND_EXIT,
      STRING_TOKEN (STR_SAVE_AND_EXIT),
      STRING_TOKEN (STR_NULL_STRING),
      EFI_IFR_FLAG_CALLBACK,
      0
      );
  }

  //
  // Ensure user can return to the main page.
  //
  HiiCreateActionOpCode (
    mStartOpCodeHandle,
    KEY_VALUE_NO_SAVE_AND_EXIT,
    STRING_TOKEN (STR_NO_SAVE_AND_EXIT),
    STRING_TOKEN (STR_NULL_STRING),
    EFI_IFR_FLAG_CALLBACK,
    0
    );

  HiiUpdateForm (
    CallbackData->BmmHiiHandle,
    &gBootMaintFormSetGuid,
    CallbackData->BmmCurrentPageId,
    mStartOpCodeHandle, // Label CallbackData->BmmCurrentPageId
    mEndOpCodeHandle    // LABEL_END
    );
}
コード例 #4
0
ファイル: FileExplorer.c プロジェクト: wensunshine/VisualUefi
/**

  Update the File Explore page.

**/
VOID
LibUpdateFileExplorePage (
  VOID
  )
{
  UINTN           Index;
  MENU_ENTRY      *NewMenuEntry;
  FILE_CONTEXT    *NewFileContext;
  MENU_OPTION     *MenuOption;

  NewMenuEntry    = NULL;
  NewFileContext  = NULL;

  LibRefreshUpdateData ();
  MenuOption = gFileExplorerPrivate.FsOptionMenu;

  for (Index = 0; Index < MenuOption->MenuNumber; Index++) {
    NewMenuEntry    = LibGetMenuEntry (MenuOption, Index);
    NewFileContext  = (FILE_CONTEXT *) NewMenuEntry->VariableContext;

    if (!NewFileContext->IsDir) {
      //
      // Create Text opcode for directory, also create Text opcode for file in FileExplorerStateBootFromFile.
      //
      HiiCreateActionOpCode (
        mLibStartOpCodeHandle,
        (UINT16) (FILE_OPTION_OFFSET + Index),
        NewMenuEntry->DisplayStringToken,
        STRING_TOKEN (STR_NULL_STRING),
        EFI_IFR_FLAG_CALLBACK,
        0
        );
    } else {
      //
      // Create Goto opcode for file in FileExplorerStateAddBootOption or FileExplorerStateAddDriverOptionState.
      //
      HiiCreateGotoOpCode (
        mLibStartOpCodeHandle,
        FORM_FILE_EXPLORER_ID,
        NewMenuEntry->DisplayStringToken,
        STRING_TOKEN (STR_NULL_STRING),
        EFI_IFR_FLAG_CALLBACK,
        (UINT16) (FILE_OPTION_OFFSET + Index)
        );
    }
  }

  HiiUpdateForm (
    gFileExplorerPrivate.FeHiiHandle,
    &FileExplorerGuid,
    FORM_FILE_EXPLORER_ID,
    mLibStartOpCodeHandle, // Label FORM_FILE_EXPLORER_ID
    mLibEndOpCodeHandle    // LABEL_END
    );
}
コード例 #5
0
ファイル: ModifyAccessPolicy.c プロジェクト: etiago/vbox
/**
  Create an action OpCode with QuestionID and DevicePath on a given OpCodeHandle.

  @param[in]  QuestionID            The question ID.
  @param[in]  DevicePath            Points to device path.
  @param[in]  OpCodeHandle          Points to container for dynamic created opcodes.

**/
VOID
AddDevicePath (
  IN  UINTN                                     QuestionID,
  IN  EFI_DEVICE_PATH_PROTOCOL                  *DevicePath,
  IN     VOID                                   *OpCodeHandle
  )
{
  EFI_STATUS                        Status;
  EFI_DEVICE_PATH_PROTOCOL          *Next;
  EFI_STRING_ID                     NameID;
  EFI_STRING                        DriverName;
  EFI_DEVICE_PATH_TO_TEXT_PROTOCOL  *DevicePathText;

  //
  // Locate device path to text protocol.
  //
  Status = gBS->LocateProtocol (
                  &gEfiDevicePathToTextProtocolGuid,
                  NULL,
                  (VOID **) &DevicePathText
                  );
  if (EFI_ERROR (Status)) {
    return ;
  }
  
  //
  // Get driver file name node.
  //
  Next = DevicePath;
  while (!IsDevicePathEnd (Next)) {
    DevicePath  = Next;
    Next        = NextDevicePathNode (Next);
  }

  //
  // Display the device path in form.
  //
  DriverName = DevicePathText->ConvertDevicePathToText (DevicePath, FALSE, FALSE);
  NameID = HiiSetString (mCallbackInfo->HiiHandle, 0, DriverName, NULL);
  FreePool (DriverName);
  if (NameID == 0) {
    return ;
  }

  HiiCreateActionOpCode (
    OpCodeHandle,                   // Container for dynamic created opcodes
    (UINT16) QuestionID,            // Question ID
    NameID,                         // Prompt text
    STRING_TOKEN (STR_NULL_STRING), // Help text
    EFI_IFR_FLAG_CALLBACK,          // Question flag
    0                               // Action String ID
    );
}
コード例 #6
0
/**
  Create Reset menu in the front page.

  @param[in]    HiiHandle           The hii handle for the Uiapp driver.
  @param[in]    StartOpCodeHandle   The opcode handle to save the new opcode.

**/
VOID
UiCreateResetMenu (
  IN EFI_HII_HANDLE              HiiHandle,
  IN VOID                        *StartOpCodeHandle
  )
{
  HiiCreateActionOpCode (
    StartOpCodeHandle,
    FRONT_PAGE_KEY_RESET,
    STRING_TOKEN (STR_RESET_STRING),
    STRING_TOKEN (STR_RESET_STRING),
    EFI_IFR_FLAG_CALLBACK,
    0
    );
}
コード例 #7
0
/**
  Create continue menu in the front page.

  @param[in]    HiiHandle           The hii handle for the Uiapp driver.
  @param[in]    StartOpCodeHandle   The opcode handle to save the new opcode.

**/
VOID
UiCreateContinueMenu (
  IN EFI_HII_HANDLE              HiiHandle,
  IN VOID                        *StartOpCodeHandle
  )
{
  HiiCreateActionOpCode (
    StartOpCodeHandle,
    FRONT_PAGE_KEY_CONTINUE,
    STRING_TOKEN (STR_CONTINUE_PROMPT),
    STRING_TOKEN (STR_CONTINUE_PROMPT),
    EFI_IFR_FLAG_CALLBACK,
    0
    );
}
コード例 #8
0
ファイル: UserProfileDelete.c プロジェクト: jeppeter/vbox
/**
  Add a username item in form.

  @param[in]  User          Points to the user profile whose username is added.
  @param[in]  Index         The index of the user in the user name list
  @param[in]  OpCodeHandle  Points to container for dynamic created opcodes.

**/
VOID
AddUserToForm (
  IN  EFI_USER_PROFILE_HANDLE                   User,
  IN  UINT16                                    Index,
  IN  VOID                                      *OpCodeHandle
  )
{
  EFI_STRING_ID NameId;

  //
  // Get user name
  //
  NameId = GetUserName (User);
  if (NameId == 0) {
    return ;
  }

  //
  // Create user name option.
  //
  switch (Index & KEY_FIRST_FORM_MASK) {
  case KEY_MODIFY_USER:
    HiiCreateGotoOpCode (
      OpCodeHandle,                   // Container for dynamic created opcodes
      FORMID_USER_INFO,               // Target Form ID
      NameId,                         // Prompt text
      STRING_TOKEN (STR_NULL_STRING), // Help text
      EFI_IFR_FLAG_CALLBACK,          // Question flag
      Index                           // Question ID
      );
    break;

  case KEY_DEL_USER:
    HiiCreateActionOpCode (
      OpCodeHandle,                   // Container for dynamic created opcodes
      Index,                          // Question ID
      NameId,                         // Prompt text
      STRING_TOKEN (STR_NULL_STRING), // Help text
      EFI_IFR_FLAG_CALLBACK,          // Question flag
      0                               // Action String ID
      );
    break;

  default:
    break;
  }
}
コード例 #9
0
ファイル: FileExplorer.c プロジェクト: kraxel/edk2
/**

  Update the File Explore page.

**/
VOID
LibUpdateFileExplorePage (
  VOID
  )
{
  UINTN           Index;
  MENU_ENTRY      *NewMenuEntry;
  FILE_CONTEXT    *NewFileContext;
  MENU_OPTION     *MenuOption;
  BOOLEAN         CreateNewFile;

  NewMenuEntry    = NULL;
  NewFileContext  = NULL;
  CreateNewFile   = FALSE;

  LibRefreshUpdateData ();
  MenuOption = gFileExplorerPrivate.FsOptionMenu;

  mQuestionIdUpdate += QUESTION_ID_UPDATE_STEP;

  for (Index = 0; Index < MenuOption->MenuNumber; Index++) {
    NewMenuEntry    = LibGetMenuEntry (MenuOption, Index);
    NewFileContext  = (FILE_CONTEXT *) NewMenuEntry->VariableContext;

    if (!NewFileContext->IsRoot && !CreateNewFile) {
      HiiCreateGotoOpCode (
        mLibStartOpCodeHandle,
        FORM_ADD_NEW_FILE_ID,
        STRING_TOKEN (STR_NEW_FILE),
        STRING_TOKEN (STR_NEW_FILE_HELP),
        EFI_IFR_FLAG_CALLBACK,
        (UINT16) (mNewFileQuestionId++)
        );
      HiiCreateGotoOpCode (
        mLibStartOpCodeHandle,
        FORM_ADD_NEW_FOLDER_ID,
        STRING_TOKEN (STR_NEW_FOLDER),
        STRING_TOKEN (STR_NEW_FOLDER_HELP),
        EFI_IFR_FLAG_CALLBACK,
        (UINT16) (mNewFolderQuestionId++)
        );
      HiiCreateTextOpCode(
        mLibStartOpCodeHandle,
        STRING_TOKEN (STR_NULL_STRING),
        STRING_TOKEN (STR_NULL_STRING),
        0
        );
      CreateNewFile = TRUE;
    }

    if (!NewFileContext->IsDir) {
      //
      // Create Text opcode for directory, also create Text opcode for file in FileExplorerStateBootFromFile.
      //
      HiiCreateActionOpCode (
        mLibStartOpCodeHandle,
        (UINT16) (FILE_OPTION_OFFSET + Index + mQuestionIdUpdate),
        NewMenuEntry->DisplayStringToken,
        STRING_TOKEN (STR_NULL_STRING),
        EFI_IFR_FLAG_CALLBACK,
        0
        );
    } else {
      //
      // Create Goto opcode for file in FileExplorerStateAddBootOption or FileExplorerStateAddDriverOptionState.
      //
      HiiCreateGotoOpCode (
        mLibStartOpCodeHandle,
        FORM_FILE_EXPLORER_ID,
        NewMenuEntry->DisplayStringToken,
        STRING_TOKEN (STR_NULL_STRING),
        EFI_IFR_FLAG_CALLBACK,
        (UINT16) (FILE_OPTION_OFFSET + Index + mQuestionIdUpdate)
        );
    }
  }

  HiiUpdateForm (
    gFileExplorerPrivate.FeHiiHandle,
    &FileExplorerGuid,
    FORM_FILE_EXPLORER_ID,
    mLibStartOpCodeHandle, // Label FORM_FILE_EXPLORER_ID
    mLibEndOpCodeHandle    // LABEL_END
    );
}
コード例 #10
0
ファイル: FileExplorer.c プロジェクト: ronnychevalier/edk2
/**
  Update the File Explore page.

  @param CallbackData    The BMM context data.
  @param MenuOption      Pointer to menu options to display.

**/
VOID
UpdateFileExplorePage (
  IN BMM_CALLBACK_DATA            *CallbackData,
  BM_MENU_OPTION                  *MenuOption
  )
{
  UINTN           Index;
  BM_MENU_ENTRY   *NewMenuEntry;
  BM_FILE_CONTEXT *NewFileContext;
  EFI_FORM_ID     FormId;

  NewMenuEntry    = NULL;
  NewFileContext  = NULL;
  FormId          = 0;

  RefreshUpdateData ();
  mStartLabel->Number = FORM_FILE_EXPLORER_ID;

  for (Index = 0; Index < MenuOption->MenuNumber; Index++) {
    NewMenuEntry    = BOpt_GetMenuEntry (MenuOption, Index);
    NewFileContext  = (BM_FILE_CONTEXT *) NewMenuEntry->VariableContext;

    if (NewFileContext->IsBootLegacy) {
      continue;
    }

    if ((NewFileContext->IsDir) || (FileExplorerStateBootFromFile == CallbackData->FeCurrentState)) {
      //
      // Create Text opcode for directory, also create Text opcode for file in FileExplorerStateBootFromFile.
      //
      HiiCreateActionOpCode (
        mStartOpCodeHandle,
        (UINT16) (FILE_OPTION_OFFSET + Index),
        NewMenuEntry->DisplayStringToken,
        STRING_TOKEN (STR_NULL_STRING),
        EFI_IFR_FLAG_CALLBACK,
        0
        );
    } else {
      //
      // Create Goto opcode for file in FileExplorerStateAddBootOption or FileExplorerStateAddDriverOptionState.
      //
      if (FileExplorerStateAddBootOption == CallbackData->FeCurrentState) {
        FormId = FORM_BOOT_ADD_DESCRIPTION_ID;
      } else if (FileExplorerStateAddDriverOptionState == CallbackData->FeCurrentState) {
        FormId = FORM_DRIVER_ADD_FILE_DESCRIPTION_ID;
      }

      HiiCreateGotoOpCode (
        mStartOpCodeHandle,
        FormId,
        NewMenuEntry->DisplayStringToken,
        STRING_TOKEN (STR_NULL_STRING),
        EFI_IFR_FLAG_CALLBACK,
        (UINT16) (FILE_OPTION_OFFSET + Index)
        );
    }
  }

  HiiUpdateForm (
    CallbackData->FeHiiHandle,
    &mFileExplorerGuid,
    FORM_FILE_EXPLORER_ID,
    mStartOpCodeHandle, // Label FORM_FILE_EXPLORER_ID
    mEndOpCodeHandle    // LABEL_END
    );
}
コード例 #11
0
ファイル: BootManager.c プロジェクト: EvanLloyd/tianocore
/**
  This function invokes Boot Manager. If all devices have not a chance to be connected,
  the connect all will be triggered. It then enumerate all boot options. If
  a boot option from the Boot Manager page is selected, Boot Manager will boot
  from this boot option.

**/
VOID
CallBootManager (
    VOID
)
{
    EFI_STATUS                  Status;
    BDS_COMMON_OPTION           *Option;
    LIST_ENTRY                  *Link;
    CHAR16                      *ExitData;
    UINTN                       ExitDataSize;
    EFI_STRING_ID               Token;
    EFI_INPUT_KEY               Key;
    CHAR16                      *HelpString;
    UINTN                       HelpSize;
    EFI_STRING_ID               HelpToken;
    UINT16                      *TempStr;
    EFI_HII_HANDLE              HiiHandle;
    EFI_BROWSER_ACTION_REQUEST  ActionRequest;
    VOID                        *StartOpCodeHandle;
    VOID                        *EndOpCodeHandle;
    EFI_IFR_GUID_LABEL          *StartLabel;
    EFI_IFR_GUID_LABEL          *EndLabel;
    UINT16                      DeviceType;
    BOOLEAN                     IsLegacyOption;
    BOOLEAN                     NeedEndOp;

    DeviceType = (UINT16) -1;
    gOption    = NULL;
    InitializeListHead (&mBootOptionsList);

    //
    // Connect all prior to entering the platform setup menu.
    //
    if (!gConnectAllHappened) {
        BdsLibConnectAllDriversToAllControllers ();
        gConnectAllHappened = TRUE;
    }

    BdsLibEnumerateAllBootOption (&mBootOptionsList);

    //
    // Group the legacy boot options for the same device type
    //
    GroupMultipleLegacyBootOption4SameType ();

    InitializeListHead (&mBootOptionsList);
    BdsLibBuildOptionFromVar (&mBootOptionsList, L"BootOrder");

    HiiHandle = gBootManagerPrivate.HiiHandle;

    //
    // Allocate space for creation of UpdateData Buffer
    //
    StartOpCodeHandle = HiiAllocateOpCodeHandle ();
    ASSERT (StartOpCodeHandle != NULL);

    EndOpCodeHandle = HiiAllocateOpCodeHandle ();
    ASSERT (EndOpCodeHandle != NULL);

    //
    // Create Hii Extend Label OpCode as the start opcode
    //
    StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
    StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
    StartLabel->Number       = LABEL_BOOT_OPTION;

    //
    // Create Hii Extend Label OpCode as the end opcode
    //
    EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
    EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
    EndLabel->Number       = LABEL_BOOT_OPTION_END;

    mKeyInput = 0;
    NeedEndOp = FALSE;
    for (Link = GetFirstNode (&mBootOptionsList); !IsNull (&mBootOptionsList, Link); Link = GetNextNode (&mBootOptionsList, Link)) {
        Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);

        //
        // At this stage we are creating a menu entry, thus the Keys are reproduceable
        //
        mKeyInput++;

        //
        // Don't display the hidden/inactive boot option
        //
        if (((Option->Attribute & LOAD_OPTION_HIDDEN) != 0) || ((Option->Attribute & LOAD_OPTION_ACTIVE) == 0)) {
            continue;
        }

        //
        // Group the legacy boot option in the sub title created dynamically
        //
        IsLegacyOption = (BOOLEAN) (
                             (DevicePathType (Option->DevicePath) == BBS_DEVICE_PATH) &&
                             (DevicePathSubType (Option->DevicePath) == BBS_BBS_DP)
                         );

        if (!IsLegacyOption && NeedEndOp) {
            NeedEndOp = FALSE;
            HiiCreateEndOpCode (StartOpCodeHandle);
        }

        if (IsLegacyOption && DeviceType != ((BBS_BBS_DEVICE_PATH *) Option->DevicePath)->DeviceType) {
            if (NeedEndOp) {
                HiiCreateEndOpCode (StartOpCodeHandle);
            }

            DeviceType = ((BBS_BBS_DEVICE_PATH *) Option->DevicePath)->DeviceType;
            Token      = HiiSetString (
                             HiiHandle,
                             0,
                             mDeviceTypeStr[
                                 MIN (DeviceType & 0xF, ARRAY_SIZE (mDeviceTypeStr) - 1)
                             ],
                             NULL
                         );
            HiiCreateSubTitleOpCode (StartOpCodeHandle, Token, 0, 0, 1);
            NeedEndOp = TRUE;
        }

        ASSERT (Option->Description != NULL);

        Token = HiiSetString (HiiHandle, 0, Option->Description, NULL);

        TempStr = DevicePathToStr (Option->DevicePath);
        HelpSize = StrSize (TempStr) + StrSize (L"Device Path : ");
        HelpString = AllocateZeroPool (HelpSize);
        ASSERT (HelpString != NULL);
        StrCatS (HelpString, HelpSize / sizeof (CHAR16), L"Device Path : ");
        StrCatS (HelpString, HelpSize / sizeof (CHAR16), TempStr);

        HelpToken = HiiSetString (HiiHandle, 0, HelpString, NULL);

        HiiCreateActionOpCode (
            StartOpCodeHandle,
            mKeyInput,
            Token,
            HelpToken,
            EFI_IFR_FLAG_CALLBACK,
            0
        );
    }

    if (NeedEndOp) {
        HiiCreateEndOpCode (StartOpCodeHandle);
    }

    HiiUpdateForm (
        HiiHandle,
        &gBootManagerFormSetGuid,
        BOOT_MANAGER_FORM_ID,
        StartOpCodeHandle,
        EndOpCodeHandle
    );

    HiiFreeOpCodeHandle (StartOpCodeHandle);
    HiiFreeOpCodeHandle (EndOpCodeHandle);

    ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
    Status = gFormBrowser2->SendForm (
                 gFormBrowser2,
                 &HiiHandle,
                 1,
                 &gBootManagerFormSetGuid,
                 0,
                 NULL,
                 &ActionRequest
             );
    if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
        EnableResetRequired ();
    }

    if (gOption == NULL) {
        return ;
    }

    //
    // Will leave browser, check any reset required change is applied? if yes, reset system
    //
    SetupResetReminder ();

    //
    // Restore to original mode before launching boot option.
    //
    BdsSetConsoleMode (FALSE);

    //
    // parse the selected option
    //
    Status = BdsLibBootViaBootOption (gOption, gOption->DevicePath, &ExitDataSize, &ExitData);

    if (!EFI_ERROR (Status)) {
        gOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED));
        PlatformBdsBootSuccess (gOption);
    } else {
        gOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_FAILED));
        PlatformBdsBootFail (gOption, Status, ExitData, ExitDataSize);
        gST->ConOut->OutputString (
            gST->ConOut,
            GetStringById (STRING_TOKEN (STR_ANY_KEY_CONTINUE))
        );
        gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
    }
}
コード例 #12
0
ファイル: DriverHealthManagerDxe.c プロジェクト: M1cha/edk2
/**
  Update the form to include the driver health instances.

  @param ConfigureOnly  Only include the configure required driver health instances
                        when TRUE, include all the driver health instances otherwise.
**/
VOID
DriverHealthManagerUpdateForm (
  BOOLEAN                     ConfigureOnly
  )
{
  EFI_STATUS                  Status;
  EFI_IFR_GUID_LABEL          *StartLabel;
  EFI_IFR_GUID_LABEL          *EndLabel;
  VOID                        *StartOpCodeHandle;
  VOID                        *EndOpCodeHandle;
  UINTN                       Index;
  EFI_STRING_ID               Prompt;
  EFI_STRING_ID               Help;
  CHAR16                      String[512];
  UINTN                       StringCount;
  EFI_STRING                  TmpString;
  EFI_STRING                  DriverName;
  EFI_STRING                  ControllerName;
  UINTN                       MessageIndex;
  EFI_HANDLE                  DriverHandle;
  EFI_STRING_ID               DevicePath;
  EFI_GUID                    FormsetGuid;

  EfiBootManagerFreeDriverHealthInfo (mDriverHealthManagerHealthInfo, mDriverHealthManagerHealthInfoCount);
  mDriverHealthManagerHealthInfo = EfiBootManagerGetDriverHealthInfo (&mDriverHealthManagerHealthInfoCount);

  //
  // Allocate space for creation of UpdateData Buffer
  //
  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (StartOpCodeHandle != NULL);

  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (EndOpCodeHandle != NULL);

  //
  // Create Hii Extend Label OpCode as the start opcode
  //
  StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  StartLabel->Number       = LABEL_BEGIN;

  //
  // Create Hii Extend Label OpCode as the end opcode
  //
  EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  EndLabel->Number       = LABEL_END;

  for (Index = 0; Index < mDriverHealthManagerHealthInfoCount; Index++) {
    if (ConfigureOnly && mDriverHealthManagerHealthInfo[Index].HealthStatus != EfiDriverHealthStatusConfigurationRequired) {
      continue;
    }
    DriverName = DriverHealthManagerGetDriverName (mDriverHealthManagerHealthInfo[Index].DriverHealthHandle);
    ASSERT (DriverName != NULL);

    if (mDriverHealthManagerHealthInfo[Index].ControllerHandle == NULL) {
      //
      // The ControllerHandle is set to NULL and the HealthStatus is set to EfiDriverHealthStatusHealthy
      // if all the controllers managed by the driver are in healthy state.
      //
      ASSERT (mDriverHealthManagerHealthInfo[Index].HealthStatus == EfiDriverHealthStatusHealthy);
      UnicodeSPrint (String, sizeof (String), L"%s", DriverName);
    } else {
      ControllerName = DriverHealthManagerGetControllerName (
                         mDriverHealthManagerHealthInfo[Index].DriverHealthHandle,
                         mDriverHealthManagerHealthInfo[Index].ControllerHandle,
                         mDriverHealthManagerHealthInfo[Index].ChildHandle
                         );
      ASSERT (ControllerName != NULL);
      UnicodeSPrint (String, sizeof (String), L"%s    %s", DriverName, ControllerName);
      FreePool (ControllerName);
    }
    FreePool (DriverName);

    Prompt = HiiSetString (mDriverHealthManagerHiiHandle, 0, String, NULL);

    switch(mDriverHealthManagerHealthInfo[Index].HealthStatus) {
    case EfiDriverHealthStatusRepairRequired:
      TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_REPAIR_REQUIRED), NULL);
      break;
    case EfiDriverHealthStatusConfigurationRequired:
      TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_CONFIGURATION_REQUIRED), NULL);
      break;
    case EfiDriverHealthStatusFailed:
      TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_FAILED), NULL);
      break;
    case EfiDriverHealthStatusReconnectRequired:
      TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_RECONNECT_REQUIRED), NULL);
      break;
    case EfiDriverHealthStatusRebootRequired:
      TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_REBOOT_REQUIRED), NULL);
      break;
    default:
      ASSERT (mDriverHealthManagerHealthInfo[Index].HealthStatus == EfiDriverHealthStatusHealthy);
      TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_HEALTHY), NULL);
      break;
    }
    StringCount = UnicodeSPrint (String, sizeof (String), L"%s\n", TmpString);
    FreePool (TmpString);

    //
    // Add the message of the Module itself provided as the help.
    //
    if (mDriverHealthManagerHealthInfo[Index].MessageList != NULL) {
      for (MessageIndex = 0; mDriverHealthManagerHealthInfo[Index].MessageList[MessageIndex].HiiHandle != NULL; MessageIndex++) {
        TmpString = HiiGetString (
                      mDriverHealthManagerHealthInfo[Index].MessageList[MessageIndex].HiiHandle,
                      mDriverHealthManagerHealthInfo[Index].MessageList[MessageIndex].StringId,
                      NULL
                      );
        StringCount += UnicodeSPrint (String + StringCount, sizeof (String) - sizeof (String[0]) * StringCount, L"\n%s", TmpString);
        FreePool (TmpString);
      }
    }
    Help = HiiSetString (mDriverHealthManagerHiiHandle, 0, String, NULL);

    switch (mDriverHealthManagerHealthInfo[Index].HealthStatus) {
    case EfiDriverHealthStatusConfigurationRequired:
      Status = mDriverHealthManagerDatabase->GetPackageListHandle (
                                               mDriverHealthManagerDatabase,
                                               mDriverHealthManagerHealthInfo[Index].HiiHandle,
                                               &DriverHandle
                                               );
      ASSERT_EFI_ERROR (Status);
      TmpString  = ConvertDevicePathToText (DevicePathFromHandle (DriverHandle), FALSE, TRUE);
      DevicePath = HiiSetString (mDriverHealthManagerHiiHandle, 0, TmpString, NULL);
      FreePool (TmpString);

      Status = DriverHealthManagerGetFormsetId (mDriverHealthManagerHealthInfo[Index].HiiHandle, &FormsetGuid);
      ASSERT_EFI_ERROR (Status);

      HiiCreateGotoExOpCode (
        StartOpCodeHandle,
        0,
        Prompt,
        Help,
        0,
        0,
        0,
        &FormsetGuid,
        DevicePath
        );
      break;

    case EfiDriverHealthStatusRepairRequired:
    case EfiDriverHealthStatusReconnectRequired:
    case EfiDriverHealthStatusRebootRequired:
      HiiCreateActionOpCode (
        StartOpCodeHandle,
        (EFI_QUESTION_ID) (Index + QUESTION_ID_DRIVER_HEALTH_BASE),
        Prompt,
        Help,
        EFI_IFR_FLAG_CALLBACK,
        0
        );
      break;

    default:
      ASSERT (mDriverHealthManagerHealthInfo[Index].HealthStatus == EfiDriverHealthStatusHealthy ||
              mDriverHealthManagerHealthInfo[Index].HealthStatus == EfiDriverHealthStatusFailed);
      HiiCreateTextOpCode (
        StartOpCodeHandle,
        Prompt,
        Help,
        0
        );
      break;
    }
  }

  Status = HiiUpdateForm (
             mDriverHealthManagerHiiHandle,
             ConfigureOnly ? PcdGetPtr (PcdDriverHealthConfigureForm) : &mDriverHealthManagerForm,
             DRIVER_HEALTH_FORM_ID,
             StartOpCodeHandle,
             EndOpCodeHandle
             );
  ASSERT_EFI_ERROR (Status);

  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);
}
コード例 #13
0
/**
  Update the File Explore page.

  @param[in] HiiHandle          Hii Handle of the package to be updated.
  @param[in] MenuOption         The Menu whose string tokens need to be updated.
  @param[in] FeCurrentState     Current file explorer state.

**/
VOID
UpdateFileExplorePage (
  IN EFI_HII_HANDLE               HiiHandle,
  IN SECUREBOOT_MENU_OPTION       *MenuOption,
  IN FILE_EXPLORER_STATE          FeCurrentState
  )
{
  UINTN                   Index;
  SECUREBOOT_MENU_ENTRY   *NewMenuEntry;
  SECUREBOOT_FILE_CONTEXT *NewFileContext;
  EFI_FORM_ID             FormId;
  EFI_FORM_ID             FileFormId;

  if (FeCurrentState == FileExplorerStateEnrollPkFile) {
    FormId     = SECUREBOOT_ADD_PK_FILE_FORM_ID;
    FileFormId = FORM_FILE_EXPLORER_ID_PK;
  } else if (FeCurrentState == FileExplorerStateEnrollKekFile) {
    FormId     = FORMID_ENROLL_KEK_FORM;
    FileFormId = FORM_FILE_EXPLORER_ID_KEK;
  } else if (FeCurrentState == FileExplorerStateEnrollSignatureFileToDb) {
    FormId     = SECUREBOOT_ENROLL_SIGNATURE_TO_DB;
    FileFormId = FORM_FILE_EXPLORER_ID_DB;
  } else if (FeCurrentState == FileExplorerStateEnrollSignatureFileToDbx) {
    FormId     = SECUREBOOT_ENROLL_SIGNATURE_TO_DBX;
    FileFormId = FORM_FILE_EXPLORER_ID_DBX;
  } else if (FeCurrentState == FileExplorerStateEnrollSignatureFileToDbt) {
    FormId     = SECUREBOOT_ENROLL_SIGNATURE_TO_DBT;
    FileFormId = FORM_FILE_EXPLORER_ID_DBT;
  } else {
    return;
  }

  NewMenuEntry    = NULL;
  NewFileContext  = NULL;

  RefreshUpdateData ();
  mStartLabel->Number = FORM_FILE_EXPLORER_ID;

  for (Index = 0; Index < MenuOption->MenuNumber; Index++) {
    NewMenuEntry    = GetMenuEntry (MenuOption, Index);
    NewFileContext  = (SECUREBOOT_FILE_CONTEXT *) NewMenuEntry->FileContext;

    if (NewFileContext->IsDir) {
      //
      // Create Text opcode for directory.
      //
      HiiCreateActionOpCode (
        mStartOpCodeHandle,
        (UINT16) (FILE_OPTION_OFFSET + Index),
        NewMenuEntry->DisplayStringToken,
        STRING_TOKEN (STR_NULL),
        EFI_IFR_FLAG_CALLBACK,
        0
        );
    } else {

      //
      // Create Goto opcode for file.
      //
      HiiCreateGotoOpCode (
        mStartOpCodeHandle,
        FormId,
        NewMenuEntry->DisplayStringToken,
        STRING_TOKEN (STR_NULL),
        EFI_IFR_FLAG_CALLBACK,
        (UINT16) (FILE_OPTION_GOTO_OFFSET + Index)
        );
    }
  }

  HiiUpdateForm (
    HiiHandle,
    &gSecureBootConfigFormSetGuid,
    FileFormId,
    mStartOpCodeHandle, // Label FORM_FILE_EXPLORER_ID
    mEndOpCodeHandle    // LABEL_END
    );
}
コード例 #14
0
ファイル: UserProfileManager.c プロジェクト: jeppeter/vbox
/**
  This function processes changes in user profile 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 Others                 Fail to handle the action.

**/
EFI_STATUS
EFIAPI
UserProfileManagerCallback (
  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;
  EFI_INPUT_KEY            Key;
  UINT32                   CurrentAccessRight;
  CHAR16                   *QuestionStr;
  CHAR16                   *PromptStr;
  VOID                     *StartOpCodeHandle;
  VOID                     *EndOpCodeHandle;
  EFI_IFR_GUID_LABEL       *StartLabel;
  EFI_IFR_GUID_LABEL       *EndLabel;
  EFI_USER_PROFILE_HANDLE  CurrentUser;

  Status = EFI_SUCCESS;

  switch (Action) {
  case EFI_BROWSER_ACTION_FORM_OPEN:
    {
      //
      // Update user manage Form when user manage Form is opened.
      // This will be done only in FORM_OPEN CallBack of question with QUESTIONID_USER_MANAGE from user manage Form.
      //
      if (QuestionId != QUESTIONID_USER_MANAGE) {
        return EFI_SUCCESS;
      }

      //
      // Get current user
      //
      CurrentUser = NULL;
      mUserManager->Current (mUserManager, &CurrentUser);
      if (CurrentUser == NULL) {
        DEBUG ((DEBUG_ERROR, "Error: current user does not exist!\n"));
        return EFI_NOT_READY;
      }

      //
      // Get current user's right information.
      //
      Status = GetAccessRight (&CurrentAccessRight);
      if (EFI_ERROR (Status)) {
        CurrentAccessRight = EFI_USER_INFO_ACCESS_ENROLL_SELF;
      }

      //
      // Init credential provider information.
      //
      Status = InitProviderInfo ();
      if (EFI_ERROR (Status)) {
        return Status;
      }

      //
      // Initialize the container for dynamic opcodes.
      //
      StartOpCodeHandle = HiiAllocateOpCodeHandle ();
      ASSERT (StartOpCodeHandle != NULL);

      EndOpCodeHandle = HiiAllocateOpCodeHandle ();
      ASSERT (EndOpCodeHandle != NULL);

      //
      // Create Hii Extend Label OpCode.
      //
      StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
                                            StartOpCodeHandle,
                                            &gEfiIfrTianoGuid,
                                            NULL,
                                            sizeof (EFI_IFR_GUID_LABEL)
                                            );
      StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
      StartLabel->Number        = LABEL_USER_MANAGE_FUNC;

      EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
                                          EndOpCodeHandle,
                                          &gEfiIfrTianoGuid,
                                          NULL,
                                          sizeof (EFI_IFR_GUID_LABEL)
                                          );
      EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
      EndLabel->Number        = LABEL_END;

      //
      // Add user profile option.
      //
      if ((CurrentAccessRight == EFI_USER_INFO_ACCESS_MANAGE) ||
          (CurrentAccessRight == EFI_USER_INFO_ACCESS_ENROLL_OTHERS)
          ) {
        HiiCreateActionOpCode (
          StartOpCodeHandle,                  // Container for dynamic created opcodes
          KEY_ADD_USER,                       // Question ID
          STRING_TOKEN (STR_ADD_USER_TITLE),  // Prompt text
          STRING_TOKEN (STR_ADD_USER_HELP),   // Help text
          EFI_IFR_FLAG_CALLBACK,              // Question flag
          0                                   // Action String ID
          );
      }

      //
      // Add modify user profile option.
      //
      HiiCreateGotoOpCode (
        StartOpCodeHandle,                    // Container for dynamic created opcodes
        FORMID_MODIFY_USER,                   // Target Form ID
        STRING_TOKEN (STR_MODIFY_USER_TITLE), // Prompt text
        STRING_TOKEN (STR_MODIFY_USER_HELP),  // Help text
        EFI_IFR_FLAG_CALLBACK,                // Question flag
        KEY_MODIFY_USER                       // Question ID
        );

      //
      // Add delete user profile option
      //
      if (CurrentAccessRight == EFI_USER_INFO_ACCESS_MANAGE) {
        HiiCreateGotoOpCode (
          StartOpCodeHandle,                    // Container for dynamic created opcodes
          FORMID_DEL_USER,                      // Target Form ID
          STRING_TOKEN (STR_DELETE_USER_TITLE), // Prompt text
          STRING_TOKEN (STR_DELETE_USER_HELP),  // Help text
          EFI_IFR_FLAG_CALLBACK,                // Question flag
          KEY_DEL_USER                          // Question ID
          );
      }

      HiiUpdateForm (
        mCallbackInfo->HiiHandle,               // HII handle
        &gUserProfileManagerGuid,               // Formset GUID
        FORMID_USER_MANAGE,                     // Form ID
        StartOpCodeHandle,                      // Label for where to insert opcodes
        EndOpCodeHandle                         // Replace data
        );

      HiiFreeOpCodeHandle (StartOpCodeHandle);
      HiiFreeOpCodeHandle (EndOpCodeHandle);

      return EFI_SUCCESS;
    }
    break;

  case EFI_BROWSER_ACTION_FORM_CLOSE:
    Status = EFI_SUCCESS;
    break;

  case EFI_BROWSER_ACTION_CHANGED:
  {
    //
    // Handle the request from form.
    //
    if ((Value == NULL) || (ActionRequest == NULL)) {
      return EFI_INVALID_PARAMETER;
    }

    //
    // Judge first 2 bits.
    //
    switch (QuestionId & KEY_FIRST_FORM_MASK) {
    //
    // Add user profile operation.
    //
    case KEY_ADD_USER:
      CallAddUser ();
      break;

    //
    // Delete user profile operation.
    //
    case KEY_DEL_USER:
      //
      // Judge next 2 bits.
      //
      switch (QuestionId & KEY_SECOND_FORM_MASK) {
      //
      // Delete specified user profile.
      //
      case KEY_SELECT_USER:
        DeleteUser ((UINT8) QuestionId);
        //
        // Update select user form after delete a user.
        //
        SelectUserToDelete ();
        break;

      default:
        break;
      }
      break;

    //
    // Modify user profile operation.
    //
    case KEY_MODIFY_USER:
      //
      // Judge next 2 bits.
      //
      switch (QuestionId & KEY_SECOND_FORM_MASK) {
      //
      // Enter user profile information form.
      //
      case KEY_SELECT_USER:
        //
        // Judge next 3 bits.
        //
        switch (QuestionId & KEY_MODIFY_INFO_MASK) {
        //
        // Modify user name.
        //
        case KEY_MODIFY_NAME:
          ModifyUserName ();
          //
          // Update username in parent form.
          //
          SelectUserToModify ();
          break;

        //
        // Modify identity policy.
        //
        case KEY_MODIFY_IP:
          //
          // Judge next 3 bits
          //
          switch (QuestionId & KEY_MODIFY_IP_MASK) {
          //
          // Change credential provider option.
          //
          case KEY_MODIFY_PROV:
            mProviderChoice = Value->u8;
            break;

          //
          // Change logical connector.
          //
          case KEY_MODIFY_CONN:
            mConncetLogical = Value->u8;
            break;

          //
          // Save option.
          //
          case KEY_ADD_IP_OP:
            AddIdentityPolicyItem ();
            break;

          //
          // Return to user profile information form.
          //
          case KEY_IP_RETURN_UIF:
            SaveIdentityPolicy ();
            *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
            break;

          default:
            break;
          }
          break;

        //
        // Modify access policy.
        //
        case KEY_MODIFY_AP:
          //
          // Judge next 3 bits.
          //
          switch (QuestionId & KEY_MODIFY_AP_MASK) {
          //
          // Change access right choice.
          //
          case KEY_MODIFY_RIGHT:
            mAccessInfo.AccessRight = Value->u8;
            break;

          //
          // Change setup choice.
          //
          case KEY_MODIFY_SETUP:
            mAccessInfo.AccessSetup= Value->u8;
            break;

          //
          // Change boot order choice.
          //
          case KEY_MODIFY_BOOT:
            mAccessInfo.AccessBootOrder = Value->u32;
            break;

          //
          // Return to user profile information form.
          //
          case KEY_AP_RETURN_UIF:
            SaveAccessPolicy ();
            *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
            break;

          default:
            break;
          }
          break;

        default:
          break;
        }
        break;

      //
      // Access policy device path modified.
      //
      case KEY_MODIFY_AP_DP:
        //
        // Judge next 2 bits.
        //
        switch (QuestionId & KEY_MODIFY_DP_MASK) {
        //
        // Load permit device path modified.
        //
        case KEY_LOAD_PERMIT_MODIFY:
          QuestionStr = GetStringById (STRING_TOKEN (STR_MOVE_TO_FORBID_LIST));
          PromptStr   = GetStringById (STRING_TOKEN (STR_PRESS_KEY_CONTINUE));
          CreatePopUp (
            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
            &Key,
            QuestionStr,
            L"",
            PromptStr,
            NULL
            );
          FreePool (QuestionStr);
          FreePool (PromptStr);
          if (Key.UnicodeChar != CHAR_CARRIAGE_RETURN) {
            break;
          }

          AddToForbidLoad ((UINT16)(QuestionId & (KEY_MODIFY_DP_MASK - 1)));
          DisplayLoadPermit ();
          break;

        //
        // Load forbid device path modified.
        //
        case KEY_LOAD_FORBID_MODIFY:
          QuestionStr = GetStringById (STRING_TOKEN (STR_MOVE_TO_PERMIT_LIST));
          PromptStr   = GetStringById (STRING_TOKEN (STR_PRESS_KEY_CONTINUE));
          CreatePopUp (
            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
            &Key,
            QuestionStr,
            L"",
            PromptStr,
            NULL
            );
          FreePool (QuestionStr);
          FreePool (PromptStr);
          if (Key.UnicodeChar != CHAR_CARRIAGE_RETURN) {
            break;
          }

          DeleteFromForbidLoad ((UINT16)(QuestionId & (KEY_MODIFY_DP_MASK - 1)));
          DisplayLoadForbid ();
          break;

        //
        // Connect permit device path modified.
        //
        case KEY_CONNECT_PERMIT_MODIFY:
          break;

        //
        // Connect forbid device path modified.
        //
        case KEY_CONNECT_FORBID_MODIFY:
          break;

        default:
          break;
        }
        break;

      default:
        break;
      }
      break;

    default:
      break;
    }
  }
  break;


  case EFI_BROWSER_ACTION_CHANGING:
  {
    //
    // Handle the request from form.
    //
    if (Value == NULL) {
      return EFI_INVALID_PARAMETER;
    }

    //
    // Judge first 2 bits.
    //
    switch (QuestionId & KEY_FIRST_FORM_MASK) {
    //
    // Delete user profile operation.
    //
    case KEY_DEL_USER:
      //
      // Judge next 2 bits.
      //
      switch (QuestionId & KEY_SECOND_FORM_MASK) {
      //
      // Enter delete user profile form.
      //
      case KEY_ENTER_NEXT_FORM:
        SelectUserToDelete ();
        break;

      default:
        break;
      }
      break;

    //
    // Modify user profile operation.
    //
    case KEY_MODIFY_USER:
      //
      // Judge next 2 bits.
      //
      switch (QuestionId & KEY_SECOND_FORM_MASK) {
      //
      // Enter modify user profile form.
      //
      case KEY_ENTER_NEXT_FORM:
        SelectUserToModify ();
        break;

      //
      // Enter user profile information form.
      //
      case KEY_SELECT_USER:
        //
        // Judge next 3 bits.
        //
        switch (QuestionId & KEY_MODIFY_INFO_MASK) {
        //
        // Display user information form.
        //
        case KEY_ENTER_NEXT_FORM:
          ModifyUserInfo ((UINT8) QuestionId);
          break;

        //
        // Modify identity policy.
        //
        case KEY_MODIFY_IP:
          //
          // Judge next 3 bits
          //
          switch (QuestionId & KEY_MODIFY_IP_MASK) {
          //
          // Display identity policy modify form.
          //
          case KEY_ENTER_NEXT_FORM:
            ModifyIdentityPolicy ();
            break;

          default:
            break;
          }
          break;

        //
        // Modify access policy.
        //
        case KEY_MODIFY_AP:
          //
          // Judge next 3 bits.
          //
          switch (QuestionId & KEY_MODIFY_AP_MASK) {
          //
          // Display access policy modify form.
          //
          case KEY_ENTER_NEXT_FORM:
            ModidyAccessPolicy ();
            break;
          //
          // Load device path form.
          //
          case KEY_MODIFY_LOAD:
            //
            // Judge next 2 bits.
            //
            switch (QuestionId & KEY_DISPLAY_DP_MASK) {
            //
            // Permit load device path.
            //
            case KEY_PERMIT_MODIFY:
              DisplayLoadPermit ();
              break;

            //
            // Forbid load device path.
            //
            case KEY_FORBID_MODIFY:
              DisplayLoadForbid ();
              break;

            default:
              break;
            }
            break;

          //
          // Connect device path form.
          //
          case KEY_MODIFY_CONNECT:
            //
            // Judge next 2 bits.
            //
            switch (QuestionId & KEY_DISPLAY_DP_MASK) {
            //
            // Permit connect device path.
            //
            case KEY_PERMIT_MODIFY:
              DisplayConnectPermit ();
              break;

            //
            // Forbid connect device path.
            //
            case KEY_FORBID_MODIFY:
              DisplayConnectForbid ();
              break;

            default:
              break;
            }
            break;

          default:
            break;
          }
          break;

        default:
          break;
        }
        break;

      default:
        break;
      }
      break;

    default:
      break;
    }
  }
  break;

  default:
    //
    // All other action return unsupported.
    //
    Status = EFI_UNSUPPORTED;
    break;
  }


  return Status;
}