Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Samer El-Haj-Mahmoud elhaj@hp.com reviewed-by: jaben carsey <jaben.carsey@intel.com> git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14063 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			2323 lines
		
	
	
		
			64 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			2323 lines
		
	
	
		
			64 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
    Defines the Main Editor data type - 
 | 
						|
     - Global variables 
 | 
						|
     - Instances of the other objects of the editor
 | 
						|
     - Main Interfaces
 | 
						|
  
 | 
						|
  Copyright (c) 2005 - 2012, 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 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
 | 
						|
  },
 | 
						|
  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_INPUT_KEY  Key;
 | 
						|
 | 
						|
  CurrentLine = 0;
 | 
						|
  // print helpInfo      
 | 
						|
  for (CurrentLine = 0; 0 != HexMainMenuHelpInfo[CurrentLine]; CurrentLine++) {
 | 
						|
    InfoString = HiiGetString(gShellDebug1HiiHandle, HexMainMenuHelpInfo[CurrentLine]
 | 
						|
, NULL);
 | 
						|
    ShellPrintEx (0,CurrentLine+1,L"%E%s%N",InfoString);        
 | 
						|
  }
 | 
						|
  
 | 
						|
  // scan for ctrl+w
 | 
						|
  do {
 | 
						|
    gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
 | 
						|
  } while(SCAN_CONTROL_W != Key.UnicodeChar); 
 | 
						|
 | 
						|
  // 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 occured.
 | 
						|
  @retval EFI_LOAD_ERROR          A load error occured.
 | 
						|
**/
 | 
						|
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;
 | 
						|
        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) {
 | 
						|
      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 occured.
 | 
						|
  @retval EFI_LOAD_ERROR          A load error occured.
 | 
						|
**/
 | 
						|
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 occured.
 | 
						|
  @retval EFI_LOAD_ERROR          A load error occured.
 | 
						|
**/
 | 
						|
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 occured.
 | 
						|
  @retval EFI_LOAD_ERROR          A load error occured.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HMainCommandCut (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  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;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Paste line to file buffer.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The operation was successful.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    A memory allocation occured.
 | 
						|
  @retval EFI_LOAD_ERROR          A load error occured.
 | 
						|
**/
 | 
						|
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 occured.
 | 
						|
  @retval EFI_LOAD_ERROR          A load error occured.
 | 
						|
**/
 | 
						|
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 occured.
 | 
						|
  @retval EFI_LOAD_ERROR          A load error occured.
 | 
						|
**/
 | 
						|
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 occured.
 | 
						|
  @retval EFI_LOAD_ERROR          A load error occured.
 | 
						|
  @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 occured.
 | 
						|
  @retval EFI_LOAD_ERROR          A load error occured.
 | 
						|
  @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 occured.
 | 
						|
**/
 | 
						|
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 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 (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 ();
 | 
						|
 | 
						|
  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 occured.
 | 
						|
**/
 | 
						|
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 occured.
 | 
						|
  @retval EFI_LOAD_ERROR          A load error occured.
 | 
						|
  @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 occured.
 | 
						|
  @retval EFI_LOAD_ERROR          A load error occured.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HMainEditorKeyInput (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  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) {
 | 
						|
            //
 | 
						|
            // 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 ");
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
 | 
						|
    if (!EFI_ERROR (Status)) {
 | 
						|
      //
 | 
						|
      // dispatch to different components' key handling function
 | 
						|
      // so not everywhere has to set this variable
 | 
						|
      //
 | 
						|
      HBufferImageMouseNeedRefresh = TRUE;
 | 
						|
 | 
						|
      //
 | 
						|
      // clear previous status string
 | 
						|
      //
 | 
						|
      StatusBarSetRefresh();
 | 
						|
      if (EFI_SUCCESS == MenuBarDispatchControlHotKey(&Key)) {
 | 
						|
        Status = EFI_SUCCESS;
 | 
						|
      } else if (Key.ScanCode == SCAN_NULL) {
 | 
						|
        Status = HBufferImageHandleInput (&Key);
 | 
						|
      } else if (((Key.ScanCode >= SCAN_UP) && (Key.ScanCode <= SCAN_PAGE_DOWN))) {
 | 
						|
        Status = HBufferImageHandleInput (&Key);
 | 
						|
      } else if (((Key.ScanCode >= SCAN_F1) && Key.ScanCode <= (SCAN_F12))) {
 | 
						|
        Status = MenuBarDispatchFunctionKey (&Key);
 | 
						|
      } else {
 | 
						|
        StatusBarSetStatusString (L"Unknown Command");
 | 
						|
 | 
						|
        HBufferImageMouseNeedRefresh = FALSE;
 | 
						|
      }
 | 
						|
 | 
						|
      if (Status != EFI_SUCCESS && Status != EFI_OUT_OF_RESOURCES) {
 | 
						|
        //
 | 
						|
        // 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
 | 
						|
EFIAPI
 | 
						|
HMainEditorBackup (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  HMainEditorBackupVar.SelectStart  = HMainEditor.SelectStart;
 | 
						|
  HMainEditorBackupVar.SelectEnd    = HMainEditor.SelectEnd;
 | 
						|
  HBufferImageBackup ();
 | 
						|
}
 |