254 lines
5.7 KiB
C

/** @file
Control MSR 0xE2 UI Input/Output in the widest sense
Copyright (c) 2020, Brumbaer. All rights reserved.<BR>
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.
**/
#include "ControlMsrE2.h"
UINTN mArgumentFlags;
/*
Read up to Length -1 Characters from keyboard.
CR will exit
LF will exit
Del key is supported
Esc any input will be cleared. If there isn't any ReadLine will exít
When length - 1 characters are entered Readline will exit automatically.
*/
UINT32
ReadLine (
OUT CHAR16 *Buffer,
IN UINT32 Length
)
{
EFI_STATUS Status;
UINTN EventIndex;
EFI_INPUT_KEY Key;
UINT32 Index;
UINT32 Pos;
INT32 StartRow;
INT32 StartColumn;
Pos = 0;
STATIC CHAR16 Output[] = L"A";
gST->ConOut->EnableCursor (gST->ConOut, TRUE);
StartRow = gST->ConOut->Mode->CursorRow;
StartColumn = gST->ConOut->Mode->CursorColumn;
do {
//
// Read a key
//
gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);
ZeroMem (&Key, sizeof (Key));
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
if (EFI_ERROR (Status)) {
if (Status == EFI_NOT_READY) {
continue;
}
break;
}
switch (Key.UnicodeChar) {
case CHAR_BACKSPACE:
if (Pos > 0) {
--Pos;
gST->ConOut->SetCursorPosition (gST->ConOut, StartColumn + Pos, StartRow);
gST->ConOut->OutputString (gST->ConOut, L" ");
gST->ConOut->SetCursorPosition (gST->ConOut, StartColumn + Pos, StartRow);
}
break;
case CHAR_ESC:
if (Pos > 0) {
Pos = 0;
gST->ConOut->SetCursorPosition (gST->ConOut, StartColumn + Pos, StartRow);
for (Index = 1; Index < Length; ++Index) {
gST->ConOut->OutputString (gST->ConOut, L" ");
}
gST->ConOut->SetCursorPosition (gST->ConOut, StartColumn + Pos, StartRow);
} else {
Buffer[Pos] = 0;
return Pos;
}
break;
case CHAR_CARRIAGE_RETURN:
case CHAR_LINEFEED:
Buffer[Pos] = 0;
gST->ConOut->EnableCursor (gST->ConOut, FALSE);
return Pos;
default:
Buffer[Pos] = Key.UnicodeChar;
++Pos;
Output[0] = Key.UnicodeChar;
gST->ConOut->OutputString (gST->ConOut, Output);
if (Pos == Length - 1) {
Buffer[Pos] = 0;
return Pos;
}
break;
}
} while (TRUE);
return 0;
}
CHAR16
ReadAnyKey (
VOID
)
{
CHAR16 Keys[2];
ReadLine (Keys, 2);
return Keys[0];
}
BOOLEAN
ReadYN (
VOID
)
{
CHAR16 Key;
do {
Key = ReadAnyKey ();
} while (Key != 'y' && Key != 'Y' && Key != 'n' && Key != 'N');
return Key == 'y' || Key == 'Y';
}
#define TOKENLENGTH 32
EFI_STATUS
InterpretArguments (
VOID
)
{
UINTN Argc;
CHAR16 **Argv;
CHAR16 *Parameter;
UINTN ParameterCount;
CHAR16 *Token;
UINT16 TokenIndex;
UINT32 Index;
EFI_STATUS Status;
mArgumentFlags = ARG_VERIFY;
Status = GetArguments (&Argc, &Argv);
if (EFI_ERROR (Status)) {
Print (L"Unable to get arguments - %r\n", Status);
return Status;
}
ParameterCount = 0;
for (Index = 1; Index < Argc; ++Index) {
Token = AllocateCopyPool (StrSize (Argv[Index]), Argv[Index]);
if (Token == NULL) {
Print (L"Could not allocate memory for Token.\n");
return EFI_OUT_OF_RESOURCES;
}
TokenIndex = 0;
while (Token[TokenIndex] != '\0') {
if (Token[TokenIndex] == ' ') {
++TokenIndex;
continue;
}
Parameter = &Token[TokenIndex];
do {
++TokenIndex;
} while (Token[TokenIndex] != '\0' && Token[TokenIndex] != ' ');
Token[TokenIndex] = '\0';
if (OcStriCmp (Parameter, L"lock") == 0) {
mArgumentFlags = ARG_LOCK;
} else if (OcStriCmp (Parameter, L"unlock") == 0) {
mArgumentFlags = ARG_UNLOCK;
} else if (OcStriCmp (Parameter, L"interactive") == 0) {
mArgumentFlags = ARG_INTERACTIVE;
} else {
Print (L"Unknown command line argument: %s\n", Parameter);
Status = EFI_INVALID_PARAMETER;
break;
}
++ParameterCount;
}
FreePool (Token);
}
if (ParameterCount > 1) {
Print (L"interactive, unlock, lock are exclusive options. Use only one of them.\n\n");
Status = EFI_INVALID_PARAMETER;
}
if (ParameterCount == 0) {
Print (L"No option selected, verify only.\n");
Print (L"Usage: ControlMsrE2 <unlock | lock | interactive>\n\n");
}
return Status;
}
VOID
ModifySearchString (
IN OUT EFI_STRING *SearchString
)
{
BOOLEAN Result;
do {
Print (L"\nCurrent search string: %s\n", *SearchString);
Print (L"Do you want to change it ? ");
Result = ReadYN ();
Print (L"\n");
if (Result) {
Print (L"Enter search string:\n");
CHAR16 *Buffer = AllocatePool (BUFFER_LENGTH * sizeof (CHAR16));
if (Buffer != NULL) {
if (ReadLine (Buffer, BUFFER_LENGTH) == 0) {
Print (L"\nNo Input. Search string not changed.\n");
FreePool (Buffer);
} else {
Print (L"\n");
FreePool (*SearchString);
*SearchString = Buffer;
}
} else {
Print (L"Could not allocate memory. Search string can not be changed.\n");
}
}
} while (Result);
}