示例#1
0
文件: Perf.c 项目: Kohrara/edk
EFI_STATUS
EFIAPI
StartGauge (
  IN EFI_PERFORMANCE_PROTOCOL         *This,
  IN EFI_HANDLE                       Handle,
  IN UINT16                           *Token,
  IN UINT16                           *Host,
  IN UINT64                           Ticker
  )
/*++

Routine Description:

  Create a guage data node and initialized it.

Arguments:

  This    - Calling context
  Handle  - Handle of gauge data
  Token   - Token of gauge data
  Host    - Host of gauge data
  Ticker  - Set gauge data's StartTick. If 0, StartTick is current timer.

Returns:

  EFI_SUCCESS     - Successfully create and initialized a guage data node.
  EFI_OUT_OF_RESOURCES  - No enough resource to create a guage data node.

--*/
{
  EFI_PERFORMANCE_INSTANCE  *PerfInstance;
  EFI_PERF_DATA_LIST        *Node;
  UINT64                    TimerValue;

  TimerValue    = 0;
  PerfInstance  = EFI_PERFORMANCE_FROM_THIS (This);

  Node          = CreateDataNode (Handle, Token, Host);
  if (!Node) {
    return EFI_OUT_OF_RESOURCES;
  }

  if (Ticker != 0) {
    TimerValue = Ticker;
  } else {
    GetTimerValue (&TimerValue);
  }

  Node->GaugeData.StartTick = TimerValue;

  if (!EfiStrCmp (Token, DXE_TOK)) {
    PerfInstance->Phase = DXE_PHASE;
  }

  if (!EfiStrCmp (Token, SHELL_TOK)) {
    PerfInstance->Phase = SHELL_PHASE;
  }

  Node->GaugeData.Phase = PerfInstance->Phase;

  InsertTailList (&mPerfDataHead, &(Node->Link));

  return EFI_SUCCESS;
}
示例#2
0
文件: Perf.c 项目: Kohrara/edk
EFI_PERF_DATA_LIST *
GetDataNode (
  IN EFI_HANDLE        Handle,
  IN UINT16            *Token,
  IN UINT16            *Host,
  IN EFI_GUID          *GuidName,
  IN EFI_GAUGE_DATA    *PrevGauge
  )
/*++

Routine Description:

  Search gauge node list to find one node with matched handle, token, host and Guid name.

Arguments:

  Handle    - Handle to match
  Token     - Token to match
  Host      - Host to match
  GuidName  - Guid name to match
  PrevGauge - Start node, start from list head if NULL

Returns:

  Return pointer to the node found, NULL if not found.

--*/
{
  EFI_PERF_DATA_LIST  *Node;
  EFI_PERF_DATA_LIST  *Temp;
  EFI_PERF_DATA_LIST  *Temp2;
  EFI_LIST_ENTRY      *CurrentLink;
  EFI_GUID            NullGuid = EFI_NULL_GUID;

  Node      = NULL;
  Temp      = NULL;
  Temp2     = NULL;

  if (PrevGauge == NULL) {
    CurrentLink = mPerfDataHead.ForwardLink;
  } else {
    Temp2       = GAUGE_DATA_FROM_GAUGE (PrevGauge);
    CurrentLink = (Temp2->Link).ForwardLink;
  }

  while (CurrentLink && CurrentLink != &mPerfDataHead) {
    Node = GAUGE_DATA_FROM_LINK (CurrentLink);

    if (Handle == 0 && Token == NULL && Host == NULL && GuidName == NULL) {
      return Node;
    }

    if (Handle != (Node->GaugeData).Handle) {
      CurrentLink = CurrentLink->ForwardLink;
      continue;
    }

    if (GuidName == NULL && !EfiCompareGuid (&((Node->GaugeData).GuidName), &NullGuid)) {
      CurrentLink = CurrentLink->ForwardLink;
      continue;
    }

    if (GuidName && !EfiCompareGuid (&((Node->GaugeData).GuidName), GuidName)) {
      CurrentLink = CurrentLink->ForwardLink;
      continue;
    }

    if (Token == NULL && EfiStrCmp (Node->GaugeData.Token, L"")) {
      CurrentLink = CurrentLink->ForwardLink;
      continue;
    }

    if (Token && EfiStrCmp (Node->GaugeData.Token, Token)) {
      CurrentLink = CurrentLink->ForwardLink;
      continue;
    }

    if (Host == NULL && EfiStrCmp (Node->GaugeData.Host, L"")) {
      CurrentLink = CurrentLink->ForwardLink;
      continue;
    }

    if (Host && EfiStrCmp (Node->GaugeData.Host, Host)) {
      CurrentLink = CurrentLink->ForwardLink;
      continue;
    }

    Temp = Node;
    break;
  }

  return Temp;
}
EFI_STATUS
BBTestGetAltCfgFunctionTestCheckpoint1 ( 
  IN EFI_STANDARD_TEST_LIBRARY_PROTOCOL         *StandardLib,
  IN EFI_HII_CONFIG_ROUTING_PROTOCOL            *HIIConfigRouting
  )
{
  EFI_TEST_ASSERTION          AssertionType;
  EFI_STATUS                  Status;
  EFI_STRING                  ConfigAltResp;
  EFI_GUID                    Guid1 = { 0x4ab90e97, 0xd4a0, 0xf749, 0xb9, 0x80, 0xbd, 0xaa, 0x47, 0xd4, 0x25, 0x27};
  EFI_GUID                    Guid2 = { 0x4ab90e97, 0xd4a0, 0xf749, 0xb9, 0x80, 0xbd, 0xaa, 0x47, 0xd4, 0x25, 0x28};
  EFI_STRING                  NameDomain1 = L"jin9"; //L"006a0069006e0039";
  EFI_STRING                  NameDomain2 = L"jin8"; //L"006a0069006e0038";
  UINT16                      AltCfgId1 = EFI_HII_DEFAULT_CLASS_STANDARD;
  UINT16                      AltCfgId2 = EFI_HII_DEFAULT_CLASS_MANUFACTURING;
  EFI_STRING                  CfgResp = NULL;

  ConfigAltResp = L"GUID=970eb94aa0d449f7b980bdaa47d42527&NAME=006a0069006e0039&PATH=000ace&OFFSET=3&WIDTH=4&VALUE=aabbccdd&OFFSET=1&WIDTH=2&VALUE=1122&GUID=970eb94aa0d449f7b980bdaa47d42527&NAME=006a0069006e0039&PATH=000ace&ALTCFG=0000&a000=abcd&b000=efef&GUID=970eb94aa0d449f7b980bdaa47d42528&NAME=006a0069006e0038&PATH=000acf&ALTCFG=0001&OFFSET=3&WIDTH=4&VALUE=aabbccdd&OFFSET=1&WIDTH=2&VALUE=eeff";
  // GUID=970eb94aa0d449f7b980bdaa47d42527&NAME=006a0069006e0039&PATH=000ace&OFFSET=3&WIDTH=4&VALUE=aabbccdd&OFFSET=1&WIDTH=2&VALUE=eeff
  //&GUID=970eb94aa0d449f7b980bdaa47d42527&NAME=006a0069006e0039&PATH=000ace&ALTCFG=0037&a000=abcd&b000=efef
  //&GUID=970eb94aa0d449f7b980bdaa47d42528&NAME=006a0069006e0038&PATH=000acf&a000=abcd&b000=efef
  //&GUID=970eb94aa0d449f7b980bdaa47d42528&NAME=006a0069006e0038&PATH=000acf&ALTCFG=0038&OFFSET=3&WIDTH=4&VALUE=aabbccdd&OFFSET=1&WIDTH=2&VALUE=eeff

  // Check All are NULL, except AltcfgId
  Status = HIIConfigRouting->GetAltCfg(
                               HIIConfigRouting,
                               ConfigAltResp,
                               NULL,
                               NULL,
                               NULL,
                               &AltCfgId1,
                               &CfgResp
                               );
  
  if ( EFI_SUCCESS == Status ) {
    if (0 != EfiStrCmp(CfgResp, L"GUID=970eb94aa0d449f7b980bdaa47d42527&NAME=006a0069006e0039&PATH=000ace&a000=abcd&b000=efef")){
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    }
    
    if (CfgResp != NULL) {
      gtBS->FreePool(CfgResp);
      CfgResp = NULL;
    }

  } else if ( EFI_OUT_OF_RESOURCES == Status ){
    AssertionType = EFI_TEST_ASSERTION_WARNING;
  } else {
    AssertionType = EFI_TEST_ASSERTION_FAILED;
  }

  StandardLib->RecordAssertion (
                 StandardLib,
                 AssertionType,
                 gHIIConfigRoutingBBTestFunctionAssertionGuid006,
                 L"HII_CONFIG_ROUTING_PROTOCOL.GetAltCfg - GetAltCfg() returns EFI_SUCCESS with valid AltcfgId1.",
                 L"%a:%d: Status - %r",
                 __FILE__,
                 (UINTN)__LINE__,
                 Status
                 );

  // Check Guid1
  Status = HIIConfigRouting->GetAltCfg(
                               HIIConfigRouting,
                               ConfigAltResp,
                               &Guid1,
                               NULL,
                               NULL,
                               &AltCfgId1,
                               &CfgResp
                               );
  
  if ( EFI_SUCCESS == Status ) {
    if (0 != EfiStrCmp(CfgResp, L"GUID=970eb94aa0d449f7b980bdaa47d42527&NAME=006a0069006e0039&PATH=000ace&a000=abcd&b000=efef")){
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    }
    
    if (CfgResp != NULL) {
      gtBS->FreePool(CfgResp);
      CfgResp = NULL;
    }
  } else if ( EFI_OUT_OF_RESOURCES == Status ){
    AssertionType = EFI_TEST_ASSERTION_WARNING;
  } else {
    AssertionType = EFI_TEST_ASSERTION_FAILED;
  }

  StandardLib->RecordAssertion (
                 StandardLib,
                 AssertionType,
                 gHIIConfigRoutingBBTestFunctionAssertionGuid007,
                 L"HII_CONFIG_ROUTING_PROTOCOL.GetAltCfg - GetAltCfg() returns EFI_SUCCESS with valid Guid1 and AltcfgId1.",
                 L"%a:%d: Status - %r",
                 __FILE__,
                 (UINTN)__LINE__,
                 Status
                 );

  // Check NameDomain1
  Status = HIIConfigRouting->GetAltCfg(
                               HIIConfigRouting,
                               ConfigAltResp,
                               NULL,
                               NameDomain1,
                               NULL,
                               &AltCfgId1,
                               &CfgResp
                               );
  
  if ( EFI_SUCCESS == Status ) {
    if (0 != EfiStrCmp(CfgResp, L"GUID=970eb94aa0d449f7b980bdaa47d42527&NAME=006a0069006e0039&PATH=000ace&a000=abcd&b000=efef")) {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    }

    if (CfgResp != NULL) {
      gtBS->FreePool(CfgResp);
      CfgResp = NULL;
    }
  } else if ( EFI_OUT_OF_RESOURCES == Status ){
    AssertionType = EFI_TEST_ASSERTION_WARNING;
  } else {
    AssertionType = EFI_TEST_ASSERTION_FAILED;
  }

  StandardLib->RecordAssertion (
                 StandardLib,
                 AssertionType,
                 gHIIConfigRoutingBBTestFunctionAssertionGuid008,
                 L"HII_CONFIG_ROUTING_PROTOCOL.GetAltCfg - GetAltCfg() returns EFI_SUCCESS with valid Name1 and AltcfgId1.",
                 L"%a:%d: Status - %r",
                 __FILE__,
                 (UINTN)__LINE__,
                 Status
                 );

  // Check NameDomain1 and Guid1
  Status = HIIConfigRouting->GetAltCfg(
                               HIIConfigRouting,
                               ConfigAltResp,
                               &Guid1,
                               NameDomain1,
                               NULL,
                               &AltCfgId1,
                               &CfgResp
                               );
  
  if ( EFI_SUCCESS == Status ) {
    if (0 != EfiStrCmp(CfgResp, L"GUID=970eb94aa0d449f7b980bdaa47d42527&NAME=006a0069006e0039&PATH=000ace&a000=abcd&b000=efef")) {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    }

    if (CfgResp != NULL) {
      gtBS->FreePool(CfgResp);
      CfgResp = NULL;
    }
  } else if ( EFI_OUT_OF_RESOURCES == Status ){
    AssertionType = EFI_TEST_ASSERTION_WARNING;
  } else {
    AssertionType = EFI_TEST_ASSERTION_FAILED;
  }

  StandardLib->RecordAssertion (
                 StandardLib,
                 AssertionType,
                 gHIIConfigRoutingBBTestFunctionAssertionGuid009,
                 L"HII_CONFIG_ROUTING_PROTOCOL.GetAltCfg - GetAltCfg() returns EFI_SUCCESS with valid Guid1, Name1, and AltCfgId1.",
                 L"%a:%d: Status - %r",
                 __FILE__,
                 (UINTN)__LINE__,
                 Status
                 );

  // Check NameDomain1 and Guid1, with AltCfgId is NULL
  Status = HIIConfigRouting->GetAltCfg(
                               HIIConfigRouting,
                               ConfigAltResp,
                               &Guid1,
                               NameDomain1,
                               NULL,
                               NULL,
                               &CfgResp
                               );
  
  if ( EFI_SUCCESS == Status ) {
    if (0 != EfiStrCmp(CfgResp, L"GUID=970eb94aa0d449f7b980bdaa47d42527&NAME=006a0069006e0039&PATH=000ace&OFFSET=3&WIDTH=4&VALUE=aabbccdd&OFFSET=1&WIDTH=2&VALUE=1122")) {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    }
    
    if (CfgResp != NULL) {
      gtBS->FreePool(CfgResp);
      CfgResp = NULL;
    }
  } else if ( EFI_OUT_OF_RESOURCES == Status ){
    AssertionType = EFI_TEST_ASSERTION_WARNING;
  } else {
    AssertionType = EFI_TEST_ASSERTION_FAILED;
  }

  StandardLib->RecordAssertion (
                 StandardLib,
                 AssertionType,
                 gHIIConfigRoutingBBTestFunctionAssertionGuid010,
                 L"HII_CONFIG_ROUTING_PROTOCOL.GetAltCfg - GetAltCfg() returns EFI_SUCCESS with valid Guid1 and Name1.",
                 L"%a:%d: Status - %r",
                 __FILE__,
                 (UINTN)__LINE__,
                 Status
                 );

  // Check NameDomain1 only
  Status = HIIConfigRouting->GetAltCfg(
                               HIIConfigRouting,
                               ConfigAltResp,
                               NULL,
                               NameDomain1,
                               NULL,
                               NULL,
                               &CfgResp
                               );
  
  if ( EFI_SUCCESS == Status ) {
    if (0 != EfiStrCmp(CfgResp, L"GUID=970eb94aa0d449f7b980bdaa47d42527&NAME=006a0069006e0039&PATH=000ace&OFFSET=3&WIDTH=4&VALUE=aabbccdd&OFFSET=1&WIDTH=2&VALUE=1122")) {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    }
    
    if (CfgResp != NULL) {
      gtBS->FreePool(CfgResp);
      CfgResp = NULL;
    }
  } else if ( EFI_OUT_OF_RESOURCES == Status ){
    AssertionType = EFI_TEST_ASSERTION_WARNING;
  } else {
    AssertionType = EFI_TEST_ASSERTION_FAILED;
  }

  StandardLib->RecordAssertion (
                 StandardLib,
                 AssertionType,
                 gHIIConfigRoutingBBTestFunctionAssertionGuid012,
                 L"HII_CONFIG_ROUTING_PROTOCOL.GetAltCfg - GetAltCfg() returns EFI_SUCCESS with valid Name1.",
                 L"%a:%d: Status - %r",
                 __FILE__,
                 (UINTN)__LINE__,
                 Status
                 );
  

  /****************************************************************************************/
  //
  // Check All are NULL, except AltcfgId
  // current setting will be returned
  //
  Status = HIIConfigRouting->GetAltCfg(
                               HIIConfigRouting,
                               ConfigAltResp,
                               NULL,
                               NULL,
                               NULL,
                               &AltCfgId2,
                               &CfgResp
                               );
  
  if ( EFI_SUCCESS == Status ) {
    if (0 != EfiStrCmp(CfgResp, L"GUID=970eb94aa0d449f7b980bdaa47d42528&NAME=006a0069006e0038&PATH=000acf&OFFSET=3&WIDTH=4&VALUE=aabbccdd&OFFSET=1&WIDTH=2&VALUE=eeff")) {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    }

    if (CfgResp != NULL) {
      gtBS->FreePool(CfgResp);
      CfgResp = NULL;
    }
  } else if ( EFI_OUT_OF_RESOURCES == Status ){
    AssertionType = EFI_TEST_ASSERTION_WARNING;
  } else {
    AssertionType = EFI_TEST_ASSERTION_FAILED;
  }

  StandardLib->RecordAssertion (
                 StandardLib,
                 AssertionType,
                 gHIIConfigRoutingBBTestFunctionAssertionGuid006,
                 L"HII_CONFIG_ROUTING_PROTOCOL.GetAltCfg - GetAltCfg() returns EFI_SUCCESS with valid AltcfgId2.",
                 L"%a:%d: Status - %r",
                 __FILE__,
                 (UINTN)__LINE__,
                 Status
                 );

  // Check Guid2
  Status = HIIConfigRouting->GetAltCfg(
                               HIIConfigRouting,
                               ConfigAltResp,
                               &Guid2,
                               NULL,
                               NULL,
                               &AltCfgId2,
                               &CfgResp
                               );
  
  if ( EFI_SUCCESS == Status ) {
    if (0 != EfiStrCmp(CfgResp, L"GUID=970eb94aa0d449f7b980bdaa47d42528&NAME=006a0069006e0038&PATH=000acf&OFFSET=3&WIDTH=4&VALUE=aabbccdd&OFFSET=1&WIDTH=2&VALUE=eeff")){
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    }

    if (CfgResp != NULL) {
      gtBS->FreePool(CfgResp);
      CfgResp = NULL;
    }
  } else if ( EFI_OUT_OF_RESOURCES == Status ){
    AssertionType = EFI_TEST_ASSERTION_WARNING;
  } else {
    AssertionType = EFI_TEST_ASSERTION_FAILED;
  }

  StandardLib->RecordAssertion (
                 StandardLib,
                 AssertionType,
                 gHIIConfigRoutingBBTestFunctionAssertionGuid007,
                 L"HII_CONFIG_ROUTING_PROTOCOL.GetAltCfg - GetAltCfg() returns EFI_SUCCESS with valid Guid2 and AltcfgId2.",
                 L"%a:%d: Status - %r",
                 __FILE__,
                 (UINTN)__LINE__,
                 Status
                 );

  // Check NameDomain2
  Status = HIIConfigRouting->GetAltCfg(
                               HIIConfigRouting,
                               ConfigAltResp,
                               NULL,
                               NameDomain2,
                               NULL,
                               &AltCfgId2,
                               &CfgResp
                               );
  
  if ( EFI_SUCCESS == Status ) {
    if (0 != EfiStrCmp(CfgResp, L"GUID=970eb94aa0d449f7b980bdaa47d42528&NAME=006a0069006e0038&PATH=000acf&OFFSET=3&WIDTH=4&VALUE=aabbccdd&OFFSET=1&WIDTH=2&VALUE=eeff")) {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    }

    if (CfgResp != NULL) {
      gtBS->FreePool(CfgResp);
      CfgResp = NULL;
    }
  } else if ( EFI_OUT_OF_RESOURCES == Status ){
    AssertionType = EFI_TEST_ASSERTION_WARNING;
  } else {
    AssertionType = EFI_TEST_ASSERTION_FAILED;
  }

  StandardLib->RecordAssertion (
                 StandardLib,
                 AssertionType,
                 gHIIConfigRoutingBBTestFunctionAssertionGuid008,
                 L"HII_CONFIG_ROUTING_PROTOCOL.GetAltCfg - GetAltCfg() returns EFI_SUCCESS with valid Name2 and AltcfgId2.",
                 L"%a:%d: Status - %r",
                 __FILE__,
                 (UINTN)__LINE__,
                 Status
                 );

  // Check NameDomain2 and Guid2
  Status = HIIConfigRouting->GetAltCfg(
                               HIIConfigRouting,
                               ConfigAltResp,
                               &Guid2,
                               NameDomain2,
                               NULL,
                               &AltCfgId2,
                               &CfgResp
                               );
  
  if ( EFI_SUCCESS == Status ) {
    if (0 != EfiStrCmp(CfgResp, L"GUID=970eb94aa0d449f7b980bdaa47d42528&NAME=006a0069006e0038&PATH=000acf&OFFSET=3&WIDTH=4&VALUE=aabbccdd&OFFSET=1&WIDTH=2&VALUE=eeff")) {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    }

    if (CfgResp != NULL) {
      gtBS->FreePool(CfgResp);
      CfgResp = NULL;
    }
  } else if ( EFI_OUT_OF_RESOURCES == Status ){
    AssertionType = EFI_TEST_ASSERTION_WARNING;
  } else {
    AssertionType = EFI_TEST_ASSERTION_FAILED;
  }

  StandardLib->RecordAssertion (
                 StandardLib,
                 AssertionType,
                 gHIIConfigRoutingBBTestFunctionAssertionGuid009,
                 L"HII_CONFIG_ROUTING_PROTOCOL.GetAltCfg - GetAltCfg() returns EFI_SUCCESS with valid Guid2, Name2 and AltcfgId2.",
                 L"%a:%d: Status - %r",
                 __FILE__,
                 (UINTN)__LINE__,
                 Status
                 );
  
  return EFI_SUCCESS;
}
示例#4
0
EFI_STATUS
ProcessOptions (
  IN  UI_MENU_SELECTION           *Selection,
  IN  UI_MENU_OPTION              *MenuOption,
  IN  BOOLEAN                     Selected,
  OUT CHAR16                      **OptionString
  )
/*++

Routine Description:
  Process a Question's Option (whether selected or un-selected).

Arguments:
  Selection        - Pointer to UI_MENU_SELECTION.
  MenuOption       - The MenuOption for this Question.
  Selected         - TRUE: if Question is selected.
  OptionString     - Pointer of the Option String to be displayed.

Returns:
  EFI_SUCCESS      - Question Option process success.
  Other            - Question Option process fail.

--*/
{
  EFI_STATUS                      Status;
  CHAR16                          *StringPtr;
  CHAR16                          *TempString;
  UINTN                           Index;
  FORM_BROWSER_STATEMENT          *Question;
  CHAR16                          FormattedNumber[21];
  UINT16                          Number;
  CHAR16                          Character[2];
  EFI_INPUT_KEY                   Key;
  UINTN                           BufferSize;
  QUESTION_OPTION                 *OneOfOption;
  EFI_LIST_ENTRY                  *Link;
  EFI_HII_VALUE                   HiiValue;
  EFI_HII_VALUE                   *QuestionValue;
  BOOLEAN                         Suppress;
  UINT16                          Minimum;
  UINT16                          Maximum;
  QUESTION_OPTION                 *Option;
  UINTN                           Index2;
  UINT8                           *ValueArray;
  UINT8                           ValueType;

  Status        = EFI_SUCCESS;

  StringPtr     = NULL;
  Character[1]  = L'\0';
  *OptionString = NULL;

  EfiZeroMem (FormattedNumber, 21 * sizeof (CHAR16));
  BufferSize = (gOptionBlockWidth + 1) * 2 * gScreenDimensions.BottomRow;

  Question = MenuOption->ThisTag;
  QuestionValue = &Question->HiiValue;
  Minimum = (UINT16) Question->Minimum;
  Maximum = (UINT16) Question->Maximum;

  ValueArray = Question->BufferValue;
  ValueType = Question->ValueType;

  switch (Question->Operand) {
  case EFI_IFR_ORDERED_LIST_OP:
    //
    // Check whether there are Options of this OrderedList
    //
    if (IsListEmpty (&Question->OptionListHead)) {
      break;
    }

    //
    // Initialize Option value array
    //
    if (GetArrayData (ValueArray, ValueType, 0) == 0) {
      GetQuestionDefault (Selection->FormSet, Selection->Form, Question, 0);
    }

    if (Selected) {
      //
      // Go ask for input
      //
      Status = GetSelectionInputPopUp (Selection, MenuOption);
    } else {
      //
      // We now know how many strings we will have, so we can allocate the
      // space required for the array or strings.
      //
      *OptionString = EfiLibAllocateZeroPool (Question->MaxContainers * BufferSize);
      ASSERT (*OptionString);

      HiiValue.Type = ValueType;
      HiiValue.Value.u64 = 0;
      for (Index = 0; Index < Question->MaxContainers; Index++) {
        HiiValue.Value.u64 = GetArrayData (ValueArray, ValueType, Index);
        if (HiiValue.Value.u64 == 0) {
          //
          // Values for the options in ordered lists should never be a 0
          //
          break;
        }

        OneOfOption = ValueToOption (Question, &HiiValue);
        if (OneOfOption == NULL) {
          //
          // Show error message
          //
          do {
            CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gOptionMismatch, gPressEnter, gEmptyString);
          } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

          //
          // The initial value of the orderedlist is invalid, force to be valid value
          //
          Link = GetFirstNode (&Question->OptionListHead);
          Index2 = 0;
          while (!IsNull (&Question->OptionListHead, Link) && Index2 < Question->MaxContainers) {
            Option = QUESTION_OPTION_FROM_LINK (Link);
            SetArrayData (ValueArray, ValueType, Index2, Option->Value.Value.u64);
            Index2++;
            Link = GetNextNode (&Question->OptionListHead, Link);
          }
          SetArrayData (ValueArray, ValueType, Index2, 0);

          Status = SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);
          UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);

          gBS->FreePool (*OptionString);
          *OptionString = NULL;
          return EFI_NOT_FOUND;
        }

        Suppress = FALSE;
        if ((OneOfOption->SuppressExpression != NULL) &&
            (OneOfOption->SuppressExpression->Result.Value.b)) {
          //
          // This option is suppressed
          //
          Suppress = TRUE;
        }

        if (!Suppress) {
          Character[0] = LEFT_ONEOF_DELIMITER;
          NewStrCat (OptionString[0], Character);
          StringPtr = GetToken (OneOfOption->Text, Selection->Handle);
          NewStrCat (OptionString[0], StringPtr);
          Character[0] = RIGHT_ONEOF_DELIMITER;
          NewStrCat (OptionString[0], Character);
          Character[0] = CHAR_CARRIAGE_RETURN;
          NewStrCat (OptionString[0], Character);

          gBS->FreePool (StringPtr);
        }
      }
    }
    break;

  case EFI_IFR_ONE_OF_OP:
    //
    // Check whether there are Options of this OneOf
    //
    if (IsListEmpty (&Question->OptionListHead)) {
      break;
    }

    if (Selected) {
      //
      // Go ask for input
      //
      Status = GetSelectionInputPopUp (Selection, MenuOption);
    } else {
      *OptionString = EfiLibAllocateZeroPool (BufferSize);
      ASSERT (*OptionString);

      OneOfOption = ValueToOption (Question, QuestionValue);
      if (OneOfOption == NULL) {
        //
        // Show error message
        //
        do {
          CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gOptionMismatch, gPressEnter, gEmptyString);
        } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

        //
        // Force the Question value to be valid
        //
        Link = GetFirstNode (&Question->OptionListHead);
        while (!IsNull (&Question->OptionListHead, Link)) {
          Option = QUESTION_OPTION_FROM_LINK (Link);

          if ((Option->SuppressExpression == NULL) ||
              !Option->SuppressExpression->Result.Value.b) {
            EfiCopyMem (QuestionValue, &Option->Value, sizeof (EFI_HII_VALUE));
            SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);
            UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);
            break;
          }

          Link = GetNextNode (&Question->OptionListHead, Link);
        }

        gBS->FreePool (*OptionString);
        *OptionString = NULL;
        return EFI_NOT_FOUND;
      }

      if ((OneOfOption->SuppressExpression != NULL) &&
          (OneOfOption->SuppressExpression->Result.Value.b)) {
        //
        // This option is suppressed
        //
        Suppress = TRUE;
      } else {
        Suppress = FALSE;
      }

      if (Suppress) {
        //
        // Current selected option happen to be suppressed,
        // enforce to select on a non-suppressed option
        //
        Link = GetFirstNode (&Question->OptionListHead);
        while (!IsNull (&Question->OptionListHead, Link)) {
          OneOfOption = QUESTION_OPTION_FROM_LINK (Link);

          if ((OneOfOption->SuppressExpression == NULL) ||
              !OneOfOption->SuppressExpression->Result.Value.b) {
            Suppress = FALSE;
            EfiCopyMem (QuestionValue, &OneOfOption->Value, sizeof (EFI_HII_VALUE));
            SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);
            UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);
            gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT | FIELD_BACKGROUND);
            break;
          }

          Link = GetNextNode (&Question->OptionListHead, Link);
        }
      }

      if (!Suppress) {
        Character[0] = LEFT_ONEOF_DELIMITER;
        NewStrCat (OptionString[0], Character);
        StringPtr = GetToken (OneOfOption->Text, Selection->Handle);
        NewStrCat (OptionString[0], StringPtr);
        Character[0] = RIGHT_ONEOF_DELIMITER;
        NewStrCat (OptionString[0], Character);

        gBS->FreePool (StringPtr);
      }
    }
    break;

  case EFI_IFR_CHECKBOX_OP:
    *OptionString = EfiLibAllocateZeroPool (BufferSize);
    ASSERT (*OptionString);

    *OptionString[0] = LEFT_CHECKBOX_DELIMITER;

    if (Selected) {
      //
      // Since this is a BOOLEAN operation, flip it upon selection
      //
      QuestionValue->Value.b = QuestionValue->Value.b ? FALSE : TRUE;

      //
      // Perform inconsistent check
      //
      Status = ValidateQuestion (Selection->FormSet, Selection->Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF);
      if (EFI_ERROR (Status)) {
        //
        // Inconsistent check fail, restore Question Value
        //
        QuestionValue->Value.b = QuestionValue->Value.b ? FALSE : TRUE;
        gBS->FreePool (*OptionString);
        *OptionString = NULL;
        return Status;
      }

      //
      // Save Question value
      //
      Status = SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);
      UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);
    }

    if (QuestionValue->Value.b) {
      *(OptionString[0] + 1) = CHECK_ON;
    } else {
      *(OptionString[0] + 1) = CHECK_OFF;
    }
    *(OptionString[0] + 2) = RIGHT_CHECKBOX_DELIMITER;
    break;

  case EFI_IFR_NUMERIC_OP:
    if (Selected) {
      //
      // Go ask for input
      //
      Status = GetNumericInput (Selection, MenuOption);
    } else {
      *OptionString = EfiLibAllocateZeroPool (BufferSize);
      ASSERT (*OptionString);

      *OptionString[0] = LEFT_NUMERIC_DELIMITER;

      //
      // Formatted print
      //
      PrintFormattedNumber (Question, FormattedNumber, 21 * sizeof (CHAR16));
      Number = (UINT16) GetStringWidth (FormattedNumber);
      EfiCopyMem (OptionString[0] + 1, FormattedNumber, Number);

      *(OptionString[0] + Number / 2) = RIGHT_NUMERIC_DELIMITER;
    }
    break;

  case EFI_IFR_DATE_OP:
    if (Selected) {
      //
      // This is similar to numerics
      //
      Status = GetNumericInput (Selection, MenuOption);
    } else {
      *OptionString = EfiLibAllocateZeroPool (BufferSize);
      ASSERT (*OptionString);

      switch (MenuOption->Sequence) {
      case 0:
        *OptionString[0] = LEFT_NUMERIC_DELIMITER;
        SPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"%02d", (UINTN) QuestionValue->Value.date.Month);
        *(OptionString[0] + 3) = DATE_SEPARATOR;
        break;

      case 1:
        SetUnicodeMem (OptionString[0], 4, L' ');
        SPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"%02d", (UINTN) QuestionValue->Value.date.Day);
        *(OptionString[0] + 6) = DATE_SEPARATOR;
        break;

      case 2:
        SetUnicodeMem (OptionString[0], 7, L' ');
        SPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"%4d", (UINTN) QuestionValue->Value.date.Year);
        *(OptionString[0] + 11) = RIGHT_NUMERIC_DELIMITER;
        break;
      }
    }
    break;

  case EFI_IFR_TIME_OP:
    if (Selected) {
      //
      // This is similar to numerics
      //
      Status = GetNumericInput (Selection, MenuOption);
    } else {
      *OptionString = EfiLibAllocateZeroPool (BufferSize);
      ASSERT (*OptionString);

      switch (MenuOption->Sequence) {
      case 0:
        *OptionString[0] = LEFT_NUMERIC_DELIMITER;
        SPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"%02d", (UINTN) QuestionValue->Value.time.Hour);
        *(OptionString[0] + 3) = TIME_SEPARATOR;
        break;

      case 1:
        SetUnicodeMem (OptionString[0], 4, L' ');
        SPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"%02d", (UINTN) QuestionValue->Value.time.Minute);
        *(OptionString[0] + 6) = TIME_SEPARATOR;
        break;

      case 2:
        SetUnicodeMem (OptionString[0], 7, L' ');
        SPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"%02d", (UINTN) QuestionValue->Value.time.Second);
        *(OptionString[0] + 9) = RIGHT_NUMERIC_DELIMITER;
        break;
      }
    }
    break;

  case EFI_IFR_STRING_OP:
    if (Selected) {
      StringPtr = EfiLibAllocateZeroPool ((Maximum + 1) * sizeof (CHAR16));
      ASSERT (StringPtr);

      Status = ReadString (MenuOption, gPromptForData, StringPtr);
      if (!EFI_ERROR (Status)) {
        EfiCopyMem (Question->BufferValue, StringPtr, Maximum * sizeof (CHAR16));
        SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);

        UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);
      }

      gBS->FreePool (StringPtr);
    } else {
      *OptionString = EfiLibAllocateZeroPool (BufferSize);
      ASSERT (*OptionString);

      if (((CHAR16 *) Question->BufferValue)[0] == 0x0000) {
        *(OptionString[0]) = '_';
      } else {
        if ((Maximum * sizeof (CHAR16)) < BufferSize) {
          BufferSize = Maximum * sizeof (CHAR16);
        }
        EfiCopyMem (OptionString[0], (CHAR16 *) Question->BufferValue, BufferSize);
      }
    }
    break;

  case EFI_IFR_PASSWORD_OP:
    if (Selected) {
      StringPtr = EfiLibAllocateZeroPool ((Maximum + 1) * sizeof (CHAR16));
      ASSERT (StringPtr);

      //
      // For interactive passwords, old password is validated by callback
      //
      if (Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) {
        //
        // Use a NULL password to test whether old password is required
        //
        *StringPtr = 0;
        Status = PasswordCallback (Selection, MenuOption, StringPtr);
        if (Status == EFI_NOT_AVAILABLE_YET) {
          //
          // Callback request to terminate password input
          //
          gBS->FreePool (StringPtr);
          return EFI_SUCCESS;
        }

        if (EFI_ERROR (Status)) {
          //
          // Old password exist, ask user for the old password
          //
          Status = ReadString (MenuOption, gPromptForPassword, StringPtr);
          if (EFI_ERROR (Status)) {
            gBS->FreePool (StringPtr);
            return Status;
          }

          //
          // Check user input old password
          //
          Status = PasswordCallback (Selection, MenuOption, StringPtr);
          if (EFI_ERROR (Status)) {
            if (Status == EFI_NOT_READY) {
              //
              // Typed in old password incorrect
              //
              PasswordInvalid ();
            } else {
              Status = EFI_SUCCESS;
            }

            gBS->FreePool (StringPtr);
            return Status;
          }
        }
      } else {
        //
        // For non-interactive password, validate old password in local
        //
        if (*((CHAR16 *) Question->BufferValue) != 0) {
          //
          // There is something there!  Prompt for password
          //
          Status = ReadString (MenuOption, gPromptForPassword, StringPtr);
          if (EFI_ERROR (Status)) {
            gBS->FreePool (StringPtr);
            return Status;
          }

          TempString = EfiLibAllocateCopyPool ((Maximum + 1) * sizeof (CHAR16), Question->BufferValue);
          TempString[Maximum] = L'\0';

          if (EfiStrCmp (StringPtr, TempString) != 0) {
            //
            // Typed in old password incorrect
            //
            PasswordInvalid ();

            gBS->FreePool (StringPtr);
            gBS->FreePool (TempString);
            return Status;
          }

          gBS->FreePool (TempString);
        }
      }

      //
      // Ask for new password
      //
      EfiZeroMem (StringPtr, (Maximum + 1) * sizeof (CHAR16));
      Status = ReadString (MenuOption, gPromptForNewPassword, StringPtr);
      if (EFI_ERROR (Status)) {
        //
        // Reset state machine for interactive password
        //
        if (Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) {
          PasswordCallback (Selection, MenuOption, NULL);
        }

        gBS->FreePool (StringPtr);
        return Status;
      }

      //
      // Confirm new password
      //
      TempString = EfiLibAllocateZeroPool ((Maximum + 1) * sizeof (CHAR16));
      ASSERT (TempString);
      Status = ReadString (MenuOption, gConfirmPassword, TempString);
      if (EFI_ERROR (Status)) {
        //
        // Reset state machine for interactive password
        //
        if (Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) {
          PasswordCallback (Selection, MenuOption, NULL);
        }

        gBS->FreePool (StringPtr);
        gBS->FreePool (TempString);
        return Status;
      }

      //
      // Compare two typed-in new passwords
      //
      if (EfiStrCmp (StringPtr, TempString) == 0) {
        //
        // Two password match, send it to Configuration Driver
        //
        if (Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) {
          PasswordCallback (Selection, MenuOption, StringPtr);
        } else {
          EfiCopyMem (Question->BufferValue, StringPtr, Maximum * sizeof (CHAR16));
          SetQuestionValue (Selection->FormSet, Selection->Form, Question, FALSE);
        }
      } else {
        //
        // Reset state machine for interactive password
        //
        if (Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) {
          PasswordCallback (Selection, MenuOption, NULL);
        }

        //
        // Two password mismatch, prompt error message
        //
        do {
          CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gConfirmError, gPressEnter, gEmptyString);
        } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
      }

      gBS->FreePool (TempString);
      gBS->FreePool (StringPtr);
    }
    break;

  default:
    break;
  }

  return Status;
}
示例#5
0
文件: Expression.c 项目: Kohrara/edk
EFI_STATUS
EvaluateExpression (
  IN FORM_BROWSER_FORMSET  *FormSet,
  IN FORM_BROWSER_FORM     *Form,
  IN OUT FORM_EXPRESSION   *Expression
  )
/*++

Routine Description:

  Evaluate the result of a HII expression

Arguments:

  FormSet    - FormSet associated with this expression.
  Form       - Form associated with this expression.
  Expression - Expression to be evaluated.

Returns:

  EFI_SUCCESS           - The expression evaluated successfuly
  EFI_NOT_FOUND         - The Question which referenced by a QuestionId could not be found.
  EFI_OUT_OF_RESOURCES  - There is not enough system memory to grow the stack.
  EFI_ACCESS_DENIED     - The pop operation underflowed the stack
  EFI_INVALID_PARAMETER - Syntax error with the Expression

--*/
{
  EFI_STATUS              Status;
  EFI_LIST_ENTRY          *Link;
  EXPRESSION_OPCODE       *OpCode;
  FORM_BROWSER_STATEMENT  *Question;
  FORM_BROWSER_STATEMENT  *Question2;
  UINT16                  Index;
  EFI_HII_VALUE           Data1;
  EFI_HII_VALUE           Data2;
  EFI_HII_VALUE           Data3;
  FORM_EXPRESSION         *RuleExpression;
  EFI_HII_VALUE           *Value;
  INTN                    Result;
  CHAR16                  *StrPtr;

  //
  // Always reset the stack before evaluating an Expression
  //
  ResetExpressionStack ();

  Expression->Result.Type = EFI_IFR_TYPE_OTHER;

  Link = GetFirstNode (&Expression->OpCodeListHead);
  while (!IsNull (&Expression->OpCodeListHead, Link)) {
    OpCode = EXPRESSION_OPCODE_FROM_LINK (Link);

    Link = GetNextNode (&Expression->OpCodeListHead, Link);

    EfiZeroMem (&Data1, sizeof (EFI_HII_VALUE));
    EfiZeroMem (&Data2, sizeof (EFI_HII_VALUE));
    EfiZeroMem (&Data3, sizeof (EFI_HII_VALUE));

    Value = &Data3;
    Value->Type = EFI_IFR_TYPE_BOOLEAN;
    Status = EFI_SUCCESS;

    switch (OpCode->Operand) {
    //
    // Built-in functions
    //
    case EFI_IFR_EQ_ID_VAL_OP:
      Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);
      if (Question == NULL) {
        return EFI_NOT_FOUND;
      }

      Result = CompareHiiValue (&Question->HiiValue, &OpCode->Value, NULL);
      if (Result == EFI_INVALID_PARAMETER) {
        return EFI_INVALID_PARAMETER;
      }
      Value->Value.b = (Result == 0) ? TRUE : FALSE;
      break;

    case EFI_IFR_EQ_ID_ID_OP:
      Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);
      if (Question == NULL) {
        return EFI_NOT_FOUND;
      }

      Question2 = IdToQuestion (FormSet, Form, OpCode->QuestionId2);
      if (Question2 == NULL) {
        return EFI_NOT_FOUND;
      }

      Result = CompareHiiValue (&Question->HiiValue, &Question2->HiiValue, FormSet->HiiHandle);
      if (Result == EFI_INVALID_PARAMETER) {
        return EFI_INVALID_PARAMETER;
      }
      Value->Value.b = (Result == 0) ? TRUE : FALSE;
      break;

    case EFI_IFR_EQ_ID_LIST_OP:
      Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);
      if (Question == NULL) {
        return EFI_NOT_FOUND;
      }

      Value->Value.b = FALSE;
      for (Index =0; Index < OpCode->ListLength; Index++) {
        if (Question->HiiValue.Value.u16 == OpCode->ValueList[Index]) {
          Value->Value.b = TRUE;
          break;
        }
      }
      break;

    case EFI_IFR_DUP_OP:
      Status = PopExpression (Value);
      if (EFI_ERROR (Status)) {
        return Status;
      }

      Status = PushExpression (Value);
      break;

    case EFI_IFR_QUESTION_REF1_OP:
    case EFI_IFR_THIS_OP:
      Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);
      if (Question == NULL) {
        return EFI_NOT_FOUND;
      }

      Value = &Question->HiiValue;
      break;

    case EFI_IFR_QUESTION_REF3_OP:
      if (OpCode->DevicePath == 0) {
        //
        // EFI_IFR_QUESTION_REF3
        // Pop an expression from the expression stack
        //
        Status = PopExpression (Value);
        if (EFI_ERROR (Status)) {
          return Status;
        }

        //
        // Validate the expression value
        //
        if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {
          return EFI_NOT_FOUND;
        }

        Question = IdToQuestion (FormSet, Form, Value->Value.u16);
        if (Question == NULL) {
          return EFI_NOT_FOUND;
        }

        //
        // push the questions' value on to the expression stack
        //
        Value = &Question->HiiValue;
      } else {
        //
        // BUGBUG: push 0 for EFI_IFR_QUESTION_REF3_2 and EFI_IFR_QUESTION_REF3_3,
        // since it is impractical to evaluate the value of a Question in another
        // Hii Package list.
        //
        EfiZeroMem (Value, sizeof (EFI_HII_VALUE));
      }
      break;

    case EFI_IFR_RULE_REF_OP:
      //
      // Find expression for this rule
      //
      RuleExpression = RuleIdToExpression (Form, OpCode->RuleId);
      if (RuleExpression == NULL) {
        return EFI_NOT_FOUND;
      }

      //
      // Evaluate this rule expression
      //
      Status = EvaluateExpression (FormSet, Form, RuleExpression);
      if (EFI_ERROR (Status)) {
        return Status;
      }

      Value = &RuleExpression->Result;
      break;

    case EFI_IFR_STRING_REF1_OP:
      Value->Type = EFI_IFR_TYPE_STRING;
      Value->Value.string = OpCode->Value.Value.string;
      break;

    //
    // Constant
    //
    case EFI_IFR_TRUE_OP:
    case EFI_IFR_FALSE_OP:
    case EFI_IFR_ONE_OP:
    case EFI_IFR_ONES_OP:
    case EFI_IFR_UINT8_OP:
    case EFI_IFR_UINT16_OP:
    case EFI_IFR_UINT32_OP:
    case EFI_IFR_UINT64_OP:
    case EFI_IFR_UNDEFINED_OP:
    case EFI_IFR_VERSION_OP:
    case EFI_IFR_ZERO_OP:
      Value = &OpCode->Value;
      break;

    //
    // unary-op
    //
    case EFI_IFR_LENGTH_OP:
      Status = PopExpression (Value);
      if (EFI_ERROR (Status)) {
        return Status;
      }
      if (Value->Type != EFI_IFR_TYPE_STRING) {
        return EFI_INVALID_PARAMETER;
      }

      StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle);
      if (StrPtr == NULL) {
        return EFI_INVALID_PARAMETER;
      }

      Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
      Value->Value.u64 = EfiStrLen (StrPtr);
      gBS->FreePool (StrPtr);
      break;

    case EFI_IFR_NOT_OP:
      Status = PopExpression (Value);
      if (EFI_ERROR (Status)) {
        return Status;
      }
      if (Value->Type != EFI_IFR_TYPE_BOOLEAN) {
        return EFI_INVALID_PARAMETER;
      }
      Value->Value.b = !Value->Value.b;
      break;

    case EFI_IFR_QUESTION_REF2_OP:
      //
      // Pop an expression from the expression stack
      //
      Status = PopExpression (Value);
      if (EFI_ERROR (Status)) {
        return Status;
      }

      //
      // Validate the expression value
      //
      if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {
        return EFI_NOT_FOUND;
      }

      Question = IdToQuestion (FormSet, Form, Value->Value.u16);
      if (Question == NULL) {
        return EFI_NOT_FOUND;
      }

      Value = &Question->HiiValue;
      break;

    case EFI_IFR_STRING_REF2_OP:
      //
      // Pop an expression from the expression stack
      //
      Status = PopExpression (Value);
      if (EFI_ERROR (Status)) {
        return Status;
      }

      //
      // Validate the expression value
      //
      if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {
        return EFI_NOT_FOUND;
      }

      Value->Type = EFI_IFR_TYPE_STRING;
      StrPtr = GetToken (Value->Value.u16, FormSet->HiiHandle);
      if (StrPtr == NULL) {
        //
        // If String not exit, push an empty string
        //
        Value->Value.string = NewString (gEmptyString, FormSet->HiiHandle);
      } else {
        Index = (UINT16) Value->Value.u64;
        Value->Value.string = Index;
        gBS->FreePool (StrPtr);
      }
      break;

    case EFI_IFR_TO_BOOLEAN_OP:
      //
      // Pop an expression from the expression stack
      //
      Status = PopExpression (Value);
      if (EFI_ERROR (Status)) {
        return Status;
      }

      //
      // Convert an expression to a Boolean
      //
      if (Value->Type <= EFI_IFR_TYPE_DATE) {
        //
        // When converting from an unsigned integer, zero will be converted to
        // FALSE and any other value will be converted to TRUE.
        //
        Value->Value.b = (Value->Value.u64) ? TRUE : FALSE;

        Value->Type = EFI_IFR_TYPE_BOOLEAN;
      } else if (Value->Type == EFI_IFR_TYPE_STRING) {
        //
        // When converting from a string, if case-insensitive compare
        // with "true" is True, then push True. If a case-insensitive compare
        // with "false" is True, then push False.
        //
        StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle);
        if (StrPtr == NULL) {
          return EFI_INVALID_PARAMETER;
        }

        if ((EfiStrCmp (StrPtr, L"true") == 0) || (EfiStrCmp (StrPtr, L"false") == 0)){
          Value->Value.b = TRUE;
        } else {
          Value->Value.b = FALSE;
        }
        gBS->FreePool (StrPtr);
        Value->Type = EFI_IFR_TYPE_BOOLEAN;
      }
      break;

    case EFI_IFR_TO_STRING_OP:
      Status = IfrToString (FormSet, OpCode->Format, Value);
      break;

    case EFI_IFR_TO_UINT_OP:
      Status = IfrToUint (FormSet, Value);
      break;

    case EFI_IFR_TO_LOWER_OP:
    case EFI_IFR_TO_UPPER_OP:
      Status = InitializeUnicodeCollationProtocol ();
      if (EFI_ERROR (Status)) {
        return Status;
      }

      Status = PopExpression (Value);
      if (EFI_ERROR (Status)) {
        return Status;
      }

      if (Value->Type != EFI_IFR_TYPE_STRING) {
        return EFI_UNSUPPORTED;
      }

      StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle);
      if (StrPtr == NULL) {
        return EFI_NOT_FOUND;
      }

      if (OpCode->Operand == EFI_IFR_TO_LOWER_OP) {
        mUnicodeCollation->StrLwr (mUnicodeCollation, StrPtr);
      } else {
        mUnicodeCollation->StrUpr (mUnicodeCollation, StrPtr);
      }
      Value->Value.string = NewString (StrPtr, FormSet->HiiHandle);
      gBS->FreePool (StrPtr);
      break;

    case EFI_IFR_BITWISE_NOT_OP:
      //
      // Pop an expression from the expression stack
      //
      Status = PopExpression (Value);
      if (EFI_ERROR (Status)) {
        return Status;
      }
      if (Value->Type > EFI_IFR_TYPE_DATE) {
        return EFI_INVALID_PARAMETER;
      }

      Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
      Value->Value.u64 = ~Value->Value.u64;
      break;

    //
    // binary-op
    //
    case EFI_IFR_ADD_OP:
    case EFI_IFR_SUBTRACT_OP:
    case EFI_IFR_MULTIPLY_OP:
    case EFI_IFR_DIVIDE_OP:
    case EFI_IFR_MODULO_OP:
    case EFI_IFR_BITWISE_AND_OP:
    case EFI_IFR_BITWISE_OR_OP:
    case EFI_IFR_SHIFT_LEFT_OP:
    case EFI_IFR_SHIFT_RIGHT_OP:
      //
      // Pop an expression from the expression stack
      //
      Status = PopExpression (&Data2);
      if (EFI_ERROR (Status)) {
        return Status;
      }
      if (Data2.Type > EFI_IFR_TYPE_DATE) {
        return EFI_INVALID_PARAMETER;
      }

      //
      // Pop another expression from the expression stack
      //
      Status = PopExpression (&Data1);
      if (EFI_ERROR (Status)) {
        return Status;
      }
      if (Data1.Type > EFI_IFR_TYPE_DATE) {
        return EFI_INVALID_PARAMETER;
      }

      Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;

      switch (OpCode->Operand) {
        case EFI_IFR_ADD_OP:
          Value->Value.u64 = Data1.Value.u64 + Data2.Value.u64;
          break;

        case EFI_IFR_SUBTRACT_OP:
          Value->Value.u64 = Data1.Value.u64 - Data2.Value.u64;
          break;

        case EFI_IFR_MULTIPLY_OP:
          Value->Value.u64 = MultU64x32 (Data1.Value.u64, (UINTN) Data2.Value.u64);
          break;

        case EFI_IFR_DIVIDE_OP:
          Value->Value.u64 = DivU64x32 (Data1.Value.u64, (UINTN) Data2.Value.u64, NULL);
          break;

        case EFI_IFR_MODULO_OP:
          DivU64x32 (Data1.Value.u64, (UINTN) Data2.Value.u64, (UINTN *) &Value->Value.u64);
          break;

        case EFI_IFR_BITWISE_AND_OP:
          Value->Value.u64 = Data1.Value.u64 & Data2.Value.u64;
          break;

        case EFI_IFR_BITWISE_OR_OP:
          Value->Value.u64 = Data1.Value.u64 | Data2.Value.u64;
          break;

        case EFI_IFR_SHIFT_LEFT_OP:
          Value->Value.u64 = LShiftU64 (Data1.Value.u64, (UINTN) Data2.Value.u64);
          break;

        case EFI_IFR_SHIFT_RIGHT_OP:
          Value->Value.u64 = RShiftU64 (Data1.Value.u64, (UINTN) Data2.Value.u64);
          break;

        default:
          break;
      }
      break;

    case EFI_IFR_AND_OP:
    case EFI_IFR_OR_OP:
      //
      // Two Boolean operator
      //
      Status = PopExpression (&Data2);
      if (EFI_ERROR (Status)) {
        return Status;
      }
      if (Data2.Type != EFI_IFR_TYPE_BOOLEAN) {
        return EFI_INVALID_PARAMETER;
      }

      //
      // Pop another expression from the expression stack
      //
      Status = PopExpression (&Data1);
      if (EFI_ERROR (Status)) {
        return Status;
      }
      if (Data1.Type != EFI_IFR_TYPE_BOOLEAN) {
        return EFI_INVALID_PARAMETER;
      }

      if (OpCode->Operand == EFI_IFR_AND_OP) {
        Value->Value.b = Data1.Value.b && Data2.Value.b;
      } else {
        Value->Value.b = Data1.Value.b || Data2.Value.b;
      }
      break;

    case EFI_IFR_EQUAL_OP:
    case EFI_IFR_NOT_EQUAL_OP:
    case EFI_IFR_GREATER_EQUAL_OP:
    case EFI_IFR_GREATER_THAN_OP:
    case EFI_IFR_LESS_EQUAL_OP:
    case EFI_IFR_LESS_THAN_OP:
      //
      // Compare two integer, string, boolean or date/time
      //
      Status = PopExpression (&Data2);
      if (EFI_ERROR (Status)) {
        return Status;
      }
      if (Data2.Type > EFI_IFR_TYPE_BOOLEAN && Data2.Type != EFI_IFR_TYPE_STRING) {
        return EFI_INVALID_PARAMETER;
      }

      //
      // Pop another expression from the expression stack
      //
      Status = PopExpression (&Data1);
      if (EFI_ERROR (Status)) {
        return Status;
      }

      Result = CompareHiiValue (&Data1, &Data2, FormSet->HiiHandle);
      if (Result == EFI_INVALID_PARAMETER) {
        return EFI_INVALID_PARAMETER;
      }

      switch (OpCode->Operand) {
      case EFI_IFR_EQUAL_OP:
        Value->Value.b = (Result == 0) ? TRUE : FALSE;
        break;

      case EFI_IFR_NOT_EQUAL_OP:
        Value->Value.b = (Result != 0) ? TRUE : FALSE;
        break;

      case EFI_IFR_GREATER_EQUAL_OP:
        Value->Value.b = (Result >= 0) ? TRUE : FALSE;
        break;

      case EFI_IFR_GREATER_THAN_OP:
        Value->Value.b = (Result > 0) ? TRUE : FALSE;
        break;

      case EFI_IFR_LESS_EQUAL_OP:
        Value->Value.b = (Result <= 0) ? TRUE : FALSE;
        break;

      case EFI_IFR_LESS_THAN_OP:
        Value->Value.b = (Result < 0) ? TRUE : FALSE;
        break;

      default:
        break;
      }
      break;

    case EFI_IFR_MATCH_OP:
      Status = IfrMatch (FormSet, Value);
      break;

    case EFI_IFR_CATENATE_OP:
      Status = IfrCatenate (FormSet, Value);
      break;

    //
    // ternary-op
    //
    case EFI_IFR_CONDITIONAL_OP:
      //
      // Pop third expression from the expression stack
      //
      Status = PopExpression (&Data3);
      if (EFI_ERROR (Status)) {
        return Status;
      }

      //
      // Pop second expression from the expression stack
      //
      Status = PopExpression (&Data2);
      if (EFI_ERROR (Status)) {
        return Status;
      }

      //
      // Pop first expression from the expression stack
      //
      Status = PopExpression (&Data1);
      if (EFI_ERROR (Status)) {
        return Status;
      }
      if (Data1.Type != EFI_IFR_TYPE_BOOLEAN) {
        return EFI_INVALID_PARAMETER;
      }

      if (Data1.Value.b) {
        Value = &Data3;
      } else {
        Value = &Data2;
      }
      break;

    case EFI_IFR_FIND_OP:
      Status = IfrFind (FormSet, OpCode->Format, Value);
      break;

    case EFI_IFR_MID_OP:
      Status = IfrMid (FormSet, Value);
      break;

    case EFI_IFR_TOKEN_OP:
      Status = IfrToken (FormSet, Value);
      break;

    case EFI_IFR_SPAN_OP:
      Status = IfrSpan (FormSet, OpCode->Flags, Value);
      break;

    default:
      break;
    }
    if (EFI_ERROR (Status)) {
      return Status;
    }

    Status = PushExpression (Value);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  //
  // Pop the final result from expression stack
  //
  Value = &Data1;
  Status = PopExpression (Value);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // After evaluating an expression, there should be only one value left on the expression stack
  //
  if (PopExpression (Value) != EFI_ACCESS_DENIED) {
    return EFI_INVALID_PARAMETER;
  }

  EfiCopyMem (&Expression->Result, Value, sizeof (EFI_HII_VALUE));

  return EFI_SUCCESS;
}
示例#6
0
文件: Expression.c 项目: Kohrara/edk
INTN
CompareHiiValue (
  IN  EFI_HII_VALUE   *Value1,
  IN  EFI_HII_VALUE   *Value2,
  IN  EFI_HII_HANDLE  HiiHandle OPTIONAL
  )
/*++

Routine Description:
  Compare two Hii value.

Arguments:
  Value1    - Expression value to compare on left-hand
  Value2    - Expression value to compare on right-hand
  HiiHandle - Only required for string compare

Returns:
  EFI_INVALID_PARAMETER  - Could not perform comparation on two values
  0                      - Two operators equeal
  < 0                    - Value1 is greater than Value2
  > 0                    - Value1 is less than Value2

--*/
{
  INTN    Result;
  INT64   Temp64;
  CHAR16  *Str1;
  CHAR16  *Str2;

  if (Value1->Type >= EFI_IFR_TYPE_OTHER || Value2->Type >= EFI_IFR_TYPE_OTHER ) {
    return EFI_INVALID_PARAMETER;
  }

  if (Value1->Type == EFI_IFR_TYPE_STRING || Value2->Type == EFI_IFR_TYPE_STRING ) {
    if (Value1->Type != Value2->Type) {
      //
      // Both Operator should be type of String
      //
      return EFI_INVALID_PARAMETER;
    }

    if (Value1->Value.string == 0 || Value2->Value.string == 0) {
      //
      // StringId 0 is reserved
      //
      return EFI_INVALID_PARAMETER;
    }

    if (Value1->Value.string == Value2->Value.string) {
      return 0;
    }

    Str1 = GetToken (Value1->Value.string, HiiHandle);
    if (Str1 == NULL) {
      //
      // String not found
      //
      return EFI_INVALID_PARAMETER;
    }

    Str2 = GetToken (Value2->Value.string, HiiHandle);
    if (Str2 == NULL) {
      gBS->FreePool (Str1);
      return EFI_INVALID_PARAMETER;
    }

    Result = EfiStrCmp (Str1, Str2);

    gBS->FreePool (Str1);
    gBS->FreePool (Str2);

    return Result;
  }

  //
  // Take remain types(integer, boolean, date/time) as integer
  //
  Temp64 = (INT64) (Value1->Value.u64 - Value2->Value.u64);
  if (Temp64 > 0) {
    Result = 1;
  } else if (Temp64 < 0) {
    Result = -1;
  } else {
    Result = 0;
  }

  return Result;
}