Ejemplo n.º 1
0
EFI_STATUS
EFIAPI
StslRecordMessage (
  IN EFI_STANDARD_TEST_LIBRARY_PROTOCOL     *This,
  IN EFI_VERBOSE_LEVEL                      VerboseLevel,
  IN CHAR16                                 *Message,
  ...
)
/*++

Routine Description:

  Records the test message.

Arguments:

  This          - Standard test library protocol instance.
  VerboseLevel  - Minimal verbose level to record this message. For example,
                  EFI_VERBOSE_LEVEL_QUIET means this message should be recorded
                  even the test is run in QUIET mode. On the contrary,
                  EFI_VERBOSE_LEVEL_EXHAUSTIVE means this message will only be
                  recorded when the test is run in EXHAUSTIVE mode.
  Message       - Format string for the detail test information.

Returns:

  EFI_SUCCESS   - record the message successfully.

--*/
{
  EFI_STATUS                      Status;
  VA_LIST                         Marker;
  CHAR16                          Buffer[EFI_MAX_PRINT_BUFFER];
  STANDARD_TEST_PRIVATE_DATA      *Private;

  Status = EFI_SUCCESS;
  Private = STANDARD_TEST_PRIVATE_DATA_FROM_STSL (This);

  if (VerboseLevel <= Private->VerboseLevel) {
    VA_START(Marker, Message);
    VSPrint (Buffer, EFI_MAX_PRINT_BUFFER, Message, Marker);
    VA_END (Marker);

    if ( EfiStrLen (Buffer) + 3 < EFI_MAX_PRINT_BUFFER ) {
      EfiStrCat (Buffer, L"\r\n");
    }
    Status = StslWriteLogFile (Private, Buffer);
  }

  return Status;
}
EFI_STATUS
BBTestExtractConfigConformanceTestCheckpoint1 (
  IN EFI_STANDARD_TEST_LIBRARY_PROTOCOL    *StandardLib,
  IN EFI_HII_CONFIG_ACCESS_PROTOCOL        *HIIConfigAccess
  )
{
  EFI_STATUS            Status;
  EFI_TEST_ASSERTION    AssertionType;
 
  EFI_STRING            Progress = NULL;
  EFI_STRING            Results = NULL;
  EFI_STRING            ResultsPtr = NULL;
  UINTN                 Len = 0;
  EFI_STRING            Pointer = NULL;
  UINT8                 IfMulti = 0;
  
  EFI_STRING            Request = NULL;
  //
  // Call ExtractConfig with Request been <MultiConfigRequest>
  //
  Status = HIIConfigAccess->ExtractConfig (
                              HIIConfigAccess,
                              NULL,
                              &Progress,
                              &Results
                              );

  if ( Status == EFI_SUCCESS ) {
    Len = StrLen(Results);
    //
    // Make sure the size of Request is enough to hold <MultiConfigRequest> 
    // if original Results is not Multi
    //
    Request = (EFI_STRING) AllocateZeroPool ( 2 * Len + 2 + 256);
    if (Request == NULL) {
  	  FreePool(Results);
      return EFI_OUT_OF_RESOURCES;
    }
  } else {
    return Status;
  }

  Status = MultiAltRespToMultiReq (Results, Request);
  ResultsPtr = Request;

  FreePool(Results);
  Results = NULL;

  if ( EfiStrStr(Request, L"GUID=") != NULL ) {
    Pointer = EfiStrStr(Request, L"GUID=");
    Pointer++;
    if ( EfiStrStr(Pointer, L"GUID=") != NULL )
	  IfMulti = 1;
  }
  
  if ( IfMulti == 0 ) {
    EfiStrCat( Request, L"&GUID=970eb94aa0d449f7b980bdaa47d42527&NAME=006a0069006e0039&PATH=000acf&grag&star");
  }

  Status = HIIConfigAccess->ExtractConfig (
                              HIIConfigAccess,
                              Request,
                              &Progress,
                              &Results
                              );
  
  if ( (EFI_INVALID_PARAMETER != Status) || (EfiStrnCmp (Progress, L"&GUID=", 6) != 0) ) {
    AssertionType = EFI_TEST_ASSERTION_FAILED;
  } else {
    AssertionType = EFI_TEST_ASSERTION_PASSED;
  }
  StandardLib->RecordAssertion (
                 StandardLib,
                 AssertionType,
                 gHIIConfigAccessBBTestConformanceAssertionGuid001,
                 L"HII_CONFIG_ACCESS_PROTOCOL.ExtractConfig - ExtractConfig() returns EFI_INVALID_PARAMETER with Request been <MultiConfigRequest>.",
                 L"%a:%d: Status - %r",
                 __FILE__,
                 (UINTN)__LINE__,
                 Status
           );
  FreePool(Request);
  return EFI_SUCCESS;
}
Ejemplo n.º 3
0
EFI_STATUS
GetSelectionInputPopUp (
  IN  UI_MENU_SELECTION           *Selection,
  IN  UI_MENU_OPTION              *MenuOption
  )
/*++

Routine Description:
  Get selection for OneOf and OrderedList (Left/Right will be ignored).

Arguments:
  Selection        -  Pointer to current selection.
  MenuOption       -  Pointer to the current input menu.

Returns:
  EFI_SUCCESS       - If Option input is processed successfully
  EFI_DEVICE_ERROR  - If operation fails

--*/
{
  EFI_STATUS              Status;
  EFI_INPUT_KEY           Key;
  UINTN                   Index;
  CHAR16                  *StringPtr;
  CHAR16                  *TempStringPtr;
  UINTN                   Index2;
  UINTN                   TopOptionIndex;
  UINTN                   HighlightOptionIndex;
  UINTN                   Start;
  UINTN                   End;
  UINTN                   Top;
  UINTN                   Bottom;
  UINTN                   PopUpMenuLines;
  UINTN                   MenuLinesInView;
  UINTN                   PopUpWidth;
  CHAR16                  Character;
  INT32                   SavedAttribute;
  BOOLEAN                 ShowDownArrow;
  BOOLEAN                 ShowUpArrow;
  UINTN                   DimensionsWidth;
  UINTN                   DimensionsHeight;
  EFI_LIST_ENTRY          *Link;
  BOOLEAN                 OrderedList;
  UINT8                   *ValueArray;
  UINT8                   ValueType;
  EFI_HII_VALUE           HiiValue;
  EFI_HII_VALUE           *HiiValueArray;
  UINTN                   OptionCount;
  QUESTION_OPTION         *OneOfOption;
  QUESTION_OPTION         *CurrentOption;
  FORM_BROWSER_STATEMENT  *Question;

  DimensionsWidth   = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn;
  DimensionsHeight  = gScreenDimensions.BottomRow - gScreenDimensions.TopRow;

  ValueArray        = NULL;
  ValueType         = 0;
  CurrentOption     = NULL;
  ShowDownArrow     = FALSE;
  ShowUpArrow       = FALSE;

  StringPtr = EfiLibAllocateZeroPool ((gOptionBlockWidth + 1) * 2);
  ASSERT (StringPtr);

  Question = MenuOption->ThisTag;
  if (Question->Operand == EFI_IFR_ORDERED_LIST_OP) {
    ValueArray = Question->BufferValue;
    ValueType = Question->ValueType;
    OrderedList = TRUE;
  } else {
    OrderedList = FALSE;
  }

  //
  // Calculate Option count
  //
  if (OrderedList) {
    for (Index = 0; Index < Question->MaxContainers; Index++) {
      if (GetArrayData (ValueArray, ValueType, Index) == 0) {
        break;
      }
    }

    OptionCount = Index;
  } else {
    OptionCount = 0;
    Link = GetFirstNode (&Question->OptionListHead);
    while (!IsNull (&Question->OptionListHead, Link)) {
      OneOfOption = QUESTION_OPTION_FROM_LINK (Link);

      OptionCount++;

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

  //
  // Prepare HiiValue array
  //
  HiiValueArray = EfiLibAllocateZeroPool (OptionCount * sizeof (EFI_HII_VALUE));
  ASSERT (HiiValueArray != NULL);
  Link = GetFirstNode (&Question->OptionListHead);
  for (Index = 0; Index < OptionCount; Index++) {
    if (OrderedList) {
      HiiValueArray[Index].Type = ValueType;
      HiiValueArray[Index].Value.u64 = GetArrayData (ValueArray, ValueType, Index);
    } else {
      OneOfOption = QUESTION_OPTION_FROM_LINK (Link);
      EfiCopyMem (&HiiValueArray[Index], &OneOfOption->Value, sizeof (EFI_HII_VALUE));
      Link = GetNextNode (&Question->OptionListHead, Link);
    }
  }

  //
  // Move Suppressed Option to list tail
  //
  PopUpMenuLines = 0;
  for (Index = 0; Index < OptionCount; Index++) {
    OneOfOption = ValueToOption (Question, &HiiValueArray[OptionCount - Index - 1]);
    if (OneOfOption == NULL) {
      return EFI_NOT_FOUND;
    }

    RemoveEntryList (&OneOfOption->Link);

    if ((OneOfOption->SuppressExpression != NULL) &&
        (OneOfOption->SuppressExpression->Result.Value.b)) {
      //
      // This option is suppressed, insert to tail
      //
      InsertTailList (&Question->OptionListHead, &OneOfOption->Link);
    } else {
      //
      // Insert to head
      //
      InsertHeadList (&Question->OptionListHead, &OneOfOption->Link);

      PopUpMenuLines++;
    }
  }

  //
  // Get the number of one of options present and its size
  //
  PopUpWidth = 0;
  HighlightOptionIndex = 0;
  Link = GetFirstNode (&Question->OptionListHead);
  for (Index = 0; Index < PopUpMenuLines; Index++) {
    OneOfOption = QUESTION_OPTION_FROM_LINK (Link);

    StringPtr = GetToken (OneOfOption->Text, MenuOption->Handle);
    if (EfiStrLen (StringPtr) > PopUpWidth) {
      PopUpWidth = EfiStrLen (StringPtr);
    }
    gBS->FreePool (StringPtr);

    if (!OrderedList && CompareHiiValue (&Question->HiiValue, &OneOfOption->Value, NULL) == 0) {
      //
      // Find current selected Option for OneOf
      //
      HighlightOptionIndex = Index;
    }

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

  //
  // Perform popup menu initialization.
  //
  PopUpWidth = PopUpWidth + POPUP_PAD_SPACE_COUNT;

  SavedAttribute = gST->ConOut->Mode->Attribute;
  gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);

  if ((PopUpWidth + POPUP_FRAME_WIDTH) > DimensionsWidth) {
    PopUpWidth = DimensionsWidth - POPUP_FRAME_WIDTH;
  }

  Start  = (DimensionsWidth - PopUpWidth - POPUP_FRAME_WIDTH) / 2 + gScreenDimensions.LeftColumn;
  End    = Start + PopUpWidth + POPUP_FRAME_WIDTH;
  Top    = gScreenDimensions.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT;
  Bottom = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT - 1;

  MenuLinesInView = Bottom - Top - 1;
  if (MenuLinesInView >= PopUpMenuLines) {
    Top     = Top + (MenuLinesInView - PopUpMenuLines) / 2;
    Bottom  = Top + PopUpMenuLines + 1;
  } else {
    ShowDownArrow = TRUE;
  }

  if (HighlightOptionIndex > (MenuLinesInView - 1)) {
    TopOptionIndex = HighlightOptionIndex - MenuLinesInView + 1;
  } else {
    TopOptionIndex = 0;
  }

  do {
    //
    // Clear that portion of the screen
    //
    ClearLines (Start, End, Top, Bottom, POPUP_TEXT | POPUP_BACKGROUND);

    //
    // Draw "One of" pop-up menu
    //
    Character = BOXDRAW_DOWN_RIGHT;
    PrintCharAt (Start, Top, Character);
    for (Index = Start; Index + 2 < End; Index++) {
      if ((ShowUpArrow) && ((Index + 1) == (Start + End) / 2)) {
        Character = GEOMETRICSHAPE_UP_TRIANGLE;
      } else {
        Character = BOXDRAW_HORIZONTAL;
      }

      PrintChar (Character);
    }

    Character = BOXDRAW_DOWN_LEFT;
    PrintChar (Character);
    Character = BOXDRAW_VERTICAL;
    for (Index = Top + 1; Index < Bottom; Index++) {
      PrintCharAt (Start, Index, Character);
      PrintCharAt (End - 1, Index, Character);
    }

    //
    // Move to top Option
    //
    Link = GetFirstNode (&Question->OptionListHead);
    for (Index = 0; Index < TopOptionIndex; Index++) {
      Link = GetNextNode (&Question->OptionListHead, Link);
    }

    //
    // Display the One of options
    //
    Index2 = Top + 1;
    for (Index = TopOptionIndex; (Index < PopUpMenuLines) && (Index2 < Bottom); Index++) {
      OneOfOption = QUESTION_OPTION_FROM_LINK (Link);
      Link = GetNextNode (&Question->OptionListHead, Link);

      StringPtr = GetToken (OneOfOption->Text, MenuOption->Handle);
      //
      // If the string occupies multiple lines, truncate it to fit in one line,
      // and append a "..." for indication.
      //
      if (EfiStrLen (StringPtr) > (PopUpWidth - 1)) {
        TempStringPtr = EfiLibAllocateZeroPool (sizeof (CHAR16) * (PopUpWidth - 1));
        ASSERT ( TempStringPtr != NULL );
        EfiCopyMem (TempStringPtr, StringPtr, (sizeof (CHAR16) * (PopUpWidth - 5)));
        gBS->FreePool (StringPtr);
        StringPtr = TempStringPtr;
        EfiStrCat (StringPtr, L"...");
      }

      if (Index == HighlightOptionIndex) {
          //
          // Highlight the selected one
          //
          CurrentOption = OneOfOption;

          gST->ConOut->SetAttribute (gST->ConOut, PICKLIST_HIGHLIGHT_TEXT | PICKLIST_HIGHLIGHT_BACKGROUND);
          PrintStringAt (Start + 2, Index2, StringPtr);
          gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);
        } else {
          gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);
          PrintStringAt (Start + 2, Index2, StringPtr);
        }

      Index2++;
      gBS->FreePool (StringPtr);
    }

    Character = BOXDRAW_UP_RIGHT;
    PrintCharAt (Start, Bottom, Character);
    for (Index = Start; Index + 2 < End; Index++) {
      if ((ShowDownArrow) && ((Index + 1) == (Start + End) / 2)) {
        Character = GEOMETRICSHAPE_DOWN_TRIANGLE;
      } else {
        Character = BOXDRAW_HORIZONTAL;
      }

      PrintChar (Character);
    }

    Character = BOXDRAW_UP_LEFT;
    PrintChar (Character);

    //
    // Get User selection
    //
    Key.UnicodeChar = CHAR_NULL;
    if ((gDirection == SCAN_UP) || (gDirection == SCAN_DOWN)) {
      Key.ScanCode  = gDirection;
      gDirection    = 0;
      goto TheKey;
    }

    Status = WaitForKeyStroke (&Key);

TheKey:
    switch (Key.UnicodeChar) {
    case '+':
      if (OrderedList) {
        if ((TopOptionIndex > 0) && (TopOptionIndex == HighlightOptionIndex)) {
          //
          // Highlight reaches the top of the popup window, scroll one menu item.
          //
          TopOptionIndex--;
          ShowDownArrow = TRUE;
        }

        if (TopOptionIndex == 0) {
          ShowUpArrow = FALSE;
        }

        if (HighlightOptionIndex > 0) {
          HighlightOptionIndex--;

          SwapListEntries (CurrentOption->Link.BackLink, &CurrentOption->Link);
        }
      }
      break;

    case '-':
      //
      // If an ordered list op-code, we will allow for a popup of +/- keys
      // to create an ordered list of items
      //
      if (OrderedList) {
        if (((TopOptionIndex + MenuLinesInView) < PopUpMenuLines) &&
            (HighlightOptionIndex == (TopOptionIndex + MenuLinesInView - 1))) {
          //
          // Highlight reaches the bottom of the popup window, scroll one menu item.
          //
          TopOptionIndex++;
          ShowUpArrow = TRUE;
        }

        if ((TopOptionIndex + MenuLinesInView) == PopUpMenuLines) {
          ShowDownArrow = FALSE;
        }

        if (HighlightOptionIndex < (PopUpMenuLines - 1)) {
          HighlightOptionIndex++;

          SwapListEntries (&CurrentOption->Link, CurrentOption->Link.ForwardLink);
        }
      }
      break;

    case CHAR_NULL:
      switch (Key.ScanCode) {
      case SCAN_UP:
      case SCAN_DOWN:
        if (Key.ScanCode == SCAN_UP) {
          if ((TopOptionIndex > 0) && (TopOptionIndex == HighlightOptionIndex)) {
            //
            // Highlight reaches the top of the popup window, scroll one menu item.
            //
            TopOptionIndex--;
            ShowDownArrow = TRUE;
          }

          if (TopOptionIndex == 0) {
            ShowUpArrow = FALSE;
          }

          if (HighlightOptionIndex > 0) {
            HighlightOptionIndex--;
          }
        } else {
          if (((TopOptionIndex + MenuLinesInView) < PopUpMenuLines) &&
              (HighlightOptionIndex == (TopOptionIndex + MenuLinesInView - 1))) {
            //
            // Highlight reaches the bottom of the popup window, scroll one menu item.
            //
            TopOptionIndex++;
            ShowUpArrow = TRUE;
          }

          if ((TopOptionIndex + MenuLinesInView) == PopUpMenuLines) {
            ShowDownArrow = FALSE;
          }

          if (HighlightOptionIndex < (PopUpMenuLines - 1)) {
            HighlightOptionIndex++;
          }
        }
        break;

      case SCAN_ESC:
        gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute);

        //
        // Restore link list order for orderedlist
        //
        if (OrderedList) {
          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) {
              break;
            }

            OneOfOption = ValueToOption (Question, &HiiValue);
            if (OneOfOption == NULL) {
              return EFI_NOT_FOUND;
            }

            RemoveEntryList (&OneOfOption->Link);
            InsertTailList (&Question->OptionListHead, &OneOfOption->Link);
          }
        }

        gBS->FreePool (HiiValueArray);
        return EFI_DEVICE_ERROR;

      default:
        break;
      }

      break;

    case CHAR_CARRIAGE_RETURN:
      //
      // return the current selection
      //
      if (OrderedList) {
        Index = 0;
        Link = GetFirstNode (&Question->OptionListHead);
        while (!IsNull (&Question->OptionListHead, Link)) {
          OneOfOption = QUESTION_OPTION_FROM_LINK (Link);

          SetArrayData (ValueArray, ValueType, Index, OneOfOption->Value.Value.u64);

          Index++;
          if (Index > Question->MaxContainers) {
            break;
          }

          Link = GetNextNode (&Question->OptionListHead, Link);
        }
      } else {
        EfiCopyMem (&Question->HiiValue, &CurrentOption->Value, sizeof (EFI_HII_VALUE));
      }

      gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute);
      gBS->FreePool (HiiValueArray);

      Status = ValidateQuestion (Selection->FormSet, Selection->Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF);
      if (EFI_ERROR (Status)) {
        //
        // Input value is not valid, restore Question Value
        //
        GetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);
      } else {
        SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);
        UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);
      }

      return Status;

    default:
      break;
    }
  } while (TRUE);

  //
  // Code will not reach here
  //
  return EFI_SUCCESS;
}
Ejemplo n.º 4
0
EFI_STATUS
ReadString (
  IN  UI_MENU_OPTION              *MenuOption,
  IN  CHAR16                      *Prompt,
  OUT CHAR16                      *StringPtr
  )
/*++

Routine Description:
  Get string or password input from user.

Arguments:
  MenuOption       -  Pointer to the current input menu.
  Prompt           -  The prompt string shown on popup window.
  StringPtr        -  Destination for use input string.

Returns:
  EFI_SUCCESS       - If string input is read successfully
  EFI_DEVICE_ERROR  - If operation fails

--*/
{
  EFI_STATUS              Status;
  EFI_INPUT_KEY           Key;
  CHAR16                  NullCharacter;
  UINTN                   ScreenSize;
  CHAR16                  Space[2];
  CHAR16                  KeyPad[2];
  CHAR16                  *TempString;
  CHAR16                  *BufferedString;
  UINTN                   Index;
  UINTN                   Count;
  UINTN                   Start;
  UINTN                   Top;
  UINTN                   DimensionsWidth;
  UINTN                   DimensionsHeight;
  BOOLEAN                 CursorVisible;
  UINTN                   Minimum;
  UINTN                   Maximum;
  FORM_BROWSER_STATEMENT  *Question;
  BOOLEAN                 IsPassword;

  DimensionsWidth  = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn;
  DimensionsHeight = gScreenDimensions.BottomRow - gScreenDimensions.TopRow;

  NullCharacter    = CHAR_NULL;
  ScreenSize       = GetStringWidth (Prompt) / sizeof (CHAR16);
  Space[0]         = L' ';
  Space[1]         = CHAR_NULL;

  Question         = MenuOption->ThisTag;
  Minimum          = (UINTN) Question->Minimum;
  Maximum          = (UINTN) Question->Maximum;

  if (Question->Operand == EFI_IFR_PASSWORD_OP) {
    IsPassword = TRUE;
  } else {
    IsPassword = FALSE;
  }

  TempString = EfiLibAllocateZeroPool ((Maximum + 1)* sizeof (CHAR16));
  ASSERT (TempString);

  if (ScreenSize < (Maximum + 1)) {
    ScreenSize = Maximum + 1;
  }

  if ((ScreenSize + 2) > DimensionsWidth) {
    ScreenSize = DimensionsWidth - 2;
  }

  BufferedString = EfiLibAllocateZeroPool (ScreenSize * 2);
  ASSERT (BufferedString);

  Start = (DimensionsWidth - ScreenSize - 2) / 2 + gScreenDimensions.LeftColumn + 1;
  Top   = ((DimensionsHeight - 6) / 2) + gScreenDimensions.TopRow - 1;

  //
  // Display prompt for string
  //
  CreatePopUp (ScreenSize, 4, &NullCharacter, Prompt, Space, &NullCharacter);

  gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY));

  CursorVisible = gST->ConOut->Mode->CursorVisible;
  gST->ConOut->EnableCursor (gST->ConOut, TRUE);

  do {
    Status = WaitForKeyStroke (&Key);

    gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY));
    switch (Key.UnicodeChar) {
    case CHAR_NULL:
      switch (Key.ScanCode) {
      case SCAN_LEFT:
        break;

      case SCAN_RIGHT:
        break;

      case SCAN_ESC:
        gBS->FreePool (TempString);
        gBS->FreePool (BufferedString);
        gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
        gST->ConOut->EnableCursor (gST->ConOut, CursorVisible);
        return EFI_DEVICE_ERROR;

      default:
        break;
      }

      break;

    case CHAR_CARRIAGE_RETURN:
      if (GetStringWidth (StringPtr) >= ((Minimum + 1) * sizeof (CHAR16))) {

        gBS->FreePool (TempString);
        gBS->FreePool (BufferedString);
        gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
        gST->ConOut->EnableCursor (gST->ConOut, CursorVisible);
        return EFI_SUCCESS;
      } else {
        //
        // Simply create a popup to tell the user that they had typed in too few characters.
        // To save code space, we can then treat this as an error and return back to the menu.
        //
        do {
          CreateDialog (4, TRUE, 0, NULL, &Key, &NullCharacter, gMiniString, gPressEnter, &NullCharacter);
        } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

        gBS->FreePool (TempString);
        gBS->FreePool (BufferedString);
        gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
        gST->ConOut->EnableCursor (gST->ConOut, CursorVisible);
        return EFI_DEVICE_ERROR;
      }

      break;

    case CHAR_BACKSPACE:
      if (StringPtr[0] != CHAR_NULL) {
        for (Index = 0; StringPtr[Index] != CHAR_NULL; Index++) {
          TempString[Index] = StringPtr[Index];
        }
        //
        // Effectively truncate string by 1 character
        //
        TempString[Index - 1] = CHAR_NULL;
        EfiStrCpy (StringPtr, TempString);
      }

    default:
      //
      // If it is the beginning of the string, don't worry about checking maximum limits
      //
      if ((StringPtr[0] == CHAR_NULL) && (Key.UnicodeChar != CHAR_BACKSPACE)) {
        StrnCpy (StringPtr, &Key.UnicodeChar, 1);
        StrnCpy (TempString, &Key.UnicodeChar, 1);
      } else if ((GetStringWidth (StringPtr) < ((Maximum + 1) * sizeof (CHAR16))) && (Key.UnicodeChar != CHAR_BACKSPACE)) {
        KeyPad[0] = Key.UnicodeChar;
        KeyPad[1] = CHAR_NULL;
        EfiStrCat (StringPtr, KeyPad);
        EfiStrCat (TempString, KeyPad);
      }

      //
      // If the width of the input string is now larger than the screen, we nee to
      // adjust the index to start printing portions of the string
      //
      SetUnicodeMem (BufferedString, ScreenSize - 1, L' ');
      PrintStringAt (Start + 1, Top + 3, BufferedString);

      if ((GetStringWidth (StringPtr) / 2) > (DimensionsWidth - 2)) {
        Index = (GetStringWidth (StringPtr) / 2) - DimensionsWidth + 2;
      } else {
        Index = 0;
      }

      if (IsPassword) {
        gST->ConOut->SetCursorPosition (gST->ConOut, Start + 1, Top + 3);
      }

      for (Count = 0; Index + 1 < GetStringWidth (StringPtr) / 2; Index++, Count++) {
        BufferedString[Count] = StringPtr[Index];

        if (IsPassword) {
          PrintChar (L'*');
        }
      }

      if (!IsPassword) {
        PrintStringAt (Start + 1, Top + 3, BufferedString);
      }
      break;
    }

    gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
    gST->ConOut->SetCursorPosition (gST->ConOut, Start + GetStringWidth (StringPtr) / 2, Top + 3);
  } while (TRUE);

  gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
  gST->ConOut->EnableCursor (gST->ConOut, CursorVisible);
  return Status;
}
EFI_STATUS
MultiAltRespToMultiResp (
  IN       EFI_STRING                           Resp1,
  IN OUT   EFI_STRING                           Resp2
  )
{
  EFI_STRING Pointer1 = Resp1;      
  EFI_STRING Pointer2 = NULL;
  EFI_STRING Pointer3 = Resp2;
  EFI_STRING CfgHdr = NULL;
  EFI_STRING FreePtr = NULL;
  CHAR8      Flag = 0;

  if (EfiStrnCmp (Pointer1, L"GUID=", 5) != 0) {    
    return EFI_INVALID_PARAMETER;
  }

  Pointer2 = (EFI_STRING) AllocateZeroPool (2 * StrLen(Resp1) + 2);
  if (Pointer2 == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  FreePtr = Pointer2;
  
  while (*Pointer1) {
    if (EfiStrnCmp (Pointer1, L"GUID=", 5) == 0) {
      CfgHdr = Pointer2;
      *(Pointer2++) = *(Pointer1++);
      while (*Pointer1 != L'&') {
        *(Pointer2++) = *(Pointer1++);
      }
    }
    if (EfiStrnCmp (Pointer1, L"&GUID=", 6) == 0) {
      *(Pointer2++) = *(Pointer1++);
      CfgHdr = Pointer2;
      while (*Pointer1 != L'&') {
        *(Pointer2++) = *(Pointer1++);
      }
    }
    if (EfiStrnCmp (Pointer1, L"&NAME=", 6) == 0) {
      *(Pointer2++) = *(Pointer1++);
      while (*Pointer1 != L'&') {
        *(Pointer2++) = *(Pointer1++);
      }
    }
    if (EfiStrnCmp (Pointer1, L"&PATH=", 6) == 0) {
      *(Pointer2++) = *(Pointer1++);
      while (*Pointer1 != L'&') {
        *(Pointer2++) = *(Pointer1++);
      }
      if (NULL == EfiStrStr(Resp2, CfgHdr)){
        if (*Resp2 == L'G')
          *(Pointer3++) = L'&';
        EfiStrCat(Resp2, CfgHdr);
        Pointer3 += StrLen(CfgHdr);
        Flag = 1;
      } else {
        Flag = 0;
      }  
    }
    while ((Flag == 1) && (EfiStrnCmp (Pointer1, L"&GUID=", 6) != 0) && *Pointer1) {
      if (EfiStrnCmp (Pointer1, L"&OFFSET=", 8) == 0) {
        *(Pointer3++) = *(Pointer1++);
        while (*Pointer1 != L'&') {
          *(Pointer3++) = *(Pointer1++);
        }
      }
      if (EfiStrnCmp (Pointer1, L"&WIDTH=", 7) == 0) {
        *(Pointer3++) = *(Pointer1++);
        while (*Pointer1 != L'&') {
          *(Pointer3++) = *(Pointer1++);
        }
      }
      if (EfiStrnCmp (Pointer1, L"&VALUE=", 7) == 0) {
        *(Pointer3++) = *(Pointer1++);
        while (*Pointer1 != L'&' && *Pointer1) {
          *(Pointer3++) = *(Pointer1++);
        }
      }
      if (EfiStrnCmp (Pointer1, L"&ALTCFG=", 8) == 0) {
        Pointer1 += 8;
        while (*Pointer1 != L'&' && *Pointer1) {
          Pointer1++;
        }
      }
      if ((*Pointer1 == L'&') && (EfiStrnCmp (Pointer1, L"&GUID=", 6) != 0)) {
        *(Pointer3++) = *(Pointer1++);
        while (*Pointer1 != L'=') {
          *(Pointer3++) = *(Pointer1++);
        }
        while (*Pointer1 != L'&' && *Pointer1) {
          *(Pointer3++) = *(Pointer1++);
        }
      }
    }
    Pointer1++;
  }

  FreePool(FreePtr);
  
  return EFI_SUCCESS;
}
Ejemplo n.º 6
0
CHAR16 *
BOpt_AppendFileName (
  IN  CHAR16  *Str1,
  IN  CHAR16  *Str2
  )
/*++

Routine Description
  Append file name to existing file name.

Arguments:
  Str1  -   existing file name
  Str2  -   file name to be appended

Returns:
  Allocate a new string to hold the appended result.
  Caller is responsible to free the returned string.

--*/
{
  UINTN   Size1;
  UINTN   Size2;
  CHAR16  *Str;
  CHAR16  *Ptr;
  CHAR16  *LastSlash;

  Size1 = EfiStrSize (Str1);
  Size2 = EfiStrSize (Str2);
  Str   = EfiAllocateZeroPool (Size1 + Size2 + sizeof (CHAR16));
  ASSERT (Str != NULL);

  EfiStrCat (Str, Str1);
  if (!((*Str == '\\') && (*(Str + 1) == 0))) {
    EfiStrCat (Str, L"\\");
  }

  EfiStrCat (Str, Str2);

  Ptr       = Str;
  LastSlash = Str;
  while (*Ptr != 0) {
    if (*Ptr == '\\' && *(Ptr + 1) == '.' && *(Ptr + 2) == '.' && *(Ptr + 3) != 0) {
      //
      // Convert \Name\..\ to \
      // DO NOT convert the .. if it is at the end of the string. This will
      // break the .. behavior in changing directories.
      //
      EfiStrCpy (LastSlash, Ptr + 3);
      Ptr = LastSlash;
    } else if (*Ptr == '\\' && *(Ptr + 1) == '.' && *(Ptr + 2) == '\\') {
      //
      // Convert a \.\ to a \
      //
      EfiStrCpy (Ptr, Ptr + 2);
      Ptr = LastSlash;
    } else if (*Ptr == '\\') {
      LastSlash = Ptr;
    }

    Ptr++;
  }

  return Str;
}
Ejemplo n.º 7
0
EFI_STATUS
EFIAPI
SetOptionsCallback (
  IN EFI_FORM_CALLBACK_PROTOCOL       *This,
  IN UINT16                           KeyValue,
  IN EFI_IFR_DATA_ARRAY               *Data,
  OUT EFI_HII_CALLBACK_PACKET         **Packet
  )
/*++

Routine Description:

  This is the function that is called to provide results data to the driver.  This data
  consists of a unique key which is used to identify what data is either being passed back
  or being asked for. 
  
  The callback function finish two main task: 
  1. Invoke the configuration protocol setoptions function according to user selection which
     is recorded by KeyValue.
  2. Collect all the available driver and controller infos to update the formset.
  
  
Arguments:

  KeyValue - A unique Goto OpCode callback value which record user's selection, 
                     In Set Options page, every item is associated to a goto IFR, and has a unique callback key.

  Data -         No use here.
  Packet-       No use here.
  
  Returns -    Always successful

--*/
{
  EFI_CALLBACK_INFO                         *Private;
  EFI_HII_UPDATE_DATA                       *UpdateData;
  
  EFI_STATUS                                Status;
  CHAR8                                     Language[4]; 
  CHAR16                                    Lang[4];
  UINTN                                     LangSize;
  
  UINTN                                     Index;   
  UINTN                                     ChoiceIndex;
  UINT8                                     *Location;
  
  UINTN                                     DriverImageHandleCount;
  EFI_HANDLE                                *DriverImageHandleBuffer;
  
  EFI_DRIVER_CONFIGURATION_PROTOCOL         *DriverConfiguration;
  EFI_DRIVER_BINDING_PROTOCOL               *DriverBinding;
  EFI_LOADED_IMAGE_PROTOCOL                 *LoadedImage;
#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
  EFI_COMPONENT_NAME_PROTOCOL               *ComponentName;
#else
  EFI_COMPONENT_NAME2_PROTOCOL              *ComponentName;
#endif
  EFI_FORM_BROWSER_PROTOCOL                 *FormBrowser;
  
  EFI_DEVICE_PATH_PROTOCOL                  *DevicePath;
  UINTN                                     ControllerHandleIndex;
  CHAR16                                    *ControllerHandleName;  
  BOOLEAN                                   FreeControllerHandleName;
  UINTN                                     ControllerHandleCount;
  EFI_HANDLE                                *ControllerHandleBuffer;

  UINTN                                     ChildControllerHandleIndex;
  CHAR16                                    *ChildControllerHandleName;
  BOOLEAN                                   FreeChildControllerHandleName;
  UINTN                                     ChildControllerHandleCount;
  EFI_HANDLE                                *ChildControllerHandleBuffer;

  CHAR16                                    *NewString;
  STRING_REF                                NewStringToken;
  CHAR16                                    *DriverName;
  BOOLEAN                                   FreeDriverName;

  EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED  ActionRequired;
  
  
  Private     = EFI_CALLBACK_INFO_FROM_THIS (This);

  //
  // Get current language to set options
  //
  LangSize = 0x3;
  Status = gRT->GetVariable (
              L"Lang",
              &gEfiGlobalVariableGuid,
              NULL,
              &LangSize,
              Language
              );

  ASSERT_EFI_ERROR (Status);
  
  Status = GetCurrentLanguage (Lang);
  ASSERT_EFI_ERROR (Status);
  //
  // Tast1:  Invoke the configuration protocol setoptions function according to user selection.
  // KeyValue between 0x100~0x200 means user select a driver or device item in 'Set Options'  dynamic page
  //
  if ((0x100 <= KeyValue) && (KeyValue <= 0x200)) {
  
    ChoiceIndex = KeyValue - 0x100;
    ActionRequired = 0;
    
    //
    // There should only be one Form Configuration protocol
    //
    Status = gBS->LocateProtocol (
                    &gEfiFormBrowserProtocolGuid, 
                    NULL, 
                    &FormBrowser
                    );
    ASSERT_EFI_ERROR (Status);
    
    //
    // Invoke the user selceted item's SetOptions function with corresponding driver or device handles 
    //
    gST->ConOut->ClearScreen (gST->ConOut);
    mChoice[ChoiceIndex].DriverConfiguration->SetOptions (
                                              mChoice[ChoiceIndex].DriverConfiguration,
                                              mChoice[ChoiceIndex].ControllerHandle,
                                              mChoice[ChoiceIndex].ChildControllerHandle,
                                              Language,
                                              &ActionRequired
                                              );
    gST->ConOut->ClearScreen (gST->ConOut);
    
    //
    // Notify user the action required after SetOptions function finish, and do the action according to user intent
    //
    Status = ProcessActionRequired (
                FormBrowser,
                Private,
                ActionRequired,
                mChoice[ChoiceIndex].DriverImageHandle,
                mChoice[ChoiceIndex].ControllerHandle,
                mChoice[ChoiceIndex].ChildControllerHandle
                );
    gST->ConOut->ClearScreen (gST->ConOut);
    
  }
  
  //
  // Task 2: Collect all the available driver infos and update the formset.
  // The available driver is those drivers which install efi driver configuration protocol
  //

  //
  // Allocate memory to Update form
  //
  DriverImageHandleBuffer = NULL;
  ControllerHandleBuffer = NULL;
  ChildControllerHandleBuffer = NULL;
  UpdateData = NULL;
  UpdateData = EfiLibAllocateZeroPool (UPDATE_DATA_SIZE);  
  ASSERT (UpdateData != NULL);
  //
  // Clear all the content in dynamic page 
  //  
  UpdateData->FormSetUpdate       = FALSE;
  UpdateData->FormCallbackHandle  = 0;
  UpdateData->FormUpdate          = FALSE;
  UpdateData->FormTitle           = 0;
  UpdateData->DataCount           = 0xff;
  UpdateData->Data                = NULL;

  Private->Hii->UpdateForm (
                  Private->Hii,
                  Private->RegisteredHandle,
                  (EFI_FORM_LABEL) 0x1234,  // Label 0x1234
                  FALSE,                    // Remove Op-codes (will never remove form/endform)
                  UpdateData                // Significant value is UpdateData->DataCount
                  );
  //
  // When user enter the page at first time, the 'first refresh' string is given to notify user to refresh all the drivers,
  // then the 'first refresh' string will be replaced by the 'refresh' string, and the two strings content are  same after the replacement
  //
  NewStringToken = (STRING_REF) STR_FIRST_REFRESH;
  NewString = GetString (Private, (STRING_REF) STR_REFRESH);
  ASSERT (NewString != NULL);
  Status = Private->Hii->NewString (Private->Hii, Lang, Private->RegisteredHandle, &NewStringToken, NewString);
  ASSERT_EFI_ERROR (Status); 
  gBS->FreePool (NewString);
  
  NewStringToken = (STRING_REF) STR_FIRST_REFRESH_HELP;
  NewString = GetString (Private, (STRING_REF) STR_REFRESH_HELP);
  ASSERT (NewString != NULL);
  Status = Private->Hii->NewString (Private->Hii, Lang, Private->RegisteredHandle, &NewStringToken, NewString);
  ASSERT_EFI_ERROR (Status); 
  gBS->FreePool (NewString); 

  //
  // Get all drivers handles which has configuration protocol
  //
  DriverImageHandleCount  = 0;
  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiDriverConfigurationProtocolGuid,
                  NULL,
                  &DriverImageHandleCount,
                  &DriverImageHandleBuffer
                  );       

  //
  // Scan every driver image handle to get its and its managed device and child device info, 
  // including Component name/image name/device handle and so on. Create and associate a item
  // in Set Option page to very driver and its managed device and  child device
  //
  ChoiceIndex = 0; // Item index in Set Option page 
  for (Index = 0; (Index < DriverImageHandleCount) && (ChoiceIndex < MAX_CHOICE_NUM); Index++) {
    //
    // step1 : get the driver info
    //
    DriverConfiguration = NULL;
    Status = gBS->OpenProtocol (
                    DriverImageHandleBuffer[Index],
                    &gEfiDriverConfigurationProtocolGuid,
                    (VOID **) &DriverConfiguration,
                    NULL,
                    NULL,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    ASSERT_EFI_ERROR (Status);
    
    DriverBinding =NULL;
    Status = gBS->OpenProtocol (
                    DriverImageHandleBuffer[Index],
                    &gEfiDriverBindingProtocolGuid,
                    (VOID **) &DriverBinding,
                    NULL,
                    NULL,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      continue;
    } 

    LoadedImage = NULL;
    Status = gBS->OpenProtocol (
                    DriverBinding->ImageHandle,
                    &gEfiLoadedImageProtocolGuid,
                    (VOID **) &LoadedImage,
                    NULL,
                    NULL,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      LoadedImage = NULL;
    }

    ComponentName  = NULL;
    Status = gBS->OpenProtocol (
                    DriverBinding->ImageHandle,
#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
                    &gEfiComponentName2ProtocolGuid,
#else
                    &gEfiComponentNameProtocolGuid,
#endif
                    (VOID **) &ComponentName,
                    NULL,
                    NULL,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR(Status)) {
      return EFI_UNSUPPORTED;
    }

    //
    // Get the driver name
    // First try to get its component name, if fail, get its image name then 
    //
    Status = EFI_UNSUPPORTED;
    DriverName = NULL;
    FreeDriverName = FALSE;
    if ((ComponentName != NULL) && (ComponentName->GetDriverName != NULL)) {
      Status = ComponentName->GetDriverName (
                                ComponentName,
                                Language,
                                &DriverName
                                );
    }
    if (EFI_ERROR (Status) && (LoadedImage != NULL)) {
      DriverName = GetImageName (LoadedImage);
    }
    if (DriverName == NULL) {
      DriverName = GetString (Private, (STRING_REF) STR_DRIVER_DEFAULT_NAME);
      ASSERT (DriverName != NULL);
      FreeDriverName = TRUE;  // the DriverName string need to free pool
    }
    //
    // Create a item for the driver in set options page
    // Clear the Update buffer 
    //
    UpdateData->FormSetUpdate       = FALSE;
    UpdateData->FormCallbackHandle  = 0;
    UpdateData->FormUpdate          = FALSE;
    UpdateData->FormTitle           = 0;
    UpdateData->DataCount           = 0;
    Location = (UINT8 *) &UpdateData->Data;
    //
    // Export the driver name string and create item in set options page
    //
    NewString = EfiLibAllocateZeroPool (EfiStrSize (DriverName) + EfiStrSize (L" |-"));
    EfiStrCat (NewString, L" |-");
    EfiStrCat (NewString, DriverName);
    NewStringToken = mChoice[ChoiceIndex].DescriptionToken;
    Status = Private->Hii->NewString (Private->Hii, NULL, Private->RegisteredHandle, &NewStringToken, NewString);
    ASSERT_EFI_ERROR (Status);
    gBS->FreePool (NewString); 
    if (FreeDriverName) {
      gBS->FreePool (DriverName);
    }
    
    CreateGotoOpCode (
      0x1234,                       
      NewStringToken,               // Description String Token
      STR_GOTO_HELP_DRIVER,         // Description Help String Token
      EFI_IFR_FLAG_INTERACTIVE,     // Flag designating callback is active
      (UINT16) ChoiceIndex + 0x100, // Callback key value
      Location                      // Buffer to fill with op-code
      );
    //
    // Update the buffer items number and adjust next item address to new one
    //
    UpdateData->DataCount +=1 ;
    Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;
    //
    // Associate callback key with  setoptions function related parameters to used by Task 1
    //
    mChoice[ChoiceIndex].DriverImageHandle = DriverImageHandleBuffer[Index];
    mChoice[ChoiceIndex].DriverConfiguration = DriverConfiguration;
    mChoice[ChoiceIndex].ControllerHandle = NULL;
    mChoice[ChoiceIndex].ChildControllerHandle = NULL;
    mChoice[ChoiceIndex].DescriptionToken = NewStringToken;
    ChoiceIndex++;    
    
    //
    // step2 : get the driver direct managed device info
    //
    
    //
    // Get the driver all direct managed devices handles
    //
    Status = GetDeviceHandlesManagedByDriver (
              DriverImageHandleBuffer[Index],
              &ControllerHandleCount,           // Get managed devices count
              &ControllerHandleBuffer           // return all handles in buffer
              );
    if (ControllerHandleBuffer == NULL) {
      continue;
    }
    
    for (ControllerHandleIndex = 0; ControllerHandleIndex < ControllerHandleCount; ControllerHandleIndex++) {
      //
      // Get the  managed device name
      // First try to get its component name, if fail, get its device path then 
      // The component name string need not free pool, but the device path string and default string need safe free pool after export the string to Hii database
      //
      FreeControllerHandleName = FALSE;
      ControllerHandleName = NULL;
      Status = EFI_UNSUPPORTED;
      if ((ComponentName != NULL) && (ComponentName->GetControllerName != NULL)) {
        Status = ComponentName->GetControllerName (
                                  ComponentName,
                                  ControllerHandleBuffer[ControllerHandleIndex],
                                  NULL,
                                  Language,
                                  &ControllerHandleName
                                  );
      }
      if (EFI_ERROR (Status)) {
        Status = gBS->OpenProtocol (
                        ControllerHandleBuffer[ControllerHandleIndex],
                        &gEfiDevicePathProtocolGuid,
                        (VOID **) &DevicePath,
                        NULL,
                        NULL,
                        EFI_OPEN_PROTOCOL_GET_PROTOCOL
                        );
        if (!EFI_ERROR (Status)) {
          ControllerHandleName = DevicePathToStr ( DevicePath );
          FreeControllerHandleName = TRUE; // the Controller Handle Name string need to free pool
        }
      }
      if (ControllerHandleName == NULL) {
        ControllerHandleName = GetString (Private, (STRING_REF) STR_DRIVER_CONTROLLER_DEFAULT_NAME);
        ASSERT (ControllerHandleName != NULL);
        FreeControllerHandleName = TRUE;  // the Controller Handle Name string need to free pool
      }
      //
      // do some alignment for NewString if needed
      //
      AlignmentItem (ControllerHandleName, L"   |-", &NewString);
      
      NewStringToken = mChoice[ChoiceIndex].DescriptionToken;
      Private->Hii->NewString (
                          Private->Hii,
                          NULL, 
                          Private->RegisteredHandle, 
                          &NewStringToken, 
                          NewString
                          );
      gBS->FreePool (NewString); 
      if (FreeControllerHandleName) {
        gBS->FreePool (ControllerHandleName);      
      }
      
      CreateGotoOpCode (
        0x1234,                 
        NewStringToken,                     // Description String Token
        STR_GOTO_HELP_DEVICE,               // Description Help String Token
        EFI_IFR_FLAG_INTERACTIVE,           // Flag designating callback is active
        (UINT16) ChoiceIndex + 0x100,       // Callback key value
        Location                            // Buffer to fill with op-code
        );
      //
      // Update the buffer items number and adjust next item address to new one
      //
      UpdateData->DataCount +=1 ;
      Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;
      //
      // Associate callback key with  setoptions function related parameters to used by Task 1
      //
      mChoice[ChoiceIndex].DriverImageHandle = DriverImageHandleBuffer[Index];
      mChoice[ChoiceIndex].DriverConfiguration = DriverConfiguration;
      mChoice[ChoiceIndex].ControllerHandle = ControllerHandleBuffer[ControllerHandleIndex];
      mChoice[ChoiceIndex].ChildControllerHandle = NULL;
      mChoice[ChoiceIndex].DescriptionToken = NewStringToken;
      ChoiceIndex++;
      
      //
      // step3 : get the infos of child devices created by the driver
      //
      Status = GetChildDeviceHandlesManagedByDriver (
                DriverImageHandleBuffer[Index],
                ControllerHandleBuffer[ControllerHandleIndex],
                &ChildControllerHandleCount,      // Get managed devices count
                &ChildControllerHandleBuffer      // return all handles in buffer
                );

      for (ChildControllerHandleIndex = 0; ChildControllerHandleIndex < ChildControllerHandleCount; ChildControllerHandleIndex++) {
        //
        // Get the  managed child device name
        // First try to get its component name, if fail, get its device path then 
        // The component name string need not free pool, but the device path string  need safe free pool after export the string to Hii database
        //
        FreeChildControllerHandleName = FALSE;
        ChildControllerHandleName = NULL;
        Status = EFI_UNSUPPORTED;
        if ((ComponentName != NULL) && (ComponentName->GetDriverName != NULL)) {
          Status = ComponentName->GetControllerName (
                                    ComponentName,
                                    ControllerHandleBuffer[ControllerHandleIndex],
                                    ChildControllerHandleBuffer[ChildControllerHandleIndex],
                                    Language,
                                    &ChildControllerHandleName
                                    );
        }
        if (EFI_ERROR (Status)) {
          Status = gBS->OpenProtocol (
                          ChildControllerHandleBuffer[ChildControllerHandleIndex],
                          &gEfiDevicePathProtocolGuid,
                          (VOID **) &DevicePath,
                          NULL,
                          NULL,
                          EFI_OPEN_PROTOCOL_GET_PROTOCOL
                          );
          if (!EFI_ERROR (Status)) {
            ChildControllerHandleName = DevicePathToStr ( DevicePath );
            FreeChildControllerHandleName = TRUE; // the Child Controller Handle Name string need to free pool
          }
        } 
        if (ChildControllerHandleName == NULL) {
          ChildControllerHandleName = GetString (Private, (STRING_REF) STR_DRIVER_CHILD_CONTROLLER_DEFAULT_NAME);
          ASSERT (ChildControllerHandleName != NULL);
          FreeChildControllerHandleName = TRUE;  // the Controller Handle Name string need to free pool
        }

        //
        // do some alignment for NewString if needed
        //
        AlignmentItem (ChildControllerHandleName, L"     |--", &NewString);
        
        NewStringToken = mChoice[ChoiceIndex].DescriptionToken;
        Private->Hii->NewString ( 
                            Private->Hii,
                            NULL, 
                            Private->RegisteredHandle, 
                            &NewStringToken, 
                            NewString
                            );
        gBS->FreePool (NewString); 
        if (FreeChildControllerHandleName) {
          gBS->FreePool (ChildControllerHandleName);      
        }
        CreateGotoOpCode (
          0x1234,                 
          NewStringToken,                          // Description String Token
          STR_GOTO_HELP_CHILD_DEVICE,              // Description Help String Token
          EFI_IFR_FLAG_INTERACTIVE,                // Flag designating callback is active
          (UINT16) ChoiceIndex + 0x100,            // Callback key value
          Location                                 // Buffer to fill with op-code
          );
        //
        // Update the buffer items number and adjust next item address to new one
        //
        UpdateData->DataCount +=1 ;
        Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;
        //
        // Associate callback key with  setoptions function related parameters to used by Task 1
        //
        mChoice[ChoiceIndex].DriverImageHandle = DriverImageHandleBuffer[Index];
        mChoice[ChoiceIndex].DriverConfiguration = DriverConfiguration;
        mChoice[ChoiceIndex].ControllerHandle = ControllerHandleBuffer[ControllerHandleIndex];
        mChoice[ChoiceIndex].ChildControllerHandle = ChildControllerHandleBuffer[ChildControllerHandleIndex];
        mChoice[ChoiceIndex].DescriptionToken = NewStringToken;
        ChoiceIndex++;
      }
      if (ChildControllerHandleBuffer != NULL) {
        gBS->FreePool (ChildControllerHandleBuffer);
      }
    }

    //
    // Update Set Option page form
    //
    Private->Hii->UpdateForm (
                    Private->Hii,
                    Private->RegisteredHandle,
                    (EFI_FORM_LABEL) 0x1234,
                    TRUE,
                    UpdateData
                    );    

    if (ControllerHandleBuffer != NULL) {
      gBS->FreePool (ControllerHandleBuffer);
    }
    
  }
  
  gBS->FreePool (UpdateData);  
  
  if (DriverImageHandleBuffer != NULL) {
    gBS->FreePool (DriverImageHandleBuffer);
  }

  return EFI_SUCCESS;
}
Ejemplo n.º 8
0
EFI_STATUS
EFIAPI
StslRecordAssertion (
  IN EFI_STANDARD_TEST_LIBRARY_PROTOCOL     *This,
  IN EFI_TEST_ASSERTION                     Type,
  IN EFI_GUID                               EventId,
  IN CHAR16                                 *Description,
  IN CHAR16                                 *Detail,
  ...
  )
/*++

Routine Description:

  Records the test result.

Arguments:

  This          - Standard test library protocol instance.
  Type          - Test result.
  EventId       - GUID for the checkpoint.
  Description   - Simple description for the checkpoint.
  Detail        - Format string for the detail test information.

Returns:

  EFI_SUCCESS           - record the assertion successfully.
  EFI_BAD_BUFFER_SIZE   - the Description string is too long.
  EFI_INVALID_PARAMETER - invalid Type.

--*/
{
  EFI_STATUS                      Status;
  VA_LIST                         Marker;
  CHAR16                          Buffer[EFI_MAX_PRINT_BUFFER];
  CHAR16                          AssertionType[10];
  STANDARD_TEST_PRIVATE_DATA      *Private;

  Private = STANDARD_TEST_PRIVATE_DATA_FROM_STSL (This);

  //
  // Check the parameter
  //
  if (EfiStrLen (Description) + 14 > EFI_MAX_PRINT_BUFFER) {
    return EFI_BAD_BUFFER_SIZE;
  }

  //
  // Write log file detail data
  //
  switch (Type) {
  case EFI_TEST_ASSERTION_PASSED:
    EfiStrCpy (AssertionType, L"PASS");
    Private->PassCount ++;
    break;
  case EFI_TEST_ASSERTION_WARNING:
    EfiStrCpy (AssertionType, L"WARNING");
    Private->WarningCount ++;
    break;
  case EFI_TEST_ASSERTION_FAILED:
    EfiStrCpy (AssertionType, L"FAILURE");
    Private->FailCount ++;
    break;
  default:
    return EFI_INVALID_PARAMETER;
    break;
  }

  SPrint (Buffer, EFI_MAX_PRINT_BUFFER, L"%s -- %s\n", Description, AssertionType);
  Status = StslWriteLogFile (Private, Buffer);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  SPrint (Buffer, EFI_MAX_PRINT_BUFFER, L"%g\n", &EventId);
  Status = StslWriteLogFile (Private, Buffer);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  VA_START(Marker, Detail);
  VSPrint (Buffer, EFI_MAX_PRINT_BUFFER, Detail, Marker);
  VA_END (Marker);

  if ( EfiStrLen (Buffer) + 5 < EFI_MAX_PRINT_BUFFER ) {
    EfiStrCat (Buffer, L"\r\n\r\n");
  }

  Status = StslWriteLogFile (Private, Buffer);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // write key file detail line
  //
  SPrint (Buffer, EFI_MAX_PRINT_BUFFER, L"%g:%s|%s:",
          &EventId, AssertionType, Description);
  Status = StslWriteKeyFile (Private, Buffer);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  VA_START(Marker, Detail);
  VSPrint (Buffer, EFI_MAX_PRINT_BUFFER, Detail, Marker);
  VA_END (Marker);

  if ( EfiStrLen (Buffer) + 3 < EFI_MAX_PRINT_BUFFER ) {
    EfiStrCat (Buffer, L"\r\n");
  }

  Status = StslWriteKeyFile (Private, Buffer);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return Status;
}
Ejemplo n.º 9
0
EFI_STATUS
EFIAPI
UpdateBindingDriverSelectPage (
    IN EFI_CALLBACK_INFO                *Private,
    IN UINT16                           KeyValue,
    IN EFI_IFR_DATA_ARRAY               *Data
)
/*++

Routine Description:
  Prepare to let user select the drivers which need mapping with the device controller selected in first page

Arguments:

  KeyValue - The callback key value of device controller item in first page
  Data -         EFI_IFR_DATA_ARRAY data.
  Packet-       No use here.

  Returns -    Always successful

--*/
{
    EFI_HII_UPDATE_DATA                       *UpdateData;
    EFI_STATUS                                Status;
    UINTN                                     Index;
    UINT8                                     *Location;

    CHAR16                                    *NewString;
    STRING_REF                                NewStringToken;
    STRING_REF                                NewStringHelpToken;
    UINTN                                     DriverImageHandleCount;

    EFI_DRIVER_BINDING_PROTOCOL               *DriverBindingInterface;
    EFI_LOADED_IMAGE_PROTOCOL                 *LoadedImage;
    CHAR16                                    *DriverName;
    BOOLEAN                                   FreeDriverName;

    EFI_DEVICE_PATH_PROTOCOL                  *LoadedImageHandleDevicePath;
    EFI_DEVICE_PATH_PROTOCOL                  *TatalFilePath;
    EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;
    EFI_HANDLE                                DriverBindingHandle;
    //
    // If user select a controller item in the first page  the following code will be run.
    // During second page, user will see all currnet driver bind protocol driver, the driver name and its device path will be shown
    //
    //First acquire the list of Loaded Image Protocols, and then when  want the name of the driver, look up all the Driver Binding Protocols
    // and find the first one whose ImageHandle field matches the image handle of the Loaded Image Protocol.
    // then use the Component Name Protocol on the same handle as the first matching Driver Binding Protocol to look up the name of the driver.
    //


    mCurrentPage = 0x02;
    //
    // Switch the item callback key value to its NO. in mDevicePathHandleBuffer
    //
    mSelectedCtrIndex = KeyValue - 0x100;
    ASSERT (0 <= mSelectedCtrIndex < MAX_CHOICE_NUM);
    mLastSavedDriverImageNum = 0;
    //
    // Clear all the content in dynamic page
    //
    UpdateData = NULL;
    UpdateData = EfiLibAllocateZeroPool (UPDATE_DATA_SIZE);
    ASSERT (UpdateData != NULL);

    UpdateData->FormSetUpdate       = FALSE;
    UpdateData->FormCallbackHandle  = 0;
    UpdateData->FormUpdate          = FALSE;
    UpdateData->FormTitle           = 0;
    UpdateData->DataCount           = 0xff;
    UpdateData->Data                = NULL;

    Private->Hii->UpdateForm (
        Private->Hii,
        Private->RegisteredHandle,
        (EFI_FORM_LABEL) 0x1200,  // Label 0x1234
        FALSE,                    // Remove Op-codes (will never remove form/endform)
        UpdateData                // Significant value is UpdateData->DataCount
    );

    //
    // Show all driver which support loaded image protocol in second page
    //
    DriverImageHandleCount  = 0;
    Status = gBS->LocateHandleBuffer (
                 ByProtocol,
                 &gEfiLoadedImageProtocolGuid,
                 NULL,
                 &DriverImageHandleCount,
                 &mDriverImageHandleBuffer
             );
    if (EFI_ERROR (Status) || (DriverImageHandleCount == 0)) {
        return EFI_NOT_FOUND;
    }

    mDriverImageHandleCount = DriverImageHandleCount;
    for (Index = 0; Index < DriverImageHandleCount; Index++) {
        //
        // Step1: Get the driver image total file path for help string and the driver name.
        //

        //
        // Find driver's Loaded Image protocol
        //
        LoadedImage =NULL;
        Status = gBS->OpenProtocol (
                     mDriverImageHandleBuffer[Index],
                     &gEfiLoadedImageProtocolGuid,
                     (VOID **) &LoadedImage,
                     NULL,
                     NULL,
                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
                 );
        if (EFI_ERROR (Status)) {
            ((MyIfrNVData *) Data->NvRamMap)->DriSelection[Index] = 0;
            continue;
        }
        mDriverImageProtocol[Index] = LoadedImage;
        //
        // Find its related driver binding protocol
        //
        DriverBindingInterface = NULL;
        DriverBindingHandle = NULL;
        DriverBindingInterface = LibGetBindingProtocolFromImageHandle (
                                     mDriverImageHandleBuffer[Index],
                                     &DriverBindingHandle
                                 );
        if (DriverBindingInterface == NULL) {
            ((MyIfrNVData *) Data->NvRamMap)->DriSelection[Index] = 0;
            continue;
        }

        //
        // Get the driver image total file path for help string
        //
        LoadedImageHandleDevicePath = NULL;
        Status = gBS->HandleProtocol (
                     LoadedImage->DeviceHandle,
                     &gEfiDevicePathProtocolGuid,
                     &LoadedImageHandleDevicePath
                 );
        if (EFI_ERROR (Status)) {
            ((MyIfrNVData *) Data->NvRamMap)->DriSelection[Index] = 0;
            continue;
        }

        if (((MyIfrNVData *) Data->NvRamMap)->PciDeviceFilter == 0x01) {
            //
            // only care the driver which is in a Pci device option rom,
            // and the driver's LoadedImage->DeviceHandle must point to a pci device which has efi option rom
            //
            if (!EFI_ERROR (Status)) {
                Status = gBS->HandleProtocol(
                             LoadedImage->DeviceHandle,
                             &gEfiBusSpecificDriverOverrideProtocolGuid,
                             &BusSpecificDriverOverride
                         );
                if (EFI_ERROR (Status) || BusSpecificDriverOverride == NULL) {
                    ((MyIfrNVData *) Data->NvRamMap)->DriSelection[Index] = 0;
                    continue;
                }
            } else {
                ((MyIfrNVData *) Data->NvRamMap)->DriSelection[Index] = 0;
                continue;
            }
        }

        TatalFilePath = NULL;
        TatalFilePath = EfiAppendDevicePath (LoadedImageHandleDevicePath, LoadedImage->FilePath);

        //
        // For driver name, try to get its component name, if fail, get its image name,
        // if also fail, give a default name.
        //
        FreeDriverName = FALSE;
        DriverName = GetComponentName (DriverBindingHandle);
        if (DriverName == NULL) {
            //
            // get its image name
            //
            DriverName = GetImageName (LoadedImage);
        }
        if (DriverName == NULL) {
            //
            // give a default name
            //
            DriverName = GetString (Private, (STRING_REF) STR_DRIVER_DEFAULT_NAME);
            ASSERT (DriverName != NULL);
            FreeDriverName = TRUE;  // the DriverName string need to free pool
        }


        //
        // Step2 Export the driver name string and create check box item in second page
        //

        //
        // Clear the Update buffer
        //
        UpdateData->FormSetUpdate       = FALSE;
        UpdateData->FormCallbackHandle  = 0;
        UpdateData->FormUpdate          = FALSE;
        UpdateData->FormTitle           = 0;
        UpdateData->DataCount           = 0;
        Location = (UINT8 *) &UpdateData->Data;
        //
        // First create the driver image name
        //
        NewString = EfiLibAllocateZeroPool (EfiStrSize (DriverName));
        if (EFI_ERROR (LibCheckMapping (mControllerDevicePathProtocol[mSelectedCtrIndex], TatalFilePath, &mMappingDataBase, NULL, NULL))) {
            ((MyIfrNVData *) Data->NvRamMap)->DriSelection[Index] = 0x00;
        } else {
            ((MyIfrNVData *) Data->NvRamMap)->DriSelection[Index] = 0x01;
            mLastSavedDriverImageNum++;
        }
        EfiStrCat (NewString, DriverName);
        NewStringToken = mDriverImageToken[Index];
        Status = Private->Hii->NewString (Private->Hii, NULL, Private->RegisteredHandle, &NewStringToken, NewString);
        mDriverImageToken[Index] = NewStringToken;
        ASSERT_EFI_ERROR (Status);
        gBS->FreePool (NewString);
        if (FreeDriverName) {
            gBS->FreePool (DriverName);
        }

        //
        // Second create the driver image device path as item help string
        //
        if (TatalFilePath == NULL) {
            DriverName = EfiLibAllocateZeroPool (EfiStrSize (L"This driver device path and file path are both NULL! Maybe it is a Option Rom driver. Can not save it!"));
            EfiStrCat (DriverName, L"This driver device path and file path are both NULL! Maybe it is a Option Rom driver. Can not save it!");
        } else {
            DriverName = DevicePathToStr (TatalFilePath);
        }
        NewString = EfiLibAllocateZeroPool (EfiStrSize (DriverName));
        EfiStrCat (NewString, DriverName);
        NewStringHelpToken = mDriverImageFilePathToken[Index];
        Status = Private->Hii->NewString (Private->Hii, NULL, Private->RegisteredHandle, &NewStringHelpToken, NewString);
        mDriverImageFilePathToken[Index] = NewStringHelpToken;
        ASSERT_EFI_ERROR (Status);
        gBS->FreePool (NewString);
        gBS->FreePool (DriverName);

        CreateCheckBoxOpCode (
            (UINT16) (DRIVER_SELECTION_QUESTION_ID + Index),
            (UINT8) 1,
            NewStringToken,                               // Description String Token
            NewStringHelpToken,                           // Description Help String Token
            EFI_IFR_FLAG_INTERACTIVE,                     // Flag designating callback is active
            (UINT16) Index + 0x500,                       // Callback key value
            Location                                      // Buffer to fill with op-code
        );

        UpdateData->DataCount +=1 ;
        Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

        //
        // Update second page form
        //
        Private->Hii->UpdateForm (
            Private->Hii,
            Private->RegisteredHandle,
            (EFI_FORM_LABEL) 0x1200,
            TRUE,
            UpdateData
        );
    }
    gBS->FreePool (UpdateData);
    return EFI_SUCCESS;
}
Ejemplo n.º 10
0
EFI_STATUS
EFIAPI
UpdateDeviceSelectPage (
    IN EFI_CALLBACK_INFO                *Private,
    IN UINT16                           KeyValue,
    IN EFI_IFR_DATA_ARRAY               *Data
)
/*++

Routine Description:
  Prepare the first page to let user select the device controller which need to add mapping drivers

Arguments:

  KeyValue -  No use here.
  Data -         EFI_IFR_DATA_ARRAY data.
  Packet-       No use here.

  Returns -    Always successful

--*/
{
    EFI_HII_UPDATE_DATA                       *UpdateData;
    EFI_STATUS                                Status;
    UINTN                                     LangSize;
    UINTN                                     Index;
    UINT8                                     *Location;
    UINTN                                     DevicePathHandleCount;

    CHAR16                                    *NewString;
    STRING_REF                                NewStringToken;
    CHAR16                                    *ControllerName;
    EFI_DEVICE_PATH_PROTOCOL                  *ControllerDevicePath;
    EFI_PCI_IO_PROTOCOL                       *PciIo;
    EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;

    mCurrentPage = 0x01;
    //
    // Following code will be run if user select 'Refresh' in first page
    // During first page, user will see all currnet controller device path in system,
    // select any device path will go to second page to select its overrides drivers
    //

    LangSize = 0x3;
    Status = gRT->GetVariable (
                 L"Lang",
                 &gEfiGlobalVariableGuid,
                 NULL,
                 &LangSize,
                 mLanguage
             );
    ASSERT_EFI_ERROR (Status);

    Status = GetCurrentLanguage (mLang);
    ASSERT_EFI_ERROR (Status);
    //
    // Initial the mapping database in memory
    //
    LibFreeMappingDatabase (&mMappingDataBase);
    Status = LibInitOverridesMapping (&mMappingDataBase);

    //
    // Clear all the content in the first page
    //
    UpdateData = NULL;
    UpdateData = EfiLibAllocateZeroPool (UPDATE_DATA_SIZE);
    ASSERT (UpdateData != NULL);

    UpdateData->FormSetUpdate       = FALSE;
    UpdateData->FormCallbackHandle  = 0;
    UpdateData->FormUpdate          = FALSE;
    UpdateData->FormTitle           = 0;
    UpdateData->DataCount           = 0xff;
    UpdateData->Data                = NULL;

    Private->Hii->UpdateForm (
        Private->Hii,
        Private->RegisteredHandle,
        (EFI_FORM_LABEL) 0x1234,  // Label 0x1234
        FALSE,                    // Remove Op-codes (will never remove form/endform)
        UpdateData                // Significant value is UpdateData->DataCount
    );
    //
    // When user enter the page at first time, the 'first refresh' string is given to notify user to refresh all the drivers,
    // then the 'first refresh' string will be replaced by the 'refresh' string, and the two strings content are  same after the replacement
    //
    NewStringToken = (STRING_REF) STR_FIRST_REFRESH;
    NewString = GetString (Private, (STRING_REF) STR_REFRESH);
    ASSERT (NewString != NULL);
    Status = Private->Hii->NewString (Private->Hii, mLang, Private->RegisteredHandle, &NewStringToken, NewString);
    ASSERT_EFI_ERROR (Status);
    gBS->FreePool (NewString);

    NewStringToken = (STRING_REF) STR_FIRST_REFRESH_HELP;
    NewString = GetString (Private, (STRING_REF) STR_REFRESH_HELP);
    ASSERT (NewString != NULL);
    Status = Private->Hii->NewString (Private->Hii, mLang, Private->RegisteredHandle, &NewStringToken, NewString);
    ASSERT_EFI_ERROR (Status);
    gBS->FreePool (NewString);
    //
    // created needed controller device item in first page
    //
    DevicePathHandleCount  = 0;
    Status = gBS->LocateHandleBuffer (
                 ByProtocol,
                 &gEfiDevicePathProtocolGuid,
                 NULL,
                 &DevicePathHandleCount,
                 &mDevicePathHandleBuffer
             );
    if (EFI_ERROR (Status) || (DevicePathHandleCount == 0)) {
        return EFI_SUCCESS;
    }

    for (Index = 0; Index < DevicePathHandleCount; Index++) {
        if (((MyIfrNVData *) Data->NvRamMap)->PciDeviceFilter == 0x01) {
            //
            // Only care PCI device which contain efi driver in its option rom.
            //

            //
            // Check whether it is a pci device
            //
            ControllerDevicePath = NULL;
            Status = gBS->OpenProtocol (
                         mDevicePathHandleBuffer[Index],
                         &gEfiPciIoProtocolGuid,
                         (VOID **) &PciIo,
                         NULL,
                         NULL,
                         EFI_OPEN_PROTOCOL_GET_PROTOCOL
                     );
            if (EFI_ERROR (Status)) {
                continue;
            }
            //
            // Check whether it contain efi driver in its option rom
            //
            Status = gBS->HandleProtocol(
                         mDevicePathHandleBuffer[Index],
                         &gEfiBusSpecificDriverOverrideProtocolGuid,
                         &BusSpecificDriverOverride
                     );
            if (EFI_ERROR (Status) || BusSpecificDriverOverride == NULL) {
                continue;
            }
        }

        ControllerDevicePath = NULL;
        Status = gBS->OpenProtocol (
                     mDevicePathHandleBuffer[Index],
                     &gEfiDevicePathProtocolGuid,
                     (VOID **) &ControllerDevicePath,
                     NULL,
                     NULL,
                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
                 );
        ASSERT_EFI_ERROR (Status);
        //
        // Save the device path protocol interface
        //
        mControllerDevicePathProtocol[Index] = ControllerDevicePath;

        //
        // Get the driver name
        //
        ControllerName = DevicePathToStr (ControllerDevicePath);

        //
        // Create a item for the driver in set options page
        // Clear the Update buffer
        //
        UpdateData->FormSetUpdate       = FALSE;
        UpdateData->FormCallbackHandle  = 0;
        UpdateData->FormUpdate          = FALSE;
        UpdateData->FormTitle           = 0;
        UpdateData->DataCount           = 0;
        Location = (UINT8 *) &UpdateData->Data;
        //
        // Export the driver name string and create item in set options page
        //
        NewString = EfiLibAllocateZeroPool (EfiStrSize (ControllerName) + EfiStrSize (L"--"));
        if (EFI_ERROR (LibCheckMapping (ControllerDevicePath,NULL, &mMappingDataBase, NULL, NULL))) {
            EfiStrCat (NewString, L"--");
        } else {
            EfiStrCat (NewString, L"**");
        }
        EfiStrCat (NewString, ControllerName);

        NewStringToken = mControllerToken[Index];
        Status = Private->Hii->NewString (Private->Hii, NULL, Private->RegisteredHandle, &NewStringToken, NewString);
        ASSERT_EFI_ERROR (Status);
        gBS->FreePool (NewString);
        //
        // Save the device path string toke for next access use
        //
        mControllerToken[Index] = NewStringToken;

        CreateGotoOpCode (
            0x1200,
            NewStringToken,               // Description String Token
            STR_GOTO_HELP_DRIVER,         // Description Help String Token
            EFI_IFR_FLAG_INTERACTIVE,     // Flag designating callback is active
            (UINT16) Index + 0x100, // Callback key value
            Location                      // Buffer to fill with op-code
        );
        //
        // Update the buffer items number and adjust next item address to new one
        //
        UpdateData->DataCount +=1 ;
        Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;
        //
        // Update first page form
        //
        Private->Hii->UpdateForm (
            Private->Hii,
            Private->RegisteredHandle,
            (EFI_FORM_LABEL) 0x1234,
            TRUE,
            UpdateData
        );

    }

    gBS->FreePool (UpdateData);
    return EFI_SUCCESS;
}
Ejemplo n.º 11
0
EFI_STATUS
IfrCatenate (
  IN FORM_BROWSER_FORMSET  *FormSet,
  OUT  EFI_HII_VALUE       *Result
  )
/*++

Routine Description:
  Evaluate opcode EFI_IFR_CATENATE.

Arguments:
  FormSet     - Formset which contains this opcode.
  Result      - Evaluation result for this opcode.

Returns:
  EFI_SUCCESS - Opcode evaluation success.
  Other       - Opcode evaluation failed.

--*/
{
  EFI_STATUS     Status;
  EFI_HII_VALUE  Value;
  CHAR16         *String[2];
  UINTN          Index;
  CHAR16         *StringPtr;

  //
  // String[0] - The second string
  // String[1] - The first string
  //
  String[0] = NULL;
  String[1] = NULL;
  StringPtr = NULL;
  Status = EFI_SUCCESS;

  for (Index = 0; Index < 2; Index++) {
    Status = PopExpression (&Value);
    if (EFI_ERROR (Status)) {
      goto Done;
    }

    if (Value.Type != EFI_IFR_TYPE_STRING) {
      Status = EFI_UNSUPPORTED;
      goto Done;
    }

    String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);
    if (String== NULL) {
      Status = EFI_NOT_FOUND;
      goto Done;
    }
  }

  StringPtr= EfiLibAllocatePool (EfiStrSize (String[1]) + EfiStrSize (String[0]));
  ASSERT (StringPtr != NULL);
  EfiStrCpy (StringPtr, String[1]);
  EfiStrCat (StringPtr, String[0]);

  Result->Type = EFI_IFR_TYPE_STRING;
  Result->Value.string = NewString (StringPtr, FormSet->HiiHandle);

Done:
  EfiLibSafeFreePool (String[0]);
  EfiLibSafeFreePool (String[1]);
  EfiLibSafeFreePool (StringPtr);

  return Status;
}
Ejemplo n.º 12
0
VOID
UpdateConModePage (
  IN BMM_CALLBACK_DATA                *CallbackData
  )
/*++

Routine Description:
  Refresh the text mode page

Arguments:
  CallbackData      - BMM_CALLBACK_DATA

Returns:
  None.

--*/
{
  UINTN                         Mode;
  UINTN                         Index;
  UINTN                         Col;
  UINTN                         Row;
  CHAR16                        RowString[50];
  CHAR16                        ModeString[50];
  UINTN                         MaxMode;
  UINTN                         ValidMode;
  EFI_STRING_ID                 *ModeToken;
  IFR_OPTION                    *IfrOptionList;
  EFI_STATUS                    Status;
  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *ConOut;

  ConOut    = gST->ConOut;
  Index     = 0;
  ValidMode = 0;
  MaxMode   = (UINTN) (ConOut->Mode->MaxMode);

  CallbackData->BmmAskSaveOrNot = TRUE;

  UpdatePageStart (CallbackData);

  //
  // Check valid mode
  //
  for (Mode = 0; Mode < MaxMode; Mode++) {
    Status = ConOut->QueryMode (ConOut, Mode, &Col, &Row);
    if (EFI_ERROR (Status)) {
      continue;
    }
    ValidMode++;
  }

  if (ValidMode == 0) {
    return;
  }

  IfrOptionList       = EfiAllocateZeroPool (sizeof (IFR_OPTION) * ValidMode);
  ASSERT(IfrOptionList != NULL);

  ModeToken           = EfiAllocateZeroPool (sizeof (EFI_STRING_ID) * ValidMode);
  ASSERT(ModeToken != NULL);

  //
  // Determin which mode should be the first entry in menu
  //
  GetConsoleOutMode (CallbackData);

  //
  // Build text mode options
  //
  for (Mode = 0; Mode < MaxMode; Mode++) {
    Status = ConOut->QueryMode (ConOut, Mode, &Col, &Row);
    if (EFI_ERROR (Status)) {
      continue;
    }
    //
    // Build mode string Column x Row
    //
    EfiValueToString (ModeString, Col, 0, 0);
    EfiStrCat (ModeString, L" x ");
    EfiValueToString (RowString, Row, 0, 0);
    EfiStrCat (ModeString, RowString);

    IfrLibNewString (CallbackData->BmmHiiHandle, &ModeToken[Index], ModeString);

    IfrOptionList[Index].StringToken  = ModeToken[Index];
    IfrOptionList[Index].Value.u16    = (UINT16) Mode;
    if (Mode == CallbackData->BmmFakeNvData.ConsoleOutMode) {
      IfrOptionList[Index].Flags      = EFI_IFR_OPTION_DEFAULT;
    } else {
      IfrOptionList[Index].Flags      = 0;
    }
    Index++;
  }

  CreateOneOfOpCode (
    CON_MODE_QUESTION_ID,
    VARSTORE_ID_BOOT_MAINT,
    CON_MODE_VAR_OFFSET,
    STRING_TOKEN (STR_CON_MODE_SETUP),
    STRING_TOKEN (STR_CON_MODE_SETUP),
    EFI_IFR_FLAG_RESET_REQUIRED,
    EFI_IFR_NUMERIC_SIZE_2,
    IfrOptionList,
    ValidMode,
    &gUpdateData
    );
  SafeFreePool (IfrOptionList);
  SafeFreePool (ModeToken);

  UpdatePageEnd (CallbackData);
}
Ejemplo n.º 13
0
VOID
AlignmentItem (
  IN        CHAR16   *ControllerHandleName,
  IN        CHAR16   *PrefixString,
  IN OUT    CHAR16   **NewString
  )
/*++

Routine Description:
  Do controller item string swap and alignment if needed. The alignment is the length of PrefixString.
  Because controller device path is too long sometime and cannot be presented in one line,
  and the browser automatic swap will break the necessary alignment, so do some additional
  process  for the problem.

Arguments:
 ControllerHandleName - a pointer to the controller real device path string
 PrefixString- a pointer to the prefix string
 NewString - a pointer to the string which will be presented by the browser

Returns:
  None

--*/
{

  CHAR16                                    *PadString;
  UINTN                                     PtrIndex;
  UINTN                                     IndexOffset;
  UINTN                                     Width;
  CHAR16                                    *NewStringSwapped;
  UINTN                                     SwapLineNum;
  UINTN                                     SwapLine;

  //
  // Register the device name string and create item in set options page
  //
  *NewString = EfiLibAllocateZeroPool (EfiStrSize (ControllerHandleName) + EfiStrSize (PrefixString));
  EfiStrCat (*NewString, PrefixString);
  EfiStrCat (*NewString, ControllerHandleName);
  //
  // Add pad chars into the string  for string swap in set options page to solve following two issue:
  // Issue1: Our form browser will do the string swap according to the spaces in the string, so
  //              if a string is too long and without space in it, the string position will be ugly.
  //              The driver need add some spaces to control the swap in the long and no space string.
  // Issue2:  If browser find a space to do swap, it will not show any other space directly followed it in swap position.
  //                So if you want to use the space to do the alignment in swapped new line, you need add another char(e.g '.')  in it.
  // e.g. if the item max lenth is 5, then the following string need add some space and '.' to get right presentation
  // '12345678901234567890' --------> '      12345 .    67890 .    12345 .    67890' , and presentation is below
  // |     12345
  // |.    67890
  // |.    12345
  // |.    67890
  //
  if ((EfiStrLen (*NewString)/SWAP_LENGTH > 0) && (EfiStrLen (PrefixString) > 0)) {
    //
    // Prepare the pad string according to the PrefixString length
    // the pad string is string of ' ', except of the NO2 charater which is '.'
    //
    PadString = EfiLibAllocateZeroPool (EfiStrSize (PrefixString) + 2);
    for (PtrIndex = 0; PtrIndex < (EfiStrLen (PrefixString) + 1); PtrIndex++) {
      PadString[PtrIndex] = ' ';
    }
    PadString[1] = '.';

    Width = SWAP_LENGTH - EfiStrLen (PrefixString);
    SwapLineNum = EfiStrLen (ControllerHandleName)/Width;

    NewStringSwapped = EfiLibAllocateZeroPool (EfiStrSize (ControllerHandleName) +
                       EfiStrSize (PrefixString) +
                       SwapLineNum * EfiStrSize (PadString));
    ASSERT (NewStringSwapped != NULL);

    IndexOffset = 0;
    EfiStrCpy (NewStringSwapped, PrefixString);
    IndexOffset += EfiStrLen (PrefixString);

    for (SwapLine = 0; SwapLine < SwapLineNum; SwapLine++) {
      EfiStrnCpy (&NewStringSwapped[IndexOffset],
                  &ControllerHandleName[SwapLine * Width],
                  Width
                 );
      IndexOffset += Width;

      EfiStrnCpy (&NewStringSwapped[IndexOffset],
                  PadString,
                  EfiStrLen (PadString)
                 );
      IndexOffset += EfiStrLen (PadString);
    }
    EfiStrCat (NewStringSwapped, &ControllerHandleName[SwapLine * Width]);
    gBS->FreePool (PadString);
    gBS->FreePool (*NewString);
    *NewString = NewStringSwapped;
  }
  return;
}