ShellPkg/[hex]edit: use SimpleTextInEx to read console
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=682 Edit and HexEdit commands assume that SimpleTxtIn translates Ctrl+<Alpha-Key> key combinations into Unicode control characters (0x1-0x1A). Such translation does not seem to be required by the UEFI spec. Shell should not rely on implementation specific behavior. It should instead use SimpleTextInEx to read Ctrl+<Alpha-Key> key combinations. The patch changes edit and hexedit to only consumes SimpleTextInEx so that the implementation specific behavior dependency is removed. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com> Reported-by: Felix <felixp@mail.ru> Cc: Felix <felixp@mail.ru> Reviewed-by: Jaben Carsey <jaben.carsey@intel.com>
This commit is contained in:
@ -4,7 +4,7 @@
|
||||
- Instances of the other objects of the editor
|
||||
- Main Interfaces
|
||||
|
||||
Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved. <BR>
|
||||
Copyright (c) 2005 - 2018, Intel Corporation. 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
|
||||
@ -56,6 +56,7 @@ HEFI_EDITOR_GLOBAL_EDITOR HMainEditorConst = {
|
||||
0,
|
||||
0
|
||||
},
|
||||
NULL,
|
||||
FALSE,
|
||||
NULL,
|
||||
0,
|
||||
@ -105,22 +106,53 @@ HMainCommandDisplayHelp (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
INT32 CurrentLine;
|
||||
CHAR16 * InfoString;
|
||||
EFI_INPUT_KEY Key;
|
||||
|
||||
CurrentLine = 0;
|
||||
INT32 CurrentLine;
|
||||
CHAR16 *InfoString;
|
||||
EFI_KEY_DATA KeyData;
|
||||
EFI_STATUS Status;
|
||||
UINTN EventIndex;
|
||||
|
||||
//
|
||||
// print helpInfo
|
||||
//
|
||||
for (CurrentLine = 0; 0 != HexMainMenuHelpInfo[CurrentLine]; CurrentLine++) {
|
||||
InfoString = HiiGetString(gShellDebug1HiiHandle, HexMainMenuHelpInfo[CurrentLine]
|
||||
, NULL);
|
||||
ShellPrintEx (0,CurrentLine+1,L"%E%s%N",InfoString);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// scan for ctrl+w
|
||||
do {
|
||||
gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
|
||||
} while(SCAN_CONTROL_W != Key.UnicodeChar);
|
||||
//
|
||||
while (TRUE) {
|
||||
Status = gBS->WaitForEvent (1, &HMainEditor.TextInputEx->WaitForKeyEx, &EventIndex);
|
||||
if (EFI_ERROR (Status) || (EventIndex != 0)) {
|
||||
continue;
|
||||
}
|
||||
Status = HMainEditor.TextInputEx->ReadKeyStrokeEx (HMainEditor.TextInputEx, &KeyData);
|
||||
if (EFI_ERROR (Status)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) {
|
||||
//
|
||||
// For consoles that don't support shift state reporting,
|
||||
// CTRL+W is translated to L'W' - L'A' + 1.
|
||||
//
|
||||
if (KeyData.Key.UnicodeChar == L'W' - L'A' + 1) {
|
||||
break;
|
||||
}
|
||||
} else if (((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) &&
|
||||
((KeyData.KeyState.KeyShiftState & ~(EFI_SHIFT_STATE_VALID | EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) == 0)) {
|
||||
//
|
||||
// For consoles that supports shift state reporting,
|
||||
// make sure that only CONTROL shift key is pressed.
|
||||
//
|
||||
if ((KeyData.Key.UnicodeChar == 'w') || (KeyData.Key.UnicodeChar == 'W')) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update screen with buffer's info
|
||||
HBufferImageNeedRefresh = TRUE;
|
||||
@ -1633,6 +1665,19 @@ HMainEditorInit (
|
||||
&(HMainEditor.ScreenSize.Row)
|
||||
);
|
||||
|
||||
//
|
||||
// Find TextInEx in System Table ConsoleInHandle
|
||||
// Per UEFI Spec, TextInEx is required for a console capable platform.
|
||||
//
|
||||
Status = gBS->HandleProtocol (
|
||||
gST->ConsoleInHandle,
|
||||
&gEfiSimpleTextInputExProtocolGuid,
|
||||
(VOID**)&HMainEditor.TextInputEx
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Find mouse in System Table ConsoleInHandle
|
||||
//
|
||||
@ -1706,7 +1751,7 @@ HMainEditorInit (
|
||||
return EFI_LOAD_ERROR;
|
||||
}
|
||||
|
||||
InputBarInit ();
|
||||
InputBarInit (HMainEditor.TextInputEx);
|
||||
|
||||
Status = HBufferImageInit ();
|
||||
if (EFI_ERROR (Status)) {
|
||||
@ -2058,9 +2103,11 @@ HMainEditorKeyInput (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_INPUT_KEY Key;
|
||||
EFI_KEY_DATA KeyData;
|
||||
EFI_STATUS Status;
|
||||
EFI_SIMPLE_POINTER_STATE MouseState;
|
||||
UINTN EventIndex;
|
||||
BOOLEAN NoShiftState;
|
||||
BOOLEAN LengthChange;
|
||||
UINTN Size;
|
||||
UINTN OldSize;
|
||||
@ -2219,84 +2266,94 @@ HMainEditorKeyInput (
|
||||
}
|
||||
}
|
||||
|
||||
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// dispatch to different components' key handling function
|
||||
// so not everywhere has to set this variable
|
||||
//
|
||||
HBufferImageMouseNeedRefresh = TRUE;
|
||||
|
||||
//
|
||||
// clear previous status string
|
||||
//
|
||||
StatusBarSetRefresh();
|
||||
if (EFI_SUCCESS == MenuBarDispatchControlHotKey(&Key)) {
|
||||
Status = EFI_SUCCESS;
|
||||
} else if (Key.ScanCode == SCAN_NULL) {
|
||||
Status = HBufferImageHandleInput (&Key);
|
||||
} else if (((Key.ScanCode >= SCAN_UP) && (Key.ScanCode <= SCAN_PAGE_DOWN))) {
|
||||
Status = HBufferImageHandleInput (&Key);
|
||||
} else if (((Key.ScanCode >= SCAN_F1) && Key.ScanCode <= (SCAN_F12))) {
|
||||
Status = MenuBarDispatchFunctionKey (&Key);
|
||||
} else {
|
||||
StatusBarSetStatusString (L"Unknown Command");
|
||||
|
||||
HBufferImageMouseNeedRefresh = FALSE;
|
||||
}
|
||||
|
||||
if (Status != EFI_SUCCESS && Status != EFI_OUT_OF_RESOURCES) {
|
||||
Status = gBS->WaitForEvent (1, &HMainEditor.TextInputEx->WaitForKeyEx, &EventIndex);
|
||||
if (!EFI_ERROR (Status) && EventIndex == 0) {
|
||||
Status = HMainEditor.TextInputEx->ReadKeyStrokeEx (HMainEditor.TextInputEx, &KeyData);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// not already has some error status
|
||||
// dispatch to different components' key handling function
|
||||
// so not everywhere has to set this variable
|
||||
//
|
||||
if (StrCmp (L"", StatusBarGetString()) == 0) {
|
||||
StatusBarSetStatusString (L"Disk Error. Try Again");
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// decide if has to set length warning
|
||||
//
|
||||
if (HBufferImage.BufferType != HBufferImageBackupVar.BufferType) {
|
||||
LengthChange = FALSE;
|
||||
} else {
|
||||
//
|
||||
// still the old buffer
|
||||
//
|
||||
if (HBufferImage.BufferType != FileTypeFileBuffer) {
|
||||
Size = HBufferImageGetTotalSize ();
|
||||
HBufferImageMouseNeedRefresh = TRUE;
|
||||
|
||||
switch (HBufferImage.BufferType) {
|
||||
case FileTypeDiskBuffer:
|
||||
OldSize = HBufferImage.DiskImage->Size * HBufferImage.DiskImage->BlockSize;
|
||||
break;
|
||||
//
|
||||
// clear previous status string
|
||||
//
|
||||
StatusBarSetRefresh();
|
||||
//
|
||||
// NoShiftState: TRUE when no shift key is pressed.
|
||||
//
|
||||
NoShiftState = ((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) || (KeyData.KeyState.KeyShiftState == EFI_SHIFT_STATE_VALID);
|
||||
//
|
||||
// dispatch to different components' key handling function
|
||||
//
|
||||
if (EFI_SUCCESS == MenuBarDispatchControlHotKey(&KeyData)) {
|
||||
Status = EFI_SUCCESS;
|
||||
} else if (NoShiftState && KeyData.Key.ScanCode == SCAN_NULL) {
|
||||
Status = HBufferImageHandleInput (&KeyData.Key);
|
||||
} else if (NoShiftState && ((KeyData.Key.ScanCode >= SCAN_UP) && (KeyData.Key.ScanCode <= SCAN_PAGE_DOWN))) {
|
||||
Status = HBufferImageHandleInput (&KeyData.Key);
|
||||
} else if (NoShiftState && ((KeyData.Key.ScanCode >= SCAN_F1) && KeyData.Key.ScanCode <= SCAN_F12)) {
|
||||
Status = MenuBarDispatchFunctionKey (&KeyData.Key);
|
||||
} else {
|
||||
StatusBarSetStatusString (L"Unknown Command");
|
||||
|
||||
case FileTypeMemBuffer:
|
||||
OldSize = HBufferImage.MemImage->Size;
|
||||
break;
|
||||
|
||||
default:
|
||||
OldSize = 0;
|
||||
break;
|
||||
HBufferImageMouseNeedRefresh = FALSE;
|
||||
}
|
||||
|
||||
if (!LengthChange) {
|
||||
if (OldSize != Size) {
|
||||
StatusBarSetStatusString (L"Disk/Mem Buffer Length should not be changed");
|
||||
if (Status != EFI_SUCCESS && Status != EFI_OUT_OF_RESOURCES) {
|
||||
//
|
||||
// not already has some error status
|
||||
//
|
||||
if (StrCmp (L"", StatusBarGetString()) == 0) {
|
||||
StatusBarSetStatusString (L"Disk Error. Try Again");
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// decide if has to set length warning
|
||||
//
|
||||
if (HBufferImage.BufferType != HBufferImageBackupVar.BufferType) {
|
||||
LengthChange = FALSE;
|
||||
} else {
|
||||
//
|
||||
// still the old buffer
|
||||
//
|
||||
if (HBufferImage.BufferType != FileTypeFileBuffer) {
|
||||
Size = HBufferImageGetTotalSize ();
|
||||
|
||||
if (OldSize != Size) {
|
||||
LengthChange = TRUE;
|
||||
} else {
|
||||
LengthChange = FALSE;
|
||||
switch (HBufferImage.BufferType) {
|
||||
case FileTypeDiskBuffer:
|
||||
OldSize = HBufferImage.DiskImage->Size * HBufferImage.DiskImage->BlockSize;
|
||||
break;
|
||||
|
||||
case FileTypeMemBuffer:
|
||||
OldSize = HBufferImage.MemImage->Size;
|
||||
break;
|
||||
|
||||
default:
|
||||
OldSize = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!LengthChange) {
|
||||
if (OldSize != Size) {
|
||||
StatusBarSetStatusString (L"Disk/Mem Buffer Length should not be changed");
|
||||
}
|
||||
}
|
||||
|
||||
if (OldSize != Size) {
|
||||
LengthChange = TRUE;
|
||||
} else {
|
||||
LengthChange = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// after handling, refresh editor
|
||||
//
|
||||
HMainEditorRefresh ();
|
||||
}
|
||||
//
|
||||
// after handling, refresh editor
|
||||
//
|
||||
HMainEditorRefresh ();
|
||||
|
||||
} while (Status != EFI_OUT_OF_RESOURCES && !HEditorExit);
|
||||
|
||||
|
Reference in New Issue
Block a user