/** @file
    Defines the Main Editor data type -
     - Global variables
     - Instances of the other objects of the editor
     - Main Interfaces

  Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#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 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,
  {
    { 0,        0}
  },
  {
    0,
    0
  },
  NULL,
  FALSE,
  NULL,
  0,
  0,
  1,
  1
};

/**
  Help info that will be displayed.
**/
EFI_STRING_ID  HexMainMenuHelpInfo[] = {
  STRING_TOKEN (STR_HEXEDIT_HELP_TITLE),
  STRING_TOKEN (STR_HEXEDIT_HELP_BLANK),
  STRING_TOKEN (STR_HEXEDIT_HELP_LIST_TITLE),
  STRING_TOKEN (STR_HEXEDIT_HELP_DIV),
  STRING_TOKEN (STR_HEXEDIT_HELP_GO_TO_OFFSET),
  STRING_TOKEN (STR_HEXEDIT_HELP_SAVE_BUFFER),
  STRING_TOKEN (STR_HEXEDIT_HELP_EXIT),
  STRING_TOKEN (STR_HEXEDIT_HELP_SELECT_START),
  STRING_TOKEN (STR_HEXEDIT_HELP_SELECT_END),
  STRING_TOKEN (STR_HEXEDIT_HELP_CUT),
  STRING_TOKEN (STR_HEXEDIT_HELP_PASTE),
  STRING_TOKEN (STR_HEXEDIT_HELP_OPEN_FILE),
  STRING_TOKEN (STR_HEXEDIT_HELP_OPEN_DISK),
  STRING_TOKEN (STR_HEXEDIT_HELP_OPEN_MEMORY),
  STRING_TOKEN (STR_HEXEDIT_HELP_BLANK),
  STRING_TOKEN (STR_HEXEDIT_HELP_EXIT_HELP),
  STRING_TOKEN (STR_HEXEDIT_HELP_BLANK),
  STRING_TOKEN (STR_HEXEDIT_HELP_BLANK),
  STRING_TOKEN (STR_HEXEDIT_HELP_BLANK),
  STRING_TOKEN (STR_HEXEDIT_HELP_BLANK),
  STRING_TOKEN (STR_HEXEDIT_HELP_BLANK),
  STRING_TOKEN (STR_HEXEDIT_HELP_BLANK),
  STRING_TOKEN (STR_HEXEDIT_HELP_DIV),
  0
};

/**
  show help menu.

  @retval EFI_SUCCESS             The operation was successful.
**/
EFI_STATUS
HMainCommandDisplayHelp (
  VOID
  )
{
  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
                   );
    if (InfoString != NULL) {
      ShellPrintEx (0, CurrentLine+1, L"%E%s%N", InfoString);
    } else {
      ASSERT (FALSE);
    }
  }

  //
  // scan for ctrl+w
  //
  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) ||
        (KeyData.KeyState.KeyShiftState == EFI_SHIFT_STATE_VALID))
    {
      //
      // For consoles that don't support/report shift state,
      // 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_SHIFT_STATE_VALID) != 0) &&
               ((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/reports shift state,
      // 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;
  HBufferImageOnlyLineNeedRefresh = FALSE;
  HBufferImageRefresh ();

  return EFI_SUCCESS;
}

/**
  Move cursor to specified lines.

  @retval EFI_SUCCESS   The operation was successful.
**/
EFI_STATUS
HMainCommandGoToOffset (
  VOID
  )
{
  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;
}

/**
  Save current opened buffer.
  If is file buffer, you can save to current file name or
  save to another file name.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation occurred.
  @retval EFI_LOAD_ERROR          A load error occurred.
**/
EFI_STATUS
HMainCommandSaveBuffer (
  VOID
  )
{
  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) {
      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;

        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) {
      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;
}

/**
  Load a disk buffer editor.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation occurred.
  @retval EFI_LOAD_ERROR          A load error occurred.
**/
EFI_STATUS
HMainCommandSelectStart (
  VOID
  )
{
  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;
}

/**
  Load a disk buffer editor.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation occurred.
  @retval EFI_LOAD_ERROR          A load error occurred.
**/
EFI_STATUS
HMainCommandSelectEnd (
  VOID
  )
{
  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;
}

/**
  Cut current line to clipboard.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation occurred.
  @retval EFI_LOAD_ERROR          A load error occurred.
**/
EFI_STATUS
HMainCommandCut (
  VOID
  )
{
  UINTN       Index;
  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;
  }

  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;
}

/**
  Paste line to file buffer.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation occurred.
  @retval EFI_LOAD_ERROR          A load error occurred.
**/
EFI_STATUS
HMainCommandPaste (
  VOID
  )
{
  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;
}

/**
  Exit editor.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation occurred.
  @retval EFI_LOAD_ERROR          A load error occurred.
**/
EFI_STATUS
HMainCommandExit (
  VOID
  )
{
  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;
}

/**
  Load a file from disk to editor.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation occurred.
  @retval EFI_LOAD_ERROR          A load error occurred.
**/
EFI_STATUS
HMainCommandOpenFile (
  VOID
  )
{
  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,
            HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer ? HMainEditor.BufferImage->DiskImage->Offset : HMainEditor.BufferImage->BufferType == FileTypeMemBuffer ? HMainEditor.BufferImage->MemImage->Offset : 0,
            HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer ? HMainEditor.BufferImage->DiskImage->Size  : HMainEditor.BufferImage->BufferType == FileTypeMemBuffer ? HMainEditor.BufferImage->MemImage->Size  : 0
            );
          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;
}

/**
  Load a disk buffer editor.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation occurred.
  @retval EFI_LOAD_ERROR          A load error occurred.
  @retval EFI_NOT_FOUND           The disk was not found.
**/
EFI_STATUS
HMainCommandOpenDisk (
  VOID
  )
{
  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,
            HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer ? HMainEditor.BufferImage->DiskImage->Offset : HMainEditor.BufferImage->BufferType == FileTypeMemBuffer ? HMainEditor.BufferImage->MemImage->Offset : 0,
            HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer ? HMainEditor.BufferImage->DiskImage->Size  : HMainEditor.BufferImage->BufferType == FileTypeMemBuffer ? HMainEditor.BufferImage->MemImage->Size  : 0
            );
          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;
}

/**
  Load memory content to editor

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation occurred.
  @retval EFI_LOAD_ERROR          A load error occurred.
  @retval EFI_NOT_FOUND           The disk was not found.
**/
EFI_STATUS
HMainCommandOpenMemory (
  VOID
  )
{
  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,
            HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer ? HMainEditor.BufferImage->DiskImage->Offset : HMainEditor.BufferImage->BufferType == FileTypeMemBuffer ? HMainEditor.BufferImage->MemImage->Offset : 0,
            HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer ? HMainEditor.BufferImage->DiskImage->Size  : HMainEditor.BufferImage->BufferType == FileTypeMemBuffer ? HMainEditor.BufferImage->MemImage->Size  : 0
            );
          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;
}

MENU_ITEM_FUNCTION  HexMainControlBasedMenuFunctions[] = {
  NULL,
  NULL,                      /* Ctrl - A */
  NULL,                      /* Ctrl - B */
  NULL,                      /* Ctrl - C */
  HMainCommandSelectEnd,     /* Ctrl - D */
  HMainCommandDisplayHelp,   /* Ctrl - E */
  NULL,                      /* Ctrl - F */
  HMainCommandGoToOffset,    /* Ctrl - G */
  NULL,                      /* Ctrl - H */
  HMainCommandOpenDisk,      /* Ctrl - I */
  NULL,                      /* Ctrl - J */
  NULL,                      /* Ctrl - K */
  NULL,                      /* Ctrl - L */
  HMainCommandOpenMemory,    /* Ctrl - M */
  NULL,                      /* Ctrl - N */
  HMainCommandOpenFile,      /* Ctrl - O */
  NULL,                      /* Ctrl - P */
  HMainCommandExit,          /* Ctrl - Q */
  NULL,                      /* Ctrl - R */
  HMainCommandSaveBuffer,    /* Ctrl - S */
  HMainCommandSelectStart,   /* Ctrl - T */
  NULL,                      /* Ctrl - U */
  HMainCommandPaste,         /* Ctrl - V */
  NULL,                      /* Ctrl - W */
  HMainCommandCut,           /* Ctrl - X */
  NULL,                      /* Ctrl - Y */
  NULL,                      /* Ctrl - Z */
};

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
  }
};

/**
  Init function for MainEditor

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_LOAD_ERROR          A load error occurred.
**/
EFI_STATUS
HMainEditorInit (
  VOID
  )
{
  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 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
  //
  Status = gBS->HandleProtocol (
                  gST->ConsoleInHandle,
                  &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 (L"UEFI HEXEDIT");
  if (EFI_ERROR (Status)) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_TITLE), gShellDebug1HiiHandle);
    return EFI_LOAD_ERROR;
  }

  Status = ControlHotKeyInit (HexMainControlBasedMenuFunctions);
  if (EFI_ERROR (Status)) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_MAINMENU), 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 (HMainEditor.TextInputEx);

  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;
}

/**
  Cleanup function for MainEditor.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_LOAD_ERROR          A load error occurred.
**/
EFI_STATUS
HMainEditorCleanup (
  VOID
  )
{
  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;
}

/**
  Refresh function for MainEditor.

  @retval EFI_SUCCESS             The operation was successful.
**/
EFI_STATUS
HMainEditorRefresh (
  VOID
  )
{
  BOOLEAN  NameChange;
  BOOLEAN  ReadChange;

  NameChange = FALSE;
  ReadChange = FALSE;

  if (HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer) {
    if ((HMainEditor.BufferImage->DiskImage != NULL) &&
        (HBufferImageBackupVar.DiskImage != NULL) &&
        ((HMainEditor.BufferImage->DiskImage->Offset != HBufferImageBackupVar.DiskImage->Offset) ||
         (HMainEditor.BufferImage->DiskImage->Size != HBufferImageBackupVar.DiskImage->Size)))
    {
      NameChange = TRUE;
    }
  } else if (HMainEditor.BufferImage->BufferType == FileTypeMemBuffer) {
    if ((HMainEditor.BufferImage->MemImage != NULL) &&
        (HBufferImageBackupVar.MemImage != NULL) &&
        ((HMainEditor.BufferImage->MemImage->Offset != HBufferImageBackupVar.MemImage->Offset) ||
         (HMainEditor.BufferImage->MemImage->Size != HBufferImageBackupVar.MemImage->Size)))
    {
      NameChange = TRUE;
    }
  } else if (HMainEditor.BufferImage->BufferType == FileTypeFileBuffer) {
    if ((HMainEditor.BufferImage->FileImage != NULL) &&
        (HMainEditor.BufferImage->FileImage->FileName != NULL) &&
        (HBufferImageBackupVar.FileImage != NULL) &&
        (HBufferImageBackupVar.FileImage->FileName != NULL) &&
        (StrCmp (HMainEditor.BufferImage->FileImage->FileName, HBufferImageBackupVar.FileImage->FileName) != 0))
    {
      NameChange = TRUE;
    }
  }

  if ((HMainEditor.BufferImage->FileImage != NULL) &&
      (HBufferImageBackupVar.FileImage != NULL) &&
      (HMainEditor.BufferImage->FileImage->ReadOnly != HBufferImageBackupVar.FileImage->ReadOnly))
  {
    ReadChange = TRUE;
  }

  //
  // to aVOID screen flicker
  // the stall value is from experience
  //
  gBS->Stall (50);

  //
  // call the components refresh function
  //
  if (  HEditorFirst
     || NameChange
     || (HMainEditor.BufferImage->BufferType != HBufferImageBackupVar.BufferType)
     || (HBufferImageBackupVar.Modified != HMainEditor.BufferImage->Modified)
     || ReadChange )
  {
    MainTitleBarRefresh (
      HMainEditor.BufferImage->BufferType == FileTypeFileBuffer && HMainEditor.BufferImage->FileImage != NULL ? HMainEditor.BufferImage->FileImage->FileName : HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer && HMainEditor.BufferImage->DiskImage != NULL ? HMainEditor.BufferImage->DiskImage->Name : NULL,
      HMainEditor.BufferImage->BufferType,
      (BOOLEAN)(HMainEditor.BufferImage->FileImage != NULL ? HMainEditor.BufferImage->FileImage->ReadOnly : FALSE),
      HMainEditor.BufferImage->Modified,
      HMainEditor.ScreenSize.Column,
      HMainEditor.ScreenSize.Row,
      HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer && HMainEditor.BufferImage->DiskImage != NULL ? HMainEditor.BufferImage->DiskImage->Offset : HMainEditor.BufferImage->BufferType == FileTypeMemBuffer && HMainEditor.BufferImage->MemImage != NULL ? HMainEditor.BufferImage->MemImage->Offset : 0,
      HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer && HMainEditor.BufferImage->DiskImage != NULL ? HMainEditor.BufferImage->DiskImage->Size  : HMainEditor.BufferImage->BufferType == FileTypeMemBuffer && HMainEditor.BufferImage->MemImage != NULL ? HMainEditor.BufferImage->MemImage->Size  : 0
      );
    HBufferImageRefresh ();
  }

  if (  HEditorFirst
     || (HBufferImageBackupVar.DisplayPosition.Row != HMainEditor.BufferImage->DisplayPosition.Row)
     || (HBufferImageBackupVar.DisplayPosition.Column != HMainEditor.BufferImage->DisplayPosition.Column)
     || StatusBarGetRefresh ())
  {
    StatusBarRefresh (
      HEditorFirst,
      HMainEditor.ScreenSize.Row,
      HMainEditor.ScreenSize.Column,
      (UINTN)(-1),
      (UINTN)(-1),
      FALSE
      );
    HBufferImageRefresh ();
  }

  if (HEditorFirst) {
    HBufferImageRefresh ();
  }

  //
  // EditorFirst is now set to FALSE
  //
  HEditorFirst = FALSE;

  return EFI_SUCCESS;
}

/**
  Handle the mouse input.

  @param[in] MouseState             The current mouse state.
  @param[out] BeforeLeftButtonDown  helps with selections.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation occurred.
  @retval EFI_LOAD_ERROR          A load error occurred.
  @retval EFI_NOT_FOUND           The disk was not found.
**/
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) {
      Action = TRUE;
    }

    //
    // mouse up
    //
    *BeforeLeftButtonDown = FALSE;
  }

  if (Action) {
    return EFI_SUCCESS;
  }

  return EFI_NOT_FOUND;
}

/**
  Handle user key input. will route it to other components handle function.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation occurred.
  @retval EFI_LOAD_ERROR          A load error occurred.
**/
EFI_STATUS
HMainEditorKeyInput (
  VOID
  )
{
  EFI_KEY_DATA              KeyData;
  EFI_STATUS                Status;
  EFI_SIMPLE_POINTER_STATE  MouseState;
  BOOLEAN                   NoShiftState;
  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) {
            //
            // mouse down
            //
            if (MouseIsDown) {
              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) {
              if (FirstDown) {
                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 ");
        }
      }
    }

    //
    // CheckEvent() returns Success when non-partial key is pressed.
    //
    Status = gBS->CheckEvent (HMainEditor.TextInputEx->WaitForKeyEx);
    if (!EFI_ERROR (Status)) {
      Status = HMainEditor.TextInputEx->ReadKeyStrokeEx (HMainEditor.TextInputEx, &KeyData);
      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 ();
        //
        // 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");

          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;

            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 ();
  } while (Status != EFI_OUT_OF_RESOURCES && !HEditorExit);

  return Status;
}

/**
  Backup function for MainEditor.
**/
VOID
HMainEditorBackup (
  VOID
  )
{
  HMainEditorBackupVar.SelectStart = HMainEditor.SelectStart;
  HMainEditorBackupVar.SelectEnd   = HMainEditor.SelectEnd;
  HBufferImageBackup ();
}
