MdeModulePkg/EbcDxe: add EBC Debugger
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Pete Batard <pete@akeo.ie> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
This commit is contained in:
708
MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSupportUI.c
Normal file
708
MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSupportUI.c
Normal file
@ -0,0 +1,708 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2007, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
EdbSupportUI.c
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
--*/
|
||||
|
||||
#include "Edb.h"
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
SetCursorPosition (
|
||||
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut,
|
||||
IN UINTN Column,
|
||||
IN INTN Row,
|
||||
IN UINTN LineLength,
|
||||
IN UINTN TotalRow,
|
||||
IN CHAR16 *Str,
|
||||
IN UINTN StrPos,
|
||||
IN UINTN Len
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
WaitForSingleEvent (
|
||||
IN EFI_EVENT Event,
|
||||
IN UINT64 Timeout OPTIONAL
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Function waits for a given event to fire, or for an optional timeout to expire.
|
||||
|
||||
Arguments:
|
||||
Event - The event to wait for
|
||||
|
||||
Timeout - An optional timeout value in 100 ns units.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - Event fired before Timeout expired.
|
||||
EFI_TIME_OUT - Timout expired before Event fired..
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
EFI_EVENT TimerEvent;
|
||||
EFI_EVENT WaitList[2];
|
||||
|
||||
if (Timeout) {
|
||||
//
|
||||
// Create a timer event
|
||||
//
|
||||
Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// Set the timer event
|
||||
//
|
||||
gBS->SetTimer (
|
||||
TimerEvent,
|
||||
TimerRelative,
|
||||
Timeout
|
||||
);
|
||||
|
||||
//
|
||||
// Wait for the original event or the timer
|
||||
//
|
||||
WaitList[0] = Event;
|
||||
WaitList[1] = TimerEvent;
|
||||
Status = gBS->WaitForEvent (2, WaitList, &Index);
|
||||
gBS->CloseEvent (TimerEvent);
|
||||
|
||||
//
|
||||
// If the timer expired, change the return to timed out
|
||||
//
|
||||
if (!EFI_ERROR (Status) && Index == 1) {
|
||||
Status = EFI_TIMEOUT;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// No timeout... just wait on the event
|
||||
//
|
||||
Status = gBS->WaitForEvent (1, &Event, &Index);
|
||||
ASSERT (!EFI_ERROR (Status));
|
||||
ASSERT (Index == 0);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
ConMoveCursorBackward (
|
||||
IN UINTN LineLength,
|
||||
IN OUT UINTN *Column,
|
||||
IN OUT UINTN *Row
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Move the cursor position one character backward.
|
||||
|
||||
Arguments:
|
||||
LineLength Length of a line. Get it by calling QueryMode
|
||||
Column Current column of the cursor position
|
||||
Row Current row of the cursor position
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
ASSERT (Column != NULL);
|
||||
ASSERT (Row != NULL);
|
||||
//
|
||||
// If current column is 0, move to the last column of the previous line,
|
||||
// otherwise, just decrement column.
|
||||
//
|
||||
if (*Column == 0) {
|
||||
(*Column) = LineLength - 1;
|
||||
//
|
||||
// if (*Row > 0) {
|
||||
//
|
||||
(*Row)--;
|
||||
//
|
||||
// }
|
||||
//
|
||||
} else {
|
||||
(*Column)--;
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
ConMoveCursorForward (
|
||||
IN UINTN LineLength,
|
||||
IN UINTN TotalRow,
|
||||
IN OUT UINTN *Column,
|
||||
IN OUT UINTN *Row
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Move the cursor position one character backward.
|
||||
|
||||
Arguments:
|
||||
LineLength Length of a line. Get it by calling QueryMode
|
||||
TotalRow Total row of a screen, get by calling QueryMode
|
||||
Column Current column of the cursor position
|
||||
Row Current row of the cursor position
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
ASSERT (Column != NULL);
|
||||
ASSERT (Row != NULL);
|
||||
//
|
||||
// If current column is at line end, move to the first column of the nest
|
||||
// line, otherwise, just increment column.
|
||||
//
|
||||
(*Column)++;
|
||||
if (*Column >= LineLength) {
|
||||
(*Column) = 0;
|
||||
if ((*Row) < TotalRow - 1) {
|
||||
(*Row)++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CHAR16 mBackupSpace[EFI_DEBUG_INPUS_BUFFER_SIZE];
|
||||
CHAR16 mInputBufferHistory[EFI_DEBUG_INPUS_BUFFER_SIZE];
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
Input (
|
||||
IN CHAR16 *Prompt OPTIONAL,
|
||||
OUT CHAR16 *InStr,
|
||||
IN UINTN StrLength
|
||||
)
|
||||
{
|
||||
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;
|
||||
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn;
|
||||
BOOLEAN Done;
|
||||
UINTN Column;
|
||||
UINTN Row;
|
||||
UINTN StartColumn;
|
||||
UINTN Update;
|
||||
UINTN Delete;
|
||||
UINTN Len;
|
||||
UINTN StrPos;
|
||||
UINTN Index;
|
||||
UINTN LineLength;
|
||||
UINTN TotalRow;
|
||||
UINTN SkipLength;
|
||||
UINTN OutputLength;
|
||||
UINTN TailRow;
|
||||
UINTN TailColumn;
|
||||
EFI_INPUT_KEY Key;
|
||||
BOOLEAN InsertMode;
|
||||
BOOLEAN NeedAdjust;
|
||||
UINTN SubIndex;
|
||||
CHAR16 *CommandStr;
|
||||
|
||||
ConOut = gST->ConOut;
|
||||
ConIn = gST->ConIn;
|
||||
|
||||
ASSERT (ConOut != NULL);
|
||||
ASSERT (ConIn != NULL);
|
||||
ASSERT (InStr != NULL);
|
||||
|
||||
if (Prompt) {
|
||||
ConOut->OutputString (ConOut, Prompt);
|
||||
}
|
||||
//
|
||||
// Read a line from the console
|
||||
//
|
||||
Len = 0;
|
||||
StrPos = 0;
|
||||
OutputLength = 0;
|
||||
Update = 0;
|
||||
Delete = 0;
|
||||
InsertMode = TRUE;
|
||||
NeedAdjust = FALSE;
|
||||
|
||||
//
|
||||
// If buffer is not large enough to hold a CHAR16, do nothing.
|
||||
//
|
||||
if (StrLength < 1) {
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// Get the screen setting and the current cursor location
|
||||
//
|
||||
StartColumn = ConOut->Mode->CursorColumn;
|
||||
Column = StartColumn;
|
||||
Row = ConOut->Mode->CursorRow;
|
||||
ConOut->QueryMode (ConOut, ConOut->Mode->Mode, &LineLength, &TotalRow);
|
||||
if (LineLength == 0) {
|
||||
return ;
|
||||
}
|
||||
|
||||
SetMem (InStr, StrLength * sizeof (CHAR16), 0);
|
||||
Done = FALSE;
|
||||
do {
|
||||
//
|
||||
// Read a key
|
||||
//
|
||||
WaitForSingleEvent (ConIn->WaitForKey, 0);
|
||||
ConIn->ReadKeyStroke (ConIn, &Key);
|
||||
|
||||
switch (Key.UnicodeChar) {
|
||||
case CHAR_CARRIAGE_RETURN:
|
||||
//
|
||||
// All done, print a newline at the end of the string
|
||||
//
|
||||
TailRow = Row + (Len - StrPos + Column) / LineLength;
|
||||
TailColumn = (Len - StrPos + Column) % LineLength;
|
||||
Done = TRUE;
|
||||
break;
|
||||
|
||||
case CHAR_BACKSPACE:
|
||||
if (StrPos) {
|
||||
//
|
||||
// If not move back beyond string beginning, move all characters behind
|
||||
// the current position one character forward
|
||||
//
|
||||
StrPos -= 1;
|
||||
Update = StrPos;
|
||||
Delete = 1;
|
||||
CopyMem (InStr + StrPos, InStr + StrPos + 1, sizeof (CHAR16) * (Len - StrPos));
|
||||
|
||||
//
|
||||
// Adjust the current column and row
|
||||
//
|
||||
ConMoveCursorBackward (LineLength, &Column, &Row);
|
||||
|
||||
NeedAdjust = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Key.UnicodeChar >= ' ') {
|
||||
//
|
||||
// If we are at the buffer's end, drop the key
|
||||
//
|
||||
if (Len == StrLength - 1 && (InsertMode || StrPos == Len)) {
|
||||
break;
|
||||
}
|
||||
//
|
||||
// If in insert mode, move all characters behind the current position
|
||||
// one character backward to make space for this character. Then store
|
||||
// the character.
|
||||
//
|
||||
if (InsertMode) {
|
||||
for (Index = Len; Index > StrPos; Index -= 1) {
|
||||
InStr[Index] = InStr[Index - 1];
|
||||
}
|
||||
}
|
||||
|
||||
InStr[StrPos] = Key.UnicodeChar;
|
||||
Update = StrPos;
|
||||
|
||||
StrPos += 1;
|
||||
OutputLength = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0:
|
||||
switch (Key.ScanCode) {
|
||||
case SCAN_DELETE:
|
||||
//
|
||||
// Move characters behind current position one character forward
|
||||
//
|
||||
if (Len) {
|
||||
Update = StrPos;
|
||||
Delete = 1;
|
||||
CopyMem (InStr + StrPos, InStr + StrPos + 1, sizeof (CHAR16) * (Len - StrPos));
|
||||
|
||||
NeedAdjust = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case SCAN_LEFT:
|
||||
//
|
||||
// Adjust current cursor position
|
||||
//
|
||||
if (StrPos) {
|
||||
StrPos -= 1;
|
||||
ConMoveCursorBackward (LineLength, &Column, &Row);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCAN_RIGHT:
|
||||
//
|
||||
// Adjust current cursor position
|
||||
//
|
||||
if (StrPos < Len) {
|
||||
StrPos += 1;
|
||||
ConMoveCursorForward (LineLength, TotalRow, &Column, &Row);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCAN_HOME:
|
||||
//
|
||||
// Move current cursor position to the beginning of the command line
|
||||
//
|
||||
Row -= (StrPos + StartColumn) / LineLength;
|
||||
Column = StartColumn;
|
||||
StrPos = 0;
|
||||
break;
|
||||
|
||||
case SCAN_END:
|
||||
//
|
||||
// Move current cursor position to the end of the command line
|
||||
//
|
||||
TailRow = Row + (Len - StrPos + Column) / LineLength;
|
||||
TailColumn = (Len - StrPos + Column) % LineLength;
|
||||
Row = TailRow;
|
||||
Column = TailColumn;
|
||||
StrPos = Len;
|
||||
break;
|
||||
|
||||
case SCAN_ESC:
|
||||
//
|
||||
// Prepare to clear the current command line
|
||||
//
|
||||
InStr[0] = 0;
|
||||
Update = 0;
|
||||
Delete = Len;
|
||||
Row -= (StrPos + StartColumn) / LineLength;
|
||||
Column = StartColumn;
|
||||
OutputLength = 0;
|
||||
|
||||
NeedAdjust = TRUE;
|
||||
break;
|
||||
|
||||
case SCAN_INSERT:
|
||||
//
|
||||
// Toggle the SEnvInsertMode flag
|
||||
//
|
||||
InsertMode = (BOOLEAN)!InsertMode;
|
||||
break;
|
||||
|
||||
case SCAN_UP:
|
||||
case SCAN_DOWN:
|
||||
//
|
||||
// show history
|
||||
//
|
||||
CopyMem (InStr, mInputBufferHistory, StrLength * sizeof(CHAR16));
|
||||
StrPos = StrLen (mInputBufferHistory);
|
||||
Update = 0;
|
||||
Delete = 0;
|
||||
OutputLength = 0;
|
||||
|
||||
TailRow = Row + (StrPos + StartColumn) / LineLength;
|
||||
TailColumn = (StrPos + StartColumn) % LineLength;
|
||||
Row = TailRow;
|
||||
Column = TailColumn;
|
||||
NeedAdjust = FALSE;
|
||||
|
||||
ConOut->SetCursorPosition (ConOut, StartColumn, Row);
|
||||
for (SubIndex = 0; SubIndex < EFI_DEBUG_INPUS_BUFFER_SIZE - (StartColumn - EFI_DEBUG_PROMPT_COLUMN); SubIndex++) {
|
||||
mBackupSpace[SubIndex] = L' ';
|
||||
}
|
||||
EDBPrint (mBackupSpace);
|
||||
SetMem (mBackupSpace, (EFI_DEBUG_INPUS_BUFFER_SIZE - (StartColumn - EFI_DEBUG_PROMPT_COLUMN)) * sizeof(CHAR16), 0);
|
||||
|
||||
ConOut->SetCursorPosition (ConOut, StartColumn, Row);
|
||||
Len = StrPos;
|
||||
|
||||
break;
|
||||
|
||||
case SCAN_F1:
|
||||
case SCAN_F2:
|
||||
case SCAN_F3:
|
||||
case SCAN_F4:
|
||||
case SCAN_F5:
|
||||
case SCAN_F6:
|
||||
case SCAN_F7:
|
||||
case SCAN_F8:
|
||||
case SCAN_F9:
|
||||
case SCAN_F10:
|
||||
case SCAN_F11:
|
||||
case SCAN_F12:
|
||||
CommandStr = GetCommandNameByKey (Key);
|
||||
if (CommandStr != NULL) {
|
||||
StrnCpyS (InStr, StrLength, CommandStr, StrLength - 1);
|
||||
return ;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Done) {
|
||||
break;
|
||||
}
|
||||
//
|
||||
// If we need to update the output do so now
|
||||
//
|
||||
if (Update != -1) {
|
||||
if (NeedAdjust) {
|
||||
ConOut->SetCursorPosition (ConOut, Column, Row);
|
||||
for (SubIndex = 0; SubIndex < EFI_DEBUG_INPUS_BUFFER_SIZE - (Column - EFI_DEBUG_PROMPT_COLUMN); SubIndex++) {
|
||||
mBackupSpace[SubIndex] = L' ';
|
||||
}
|
||||
EDBPrint (mBackupSpace);
|
||||
SetMem (mBackupSpace, (EFI_DEBUG_INPUS_BUFFER_SIZE - (Column - EFI_DEBUG_PROMPT_COLUMN)) * sizeof(CHAR16), 0);
|
||||
ConOut->SetCursorPosition (ConOut, Column, Row);
|
||||
NeedAdjust = FALSE;
|
||||
}
|
||||
EDBPrint (InStr + Update);
|
||||
Len = StrLen (InStr);
|
||||
|
||||
if (Delete) {
|
||||
SetMem (InStr + Len, Delete * sizeof (CHAR16), 0x00);
|
||||
}
|
||||
|
||||
if (StrPos > Len) {
|
||||
StrPos = Len;
|
||||
}
|
||||
|
||||
Update = (UINTN) -1;
|
||||
|
||||
//
|
||||
// After using print to reflect newly updates, if we're not using
|
||||
// BACKSPACE and DELETE, we need to move the cursor position forward,
|
||||
// so adjust row and column here.
|
||||
//
|
||||
if (Key.UnicodeChar != CHAR_BACKSPACE && !(Key.UnicodeChar == 0 && Key.ScanCode == SCAN_DELETE)) {
|
||||
//
|
||||
// Calulate row and column of the tail of current string
|
||||
//
|
||||
TailRow = Row + (Len - StrPos + Column + OutputLength) / LineLength;
|
||||
TailColumn = (Len - StrPos + Column + OutputLength) % LineLength;
|
||||
|
||||
//
|
||||
// If the tail of string reaches screen end, screen rolls up, so if
|
||||
// Row does not equal TailRow, Row should be decremented
|
||||
//
|
||||
// (if we are recalling commands using UPPER and DOWN key, and if the
|
||||
// old command is too long to fit the screen, TailColumn must be 79.
|
||||
//
|
||||
if (TailColumn == 0 && TailRow >= TotalRow && (UINTN) Row != TailRow) {
|
||||
Row--;
|
||||
}
|
||||
//
|
||||
// Calculate the cursor position after current operation. If cursor
|
||||
// reaches line end, update both row and column, otherwise, only
|
||||
// column will be changed.
|
||||
//
|
||||
if (Column + OutputLength >= LineLength) {
|
||||
SkipLength = OutputLength - (LineLength - Column);
|
||||
|
||||
Row += SkipLength / LineLength + 1;
|
||||
if ((UINTN) Row > TotalRow - 1) {
|
||||
Row = TotalRow - 1;
|
||||
}
|
||||
|
||||
Column = SkipLength % LineLength;
|
||||
} else {
|
||||
Column += OutputLength;
|
||||
}
|
||||
}
|
||||
|
||||
Delete = 0;
|
||||
}
|
||||
//
|
||||
// Set the cursor position for this key
|
||||
//
|
||||
SetCursorPosition (ConOut, Column, Row, LineLength, TotalRow, InStr, StrPos, Len);
|
||||
} while (!Done);
|
||||
|
||||
CopyMem (mInputBufferHistory, InStr, StrLength * sizeof(CHAR16));
|
||||
|
||||
//
|
||||
// Return the data to the caller
|
||||
//
|
||||
return ;
|
||||
}
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
SetCursorPosition (
|
||||
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut,
|
||||
IN UINTN Column,
|
||||
IN INTN Row,
|
||||
IN UINTN LineLength,
|
||||
IN UINTN TotalRow,
|
||||
IN CHAR16 *Str,
|
||||
IN UINTN StrPos,
|
||||
IN UINTN Len
|
||||
)
|
||||
{
|
||||
CHAR16 Backup;
|
||||
|
||||
ASSERT (ConOut != NULL);
|
||||
ASSERT (Str != NULL);
|
||||
|
||||
Backup = 0;
|
||||
if (Row >= 0) {
|
||||
ConOut->SetCursorPosition (ConOut, Column, Row);
|
||||
return ;
|
||||
}
|
||||
|
||||
if (Len - StrPos > Column * Row) {
|
||||
Backup = *(Str + StrPos + Column * Row);
|
||||
*(Str + StrPos + Column * Row) = 0;
|
||||
}
|
||||
|
||||
EDBPrint (L"%s", Str + StrPos);
|
||||
if (Len - StrPos > Column * Row) {
|
||||
*(Str + StrPos + Column * Row) = Backup;
|
||||
}
|
||||
|
||||
ConOut->SetCursorPosition (ConOut, 0, 0);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
SetPageBreak (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_INPUT_KEY Key;
|
||||
CHAR16 Str[3];
|
||||
BOOLEAN OmitPrint;
|
||||
|
||||
//
|
||||
// Check
|
||||
//
|
||||
if (!mDebuggerPrivate.EnablePageBreak) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gST->ConOut->OutputString (gST->ConOut, L"Press ENTER to continue, 'q' to exit:");
|
||||
|
||||
OmitPrint = FALSE;
|
||||
//
|
||||
// Wait for user input
|
||||
//
|
||||
Str[0] = ' ';
|
||||
Str[1] = 0;
|
||||
Str[2] = 0;
|
||||
for (;;) {
|
||||
WaitForSingleEvent (gST->ConIn->WaitForKey, 0);
|
||||
gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
|
||||
|
||||
//
|
||||
// handle control keys
|
||||
//
|
||||
if (Key.UnicodeChar == CHAR_NULL) {
|
||||
if (Key.ScanCode == SCAN_ESC) {
|
||||
gST->ConOut->OutputString (gST->ConOut, L"\r\n");
|
||||
OmitPrint = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
|
||||
gST->ConOut->OutputString (gST->ConOut, L"\r\n");
|
||||
break;
|
||||
}
|
||||
//
|
||||
// Echo input
|
||||
//
|
||||
Str[1] = Key.UnicodeChar;
|
||||
if (Str[1] == CHAR_BACKSPACE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
gST->ConOut->OutputString (gST->ConOut, Str);
|
||||
|
||||
if ((Str[1] == L'q') || (Str[1] == L'Q')) {
|
||||
OmitPrint = TRUE;
|
||||
} else {
|
||||
OmitPrint = FALSE;
|
||||
}
|
||||
|
||||
Str[0] = CHAR_BACKSPACE;
|
||||
}
|
||||
|
||||
return OmitPrint;
|
||||
}
|
||||
|
||||
UINTN
|
||||
EFIAPI
|
||||
EDBPrint (
|
||||
IN CONST CHAR16 *Format,
|
||||
...
|
||||
)
|
||||
{
|
||||
UINTN Return;
|
||||
VA_LIST Marker;
|
||||
CHAR16 Buffer[EFI_DEBUG_MAX_PRINT_BUFFER];
|
||||
|
||||
VA_START (Marker, Format);
|
||||
Return = UnicodeVSPrint (Buffer, sizeof (Buffer), Format, Marker);
|
||||
VA_END (Marker);
|
||||
|
||||
if (gST->ConOut != NULL) {
|
||||
//
|
||||
// To be extra safe make sure ConOut has been initialized
|
||||
//
|
||||
gST->ConOut->OutputString (gST->ConOut, Buffer);
|
||||
}
|
||||
|
||||
return Return;
|
||||
}
|
||||
|
||||
UINTN
|
||||
EFIAPI
|
||||
EDBSPrint (
|
||||
OUT CHAR16 *Buffer,
|
||||
IN INTN BufferSize,
|
||||
IN CONST CHAR16 *Format,
|
||||
...
|
||||
)
|
||||
{
|
||||
UINTN Return;
|
||||
VA_LIST Marker;
|
||||
|
||||
ASSERT (BufferSize > 0);
|
||||
|
||||
VA_START (Marker, Format);
|
||||
Return = UnicodeVSPrint (Buffer, (UINTN)BufferSize, Format, Marker);
|
||||
VA_END (Marker);
|
||||
|
||||
return Return;
|
||||
}
|
||||
|
||||
UINTN
|
||||
EFIAPI
|
||||
EDBSPrintWithOffset (
|
||||
OUT CHAR16 *Buffer,
|
||||
IN INTN BufferSize,
|
||||
IN UINTN Offset,
|
||||
IN CONST CHAR16 *Format,
|
||||
...
|
||||
)
|
||||
{
|
||||
UINTN Return;
|
||||
VA_LIST Marker;
|
||||
|
||||
ASSERT (BufferSize - (Offset * sizeof(CHAR16)) > 0);
|
||||
|
||||
VA_START (Marker, Format);
|
||||
Return = UnicodeVSPrint (Buffer + Offset, (UINTN)(BufferSize - (Offset * sizeof(CHAR16))), Format, Marker);
|
||||
VA_END (Marker);
|
||||
|
||||
return Return;
|
||||
}
|
Reference in New Issue
Block a user