示例#1
0
文件: FrontPage.c 项目: pmj/edk2
/**

  Acquire the string associated with the Index from smbios structure and return it.
  The caller is responsible for free the string buffer.

  @param    OptionalStrStart  The start position to search the string
  @param    Index             The index of the string to extract
  @param    String            The string that is extracted

  @retval   EFI_SUCCESS       The function returns EFI_SUCCESS always.

**/
EFI_STATUS
GetOptionalStringByIndex (
  IN      CHAR8                   *OptionalStrStart,
  IN      UINT8                   Index,
  OUT     CHAR16                  **String
  )
{
  UINTN          StrSize;

  if (Index == 0) {
    *String = AllocateZeroPool (sizeof (CHAR16));
    return EFI_SUCCESS;
  }

  StrSize = 0;
  do {
    Index--;
    OptionalStrStart += StrSize;
    StrSize           = AsciiStrSize (OptionalStrStart);
  } while (OptionalStrStart[StrSize] != 0 && Index != 0);

  if ((Index != 0) || (StrSize == 1)) {
    //
    // Meet the end of strings set but Index is non-zero, or
    // Find an empty string
    //
    *String = GetStringById (STRING_TOKEN (STR_MISSING_STRING));
  } else {
    *String = AllocatePool (StrSize * sizeof (CHAR16));
    AsciiStrToUnicodeStrS (OptionalStrStart, *String, StrSize);
  }

  return EFI_SUCCESS;
}
示例#2
0
文件: Hotkey.c 项目: etiago/vbox
/**
  Try to boot the boot option triggered by hotkey.
  @retval  EFI_SUCCESS             There is HotkeyBootOption & it is processed
  @retval  EFI_NOT_FOUND           There is no HotkeyBootOption
**/
EFI_STATUS
HotkeyBoot (
  VOID
  )
{ 
  EFI_STATUS           Status;
  UINTN                ExitDataSize;
  CHAR16               *ExitData;

  if (mHotkeyBootOption == NULL) {
    return EFI_NOT_FOUND;
  } 
  
  BdsLibConnectDevicePath (mHotkeyBootOption->DevicePath);

  //
  // Clear the screen before launch this BootOption
  //
  gST->ConOut->Reset (gST->ConOut, FALSE);

  Status = BdsLibBootViaBootOption (mHotkeyBootOption, mHotkeyBootOption->DevicePath, &ExitDataSize, &ExitData);

  if (EFI_ERROR (Status)) {
    //
    // Call platform action to indicate the boot fail
    //
    mHotkeyBootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_FAILED));
    PlatformBdsBootFail (mHotkeyBootOption, Status, ExitData, ExitDataSize);
  } else {
    //
    // Call platform action to indicate the boot success
    //
    mHotkeyBootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED));
    PlatformBdsBootSuccess (mHotkeyBootOption);
  }
  FreePool (mHotkeyBootOption->Description);
  FreePool (mHotkeyBootOption->DevicePath);
  FreePool (mHotkeyBootOption->LoadOptions);
  FreePool (mHotkeyBootOption);

  mHotkeyBootOption = NULL;

  return EFI_SUCCESS;
}
示例#3
0
文件: FrontPage.c 项目: OznOg/edk2
/**
  Acquire the string associated with the ProducerGuid and return it.


  @param ProducerGuid    The Guid to search the HII database for
  @param Token           The token value of the string to extract
  @param String          The string that is extracted

  @retval  EFI_SUCCESS  The function returns EFI_SUCCESS always.

**/
EFI_STATUS
GetProducerString (
  IN      EFI_GUID                  *ProducerGuid,
  IN      EFI_STRING_ID             Token,
  OUT     CHAR16                    **String
  )
{
  EFI_STRING      TmpString;

  TmpString = HiiGetPackageString (ProducerGuid, Token, NULL);
  if (TmpString == NULL) {
    *String = GetStringById (STRING_TOKEN (STR_MISSING_STRING));
  } else {
    *String = TmpString;
  }

  return EFI_SUCCESS;
}
示例#4
0
/**
  Perform the memory test base on the memory test intensive level,
  and update the memory resource.

  @param  Level         The memory test intensive level.

  @retval EFI_STATUS    Success test all the system memory and update
                        the memory resource

**/
EFI_STATUS
EFIAPI
BdsMemoryTest (
  IN EXTENDMEM_COVERAGE_LEVEL Level
  )
{
  EFI_STATUS                        Status;
  EFI_STATUS                        KeyStatus;
  EFI_STATUS                        InitStatus;
  EFI_STATUS                        ReturnStatus;
  BOOLEAN                           RequireSoftECCInit;
  EFI_GENERIC_MEMORY_TEST_PROTOCOL  *GenMemoryTest;
  UINT64                            TestedMemorySize;
  UINT64                            TotalMemorySize;
  UINTN                             TestPercent;
  UINT64                            PreviousValue;
  BOOLEAN                           ErrorOut;
  BOOLEAN                           TestAbort;
  EFI_INPUT_KEY                     Key;
  CHAR16                            StrPercent[80];
  CHAR16                            *StrTotalMemory;
  CHAR16                            *Pos;
  CHAR16                            *TmpStr;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL     Foreground;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL     Background;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL     Color;
  BOOLEAN                           IsFirstBoot;
  UINT32                            TempData;
  UINTN                             StrTotalMemorySize;

  ReturnStatus = EFI_SUCCESS;
  ZeroMem (&Key, sizeof (EFI_INPUT_KEY));

  StrTotalMemorySize = 128;
  Pos = AllocateZeroPool (StrTotalMemorySize);

  if (Pos == NULL) {
    return ReturnStatus;
  }

  StrTotalMemory    = Pos;

  TestedMemorySize  = 0;
  TotalMemorySize   = 0;
  PreviousValue     = 0;
  ErrorOut          = FALSE;
  TestAbort         = FALSE;

  SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
  SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
  SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);

  RequireSoftECCInit = FALSE;

  Status = gBS->LocateProtocol (
                  &gEfiGenericMemTestProtocolGuid,
                  NULL,
                  (VOID **) &GenMemoryTest
                  );
  if (EFI_ERROR (Status)) {
    FreePool (Pos);
    return EFI_SUCCESS;
  }

  InitStatus = GenMemoryTest->MemoryTestInit (
                                GenMemoryTest,
                                Level,
                                &RequireSoftECCInit
                                );
  if (InitStatus == EFI_NO_MEDIA) {
    //
    // The PEI codes also have the relevant memory test code to check the memory,
    // it can select to test some range of the memory or all of them. If PEI code
    // checks all the memory, this BDS memory test will has no not-test memory to
    // do the test, and then the status of EFI_NO_MEDIA will be returned by
    // "MemoryTestInit". So it does not need to test memory again, just return.
    //
    FreePool (Pos);
    return EFI_SUCCESS;
  }
  
  if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
    TmpStr = GetStringById (STRING_TOKEN (STR_ESC_TO_SKIP_MEM_TEST));

    if (TmpStr != NULL) {
      PrintXY (10, 10, NULL, NULL, TmpStr);
      FreePool (TmpStr);
    }
  } else {
    DEBUG ((EFI_D_INFO, "Enter memory test.\n"));
  }
  do {
    Status = GenMemoryTest->PerformMemoryTest (
                              GenMemoryTest,
                              &TestedMemorySize,
                              &TotalMemorySize,
                              &ErrorOut,
                              TestAbort
                              );
    if (ErrorOut && (Status == EFI_DEVICE_ERROR)) {
      TmpStr = GetStringById (STRING_TOKEN (STR_SYSTEM_MEM_ERROR));
      if (TmpStr != NULL) {
        PrintXY (10, 10, NULL, NULL, TmpStr);
        FreePool (TmpStr);
      }

      ASSERT (0);
    }
    
    if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
      TempData = (UINT32) DivU64x32 (TotalMemorySize, 16);
      TestPercent = (UINTN) DivU64x32 (
                              DivU64x32 (MultU64x32 (TestedMemorySize, 100), 16),
                              TempData
                              );
      if (TestPercent != PreviousValue) {
        UnicodeValueToString (StrPercent, 0, TestPercent, 0);
        TmpStr = GetStringById (STRING_TOKEN (STR_MEMORY_TEST_PERCENT));
        if (TmpStr != NULL) {
          //
          // TmpStr size is 64, StrPercent is reserved to 16.
          //
          StrCatS (StrPercent, sizeof (StrPercent) / sizeof (CHAR16), TmpStr);
          PrintXY (10, 10, NULL, NULL, StrPercent);
          FreePool (TmpStr);
        }

        TmpStr = GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST));
        if (TmpStr != NULL) {
          PlatformBdsShowProgress (
            Foreground,
            Background,
            TmpStr,
            Color,
            TestPercent,
            (UINTN) PreviousValue
            );
          FreePool (TmpStr);
        }
      }

      PreviousValue = TestPercent;
    } else {
      DEBUG ((EFI_D_INFO, "Perform memory test (ESC to skip).\n"));
    }

    if (!PcdGetBool (PcdConInConnectOnDemand)) {
      KeyStatus     = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
      if (!EFI_ERROR (KeyStatus) && (Key.ScanCode == SCAN_ESC)) {
        if (!RequireSoftECCInit) {
          if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
            TmpStr = GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST));
            if (TmpStr != NULL) {
              PlatformBdsShowProgress (
                Foreground,
                Background,
                TmpStr,
                Color,
                100,
                (UINTN) PreviousValue
                );
              FreePool (TmpStr);
            }

            PrintXY (10, 10, NULL, NULL, L"100");
          }
          Status = GenMemoryTest->Finished (GenMemoryTest);
          goto Done;
        }

        TestAbort = TRUE;
      }
    }
  } while (Status != EFI_NOT_FOUND);

  Status = GenMemoryTest->Finished (GenMemoryTest);

Done:
  if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
    UnicodeValueToString (StrTotalMemory, COMMA_TYPE, TotalMemorySize, 0);
    if (StrTotalMemory[0] == L',') {
      StrTotalMemory++;
      StrTotalMemorySize -= sizeof (CHAR16);
    }

    TmpStr = GetStringById (STRING_TOKEN (STR_MEM_TEST_COMPLETED));
    if (TmpStr != NULL) {
      StrCatS (StrTotalMemory, StrTotalMemorySize / sizeof (CHAR16), TmpStr);
      FreePool (TmpStr);
    }

    PrintXY (10, 10, NULL, NULL, StrTotalMemory);
    PlatformBdsShowProgress (
      Foreground,
      Background,
      StrTotalMemory,
      Color,
      100,
      (UINTN) PreviousValue
      );
    
  } else {
    DEBUG ((EFI_D_INFO, "%d bytes of system memory tested OK\r\n", TotalMemorySize));
  }
  
  FreePool (Pos);


  //
  // Use a DynamicHii type pcd to save the boot status, which is used to
  // control configuration mode, such as FULL/MINIMAL/NO_CHANGES configuration.
  //
  IsFirstBoot = PcdGetBool(PcdBootState);
  if (IsFirstBoot) {
    PcdSetBool(PcdBootState, FALSE);
  }

  return ReturnStatus;
}
示例#5
0
/**
  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);
    }
}
示例#6
0
文件: FrontPage.c 项目: OznOg/edk2
/**
  Function show progress bar to wait for user input.


  @param   TimeoutDefault  The fault time out value before the system continue to boot.

  @retval  EFI_SUCCESS       User pressed some key except "Enter"
  @retval  EFI_TIME_OUT      Timeout expired or user press "Enter"

**/
EFI_STATUS
ShowProgress (
  IN UINT16                       TimeoutDefault
  )
{
  CHAR16                        *TmpStr;
  UINT16                        TimeoutRemain;
  EFI_STATUS                    Status;
  EFI_INPUT_KEY                 Key;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;

  if (TimeoutDefault != 0) {
    DEBUG ((EFI_D_INFO, "\n\nStart showing progress bar... Press any key to stop it! ...Zzz....\n"));

    SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
    SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
    SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
    
    TmpStr = GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION));

    if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
      //
      // Clear the progress status bar first
      //
      if (TmpStr != NULL) {
        PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0);
      }
    }
    

    TimeoutRemain = TimeoutDefault;
    while (TimeoutRemain != 0) {
      DEBUG ((EFI_D_INFO, "Showing progress bar...Remaining %d second!\n", TimeoutRemain));

      Status = WaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND);
      if (Status != EFI_TIMEOUT) {
        break;
      }
      TimeoutRemain--;
      
      if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
        //
        // Show progress
        //
        if (TmpStr != NULL) {
          PlatformBdsShowProgress (
            Foreground,
            Background,
            TmpStr,
            Color,
            ((TimeoutDefault - TimeoutRemain) * 100 / TimeoutDefault),
            0
            );
        }
      }
    }
    
    if (TmpStr != NULL) {
      gBS->FreePool (TmpStr);
    }

    //
    // Timeout expired
    //
    if (TimeoutRemain == 0) {
      return EFI_TIMEOUT;
    }
  }

  //
  // User pressed some key
  //
  if (!PcdGetBool (PcdConInConnectOnDemand)) {
    Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
      //
      // User pressed enter, equivalent to select "continue"
      //
      return EFI_TIMEOUT;
    }
  }

  return EFI_SUCCESS;
}
示例#7
0
/**

  This function attempts to boot for the boot order specified
  by platform policy.

**/
VOID
BdsBootDeviceSelect (
  VOID
  )
{
  EFI_STATUS        Status;
  LIST_ENTRY        *Link;
  BDS_COMMON_OPTION *BootOption;
  UINTN             ExitDataSize;
  CHAR16            *ExitData;
  UINT16            Timeout;
  LIST_ENTRY        BootLists;
  CHAR16            Buffer[20];
  BOOLEAN           BootNextExist;
  LIST_ENTRY        *LinkBootNext;
  EFI_EVENT         ConnectConInEvent;

  //
  // Got the latest boot option
  //
  BootNextExist = FALSE;
  LinkBootNext  = NULL;
  ConnectConInEvent = NULL;
  InitializeListHead (&BootLists);

  //
  // First check the boot next option
  //
  ZeroMem (Buffer, sizeof (Buffer));

  //
  // Create Event to signal ConIn connection request
  //
  if (PcdGetBool (PcdConInConnectOnDemand)) {
    Status = gBS->CreateEventEx (
                    EVT_NOTIFY_SIGNAL,
                    TPL_CALLBACK,
                    BdsEmptyCallbackFunction,
                    NULL,
                    &gConnectConInEventGuid,
                    &ConnectConInEvent
                    );
    if (EFI_ERROR(Status)) {
      ConnectConInEvent = NULL;
    }
  }

  if (mBootNext != NULL) {
    //
    // Indicate we have the boot next variable, so this time
    // boot will always have this boot option
    //
    BootNextExist = TRUE;

    //
    // Clear the this variable so it's only exist in this time boot
    //
    Status = gRT->SetVariable (
                    L"BootNext",
                    &gEfiGlobalVariableGuid,
                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
                    0,
                    NULL
                    );
    //
    // Deleting variable with current variable implementation shouldn't fail.
    //
    ASSERT_EFI_ERROR (Status);

    //
    // Add the boot next boot option
    //
    UnicodeSPrint (Buffer, sizeof (Buffer), L"Boot%04x", *mBootNext);
    BootOption = BdsLibVariableToOption (&BootLists, Buffer);

    //
    // If fail to get boot option from variable, just return and do nothing.
    //
    if (BootOption == NULL) {
      return;
    }

    BootOption->BootCurrent = *mBootNext;
  }
  //
  // Parse the boot order to get boot option
  //
  BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");

  //
  // When we didn't have chance to build boot option variables in the first 
  // full configuration boot (e.g.: Reset in the first page or in Device Manager),
  // we have no boot options in the following mini configuration boot.
  // Give the last chance to enumerate the boot options.
  //
  if (IsListEmpty (&BootLists)) {
    BdsLibEnumerateAllBootOption (&BootLists);
  }

  Link = BootLists.ForwardLink;

  //
  // Parameter check, make sure the loop will be valid
  //
  if (Link == NULL) {
    return ;
  }
  //
  // Here we make the boot in a loop, every boot success will
  // return to the front page
  //
  for (;;) {
    //
    // Check the boot option list first
    //
    if (Link == &BootLists) {
      //
      // When LazyConIn enabled, signal connect ConIn event before enter UI
      //
      if (PcdGetBool (PcdConInConnectOnDemand) && ConnectConInEvent != NULL) {
        gBS->SignalEvent (ConnectConInEvent);
      }

      //
      // There are two ways to enter here:
      // 1. There is no active boot option, give user chance to
      //    add new boot option
      // 2. All the active boot option processed, and there is no
      //    one is success to boot, then we back here to allow user
      //    add new active boot option
      //
      Timeout = 0xffff;
      PlatformBdsEnterFrontPage (Timeout, FALSE);
      InitializeListHead (&BootLists);
      BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");
      Link = BootLists.ForwardLink;
      continue;
    }
    //
    // Get the boot option from the link list
    //
    BootOption = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);

    //
    // According to EFI Specification, if a load option is not marked
    // as LOAD_OPTION_ACTIVE, the boot manager will not automatically
    // load the option.
    //
    if (!IS_LOAD_OPTION_TYPE (BootOption->Attribute, LOAD_OPTION_ACTIVE)) {
      //
      // skip the header of the link list, because it has no boot option
      //
      Link = Link->ForwardLink;
      continue;
    }
    //
    // Make sure the boot option device path connected,
    // but ignore the BBS device path
    //
    if (DevicePathType (BootOption->DevicePath) != BBS_DEVICE_PATH) {
      //
      // Notes: the internal shell can not been connected with device path
      // so we do not check the status here
      //
      BdsLibConnectDevicePath (BootOption->DevicePath);
    }

    //
    // Restore to original mode before launching boot option.
    //
    BdsSetConsoleMode (FALSE);
    
    //
    // All the driver options should have been processed since
    // now boot will be performed.
    //
    Status = BdsLibBootViaBootOption (BootOption, BootOption->DevicePath, &ExitDataSize, &ExitData);
    if (Status != EFI_SUCCESS) {
      //
      // Call platform action to indicate the boot fail
      //
      BootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_FAILED));
      PlatformBdsBootFail (BootOption, Status, ExitData, ExitDataSize);

      //
      // Check the next boot option
      //
      Link = Link->ForwardLink;

    } else {
      //
      // Call platform action to indicate the boot success
      //
      BootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED));
      PlatformBdsBootSuccess (BootOption);

      //
      // Boot success, then stop process the boot order, and
      // present the boot manager menu, front page
      //

      //
      // When LazyConIn enabled, signal connect ConIn Event before enter UI
      //
      if (PcdGetBool (PcdConInConnectOnDemand) && ConnectConInEvent != NULL) {
        gBS->SignalEvent (ConnectConInEvent);
      }

      Timeout = 0xffff;
      PlatformBdsEnterFrontPage (Timeout, FALSE);

      //
      // Rescan the boot option list, avoid potential risk of the boot
      // option change in front page
      //
      if (BootNextExist) {
        LinkBootNext = BootLists.ForwardLink;
      }

      InitializeListHead (&BootLists);
      if (LinkBootNext != NULL) {
        //
        // Reserve the boot next option
        //
        InsertTailList (&BootLists, LinkBootNext);
      }

      BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");
      Link = BootLists.ForwardLink;
    }
  }

}
示例#8
0
/**

  This is the common notification function for HotKeys, it will be registered
  with SimpleTextInEx protocol interface - RegisterKeyNotify() of ConIn handle.

  @param KeyData         A pointer to a buffer that is filled in with the keystroke
                         information for the key that was pressed.

  @retval  EFI_SUCCESS   KeyData is successfully processed.
  @return  EFI_NOT_FOUND Fail to find boot option variable.
**/
EFI_STATUS
EFIAPI
HotkeyCallback (
  IN EFI_KEY_DATA     *KeyData
)
{
  BOOLEAN            HotkeyCatched;
  LIST_ENTRY         BootLists;
  LIST_ENTRY         *Link;
  BDS_HOTKEY_OPTION  *Hotkey;
  UINT16             Buffer[10];
  BDS_COMMON_OPTION  *BootOption;
  UINTN              ExitDataSize;
  CHAR16             *ExitData;
  EFI_STATUS         Status;
  EFI_KEY_DATA       *HotkeyData;

  if (mHotkeyCallbackPending) {
    //
    // When responsing to a Hotkey, ignore sequential hotkey stroke until
    // the current Boot#### load option returned
    //
    return EFI_SUCCESS;
  }

  Status = EFI_SUCCESS;
  Link = GetFirstNode (&mHotkeyList);

  while (!IsNull (&mHotkeyList, Link)) {
    HotkeyCatched = FALSE;
    Hotkey = BDS_HOTKEY_OPTION_FROM_LINK (Link);

    //
    // Is this Key Stroke we are waiting for?
    //
    ASSERT (Hotkey->WaitingKey < (sizeof (Hotkey->KeyData) / sizeof (Hotkey->KeyData[0])));
    HotkeyData = &Hotkey->KeyData[Hotkey->WaitingKey];
    if ((KeyData->Key.ScanCode == HotkeyData->Key.ScanCode) &&
       (KeyData->Key.UnicodeChar == HotkeyData->Key.UnicodeChar) &&
       (((HotkeyData->KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) ? (KeyData->KeyState.KeyShiftState == HotkeyData->KeyState.KeyShiftState) : TRUE)) {
      //
      // Receive an expecting key stroke
      //
      if (Hotkey->CodeCount > 1) {
        //
        // For hotkey of key combination, transit to next waiting state
        //
        Hotkey->WaitingKey++;

        if (Hotkey->WaitingKey == Hotkey->CodeCount) {
          //
          // Received the whole key stroke sequence
          //
          HotkeyCatched = TRUE;
        }
      } else {
        //
        // For hotkey of single key stroke
        //
        HotkeyCatched = TRUE;
      }
    } else {
      //
      // Receive an unexpected key stroke, reset to initial waiting state
      //
      Hotkey->WaitingKey = 0;
    }

    if (HotkeyCatched) {
      //
      // Reset to initial waiting state
      //
      Hotkey->WaitingKey = 0;

      //
      // Launch its BootOption
      //
      InitializeListHead (&BootLists);

      UnicodeSPrint (Buffer, sizeof (Buffer), L"Boot%04x", Hotkey->BootOptionNumber);
      BootOption = BdsLibVariableToOption (&BootLists, Buffer);
      if (BootOption == NULL) {
        return EFI_NOT_FOUND;
      }
      BootOption->BootCurrent = Hotkey->BootOptionNumber;
      BdsLibConnectDevicePath (BootOption->DevicePath);

      //
      // Clear the screen before launch this BootOption
      //
      gST->ConOut->Reset (gST->ConOut, FALSE);

      mHotkeyCallbackPending = TRUE;
      Status = BdsLibBootViaBootOption (BootOption, BootOption->DevicePath, &ExitDataSize, &ExitData);
      mHotkeyCallbackPending = FALSE;

      if (EFI_ERROR (Status)) {
        //
        // Call platform action to indicate the boot fail
        //
        BootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_FAILED));
        PlatformBdsBootFail (BootOption, Status, ExitData, ExitDataSize);
      } else {
        //
        // Call platform action to indicate the boot success
        //
        BootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED));
        PlatformBdsBootSuccess (BootOption);
      }
    }

    Link = GetNextNode (&mHotkeyList, Link);
  }

  return Status;
}
示例#9
0
/**
  Add a new user profile into the user profile database.

**/
VOID
CallAddUser (
  VOID
  )
{
  EFI_STATUS              Status;
  EFI_INPUT_KEY           Key;
  EFI_USER_PROFILE_HANDLE User;
  UINTN                   UserNameLen;
  CHAR16                  UserName[USER_NAME_LENGTH];
  CHAR16                  *QuestionStr;
  CHAR16                  *PromptStr;

  QuestionStr = NULL;
  PromptStr   = NULL;

  //
  // Get user name to add.
  //
  UserNameLen = sizeof (UserName);
  Status = GetUserNameInput (&UserNameLen, UserName);
  if (EFI_ERROR (Status)) {
    if (Status != EFI_ABORTED) {
      QuestionStr = GetStringById (STRING_TOKEN (STR_GET_USERNAME_FAILED));
      PromptStr   = GetStringById (STRING_TOKEN (STR_STROKE_KEY_CONTINUE));
      goto Done;
    }
    return ;
  }

  //
  // Create a new user profile.
  //
  User    = NULL;
  Status  = mUserManager->Create (mUserManager, &User);
  if (EFI_ERROR (Status)) {
    QuestionStr = GetStringById (STRING_TOKEN (STR_CREATE_PROFILE_FAILED));
    PromptStr   = GetStringById (STRING_TOKEN (STR_STROKE_KEY_CONTINUE));
  } else {
    //
    // Add default user information.
    //
    Status = SetUserName (User, UserNameLen, UserName);
    if (EFI_ERROR (Status)) {
      QuestionStr = GetStringById (STRING_TOKEN (STR_USER_ALREADY_EXISTED));
      PromptStr   = GetStringById (STRING_TOKEN (STR_STROKE_KEY_CONTINUE));
      goto Done;
    }

    SetCreateDate (User);
    SetIdentityPolicy (User);
    SetAccessPolicy (User);

    QuestionStr = GetStringById (STRING_TOKEN (STR_CREATE_PROFILE_SUCCESS));
    PromptStr   = GetStringById (STRING_TOKEN (STR_STROKE_KEY_CONTINUE));
  }

Done:
  CreatePopUp (
    EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
    &Key,
    QuestionStr,
    L"",
    PromptStr,
    NULL
    );
  FreePool (QuestionStr);
  FreePool (PromptStr);
}
示例#10
0
/**
  This call back function is registered with Boot Manager formset.
  When user selects a boot option, this call back function will
  be triggered. The boot option is saved for later processing.


  @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_INVALID_PARAMETER The setup browser call this function with invalid parameters.

**/
EFI_STATUS
EFIAPI
BootManagerCallback (
  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
  )
{
  UINTN                         Index;
  EFI_BOOT_MANAGER_LOAD_OPTION  *BootOption;
  UINTN                         BootOptionCount;
  UINT16                        KeyCount;
  EFI_INPUT_KEY                 Key;
  EFI_BOOT_MANAGER_LOAD_OPTION  Option;

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

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

  //
  // Initialize the key count
  //
  KeyCount = 0;
  Option.Attributes = 0;
  BootOption = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);

  for (Index = 0; Index < BootOptionCount; Index++) {
    KeyCount++;

    EfiBootManagerInitializeLoadOption (
      &Option,
      BootOption[Index].OptionNumber,
      BootOption[Index].OptionType,
      BootOption[Index].Attributes,
      BootOption[Index].Description,
      BootOption[Index].FilePath,
      BootOption[Index].OptionalData,
      BootOption[Index].OptionalDataSize
      );

    //
    // Is this device the one chosen?
    //
    if (KeyCount == QuestionId) {
      //
      // Clear  the  screen  before.
      //
      gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
      gST->ConOut->ClearScreen (gST->ConOut);
      //
      // Check any reset required change is applied? if yes, reset system
      //
      SetupResetReminder();
      //
      // Parse the selected option.
      //
      BdsSetConsoleMode(FALSE);
      EfiBootManagerBoot (&Option);
      BdsSetConsoleMode(TRUE);

      if (EFI_ERROR (Option.Status)) {
        gST->ConOut->OutputString (
                      gST->ConOut,
                      GetStringById (STRING_TOKEN (STR_ANY_KEY_CONTINUE))
                      );
        gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
      }
      break;
    }
  }
  EfiBootManagerFreeLoadOptions (BootOption, BootOptionCount);

  return EFI_SUCCESS;
}
示例#11
0
/**
  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;
}