inputhandler.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,569 行 · 第 1/4 页
C
1,569 行
PageData->Data->Length = sizeof (EFI_IFR_DATA_ENTRY);
PageData->Data->Data = (VOID *) TempString2;
}
if ((FormCallback != NULL) && (FormCallback->Callback != NULL)) {
Status = FormCallback->Callback (
FormCallback,
Tag->Key,
PageData,
&Packet
);
}
//
// If this was the confirmation round of callbacks
// and an error comes back, display an error
//
if (Confirmation) {
if (EFI_ERROR (Status)) {
if (Packet->String == NULL) {
ScreenSize = EFI_MAX (GetStringWidth (gConfirmError), GetStringWidth (gPressEnter)) / 2;
CreatePopUp (ScreenSize, 4, &NullCharacter, gConfirmError, gPressEnter, &NullCharacter);
} else {
ScreenSize = EFI_MAX (GetStringWidth (Packet->String), GetStringWidth (gPressEnter)) / 2;
CreatePopUp (ScreenSize, 4, &NullCharacter, Packet->String, gPressEnter, &NullCharacter);
gBS->FreePool (Packet);
}
StringPtr[0] = CHAR_NULL;
do {
Status = WaitForKeyStroke (&Key);
if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
gBS->FreePool (TempString);
gBS->FreePool (TempString2);
return EFI_NOT_READY;
}
} while (1);
} else {
gBS->FreePool (TempString);
gBS->FreePool (TempString2);
return EFI_NOT_READY;
}
} else {
//
// User typed a string in and it wasn't valid somehow from the callback
// For instance, callback may have said that some invalid characters were contained in the string
//
if (Status == EFI_NOT_READY) {
goto Error;
}
if (PromptForPassword && EFI_ERROR (Status)) {
gBS->FreePool (TempString);
gBS->FreePool (TempString2);
return EFI_DEVICE_ERROR;
}
}
}
if (Confirmation) {
//
// Compare tempstring and tempstring2, if the same, return with StringPtr success
// Otherwise, kick and error box, and return an error
//
if (EfiStrCmp (TempString, TempString2) == 0) {
gBS->FreePool (TempString);
gBS->FreePool (TempString2);
return EFI_SUCCESS;
} else {
ScreenSize = EFI_MAX (GetStringWidth (gConfirmError), GetStringWidth (gPressEnter)) / 2;
CreatePopUp (ScreenSize, 4, &NullCharacter, gConfirmError, gPressEnter, &NullCharacter);
StringPtr[0] = CHAR_NULL;
do {
Status = WaitForKeyStroke (&Key);
if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
gBS->FreePool (TempString);
gBS->FreePool (TempString2);
return EFI_DEVICE_ERROR;
}
} while (1);
}
}
if (PromptForPassword) {
//
// I was asked for a password, return it back in StringPtr
//
gBS->FreePool (TempString);
gBS->FreePool (TempString2);
return EFI_SUCCESS;
} else {
//
// If the two passwords were not the same kick an error popup
//
Confirmation = TRUE;
ConfirmationComplete = TRUE;
break;
}
case CHAR_BACKSPACE:
if (StringPtr[0] != CHAR_NULL) {
if (!Confirmation) {
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);
} else {
for (Index = 0; StringPtr[Index] != CHAR_NULL; Index++) {
TempString2[Index] = StringPtr[Index];
}
//
// Effectively truncate string by 1 character
//
TempString2[Index - 1] = CHAR_NULL;
EfiStrCpy (StringPtr, TempString2);
}
ConfirmationComplete = FALSE;
} else {
ConfirmationComplete = FALSE;
}
//
// Must be a character we are interested in!
//
default:
if ((StringPtr[0] == CHAR_NULL) && (Key.UnicodeChar != CHAR_BACKSPACE)) {
if (!Confirmation) {
StrnCpy (StringPtr, &Key.UnicodeChar, 1);
StrnCpy (TempString, &Key.UnicodeChar, 1);
} else {
StrnCpy (StringPtr, &Key.UnicodeChar, 1);
StrnCpy (TempString2, &Key.UnicodeChar, 1);
ConfirmationComplete = FALSE;
}
} else if ((GetStringWidth (StringPtr) / 2 <= (UINTN) (MenuOption->ThisTag->Maximum - 1) / 2) &&
(Key.UnicodeChar != CHAR_BACKSPACE)
) {
KeyPad[0] = Key.UnicodeChar;
KeyPad[1] = CHAR_NULL;
if (!Confirmation) {
EfiStrCat (StringPtr, KeyPad);
EfiStrCat (TempString, KeyPad);
} else {
EfiStrCat (StringPtr, KeyPad);
EfiStrCat (TempString2, KeyPad);
}
}
gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY));
for (Index = 1; Index < ScreenSize; Index++) {
PrintCharAt (Start + Index, Top + 3, L' ');
}
gST->ConOut->SetCursorPosition (
gST->ConOut,
(DimensionsWidth - GetStringWidth (StringPtr) / 2) / 2 + gScreenDimensions.LeftColumn,
Top + 3
);
for (Index = 0; Index + 1 < GetStringWidth (StringPtr) / 2; Index++) {
PrintChar (L'*');
}
gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
break;
}
//
// end switch
//
} while (!ConfirmationComplete);
} while (1);
gBS->FreePool (TempString);
gBS->FreePool (TempString2);
return Status;
}
VOID
EncodePassword (
IN CHAR16 *Password,
IN UINT8 MaxSize
)
{
UINTN Index;
UINTN Loop;
CHAR16 *Buffer;
CHAR16 *Key;
Key = L"MAR10648567";
Buffer = EfiLibAllocateZeroPool (MaxSize);
ASSERT (Buffer);
for (Index = 0; Key[Index] != 0; Index++) {
for (Loop = 0; Loop < (UINT8) (MaxSize / 2); Loop++) {
Buffer[Loop] = (CHAR16) (Password[Loop] ^ Key[Index]);
}
}
EfiCopyMem (Password, Buffer, MaxSize);
gBS->FreePool (Buffer);
return ;
}
EFI_STATUS
GetNumericInput (
IN UI_MENU_OPTION *MenuOption,
IN EFI_FILE_FORM_TAGS *FileFormTagsHead,
IN BOOLEAN ManualInput,
IN EFI_TAG *Tag,
IN UINTN NumericType,
OUT UINT16 *Value
)
/*++
Routine Description:
This routine reads a numeric value from the user input.
Arguments:
MenuOption - Pointer to the current input menu.
FileFormTagsHead - Pointer to the root of formset.
ManualInput - If the input is manual or not.
Tag - Pointer to all the attributes and values associated with a tag.
Value - Pointer to the numeric value that is going to be read.
Returns:
EFI_SUCCESS - If numerical input is read successfully
EFI_DEVICE_ERROR - If operation fails
--*/
{
EFI_INPUT_KEY Key;
BOOLEAN SelectionComplete;
UINTN Column;
UINTN Row;
CHAR16 FormattedNumber[6];
UINTN PreviousNumber[6];
INTN Number;
UINTN Count;
UINT16 BackupValue;
STRING_REF PopUp;
CHAR16 NullCharacter;
CHAR16 *StringPtr;
EFI_FILE_FORM_TAGS *FileFormTags;
EFI_STATUS Status;
EFI_VARIABLE_DEFINITION *VariableDefinition;
UINTN Loop;
NullCharacter = CHAR_NULL;
StringPtr = NULL;
Column = MenuOption->OptCol;
Row = MenuOption->Row;
Number = 0;
PreviousNumber[0] = 0;
Count = 0;
SelectionComplete = FALSE;
BackupValue = Tag->Value;
FileFormTags = FileFormTagsHead;
if (ManualInput) {
PrintAt (Column, Row, L"[ ]");
Column++;
if (Tag->Operand != EFI_IFR_TIME_OP) {
*Value = BackupValue;
}
}
//
// First time we enter this handler, we need to check to see if
// we were passed an increment or decrement directive
//
do {
Key.UnicodeChar = CHAR_NULL;
if (gDirection != 0) {
Key.ScanCode = gDirection;
gDirection = 0;
goto TheKey2;
}
Status = WaitForKeyStroke (&Key);
TheKey2:
switch (Key.UnicodeChar) {
case '+':
case '-':
if ((Tag->Operand == EFI_IFR_DATE_OP) || (Tag->Operand == EFI_IFR_TIME_OP)) {
Key.UnicodeChar = CHAR_NULL;
if (Key.UnicodeChar == '+') {
Key.ScanCode = SCAN_RIGHT;
} else {
Key.ScanCode = SCAN_LEFT;
}
goto TheKey2;
}
break;
case CHAR_NULL:
switch (Key.ScanCode) {
case SCAN_LEFT:
case SCAN_RIGHT:
if ((Tag->Operand == EFI_IFR_DATE_OP) || (Tag->Operand == EFI_IFR_TIME_OP)) {
//
// By setting this value, we will return back to the caller.
// We need to do this since an auto-refresh will destroy the adjustment
// based on what the real-time-clock is showing. So we always commit
// upon changing the value.
//
gDirection = SCAN_DOWN;
}
if (!ManualInput) {
Tag->Value = *Value;
if (Key.ScanCode == SCAN_LEFT) {
Number = *Value - Tag->Step;
if (Number < Tag->Minimum) {
Number = Tag->Minimum;
}
} else if (Key.ScanCode == SCAN_RIGHT) {
Number = *Value + Tag->Step;
if (Number > Tag->Maximum) {
Number = Tag->Maximum;
}
}
Tag->Value = (UINT16) Number;
*Value = (UINT16) Number;
ValueToString (FormattedNumber, FALSE, (UINT64) Number);
Number = (UINT16) GetStringWidth (FormattedNumber);
gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT | FIELD_BACKGROUND);
if ((Tag->Operand == EFI_IFR_DATE_OP) || (Tag->Operand == EFI_IFR_TIME_OP)) {
for (Loop = 0; Loop < (UINTN) ((Number >= 8) ? 4 : 2); Loop++) {
PrintAt (MenuOption->OptCol + Loop, MenuOption->Row, L" ");
}
} else {
for (Loop = 0; Loop < gOptionBlockWidth; Loop++) {
PrintAt (MenuOption->OptCol + Loop, MenuOption->Row, L" ");
}
}
gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT_HIGHLIGHT | FIELD_BACKGROUND_HIGHLIGHT);
if ((MenuOption->Col + gPromptBlockWidth + 1) == MenuOption->OptCol) {
PrintCharAt (MenuOption->OptCol, Row, LEFT_NUMERIC_DELIMITER);
Column = MenuOption->OptCol + 1;
}
//
// If Number looks like "3", convert it to "03/"
//
if (Number == 4 && (NumericType == DATE_NUMERIC)) {
FormattedNumber[3] = FormattedNumber[1];
FormattedNumber[2] = DATE_SEPARATOR;
FormattedNumber[1] = FormattedNumber[0];
FormattedNumber[0] = L'0';
Number = 8;
}
//
// If Number looks like "13", convert it to "13/"
//
if (Number == 6 && (NumericType == DATE_NUMERIC)) {
FormattedNumber[3] = FormattedNumber[2];
FormattedNumber[2] = DATE_SEPARATOR;
Number = 8;
}
if (Number == 4 &&
(NumericType == TIME_NUMERIC) &&
(MenuOption->Col + gPromptBlockWidth + 8) != MenuOption->OptCol
) {
FormattedNumber[3] = FormattedNumber[1];
FormattedNumber[2] = TIME_SEPARATOR;
FormattedNumber[1] = FormattedNumber[0];
FormattedNumber[0] = L'0';
Number = 8;
}
if (Number == 4 &&
(NumericType == TIME_NUMERIC) &&
(MenuOption->Col + gPromptBlockWidth + 8) == MenuOption->OptCol
) {
FormattedNumber[3] = FormattedNumber[1];
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?