summaryrefslogtreecommitdiff
path: root/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.c
diff options
context:
space:
mode:
authorjcarsey <jcarsey@6f19259b-4bc3-4df7-8a09-765794883524>2011-03-25 21:15:07 +0000
committerjcarsey <jcarsey@6f19259b-4bc3-4df7-8a09-765794883524>2011-03-25 21:15:07 +0000
commit632820d1cf1ce7a18ef354255eaeae6fdbf383b9 (patch)
tree4bae0e4268fdf79eb2f3aa8035b413c95cb28f10 /ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.c
parent5a0fe66eda4a187724b0eb9d660ab21296178af5 (diff)
downloadedk2-platforms-632820d1cf1ce7a18ef354255eaeae6fdbf383b9.tar.xz
add Edit and HexEdit commands.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11436 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.c')
-rw-r--r--ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.c2294
1 files changed, 2294 insertions, 0 deletions
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.c
new file mode 100644
index 0000000000..387a1e2d1e
--- /dev/null
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.c
@@ -0,0 +1,2294 @@
+/** @file
+ Defines the Main Editor data type -
+ - Global variables
+ - Instances of the other objects of the editor
+ - Main Interfaces
+
+ Copyright (c) 2005 - 2011, 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
+ 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 "HexEditor.h"
+#include "EditStatusBar.h"
+#include "EditInputBar.h"
+
+HEFI_EDITOR_COLOR_ATTRIBUTES HOriginalColors;
+INTN HOriginalMode;
+
+//
+// the first time editor launch
+//
+BOOLEAN HEditorFirst;
+
+//
+// it's time editor should exit
+//
+BOOLEAN HEditorExit;
+
+BOOLEAN HEditorMouseAction;
+
+extern HEFI_EDITOR_BUFFER_IMAGE HBufferImage;
+extern HEFI_EDITOR_BUFFER_IMAGE HBufferImageBackupVar;
+
+extern HEFI_EDITOR_CLIPBOARD HClipBoard;
+
+extern BOOLEAN HBufferImageMouseNeedRefresh;
+extern BOOLEAN HBufferImageNeedRefresh;
+extern BOOLEAN HBufferImageOnlyLineNeedRefresh;
+
+HEFI_EDITOR_GLOBAL_EDITOR HMainEditor;
+HEFI_EDITOR_GLOBAL_EDITOR HMainEditorBackupVar;
+
+//
+// basic initialization for MainEditor
+//
+HEFI_EDITOR_GLOBAL_EDITOR HMainEditorConst = {
+ &HBufferImage,
+ &HClipBoard,
+ {
+ 0,
+ 0
+ },
+ {
+ 0,
+ 0
+ },
+ FALSE,
+ NULL,
+ 0,
+ 0,
+ 1,
+ 1
+};
+
+EFI_STATUS
+HMainCommandGoToOffset (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ move cursor to specified lines
+
+Arguments:
+
+ None
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+{
+ UINTN Size;
+ UINT64 Offset;
+ EFI_STATUS Status;
+ UINTN FRow;
+ UINTN FCol;
+
+ //
+ // variable initialization
+ //
+ Size = 0;
+ Offset = 0;
+ FRow = 0;
+ FCol = 0;
+
+ //
+ // get offset
+ //
+ Status = InputBarSetPrompt (L"Go To Offset: ");
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = InputBarSetStringSize (8);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ while (1) {
+ Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
+
+ //
+ // ESC pressed
+ //
+ if (Status == EFI_NOT_READY) {
+
+ return EFI_SUCCESS;
+ }
+ //
+ // THE input string length should > 0
+ //
+ if (StrLen (InputBarGetString()) > 0) {
+ Status = ShellConvertStringToUint64 (InputBarGetString(), &Offset, TRUE, FALSE);
+ if (EFI_ERROR (Status)) {
+ StatusBarSetStatusString (L"Invalid Offset");
+ return EFI_SUCCESS;
+ }
+
+ break;
+ }
+ }
+
+ Size = HBufferImageGetTotalSize ();
+ if (Offset >= Size) {
+ StatusBarSetStatusString (L"Invalid Offset");
+ return EFI_SUCCESS;
+ }
+
+ FRow = (UINTN)DivU64x32(Offset , 0x10) + 1;
+ FCol = (UINTN)ModU64x32(Offset , 0x10) + 1;
+
+ HBufferImageMovePosition (FRow, FCol, TRUE);
+
+ HBufferImageNeedRefresh = TRUE;
+ HBufferImageOnlyLineNeedRefresh = FALSE;
+ HBufferImageMouseNeedRefresh = TRUE;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+HMainCommandSaveBuffer (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ save current opened buffer .
+ if is file buffer, you can save to current file name or
+ save to another file name
+
+Arguments:
+
+ None
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_OUT_OF_RESOURCES
+ EFI_LOAD_ERROR
+
+--*/
+{
+ EFI_STATUS Status;
+ BOOLEAN Done;
+ CHAR16 *FileName;
+ BOOLEAN OldFile;
+ CHAR16 *Str;
+ EFI_FILE_INFO *Info;
+ SHELL_FILE_HANDLE ShellFileHandle;
+
+ if (HMainEditor.BufferImage->BufferType != FileTypeFileBuffer) {
+ if (HMainEditor.BufferImage->Modified == FALSE) {
+ return EFI_SUCCESS;
+ }
+
+ Status = InputBarSetPrompt (L"Dangerous to save disk/mem buffer. Save (Yes/No/Cancel) ? ");
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // the answer is just one character
+ //
+ Status = InputBarSetStringSize (1);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // loop for user's answer
+ // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'
+ //
+ while (1) {
+ Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
+
+ //
+ // ESC pressed
+ //
+ if (Status == EFI_NOT_READY) {
+ return EFI_SUCCESS;
+ }
+
+ switch (InputBarGetString()[0]) {
+ case L'y':
+ case L'Y':
+ //
+ // want to save this buffer first
+ //
+ Status = HBufferImageSave (
+ NULL,
+ HMainEditor.BufferImage->DiskImage->Name,
+ HMainEditor.BufferImage->DiskImage->Offset,
+ HMainEditor.BufferImage->DiskImage->Size,
+ HMainEditor.BufferImage->MemImage->Offset,
+ HMainEditor.BufferImage->MemImage->Size,
+ HMainEditor.BufferImage->BufferType
+ );
+
+ if (EFI_ERROR (Status)) {
+ StatusBarSetStatusString (L"BufferSave: Problems Writing");
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+
+ case L'n':
+ case L'N':
+ //
+ // the file won't be saved
+ //
+ return EFI_SUCCESS;
+ break;
+
+ case L'c':
+ case L'C':
+ return EFI_SUCCESS;
+ }
+ //
+ // end of switch
+ //
+ }
+ //
+ // ENDOF WHILE
+ //
+ }
+ //
+ // ENDOF != FILEBUFFER
+ //
+ // This command will save currently opened file to disk.
+ // You can choose save to another file name or just save to
+ // current file name.
+ // Below is the scenario of Save File command: (
+ // Suppose the old file name is A )
+ // 1. An Input Bar will be prompted: "File To Save: [ old file name]"
+ // IF user press ESC, Save File command ends .
+ // IF user press Enter, input file name will be A.
+ // IF user inputs a new file name B, input file name will be B.
+ //
+ // 2. IF input file name is A, go to do Step 3.
+ // IF input file name is B, go to do Step 4.
+ //
+ // 3. IF A is read only, Status Bar will show "Access Denied"
+ // and Save File commands ends.
+ // IF A is not read only, save file buffer to disk
+ // and remove Modified flag in Title Bar , then Save File command ends.
+ //
+ // 4. IF B does not exist, create this file and save file buffer to it.
+ // Go to do Step 7.
+ // IF B exits, do Step 5.
+ //
+ // 5. An Input Bar will be prompted:
+ // "File Exists. Overwrite ( Yes/No/Cancel ) ?"
+ // IF user press 'y' or 'Y', do Step 6.
+ // IF user press 'n' or 'N', Save File commands ends.
+ // IF user press 'c' or 'C' or ESC, Save File commands ends.
+ //
+ // 6. IF B is a read-only file, Status Bar will show "Access Denied"
+ // and Save File commands ends.
+ // IF B can be read and write, save file buffer to B.
+ //
+ // 7. Update File Name field in Title Bar to B
+ // and remove the Modified flag in Title Bar.
+ //
+ Str = CatSPrint(NULL,
+ L"File to Save: [%s]",
+ HMainEditor.BufferImage->FileImage->FileName
+ );
+ if (Str == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (StrLen (Str) >= 50) {
+ //
+ // replace the long file name with "..."
+ //
+ Str[46] = L'.';
+ Str[47] = L'.';
+ Str[48] = L'.';
+ Str[49] = L']';
+ Str[50] = L'\0';
+ }
+
+ Status = InputBarSetPrompt (Str);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = InputBarSetStringSize (100);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // get new file name
+ //
+ Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
+
+ //
+ // if user pressed ESC
+ //
+ if (Status == EFI_NOT_READY) {
+ SHELL_FREE_NON_NULL (Str);
+ return EFI_SUCCESS;
+ }
+
+ SHELL_FREE_NON_NULL (Str);
+
+ //
+ // if just enter pressed, so think save to current file name
+ //
+ if (StrLen (InputBarGetString()) == 0) {
+ FileName = CatSPrint(NULL,
+ L"%s",
+ HMainEditor.BufferImage->FileImage->FileName
+ );
+ } else {
+ FileName = CatSPrint(NULL, L"%s", InputBarGetString());
+ }
+
+ if (FileName == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (!IsValidFileName (FileName)) {
+ StatusBarSetStatusString (L"Invalid File Name");
+ SHELL_FREE_NON_NULL (FileName);
+ return EFI_SUCCESS;
+ }
+
+ OldFile = FALSE;
+
+ //
+ // save to the old file
+ //
+ if (StringNoCaseCompare (
+ &FileName,
+ &HMainEditor.BufferImage->FileImage->FileName
+ ) == 0) {
+ OldFile = TRUE;
+ }
+
+ if (OldFile) {
+ //
+ // if the file is read only, so can not write back to it.
+ //
+ if (HMainEditor.BufferImage->FileImage->ReadOnly == TRUE) {
+ StatusBarSetStatusString (L"Access Denied");
+ SHELL_FREE_NON_NULL (FileName);
+ return EFI_SUCCESS;
+ }
+ } else {
+ Status = ShellOpenFileByName (FileName, &ShellFileHandle, EFI_FILE_MODE_READ, 0);
+
+ if (!EFI_ERROR (Status)) {
+
+ Info = ShellGetFileInfo(ShellFileHandle);
+
+ ShellCloseFile(&ShellFileHandle);
+ //
+ // check if read only
+ //
+ if (Info->Attribute & EFI_FILE_READ_ONLY) {
+ StatusBarSetStatusString (L"Access Denied");
+ SHELL_FREE_NON_NULL (FileName);
+ return EFI_SUCCESS;
+ }
+
+ SHELL_FREE_NON_NULL(Info);
+ //
+ // ask user whether to overwrite this file
+ //
+ Status = InputBarSetPrompt (L"File exists. Overwrite (Yes/No/Cancel) ? ");
+ if (EFI_ERROR (Status)) {
+ SHELL_FREE_NON_NULL (FileName);
+ return Status;
+ }
+
+ Status = InputBarSetStringSize (1);
+ if (EFI_ERROR (Status)) {
+ SHELL_FREE_NON_NULL (FileName);
+ return Status;
+ }
+
+ Done = FALSE;
+ while (!Done) {
+ Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
+
+ if (Status == EFI_NOT_READY) {
+ SHELL_FREE_NON_NULL (FileName);
+ return EFI_SUCCESS;
+ }
+
+ switch (InputBarGetString()[0]) {
+ case L'y':
+ case L'Y':
+ Done = TRUE;
+ break;
+ case L'n':
+ case L'N':
+ SHELL_FREE_NON_NULL (FileName);
+ return EFI_SUCCESS;
+ case L'c':
+ case L'C':
+ SHELL_FREE_NON_NULL (FileName);
+ return EFI_SUCCESS;
+ } // switch
+ } // while
+ } // if opened existing file
+ } // if OldFile
+
+ //
+ // save file back to disk
+ //
+ Status = HBufferImageSave (
+ FileName,
+ HMainEditor.BufferImage->DiskImage->Name,
+ HMainEditor.BufferImage->DiskImage->Offset,
+ HMainEditor.BufferImage->DiskImage->Size,
+ HMainEditor.BufferImage->MemImage->Offset,
+ HMainEditor.BufferImage->MemImage->Size,
+ FileTypeFileBuffer
+ );
+ SHELL_FREE_NON_NULL (FileName);
+
+ if (EFI_ERROR (Status)) {
+ return EFI_LOAD_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+HMainCommandSelectStart (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Load a disk buffer editor
+
+Arguments:
+
+ None
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_LOAD_ERROR
+ EFI_OUT_OF_RESOURCES
+
+--*/
+{
+ UINTN Start;
+
+ Start = (HMainEditor.BufferImage->BufferPosition.Row - 1) * 0x10 + HMainEditor.BufferImage->BufferPosition.Column;
+
+ //
+ // last line
+ //
+ if (HMainEditor.BufferImage->CurrentLine->Link.ForwardLink == HMainEditor.BufferImage->ListHead) {
+ if (HMainEditor.BufferImage->BufferPosition.Column > HMainEditor.BufferImage->CurrentLine->Size) {
+ StatusBarSetStatusString (L"Invalid Block Start");
+ return EFI_LOAD_ERROR;
+ }
+ }
+
+ if (HMainEditor.SelectEnd != 0 && Start > HMainEditor.SelectEnd) {
+ StatusBarSetStatusString (L"Invalid Block Start");
+ return EFI_LOAD_ERROR;
+ }
+
+ HMainEditor.SelectStart = Start;
+
+ HBufferImageNeedRefresh = TRUE;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+HMainCommandSelectEnd (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Load a disk buffer editor
+
+Arguments:
+
+ None
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_LOAD_ERROR
+ EFI_OUT_OF_RESOURCES
+
+--*/
+{
+ UINTN End;
+
+ End = (HMainEditor.BufferImage->BufferPosition.Row - 1) * 0x10 + HMainEditor.BufferImage->BufferPosition.Column;
+
+ //
+ // last line
+ //
+ if (HMainEditor.BufferImage->CurrentLine->Link.ForwardLink == HMainEditor.BufferImage->ListHead) {
+ if (HMainEditor.BufferImage->BufferPosition.Column > HMainEditor.BufferImage->CurrentLine->Size) {
+ StatusBarSetStatusString (L"Invalid Block End");
+ return EFI_LOAD_ERROR;
+ }
+ }
+
+ if (HMainEditor.SelectStart != 0 && End < HMainEditor.SelectStart) {
+ StatusBarSetStatusString (L"Invalid Block End");
+ return EFI_SUCCESS;
+ }
+
+ HMainEditor.SelectEnd = End;
+
+ HBufferImageNeedRefresh = TRUE;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+HMainCommandCut (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ cut current line to clipboard
+
+Arguments:
+
+ None
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_OUT_OF_RESOURCES
+ EFI_LOAD_ERROR
+
+--*/
+{
+ UINTN Index;
+ HEFI_EDITOR_LINE *Line;
+ LIST_ENTRY *Link;
+ UINT8 *Buffer;
+ UINTN Count;
+
+ //
+ // not select, so not allowed to cut
+ //
+ if (HMainEditor.SelectStart == 0) {
+ StatusBarSetStatusString (L"No Block is Selected");
+ return EFI_SUCCESS;
+ }
+ //
+ // not select, so not allowed to cut
+ //
+ if (HMainEditor.SelectEnd == 0) {
+ StatusBarSetStatusString (L"No Block is Selected");
+ return EFI_SUCCESS;
+ }
+
+ Link = HMainEditor.BufferImage->ListHead->ForwardLink;
+ for (Index = 0; Index < (HMainEditor.SelectEnd - 1) / 0x10; Index++) {
+ Link = Link->ForwardLink;
+ }
+
+ Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
+
+ Count = HMainEditor.SelectEnd - HMainEditor.SelectStart + 1;
+ Buffer = AllocateZeroPool (Count);
+ if (Buffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // cut the selected area
+ //
+ HBufferImageDeleteCharacterFromBuffer (
+ HMainEditor.SelectStart - 1,
+ Count,
+ Buffer
+ );
+
+ //
+ // put to clipboard
+ //
+ HClipBoardSet (Buffer, Count);
+
+ HBufferImageNeedRefresh = TRUE;
+ HBufferImageOnlyLineNeedRefresh = FALSE;
+
+ if (!HMainEditor.BufferImage->Modified) {
+ HMainEditor.BufferImage->Modified = TRUE;
+ }
+
+ //
+ // now no select area
+ //
+ HMainEditor.SelectStart = 0;
+ HMainEditor.SelectEnd = 0;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+HMainCommandPaste (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ paste line to file buffer
+
+Arguments:
+
+ None
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_OUT_OF_RESOURCES
+ EFI_LOAD_ERROR
+
+
+--*/
+{
+
+ BOOLEAN OnlyLineRefresh;
+ HEFI_EDITOR_LINE *Line;
+ UINT8 *Buffer;
+ UINTN Count;
+ UINTN FPos;
+
+ Count = HClipBoardGet (&Buffer);
+ if (Count == 0 || Buffer == NULL) {
+ StatusBarSetStatusString (L"Nothing to Paste");
+ return EFI_SUCCESS;
+ }
+
+ Line = HMainEditor.BufferImage->CurrentLine;
+
+ OnlyLineRefresh = FALSE;
+ if (Line->Link.ForwardLink == HMainEditor.BufferImage->ListHead && Line->Size + Count < 0x10) {
+ //
+ // is at last line, and after paste will not exceed
+ // so only this line need to be refreshed
+ //
+ // if after add, the line is 0x10, then will append a new line
+ // so the whole page will need be refreshed
+ //
+ OnlyLineRefresh = TRUE;
+
+ }
+
+ FPos = 0x10 * (HMainEditor.BufferImage->BufferPosition.Row - 1) + HMainEditor.BufferImage->BufferPosition.Column - 1;
+
+ HBufferImageAddCharacterToBuffer (FPos, Count, Buffer);
+
+ if (OnlyLineRefresh) {
+ HBufferImageNeedRefresh = FALSE;
+ HBufferImageOnlyLineNeedRefresh = TRUE;
+ } else {
+ HBufferImageNeedRefresh = TRUE;
+ HBufferImageOnlyLineNeedRefresh = FALSE;
+ }
+
+ if (!HMainEditor.BufferImage->Modified) {
+ HMainEditor.BufferImage->Modified = TRUE;
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+EFI_STATUS
+HMainCommandExit (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ exit editor
+
+Arguments:
+
+ None
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_OUT_OF_RESOURCES
+ EFI_LOAD_ERROR
+
+--*/
+{
+ EFI_STATUS Status;
+
+ //
+ // Below is the scenario of Exit command:
+ // 1. IF currently opened file is not modified, exit the editor and
+ // Exit command ends.
+ // IF currently opened file is modified, do Step 2
+ //
+ // 2. An Input Bar will be prompted:
+ // "File modified. Save ( Yes/No/Cancel )?"
+ // IF user press 'y' or 'Y', currently opened file will be saved and
+ // Editor exits
+ // IF user press 'n' or 'N', currently opened file will not be saved
+ // and Editor exits.
+ // IF user press 'c' or 'C' or ESC, Exit command ends.
+ //
+ //
+ // if file has been modified, so will prompt user
+ // whether to save the changes
+ //
+ if (HMainEditor.BufferImage->Modified) {
+
+ Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? ");
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = InputBarSetStringSize (1);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ while (1) {
+ Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
+
+ //
+ // ESC pressed
+ //
+ if (Status == EFI_NOT_READY) {
+ return EFI_SUCCESS;
+ }
+
+ switch (InputBarGetString()[0]) {
+ case L'y':
+ case L'Y':
+ //
+ // write file back to disk
+ //
+ Status = HBufferImageSave (
+ HMainEditor.BufferImage->FileImage->FileName,
+ HMainEditor.BufferImage->DiskImage->Name,
+ HMainEditor.BufferImage->DiskImage->Offset,
+ HMainEditor.BufferImage->DiskImage->Size,
+ HMainEditor.BufferImage->MemImage->Offset,
+ HMainEditor.BufferImage->MemImage->Size,
+ HMainEditor.BufferImage->BufferType
+ );
+ if (!EFI_ERROR (Status)) {
+ HEditorExit = TRUE;
+ }
+
+ return Status;
+
+ case L'n':
+ case L'N':
+ HEditorExit = TRUE;
+ return EFI_SUCCESS;
+
+ case L'c':
+ case L'C':
+ return EFI_SUCCESS;
+
+ }
+ }
+ }
+
+ HEditorExit = TRUE;
+ return EFI_SUCCESS;
+
+}
+
+EFI_STATUS
+HMainCommandOpenFile (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Load a file from disk to editor
+
+Arguments:
+
+ None
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_LOAD_ERROR
+ EFI_OUT_OF_RESOURCES
+
+--*/
+{
+ BOOLEAN Done;
+ EFI_STATUS Status;
+ EDIT_FILE_TYPE BufferType;
+
+ BufferType = HMainEditor.BufferImage->BufferType;
+
+ //
+ // This command will open a file from current working directory.
+ // Read-only file can also be opened. But it can not be modified.
+ // Below is the scenario of Open File command:
+ // 1. IF currently opened file has not been modified, directly go to step .
+ // IF currently opened file has been modified, an Input Bar will be
+ // prompted as :
+ // "File Modified. Save ( Yes/No/Cancel) ?"
+ // IF user press 'y' or 'Y', currently opened file will be saved.
+ // IF user press 'n' or 'N', currently opened file will
+ // not be saved.
+ // IF user press 'c' or 'C' or ESC, Open File command ends and
+ // currently opened file is still opened.
+ //
+ // 2. An Input Bar will be prompted as : "File Name to Open: "
+ // IF user press ESC, Open File command ends and
+ // currently opened file is still opened.
+ // Any other inputs with a Return will cause
+ // currently opened file close.
+ //
+ // 3. IF user input file name is an existing file ,
+ // this file will be read and opened.
+ // IF user input file name is a new file, this file will be created
+ // and opened. This file's type ( UNICODE or ASCII ) is the same with
+ // the old file.
+ //
+ //
+ // if current file is modified, so you need to choose whether to
+ // save it first.
+ //
+ if (HMainEditor.BufferImage->Modified) {
+
+ Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? ");
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // the answer is just one character
+ //
+ Status = InputBarSetStringSize (1);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // loop for user's answer
+ // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'
+ //
+ Done = FALSE;
+ while (!Done) {
+ Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
+
+ //
+ // ESC pressed
+ //
+ if (Status == EFI_NOT_READY) {
+ return EFI_SUCCESS;
+ }
+
+ switch (InputBarGetString()[0]) {
+ case L'y':
+ case L'Y':
+ //
+ // want to save this buffer first
+ //
+ Status = HBufferImageSave (
+ HMainEditor.BufferImage->FileImage->FileName,
+ HMainEditor.BufferImage->DiskImage->Name,
+ HMainEditor.BufferImage->DiskImage->Offset,
+ HMainEditor.BufferImage->DiskImage->Size,
+ HMainEditor.BufferImage->MemImage->Offset,
+ HMainEditor.BufferImage->MemImage->Size,
+ HMainEditor.BufferImage->BufferType
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ MainTitleBarRefresh (
+ HMainEditor.BufferImage->BufferType == FileTypeFileBuffer?HMainEditor.BufferImage->FileImage->FileName:HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Name:NULL,
+ HMainEditor.BufferImage->BufferType,
+ HMainEditor.BufferImage->FileImage->ReadOnly,
+ FALSE,
+ HMainEditor.ScreenSize.Column,
+ HMainEditor.ScreenSize.Row
+ );
+ Done = TRUE;
+ break;
+
+ case L'n':
+ case L'N':
+ //
+ // the file won't be saved
+ //
+ Done = TRUE;
+ break;
+
+ case L'c':
+ case L'C':
+ return EFI_SUCCESS;
+ }
+ }
+ }
+ //
+ // TO get the open file name
+ //
+ Status = InputBarSetPrompt (L"File Name to Open: ");
+ if (EFI_ERROR (Status)) {
+ HBufferImageRead (
+ HMainEditor.BufferImage->FileImage->FileName,
+ HMainEditor.BufferImage->DiskImage->Name,
+ HMainEditor.BufferImage->DiskImage->Offset,
+ HMainEditor.BufferImage->DiskImage->Size,
+ HMainEditor.BufferImage->MemImage->Offset,
+ HMainEditor.BufferImage->MemImage->Size,
+ BufferType,
+ TRUE
+ );
+ return Status;
+ }
+
+ Status = InputBarSetStringSize (100);
+ if (EFI_ERROR (Status)) {
+ Status = HBufferImageRead (
+ HMainEditor.BufferImage->FileImage->FileName,
+ HMainEditor.BufferImage->DiskImage->Name,
+ HMainEditor.BufferImage->DiskImage->Offset,
+ HMainEditor.BufferImage->DiskImage->Size,
+ HMainEditor.BufferImage->MemImage->Offset,
+ HMainEditor.BufferImage->MemImage->Size,
+ BufferType,
+ TRUE
+ );
+ return Status;
+ }
+
+ while (1) {
+ Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
+
+ //
+ // ESC pressed
+ //
+ if (Status == EFI_NOT_READY) {
+ Status = HBufferImageRead (
+ HMainEditor.BufferImage->FileImage->FileName,
+ HMainEditor.BufferImage->DiskImage->Name,
+ HMainEditor.BufferImage->DiskImage->Offset,
+ HMainEditor.BufferImage->DiskImage->Size,
+ HMainEditor.BufferImage->MemImage->Offset,
+ HMainEditor.BufferImage->MemImage->Size,
+ BufferType,
+ TRUE
+ );
+
+ return Status;
+ }
+ //
+ // THE input string length should > 0
+ //
+ if (StrLen (InputBarGetString()) > 0) {
+ //
+ // CHECK if filename's valid
+ //
+ if (!IsValidFileName (InputBarGetString())) {
+ HBufferImageRead (
+ HMainEditor.BufferImage->FileImage->FileName,
+ HMainEditor.BufferImage->DiskImage->Name,
+ HMainEditor.BufferImage->DiskImage->Offset,
+ HMainEditor.BufferImage->DiskImage->Size,
+ HMainEditor.BufferImage->MemImage->Offset,
+ HMainEditor.BufferImage->MemImage->Size,
+ BufferType,
+ TRUE
+ );
+
+ StatusBarSetStatusString (L"Invalid File Name");
+ return EFI_SUCCESS;
+ }
+
+ break;
+ }
+ }
+ //
+ // read from disk
+ //
+ Status = HBufferImageRead (
+ InputBarGetString(),
+ HMainEditor.BufferImage->DiskImage->Name,
+ HMainEditor.BufferImage->DiskImage->Offset,
+ HMainEditor.BufferImage->DiskImage->Size,
+ HMainEditor.BufferImage->MemImage->Offset,
+ HMainEditor.BufferImage->MemImage->Size,
+ FileTypeFileBuffer,
+ FALSE
+ );
+
+ if (EFI_ERROR (Status)) {
+ HBufferImageRead (
+ HMainEditor.BufferImage->FileImage->FileName,
+ HMainEditor.BufferImage->DiskImage->Name,
+ HMainEditor.BufferImage->DiskImage->Offset,
+ HMainEditor.BufferImage->DiskImage->Size,
+ HMainEditor.BufferImage->MemImage->Offset,
+ HMainEditor.BufferImage->MemImage->Size,
+ BufferType,
+ TRUE
+ );
+
+ return EFI_LOAD_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+HMainCommandOpenDisk (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Load a disk buffer editor
+
+Arguments:
+
+ None
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_LOAD_ERROR
+ EFI_OUT_OF_RESOURCES
+ EFI_NOT_FOUND
+
+--*/
+{
+ UINT64 Size;
+ UINT64 Offset;
+ CHAR16 *DeviceName;
+ EFI_STATUS Status;
+ BOOLEAN Done;
+
+ EDIT_FILE_TYPE BufferType;
+
+ //
+ // variable initialization
+ //
+ Size = 0;
+ Offset = 0;
+ BufferType = HMainEditor.BufferImage->BufferType;
+
+ //
+ // if current file is modified, so you need to choose
+ // whether to save it first.
+ //
+ if (HMainEditor.BufferImage->Modified) {
+
+ Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? ");
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // the answer is just one character
+ //
+ Status = InputBarSetStringSize (1);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // loop for user's answer
+ // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'
+ //
+ Done = FALSE;
+ while (!Done) {
+ Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
+
+ //
+ // ESC pressed
+ //
+ if (Status == EFI_NOT_READY) {
+ return EFI_SUCCESS;
+ }
+
+ switch (InputBarGetString()[0]) {
+ case L'y':
+ case L'Y':
+ //
+ // want to save this buffer first
+ //
+ Status = HBufferImageSave (
+ HMainEditor.BufferImage->FileImage->FileName,
+ HMainEditor.BufferImage->DiskImage->Name,
+ HMainEditor.BufferImage->DiskImage->Offset,
+ HMainEditor.BufferImage->DiskImage->Size,
+ HMainEditor.BufferImage->MemImage->Offset,
+ HMainEditor.BufferImage->MemImage->Size,
+ BufferType
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ MainTitleBarRefresh (
+ HMainEditor.BufferImage->BufferType == FileTypeFileBuffer?HMainEditor.BufferImage->FileImage->FileName:HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Name:NULL,
+ HMainEditor.BufferImage->BufferType,
+ HMainEditor.BufferImage->FileImage->ReadOnly,
+ FALSE,
+ HMainEditor.ScreenSize.Column,
+ HMainEditor.ScreenSize.Row
+ );
+ Done = TRUE;
+ break;
+
+ case L'n':
+ case L'N':
+ //
+ // the file won't be saved
+ //
+ Done = TRUE;
+ break;
+
+ case L'c':
+ case L'C':
+ return EFI_SUCCESS;
+ }
+ }
+ }
+ //
+ // get disk block device name
+ //
+ Status = InputBarSetPrompt (L"Block Device to Open: ");
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = InputBarSetStringSize (100);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ while (1) {
+ Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
+
+ //
+ // ESC pressed
+ //
+ if (Status == EFI_NOT_READY) {
+
+ return EFI_SUCCESS;
+ }
+ //
+ // THE input string length should > 0
+ //
+ if (StrLen (InputBarGetString()) > 0) {
+ break;
+ }
+ }
+
+ DeviceName = CatSPrint(NULL, L"%s", InputBarGetString());
+ if (DeviceName == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // get starting offset
+ //
+ Status = InputBarSetPrompt (L"First Block No.: ");
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = InputBarSetStringSize (16);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ while (1) {
+ Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
+
+ //
+ // ESC pressed
+ //
+ if (Status == EFI_NOT_READY) {
+
+ return EFI_SUCCESS;
+ }
+ //
+ // THE input string length should > 0
+ //
+ if (StrLen (InputBarGetString()) > 0) {
+ Status = ShellConvertStringToUint64 (InputBarGetString(), &Offset, TRUE, FALSE);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ break;
+ }
+ }
+ //
+ // get Number of Blocks:
+ //
+ Status = InputBarSetPrompt (L"Number of Blocks: ");
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = InputBarSetStringSize (8);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ while (1) {
+ Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
+
+ //
+ // ESC pressed
+ //
+ if (Status == EFI_NOT_READY) {
+
+ return EFI_SUCCESS;
+ }
+ //
+ // THE input string length should > 0
+ //
+ if (StrLen (InputBarGetString()) > 0) {
+ Status = ShellConvertStringToUint64 (InputBarGetString(), &Size, TRUE, FALSE);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ if (Size == 0) {
+ continue;
+ }
+
+ break;
+ }
+ }
+
+ Status = HBufferImageRead (
+ NULL,
+ DeviceName,
+ (UINTN)Offset,
+ (UINTN)Size,
+ 0,
+ 0,
+ FileTypeDiskBuffer,
+ FALSE
+ );
+
+ if (EFI_ERROR (Status)) {
+
+ HBufferImageRead (
+ HMainEditor.BufferImage->FileImage->FileName,
+ HMainEditor.BufferImage->DiskImage->Name,
+ HMainEditor.BufferImage->DiskImage->Offset,
+ HMainEditor.BufferImage->DiskImage->Size,
+ HMainEditor.BufferImage->MemImage->Offset,
+ HMainEditor.BufferImage->MemImage->Size,
+ BufferType,
+ TRUE
+ );
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+HMainCommandOpenMemory (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Load memory content to editor
+
+Arguments:
+
+ None
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_LOAD_ERROR
+ EFI_OUT_OF_RESOURCES
+ EFI_NOT_FOUND
+
+--*/
+{
+ UINT64 Size;
+ UINT64 Offset;
+ EFI_STATUS Status;
+ BOOLEAN Done;
+ EDIT_FILE_TYPE BufferType;
+
+ //
+ // variable initialization
+ //
+ Size = 0;
+ Offset = 0;
+ BufferType = HMainEditor.BufferImage->BufferType;
+
+ //
+ // if current buffer is modified, so you need to choose
+ // whether to save it first.
+ //
+ if (HMainEditor.BufferImage->Modified) {
+
+ Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? ");
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // the answer is just one character
+ //
+ Status = InputBarSetStringSize (1);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // loop for user's answer
+ // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'
+ //
+ Done = FALSE;
+ while (!Done) {
+ Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
+
+ //
+ // ESC pressed
+ //
+ if (Status == EFI_NOT_READY) {
+ return EFI_SUCCESS;
+ }
+
+ switch (InputBarGetString()[0]) {
+ case L'y':
+ case L'Y':
+ //
+ // want to save this buffer first
+ //
+ Status = HBufferImageSave (
+ HMainEditor.BufferImage->FileImage->FileName,
+ HMainEditor.BufferImage->DiskImage->Name,
+ HMainEditor.BufferImage->DiskImage->Offset,
+ HMainEditor.BufferImage->DiskImage->Size,
+ HMainEditor.BufferImage->MemImage->Offset,
+ HMainEditor.BufferImage->MemImage->Size,
+ BufferType
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ MainTitleBarRefresh (
+ HMainEditor.BufferImage->BufferType == FileTypeFileBuffer?HMainEditor.BufferImage->FileImage->FileName:HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Name:NULL,
+ HMainEditor.BufferImage->BufferType,
+ HMainEditor.BufferImage->FileImage->ReadOnly,
+ FALSE,
+ HMainEditor.ScreenSize.Column,
+ HMainEditor.ScreenSize.Row
+ );
+ Done = TRUE;
+ break;
+
+ case L'n':
+ case L'N':
+ //
+ // the file won't be saved
+ //
+ Done = TRUE;
+ break;
+
+ case L'c':
+ case L'C':
+ return EFI_SUCCESS;
+ }
+ }
+ }
+ //
+ // get starting offset
+ //
+ Status = InputBarSetPrompt (L"Starting Offset: ");
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = InputBarSetStringSize (8);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ while (1) {
+ Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
+
+ //
+ // ESC pressed
+ //
+ if (Status == EFI_NOT_READY) {
+
+ return EFI_SUCCESS;
+ }
+ //
+ // THE input string length should > 0
+ //
+ if (StrLen (InputBarGetString()) > 0) {
+ Status = ShellConvertStringToUint64 (InputBarGetString(), &Offset, TRUE, FALSE);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ break;
+ }
+ }
+ //
+ // get Number of Blocks:
+ //
+ Status = InputBarSetPrompt (L"Buffer Size: ");
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = InputBarSetStringSize (8);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ while (1) {
+ Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
+
+ //
+ // ESC pressed
+ //
+ if (Status == EFI_NOT_READY) {
+
+ return EFI_SUCCESS;
+ }
+ //
+ // THE input string length should > 0
+ //
+ if (StrLen (InputBarGetString()) > 0) {
+ Status = ShellConvertStringToUint64 (InputBarGetString(), &Size, TRUE, FALSE);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ if (Size == 0) {
+ continue;
+ }
+
+ break;
+ }
+ }
+
+ if ((Offset + Size - 1)> 0xffffffff) {
+ StatusBarSetStatusString (L"Invalid parameter");
+ return EFI_LOAD_ERROR;
+ }
+
+ Status = HBufferImageRead (
+ NULL,
+ NULL,
+ 0,
+ 0,
+ (UINTN)Offset,
+ (UINTN)Size,
+ FileTypeMemBuffer,
+ FALSE
+ );
+
+ if (EFI_ERROR (Status)) {
+ StatusBarSetStatusString (L"Read Device Error!");
+ HBufferImageRead (
+ HMainEditor.BufferImage->FileImage->FileName,
+ HMainEditor.BufferImage->DiskImage->Name,
+ HMainEditor.BufferImage->DiskImage->Offset,
+ HMainEditor.BufferImage->DiskImage->Size,
+ HMainEditor.BufferImage->MemImage->Offset,
+ HMainEditor.BufferImage->MemImage->Size,
+ BufferType,
+ TRUE
+ );
+ return EFI_NOT_FOUND;
+ }
+ return EFI_SUCCESS;
+
+}
+
+CONST EDITOR_MENU_ITEM HexEditorMenuItems[] = {
+ {
+ STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_GO_TO_OFFSET),
+ STRING_TOKEN(STR_EDIT_LIBMENUBAR_F1),
+ HMainCommandGoToOffset
+ },
+ {
+ STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_SAVE_BUFFER),
+ STRING_TOKEN(STR_EDIT_LIBMENUBAR_F2),
+ HMainCommandSaveBuffer
+ },
+ {
+ STRING_TOKEN(STR_EDIT_LIBMENUBAR_EXIT),
+ STRING_TOKEN(STR_EDIT_LIBMENUBAR_F3),
+ HMainCommandExit
+ },
+
+ {
+ STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_SELECT_START),
+ STRING_TOKEN(STR_EDIT_LIBMENUBAR_F4),
+ HMainCommandSelectStart
+ },
+ {
+ STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_SELECT_END),
+ STRING_TOKEN(STR_EDIT_LIBMENUBAR_F5),
+ HMainCommandSelectEnd
+ },
+ {
+ STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_CUT),
+ STRING_TOKEN(STR_EDIT_LIBMENUBAR_F6),
+ HMainCommandCut
+ },
+ {
+ STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_PASTE),
+ STRING_TOKEN(STR_EDIT_LIBMENUBAR_F7),
+ HMainCommandPaste
+ },
+
+ {
+ STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_OPEN_FILE),
+ STRING_TOKEN(STR_EDIT_LIBMENUBAR_F8),
+ HMainCommandOpenFile
+ },
+ {
+ STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_OPEN_DISK),
+ STRING_TOKEN(STR_EDIT_LIBMENUBAR_F9),
+ HMainCommandOpenDisk
+ },
+ {
+ STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_OPEN_MEMORY),
+ STRING_TOKEN(STR_EDIT_LIBMENUBAR_F10),
+ HMainCommandOpenMemory
+ },
+
+ {
+ 0,
+ 0,
+ NULL
+ }
+};
+
+
+EFI_STATUS
+HMainEditorInit (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Init function for MainEditor
+
+Arguments:
+
+ None
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_LOAD_ERROR
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer;
+ UINTN HandleCount;
+ UINTN Index;
+
+ //
+ // basic initialization
+ //
+ CopyMem (&HMainEditor, &HMainEditorConst, sizeof (HMainEditor));
+
+ //
+ // set screen attributes
+ //
+ HMainEditor.ColorAttributes.Colors.Foreground = gST->ConOut->Mode->Attribute & 0x000000ff;
+
+ HMainEditor.ColorAttributes.Colors.Background = (UINT8) (gST->ConOut->Mode->Attribute >> 4);
+
+ HOriginalColors = HMainEditor.ColorAttributes.Colors;
+
+ HOriginalMode = gST->ConOut->Mode->Mode;
+
+ //
+ // query screen size
+ //
+ gST->ConOut->QueryMode (
+ gST->ConOut,
+ gST->ConOut->Mode->Mode,
+ &(HMainEditor.ScreenSize.Column),
+ &(HMainEditor.ScreenSize.Row)
+ );
+
+ //
+ // Find mouse in System Table ConsoleInHandle
+ //
+ Status = gBS->HandleProtocol (
+ gST->ConIn,
+ &gEfiSimplePointerProtocolGuid,
+ (VOID**)&HMainEditor.MouseInterface
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // If there is no Simple Pointer Protocol on System Table
+ //
+ HandleBuffer = NULL;
+ HMainEditor.MouseInterface = NULL;
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiSimplePointerProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (!EFI_ERROR (Status) && HandleCount > 0) {
+ //
+ // Try to find the first available mouse device
+ //
+ for (Index = 0; Index < HandleCount; Index++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiSimplePointerProtocolGuid,
+ (VOID**)&HMainEditor.MouseInterface
+ );
+ if (!EFI_ERROR (Status)) {
+ break;
+ }
+ }
+ }
+ if (HandleBuffer != NULL) {
+ FreePool (HandleBuffer);
+ }
+ }
+
+ if (!EFI_ERROR (Status) && HMainEditor.MouseInterface != NULL) {
+ HMainEditor.MouseAccumulatorX = 0;
+ HMainEditor.MouseAccumulatorY = 0;
+ HMainEditor.MouseSupported = TRUE;
+ }
+
+ //
+ // below will call the five components' init function
+ //
+ Status = MainTitleBarInit (NULL);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_TITLE), gShellDebug1HiiHandle);
+ return EFI_LOAD_ERROR;
+ }
+
+ Status = MenuBarInit (HexEditorMenuItems);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_MAINMENU), gShellDebug1HiiHandle);
+ return EFI_LOAD_ERROR;
+ }
+
+ Status = StatusBarInit ();
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_STATUS), gShellDebug1HiiHandle);
+ return EFI_LOAD_ERROR;
+ }
+
+ InputBarInit ();
+
+ Status = HBufferImageInit ();
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_BUFFERIMAGE), gShellDebug1HiiHandle);
+ return EFI_LOAD_ERROR;
+ }
+
+ Status = HClipBoardInit ();
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_CLIPBOARD), gShellDebug1HiiHandle);
+ return EFI_LOAD_ERROR;
+ }
+ //
+ // clear whole screen and enable cursor
+ //
+ gST->ConOut->ClearScreen (gST->ConOut);
+ gST->ConOut->EnableCursor (gST->ConOut, TRUE);
+
+ //
+ // initialize EditorFirst and EditorExit
+ //
+ HEditorFirst = TRUE;
+ HEditorExit = FALSE;
+ HEditorMouseAction = FALSE;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+HMainEditorCleanup (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ cleanup function for MainEditor
+
+Arguments:
+
+ None
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_LOAD_ERROR
+
+--*/
+{
+ EFI_STATUS Status;
+
+ //
+ // call the five components' cleanup function
+ //
+ MainTitleBarCleanup ();
+
+ MenuBarCleanup ();
+
+ StatusBarCleanup ();
+
+ InputBarCleanup ();
+
+ Status = HBufferImageCleanup ();
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_BUFFERIMAGE_CLEAN), gShellDebug1HiiHandle);
+ }
+
+ Status = HClipBoardCleanup ();
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_CLIPBOARD_CLEAN), gShellDebug1HiiHandle);
+ }
+ //
+ // restore old mode
+ //
+ if (HOriginalMode != gST->ConOut->Mode->Mode) {
+ gST->ConOut->SetMode (gST->ConOut, HOriginalMode);
+ }
+
+ gST->ConOut->SetAttribute (
+ gST->ConOut,
+ EFI_TEXT_ATTR (HOriginalColors.Foreground, HOriginalColors.Background)
+ );
+ gST->ConOut->ClearScreen (gST->ConOut);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+HMainEditorRefresh (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Refresh function for MainEditor
+
+Arguments:
+
+ None
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+{
+ //
+ // to aVOID screen flicker
+ // the stall value is from experience
+ //
+ gBS->Stall (50);
+
+ //
+ // call the four components refresh function
+ //
+ MainTitleBarRefresh (
+ HMainEditor.BufferImage->BufferType == FileTypeFileBuffer?HMainEditor.BufferImage->FileImage->FileName:HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Name:NULL,
+ HMainEditor.BufferImage->BufferType,
+ HMainEditor.BufferImage->FileImage->ReadOnly,
+ HMainEditor.BufferImage->Modified,
+ HMainEditor.ScreenSize.Column,
+ HMainEditor.ScreenSize.Row
+ );
+ HBufferImageRefresh ();
+ StatusBarRefresh (
+ HEditorFirst,
+ HMainEditor.ScreenSize.Row,
+ HMainEditor.ScreenSize.Column,
+ 0,
+ 0,
+ TRUE
+ );
+ MenuBarRefresh (
+ HMainEditor.ScreenSize.Row,
+ HMainEditor.ScreenSize.Column);
+
+ //
+ // EditorFirst is now set to FALSE
+ //
+ HEditorFirst = FALSE;
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+HMainEditorHandleMouseInput (
+ IN EFI_SIMPLE_POINTER_STATE MouseState,
+ OUT BOOLEAN *BeforeLeftButtonDown
+ )
+{
+
+ INT32 TextX;
+ INT32 TextY;
+ UINTN FRow;
+ UINTN FCol;
+ BOOLEAN HighBits;
+ LIST_ENTRY *Link;
+ HEFI_EDITOR_LINE *Line;
+ UINTN Index;
+ BOOLEAN Action;
+
+ Action = FALSE;
+
+ //
+ // have mouse movement
+ //
+ if (MouseState.RelativeMovementX || MouseState.RelativeMovementY) {
+ //
+ // handle
+ //
+ TextX = HGetTextX (MouseState.RelativeMovementX);
+ TextY = HGetTextY (MouseState.RelativeMovementY);
+
+ HBufferImageAdjustMousePosition (TextX, TextY);
+
+ Action = TRUE;
+
+ }
+
+ if (MouseState.LeftButton) {
+ HighBits = HBufferImageIsAtHighBits (
+ HMainEditor.BufferImage->MousePosition.Column,
+ &FCol
+ );
+
+ //
+ // not at an movable place
+ //
+ if (FCol == 0) {
+ //
+ // now just move mouse pointer to legal position
+ //
+ //
+ // move mouse position to legal position
+ //
+ HMainEditor.BufferImage->MousePosition.Column -= 10;
+ if (HMainEditor.BufferImage->MousePosition.Column > 24) {
+ HMainEditor.BufferImage->MousePosition.Column--;
+ FCol = HMainEditor.BufferImage->MousePosition.Column / 3 + 1 + 1;
+ } else {
+ if (HMainEditor.BufferImage->MousePosition.Column < 24) {
+ FCol = HMainEditor.BufferImage->MousePosition.Column / 3 + 1 + 1;
+ } else {
+ //
+ // == 24
+ //
+ FCol = 9;
+ }
+ }
+
+ HighBits = TRUE;
+
+ }
+
+ FRow = HMainEditor.BufferImage->BufferPosition.Row +
+ HMainEditor.BufferImage->MousePosition.Row -
+ HMainEditor.BufferImage->DisplayPosition.Row;
+
+ if (HMainEditor.BufferImage->NumLines < FRow) {
+ //
+ // dragging
+ //
+ //
+ // now just move mouse pointer to legal position
+ //
+ FRow = HMainEditor.BufferImage->NumLines;
+ HighBits = TRUE;
+ }
+
+ Link = HMainEditor.BufferImage->ListHead->ForwardLink;
+ for (Index = 0; Index < FRow - 1; Index++) {
+ Link = Link->ForwardLink;
+ }
+
+ Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
+
+ //
+ // dragging
+ //
+ //
+ // now just move mouse pointer to legal position
+ //
+ if (FCol > Line->Size) {
+ if (*BeforeLeftButtonDown) {
+ HighBits = FALSE;
+
+ if (Line->Size == 0) {
+ if (FRow > 1) {
+ FRow--;
+ FCol = 16;
+ } else {
+ FRow = 1;
+ FCol = 1;
+ }
+
+ } else {
+ FCol = Line->Size;
+ }
+ } else {
+ FCol = Line->Size + 1;
+ HighBits = TRUE;
+ }
+ }
+
+ HBufferImageMovePosition (FRow, FCol, HighBits);
+
+ HMainEditor.BufferImage->MousePosition.Row = HMainEditor.BufferImage->DisplayPosition.Row;
+
+ HMainEditor.BufferImage->MousePosition.Column = HMainEditor.BufferImage->DisplayPosition.Column;
+
+ *BeforeLeftButtonDown = TRUE;
+
+ Action = TRUE;
+ } else {
+ //
+ // else of if LButton
+ //
+ // release LButton
+ //
+ if (*BeforeLeftButtonDown == TRUE) {
+ Action = TRUE;
+ }
+ //
+ // mouse up
+ //
+ *BeforeLeftButtonDown = FALSE;
+ }
+
+ if (Action) {
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+HMainEditorKeyInput (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Handle user key input. will route it to other components handle function
+
+Arguments:
+
+ None
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_LOAD_ERROR
+ EFI_OUT_OF_RESOURCES
+
+--*/
+{
+ EFI_INPUT_KEY Key;
+ EFI_STATUS Status;
+ EFI_SIMPLE_POINTER_STATE MouseState;
+ BOOLEAN LengthChange;
+ UINTN Size;
+ UINTN OldSize;
+ BOOLEAN BeforeMouseIsDown;
+ BOOLEAN MouseIsDown;
+ BOOLEAN FirstDown;
+ BOOLEAN MouseDrag;
+ UINTN FRow;
+ UINTN FCol;
+ UINTN SelectStartBackup;
+ UINTN SelectEndBackup;
+
+ //
+ // variable initialization
+ //
+ OldSize = 0;
+ FRow = 0;
+ FCol = 0;
+ LengthChange = FALSE;
+
+ MouseIsDown = FALSE;
+ FirstDown = FALSE;
+ MouseDrag = FALSE;
+
+ do {
+
+ Status = EFI_SUCCESS;
+
+ HEditorMouseAction = FALSE;
+
+ //
+ // backup some key elements, so that can aVOID some refresh work
+ //
+ HMainEditorBackup ();
+
+ //
+ // wait for user key input
+ //
+ //
+ // change priority of checking mouse/keyboard activity dynamically
+ // so prevent starvation of keyboard.
+ // if last time, mouse moves then this time check keyboard
+ //
+ if (HMainEditor.MouseSupported) {
+ Status = HMainEditor.MouseInterface->GetState (
+ HMainEditor.MouseInterface,
+ &MouseState
+ );
+ if (!EFI_ERROR (Status)) {
+
+ BeforeMouseIsDown = MouseIsDown;
+
+ Status = HMainEditorHandleMouseInput (MouseState, &MouseIsDown);
+
+ if (!EFI_ERROR (Status)) {
+ if (BeforeMouseIsDown == FALSE) {
+ //
+ // mouse down
+ //
+ if (MouseIsDown == TRUE) {
+ FRow = HBufferImage.BufferPosition.Row;
+ FCol = HBufferImage.BufferPosition.Column;
+ SelectStartBackup = HMainEditor.SelectStart;
+ SelectEndBackup = HMainEditor.SelectEnd;
+
+ FirstDown = TRUE;
+ }
+ } else {
+
+ SelectStartBackup = HMainEditor.SelectStart;
+ SelectEndBackup = HMainEditor.SelectEnd;
+
+ //
+ // begin to drag
+ //
+ if (MouseIsDown == TRUE) {
+ if (FirstDown == TRUE) {
+ if (MouseState.RelativeMovementX || MouseState.RelativeMovementY) {
+ HMainEditor.SelectStart = 0;
+ HMainEditor.SelectEnd = 0;
+ HMainEditor.SelectStart = (FRow - 1) * 0x10 + FCol;
+
+ MouseDrag = TRUE;
+ FirstDown = FALSE;
+ }
+ } else {
+ if ((
+ (HBufferImage.BufferPosition.Row - 1) *
+ 0x10 +
+ HBufferImage.BufferPosition.Column
+ ) >= HMainEditor.SelectStart
+ ) {
+ HMainEditor.SelectEnd = (HBufferImage.BufferPosition.Row - 1) *
+ 0x10 +
+ HBufferImage.BufferPosition.Column;
+ } else {
+ HMainEditor.SelectEnd = 0;
+ }
+ }
+ //
+ // end of if RelativeX/Y
+ //
+ } else {
+ //
+ // mouse is up
+ //
+ if (MouseDrag) {
+ if (HBufferImageGetTotalSize () == 0) {
+ HMainEditor.SelectStart = 0;
+ HMainEditor.SelectEnd = 0;
+ FirstDown = FALSE;
+ MouseDrag = FALSE;
+ }
+
+ if ((
+ (HBufferImage.BufferPosition.Row - 1) *
+ 0x10 +
+ HBufferImage.BufferPosition.Column
+ ) >= HMainEditor.SelectStart
+ ) {
+ HMainEditor.SelectEnd = (HBufferImage.BufferPosition.Row - 1) *
+ 0x10 +
+ HBufferImage.BufferPosition.Column;
+ } else {
+ HMainEditor.SelectEnd = 0;
+ }
+
+ if (HMainEditor.SelectEnd == 0) {
+ HMainEditor.SelectStart = 0;
+ }
+ }
+
+ FirstDown = FALSE;
+ MouseDrag = FALSE;
+ }
+
+ if (SelectStartBackup != HMainEditor.SelectStart || SelectEndBackup != HMainEditor.SelectEnd) {
+ if ((SelectStartBackup - 1) / 0x10 != (HMainEditor.SelectStart - 1) / 0x10) {
+ HBufferImageNeedRefresh = TRUE;
+ } else {
+ if ((SelectEndBackup - 1) / 0x10 != (HMainEditor.SelectEnd - 1) / 0x10) {
+ HBufferImageNeedRefresh = TRUE;
+ } else {
+ HBufferImageOnlyLineNeedRefresh = TRUE;
+ }
+ }
+ }
+ }
+
+ HEditorMouseAction = TRUE;
+ HBufferImageMouseNeedRefresh = TRUE;
+
+ } else if (Status == EFI_LOAD_ERROR) {
+ StatusBarSetStatusString (L"Invalid Mouse Movement ");
+ }
+ }
+ }
+
+ 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 (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) {
+ //
+ // 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 ();
+
+ switch (HBufferImage.BufferType) {
+ case FileTypeDiskBuffer:
+ OldSize = HBufferImage.DiskImage->Size * HBufferImage.DiskImage->BlockSize;
+ break;
+
+ case FileTypeMemBuffer:
+ OldSize = HBufferImage.MemImage->Size;
+ break;
+ }
+
+ if (LengthChange == FALSE) {
+ 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 ();
+
+ } while (Status != EFI_OUT_OF_RESOURCES && !HEditorExit);
+
+ return Status;
+}
+
+/**
+ Backup function for MainEditor.
+**/
+VOID
+EFIAPI
+HMainEditorBackup (
+ VOID
+ )
+{
+ HMainEditorBackupVar.SelectStart = HMainEditor.SelectStart;
+ HMainEditorBackupVar.SelectEnd = HMainEditor.SelectEnd;
+ HBufferImageBackup ();
+}