示例#1
0
/**
  Event handler registered with the Data Hub to parse EFI_DEBUG_CODE. This
  handler reads the Data Hub and sends any DEBUG info to StdErr.

  @param Event      The event that occured, not used
  @param Context    DataHub Protocol Pointer
**/
VOID
EFIAPI
DataHubStdErrEventHandler (
  IN EFI_EVENT Event,
  IN VOID      *Context
  )
{
  EFI_STATUS                           Status;
  EFI_DATA_HUB_PROTOCOL                *DataHub;
  EFI_DATA_RECORD_HEADER               *Record;
  DATA_HUB_STATUS_CODE_DATA_RECORD     *DataRecord;
  UINT64                               Mtc;
  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL      *Sto;
  INT32                                OldAttribute;

  DataHub = (EFI_DATA_HUB_PROTOCOL *) Context;

  //
  // If StdErr is not yet initialized just return a DEBUG print in the BDS
  // after consoles are connect will make sure data gets flushed properly
  // when StdErr is available.
  //
  if (gST == NULL) {
    return ;
  }

  if (gST->StdErr == NULL) {
    return ;
  }

  //
  // Mtc of zero means return the next record that has not been read by the
  // event handler.
  //
  Mtc = 0;
  do {
    Status = DataHub->GetNextRecord (DataHub, &Mtc, &mDataHubStdErrEvent, &Record);
    if (!EFI_ERROR (Status)) {
      if (CompareGuid (&Record->DataRecordGuid, &gEfiDataHubStatusCodeRecordGuid)) {
        DataRecord = (DATA_HUB_STATUS_CODE_DATA_RECORD *) (((CHAR8 *) Record) + Record->HeaderSize);

        if (DataRecord->Data.HeaderSize > 0) {
          if (CompareGuid (&DataRecord->Data.Type, &gEfiStatusCodeDataTypeDebugGuid)) {
            //
            // If the Data record is from a DEBUG () then send it to Standard Error
            //
            Sto           = gST->StdErr;
            OldAttribute  = Sto->Mode->Attribute;
            Sto->SetAttribute (Sto, EFI_TEXT_ATTR (EFI_MAGENTA, EFI_BLACK));
            Sto->OutputString (Sto, (CHAR16 *) (DataRecord + 1));
            Sto->SetAttribute (Sto, OldAttribute);
          }
        }
      }
    }
  } while ((Mtc != 0) && !EFI_ERROR (Status));
}
示例#2
0
/**
  Draws a dialog box to the console output device specified by
  ConOut defined in the EFI_SYSTEM_TABLE and waits for a keystroke
  from the console input device specified by ConIn defined in the
  EFI_SYSTEM_TABLE.

  If there are no strings in the variable argument list, then ASSERT().
  If all the strings in the variable argument list are empty, then ASSERT().

  @param[in]   Attribute  Specifies the foreground and background color of the popup.
  @param[out]  Key        A pointer to the EFI_KEY value of the key that was
                          pressed.  This is an optional parameter that may be NULL.
                          If it is NULL then no wait for a keypress will be performed.
  @param[in]  ...         The variable argument list that contains pointers to Null-
                          terminated Unicode strings to display in the dialog box.
                          The variable argument list is terminated by a NULL.

**/
VOID
EFIAPI
CreatePopUp (
  IN  UINTN          Attribute,
  OUT EFI_INPUT_KEY  *Key,      OPTIONAL
  ...
  )
{
  EFI_STATUS                       Status;
  VA_LIST                          Args;
  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *ConOut;
  EFI_SIMPLE_TEXT_OUTPUT_MODE      SavedConsoleMode;
  UINTN                            Columns;
  UINTN                            Rows;
  UINTN                            Column;
  UINTN                            Row;
  UINTN                            NumberOfLines;
  UINTN                            MaxLength;
  CHAR16                           *String;
  UINTN                            Length;
  CHAR16                           *Line;
  UINTN                            EventIndex;

  //
  // Determine the length of the longest line in the popup and the the total
  // number of lines in the popup
  //
  VA_START (Args, Key);
  MaxLength = 0;
  NumberOfLines = 0;
  while ((String = VA_ARG (Args, CHAR16 *)) != NULL) {
    MaxLength = MAX (MaxLength, StrLen (String));
    NumberOfLines++;
  }
  VA_END (Args);

  //
  // If the total number of lines in the popup is zero, then ASSERT()
  //
  ASSERT (NumberOfLines != 0);

  //
  // If the maximum length of all the strings is zero, then ASSERT()
  //
  ASSERT (MaxLength != 0);

  //
  // Cache a pointer to the Simple Text Output Protocol in the EFI System Table
  //
  ConOut = gST->ConOut;

  //
  // Save the current console cursor position and attributes
  //
  CopyMem (&SavedConsoleMode, ConOut->Mode, sizeof (SavedConsoleMode));

  //
  // Retrieve the number of columns and rows in the current console mode
  //
  ConOut->QueryMode (ConOut, SavedConsoleMode.Mode, &Columns, &Rows);

  //
  // Disable cursor and set the foreground and background colors specified by Attribute
  //
  ConOut->EnableCursor (ConOut, FALSE);
  ConOut->SetAttribute (ConOut, Attribute);

  //
  // Limit NumberOfLines to height of the screen minus 3 rows for the box itself
  //
  NumberOfLines = MIN (NumberOfLines, Rows - 3);

  //
  // Limit MaxLength to width of the screen minus 2 columns for the box itself
  //
  MaxLength = MIN (MaxLength, Columns - 2);

  //
  // Compute the starting row and starting column for the popup
  //
  Row    = (Rows - (NumberOfLines + 3)) / 2;
  Column = (Columns - (MaxLength + 2)) / 2;

  //
  // Allocate a buffer for a single line of the popup with borders and a Null-terminator
  //
  Line = AllocateZeroPool ((MaxLength + 3) * sizeof (CHAR16));
  ASSERT (Line != NULL);

  //
  // Draw top of popup box
  //
  SetMem16 (Line, (MaxLength + 2) * 2, BOXDRAW_HORIZONTAL);
  Line[0]             = BOXDRAW_DOWN_RIGHT;
  Line[MaxLength + 1] = BOXDRAW_DOWN_LEFT;
  Line[MaxLength + 2] = L'\0';
  ConOut->SetCursorPosition (ConOut, Column, Row++);
  ConOut->OutputString (ConOut, Line);

  //
  // Draw middle of the popup with strings
  //
  VA_START (Args, Key);
  while ((String = VA_ARG (Args, CHAR16 *)) != NULL && NumberOfLines > 0) {
    Length = StrLen (String);
    SetMem16 (Line, (MaxLength + 2) * 2, L' ');
    if (Length <= MaxLength) {
      //
      // Length <= MaxLength
      //
      CopyMem (Line + 1 + (MaxLength - Length) / 2, String , Length * sizeof (CHAR16));
    } else {
      //
      // Length > MaxLength
      //
      CopyMem (Line + 1, String + (Length - MaxLength) / 2 , MaxLength * sizeof (CHAR16));
    }
    Line[0]             = BOXDRAW_VERTICAL;
    Line[MaxLength + 1] = BOXDRAW_VERTICAL;
    Line[MaxLength + 2] = L'\0';
    ConOut->SetCursorPosition (ConOut, Column, Row++);
    ConOut->OutputString (ConOut, Line);
    NumberOfLines--;
  }
  VA_END (Args);

  //
  // Draw bottom of popup box
  //
  SetMem16 (Line, (MaxLength + 2) * 2, BOXDRAW_HORIZONTAL);
  Line[0]             = BOXDRAW_UP_RIGHT;
  Line[MaxLength + 1] = BOXDRAW_UP_LEFT;
  Line[MaxLength + 2] = L'\0';
  ConOut->SetCursorPosition (ConOut, Column, Row++);
  ConOut->OutputString (ConOut, Line);

  //
  // Free the allocated line buffer
  //
  FreePool (Line);

  //
  // Restore the cursor visibility, position, and attributes
  //
  ConOut->EnableCursor      (ConOut, SavedConsoleMode.CursorVisible);
  ConOut->SetCursorPosition (ConOut, SavedConsoleMode.CursorColumn, SavedConsoleMode.CursorRow);
  ConOut->SetAttribute      (ConOut, SavedConsoleMode.Attribute);

  //
  // Wait for a keystroke
  //
  if (Key != NULL) {
    while (TRUE) {
      Status = gST->ConIn->ReadKeyStroke (gST->ConIn, Key);
      if (!EFI_ERROR (Status)) {
        break;
      }

      //
      // If we encounter error, continue to read another key in.
      //
      if (Status != EFI_NOT_READY) {
        continue;
      }
      gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);
    }
  }
}
示例#3
0
/* Write a NULL terminated WCS to the EFI console.

  @param[in,out]  BufferSize  Number of bytes in Buffer.  Set to zero if
                              the string couldn't be displayed.
  @param[in]      Buffer      The WCS string to be displayed

  @return   The number of characters written.
*/
static
ssize_t
EFIAPI
da_ConWrite(
  IN  struct __filedes     *filp,
  IN  off_t                *Position,
  IN  size_t                BufferSize,
  IN  const void           *Buffer
  )
{
  EFI_STATUS                          Status;
  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL    *Proto;
  ConInstance                        *Stream;
  ssize_t                             NumChar;
  //XYoffset                            CursorPos;

  Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);
  // Quick check to see if Stream looks reasonable
  if(Stream->Cookie != CON_COOKIE) {    // Cookie == 'IoAb'
    EFIerrno = RETURN_INVALID_PARAMETER;
    return -1;    // Looks like a bad This pointer
  }
  if(Stream->InstanceNum == STDIN_FILENO) {
    // Write is not valid for stdin
    EFIerrno = RETURN_UNSUPPORTED;
    return -1;
  }
  // Everything is OK to do the write.
  Proto = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)Stream->Dev;

  // Convert string from MBCS to WCS and translate \n to \r\n.
  NumChar = WideTtyCvt(gMD->UString, (const char *)Buffer, BufferSize);
  //if(NumChar > 0) {
  //  BufferSize = (size_t)(NumChar * sizeof(CHAR16));
  //}
  BufferSize = NumChar;

  //if( Position != NULL) {
  //  CursorPos.Offset = (UINT64)*Position;

  //  Status = Proto->SetCursorPosition(Proto,
  //                                    (INTN)CursorPos.XYpos.Column,
  //                                    (INTN)CursorPos.XYpos.Row);
  //  if(RETURN_ERROR(Status)) {
  //    return -1;
  //  }
  //}

  // Send the Unicode buffer to the console
  Status = Proto->OutputString( Proto, gMD->UString);
  // Depending on status, update BufferSize and return
  if(RETURN_ERROR(Status)) {
    BufferSize = 0;    // We don't really know how many characters made it out
  }
  else {
    //BufferSize = NumChar;
    Stream->NumWritten += NumChar;
  }
  EFIerrno = Status;
  return BufferSize;
}