diff options
Diffstat (limited to 'ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit')
18 files changed, 7549 insertions, 7549 deletions
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/BufferImage.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/BufferImage.c index be77e31a40..3af53c516a 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/BufferImage.c +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/BufferImage.c @@ -1,2472 +1,2472 @@ -/** @file
- Defines HBufferImage - the view of the file that is visible at any point,
- as well as the event handlers for editing the file
-
- Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "HexEditor.h"
-
-extern EFI_HANDLE HImageHandleBackup;
-
-extern HEFI_EDITOR_FILE_IMAGE HFileImage;
-extern HEFI_EDITOR_DISK_IMAGE HDiskImage;
-extern HEFI_EDITOR_MEM_IMAGE HMemImage;
-
-extern HEFI_EDITOR_FILE_IMAGE HFileImageBackupVar;
-extern HEFI_EDITOR_DISK_IMAGE HDiskImageBackupVar;
-extern HEFI_EDITOR_MEM_IMAGE HMemImageBackupVar;
-
-extern BOOLEAN HEditorMouseAction;
-
-extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditor;
-extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditorBackupVar;
-
-HEFI_EDITOR_BUFFER_IMAGE HBufferImage;
-HEFI_EDITOR_BUFFER_IMAGE HBufferImageBackupVar;
-
-//
-// for basic initialization of HBufferImage
-//
-HEFI_EDITOR_BUFFER_IMAGE HBufferImageConst = {
- NULL,
- NULL,
- 0,
- NULL,
- {
- 0,
- 0
- },
- {
- 0,
- 0
- },
- {
- 0,
- 0
- },
- 0,
- TRUE,
- FALSE,
- FileTypeNone,
- NULL,
- NULL,
- NULL
-};
-
-//
-// the whole edit area needs to be refreshed
-//
-BOOLEAN HBufferImageNeedRefresh;
-
-//
-// only the current line in edit area needs to be refresh
-//
-BOOLEAN HBufferImageOnlyLineNeedRefresh;
-
-BOOLEAN HBufferImageMouseNeedRefresh;
-
-/**
- Initialization function for HBufferImage
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_LOAD_ERROR A load error occurred.
-**/
-EFI_STATUS
-HBufferImageInit (
- VOID
- )
-{
- EFI_STATUS Status;
-
- //
- // basically initialize the HBufferImage
- //
- CopyMem (&HBufferImage, &HBufferImageConst, sizeof (HBufferImage));
-
- //
- // INIT listhead
- //
- HBufferImage.ListHead = AllocateZeroPool (sizeof (LIST_ENTRY));
- if (HBufferImage.ListHead == NULL) {
- return EFI_LOAD_ERROR;
- }
-
- InitializeListHead (HBufferImage.ListHead);
-
- HBufferImage.DisplayPosition.Row = 2;
- HBufferImage.DisplayPosition.Column = 10;
- HBufferImage.MousePosition.Row = 2;
- HBufferImage.MousePosition.Column = 10;
-
- HBufferImage.FileImage = &HFileImage;
- HBufferImage.DiskImage = &HDiskImage;
- HBufferImage.MemImage = &HMemImage;
-
- HBufferImageNeedRefresh = FALSE;
- HBufferImageOnlyLineNeedRefresh = FALSE;
- HBufferImageMouseNeedRefresh = FALSE;
-
- HBufferImageBackupVar.FileImage = &HFileImageBackupVar;
- HBufferImageBackupVar.DiskImage = &HDiskImageBackupVar;
- HBufferImageBackupVar.MemImage = &HMemImageBackupVar;
-
- Status = HFileImageInit ();
- if (EFI_ERROR (Status)) {
- return EFI_LOAD_ERROR;
- }
-
- Status = HDiskImageInit ();
- if (EFI_ERROR (Status)) {
- return EFI_LOAD_ERROR;
- }
-
- Status = HMemImageInit ();
- if (EFI_ERROR (Status)) {
- return EFI_LOAD_ERROR;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Backup function for HBufferImage. Only a few fields need to be backup.
- This is for making the file buffer refresh as few as possible.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HBufferImageBackup (
- VOID
- )
-{
- HBufferImageBackupVar.MousePosition = HBufferImage.MousePosition;
-
- HBufferImageBackupVar.BufferPosition = HBufferImage.BufferPosition;
-
- HBufferImageBackupVar.Modified = HBufferImage.Modified;
-
- HBufferImageBackupVar.BufferType = HBufferImage.BufferType;
- HBufferImageBackupVar.LowVisibleRow = HBufferImage.LowVisibleRow;
- HBufferImageBackupVar.HighBits = HBufferImage.HighBits;
-
- //
- // three kinds of buffer supported
- // file buffer
- // disk buffer
- // memory buffer
- //
- switch (HBufferImage.BufferType) {
- case FileTypeFileBuffer:
- HFileImageBackup ();
- break;
-
- case FileTypeDiskBuffer:
- HDiskImageBackup ();
- break;
-
- case FileTypeMemBuffer:
- HMemImageBackup ();
- break;
-
- default:
- break;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Free all the lines in HBufferImage.
- Fields affected:
- Lines
- CurrentLine
- NumLines
- ListHead
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HBufferImageFreeLines (
- VOID
- )
-{
- HFreeLines (HBufferImage.ListHead, HBufferImage.Lines);
-
- HBufferImage.Lines = NULL;
- HBufferImage.CurrentLine = NULL;
- HBufferImage.NumLines = 0;
-
- return EFI_SUCCESS;
-}
-
-/**
- Cleanup function for HBufferImage
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HBufferImageCleanup (
- VOID
- )
-{
- EFI_STATUS Status;
-
- //
- // free all the lines
- //
- Status = HBufferImageFreeLines ();
-
- SHELL_FREE_NON_NULL (HBufferImage.ListHead);
- HBufferImage.ListHead = NULL;
-
- HFileImageCleanup ();
- HDiskImageCleanup ();
-
- return Status;
-}
-
-/**
- Print Line on Row
-
- @param[in] Line The lline to print.
- @param[in] Row The row on screen ( begin from 1 ).
- @param[in] FRow The FRow.
- @param[in] Orig The original color.
- @param[in] New The color to print with.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HBufferImagePrintLine (
- IN HEFI_EDITOR_LINE *Line,
- IN UINTN Row,
- IN UINTN FRow,
- IN HEFI_EDITOR_COLOR_UNION Orig,
- IN HEFI_EDITOR_COLOR_UNION New
-
- )
-{
- UINTN Index;
- UINTN Pos;
- BOOLEAN Selected;
- BOOLEAN BeNewColor;
- UINTN RowStart;
- UINTN RowEnd;
- UINTN ColStart;
- UINTN ColEnd;
-
- //
- // variable initialization
- //
- ColStart = 0;
- ColEnd = 0;
- Selected = FALSE;
-
- //
- // print the selected area in opposite color
- //
- if ((HMainEditor.SelectStart != 0) && (HMainEditor.SelectEnd != 0)) {
- RowStart = (HMainEditor.SelectStart - 1) / 0x10 + 1;
- RowEnd = (HMainEditor.SelectEnd - 1) / 0x10 + 1;
-
- ColStart = (HMainEditor.SelectStart - 1) % 0x10 + 1;
- ColEnd = (HMainEditor.SelectEnd - 1) % 0x10 + 1;
-
- if ((FRow >= RowStart) && (FRow <= RowEnd)) {
- Selected = TRUE;
- }
-
- if (FRow > RowStart) {
- ColStart = 1;
- }
-
- if (FRow < RowEnd) {
- ColEnd = 0x10;
- }
- }
-
- if (!HEditorMouseAction) {
- ShellPrintEx (
- 0,
- (INT32)Row - 1,
- L"%8X ",
- ((INT32)Row - 2 + HBufferImage.LowVisibleRow - 1) * 0x10
- );
- }
-
- for (Index = 0; Index < 0x08 && Index < Line->Size; Index++) {
- BeNewColor = FALSE;
-
- if (Selected) {
- if ((Index + 1 >= ColStart) && (Index + 1 <= ColEnd)) {
- BeNewColor = TRUE;
- }
- }
-
- if (BeNewColor) {
- gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F);
- } else {
- gST->ConOut->SetAttribute (gST->ConOut, Orig.Data & 0x7F);
- }
-
- Pos = 10 + (Index * 3);
- if (Line->Buffer[Index] < 0x10) {
- ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"0");
- Pos++;
- }
-
- if (Index < 0x07) {
- ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%x ", Line->Buffer[Index]);
- } else {
- ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%x ", Line->Buffer[Index]);
- }
- }
-
- gST->ConOut->SetAttribute (gST->ConOut, Orig.Data & 0x7F);
- while (Index < 0x08) {
- Pos = 10 + (Index * 3);
- ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" ");
- Index++;
- }
-
- while (Index < 0x10 && Index < Line->Size) {
- BeNewColor = FALSE;
-
- if (Selected) {
- if ((Index + 1 >= ColStart) && (Index + 1 <= ColEnd)) {
- BeNewColor = TRUE;
- }
- }
-
- if (BeNewColor) {
- gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F);
- } else {
- gST->ConOut->SetAttribute (gST->ConOut, Orig.Data & 0x7F);
- }
-
- Pos = 10 + (Index * 3) + 1;
- if (Line->Buffer[Index] < 0x10) {
- ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"0");
- Pos++;
- }
-
- ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%x ", Line->Buffer[Index]);
- Index++;
- }
-
- gST->ConOut->SetAttribute (gST->ConOut, Orig.Data & 0x7F);
- while (Index < 0x10) {
- Pos = 10 + (Index * 3) + 1;
- ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" ");
- Index++;
- }
-
- //
- // restore the original color
- //
- gST->ConOut->SetAttribute (gST->ConOut, Orig.Data & 0x7F);
-
- //
- // PRINT the buffer content
- //
- if (!HEditorMouseAction) {
- for (Index = 0; Index < 0x10 && Index < Line->Size; Index++) {
- Pos = ASCII_POSITION + Index;
-
- //
- // learned from shelle.h -- IsValidChar
- //
- if (Line->Buffer[Index] >= L' ') {
- ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%c", (CHAR16)Line->Buffer[Index]);
- } else {
- ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%c", '.');
- }
- }
-
- while (Index < 0x10) {
- Pos = ASCII_POSITION + Index;
- ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" ");
- Index++;
- }
- }
-
- //
- // restore the abundant blank in hex edit area to original color
- //
- if (Selected) {
- if (ColEnd <= 7) {
- Pos = 10 + (ColEnd - 1) * 3 + 2;
- ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" ");
- } else if (ColEnd == 8) {
- Pos = 10 + (ColEnd - 1) * 3 + 2;
- ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" ");
- } else {
- Pos = 10 + (ColEnd - 1) * 3 + 3;
- ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" ");
- }
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Function to decide if a column number is stored in the high bits.
-
- @param[in] Column The column to examine.
- @param[out] FCol The actual column number.
-
- @retval TRUE The actual column was in high bits and is now in FCol.
- @retval FALSE There was not a column number in the high bits.
-**/
-BOOLEAN
-HBufferImageIsAtHighBits (
- IN UINTN Column,
- OUT UINTN *FCol
- )
-{
- Column -= 10;
-
- //
- // NOW AFTER THE SUB, Column start from 0
- // 23 AND 24 ARE BOTH BLANK
- //
- if (Column == 24) {
- *FCol = 0;
- return FALSE;
- }
-
- if (Column > 24) {
- Column--;
- }
-
- *FCol = (Column / 3) + 1;
-
- if (Column % 3 == 0) {
- return TRUE;
- }
-
- if ((Column % 3 == 2)) {
- *FCol = 0;
- }
-
- return FALSE;
-}
-
-/**
- Decide if a point is in the already selected area.
-
- @param[in] MouseRow The row of the point to test.
- @param[in] MouseCol The col of the point to test.
-
- @retval TRUE The point is in the selected area.
- @retval FALSE The point is not in the selected area.
-**/
-BOOLEAN
-HBufferImageIsInSelectedArea (
- IN UINTN MouseRow,
- IN UINTN MouseCol
- )
-{
- UINTN FRow;
- UINTN RowStart;
- UINTN RowEnd;
- UINTN ColStart;
- UINTN ColEnd;
- UINTN MouseColStart;
- UINTN MouseColEnd;
-
- //
- // judge mouse position whether is in selected area
- //
- //
- // not select
- //
- if ((HMainEditor.SelectStart == 0) || (HMainEditor.SelectEnd == 0)) {
- return FALSE;
- }
-
- //
- // calculate the select area
- //
- RowStart = (HMainEditor.SelectStart - 1) / 0x10 + 1;
- RowEnd = (HMainEditor.SelectEnd - 1) / 0x10 + 1;
-
- ColStart = (HMainEditor.SelectStart - 1) % 0x10 + 1;
- ColEnd = (HMainEditor.SelectEnd - 1) % 0x10 + 1;
-
- FRow = HBufferImage.LowVisibleRow + MouseRow - 2;
- if ((FRow < RowStart) || (FRow > RowEnd)) {
- return FALSE;
- }
-
- if (FRow > RowStart) {
- ColStart = 1;
- }
-
- if (FRow < RowEnd) {
- ColEnd = 0x10;
- }
-
- MouseColStart = 10 + (ColStart - 1) * 3;
- if (ColStart > 8) {
- MouseColStart++;
- }
-
- MouseColEnd = 10 + (ColEnd - 1) * 3 + 1;
- if (ColEnd > 8) {
- MouseColEnd++;
- }
-
- if ((MouseCol < MouseColStart) || (MouseCol > MouseColEnd)) {
- return FALSE;
- }
-
- return TRUE;
-}
-
-/**
- Set mouse position according to HBufferImage.MousePosition.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HBufferImageRestoreMousePosition (
- VOID
- )
-{
- HEFI_EDITOR_COLOR_UNION Orig;
- HEFI_EDITOR_COLOR_UNION New;
- UINTN FRow;
- UINTN FColumn;
- BOOLEAN HasCharacter;
- HEFI_EDITOR_LINE *CurrentLine;
- HEFI_EDITOR_LINE *Line;
- UINT8 Value;
- BOOLEAN HighBits;
-
- Line = NULL;
- if (HMainEditor.MouseSupported) {
- if (HBufferImageMouseNeedRefresh) {
- HBufferImageMouseNeedRefresh = FALSE;
-
- //
- // if mouse position not moved and only mouse action
- // so do not need to refresh mouse position
- //
- if ((
- (HBufferImage.MousePosition.Row == HBufferImageBackupVar.MousePosition.Row) &&
- (HBufferImage.MousePosition.Column == HBufferImageBackupVar.MousePosition.Column)
- ) &&
- HEditorMouseAction
- )
- {
- return EFI_SUCCESS;
- }
-
- //
- // backup the old screen attributes
- //
- Orig = HMainEditor.ColorAttributes;
- New.Data = 0;
- New.Colors.Foreground = Orig.Colors.Background & 0xF;
- New.Colors.Background = Orig.Colors.Foreground & 0x7;
-
- //
- // if in selected area,
- // so do not need to refresh mouse
- //
- if (!HBufferImageIsInSelectedArea (
- HBufferImageBackupVar.MousePosition.Row,
- HBufferImageBackupVar.MousePosition.Column
- ))
- {
- gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);
- } else {
- gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F);
- }
-
- //
- // clear the old mouse position
- //
- FRow = HBufferImage.LowVisibleRow + HBufferImageBackupVar.MousePosition.Row - 2;
-
- HighBits = HBufferImageIsAtHighBits (
- HBufferImageBackupVar.MousePosition.Column,
- &FColumn
- );
-
- HasCharacter = TRUE;
- if ((FRow > HBufferImage.NumLines) || (FColumn == 0)) {
- HasCharacter = FALSE;
- } else {
- CurrentLine = HBufferImage.CurrentLine;
- Line = HMoveLine (FRow - HBufferImage.BufferPosition.Row);
-
- if ((Line == NULL) || (FColumn > Line->Size)) {
- HasCharacter = FALSE;
- }
-
- HBufferImage.CurrentLine = CurrentLine;
- }
-
- ShellPrintEx (
- (INT32)HBufferImageBackupVar.MousePosition.Column - 1,
- (INT32)HBufferImageBackupVar.MousePosition.Row - 1,
- L" "
- );
-
- if (HasCharacter) {
- if (HighBits) {
- Value = (UINT8)(Line->Buffer[FColumn - 1] & 0xf0);
- Value = (UINT8)(Value >> 4);
- } else {
- Value = (UINT8)(Line->Buffer[FColumn - 1] & 0xf);
- }
-
- ShellPrintEx (
- (INT32)HBufferImageBackupVar.MousePosition.Column - 1,
- (INT32)HBufferImageBackupVar.MousePosition.Row - 1,
- L"%x",
- Value
- );
- }
-
- if (!HBufferImageIsInSelectedArea (
- HBufferImage.MousePosition.Row,
- HBufferImage.MousePosition.Column
- ))
- {
- gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F);
- } else {
- gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);
- }
-
- //
- // clear the old mouse position
- //
- FRow = HBufferImage.LowVisibleRow + HBufferImage.MousePosition.Row - 2;
-
- HighBits = HBufferImageIsAtHighBits (
- HBufferImage.MousePosition.Column,
- &FColumn
- );
-
- HasCharacter = TRUE;
- if ((FRow > HBufferImage.NumLines) || (FColumn == 0)) {
- HasCharacter = FALSE;
- } else {
- CurrentLine = HBufferImage.CurrentLine;
- Line = HMoveLine (FRow - HBufferImage.BufferPosition.Row);
-
- if ((Line == NULL) || (FColumn > Line->Size)) {
- HasCharacter = FALSE;
- }
-
- HBufferImage.CurrentLine = CurrentLine;
- }
-
- ShellPrintEx (
- (INT32)HBufferImage.MousePosition.Column - 1,
- (INT32)HBufferImage.MousePosition.Row - 1,
- L" "
- );
-
- if (HasCharacter) {
- if (HighBits) {
- Value = (UINT8)(Line->Buffer[FColumn - 1] & 0xf0);
- Value = (UINT8)(Value >> 4);
- } else {
- Value = (UINT8)(Line->Buffer[FColumn - 1] & 0xf);
- }
-
- ShellPrintEx (
- (INT32)HBufferImage.MousePosition.Column - 1,
- (INT32)HBufferImage.MousePosition.Row - 1,
- L"%x",
- Value
- );
- }
-
- //
- // end of HasCharacter
- //
- gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);
- }
-
- //
- // end of MouseNeedRefresh
- //
- }
-
- //
- // end of MouseSupported
- //
- return EFI_SUCCESS;
-}
-
-/**
- Set cursor position according to HBufferImage.DisplayPosition.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HBufferImageRestorePosition (
- VOID
- )
-{
- //
- // set cursor position
- //
- gST->ConOut->SetCursorPosition (
- gST->ConOut,
- HBufferImage.DisplayPosition.Column - 1,
- HBufferImage.DisplayPosition.Row - 1
- );
-
- return EFI_SUCCESS;
-}
-
-/**
- Refresh function for HBufferImage.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_LOAD_ERROR A Load error occurred.
-
-**/
-EFI_STATUS
-HBufferImageRefresh (
- VOID
- )
-{
- LIST_ENTRY *Link;
- HEFI_EDITOR_LINE *Line;
- UINTN Row;
- HEFI_EDITOR_COLOR_UNION Orig;
- HEFI_EDITOR_COLOR_UNION New;
-
- UINTN StartRow;
- UINTN EndRow;
- UINTN FStartRow;
- UINTN Tmp;
-
- Orig = HMainEditor.ColorAttributes;
- New.Data = 0;
- New.Colors.Foreground = Orig.Colors.Background;
- New.Colors.Background = Orig.Colors.Foreground;
-
- //
- // if it's the first time after editor launch, so should refresh
- //
- if (HEditorFirst == FALSE) {
- //
- // no definite required refresh
- // and file position displayed on screen has not been changed
- //
- if (!HBufferImageNeedRefresh &&
- !HBufferImageOnlyLineNeedRefresh &&
- (HBufferImageBackupVar.LowVisibleRow == HBufferImage.LowVisibleRow)
- )
- {
- HBufferImageRestoreMousePosition ();
- HBufferImageRestorePosition ();
- return EFI_SUCCESS;
- }
- }
-
- gST->ConOut->EnableCursor (gST->ConOut, FALSE);
-
- //
- // only need to refresh current line
- //
- if (HBufferImageOnlyLineNeedRefresh && (HBufferImageBackupVar.LowVisibleRow == HBufferImage.LowVisibleRow)) {
- HBufferImagePrintLine (
- HBufferImage.CurrentLine,
- HBufferImage.DisplayPosition.Row,
- HBufferImage.BufferPosition.Row,
- Orig,
- New
- );
- } else {
- //
- // the whole edit area need refresh
- //
- if (HEditorMouseAction && (HMainEditor.SelectStart != 0) && (HMainEditor.SelectEnd != 0)) {
- if (HMainEditor.SelectStart != HMainEditorBackupVar.SelectStart) {
- if ((HMainEditor.SelectStart >= HMainEditorBackupVar.SelectStart) && (HMainEditorBackupVar.SelectStart != 0)) {
- StartRow = (HMainEditorBackupVar.SelectStart - 1) / 0x10 + 1;
- } else {
- StartRow = (HMainEditor.SelectStart - 1) / 0x10 + 1;
- }
- } else {
- StartRow = (HMainEditor.SelectStart - 1) / 0x10 + 1;
- }
-
- if (HMainEditor.SelectEnd <= HMainEditorBackupVar.SelectEnd) {
- EndRow = (HMainEditorBackupVar.SelectEnd - 1) / 0x10 + 1;
- } else {
- EndRow = (HMainEditor.SelectEnd - 1) / 0x10 + 1;
- }
-
- //
- // swap
- //
- if (StartRow > EndRow) {
- Tmp = StartRow;
- StartRow = EndRow;
- EndRow = Tmp;
- }
-
- FStartRow = StartRow;
-
- StartRow = 2 + StartRow - HBufferImage.LowVisibleRow;
- EndRow = 2 + EndRow - HBufferImage.LowVisibleRow;
- } else {
- //
- // not mouse selection actions
- //
- FStartRow = HBufferImage.LowVisibleRow;
- StartRow = 2;
- EndRow = (HMainEditor.ScreenSize.Row - 1);
- }
-
- //
- // no line
- //
- if (HBufferImage.Lines == NULL) {
- HBufferImageRestoreMousePosition ();
- HBufferImageRestorePosition ();
- gST->ConOut->EnableCursor (gST->ConOut, TRUE);
- return EFI_SUCCESS;
- }
-
- //
- // get the first line that will be displayed
- //
- Line = HMoveLine (FStartRow - HBufferImage.BufferPosition.Row);
- if (Line == NULL) {
- gST->ConOut->EnableCursor (gST->ConOut, TRUE);
- return EFI_LOAD_ERROR;
- }
-
- Link = &(Line->Link);
- Row = StartRow;
- do {
- Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
-
- //
- // print line at row
- //
- HBufferImagePrintLine (
- Line,
- Row,
- HBufferImage.LowVisibleRow + Row - 2,
- Orig,
- New
- );
-
- Link = Link->ForwardLink;
- Row++;
- } while (Link != HBufferImage.ListHead && Row <= EndRow);
-
- while (Row <= EndRow) {
- EditorClearLine (Row, HMainEditor.ScreenSize.Column, HMainEditor.ScreenSize.Row);
- Row++;
- }
-
- //
- // while not file end and not screen full
- //
- }
-
- HBufferImageRestoreMousePosition ();
- HBufferImageRestorePosition ();
-
- HBufferImageNeedRefresh = FALSE;
- HBufferImageOnlyLineNeedRefresh = FALSE;
- gST->ConOut->EnableCursor (gST->ConOut, TRUE);
-
- return EFI_SUCCESS;
-}
-
-/**
- Read an image into a buffer friom a source.
-
- @param[in] FileName Pointer to the file name. OPTIONAL and ignored if not FileTypeFileBuffer.
- @param[in] DiskName Pointer to the disk name. OPTIONAL and ignored if not FileTypeDiskBuffer.
- @param[in] DiskOffset Offset into the disk. OPTIONAL and ignored if not FileTypeDiskBuffer.
- @param[in] DiskSize Size of the disk buffer. OPTIONAL and ignored if not FileTypeDiskBuffer.
- @param[in] MemOffset Offset into the Memory. OPTIONAL and ignored if not FileTypeMemBuffer.
- @param[in] MemSize Size of the Memory buffer. OPTIONAL and ignored if not FileTypeMemBuffer.
- @param[in] BufferType The type of buffer to save. IGNORED.
- @param[in] Recover TRUE for recovermode, FALSE otherwise.
-
- @return EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HBufferImageRead (
- IN CONST CHAR16 *FileName,
- IN CONST CHAR16 *DiskName,
- IN UINTN DiskOffset,
- IN UINTN DiskSize,
- IN UINTN MemOffset,
- IN UINTN MemSize,
- IN EDIT_FILE_TYPE BufferType,
- IN BOOLEAN Recover
- )
-{
- EFI_STATUS Status;
- EDIT_FILE_TYPE BufferTypeBackup;
-
- //
- // variable initialization
- //
- Status = EFI_SUCCESS;
- HBufferImage.BufferType = BufferType;
-
- //
- // three types of buffer supported
- // file buffer
- // disk buffer
- // memory buffer
- //
- BufferTypeBackup = HBufferImage.BufferType;
-
- switch (BufferType) {
- case FileTypeFileBuffer:
- Status = HFileImageRead (FileName, Recover);
- break;
-
- case FileTypeDiskBuffer:
- Status = HDiskImageRead (DiskName, DiskOffset, DiskSize, Recover);
- break;
-
- case FileTypeMemBuffer:
- Status = HMemImageRead (MemOffset, MemSize, Recover);
- break;
-
- default:
- Status = EFI_NOT_FOUND;
- break;
- }
-
- if (EFI_ERROR (Status)) {
- HBufferImage.BufferType = BufferTypeBackup;
- }
-
- return Status;
-}
-
-/**
- Save the current image.
-
- @param[in] FileName Pointer to the file name. OPTIONAL and ignored if not FileTypeFileBuffer.
- @param[in] DiskName Pointer to the disk name. OPTIONAL and ignored if not FileTypeDiskBuffer.
- @param[in] DiskOffset Offset into the disk. OPTIONAL and ignored if not FileTypeDiskBuffer.
- @param[in] DiskSize Size of the disk buffer. OPTIONAL and ignored if not FileTypeDiskBuffer.
- @param[in] MemOffset Offset into the Memory. OPTIONAL and ignored if not FileTypeMemBuffer.
- @param[in] MemSize Size of the Memory buffer. OPTIONAL and ignored if not FileTypeMemBuffer.
- @param[in] BufferType The type of buffer to save. IGNORED.
-
- @return EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HBufferImageSave (
- IN CHAR16 *FileName,
- IN CHAR16 *DiskName,
- IN UINTN DiskOffset,
- IN UINTN DiskSize,
- IN UINTN MemOffset,
- IN UINTN MemSize,
- IN EDIT_FILE_TYPE BufferType
- )
-{
- EFI_STATUS Status;
- EDIT_FILE_TYPE BufferTypeBackup;
-
- //
- // variable initialization
- //
- Status = EFI_SUCCESS;
- BufferTypeBackup = HBufferImage.BufferType;
-
- switch (HBufferImage.BufferType) {
- //
- // file buffer
- //
- case FileTypeFileBuffer:
- Status = HFileImageSave (FileName);
- break;
-
- //
- // disk buffer
- //
- case FileTypeDiskBuffer:
- Status = HDiskImageSave (DiskName, DiskOffset, DiskSize);
- break;
-
- //
- // memory buffer
- //
- case FileTypeMemBuffer:
- Status = HMemImageSave (MemOffset, MemSize);
- break;
-
- default:
- Status = EFI_NOT_FOUND;
- break;
- }
-
- if (EFI_ERROR (Status)) {
- HBufferImage.BufferType = BufferTypeBackup;
- }
-
- return Status;
-}
-
-/**
- Create a new line and append it to the line list.
- Fields affected:
- NumLines
- Lines
-
- @retval NULL create line failed.
- @return the line created.
-
-**/
-HEFI_EDITOR_LINE *
-HBufferImageCreateLine (
- VOID
- )
-{
- HEFI_EDITOR_LINE *Line;
-
- //
- // allocate for line structure
- //
- Line = AllocateZeroPool (sizeof (HEFI_EDITOR_LINE));
- if (Line == NULL) {
- return NULL;
- }
-
- Line->Signature = EFI_EDITOR_LINE_LIST;
- Line->Size = 0;
-
- HBufferImage.NumLines++;
-
- //
- // insert to line list
- //
- InsertTailList (HBufferImage.ListHead, &Line->Link);
-
- if (HBufferImage.Lines == NULL) {
- HBufferImage.Lines = CR (
- HBufferImage.ListHead->ForwardLink,
- HEFI_EDITOR_LINE,
- Link,
- EFI_EDITOR_LINE_LIST
- );
- }
-
- return Line;
-}
-
-/**
- Free the current image.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HBufferImageFree (
- VOID
- )
-{
- //
- // free all lines
- //
- HBufferImageFreeLines ();
-
- return EFI_SUCCESS;
-}
-
-/**
- change char to int value based on Hex.
-
- @param[in] Char The input char.
-
- @return The character's index value.
- @retval -1 The operation failed.
-**/
-INTN
-HBufferImageCharToHex (
- IN CHAR16 Char
- )
-{
- //
- // change the character to hex
- //
- if ((Char >= L'0') && (Char <= L'9')) {
- return (Char - L'0');
- }
-
- if ((Char >= L'a') && (Char <= L'f')) {
- return (Char - L'a' + 10);
- }
-
- if ((Char >= L'A') && (Char <= L'F')) {
- return (Char - L'A' + 10);
- }
-
- return -1;
-}
-
-/**
- Add character.
-
- @param[in] Char -- input char.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
-**/
-EFI_STATUS
-HBufferImageAddChar (
- IN CHAR16 Char
- )
-{
- HEFI_EDITOR_LINE *Line;
- HEFI_EDITOR_LINE *NewLine;
- INTN Value;
- UINT8 Old;
- UINTN FRow;
- UINTN FCol;
- BOOLEAN High;
-
- Value = HBufferImageCharToHex (Char);
-
- //
- // invalid input
- //
- if (Value == -1) {
- return EFI_SUCCESS;
- }
-
- Line = HBufferImage.CurrentLine;
- FRow = HBufferImage.BufferPosition.Row;
- FCol = HBufferImage.BufferPosition.Column;
- High = HBufferImage.HighBits;
-
- //
- // only needs to refresh current line
- //
- HBufferImageOnlyLineNeedRefresh = TRUE;
-
- //
- // not a full line and beyond the last character
- //
- if (FCol > Line->Size) {
- //
- // cursor always at high 4 bits
- // and always put input to the low 4 bits
- //
- Line->Buffer[Line->Size] = (UINT8)Value;
- Line->Size++;
- High = FALSE;
- } else {
- Old = Line->Buffer[FCol - 1];
-
- //
- // always put the input to the low 4 bits
- //
- Old = (UINT8)(Old & 0x0f);
- Old = (UINT8)(Old << 4);
- Old = (UINT8)(Value + Old);
- Line->Buffer[FCol - 1] = Old;
-
- //
- // at the low 4 bits of the last character of a full line
- // so if no next line, need to create a new line
- //
- if (!High && (FCol == 0x10)) {
- HBufferImageOnlyLineNeedRefresh = FALSE;
- HBufferImageNeedRefresh = TRUE;
-
- if (Line->Link.ForwardLink == HBufferImage.ListHead) {
- //
- // last line
- //
- // create a new line
- //
- NewLine = HBufferImageCreateLine ();
- if (NewLine == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // end of NULL
- //
- }
-
- //
- // end of == ListHead
- //
- }
-
- //
- // end of == 0x10
- //
- // if already at end of this line, scroll it to the start of next line
- //
- if ((FCol == 0x10) && !High) {
- //
- // definitely has next line
- //
- FRow++;
- FCol = 1;
- High = TRUE;
- } else {
- //
- // if not at end of this line, just move to next column
- //
- if (!High) {
- FCol++;
- }
-
- if (High) {
- High = FALSE;
- } else {
- High = TRUE;
- }
- }
-
- //
- // end of ==FALSE
- //
- }
-
- //
- // move cursor to right
- //
- HBufferImageMovePosition (FRow, FCol, High);
-
- if (!HBufferImage.Modified) {
- HBufferImage.Modified = TRUE;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Delete the previous character.
-
- @retval EFI_SUCCESS The operationw as successful.
-**/
-EFI_STATUS
-HBufferImageDoBackspace (
- VOID
- )
-{
- HEFI_EDITOR_LINE *Line;
-
- UINTN FileColumn;
- UINTN FPos;
- BOOLEAN LastLine;
-
- //
- // variable initialization
- //
- LastLine = FALSE;
-
- //
- // already the first character
- //
- if ((HBufferImage.BufferPosition.Row == 1) && (HBufferImage.BufferPosition.Column == 1)) {
- return EFI_SUCCESS;
- }
-
- FPos = (HBufferImage.BufferPosition.Row - 1) * 0x10 + HBufferImage.BufferPosition.Column - 1;
-
- FileColumn = HBufferImage.BufferPosition.Column;
-
- Line = HBufferImage.CurrentLine;
- LastLine = FALSE;
- if ((Line->Link.ForwardLink == HBufferImage.ListHead) && (FileColumn > 1)) {
- LastLine = TRUE;
- }
-
- HBufferImageDeleteCharacterFromBuffer (FPos - 1, 1, NULL);
-
- //
- // if is the last line
- // then only this line need to be refreshed
- //
- if (LastLine) {
- HBufferImageNeedRefresh = FALSE;
- HBufferImageOnlyLineNeedRefresh = TRUE;
- } else {
- HBufferImageNeedRefresh = TRUE;
- HBufferImageOnlyLineNeedRefresh = FALSE;
- }
-
- if (!HBufferImage.Modified) {
- HBufferImage.Modified = TRUE;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- ASCII key + Backspace + return.
-
- @param[in] Char The input char.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_LOAD_ERROR A load error occurred.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
-**/
-EFI_STATUS
-HBufferImageDoCharInput (
- IN CHAR16 Char
- )
-{
- EFI_STATUS Status;
-
- Status = EFI_SUCCESS;
-
- switch (Char) {
- case 0:
- break;
-
- case 0x08:
- Status = HBufferImageDoBackspace ();
- break;
-
- case 0x09:
- case 0x0a:
- case 0x0d:
- //
- // Tabs, Returns are thought as nothing
- //
- break;
-
- default:
- //
- // DEAL WITH ASCII CHAR, filter out thing like ctrl+f
- //
- if ((Char > 127) || (Char < 32)) {
- Status = StatusBarSetStatusString (L"Unknown Command");
- } else {
- Status = HBufferImageAddChar (Char);
- }
-
- break;
- }
-
- return Status;
-}
-
-/**
- Check user specified FileRow is above current screen.
-
- @param[in] FileRow Row of file position ( start from 1 ).
-
- @retval TRUE It is above the current screen.
- @retval FALSE It is not above the current screen.
-
-**/
-BOOLEAN
-HAboveCurrentScreen (
- IN UINTN FileRow
- )
-{
- if (FileRow < HBufferImage.LowVisibleRow) {
- return TRUE;
- }
-
- return FALSE;
-}
-
-/**
- Check user specified FileRow is under current screen.
-
- @param[in] FileRow Row of file position ( start from 1 ).
-
- @retval TRUE It is under the current screen.
- @retval FALSE It is not under the current screen.
-
-**/
-BOOLEAN
-HUnderCurrentScreen (
- IN UINTN FileRow
- )
-{
- if (FileRow > HBufferImage.LowVisibleRow + (HMainEditor.ScreenSize.Row - 2) - 1) {
- return TRUE;
- }
-
- return FALSE;
-}
-
-/**
- According to cursor's file position, adjust screen display.
-
- @param[in] NewFilePosRow Row of file position ( start from 1 ).
- @param[in] NewFilePosCol Column of file position ( start from 1 ).
- @param[in] HighBits Cursor will on high4 bits or low4 bits.
-**/
-VOID
-HBufferImageMovePosition (
- IN UINTN NewFilePosRow,
- IN UINTN NewFilePosCol,
- IN BOOLEAN HighBits
- )
-{
- INTN RowGap;
- UINTN Abs;
- BOOLEAN Above;
- BOOLEAN Under;
- UINTN NewDisplayCol;
-
- //
- // CALCULATE gap between current file position and new file position
- //
- RowGap = NewFilePosRow - HBufferImage.BufferPosition.Row;
-
- Under = HUnderCurrentScreen (NewFilePosRow);
- Above = HAboveCurrentScreen (NewFilePosRow);
-
- HBufferImage.HighBits = HighBits;
-
- //
- // if is below current screen
- //
- if (Under) {
- //
- // display row will be unchanged
- //
- HBufferImage.BufferPosition.Row = NewFilePosRow;
- } else {
- if (Above) {
- //
- // has enough above line, so display row unchanged
- // not has enough above lines, so the first line is
- // at the first display line
- //
- if (NewFilePosRow < (HBufferImage.DisplayPosition.Row - 2 + 1)) {
- HBufferImage.DisplayPosition.Row = NewFilePosRow + 2 - 1;
- }
-
- HBufferImage.BufferPosition.Row = NewFilePosRow;
- } else {
- //
- // in current screen
- //
- HBufferImage.BufferPosition.Row = NewFilePosRow;
- if (RowGap <= 0) {
- Abs = (UINTN)ABS (RowGap);
- HBufferImage.DisplayPosition.Row -= Abs;
- } else {
- HBufferImage.DisplayPosition.Row += RowGap;
- }
- }
- }
-
- HBufferImage.LowVisibleRow = HBufferImage.BufferPosition.Row - (HBufferImage.DisplayPosition.Row - 2);
-
- //
- // always in current screen
- //
- HBufferImage.BufferPosition.Column = NewFilePosCol;
-
- NewDisplayCol = 10 + (NewFilePosCol - 1) * 3;
- if (NewFilePosCol > 0x8) {
- NewDisplayCol++;
- }
-
- if (!HighBits) {
- NewDisplayCol++;
- }
-
- HBufferImage.DisplayPosition.Column = NewDisplayCol;
-
- //
- // let CurrentLine point to correct line;
- //
- HBufferImage.CurrentLine = HMoveCurrentLine (RowGap);
-}
-
-/**
- Scroll cursor to right.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HBufferImageScrollRight (
- VOID
- )
-{
- HEFI_EDITOR_LINE *Line;
- UINTN FRow;
- UINTN FCol;
-
- //
- // scroll right will always move to the high4 bits of the next character
- //
- HBufferImageNeedRefresh = FALSE;
- HBufferImageOnlyLineNeedRefresh = FALSE;
-
- Line = HBufferImage.CurrentLine;
-
- FRow = HBufferImage.BufferPosition.Row;
- FCol = HBufferImage.BufferPosition.Column;
-
- //
- // this line is not full and no next line
- //
- if (FCol > Line->Size) {
- return EFI_SUCCESS;
- }
-
- //
- // if already at end of this line, scroll it to the start of next line
- //
- if (FCol == 0x10) {
- //
- // has next line
- //
- if (Line->Link.ForwardLink != HBufferImage.ListHead) {
- FRow++;
- FCol = 1;
- } else {
- return EFI_SUCCESS;
- }
- } else {
- //
- // if not at end of this line, just move to next column
- //
- FCol++;
- }
-
- HBufferImageMovePosition (FRow, FCol, TRUE);
-
- return EFI_SUCCESS;
-}
-
-/**
- Scroll cursor to left.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HBufferImageScrollLeft (
- VOID
- )
-{
- HEFI_EDITOR_LINE *Line;
- UINTN FRow;
- UINTN FCol;
-
- HBufferImageNeedRefresh = FALSE;
- HBufferImageOnlyLineNeedRefresh = FALSE;
-
- Line = HBufferImage.CurrentLine;
-
- FRow = HBufferImage.BufferPosition.Row;
- FCol = HBufferImage.BufferPosition.Column;
-
- //
- // if already at start of this line, so move to the end of previous line
- //
- if (FCol <= 1) {
- //
- // has previous line
- //
- if (Line->Link.BackLink != HBufferImage.ListHead) {
- FRow--;
- Line = CR (Line->Link.BackLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
- FCol = Line->Size;
- } else {
- return EFI_SUCCESS;
- }
- } else {
- //
- // if not at start of this line, just move to previous column
- //
- FCol--;
- }
-
- HBufferImageMovePosition (FRow, FCol, TRUE);
-
- return EFI_SUCCESS;
-}
-
-/**
- Scroll cursor to the next line
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HBufferImageScrollDown (
- VOID
- )
-{
- HEFI_EDITOR_LINE *Line;
- UINTN FRow;
- UINTN FCol;
- BOOLEAN HighBits;
-
- Line = HBufferImage.CurrentLine;
-
- FRow = HBufferImage.BufferPosition.Row;
- FCol = HBufferImage.BufferPosition.Column;
- HighBits = HBufferImage.HighBits;
-
- //
- // has next line
- //
- if (Line->Link.ForwardLink != HBufferImage.ListHead) {
- FRow++;
- Line = CR (Line->Link.ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
-
- //
- // if the next line is not that long, so move to end of next line
- //
- if (FCol > Line->Size) {
- FCol = Line->Size + 1;
- HighBits = TRUE;
- }
- } else {
- return EFI_SUCCESS;
- }
-
- HBufferImageMovePosition (FRow, FCol, HighBits);
-
- return EFI_SUCCESS;
-}
-
-/**
- Scroll cursor to previous line
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HBufferImageScrollUp (
- VOID
- )
-{
- HEFI_EDITOR_LINE *Line;
- UINTN FRow;
- UINTN FCol;
-
- Line = HBufferImage.CurrentLine;
-
- FRow = HBufferImage.BufferPosition.Row;
- FCol = HBufferImage.BufferPosition.Column;
-
- //
- // has previous line
- //
- if (Line->Link.BackLink != HBufferImage.ListHead) {
- FRow--;
- } else {
- return EFI_SUCCESS;
- }
-
- HBufferImageMovePosition (FRow, FCol, HBufferImage.HighBits);
-
- return EFI_SUCCESS;
-}
-
-/**
- Scroll cursor to next page
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HBufferImagePageDown (
- VOID
- )
-{
- HEFI_EDITOR_LINE *Line;
- UINTN FRow;
- UINTN FCol;
- UINTN Gap;
- BOOLEAN HighBits;
-
- Line = HBufferImage.CurrentLine;
-
- FRow = HBufferImage.BufferPosition.Row;
- FCol = HBufferImage.BufferPosition.Column;
- HighBits = HBufferImage.HighBits;
-
- //
- // has next page
- //
- if (HBufferImage.NumLines >= FRow + (HMainEditor.ScreenSize.Row - 2)) {
- Gap = (HMainEditor.ScreenSize.Row - 2);
- } else {
- //
- // MOVE CURSOR TO LAST LINE
- //
- Gap = HBufferImage.NumLines - FRow;
- }
-
- //
- // get correct line
- //
- Line = HMoveLine (Gap);
-
- //
- // if that line, is not that long, so move to the end of that line
- //
- if ((Line != NULL) && (FCol > Line->Size)) {
- FCol = Line->Size + 1;
- HighBits = TRUE;
- }
-
- FRow += Gap;
-
- HBufferImageMovePosition (FRow, FCol, HighBits);
-
- return EFI_SUCCESS;
-}
-
-/**
- Scroll cursor to previous page
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HBufferImagePageUp (
- VOID
- )
-{
- UINTN FRow;
- UINTN FCol;
- UINTN Gap;
- INTN Retreat;
-
- FRow = HBufferImage.BufferPosition.Row;
- FCol = HBufferImage.BufferPosition.Column;
-
- //
- // has previous page
- //
- if (FRow > (HMainEditor.ScreenSize.Row - 2)) {
- Gap = (HMainEditor.ScreenSize.Row - 2);
- } else {
- //
- // the first line of file will displayed on the first line of screen
- //
- Gap = FRow - 1;
- }
-
- Retreat = Gap;
- Retreat = -Retreat;
-
- FRow -= Gap;
-
- HBufferImageMovePosition (FRow, FCol, HBufferImage.HighBits);
-
- return EFI_SUCCESS;
-}
-
-/**
- Scroll cursor to start of line
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HBufferImageHome (
- VOID
- )
-{
- UINTN FRow;
- UINTN FCol;
- BOOLEAN HighBits;
-
- //
- // curosr will at the high bit
- //
- FRow = HBufferImage.BufferPosition.Row;
- FCol = 1;
- HighBits = TRUE;
-
- //
- // move cursor position
- //
- HBufferImageMovePosition (FRow, FCol, HighBits);
-
- return EFI_SUCCESS;
-}
-
-/**
- Scroll cursor to end of line.
-
- @retval EFI_SUCCESS Teh operation was successful.
-**/
-EFI_STATUS
-HBufferImageEnd (
- VOID
- )
-{
- HEFI_EDITOR_LINE *Line;
- UINTN FRow;
- UINTN FCol;
- BOOLEAN HighBits;
-
- //
- // need refresh mouse
- //
- HBufferImageMouseNeedRefresh = TRUE;
-
- Line = HBufferImage.CurrentLine;
-
- FRow = HBufferImage.BufferPosition.Row;
-
- if (Line->Size == 0x10) {
- FCol = Line->Size;
- HighBits = FALSE;
- } else {
- FCol = Line->Size + 1;
- HighBits = TRUE;
- }
-
- //
- // move cursor position
- //
- HBufferImageMovePosition (FRow, FCol, HighBits);
-
- return EFI_SUCCESS;
-}
-
-/**
- Get the size of the open buffer.
-
- @retval The size in bytes.
-**/
-UINTN
-HBufferImageGetTotalSize (
- VOID
- )
-{
- UINTN Size;
-
- HEFI_EDITOR_LINE *Line;
-
- //
- // calculate the total size of whole line list's buffer
- //
- if (HBufferImage.Lines == NULL) {
- return 0;
- }
-
- Line = CR (
- HBufferImage.ListHead->BackLink,
- HEFI_EDITOR_LINE,
- Link,
- EFI_EDITOR_LINE_LIST
- );
- //
- // one line at most 0x10
- //
- Size = 0x10 * (HBufferImage.NumLines - 1) + Line->Size;
-
- return Size;
-}
-
-/**
- Delete character from buffer.
-
- @param[in] Pos Position, Pos starting from 0.
- @param[in] Count The Count of characters to delete.
- @param[out] DeleteBuffer The DeleteBuffer.
-
- @retval EFI_SUCCESS Success
-**/
-EFI_STATUS
-HBufferImageDeleteCharacterFromBuffer (
- IN UINTN Pos,
- IN UINTN Count,
- OUT UINT8 *DeleteBuffer
- )
-{
- UINTN Index;
-
- VOID *Buffer;
- UINT8 *BufferPtr;
- UINTN Size;
-
- HEFI_EDITOR_LINE *Line;
- LIST_ENTRY *Link;
-
- UINTN OldFCol;
- UINTN OldFRow;
- UINTN OldPos;
-
- UINTN NewPos;
-
- EFI_STATUS Status;
-
- Size = HBufferImageGetTotalSize ();
-
- if (Size < Count) {
- return EFI_LOAD_ERROR;
- }
-
- if (Size == 0) {
- return EFI_SUCCESS;
- }
-
- //
- // relocate all the HBufferImage fields
- //
- OldFRow = HBufferImage.BufferPosition.Row;
- OldFCol = HBufferImage.BufferPosition.Column;
- OldPos = (OldFRow - 1) * 0x10 + OldFCol - 1;
-
- if (Pos > 0) {
- //
- // has character before it,
- // so locate according to block's previous character
- //
- NewPos = Pos - 1;
- } else {
- //
- // has no character before it,
- // so locate according to block's next character
- //
- NewPos = 0;
- }
-
- HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);
-
- Buffer = AllocateZeroPool (Size);
- if (Buffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- HBufferImageListToBuffer (Buffer, Size);
-
- BufferPtr = (UINT8 *)Buffer;
-
- //
- // pass deleted buffer out
- //
- if (DeleteBuffer != NULL) {
- for (Index = 0; Index < Count; Index++) {
- DeleteBuffer[Index] = BufferPtr[Pos + Index];
- }
- }
-
- //
- // delete the part from Pos
- //
- for (Index = Pos; Index < Size - Count; Index++) {
- BufferPtr[Index] = BufferPtr[Index + Count];
- }
-
- Size -= Count;
-
- HBufferImageFreeLines ();
-
- Status = HBufferImageBufferToList (Buffer, Size);
- FreePool (Buffer);
-
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- Link = HMainEditor.BufferImage->ListHead->ForwardLink;
- for (Index = 0; Index < NewPos / 0x10; Index++) {
- Link = Link->ForwardLink;
- }
-
- Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
- HBufferImage.CurrentLine = Line;
-
- //
- // if current cursor position if inside select area
- // then move it to the block's NEXT character
- //
- if ((OldPos >= Pos) && (OldPos < (Pos + Count))) {
- NewPos = Pos;
- } else {
- if (OldPos < Pos) {
- NewPos = OldPos;
- } else {
- NewPos = OldPos - Count;
- }
- }
-
- HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);
-
- return EFI_SUCCESS;
-}
-
-/**
- Add character to buffer, add before pos.
-
- @param[in] Pos Position, Pos starting from 0.
- @param[in] Count Count of characters to add.
- @param[in] AddBuffer Add buffer.
-
- @retval EFI_SUCCESS Success.
-**/
-EFI_STATUS
-HBufferImageAddCharacterToBuffer (
- IN UINTN Pos,
- IN UINTN Count,
- IN UINT8 *AddBuffer
- )
-{
- INTN Index;
-
- VOID *Buffer;
- UINT8 *BufferPtr;
- UINTN Size;
-
- HEFI_EDITOR_LINE *Line;
-
- LIST_ENTRY *Link;
-
- UINTN OldFCol;
- UINTN OldFRow;
- UINTN OldPos;
-
- UINTN NewPos;
-
- Size = HBufferImageGetTotalSize ();
-
- //
- // relocate all the HBufferImage fields
- //
- OldFRow = HBufferImage.BufferPosition.Row;
- OldFCol = HBufferImage.BufferPosition.Column;
- OldPos = (OldFRow - 1) * 0x10 + OldFCol - 1;
-
- //
- // move cursor before Pos
- //
- if (Pos > 0) {
- NewPos = Pos - 1;
- } else {
- NewPos = 0;
- }
-
- HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);
-
- Buffer = AllocateZeroPool (Size + Count);
- if (Buffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- HBufferImageListToBuffer (Buffer, Size);
-
- BufferPtr = (UINT8 *)Buffer;
-
- //
- // get a place to add
- //
- for (Index = (INTN)(Size + Count - 1); Index >= (INTN)Pos; Index--) {
- BufferPtr[Index] = BufferPtr[Index - Count];
- }
-
- //
- // add the buffer
- //
- for (Index = (INTN)0; Index < (INTN)Count; Index++) {
- BufferPtr[Index + Pos] = AddBuffer[Index];
- }
-
- Size += Count;
-
- HBufferImageFreeLines ();
-
- HBufferImageBufferToList (Buffer, Size);
-
- FreePool (Buffer);
-
- Link = HMainEditor.BufferImage->ListHead->ForwardLink;
- for (Index = 0; Index < (INTN)NewPos / 0x10; Index++) {
- Link = Link->ForwardLink;
- }
-
- Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
- HBufferImage.CurrentLine = Line;
-
- if (OldPos >= Pos) {
- NewPos = OldPos + Count;
- } else {
- NewPos = OldPos;
- }
-
- HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);
-
- return EFI_SUCCESS;
-}
-
-/**
- Delete current character from line.
-
- @retval EFI_SUCCESS The operationw as successful.
-**/
-EFI_STATUS
-HBufferImageDoDelete (
- VOID
- )
-{
- HEFI_EDITOR_LINE *Line;
-
- BOOLEAN LastLine;
- UINTN FileColumn;
- UINTN FPos;
-
- FPos = (HBufferImage.BufferPosition.Row - 1) * 0x10 + HBufferImage.BufferPosition.Column - 1;
-
- FileColumn = HBufferImage.BufferPosition.Column;
-
- Line = HBufferImage.CurrentLine;
-
- //
- // if beyond the last character
- //
- if (FileColumn > Line->Size) {
- return EFI_SUCCESS;
- }
-
- LastLine = FALSE;
- if (Line->Link.ForwardLink == HBufferImage.ListHead) {
- LastLine = TRUE;
- }
-
- HBufferImageDeleteCharacterFromBuffer (FPos, 1, NULL);
-
- //
- // if is the last line
- // then only this line need to be refreshed
- //
- if (LastLine) {
- HBufferImageNeedRefresh = FALSE;
- HBufferImageOnlyLineNeedRefresh = TRUE;
- } else {
- HBufferImageNeedRefresh = TRUE;
- HBufferImageOnlyLineNeedRefresh = FALSE;
- }
-
- if (!HBufferImage.Modified) {
- HBufferImage.Modified = TRUE;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Change the raw buffer to a list of lines for the UI.
-
- @param[in] Buffer The pointer to the buffer to fill.
- @param[in] Bytes The size of the buffer in bytes.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
-**/
-EFI_STATUS
-HBufferImageBufferToList (
- IN VOID *Buffer,
- IN UINTN Bytes
- )
-{
- UINTN TempI;
- UINTN TempJ;
- UINTN Left;
- HEFI_EDITOR_LINE *Line;
- UINT8 *BufferPtr;
-
- TempI = 0;
- Left = 0;
- BufferPtr = (UINT8 *)Buffer;
-
- //
- // parse file content line by line
- //
- while (TempI < Bytes) {
- if (Bytes - TempI >= 0x10) {
- Left = 0x10;
- } else {
- Left = Bytes - TempI;
- }
-
- //
- // allocate a new line
- //
- Line = HBufferImageCreateLine ();
- if (Line == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Line->Size = Left;
-
- for (TempJ = 0; TempJ < Left; TempJ++) {
- Line->Buffer[TempJ] = BufferPtr[TempI];
- TempI++;
- }
- }
-
- //
- // last line is a full line, SO create a new line
- //
- if ((Left == 0x10) || (Bytes == 0)) {
- Line = HBufferImageCreateLine ();
- if (Line == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Change the list of lines from the UI to a raw buffer.
-
- @param[in] Buffer The pointer to the buffer to fill.
- @param[in] Bytes The size of the buffer in bytes.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HBufferImageListToBuffer (
- IN VOID *Buffer,
- IN UINTN Bytes
- )
-{
- UINTN Count;
- UINTN Index;
- HEFI_EDITOR_LINE *Line;
- LIST_ENTRY *Link;
- UINT8 *BufferPtr;
-
- //
- // change the line list to a large buffer
- //
- if (HBufferImage.Lines == NULL) {
- return EFI_SUCCESS;
- }
-
- Link = &HBufferImage.Lines->Link;
- Count = 0;
- BufferPtr = (UINT8 *)Buffer;
-
- //
- // deal line by line
- //
- while (Link != HBufferImage.ListHead) {
- Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
-
- // @todo shouldn't this be an error???
- if (Count + Line->Size > Bytes) {
- return EFI_SUCCESS;
- }
-
- for (Index = 0; Index < Line->Size; Index++) {
- BufferPtr[Index] = Line->Buffer[Index];
- }
-
- Count += Line->Size;
- BufferPtr += Line->Size;
-
- Link = Link->ForwardLink;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Move the mouse in the image buffer.
-
- @param[in] TextX The x-coordinate.
- @param[in] TextY The y-coordinate.
-**/
-VOID
-HBufferImageAdjustMousePosition (
- IN INT32 TextX,
- IN INT32 TextY
- )
-{
- UINTN TempX;
- UINTN TempY;
- UINTN AbsX;
- UINTN AbsY;
-
- //
- // TextX and TextY is mouse movement data returned by mouse driver
- // This function will change it to MousePosition
- //
- //
- // get absolute TempX value
- //
- if (TextX >= 0) {
- AbsX = TextX;
- } else {
- AbsX = -TextX;
- }
-
- //
- // get absolute TempY value
- //
- if (TextY >= 0) {
- AbsY = TextY;
- } else {
- AbsY = -TextY;
- }
-
- TempX = HBufferImage.MousePosition.Column;
- TempY = HBufferImage.MousePosition.Row;
-
- if (TextX >= 0) {
- TempX += TextX;
- } else {
- if (TempX >= AbsX) {
- TempX -= AbsX;
- } else {
- TempX = 0;
- }
- }
-
- if (TextY >= 0) {
- TempY += TextY;
- } else {
- if (TempY >= AbsY) {
- TempY -= AbsY;
- } else {
- TempY = 0;
- }
- }
-
- //
- // check whether new mouse column position is beyond screen
- // if not, adjust it
- //
- if ((TempX >= 10) && (TempX <= (10 + 0x10 * 3 - 1))) {
- HBufferImage.MousePosition.Column = TempX;
- } else if (TempX < 10) {
- HBufferImage.MousePosition.Column = 10;
- } else if (TempX > (10 + 0x10 * 3 - 1)) {
- HBufferImage.MousePosition.Column = 10 + 0x10 * 3 - 1;
- }
-
- //
- // check whether new mouse row position is beyond screen
- // if not, adjust it
- //
- if ((TempY >= 2) && (TempY <= (HMainEditor.ScreenSize.Row - 1))) {
- HBufferImage.MousePosition.Row = TempY;
- } else if (TempY < 2) {
- HBufferImage.MousePosition.Row = 2;
- } else if (TempY > (HMainEditor.ScreenSize.Row - 1)) {
- HBufferImage.MousePosition.Row = (HMainEditor.ScreenSize.Row - 1);
- }
-}
-
-/**
- Dispatch input to different handler
-
- @param[in] Key The input key:
- the keys can be:
- ASCII KEY
- Backspace/Delete
- Direction key: up/down/left/right/pgup/pgdn
- Home/End
- INS
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_LOAD_ERROR A load error occurred.
- @retval EFI_OUT_OF_RESOURCES A Memory allocation failed.
-**/
-EFI_STATUS
-HBufferImageHandleInput (
- IN EFI_INPUT_KEY *Key
- )
-{
- EFI_STATUS Status;
-
- Status = EFI_SUCCESS;
-
- switch (Key->ScanCode) {
- //
- // ordinary key
- //
- case SCAN_NULL:
- Status = HBufferImageDoCharInput (Key->UnicodeChar);
- break;
-
- //
- // up arrow
- //
- case SCAN_UP:
- Status = HBufferImageScrollUp ();
- break;
-
- //
- // down arrow
- //
- case SCAN_DOWN:
- Status = HBufferImageScrollDown ();
- break;
-
- //
- // right arrow
- //
- case SCAN_RIGHT:
- Status = HBufferImageScrollRight ();
- break;
-
- //
- // left arrow
- //
- case SCAN_LEFT:
- Status = HBufferImageScrollLeft ();
- break;
-
- //
- // page up
- //
- case SCAN_PAGE_UP:
- Status = HBufferImagePageUp ();
- break;
-
- //
- // page down
- //
- case SCAN_PAGE_DOWN:
- Status = HBufferImagePageDown ();
- break;
-
- //
- // delete
- //
- case SCAN_DELETE:
- Status = HBufferImageDoDelete ();
- break;
-
- //
- // home
- //
- case SCAN_HOME:
- Status = HBufferImageHome ();
- break;
-
- //
- // end
- //
- case SCAN_END:
- Status = HBufferImageEnd ();
- break;
-
- default:
- Status = StatusBarSetStatusString (L"Unknown Command");
- break;
- }
-
- return Status;
-}
+/** @file + Defines HBufferImage - the view of the file that is visible at any point, + as well as the event handlers for editing the file + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "HexEditor.h" + +extern EFI_HANDLE HImageHandleBackup; + +extern HEFI_EDITOR_FILE_IMAGE HFileImage; +extern HEFI_EDITOR_DISK_IMAGE HDiskImage; +extern HEFI_EDITOR_MEM_IMAGE HMemImage; + +extern HEFI_EDITOR_FILE_IMAGE HFileImageBackupVar; +extern HEFI_EDITOR_DISK_IMAGE HDiskImageBackupVar; +extern HEFI_EDITOR_MEM_IMAGE HMemImageBackupVar; + +extern BOOLEAN HEditorMouseAction; + +extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditor; +extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditorBackupVar; + +HEFI_EDITOR_BUFFER_IMAGE HBufferImage; +HEFI_EDITOR_BUFFER_IMAGE HBufferImageBackupVar; + +// +// for basic initialization of HBufferImage +// +HEFI_EDITOR_BUFFER_IMAGE HBufferImageConst = { + NULL, + NULL, + 0, + NULL, + { + 0, + 0 + }, + { + 0, + 0 + }, + { + 0, + 0 + }, + 0, + TRUE, + FALSE, + FileTypeNone, + NULL, + NULL, + NULL +}; + +// +// the whole edit area needs to be refreshed +// +BOOLEAN HBufferImageNeedRefresh; + +// +// only the current line in edit area needs to be refresh +// +BOOLEAN HBufferImageOnlyLineNeedRefresh; + +BOOLEAN HBufferImageMouseNeedRefresh; + +/** + Initialization function for HBufferImage + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HBufferImageInit ( + VOID + ) +{ + EFI_STATUS Status; + + // + // basically initialize the HBufferImage + // + CopyMem (&HBufferImage, &HBufferImageConst, sizeof (HBufferImage)); + + // + // INIT listhead + // + HBufferImage.ListHead = AllocateZeroPool (sizeof (LIST_ENTRY)); + if (HBufferImage.ListHead == NULL) { + return EFI_LOAD_ERROR; + } + + InitializeListHead (HBufferImage.ListHead); + + HBufferImage.DisplayPosition.Row = 2; + HBufferImage.DisplayPosition.Column = 10; + HBufferImage.MousePosition.Row = 2; + HBufferImage.MousePosition.Column = 10; + + HBufferImage.FileImage = &HFileImage; + HBufferImage.DiskImage = &HDiskImage; + HBufferImage.MemImage = &HMemImage; + + HBufferImageNeedRefresh = FALSE; + HBufferImageOnlyLineNeedRefresh = FALSE; + HBufferImageMouseNeedRefresh = FALSE; + + HBufferImageBackupVar.FileImage = &HFileImageBackupVar; + HBufferImageBackupVar.DiskImage = &HDiskImageBackupVar; + HBufferImageBackupVar.MemImage = &HMemImageBackupVar; + + Status = HFileImageInit (); + if (EFI_ERROR (Status)) { + return EFI_LOAD_ERROR; + } + + Status = HDiskImageInit (); + if (EFI_ERROR (Status)) { + return EFI_LOAD_ERROR; + } + + Status = HMemImageInit (); + if (EFI_ERROR (Status)) { + return EFI_LOAD_ERROR; + } + + return EFI_SUCCESS; +} + +/** + Backup function for HBufferImage. Only a few fields need to be backup. + This is for making the file buffer refresh as few as possible. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageBackup ( + VOID + ) +{ + HBufferImageBackupVar.MousePosition = HBufferImage.MousePosition; + + HBufferImageBackupVar.BufferPosition = HBufferImage.BufferPosition; + + HBufferImageBackupVar.Modified = HBufferImage.Modified; + + HBufferImageBackupVar.BufferType = HBufferImage.BufferType; + HBufferImageBackupVar.LowVisibleRow = HBufferImage.LowVisibleRow; + HBufferImageBackupVar.HighBits = HBufferImage.HighBits; + + // + // three kinds of buffer supported + // file buffer + // disk buffer + // memory buffer + // + switch (HBufferImage.BufferType) { + case FileTypeFileBuffer: + HFileImageBackup (); + break; + + case FileTypeDiskBuffer: + HDiskImageBackup (); + break; + + case FileTypeMemBuffer: + HMemImageBackup (); + break; + + default: + break; + } + + return EFI_SUCCESS; +} + +/** + Free all the lines in HBufferImage. + Fields affected: + Lines + CurrentLine + NumLines + ListHead + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageFreeLines ( + VOID + ) +{ + HFreeLines (HBufferImage.ListHead, HBufferImage.Lines); + + HBufferImage.Lines = NULL; + HBufferImage.CurrentLine = NULL; + HBufferImage.NumLines = 0; + + return EFI_SUCCESS; +} + +/** + Cleanup function for HBufferImage + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageCleanup ( + VOID + ) +{ + EFI_STATUS Status; + + // + // free all the lines + // + Status = HBufferImageFreeLines (); + + SHELL_FREE_NON_NULL (HBufferImage.ListHead); + HBufferImage.ListHead = NULL; + + HFileImageCleanup (); + HDiskImageCleanup (); + + return Status; +} + +/** + Print Line on Row + + @param[in] Line The lline to print. + @param[in] Row The row on screen ( begin from 1 ). + @param[in] FRow The FRow. + @param[in] Orig The original color. + @param[in] New The color to print with. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImagePrintLine ( + IN HEFI_EDITOR_LINE *Line, + IN UINTN Row, + IN UINTN FRow, + IN HEFI_EDITOR_COLOR_UNION Orig, + IN HEFI_EDITOR_COLOR_UNION New + + ) +{ + UINTN Index; + UINTN Pos; + BOOLEAN Selected; + BOOLEAN BeNewColor; + UINTN RowStart; + UINTN RowEnd; + UINTN ColStart; + UINTN ColEnd; + + // + // variable initialization + // + ColStart = 0; + ColEnd = 0; + Selected = FALSE; + + // + // print the selected area in opposite color + // + if ((HMainEditor.SelectStart != 0) && (HMainEditor.SelectEnd != 0)) { + RowStart = (HMainEditor.SelectStart - 1) / 0x10 + 1; + RowEnd = (HMainEditor.SelectEnd - 1) / 0x10 + 1; + + ColStart = (HMainEditor.SelectStart - 1) % 0x10 + 1; + ColEnd = (HMainEditor.SelectEnd - 1) % 0x10 + 1; + + if ((FRow >= RowStart) && (FRow <= RowEnd)) { + Selected = TRUE; + } + + if (FRow > RowStart) { + ColStart = 1; + } + + if (FRow < RowEnd) { + ColEnd = 0x10; + } + } + + if (!HEditorMouseAction) { + ShellPrintEx ( + 0, + (INT32)Row - 1, + L"%8X ", + ((INT32)Row - 2 + HBufferImage.LowVisibleRow - 1) * 0x10 + ); + } + + for (Index = 0; Index < 0x08 && Index < Line->Size; Index++) { + BeNewColor = FALSE; + + if (Selected) { + if ((Index + 1 >= ColStart) && (Index + 1 <= ColEnd)) { + BeNewColor = TRUE; + } + } + + if (BeNewColor) { + gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F); + } else { + gST->ConOut->SetAttribute (gST->ConOut, Orig.Data & 0x7F); + } + + Pos = 10 + (Index * 3); + if (Line->Buffer[Index] < 0x10) { + ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"0"); + Pos++; + } + + if (Index < 0x07) { + ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%x ", Line->Buffer[Index]); + } else { + ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%x ", Line->Buffer[Index]); + } + } + + gST->ConOut->SetAttribute (gST->ConOut, Orig.Data & 0x7F); + while (Index < 0x08) { + Pos = 10 + (Index * 3); + ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" "); + Index++; + } + + while (Index < 0x10 && Index < Line->Size) { + BeNewColor = FALSE; + + if (Selected) { + if ((Index + 1 >= ColStart) && (Index + 1 <= ColEnd)) { + BeNewColor = TRUE; + } + } + + if (BeNewColor) { + gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F); + } else { + gST->ConOut->SetAttribute (gST->ConOut, Orig.Data & 0x7F); + } + + Pos = 10 + (Index * 3) + 1; + if (Line->Buffer[Index] < 0x10) { + ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"0"); + Pos++; + } + + ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%x ", Line->Buffer[Index]); + Index++; + } + + gST->ConOut->SetAttribute (gST->ConOut, Orig.Data & 0x7F); + while (Index < 0x10) { + Pos = 10 + (Index * 3) + 1; + ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" "); + Index++; + } + + // + // restore the original color + // + gST->ConOut->SetAttribute (gST->ConOut, Orig.Data & 0x7F); + + // + // PRINT the buffer content + // + if (!HEditorMouseAction) { + for (Index = 0; Index < 0x10 && Index < Line->Size; Index++) { + Pos = ASCII_POSITION + Index; + + // + // learned from shelle.h -- IsValidChar + // + if (Line->Buffer[Index] >= L' ') { + ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%c", (CHAR16)Line->Buffer[Index]); + } else { + ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%c", '.'); + } + } + + while (Index < 0x10) { + Pos = ASCII_POSITION + Index; + ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" "); + Index++; + } + } + + // + // restore the abundant blank in hex edit area to original color + // + if (Selected) { + if (ColEnd <= 7) { + Pos = 10 + (ColEnd - 1) * 3 + 2; + ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" "); + } else if (ColEnd == 8) { + Pos = 10 + (ColEnd - 1) * 3 + 2; + ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" "); + } else { + Pos = 10 + (ColEnd - 1) * 3 + 3; + ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" "); + } + } + + return EFI_SUCCESS; +} + +/** + Function to decide if a column number is stored in the high bits. + + @param[in] Column The column to examine. + @param[out] FCol The actual column number. + + @retval TRUE The actual column was in high bits and is now in FCol. + @retval FALSE There was not a column number in the high bits. +**/ +BOOLEAN +HBufferImageIsAtHighBits ( + IN UINTN Column, + OUT UINTN *FCol + ) +{ + Column -= 10; + + // + // NOW AFTER THE SUB, Column start from 0 + // 23 AND 24 ARE BOTH BLANK + // + if (Column == 24) { + *FCol = 0; + return FALSE; + } + + if (Column > 24) { + Column--; + } + + *FCol = (Column / 3) + 1; + + if (Column % 3 == 0) { + return TRUE; + } + + if ((Column % 3 == 2)) { + *FCol = 0; + } + + return FALSE; +} + +/** + Decide if a point is in the already selected area. + + @param[in] MouseRow The row of the point to test. + @param[in] MouseCol The col of the point to test. + + @retval TRUE The point is in the selected area. + @retval FALSE The point is not in the selected area. +**/ +BOOLEAN +HBufferImageIsInSelectedArea ( + IN UINTN MouseRow, + IN UINTN MouseCol + ) +{ + UINTN FRow; + UINTN RowStart; + UINTN RowEnd; + UINTN ColStart; + UINTN ColEnd; + UINTN MouseColStart; + UINTN MouseColEnd; + + // + // judge mouse position whether is in selected area + // + // + // not select + // + if ((HMainEditor.SelectStart == 0) || (HMainEditor.SelectEnd == 0)) { + return FALSE; + } + + // + // calculate the select area + // + RowStart = (HMainEditor.SelectStart - 1) / 0x10 + 1; + RowEnd = (HMainEditor.SelectEnd - 1) / 0x10 + 1; + + ColStart = (HMainEditor.SelectStart - 1) % 0x10 + 1; + ColEnd = (HMainEditor.SelectEnd - 1) % 0x10 + 1; + + FRow = HBufferImage.LowVisibleRow + MouseRow - 2; + if ((FRow < RowStart) || (FRow > RowEnd)) { + return FALSE; + } + + if (FRow > RowStart) { + ColStart = 1; + } + + if (FRow < RowEnd) { + ColEnd = 0x10; + } + + MouseColStart = 10 + (ColStart - 1) * 3; + if (ColStart > 8) { + MouseColStart++; + } + + MouseColEnd = 10 + (ColEnd - 1) * 3 + 1; + if (ColEnd > 8) { + MouseColEnd++; + } + + if ((MouseCol < MouseColStart) || (MouseCol > MouseColEnd)) { + return FALSE; + } + + return TRUE; +} + +/** + Set mouse position according to HBufferImage.MousePosition. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageRestoreMousePosition ( + VOID + ) +{ + HEFI_EDITOR_COLOR_UNION Orig; + HEFI_EDITOR_COLOR_UNION New; + UINTN FRow; + UINTN FColumn; + BOOLEAN HasCharacter; + HEFI_EDITOR_LINE *CurrentLine; + HEFI_EDITOR_LINE *Line; + UINT8 Value; + BOOLEAN HighBits; + + Line = NULL; + if (HMainEditor.MouseSupported) { + if (HBufferImageMouseNeedRefresh) { + HBufferImageMouseNeedRefresh = FALSE; + + // + // if mouse position not moved and only mouse action + // so do not need to refresh mouse position + // + if (( + (HBufferImage.MousePosition.Row == HBufferImageBackupVar.MousePosition.Row) && + (HBufferImage.MousePosition.Column == HBufferImageBackupVar.MousePosition.Column) + ) && + HEditorMouseAction + ) + { + return EFI_SUCCESS; + } + + // + // backup the old screen attributes + // + Orig = HMainEditor.ColorAttributes; + New.Data = 0; + New.Colors.Foreground = Orig.Colors.Background & 0xF; + New.Colors.Background = Orig.Colors.Foreground & 0x7; + + // + // if in selected area, + // so do not need to refresh mouse + // + if (!HBufferImageIsInSelectedArea ( + HBufferImageBackupVar.MousePosition.Row, + HBufferImageBackupVar.MousePosition.Column + )) + { + gST->ConOut->SetAttribute (gST->ConOut, Orig.Data); + } else { + gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F); + } + + // + // clear the old mouse position + // + FRow = HBufferImage.LowVisibleRow + HBufferImageBackupVar.MousePosition.Row - 2; + + HighBits = HBufferImageIsAtHighBits ( + HBufferImageBackupVar.MousePosition.Column, + &FColumn + ); + + HasCharacter = TRUE; + if ((FRow > HBufferImage.NumLines) || (FColumn == 0)) { + HasCharacter = FALSE; + } else { + CurrentLine = HBufferImage.CurrentLine; + Line = HMoveLine (FRow - HBufferImage.BufferPosition.Row); + + if ((Line == NULL) || (FColumn > Line->Size)) { + HasCharacter = FALSE; + } + + HBufferImage.CurrentLine = CurrentLine; + } + + ShellPrintEx ( + (INT32)HBufferImageBackupVar.MousePosition.Column - 1, + (INT32)HBufferImageBackupVar.MousePosition.Row - 1, + L" " + ); + + if (HasCharacter) { + if (HighBits) { + Value = (UINT8)(Line->Buffer[FColumn - 1] & 0xf0); + Value = (UINT8)(Value >> 4); + } else { + Value = (UINT8)(Line->Buffer[FColumn - 1] & 0xf); + } + + ShellPrintEx ( + (INT32)HBufferImageBackupVar.MousePosition.Column - 1, + (INT32)HBufferImageBackupVar.MousePosition.Row - 1, + L"%x", + Value + ); + } + + if (!HBufferImageIsInSelectedArea ( + HBufferImage.MousePosition.Row, + HBufferImage.MousePosition.Column + )) + { + gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F); + } else { + gST->ConOut->SetAttribute (gST->ConOut, Orig.Data); + } + + // + // clear the old mouse position + // + FRow = HBufferImage.LowVisibleRow + HBufferImage.MousePosition.Row - 2; + + HighBits = HBufferImageIsAtHighBits ( + HBufferImage.MousePosition.Column, + &FColumn + ); + + HasCharacter = TRUE; + if ((FRow > HBufferImage.NumLines) || (FColumn == 0)) { + HasCharacter = FALSE; + } else { + CurrentLine = HBufferImage.CurrentLine; + Line = HMoveLine (FRow - HBufferImage.BufferPosition.Row); + + if ((Line == NULL) || (FColumn > Line->Size)) { + HasCharacter = FALSE; + } + + HBufferImage.CurrentLine = CurrentLine; + } + + ShellPrintEx ( + (INT32)HBufferImage.MousePosition.Column - 1, + (INT32)HBufferImage.MousePosition.Row - 1, + L" " + ); + + if (HasCharacter) { + if (HighBits) { + Value = (UINT8)(Line->Buffer[FColumn - 1] & 0xf0); + Value = (UINT8)(Value >> 4); + } else { + Value = (UINT8)(Line->Buffer[FColumn - 1] & 0xf); + } + + ShellPrintEx ( + (INT32)HBufferImage.MousePosition.Column - 1, + (INT32)HBufferImage.MousePosition.Row - 1, + L"%x", + Value + ); + } + + // + // end of HasCharacter + // + gST->ConOut->SetAttribute (gST->ConOut, Orig.Data); + } + + // + // end of MouseNeedRefresh + // + } + + // + // end of MouseSupported + // + return EFI_SUCCESS; +} + +/** + Set cursor position according to HBufferImage.DisplayPosition. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageRestorePosition ( + VOID + ) +{ + // + // set cursor position + // + gST->ConOut->SetCursorPosition ( + gST->ConOut, + HBufferImage.DisplayPosition.Column - 1, + HBufferImage.DisplayPosition.Row - 1 + ); + + return EFI_SUCCESS; +} + +/** + Refresh function for HBufferImage. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A Load error occurred. + +**/ +EFI_STATUS +HBufferImageRefresh ( + VOID + ) +{ + LIST_ENTRY *Link; + HEFI_EDITOR_LINE *Line; + UINTN Row; + HEFI_EDITOR_COLOR_UNION Orig; + HEFI_EDITOR_COLOR_UNION New; + + UINTN StartRow; + UINTN EndRow; + UINTN FStartRow; + UINTN Tmp; + + Orig = HMainEditor.ColorAttributes; + New.Data = 0; + New.Colors.Foreground = Orig.Colors.Background; + New.Colors.Background = Orig.Colors.Foreground; + + // + // if it's the first time after editor launch, so should refresh + // + if (HEditorFirst == FALSE) { + // + // no definite required refresh + // and file position displayed on screen has not been changed + // + if (!HBufferImageNeedRefresh && + !HBufferImageOnlyLineNeedRefresh && + (HBufferImageBackupVar.LowVisibleRow == HBufferImage.LowVisibleRow) + ) + { + HBufferImageRestoreMousePosition (); + HBufferImageRestorePosition (); + return EFI_SUCCESS; + } + } + + gST->ConOut->EnableCursor (gST->ConOut, FALSE); + + // + // only need to refresh current line + // + if (HBufferImageOnlyLineNeedRefresh && (HBufferImageBackupVar.LowVisibleRow == HBufferImage.LowVisibleRow)) { + HBufferImagePrintLine ( + HBufferImage.CurrentLine, + HBufferImage.DisplayPosition.Row, + HBufferImage.BufferPosition.Row, + Orig, + New + ); + } else { + // + // the whole edit area need refresh + // + if (HEditorMouseAction && (HMainEditor.SelectStart != 0) && (HMainEditor.SelectEnd != 0)) { + if (HMainEditor.SelectStart != HMainEditorBackupVar.SelectStart) { + if ((HMainEditor.SelectStart >= HMainEditorBackupVar.SelectStart) && (HMainEditorBackupVar.SelectStart != 0)) { + StartRow = (HMainEditorBackupVar.SelectStart - 1) / 0x10 + 1; + } else { + StartRow = (HMainEditor.SelectStart - 1) / 0x10 + 1; + } + } else { + StartRow = (HMainEditor.SelectStart - 1) / 0x10 + 1; + } + + if (HMainEditor.SelectEnd <= HMainEditorBackupVar.SelectEnd) { + EndRow = (HMainEditorBackupVar.SelectEnd - 1) / 0x10 + 1; + } else { + EndRow = (HMainEditor.SelectEnd - 1) / 0x10 + 1; + } + + // + // swap + // + if (StartRow > EndRow) { + Tmp = StartRow; + StartRow = EndRow; + EndRow = Tmp; + } + + FStartRow = StartRow; + + StartRow = 2 + StartRow - HBufferImage.LowVisibleRow; + EndRow = 2 + EndRow - HBufferImage.LowVisibleRow; + } else { + // + // not mouse selection actions + // + FStartRow = HBufferImage.LowVisibleRow; + StartRow = 2; + EndRow = (HMainEditor.ScreenSize.Row - 1); + } + + // + // no line + // + if (HBufferImage.Lines == NULL) { + HBufferImageRestoreMousePosition (); + HBufferImageRestorePosition (); + gST->ConOut->EnableCursor (gST->ConOut, TRUE); + return EFI_SUCCESS; + } + + // + // get the first line that will be displayed + // + Line = HMoveLine (FStartRow - HBufferImage.BufferPosition.Row); + if (Line == NULL) { + gST->ConOut->EnableCursor (gST->ConOut, TRUE); + return EFI_LOAD_ERROR; + } + + Link = &(Line->Link); + Row = StartRow; + do { + Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); + + // + // print line at row + // + HBufferImagePrintLine ( + Line, + Row, + HBufferImage.LowVisibleRow + Row - 2, + Orig, + New + ); + + Link = Link->ForwardLink; + Row++; + } while (Link != HBufferImage.ListHead && Row <= EndRow); + + while (Row <= EndRow) { + EditorClearLine (Row, HMainEditor.ScreenSize.Column, HMainEditor.ScreenSize.Row); + Row++; + } + + // + // while not file end and not screen full + // + } + + HBufferImageRestoreMousePosition (); + HBufferImageRestorePosition (); + + HBufferImageNeedRefresh = FALSE; + HBufferImageOnlyLineNeedRefresh = FALSE; + gST->ConOut->EnableCursor (gST->ConOut, TRUE); + + return EFI_SUCCESS; +} + +/** + Read an image into a buffer friom a source. + + @param[in] FileName Pointer to the file name. OPTIONAL and ignored if not FileTypeFileBuffer. + @param[in] DiskName Pointer to the disk name. OPTIONAL and ignored if not FileTypeDiskBuffer. + @param[in] DiskOffset Offset into the disk. OPTIONAL and ignored if not FileTypeDiskBuffer. + @param[in] DiskSize Size of the disk buffer. OPTIONAL and ignored if not FileTypeDiskBuffer. + @param[in] MemOffset Offset into the Memory. OPTIONAL and ignored if not FileTypeMemBuffer. + @param[in] MemSize Size of the Memory buffer. OPTIONAL and ignored if not FileTypeMemBuffer. + @param[in] BufferType The type of buffer to save. IGNORED. + @param[in] Recover TRUE for recovermode, FALSE otherwise. + + @return EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageRead ( + IN CONST CHAR16 *FileName, + IN CONST CHAR16 *DiskName, + IN UINTN DiskOffset, + IN UINTN DiskSize, + IN UINTN MemOffset, + IN UINTN MemSize, + IN EDIT_FILE_TYPE BufferType, + IN BOOLEAN Recover + ) +{ + EFI_STATUS Status; + EDIT_FILE_TYPE BufferTypeBackup; + + // + // variable initialization + // + Status = EFI_SUCCESS; + HBufferImage.BufferType = BufferType; + + // + // three types of buffer supported + // file buffer + // disk buffer + // memory buffer + // + BufferTypeBackup = HBufferImage.BufferType; + + switch (BufferType) { + case FileTypeFileBuffer: + Status = HFileImageRead (FileName, Recover); + break; + + case FileTypeDiskBuffer: + Status = HDiskImageRead (DiskName, DiskOffset, DiskSize, Recover); + break; + + case FileTypeMemBuffer: + Status = HMemImageRead (MemOffset, MemSize, Recover); + break; + + default: + Status = EFI_NOT_FOUND; + break; + } + + if (EFI_ERROR (Status)) { + HBufferImage.BufferType = BufferTypeBackup; + } + + return Status; +} + +/** + Save the current image. + + @param[in] FileName Pointer to the file name. OPTIONAL and ignored if not FileTypeFileBuffer. + @param[in] DiskName Pointer to the disk name. OPTIONAL and ignored if not FileTypeDiskBuffer. + @param[in] DiskOffset Offset into the disk. OPTIONAL and ignored if not FileTypeDiskBuffer. + @param[in] DiskSize Size of the disk buffer. OPTIONAL and ignored if not FileTypeDiskBuffer. + @param[in] MemOffset Offset into the Memory. OPTIONAL and ignored if not FileTypeMemBuffer. + @param[in] MemSize Size of the Memory buffer. OPTIONAL and ignored if not FileTypeMemBuffer. + @param[in] BufferType The type of buffer to save. IGNORED. + + @return EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageSave ( + IN CHAR16 *FileName, + IN CHAR16 *DiskName, + IN UINTN DiskOffset, + IN UINTN DiskSize, + IN UINTN MemOffset, + IN UINTN MemSize, + IN EDIT_FILE_TYPE BufferType + ) +{ + EFI_STATUS Status; + EDIT_FILE_TYPE BufferTypeBackup; + + // + // variable initialization + // + Status = EFI_SUCCESS; + BufferTypeBackup = HBufferImage.BufferType; + + switch (HBufferImage.BufferType) { + // + // file buffer + // + case FileTypeFileBuffer: + Status = HFileImageSave (FileName); + break; + + // + // disk buffer + // + case FileTypeDiskBuffer: + Status = HDiskImageSave (DiskName, DiskOffset, DiskSize); + break; + + // + // memory buffer + // + case FileTypeMemBuffer: + Status = HMemImageSave (MemOffset, MemSize); + break; + + default: + Status = EFI_NOT_FOUND; + break; + } + + if (EFI_ERROR (Status)) { + HBufferImage.BufferType = BufferTypeBackup; + } + + return Status; +} + +/** + Create a new line and append it to the line list. + Fields affected: + NumLines + Lines + + @retval NULL create line failed. + @return the line created. + +**/ +HEFI_EDITOR_LINE * +HBufferImageCreateLine ( + VOID + ) +{ + HEFI_EDITOR_LINE *Line; + + // + // allocate for line structure + // + Line = AllocateZeroPool (sizeof (HEFI_EDITOR_LINE)); + if (Line == NULL) { + return NULL; + } + + Line->Signature = EFI_EDITOR_LINE_LIST; + Line->Size = 0; + + HBufferImage.NumLines++; + + // + // insert to line list + // + InsertTailList (HBufferImage.ListHead, &Line->Link); + + if (HBufferImage.Lines == NULL) { + HBufferImage.Lines = CR ( + HBufferImage.ListHead->ForwardLink, + HEFI_EDITOR_LINE, + Link, + EFI_EDITOR_LINE_LIST + ); + } + + return Line; +} + +/** + Free the current image. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageFree ( + VOID + ) +{ + // + // free all lines + // + HBufferImageFreeLines (); + + return EFI_SUCCESS; +} + +/** + change char to int value based on Hex. + + @param[in] Char The input char. + + @return The character's index value. + @retval -1 The operation failed. +**/ +INTN +HBufferImageCharToHex ( + IN CHAR16 Char + ) +{ + // + // change the character to hex + // + if ((Char >= L'0') && (Char <= L'9')) { + return (Char - L'0'); + } + + if ((Char >= L'a') && (Char <= L'f')) { + return (Char - L'a' + 10); + } + + if ((Char >= L'A') && (Char <= L'F')) { + return (Char - L'A' + 10); + } + + return -1; +} + +/** + Add character. + + @param[in] Char -- input char. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HBufferImageAddChar ( + IN CHAR16 Char + ) +{ + HEFI_EDITOR_LINE *Line; + HEFI_EDITOR_LINE *NewLine; + INTN Value; + UINT8 Old; + UINTN FRow; + UINTN FCol; + BOOLEAN High; + + Value = HBufferImageCharToHex (Char); + + // + // invalid input + // + if (Value == -1) { + return EFI_SUCCESS; + } + + Line = HBufferImage.CurrentLine; + FRow = HBufferImage.BufferPosition.Row; + FCol = HBufferImage.BufferPosition.Column; + High = HBufferImage.HighBits; + + // + // only needs to refresh current line + // + HBufferImageOnlyLineNeedRefresh = TRUE; + + // + // not a full line and beyond the last character + // + if (FCol > Line->Size) { + // + // cursor always at high 4 bits + // and always put input to the low 4 bits + // + Line->Buffer[Line->Size] = (UINT8)Value; + Line->Size++; + High = FALSE; + } else { + Old = Line->Buffer[FCol - 1]; + + // + // always put the input to the low 4 bits + // + Old = (UINT8)(Old & 0x0f); + Old = (UINT8)(Old << 4); + Old = (UINT8)(Value + Old); + Line->Buffer[FCol - 1] = Old; + + // + // at the low 4 bits of the last character of a full line + // so if no next line, need to create a new line + // + if (!High && (FCol == 0x10)) { + HBufferImageOnlyLineNeedRefresh = FALSE; + HBufferImageNeedRefresh = TRUE; + + if (Line->Link.ForwardLink == HBufferImage.ListHead) { + // + // last line + // + // create a new line + // + NewLine = HBufferImageCreateLine (); + if (NewLine == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // end of NULL + // + } + + // + // end of == ListHead + // + } + + // + // end of == 0x10 + // + // if already at end of this line, scroll it to the start of next line + // + if ((FCol == 0x10) && !High) { + // + // definitely has next line + // + FRow++; + FCol = 1; + High = TRUE; + } else { + // + // if not at end of this line, just move to next column + // + if (!High) { + FCol++; + } + + if (High) { + High = FALSE; + } else { + High = TRUE; + } + } + + // + // end of ==FALSE + // + } + + // + // move cursor to right + // + HBufferImageMovePosition (FRow, FCol, High); + + if (!HBufferImage.Modified) { + HBufferImage.Modified = TRUE; + } + + return EFI_SUCCESS; +} + +/** + Delete the previous character. + + @retval EFI_SUCCESS The operationw as successful. +**/ +EFI_STATUS +HBufferImageDoBackspace ( + VOID + ) +{ + HEFI_EDITOR_LINE *Line; + + UINTN FileColumn; + UINTN FPos; + BOOLEAN LastLine; + + // + // variable initialization + // + LastLine = FALSE; + + // + // already the first character + // + if ((HBufferImage.BufferPosition.Row == 1) && (HBufferImage.BufferPosition.Column == 1)) { + return EFI_SUCCESS; + } + + FPos = (HBufferImage.BufferPosition.Row - 1) * 0x10 + HBufferImage.BufferPosition.Column - 1; + + FileColumn = HBufferImage.BufferPosition.Column; + + Line = HBufferImage.CurrentLine; + LastLine = FALSE; + if ((Line->Link.ForwardLink == HBufferImage.ListHead) && (FileColumn > 1)) { + LastLine = TRUE; + } + + HBufferImageDeleteCharacterFromBuffer (FPos - 1, 1, NULL); + + // + // if is the last line + // then only this line need to be refreshed + // + if (LastLine) { + HBufferImageNeedRefresh = FALSE; + HBufferImageOnlyLineNeedRefresh = TRUE; + } else { + HBufferImageNeedRefresh = TRUE; + HBufferImageOnlyLineNeedRefresh = FALSE; + } + + if (!HBufferImage.Modified) { + HBufferImage.Modified = TRUE; + } + + return EFI_SUCCESS; +} + +/** + ASCII key + Backspace + return. + + @param[in] Char The input char. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HBufferImageDoCharInput ( + IN CHAR16 Char + ) +{ + EFI_STATUS Status; + + Status = EFI_SUCCESS; + + switch (Char) { + case 0: + break; + + case 0x08: + Status = HBufferImageDoBackspace (); + break; + + case 0x09: + case 0x0a: + case 0x0d: + // + // Tabs, Returns are thought as nothing + // + break; + + default: + // + // DEAL WITH ASCII CHAR, filter out thing like ctrl+f + // + if ((Char > 127) || (Char < 32)) { + Status = StatusBarSetStatusString (L"Unknown Command"); + } else { + Status = HBufferImageAddChar (Char); + } + + break; + } + + return Status; +} + +/** + Check user specified FileRow is above current screen. + + @param[in] FileRow Row of file position ( start from 1 ). + + @retval TRUE It is above the current screen. + @retval FALSE It is not above the current screen. + +**/ +BOOLEAN +HAboveCurrentScreen ( + IN UINTN FileRow + ) +{ + if (FileRow < HBufferImage.LowVisibleRow) { + return TRUE; + } + + return FALSE; +} + +/** + Check user specified FileRow is under current screen. + + @param[in] FileRow Row of file position ( start from 1 ). + + @retval TRUE It is under the current screen. + @retval FALSE It is not under the current screen. + +**/ +BOOLEAN +HUnderCurrentScreen ( + IN UINTN FileRow + ) +{ + if (FileRow > HBufferImage.LowVisibleRow + (HMainEditor.ScreenSize.Row - 2) - 1) { + return TRUE; + } + + return FALSE; +} + +/** + According to cursor's file position, adjust screen display. + + @param[in] NewFilePosRow Row of file position ( start from 1 ). + @param[in] NewFilePosCol Column of file position ( start from 1 ). + @param[in] HighBits Cursor will on high4 bits or low4 bits. +**/ +VOID +HBufferImageMovePosition ( + IN UINTN NewFilePosRow, + IN UINTN NewFilePosCol, + IN BOOLEAN HighBits + ) +{ + INTN RowGap; + UINTN Abs; + BOOLEAN Above; + BOOLEAN Under; + UINTN NewDisplayCol; + + // + // CALCULATE gap between current file position and new file position + // + RowGap = NewFilePosRow - HBufferImage.BufferPosition.Row; + + Under = HUnderCurrentScreen (NewFilePosRow); + Above = HAboveCurrentScreen (NewFilePosRow); + + HBufferImage.HighBits = HighBits; + + // + // if is below current screen + // + if (Under) { + // + // display row will be unchanged + // + HBufferImage.BufferPosition.Row = NewFilePosRow; + } else { + if (Above) { + // + // has enough above line, so display row unchanged + // not has enough above lines, so the first line is + // at the first display line + // + if (NewFilePosRow < (HBufferImage.DisplayPosition.Row - 2 + 1)) { + HBufferImage.DisplayPosition.Row = NewFilePosRow + 2 - 1; + } + + HBufferImage.BufferPosition.Row = NewFilePosRow; + } else { + // + // in current screen + // + HBufferImage.BufferPosition.Row = NewFilePosRow; + if (RowGap <= 0) { + Abs = (UINTN)ABS (RowGap); + HBufferImage.DisplayPosition.Row -= Abs; + } else { + HBufferImage.DisplayPosition.Row += RowGap; + } + } + } + + HBufferImage.LowVisibleRow = HBufferImage.BufferPosition.Row - (HBufferImage.DisplayPosition.Row - 2); + + // + // always in current screen + // + HBufferImage.BufferPosition.Column = NewFilePosCol; + + NewDisplayCol = 10 + (NewFilePosCol - 1) * 3; + if (NewFilePosCol > 0x8) { + NewDisplayCol++; + } + + if (!HighBits) { + NewDisplayCol++; + } + + HBufferImage.DisplayPosition.Column = NewDisplayCol; + + // + // let CurrentLine point to correct line; + // + HBufferImage.CurrentLine = HMoveCurrentLine (RowGap); +} + +/** + Scroll cursor to right. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageScrollRight ( + VOID + ) +{ + HEFI_EDITOR_LINE *Line; + UINTN FRow; + UINTN FCol; + + // + // scroll right will always move to the high4 bits of the next character + // + HBufferImageNeedRefresh = FALSE; + HBufferImageOnlyLineNeedRefresh = FALSE; + + Line = HBufferImage.CurrentLine; + + FRow = HBufferImage.BufferPosition.Row; + FCol = HBufferImage.BufferPosition.Column; + + // + // this line is not full and no next line + // + if (FCol > Line->Size) { + return EFI_SUCCESS; + } + + // + // if already at end of this line, scroll it to the start of next line + // + if (FCol == 0x10) { + // + // has next line + // + if (Line->Link.ForwardLink != HBufferImage.ListHead) { + FRow++; + FCol = 1; + } else { + return EFI_SUCCESS; + } + } else { + // + // if not at end of this line, just move to next column + // + FCol++; + } + + HBufferImageMovePosition (FRow, FCol, TRUE); + + return EFI_SUCCESS; +} + +/** + Scroll cursor to left. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageScrollLeft ( + VOID + ) +{ + HEFI_EDITOR_LINE *Line; + UINTN FRow; + UINTN FCol; + + HBufferImageNeedRefresh = FALSE; + HBufferImageOnlyLineNeedRefresh = FALSE; + + Line = HBufferImage.CurrentLine; + + FRow = HBufferImage.BufferPosition.Row; + FCol = HBufferImage.BufferPosition.Column; + + // + // if already at start of this line, so move to the end of previous line + // + if (FCol <= 1) { + // + // has previous line + // + if (Line->Link.BackLink != HBufferImage.ListHead) { + FRow--; + Line = CR (Line->Link.BackLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); + FCol = Line->Size; + } else { + return EFI_SUCCESS; + } + } else { + // + // if not at start of this line, just move to previous column + // + FCol--; + } + + HBufferImageMovePosition (FRow, FCol, TRUE); + + return EFI_SUCCESS; +} + +/** + Scroll cursor to the next line + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageScrollDown ( + VOID + ) +{ + HEFI_EDITOR_LINE *Line; + UINTN FRow; + UINTN FCol; + BOOLEAN HighBits; + + Line = HBufferImage.CurrentLine; + + FRow = HBufferImage.BufferPosition.Row; + FCol = HBufferImage.BufferPosition.Column; + HighBits = HBufferImage.HighBits; + + // + // has next line + // + if (Line->Link.ForwardLink != HBufferImage.ListHead) { + FRow++; + Line = CR (Line->Link.ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); + + // + // if the next line is not that long, so move to end of next line + // + if (FCol > Line->Size) { + FCol = Line->Size + 1; + HighBits = TRUE; + } + } else { + return EFI_SUCCESS; + } + + HBufferImageMovePosition (FRow, FCol, HighBits); + + return EFI_SUCCESS; +} + +/** + Scroll cursor to previous line + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageScrollUp ( + VOID + ) +{ + HEFI_EDITOR_LINE *Line; + UINTN FRow; + UINTN FCol; + + Line = HBufferImage.CurrentLine; + + FRow = HBufferImage.BufferPosition.Row; + FCol = HBufferImage.BufferPosition.Column; + + // + // has previous line + // + if (Line->Link.BackLink != HBufferImage.ListHead) { + FRow--; + } else { + return EFI_SUCCESS; + } + + HBufferImageMovePosition (FRow, FCol, HBufferImage.HighBits); + + return EFI_SUCCESS; +} + +/** + Scroll cursor to next page + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImagePageDown ( + VOID + ) +{ + HEFI_EDITOR_LINE *Line; + UINTN FRow; + UINTN FCol; + UINTN Gap; + BOOLEAN HighBits; + + Line = HBufferImage.CurrentLine; + + FRow = HBufferImage.BufferPosition.Row; + FCol = HBufferImage.BufferPosition.Column; + HighBits = HBufferImage.HighBits; + + // + // has next page + // + if (HBufferImage.NumLines >= FRow + (HMainEditor.ScreenSize.Row - 2)) { + Gap = (HMainEditor.ScreenSize.Row - 2); + } else { + // + // MOVE CURSOR TO LAST LINE + // + Gap = HBufferImage.NumLines - FRow; + } + + // + // get correct line + // + Line = HMoveLine (Gap); + + // + // if that line, is not that long, so move to the end of that line + // + if ((Line != NULL) && (FCol > Line->Size)) { + FCol = Line->Size + 1; + HighBits = TRUE; + } + + FRow += Gap; + + HBufferImageMovePosition (FRow, FCol, HighBits); + + return EFI_SUCCESS; +} + +/** + Scroll cursor to previous page + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImagePageUp ( + VOID + ) +{ + UINTN FRow; + UINTN FCol; + UINTN Gap; + INTN Retreat; + + FRow = HBufferImage.BufferPosition.Row; + FCol = HBufferImage.BufferPosition.Column; + + // + // has previous page + // + if (FRow > (HMainEditor.ScreenSize.Row - 2)) { + Gap = (HMainEditor.ScreenSize.Row - 2); + } else { + // + // the first line of file will displayed on the first line of screen + // + Gap = FRow - 1; + } + + Retreat = Gap; + Retreat = -Retreat; + + FRow -= Gap; + + HBufferImageMovePosition (FRow, FCol, HBufferImage.HighBits); + + return EFI_SUCCESS; +} + +/** + Scroll cursor to start of line + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageHome ( + VOID + ) +{ + UINTN FRow; + UINTN FCol; + BOOLEAN HighBits; + + // + // curosr will at the high bit + // + FRow = HBufferImage.BufferPosition.Row; + FCol = 1; + HighBits = TRUE; + + // + // move cursor position + // + HBufferImageMovePosition (FRow, FCol, HighBits); + + return EFI_SUCCESS; +} + +/** + Scroll cursor to end of line. + + @retval EFI_SUCCESS Teh operation was successful. +**/ +EFI_STATUS +HBufferImageEnd ( + VOID + ) +{ + HEFI_EDITOR_LINE *Line; + UINTN FRow; + UINTN FCol; + BOOLEAN HighBits; + + // + // need refresh mouse + // + HBufferImageMouseNeedRefresh = TRUE; + + Line = HBufferImage.CurrentLine; + + FRow = HBufferImage.BufferPosition.Row; + + if (Line->Size == 0x10) { + FCol = Line->Size; + HighBits = FALSE; + } else { + FCol = Line->Size + 1; + HighBits = TRUE; + } + + // + // move cursor position + // + HBufferImageMovePosition (FRow, FCol, HighBits); + + return EFI_SUCCESS; +} + +/** + Get the size of the open buffer. + + @retval The size in bytes. +**/ +UINTN +HBufferImageGetTotalSize ( + VOID + ) +{ + UINTN Size; + + HEFI_EDITOR_LINE *Line; + + // + // calculate the total size of whole line list's buffer + // + if (HBufferImage.Lines == NULL) { + return 0; + } + + Line = CR ( + HBufferImage.ListHead->BackLink, + HEFI_EDITOR_LINE, + Link, + EFI_EDITOR_LINE_LIST + ); + // + // one line at most 0x10 + // + Size = 0x10 * (HBufferImage.NumLines - 1) + Line->Size; + + return Size; +} + +/** + Delete character from buffer. + + @param[in] Pos Position, Pos starting from 0. + @param[in] Count The Count of characters to delete. + @param[out] DeleteBuffer The DeleteBuffer. + + @retval EFI_SUCCESS Success +**/ +EFI_STATUS +HBufferImageDeleteCharacterFromBuffer ( + IN UINTN Pos, + IN UINTN Count, + OUT UINT8 *DeleteBuffer + ) +{ + UINTN Index; + + VOID *Buffer; + UINT8 *BufferPtr; + UINTN Size; + + HEFI_EDITOR_LINE *Line; + LIST_ENTRY *Link; + + UINTN OldFCol; + UINTN OldFRow; + UINTN OldPos; + + UINTN NewPos; + + EFI_STATUS Status; + + Size = HBufferImageGetTotalSize (); + + if (Size < Count) { + return EFI_LOAD_ERROR; + } + + if (Size == 0) { + return EFI_SUCCESS; + } + + // + // relocate all the HBufferImage fields + // + OldFRow = HBufferImage.BufferPosition.Row; + OldFCol = HBufferImage.BufferPosition.Column; + OldPos = (OldFRow - 1) * 0x10 + OldFCol - 1; + + if (Pos > 0) { + // + // has character before it, + // so locate according to block's previous character + // + NewPos = Pos - 1; + } else { + // + // has no character before it, + // so locate according to block's next character + // + NewPos = 0; + } + + HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE); + + Buffer = AllocateZeroPool (Size); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + HBufferImageListToBuffer (Buffer, Size); + + BufferPtr = (UINT8 *)Buffer; + + // + // pass deleted buffer out + // + if (DeleteBuffer != NULL) { + for (Index = 0; Index < Count; Index++) { + DeleteBuffer[Index] = BufferPtr[Pos + Index]; + } + } + + // + // delete the part from Pos + // + for (Index = Pos; Index < Size - Count; Index++) { + BufferPtr[Index] = BufferPtr[Index + Count]; + } + + Size -= Count; + + HBufferImageFreeLines (); + + Status = HBufferImageBufferToList (Buffer, Size); + FreePool (Buffer); + + if (EFI_ERROR (Status)) { + return Status; + } + + Link = HMainEditor.BufferImage->ListHead->ForwardLink; + for (Index = 0; Index < NewPos / 0x10; Index++) { + Link = Link->ForwardLink; + } + + Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); + HBufferImage.CurrentLine = Line; + + // + // if current cursor position if inside select area + // then move it to the block's NEXT character + // + if ((OldPos >= Pos) && (OldPos < (Pos + Count))) { + NewPos = Pos; + } else { + if (OldPos < Pos) { + NewPos = OldPos; + } else { + NewPos = OldPos - Count; + } + } + + HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE); + + return EFI_SUCCESS; +} + +/** + Add character to buffer, add before pos. + + @param[in] Pos Position, Pos starting from 0. + @param[in] Count Count of characters to add. + @param[in] AddBuffer Add buffer. + + @retval EFI_SUCCESS Success. +**/ +EFI_STATUS +HBufferImageAddCharacterToBuffer ( + IN UINTN Pos, + IN UINTN Count, + IN UINT8 *AddBuffer + ) +{ + INTN Index; + + VOID *Buffer; + UINT8 *BufferPtr; + UINTN Size; + + HEFI_EDITOR_LINE *Line; + + LIST_ENTRY *Link; + + UINTN OldFCol; + UINTN OldFRow; + UINTN OldPos; + + UINTN NewPos; + + Size = HBufferImageGetTotalSize (); + + // + // relocate all the HBufferImage fields + // + OldFRow = HBufferImage.BufferPosition.Row; + OldFCol = HBufferImage.BufferPosition.Column; + OldPos = (OldFRow - 1) * 0x10 + OldFCol - 1; + + // + // move cursor before Pos + // + if (Pos > 0) { + NewPos = Pos - 1; + } else { + NewPos = 0; + } + + HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE); + + Buffer = AllocateZeroPool (Size + Count); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + HBufferImageListToBuffer (Buffer, Size); + + BufferPtr = (UINT8 *)Buffer; + + // + // get a place to add + // + for (Index = (INTN)(Size + Count - 1); Index >= (INTN)Pos; Index--) { + BufferPtr[Index] = BufferPtr[Index - Count]; + } + + // + // add the buffer + // + for (Index = (INTN)0; Index < (INTN)Count; Index++) { + BufferPtr[Index + Pos] = AddBuffer[Index]; + } + + Size += Count; + + HBufferImageFreeLines (); + + HBufferImageBufferToList (Buffer, Size); + + FreePool (Buffer); + + Link = HMainEditor.BufferImage->ListHead->ForwardLink; + for (Index = 0; Index < (INTN)NewPos / 0x10; Index++) { + Link = Link->ForwardLink; + } + + Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); + HBufferImage.CurrentLine = Line; + + if (OldPos >= Pos) { + NewPos = OldPos + Count; + } else { + NewPos = OldPos; + } + + HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE); + + return EFI_SUCCESS; +} + +/** + Delete current character from line. + + @retval EFI_SUCCESS The operationw as successful. +**/ +EFI_STATUS +HBufferImageDoDelete ( + VOID + ) +{ + HEFI_EDITOR_LINE *Line; + + BOOLEAN LastLine; + UINTN FileColumn; + UINTN FPos; + + FPos = (HBufferImage.BufferPosition.Row - 1) * 0x10 + HBufferImage.BufferPosition.Column - 1; + + FileColumn = HBufferImage.BufferPosition.Column; + + Line = HBufferImage.CurrentLine; + + // + // if beyond the last character + // + if (FileColumn > Line->Size) { + return EFI_SUCCESS; + } + + LastLine = FALSE; + if (Line->Link.ForwardLink == HBufferImage.ListHead) { + LastLine = TRUE; + } + + HBufferImageDeleteCharacterFromBuffer (FPos, 1, NULL); + + // + // if is the last line + // then only this line need to be refreshed + // + if (LastLine) { + HBufferImageNeedRefresh = FALSE; + HBufferImageOnlyLineNeedRefresh = TRUE; + } else { + HBufferImageNeedRefresh = TRUE; + HBufferImageOnlyLineNeedRefresh = FALSE; + } + + if (!HBufferImage.Modified) { + HBufferImage.Modified = TRUE; + } + + return EFI_SUCCESS; +} + +/** + Change the raw buffer to a list of lines for the UI. + + @param[in] Buffer The pointer to the buffer to fill. + @param[in] Bytes The size of the buffer in bytes. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HBufferImageBufferToList ( + IN VOID *Buffer, + IN UINTN Bytes + ) +{ + UINTN TempI; + UINTN TempJ; + UINTN Left; + HEFI_EDITOR_LINE *Line; + UINT8 *BufferPtr; + + TempI = 0; + Left = 0; + BufferPtr = (UINT8 *)Buffer; + + // + // parse file content line by line + // + while (TempI < Bytes) { + if (Bytes - TempI >= 0x10) { + Left = 0x10; + } else { + Left = Bytes - TempI; + } + + // + // allocate a new line + // + Line = HBufferImageCreateLine (); + if (Line == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Line->Size = Left; + + for (TempJ = 0; TempJ < Left; TempJ++) { + Line->Buffer[TempJ] = BufferPtr[TempI]; + TempI++; + } + } + + // + // last line is a full line, SO create a new line + // + if ((Left == 0x10) || (Bytes == 0)) { + Line = HBufferImageCreateLine (); + if (Line == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + return EFI_SUCCESS; +} + +/** + Change the list of lines from the UI to a raw buffer. + + @param[in] Buffer The pointer to the buffer to fill. + @param[in] Bytes The size of the buffer in bytes. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageListToBuffer ( + IN VOID *Buffer, + IN UINTN Bytes + ) +{ + UINTN Count; + UINTN Index; + HEFI_EDITOR_LINE *Line; + LIST_ENTRY *Link; + UINT8 *BufferPtr; + + // + // change the line list to a large buffer + // + if (HBufferImage.Lines == NULL) { + return EFI_SUCCESS; + } + + Link = &HBufferImage.Lines->Link; + Count = 0; + BufferPtr = (UINT8 *)Buffer; + + // + // deal line by line + // + while (Link != HBufferImage.ListHead) { + Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); + + // @todo shouldn't this be an error??? + if (Count + Line->Size > Bytes) { + return EFI_SUCCESS; + } + + for (Index = 0; Index < Line->Size; Index++) { + BufferPtr[Index] = Line->Buffer[Index]; + } + + Count += Line->Size; + BufferPtr += Line->Size; + + Link = Link->ForwardLink; + } + + return EFI_SUCCESS; +} + +/** + Move the mouse in the image buffer. + + @param[in] TextX The x-coordinate. + @param[in] TextY The y-coordinate. +**/ +VOID +HBufferImageAdjustMousePosition ( + IN INT32 TextX, + IN INT32 TextY + ) +{ + UINTN TempX; + UINTN TempY; + UINTN AbsX; + UINTN AbsY; + + // + // TextX and TextY is mouse movement data returned by mouse driver + // This function will change it to MousePosition + // + // + // get absolute TempX value + // + if (TextX >= 0) { + AbsX = TextX; + } else { + AbsX = -TextX; + } + + // + // get absolute TempY value + // + if (TextY >= 0) { + AbsY = TextY; + } else { + AbsY = -TextY; + } + + TempX = HBufferImage.MousePosition.Column; + TempY = HBufferImage.MousePosition.Row; + + if (TextX >= 0) { + TempX += TextX; + } else { + if (TempX >= AbsX) { + TempX -= AbsX; + } else { + TempX = 0; + } + } + + if (TextY >= 0) { + TempY += TextY; + } else { + if (TempY >= AbsY) { + TempY -= AbsY; + } else { + TempY = 0; + } + } + + // + // check whether new mouse column position is beyond screen + // if not, adjust it + // + if ((TempX >= 10) && (TempX <= (10 + 0x10 * 3 - 1))) { + HBufferImage.MousePosition.Column = TempX; + } else if (TempX < 10) { + HBufferImage.MousePosition.Column = 10; + } else if (TempX > (10 + 0x10 * 3 - 1)) { + HBufferImage.MousePosition.Column = 10 + 0x10 * 3 - 1; + } + + // + // check whether new mouse row position is beyond screen + // if not, adjust it + // + if ((TempY >= 2) && (TempY <= (HMainEditor.ScreenSize.Row - 1))) { + HBufferImage.MousePosition.Row = TempY; + } else if (TempY < 2) { + HBufferImage.MousePosition.Row = 2; + } else if (TempY > (HMainEditor.ScreenSize.Row - 1)) { + HBufferImage.MousePosition.Row = (HMainEditor.ScreenSize.Row - 1); + } +} + +/** + Dispatch input to different handler + + @param[in] Key The input key: + the keys can be: + ASCII KEY + Backspace/Delete + Direction key: up/down/left/right/pgup/pgdn + Home/End + INS + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_OUT_OF_RESOURCES A Memory allocation failed. +**/ +EFI_STATUS +HBufferImageHandleInput ( + IN EFI_INPUT_KEY *Key + ) +{ + EFI_STATUS Status; + + Status = EFI_SUCCESS; + + switch (Key->ScanCode) { + // + // ordinary key + // + case SCAN_NULL: + Status = HBufferImageDoCharInput (Key->UnicodeChar); + break; + + // + // up arrow + // + case SCAN_UP: + Status = HBufferImageScrollUp (); + break; + + // + // down arrow + // + case SCAN_DOWN: + Status = HBufferImageScrollDown (); + break; + + // + // right arrow + // + case SCAN_RIGHT: + Status = HBufferImageScrollRight (); + break; + + // + // left arrow + // + case SCAN_LEFT: + Status = HBufferImageScrollLeft (); + break; + + // + // page up + // + case SCAN_PAGE_UP: + Status = HBufferImagePageUp (); + break; + + // + // page down + // + case SCAN_PAGE_DOWN: + Status = HBufferImagePageDown (); + break; + + // + // delete + // + case SCAN_DELETE: + Status = HBufferImageDoDelete (); + break; + + // + // home + // + case SCAN_HOME: + Status = HBufferImageHome (); + break; + + // + // end + // + case SCAN_END: + Status = HBufferImageEnd (); + break; + + default: + Status = StatusBarSetStatusString (L"Unknown Command"); + break; + } + + return Status; +} diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/BufferImage.h b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/BufferImage.h index 777a7ce93b..938fa4f898 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/BufferImage.h +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/BufferImage.h @@ -1,266 +1,266 @@ -/** @file
- Defines BufferImage - the view of the file that is visible at any point,
- as well as the event handlers for editing the file
-
- Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _LIB_BUFFER_IMAGE_H_
-#define _LIB_BUFFER_IMAGE_H_
-
-#include "HexEditor.h"
-
-/**
- Initialization function for HBufferImage
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_LOAD_ERROR A load error occurred.
-**/
-EFI_STATUS
-HBufferImageInit (
- VOID
- );
-
-/**
- Cleanup function for HBufferImage
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HBufferImageCleanup (
- VOID
- );
-
-/**
- Refresh function for HBufferImage.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_LOAD_ERROR A Load error occurred.
-
-**/
-EFI_STATUS
-HBufferImageRefresh (
- VOID
- );
-
-/**
- Dispatch input to different handler
-
- @param[in] Key The input key:
- the keys can be:
- ASCII KEY
- Backspace/Delete
- Direction key: up/down/left/right/pgup/pgdn
- Home/End
- INS
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_LOAD_ERROR A load error occurred.
- @retval EFI_OUT_OF_RESOURCES A Memory allocation failed.
-**/
-EFI_STATUS
-HBufferImageHandleInput (
- IN EFI_INPUT_KEY *Key
- );
-
-/**
- Backup function for HBufferImage. Only a few fields need to be backup.
- This is for making the file buffer refresh as few as possible.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HBufferImageBackup (
- VOID
- );
-
-/**
- Read an image into a buffer friom a source.
-
- @param[in] FileName Pointer to the file name. OPTIONAL and ignored if not FileTypeFileBuffer.
- @param[in] DiskName Pointer to the disk name. OPTIONAL and ignored if not FileTypeDiskBuffer.
- @param[in] DiskOffset Offset into the disk. OPTIONAL and ignored if not FileTypeDiskBuffer.
- @param[in] DiskSize Size of the disk buffer. OPTIONAL and ignored if not FileTypeDiskBuffer.
- @param[in] MemOffset Offset into the Memory. OPTIONAL and ignored if not FileTypeMemBuffer.
- @param[in] MemSize Size of the Memory buffer. OPTIONAL and ignored if not FileTypeMemBuffer.
- @param[in] BufferType The type of buffer to save. IGNORED.
- @param[in] Recover TRUE for recovermode, FALSE otherwise.
-
- @return EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HBufferImageRead (
- IN CONST CHAR16 *FileName,
- IN CONST CHAR16 *DiskName,
- IN UINTN DiskOffset,
- IN UINTN DiskSize,
- IN UINTN MemOffset,
- IN UINTN MemSize,
- IN EDIT_FILE_TYPE BufferType,
- IN BOOLEAN Recover
- );
-
-/**
- Save the current image.
-
- @param[in] FileName Pointer to the file name. OPTIONAL and ignored if not FileTypeFileBuffer.
- @param[in] DiskName Pointer to the disk name. OPTIONAL and ignored if not FileTypeDiskBuffer.
- @param[in] DiskOffset Offset into the disk. OPTIONAL and ignored if not FileTypeDiskBuffer.
- @param[in] DiskSize Size of the disk buffer. OPTIONAL and ignored if not FileTypeDiskBuffer.
- @param[in] MemOffset Offset into the Memory. OPTIONAL and ignored if not FileTypeMemBuffer.
- @param[in] MemSize Size of the Memory buffer. OPTIONAL and ignored if not FileTypeMemBuffer.
- @param[in] BufferType The type of buffer to save. IGNORED.
-
- @return EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HBufferImageSave (
- IN CHAR16 *FileName,
- IN CHAR16 *DiskName,
- IN UINTN DiskOffset,
- IN UINTN DiskSize,
- IN UINTN MemOffset,
- IN UINTN MemSize,
- IN EDIT_FILE_TYPE BufferType
- );
-
-/**
- According to cursor's file position, adjust screen display.
-
- @param[in] NewFilePosRow Row of file position ( start from 1 ).
- @param[in] NewFilePosCol Column of file position ( start from 1 ).
- @param[in] HighBits Cursor will on high4 bits or low4 bits.
-**/
-VOID
-HBufferImageMovePosition (
- IN UINTN NewFilePosRow,
- IN UINTN NewFilePosCol,
- IN BOOLEAN HighBits
- );
-
-/**
- Create a new line and append it to the line list.
- Fields affected:
- NumLines
- Lines
-
- @retval NULL create line failed.
- @return the line created.
-
-**/
-HEFI_EDITOR_LINE *
-HBufferImageCreateLine (
- VOID
- );
-
-/**
- Free the current image.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HBufferImageFree (
- VOID
- );
-
-/**
- Delete character from buffer.
-
- @param[in] Pos Position, Pos starting from 0.
- @param[in] Count The Count of characters to delete.
- @param[out] DeleteBuffer The DeleteBuffer.
-
- @retval EFI_SUCCESS Success
-**/
-EFI_STATUS
-HBufferImageDeleteCharacterFromBuffer (
- IN UINTN Pos,
- IN UINTN Count,
- OUT UINT8 *DeleteBuffer
- );
-
-/**
- Add character to buffer, add before pos.
-
- @param[in] Pos Position, Pos starting from 0.
- @param[in] Count Count of characters to add.
- @param[in] AddBuffer Add buffer.
-
- @retval EFI_SUCCESS Success.
-**/
-EFI_STATUS
-HBufferImageAddCharacterToBuffer (
- IN UINTN Pos,
- IN UINTN Count,
- IN UINT8 *AddBuffer
- );
-
-/**
- Change the raw buffer to a list of lines for the UI.
-
- @param[in] Buffer The pointer to the buffer to fill.
- @param[in] Bytes The size of the buffer in bytes.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
-**/
-EFI_STATUS
-HBufferImageBufferToList (
- IN VOID *Buffer,
- IN UINTN Bytes
- );
-
-/**
- Change the list of lines from the UI to a raw buffer.
-
- @param[in] Buffer The pointer to the buffer to fill.
- @param[in] Bytes The size of the buffer in bytes.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HBufferImageListToBuffer (
- IN VOID *Buffer,
- IN UINTN Bytes
- );
-
-/**
- Move the mouse in the image buffer.
-
- @param[in] TextX The x-coordinate.
- @param[in] TextY The y-coordinate.
-**/
-VOID
-HBufferImageAdjustMousePosition (
- IN INT32 TextX,
- IN INT32 TextY
- );
-
-/**
- Function to decide if a column number is stored in the high bits.
-
- @param[in] Column The column to examine.
- @param[out] FCol The actual column number.
-
- @retval TRUE The actual column was in high bits and is now in FCol.
- @retval FALSE There was not a column number in the high bits.
-**/
-BOOLEAN
-HBufferImageIsAtHighBits (
- IN UINTN Column,
- OUT UINTN *FCol
- );
-
-/**
- Get the size of the open buffer.
-
- @retval The size in bytes.
-**/
-UINTN
-HBufferImageGetTotalSize (
- VOID
- );
-
-#endif
+/** @file + Defines BufferImage - the view of the file that is visible at any point, + as well as the event handlers for editing the file + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _LIB_BUFFER_IMAGE_H_ +#define _LIB_BUFFER_IMAGE_H_ + +#include "HexEditor.h" + +/** + Initialization function for HBufferImage + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HBufferImageInit ( + VOID + ); + +/** + Cleanup function for HBufferImage + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageCleanup ( + VOID + ); + +/** + Refresh function for HBufferImage. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A Load error occurred. + +**/ +EFI_STATUS +HBufferImageRefresh ( + VOID + ); + +/** + Dispatch input to different handler + + @param[in] Key The input key: + the keys can be: + ASCII KEY + Backspace/Delete + Direction key: up/down/left/right/pgup/pgdn + Home/End + INS + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_OUT_OF_RESOURCES A Memory allocation failed. +**/ +EFI_STATUS +HBufferImageHandleInput ( + IN EFI_INPUT_KEY *Key + ); + +/** + Backup function for HBufferImage. Only a few fields need to be backup. + This is for making the file buffer refresh as few as possible. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageBackup ( + VOID + ); + +/** + Read an image into a buffer friom a source. + + @param[in] FileName Pointer to the file name. OPTIONAL and ignored if not FileTypeFileBuffer. + @param[in] DiskName Pointer to the disk name. OPTIONAL and ignored if not FileTypeDiskBuffer. + @param[in] DiskOffset Offset into the disk. OPTIONAL and ignored if not FileTypeDiskBuffer. + @param[in] DiskSize Size of the disk buffer. OPTIONAL and ignored if not FileTypeDiskBuffer. + @param[in] MemOffset Offset into the Memory. OPTIONAL and ignored if not FileTypeMemBuffer. + @param[in] MemSize Size of the Memory buffer. OPTIONAL and ignored if not FileTypeMemBuffer. + @param[in] BufferType The type of buffer to save. IGNORED. + @param[in] Recover TRUE for recovermode, FALSE otherwise. + + @return EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageRead ( + IN CONST CHAR16 *FileName, + IN CONST CHAR16 *DiskName, + IN UINTN DiskOffset, + IN UINTN DiskSize, + IN UINTN MemOffset, + IN UINTN MemSize, + IN EDIT_FILE_TYPE BufferType, + IN BOOLEAN Recover + ); + +/** + Save the current image. + + @param[in] FileName Pointer to the file name. OPTIONAL and ignored if not FileTypeFileBuffer. + @param[in] DiskName Pointer to the disk name. OPTIONAL and ignored if not FileTypeDiskBuffer. + @param[in] DiskOffset Offset into the disk. OPTIONAL and ignored if not FileTypeDiskBuffer. + @param[in] DiskSize Size of the disk buffer. OPTIONAL and ignored if not FileTypeDiskBuffer. + @param[in] MemOffset Offset into the Memory. OPTIONAL and ignored if not FileTypeMemBuffer. + @param[in] MemSize Size of the Memory buffer. OPTIONAL and ignored if not FileTypeMemBuffer. + @param[in] BufferType The type of buffer to save. IGNORED. + + @return EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageSave ( + IN CHAR16 *FileName, + IN CHAR16 *DiskName, + IN UINTN DiskOffset, + IN UINTN DiskSize, + IN UINTN MemOffset, + IN UINTN MemSize, + IN EDIT_FILE_TYPE BufferType + ); + +/** + According to cursor's file position, adjust screen display. + + @param[in] NewFilePosRow Row of file position ( start from 1 ). + @param[in] NewFilePosCol Column of file position ( start from 1 ). + @param[in] HighBits Cursor will on high4 bits or low4 bits. +**/ +VOID +HBufferImageMovePosition ( + IN UINTN NewFilePosRow, + IN UINTN NewFilePosCol, + IN BOOLEAN HighBits + ); + +/** + Create a new line and append it to the line list. + Fields affected: + NumLines + Lines + + @retval NULL create line failed. + @return the line created. + +**/ +HEFI_EDITOR_LINE * +HBufferImageCreateLine ( + VOID + ); + +/** + Free the current image. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageFree ( + VOID + ); + +/** + Delete character from buffer. + + @param[in] Pos Position, Pos starting from 0. + @param[in] Count The Count of characters to delete. + @param[out] DeleteBuffer The DeleteBuffer. + + @retval EFI_SUCCESS Success +**/ +EFI_STATUS +HBufferImageDeleteCharacterFromBuffer ( + IN UINTN Pos, + IN UINTN Count, + OUT UINT8 *DeleteBuffer + ); + +/** + Add character to buffer, add before pos. + + @param[in] Pos Position, Pos starting from 0. + @param[in] Count Count of characters to add. + @param[in] AddBuffer Add buffer. + + @retval EFI_SUCCESS Success. +**/ +EFI_STATUS +HBufferImageAddCharacterToBuffer ( + IN UINTN Pos, + IN UINTN Count, + IN UINT8 *AddBuffer + ); + +/** + Change the raw buffer to a list of lines for the UI. + + @param[in] Buffer The pointer to the buffer to fill. + @param[in] Bytes The size of the buffer in bytes. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HBufferImageBufferToList ( + IN VOID *Buffer, + IN UINTN Bytes + ); + +/** + Change the list of lines from the UI to a raw buffer. + + @param[in] Buffer The pointer to the buffer to fill. + @param[in] Bytes The size of the buffer in bytes. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageListToBuffer ( + IN VOID *Buffer, + IN UINTN Bytes + ); + +/** + Move the mouse in the image buffer. + + @param[in] TextX The x-coordinate. + @param[in] TextY The y-coordinate. +**/ +VOID +HBufferImageAdjustMousePosition ( + IN INT32 TextX, + IN INT32 TextY + ); + +/** + Function to decide if a column number is stored in the high bits. + + @param[in] Column The column to examine. + @param[out] FCol The actual column number. + + @retval TRUE The actual column was in high bits and is now in FCol. + @retval FALSE There was not a column number in the high bits. +**/ +BOOLEAN +HBufferImageIsAtHighBits ( + IN UINTN Column, + OUT UINTN *FCol + ); + +/** + Get the size of the open buffer. + + @retval The size in bytes. +**/ +UINTN +HBufferImageGetTotalSize ( + VOID + ); + +#endif diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Clipboard.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Clipboard.c index f18a7dd098..77c5920a69 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Clipboard.c +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Clipboard.c @@ -1,105 +1,105 @@ -/** @file
- Functions to deal with Clip Board
-
- Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "HexEditor.h"
-
-typedef struct {
- UINT8 *Buffer;
- UINTN Size;
-} HEFI_EDITOR_CLIPBOARD;
-
-HEFI_EDITOR_CLIPBOARD HClipBoard;
-
-//
-// for basic initialization of HClipBoard
-//
-HEFI_EDITOR_CLIPBOARD HClipBoardConst = {
- NULL,
- 0
-};
-
-/**
- Initialization function for HDiskImage.
-
- @param[in] EFI_SUCCESS The operation was successful.
- @param[in] EFI_LOAD_ERROR A load error occurred.
-**/
-EFI_STATUS
-HClipBoardInit (
- VOID
- )
-{
- //
- // basiclly initialize the HDiskImage
- //
- CopyMem (&HClipBoard, &HClipBoardConst, sizeof (HClipBoard));
-
- return EFI_SUCCESS;
-}
-
-/**
- Initialization function for HDiskImage.
-
- @param[in] EFI_SUCCESS The operation was successful.
- @param[in] EFI_LOAD_ERROR A load error occurred.
-**/
-EFI_STATUS
-HClipBoardCleanup (
- VOID
- )
-{
- SHELL_FREE_NON_NULL (HClipBoard.Buffer);
-
- return EFI_SUCCESS;
-}
-
-/**
- Set a buffer into the clipboard.
-
- @param[in] Buffer The buffer to add to the clipboard.
- @param[in] Size The size of Buffer in bytes.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HClipBoardSet (
- IN UINT8 *Buffer,
- IN UINTN Size
- )
-{
- //
- // free the old clipboard buffer
- // and set new clipboard buffer
- //
- SHELL_FREE_NON_NULL (HClipBoard.Buffer);
- HClipBoard.Buffer = Buffer;
-
- HClipBoard.Size = Size;
-
- return EFI_SUCCESS;
-}
-
-/**
- Get a buffer from the clipboard.
-
- @param[out] Buffer The pointer to the buffer to add to the clipboard.
-
- @return the size of the buffer.
-**/
-UINTN
-HClipBoardGet (
- OUT UINT8 **Buffer
- )
-{
- //
- // return the clipboard buffer
- //
- *Buffer = HClipBoard.Buffer;
-
- return HClipBoard.Size;
-}
+/** @file + Functions to deal with Clip Board + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "HexEditor.h" + +typedef struct { + UINT8 *Buffer; + UINTN Size; +} HEFI_EDITOR_CLIPBOARD; + +HEFI_EDITOR_CLIPBOARD HClipBoard; + +// +// for basic initialization of HClipBoard +// +HEFI_EDITOR_CLIPBOARD HClipBoardConst = { + NULL, + 0 +}; + +/** + Initialization function for HDiskImage. + + @param[in] EFI_SUCCESS The operation was successful. + @param[in] EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HClipBoardInit ( + VOID + ) +{ + // + // basiclly initialize the HDiskImage + // + CopyMem (&HClipBoard, &HClipBoardConst, sizeof (HClipBoard)); + + return EFI_SUCCESS; +} + +/** + Initialization function for HDiskImage. + + @param[in] EFI_SUCCESS The operation was successful. + @param[in] EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HClipBoardCleanup ( + VOID + ) +{ + SHELL_FREE_NON_NULL (HClipBoard.Buffer); + + return EFI_SUCCESS; +} + +/** + Set a buffer into the clipboard. + + @param[in] Buffer The buffer to add to the clipboard. + @param[in] Size The size of Buffer in bytes. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HClipBoardSet ( + IN UINT8 *Buffer, + IN UINTN Size + ) +{ + // + // free the old clipboard buffer + // and set new clipboard buffer + // + SHELL_FREE_NON_NULL (HClipBoard.Buffer); + HClipBoard.Buffer = Buffer; + + HClipBoard.Size = Size; + + return EFI_SUCCESS; +} + +/** + Get a buffer from the clipboard. + + @param[out] Buffer The pointer to the buffer to add to the clipboard. + + @return the size of the buffer. +**/ +UINTN +HClipBoardGet ( + OUT UINT8 **Buffer + ) +{ + // + // return the clipboard buffer + // + *Buffer = HClipBoard.Buffer; + + return HClipBoard.Size; +} diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Clipboard.h b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Clipboard.h index eaeaa00d3a..499e9fe075 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Clipboard.h +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Clipboard.h @@ -1,63 +1,63 @@ -/** @file
- Defines DiskImage - the view of the file that is visible at any point,
- as well as the event handlers for editing the file
-
- Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _LIB_CLIP_BOARD_H_
-#define _LIB_CLIP_BOARD_H_
-
-#include "HexEditor.h"
-
-/**
- Initialization function for HDiskImage
-
- @param[in] EFI_SUCCESS The operation was successful.
- @param[in] EFI_LOAD_ERROR A load error occurred.
-**/
-EFI_STATUS
-HClipBoardInit (
- VOID
- );
-
-/**
- Initialization function for HDiskImage.
-
- @param[in] EFI_SUCCESS The operation was successful.
- @param[in] EFI_LOAD_ERROR A load error occurred.
-**/
-EFI_STATUS
-HClipBoardCleanup (
- VOID
- );
-
-/**
- Set a buffer into the clipboard.
-
- @param[in] Buffer The buffer to add to the clipboard.
- @param[in] Size The size of Buffer in bytes.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HClipBoardSet (
- IN UINT8 *Buffer,
- IN UINTN Size
- );
-
-/**
- Get a buffer from the clipboard.
-
- @param[out] Buffer The pointer to the buffer to add to the clipboard.
-
- @return the size of the buffer.
-**/
-UINTN
-HClipBoardGet (
- OUT UINT8 **Buffer
- );
-
-#endif
+/** @file + Defines DiskImage - the view of the file that is visible at any point, + as well as the event handlers for editing the file + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _LIB_CLIP_BOARD_H_ +#define _LIB_CLIP_BOARD_H_ + +#include "HexEditor.h" + +/** + Initialization function for HDiskImage + + @param[in] EFI_SUCCESS The operation was successful. + @param[in] EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HClipBoardInit ( + VOID + ); + +/** + Initialization function for HDiskImage. + + @param[in] EFI_SUCCESS The operation was successful. + @param[in] EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HClipBoardCleanup ( + VOID + ); + +/** + Set a buffer into the clipboard. + + @param[in] Buffer The buffer to add to the clipboard. + @param[in] Size The size of Buffer in bytes. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HClipBoardSet ( + IN UINT8 *Buffer, + IN UINTN Size + ); + +/** + Get a buffer from the clipboard. + + @param[out] Buffer The pointer to the buffer to add to the clipboard. + + @return the size of the buffer. +**/ +UINTN +HClipBoardGet ( + OUT UINT8 **Buffer + ); + +#endif diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/DiskImage.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/DiskImage.c index f884428240..eab35eb5b9 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/DiskImage.c +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/DiskImage.c @@ -1,417 +1,417 @@ -/** @file
- Functions to deal with Disk buffer.
-
- Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "HexEditor.h"
-#include <Protocol/BlockIo.h>
-
-extern EFI_HANDLE HImageHandleBackup;
-extern HEFI_EDITOR_BUFFER_IMAGE HBufferImage;
-
-extern BOOLEAN HBufferImageNeedRefresh;
-extern BOOLEAN HBufferImageOnlyLineNeedRefresh;
-extern BOOLEAN HBufferImageMouseNeedRefresh;
-
-extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditor;
-
-HEFI_EDITOR_DISK_IMAGE HDiskImage;
-HEFI_EDITOR_DISK_IMAGE HDiskImageBackupVar;
-
-//
-// for basic initialization of HDiskImage
-//
-HEFI_EDITOR_DISK_IMAGE HDiskImageConst = {
- NULL,
- 0,
- 0,
- 0
-};
-
-/**
- Initialization function for HDiskImage.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_LOAD_ERROR A load error occurred.
-**/
-EFI_STATUS
-HDiskImageInit (
- VOID
- )
-{
- //
- // basically initialize the HDiskImage
- //
- CopyMem (&HDiskImage, &HDiskImageConst, sizeof (HDiskImage));
-
- CopyMem (&HDiskImageBackupVar, &HDiskImageConst, sizeof (HDiskImageBackupVar));
-
- return EFI_SUCCESS;
-}
-
-/**
- Backup function for HDiskImage. Only a few fields need to be backup.
- This is for making the Disk buffer refresh as few as possible.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES gST->ConOut of resources.
-**/
-EFI_STATUS
-HDiskImageBackup (
- VOID
- )
-{
- //
- // backup the disk name, offset and size
- //
- //
- SHELL_FREE_NON_NULL (HDiskImageBackupVar.Name);
-
- HDiskImageBackupVar.Name = CatSPrint (NULL, L"%s", HDiskImage.Name);
- if (HDiskImageBackupVar.Name == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- HDiskImageBackupVar.Offset = HDiskImage.Offset;
- HDiskImageBackupVar.Size = HDiskImage.Size;
-
- return EFI_SUCCESS;
-}
-
-/**
- Cleanup function for HDiskImage.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HDiskImageCleanup (
- VOID
- )
-{
- SHELL_FREE_NON_NULL (HDiskImage.Name);
- SHELL_FREE_NON_NULL (HDiskImageBackupVar.Name);
-
- return EFI_SUCCESS;
-}
-
-/**
- Set FileName field in HFileImage.
-
- @param[in] Str File name to set.
- @param[in] Offset The offset.
- @param[in] Size The size.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
-**/
-EFI_STATUS
-HDiskImageSetDiskNameOffsetSize (
- IN CONST CHAR16 *Str,
- IN UINTN Offset,
- IN UINTN Size
- )
-{
- if (Str == HDiskImage.Name) {
- //
- // This function might be called using HDiskImage.FileName as Str.
- // Directly return without updating HDiskImage.FileName.
- //
- return EFI_SUCCESS;
- }
-
- //
- // free the old file name
- //
- SHELL_FREE_NON_NULL (HDiskImage.Name);
- HDiskImage.Name = AllocateCopyPool (StrSize (Str), Str);
- if (HDiskImage.Name == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- HDiskImage.Offset = Offset;
- HDiskImage.Size = Size;
-
- return EFI_SUCCESS;
-}
-
-/**
- Read a disk from disk into HBufferImage.
-
- @param[in] DeviceName filename to read.
- @param[in] Offset The offset.
- @param[in] Size The size.
- @param[in] Recover if is for recover, no information print.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
- @retval EFI_LOAD_ERROR A load error occurred.
- @retval EFI_INVALID_PARAMETER A parameter was invalid.
-**/
-EFI_STATUS
-HDiskImageRead (
- IN CONST CHAR16 *DeviceName,
- IN UINTN Offset,
- IN UINTN Size,
- IN BOOLEAN Recover
- )
-{
- CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath;
- EFI_DEVICE_PATH_PROTOCOL *DupDevicePath;
- EFI_DEVICE_PATH_PROTOCOL *DupDevicePathForFree;
- EFI_HANDLE Handle;
- EFI_BLOCK_IO_PROTOCOL *BlkIo;
- EFI_STATUS Status;
-
- VOID *Buffer;
- CHAR16 *Str;
- UINTN Bytes;
-
- HEFI_EDITOR_LINE *Line;
-
- HBufferImage.BufferType = FileTypeDiskBuffer;
-
- DevicePath = gEfiShellProtocol->GetDevicePathFromMap (DeviceName);
- if (DevicePath == NULL) {
- StatusBarSetStatusString (L"Cannot Find Device");
- return EFI_INVALID_PARAMETER;
- }
-
- DupDevicePath = DuplicateDevicePath (DevicePath);
- DupDevicePathForFree = DupDevicePath;
- //
- // get blkio interface
- //
- Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &DupDevicePath, &Handle);
- FreePool (DupDevicePathForFree);
- if (EFI_ERROR (Status)) {
- StatusBarSetStatusString (L"Read Disk Failed");
- return Status;
- }
-
- Status = gBS->OpenProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlkIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
- if (EFI_ERROR (Status)) {
- StatusBarSetStatusString (L"Read Disk Failed");
- return Status;
- }
-
- //
- // if Offset exceeds LastBlock,
- // return error
- //
- if ((Offset > BlkIo->Media->LastBlock) || (Offset + Size > BlkIo->Media->LastBlock)) {
- StatusBarSetStatusString (L"Invalid Offset + Size");
- return EFI_LOAD_ERROR;
- }
-
- Bytes = BlkIo->Media->BlockSize * Size;
- Buffer = AllocateZeroPool (Bytes);
-
- if (Buffer == NULL) {
- StatusBarSetStatusString (L"Read Disk Failed");
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // read from disk
- //
- Status = BlkIo->ReadBlocks (
- BlkIo,
- BlkIo->Media->MediaId,
- Offset,
- Bytes,
- Buffer
- );
-
- if (EFI_ERROR (Status)) {
- FreePool (Buffer);
- StatusBarSetStatusString (L"Read Disk Failed");
- return EFI_LOAD_ERROR;
- }
-
- HBufferImageFree ();
-
- //
- // convert buffer to line list
- //
- Status = HBufferImageBufferToList (Buffer, Bytes);
- FreePool (Buffer);
-
- if (EFI_ERROR (Status)) {
- StatusBarSetStatusString (L"Read Disk Failed");
- return Status;
- }
-
- Status = HDiskImageSetDiskNameOffsetSize (DeviceName, Offset, Size);
- if (EFI_ERROR (Status)) {
- StatusBarSetStatusString (L"Read Disk Failed");
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // initialize some variables
- //
- HDiskImage.BlockSize = BlkIo->Media->BlockSize;
-
- HBufferImage.DisplayPosition.Row = 2;
- HBufferImage.DisplayPosition.Column = 10;
-
- HBufferImage.MousePosition.Row = 2;
- HBufferImage.MousePosition.Column = 10;
-
- HBufferImage.LowVisibleRow = 1;
- HBufferImage.HighBits = TRUE;
-
- HBufferImage.BufferPosition.Row = 1;
- HBufferImage.BufferPosition.Column = 1;
-
- if (!Recover) {
- Str = CatSPrint (NULL, L"%d Lines Read", HBufferImage.NumLines);
- if (Str == NULL) {
- StatusBarSetStatusString (L"Read Disk Failed");
- return EFI_OUT_OF_RESOURCES;
- }
-
- StatusBarSetStatusString (Str);
- SHELL_FREE_NON_NULL (Str);
-
- HMainEditor.SelectStart = 0;
- HMainEditor.SelectEnd = 0;
- }
-
- //
- // has line
- //
- if (HBufferImage.Lines != NULL) {
- HBufferImage.CurrentLine = CR (
- HBufferImage.ListHead->ForwardLink,
- HEFI_EDITOR_LINE,
- Link,
- EFI_EDITOR_LINE_LIST
- );
- } else {
- //
- // create a dummy line
- //
- Line = HBufferImageCreateLine ();
- if (Line == NULL) {
- StatusBarSetStatusString (L"Read Disk Failed");
- return EFI_OUT_OF_RESOURCES;
- }
-
- HBufferImage.CurrentLine = Line;
- }
-
- HBufferImage.Modified = FALSE;
- HBufferImageNeedRefresh = TRUE;
- HBufferImageOnlyLineNeedRefresh = FALSE;
- HBufferImageMouseNeedRefresh = TRUE;
-
- return EFI_SUCCESS;
-}
-
-/**
- Save lines in HBufferImage to disk.
- NOT ALLOW TO WRITE TO ANOTHER DISK!!!!!!!!!
-
- @param[in] DeviceName The device name.
- @param[in] Offset The offset.
- @param[in] Size The size.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
- @retval EFI_LOAD_ERROR A load error occurred.
- @retval EFI_INVALID_PARAMETER A parameter was invalid.
-**/
-EFI_STATUS
-HDiskImageSave (
- IN CHAR16 *DeviceName,
- IN UINTN Offset,
- IN UINTN Size
- )
-{
- CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath;
- EFI_DEVICE_PATH_PROTOCOL *DupDevicePath;
- EFI_DEVICE_PATH_PROTOCOL *DupDevicePathForFree;
- EFI_BLOCK_IO_PROTOCOL *BlkIo;
- EFI_STATUS Status;
- EFI_HANDLE Handle;
- VOID *Buffer;
- UINTN Bytes;
-
- //
- // if not modified, directly return
- //
- if (HBufferImage.Modified == FALSE) {
- return EFI_SUCCESS;
- }
-
- HBufferImage.BufferType = FileTypeDiskBuffer;
-
- DevicePath = gEfiShellProtocol->GetDevicePathFromMap (DeviceName);
- if (DevicePath == NULL) {
- // StatusBarSetStatusString (L"Cannot Find Device");
- return EFI_INVALID_PARAMETER;
- }
-
- DupDevicePath = DuplicateDevicePath (DevicePath);
- DupDevicePathForFree = DupDevicePath;
-
- //
- // get blkio interface
- //
- Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &DupDevicePath, &Handle);
- FreePool (DupDevicePathForFree);
- if (EFI_ERROR (Status)) {
- // StatusBarSetStatusString (L"Read Disk Failed");
- return Status;
- }
-
- Status = gBS->OpenProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlkIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
- if (EFI_ERROR (Status)) {
- // StatusBarSetStatusString (L"Read Disk Failed");
- return Status;
- }
-
- Bytes = BlkIo->Media->BlockSize * Size;
- Buffer = AllocateZeroPool (Bytes);
-
- if (Buffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // concatenate the line list to a buffer
- //
- Status = HBufferImageListToBuffer (Buffer, Bytes);
- if (EFI_ERROR (Status)) {
- FreePool (Buffer);
- return Status;
- }
-
- //
- // write the buffer to disk
- //
- Status = BlkIo->WriteBlocks (
- BlkIo,
- BlkIo->Media->MediaId,
- Offset,
- Bytes,
- Buffer
- );
-
- FreePool (Buffer);
-
- if (EFI_ERROR (Status)) {
- return EFI_LOAD_ERROR;
- }
-
- //
- // now not modified
- //
- HBufferImage.Modified = FALSE;
-
- return EFI_SUCCESS;
-}
+/** @file + Functions to deal with Disk buffer. + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "HexEditor.h" +#include <Protocol/BlockIo.h> + +extern EFI_HANDLE HImageHandleBackup; +extern HEFI_EDITOR_BUFFER_IMAGE HBufferImage; + +extern BOOLEAN HBufferImageNeedRefresh; +extern BOOLEAN HBufferImageOnlyLineNeedRefresh; +extern BOOLEAN HBufferImageMouseNeedRefresh; + +extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditor; + +HEFI_EDITOR_DISK_IMAGE HDiskImage; +HEFI_EDITOR_DISK_IMAGE HDiskImageBackupVar; + +// +// for basic initialization of HDiskImage +// +HEFI_EDITOR_DISK_IMAGE HDiskImageConst = { + NULL, + 0, + 0, + 0 +}; + +/** + Initialization function for HDiskImage. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HDiskImageInit ( + VOID + ) +{ + // + // basically initialize the HDiskImage + // + CopyMem (&HDiskImage, &HDiskImageConst, sizeof (HDiskImage)); + + CopyMem (&HDiskImageBackupVar, &HDiskImageConst, sizeof (HDiskImageBackupVar)); + + return EFI_SUCCESS; +} + +/** + Backup function for HDiskImage. Only a few fields need to be backup. + This is for making the Disk buffer refresh as few as possible. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES gST->ConOut of resources. +**/ +EFI_STATUS +HDiskImageBackup ( + VOID + ) +{ + // + // backup the disk name, offset and size + // + // + SHELL_FREE_NON_NULL (HDiskImageBackupVar.Name); + + HDiskImageBackupVar.Name = CatSPrint (NULL, L"%s", HDiskImage.Name); + if (HDiskImageBackupVar.Name == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + HDiskImageBackupVar.Offset = HDiskImage.Offset; + HDiskImageBackupVar.Size = HDiskImage.Size; + + return EFI_SUCCESS; +} + +/** + Cleanup function for HDiskImage. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HDiskImageCleanup ( + VOID + ) +{ + SHELL_FREE_NON_NULL (HDiskImage.Name); + SHELL_FREE_NON_NULL (HDiskImageBackupVar.Name); + + return EFI_SUCCESS; +} + +/** + Set FileName field in HFileImage. + + @param[in] Str File name to set. + @param[in] Offset The offset. + @param[in] Size The size. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HDiskImageSetDiskNameOffsetSize ( + IN CONST CHAR16 *Str, + IN UINTN Offset, + IN UINTN Size + ) +{ + if (Str == HDiskImage.Name) { + // + // This function might be called using HDiskImage.FileName as Str. + // Directly return without updating HDiskImage.FileName. + // + return EFI_SUCCESS; + } + + // + // free the old file name + // + SHELL_FREE_NON_NULL (HDiskImage.Name); + HDiskImage.Name = AllocateCopyPool (StrSize (Str), Str); + if (HDiskImage.Name == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + HDiskImage.Offset = Offset; + HDiskImage.Size = Size; + + return EFI_SUCCESS; +} + +/** + Read a disk from disk into HBufferImage. + + @param[in] DeviceName filename to read. + @param[in] Offset The offset. + @param[in] Size The size. + @param[in] Recover if is for recover, no information print. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_INVALID_PARAMETER A parameter was invalid. +**/ +EFI_STATUS +HDiskImageRead ( + IN CONST CHAR16 *DeviceName, + IN UINTN Offset, + IN UINTN Size, + IN BOOLEAN Recover + ) +{ + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *DupDevicePath; + EFI_DEVICE_PATH_PROTOCOL *DupDevicePathForFree; + EFI_HANDLE Handle; + EFI_BLOCK_IO_PROTOCOL *BlkIo; + EFI_STATUS Status; + + VOID *Buffer; + CHAR16 *Str; + UINTN Bytes; + + HEFI_EDITOR_LINE *Line; + + HBufferImage.BufferType = FileTypeDiskBuffer; + + DevicePath = gEfiShellProtocol->GetDevicePathFromMap (DeviceName); + if (DevicePath == NULL) { + StatusBarSetStatusString (L"Cannot Find Device"); + return EFI_INVALID_PARAMETER; + } + + DupDevicePath = DuplicateDevicePath (DevicePath); + DupDevicePathForFree = DupDevicePath; + // + // get blkio interface + // + Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &DupDevicePath, &Handle); + FreePool (DupDevicePathForFree); + if (EFI_ERROR (Status)) { + StatusBarSetStatusString (L"Read Disk Failed"); + return Status; + } + + Status = gBS->OpenProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlkIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (EFI_ERROR (Status)) { + StatusBarSetStatusString (L"Read Disk Failed"); + return Status; + } + + // + // if Offset exceeds LastBlock, + // return error + // + if ((Offset > BlkIo->Media->LastBlock) || (Offset + Size > BlkIo->Media->LastBlock)) { + StatusBarSetStatusString (L"Invalid Offset + Size"); + return EFI_LOAD_ERROR; + } + + Bytes = BlkIo->Media->BlockSize * Size; + Buffer = AllocateZeroPool (Bytes); + + if (Buffer == NULL) { + StatusBarSetStatusString (L"Read Disk Failed"); + return EFI_OUT_OF_RESOURCES; + } + + // + // read from disk + // + Status = BlkIo->ReadBlocks ( + BlkIo, + BlkIo->Media->MediaId, + Offset, + Bytes, + Buffer + ); + + if (EFI_ERROR (Status)) { + FreePool (Buffer); + StatusBarSetStatusString (L"Read Disk Failed"); + return EFI_LOAD_ERROR; + } + + HBufferImageFree (); + + // + // convert buffer to line list + // + Status = HBufferImageBufferToList (Buffer, Bytes); + FreePool (Buffer); + + if (EFI_ERROR (Status)) { + StatusBarSetStatusString (L"Read Disk Failed"); + return Status; + } + + Status = HDiskImageSetDiskNameOffsetSize (DeviceName, Offset, Size); + if (EFI_ERROR (Status)) { + StatusBarSetStatusString (L"Read Disk Failed"); + return EFI_OUT_OF_RESOURCES; + } + + // + // initialize some variables + // + HDiskImage.BlockSize = BlkIo->Media->BlockSize; + + HBufferImage.DisplayPosition.Row = 2; + HBufferImage.DisplayPosition.Column = 10; + + HBufferImage.MousePosition.Row = 2; + HBufferImage.MousePosition.Column = 10; + + HBufferImage.LowVisibleRow = 1; + HBufferImage.HighBits = TRUE; + + HBufferImage.BufferPosition.Row = 1; + HBufferImage.BufferPosition.Column = 1; + + if (!Recover) { + Str = CatSPrint (NULL, L"%d Lines Read", HBufferImage.NumLines); + if (Str == NULL) { + StatusBarSetStatusString (L"Read Disk Failed"); + return EFI_OUT_OF_RESOURCES; + } + + StatusBarSetStatusString (Str); + SHELL_FREE_NON_NULL (Str); + + HMainEditor.SelectStart = 0; + HMainEditor.SelectEnd = 0; + } + + // + // has line + // + if (HBufferImage.Lines != NULL) { + HBufferImage.CurrentLine = CR ( + HBufferImage.ListHead->ForwardLink, + HEFI_EDITOR_LINE, + Link, + EFI_EDITOR_LINE_LIST + ); + } else { + // + // create a dummy line + // + Line = HBufferImageCreateLine (); + if (Line == NULL) { + StatusBarSetStatusString (L"Read Disk Failed"); + return EFI_OUT_OF_RESOURCES; + } + + HBufferImage.CurrentLine = Line; + } + + HBufferImage.Modified = FALSE; + HBufferImageNeedRefresh = TRUE; + HBufferImageOnlyLineNeedRefresh = FALSE; + HBufferImageMouseNeedRefresh = TRUE; + + return EFI_SUCCESS; +} + +/** + Save lines in HBufferImage to disk. + NOT ALLOW TO WRITE TO ANOTHER DISK!!!!!!!!! + + @param[in] DeviceName The device name. + @param[in] Offset The offset. + @param[in] Size The size. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_INVALID_PARAMETER A parameter was invalid. +**/ +EFI_STATUS +HDiskImageSave ( + IN CHAR16 *DeviceName, + IN UINTN Offset, + IN UINTN Size + ) +{ + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *DupDevicePath; + EFI_DEVICE_PATH_PROTOCOL *DupDevicePathForFree; + EFI_BLOCK_IO_PROTOCOL *BlkIo; + EFI_STATUS Status; + EFI_HANDLE Handle; + VOID *Buffer; + UINTN Bytes; + + // + // if not modified, directly return + // + if (HBufferImage.Modified == FALSE) { + return EFI_SUCCESS; + } + + HBufferImage.BufferType = FileTypeDiskBuffer; + + DevicePath = gEfiShellProtocol->GetDevicePathFromMap (DeviceName); + if (DevicePath == NULL) { + // StatusBarSetStatusString (L"Cannot Find Device"); + return EFI_INVALID_PARAMETER; + } + + DupDevicePath = DuplicateDevicePath (DevicePath); + DupDevicePathForFree = DupDevicePath; + + // + // get blkio interface + // + Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &DupDevicePath, &Handle); + FreePool (DupDevicePathForFree); + if (EFI_ERROR (Status)) { + // StatusBarSetStatusString (L"Read Disk Failed"); + return Status; + } + + Status = gBS->OpenProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlkIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (EFI_ERROR (Status)) { + // StatusBarSetStatusString (L"Read Disk Failed"); + return Status; + } + + Bytes = BlkIo->Media->BlockSize * Size; + Buffer = AllocateZeroPool (Bytes); + + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // concatenate the line list to a buffer + // + Status = HBufferImageListToBuffer (Buffer, Bytes); + if (EFI_ERROR (Status)) { + FreePool (Buffer); + return Status; + } + + // + // write the buffer to disk + // + Status = BlkIo->WriteBlocks ( + BlkIo, + BlkIo->Media->MediaId, + Offset, + Bytes, + Buffer + ); + + FreePool (Buffer); + + if (EFI_ERROR (Status)) { + return EFI_LOAD_ERROR; + } + + // + // now not modified + // + HBufferImage.Modified = FALSE; + + return EFI_SUCCESS; +} diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/DiskImage.h b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/DiskImage.h index 69d822e7e4..8d3cf338ac 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/DiskImage.h +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/DiskImage.h @@ -1,89 +1,89 @@ -/** @file
- Defines DiskImage - the view of the file that is visible at any point,
- as well as the event handlers for editing the file
-
- Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _LIB_DISK_IMAGE_H_
-#define _LIB_DISK_IMAGE_H_
-
-#include "HexEditor.h"
-
-/**
- Initialization function for HDiskImage.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_LOAD_ERROR A load error occurred.
-**/
-EFI_STATUS
-HDiskImageInit (
- VOID
- );
-
-/**
- Cleanup function for HDiskImage.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HDiskImageCleanup (
- VOID
- );
-
-/**
- Backup function for HDiskImage. Only a few fields need to be backup.
- This is for making the Disk buffer refresh as few as possible.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES gST->ConOut of resources.
-**/
-EFI_STATUS
-HDiskImageBackup (
- VOID
- );
-
-/**
- Read a disk from disk into HBufferImage.
-
- @param[in] DeviceName filename to read.
- @param[in] Offset The offset.
- @param[in] Size The size.
- @param[in] Recover if is for recover, no information print.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
- @retval EFI_LOAD_ERROR A load error occurred.
- @retval EFI_INVALID_PARAMETER A parameter was invalid.
-**/
-EFI_STATUS
-HDiskImageRead (
- IN CONST CHAR16 *DeviceName,
- IN UINTN Offset,
- IN UINTN Size,
- IN BOOLEAN Recover
- );
-
-/**
- Save lines in HBufferImage to disk.
- NOT ALLOW TO WRITE TO ANOTHER DISK!!!!!!!!!
-
- @param[in] DeviceName The device name.
- @param[in] Offset The offset.
- @param[in] Size The size.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
- @retval EFI_LOAD_ERROR A load error occurred.
- @retval EFI_INVALID_PARAMETER A parameter was invalid.
-**/
-EFI_STATUS
-HDiskImageSave (
- IN CHAR16 *DeviceName,
- IN UINTN Offset,
- IN UINTN Size
- );
-
-#endif
+/** @file + Defines DiskImage - the view of the file that is visible at any point, + as well as the event handlers for editing the file + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _LIB_DISK_IMAGE_H_ +#define _LIB_DISK_IMAGE_H_ + +#include "HexEditor.h" + +/** + Initialization function for HDiskImage. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HDiskImageInit ( + VOID + ); + +/** + Cleanup function for HDiskImage. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HDiskImageCleanup ( + VOID + ); + +/** + Backup function for HDiskImage. Only a few fields need to be backup. + This is for making the Disk buffer refresh as few as possible. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES gST->ConOut of resources. +**/ +EFI_STATUS +HDiskImageBackup ( + VOID + ); + +/** + Read a disk from disk into HBufferImage. + + @param[in] DeviceName filename to read. + @param[in] Offset The offset. + @param[in] Size The size. + @param[in] Recover if is for recover, no information print. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_INVALID_PARAMETER A parameter was invalid. +**/ +EFI_STATUS +HDiskImageRead ( + IN CONST CHAR16 *DeviceName, + IN UINTN Offset, + IN UINTN Size, + IN BOOLEAN Recover + ); + +/** + Save lines in HBufferImage to disk. + NOT ALLOW TO WRITE TO ANOTHER DISK!!!!!!!!! + + @param[in] DeviceName The device name. + @param[in] Offset The offset. + @param[in] Size The size. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_INVALID_PARAMETER A parameter was invalid. +**/ +EFI_STATUS +HDiskImageSave ( + IN CHAR16 *DeviceName, + IN UINTN Offset, + IN UINTN Size + ); + +#endif diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/FileImage.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/FileImage.c index d8818dd958..5a3f27a77d 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/FileImage.c +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/FileImage.c @@ -1,395 +1,395 @@ -/** @file
- Functions to deal with file buffer.
-
- Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "HexEditor.h"
-
-extern EFI_HANDLE HImageHandleBackup;
-extern HEFI_EDITOR_BUFFER_IMAGE HBufferImage;
-
-extern BOOLEAN HBufferImageNeedRefresh;
-extern BOOLEAN HBufferImageOnlyLineNeedRefresh;
-extern BOOLEAN HBufferImageMouseNeedRefresh;
-
-extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditor;
-
-HEFI_EDITOR_FILE_IMAGE HFileImage;
-HEFI_EDITOR_FILE_IMAGE HFileImageBackupVar;
-
-//
-// for basic initialization of HFileImage
-//
-HEFI_EDITOR_BUFFER_IMAGE HFileImageConst = {
- NULL,
- 0,
- FALSE
-};
-
-/**
- Initialization function for HFileImage
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HFileImageInit (
- VOID
- )
-{
- //
- // basically initialize the HFileImage
- //
- CopyMem (&HFileImage, &HFileImageConst, sizeof (HFileImage));
-
- CopyMem (
- &HFileImageBackupVar,
- &HFileImageConst,
- sizeof (HFileImageBackupVar)
- );
-
- return EFI_SUCCESS;
-}
-
-/**
- Backup function for HFileImage. Only a few fields need to be backup.
- This is for making the file buffer refresh as few as possible.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
-**/
-EFI_STATUS
-HFileImageBackup (
- VOID
- )
-{
- SHELL_FREE_NON_NULL (HFileImageBackupVar.FileName);
- HFileImageBackupVar.FileName = CatSPrint (NULL, L"%s", HFileImage.FileName);
- if (HFileImageBackupVar.FileName == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Cleanup function for HFileImage.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HFileImageCleanup (
- VOID
- )
-{
- SHELL_FREE_NON_NULL (HFileImage.FileName);
- SHELL_FREE_NON_NULL (HFileImageBackupVar.FileName);
-
- return EFI_SUCCESS;
-}
-
-/**
- Set FileName field in HFileImage
-
- @param[in] Str File name to set.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
-**/
-EFI_STATUS
-HFileImageSetFileName (
- IN CONST CHAR16 *Str
- )
-{
- if (Str == HFileImage.FileName) {
- //
- // This function might be called using HFileImage.FileName as Str.
- // Directly return without updating HFileImage.FileName.
- //
- return EFI_SUCCESS;
- }
-
- //
- // free the old file name
- //
- SHELL_FREE_NON_NULL (HFileImage.FileName);
- HFileImage.FileName = AllocateCopyPool (StrSize (Str), Str);
- if (HFileImage.FileName == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Read a file from disk into HBufferImage.
-
- @param[in] FileName filename to read.
- @param[in] Recover if is for recover, no information print.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
- @retval EFI_LOAD_ERROR A load error occurred.
-**/
-EFI_STATUS
-HFileImageRead (
- IN CONST CHAR16 *FileName,
- IN BOOLEAN Recover
- )
-{
- HEFI_EDITOR_LINE *Line;
- UINT8 *Buffer;
- CHAR16 *UnicodeBuffer;
- EFI_STATUS Status;
-
- //
- // variable initialization
- //
- Line = NULL;
-
- //
- // in this function, when you return error ( except EFI_OUT_OF_RESOURCES )
- // you should set status string
- // since this function maybe called before the editorhandleinput loop
- // so any error will cause editor return
- // so if you want to print the error status
- // you should set the status string
- //
- Status = ReadFileIntoBuffer (FileName, (VOID **)&Buffer, &HFileImage.Size, &HFileImage.ReadOnly);
- //
- // NULL pointer is only also a failure for a non-zero file size.
- //
- if ((EFI_ERROR (Status)) || ((Buffer == NULL) && (HFileImage.Size != 0))) {
- UnicodeBuffer = CatSPrint (NULL, L"Read error on file %s: %r", FileName, Status);
- if (UnicodeBuffer == NULL) {
- SHELL_FREE_NON_NULL (Buffer);
- return EFI_OUT_OF_RESOURCES;
- }
-
- StatusBarSetStatusString (UnicodeBuffer);
- FreePool (UnicodeBuffer);
- return EFI_OUT_OF_RESOURCES;
- }
-
- HFileImageSetFileName (FileName);
-
- //
- // free the old lines
- //
- HBufferImageFree ();
-
- Status = HBufferImageBufferToList (Buffer, HFileImage.Size);
- SHELL_FREE_NON_NULL (Buffer);
- if (EFI_ERROR (Status)) {
- StatusBarSetStatusString (L"Error parsing file.");
- return Status;
- }
-
- HBufferImage.DisplayPosition.Row = 2;
- HBufferImage.DisplayPosition.Column = 10;
- HBufferImage.MousePosition.Row = 2;
- HBufferImage.MousePosition.Column = 10;
- HBufferImage.LowVisibleRow = 1;
- HBufferImage.HighBits = TRUE;
- HBufferImage.BufferPosition.Row = 1;
- HBufferImage.BufferPosition.Column = 1;
- HBufferImage.BufferType = FileTypeFileBuffer;
-
- if (!Recover) {
- UnicodeBuffer = CatSPrint (NULL, L"%d Lines Read", HBufferImage.NumLines);
- if (UnicodeBuffer == NULL) {
- SHELL_FREE_NON_NULL (Buffer);
- return EFI_OUT_OF_RESOURCES;
- }
-
- StatusBarSetStatusString (UnicodeBuffer);
- FreePool (UnicodeBuffer);
-
- HMainEditor.SelectStart = 0;
- HMainEditor.SelectEnd = 0;
- }
-
- //
- // has line
- //
- if (HBufferImage.Lines != 0) {
- HBufferImage.CurrentLine = CR (HBufferImage.ListHead->ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
- } else {
- //
- // create a dummy line
- //
- Line = HBufferImageCreateLine ();
- if (Line == NULL) {
- SHELL_FREE_NON_NULL (Buffer);
- return EFI_OUT_OF_RESOURCES;
- }
-
- HBufferImage.CurrentLine = Line;
- }
-
- HBufferImage.Modified = FALSE;
- HBufferImageNeedRefresh = TRUE;
- HBufferImageOnlyLineNeedRefresh = FALSE;
- HBufferImageMouseNeedRefresh = TRUE;
-
- return EFI_SUCCESS;
-}
-
-/**
- Save lines in HBufferImage to disk.
-
- @param[in] FileName The file name.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
- @retval EFI_LOAD_ERROR A load error occurred.
-**/
-EFI_STATUS
-HFileImageSave (
- IN CHAR16 *FileName
- )
-{
- LIST_ENTRY *Link;
- HEFI_EDITOR_LINE *Line;
- CHAR16 *Str;
- EFI_STATUS Status;
- UINTN NumLines;
- SHELL_FILE_HANDLE FileHandle;
- UINTN TotalSize;
- UINT8 *Buffer;
- UINT8 *Ptr;
- EDIT_FILE_TYPE BufferTypeBackup;
-
- BufferTypeBackup = HBufferImage.BufferType;
- HBufferImage.BufferType = FileTypeFileBuffer;
-
- //
- // if is the old file
- //
- if ((HFileImage.FileName != NULL) && (FileName != NULL) && (StrCmp (FileName, HFileImage.FileName) == 0)) {
- //
- // check whether file exists on disk
- //
- if (ShellIsFile (FileName) == EFI_SUCCESS) {
- //
- // current file exists on disk
- // so if not modified, then not save
- //
- if (HBufferImage.Modified == FALSE) {
- return EFI_SUCCESS;
- }
-
- //
- // if file is read-only, set error
- //
- if (HFileImage.ReadOnly == TRUE) {
- StatusBarSetStatusString (L"Read Only File Can Not Be Saved");
- return EFI_SUCCESS;
- }
- }
- }
-
- if (ShellIsDirectory (FileName) == EFI_SUCCESS) {
- StatusBarSetStatusString (L"Directory Can Not Be Saved");
- return EFI_LOAD_ERROR;
- }
-
- Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0);
-
- if (!EFI_ERROR (Status)) {
- //
- // the file exits, delete it
- //
- Status = ShellDeleteFile (&FileHandle);
- if (EFI_ERROR (Status) || (Status == EFI_WARN_DELETE_FAILURE)) {
- StatusBarSetStatusString (L"Write File Failed");
- return EFI_LOAD_ERROR;
- }
- }
-
- //
- // write all the lines back to disk
- //
- NumLines = 0;
- TotalSize = 0;
- for (Link = HBufferImage.ListHead->ForwardLink; Link != HBufferImage.ListHead; Link = Link->ForwardLink) {
- Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
-
- if (Line->Size != 0) {
- TotalSize += Line->Size;
- }
-
- //
- // end of if Line -> Size != 0
- //
- NumLines++;
- }
-
- //
- // end of for Link
- //
- Buffer = AllocateZeroPool (TotalSize);
- if (Buffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Ptr = Buffer;
- for (Link = HBufferImage.ListHead->ForwardLink; Link != HBufferImage.ListHead; Link = Link->ForwardLink) {
- Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
-
- if (Line->Size != 0) {
- CopyMem (Ptr, Line->Buffer, Line->Size);
- Ptr += Line->Size;
- }
-
- //
- // end of if Line -> Size != 0
- //
- }
-
- Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);
-
- if (EFI_ERROR (Status)) {
- StatusBarSetStatusString (L"Create File Failed");
- return EFI_LOAD_ERROR;
- }
-
- Status = ShellWriteFile (FileHandle, &TotalSize, Buffer);
- FreePool (Buffer);
- if (EFI_ERROR (Status)) {
- ShellDeleteFile (&FileHandle);
- return EFI_LOAD_ERROR;
- }
-
- ShellCloseFile (&FileHandle);
-
- HBufferImage.Modified = FALSE;
-
- //
- // set status string
- //
- Str = CatSPrint (NULL, L"%d Lines Written", NumLines);
- StatusBarSetStatusString (Str);
- FreePool (Str);
-
- //
- // now everything is ready , you can set the new file name to filebuffer
- //
- if (((BufferTypeBackup != FileTypeFileBuffer) && (FileName != NULL)) ||
- ((FileName != NULL) && (HFileImage.FileName != NULL) && (StringNoCaseCompare (&FileName, &HFileImage.FileName) != 0)))
- {
- //
- // not the same
- //
- HFileImageSetFileName (FileName);
- if (HFileImage.FileName == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- }
-
- HFileImage.ReadOnly = FALSE;
-
- return EFI_SUCCESS;
-}
+/** @file + Functions to deal with file buffer. + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "HexEditor.h" + +extern EFI_HANDLE HImageHandleBackup; +extern HEFI_EDITOR_BUFFER_IMAGE HBufferImage; + +extern BOOLEAN HBufferImageNeedRefresh; +extern BOOLEAN HBufferImageOnlyLineNeedRefresh; +extern BOOLEAN HBufferImageMouseNeedRefresh; + +extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditor; + +HEFI_EDITOR_FILE_IMAGE HFileImage; +HEFI_EDITOR_FILE_IMAGE HFileImageBackupVar; + +// +// for basic initialization of HFileImage +// +HEFI_EDITOR_BUFFER_IMAGE HFileImageConst = { + NULL, + 0, + FALSE +}; + +/** + Initialization function for HFileImage + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HFileImageInit ( + VOID + ) +{ + // + // basically initialize the HFileImage + // + CopyMem (&HFileImage, &HFileImageConst, sizeof (HFileImage)); + + CopyMem ( + &HFileImageBackupVar, + &HFileImageConst, + sizeof (HFileImageBackupVar) + ); + + return EFI_SUCCESS; +} + +/** + Backup function for HFileImage. Only a few fields need to be backup. + This is for making the file buffer refresh as few as possible. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HFileImageBackup ( + VOID + ) +{ + SHELL_FREE_NON_NULL (HFileImageBackupVar.FileName); + HFileImageBackupVar.FileName = CatSPrint (NULL, L"%s", HFileImage.FileName); + if (HFileImageBackupVar.FileName == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + return EFI_SUCCESS; +} + +/** + Cleanup function for HFileImage. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HFileImageCleanup ( + VOID + ) +{ + SHELL_FREE_NON_NULL (HFileImage.FileName); + SHELL_FREE_NON_NULL (HFileImageBackupVar.FileName); + + return EFI_SUCCESS; +} + +/** + Set FileName field in HFileImage + + @param[in] Str File name to set. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HFileImageSetFileName ( + IN CONST CHAR16 *Str + ) +{ + if (Str == HFileImage.FileName) { + // + // This function might be called using HFileImage.FileName as Str. + // Directly return without updating HFileImage.FileName. + // + return EFI_SUCCESS; + } + + // + // free the old file name + // + SHELL_FREE_NON_NULL (HFileImage.FileName); + HFileImage.FileName = AllocateCopyPool (StrSize (Str), Str); + if (HFileImage.FileName == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + return EFI_SUCCESS; +} + +/** + Read a file from disk into HBufferImage. + + @param[in] FileName filename to read. + @param[in] Recover if is for recover, no information print. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HFileImageRead ( + IN CONST CHAR16 *FileName, + IN BOOLEAN Recover + ) +{ + HEFI_EDITOR_LINE *Line; + UINT8 *Buffer; + CHAR16 *UnicodeBuffer; + EFI_STATUS Status; + + // + // variable initialization + // + Line = NULL; + + // + // in this function, when you return error ( except EFI_OUT_OF_RESOURCES ) + // you should set status string + // since this function maybe called before the editorhandleinput loop + // so any error will cause editor return + // so if you want to print the error status + // you should set the status string + // + Status = ReadFileIntoBuffer (FileName, (VOID **)&Buffer, &HFileImage.Size, &HFileImage.ReadOnly); + // + // NULL pointer is only also a failure for a non-zero file size. + // + if ((EFI_ERROR (Status)) || ((Buffer == NULL) && (HFileImage.Size != 0))) { + UnicodeBuffer = CatSPrint (NULL, L"Read error on file %s: %r", FileName, Status); + if (UnicodeBuffer == NULL) { + SHELL_FREE_NON_NULL (Buffer); + return EFI_OUT_OF_RESOURCES; + } + + StatusBarSetStatusString (UnicodeBuffer); + FreePool (UnicodeBuffer); + return EFI_OUT_OF_RESOURCES; + } + + HFileImageSetFileName (FileName); + + // + // free the old lines + // + HBufferImageFree (); + + Status = HBufferImageBufferToList (Buffer, HFileImage.Size); + SHELL_FREE_NON_NULL (Buffer); + if (EFI_ERROR (Status)) { + StatusBarSetStatusString (L"Error parsing file."); + return Status; + } + + HBufferImage.DisplayPosition.Row = 2; + HBufferImage.DisplayPosition.Column = 10; + HBufferImage.MousePosition.Row = 2; + HBufferImage.MousePosition.Column = 10; + HBufferImage.LowVisibleRow = 1; + HBufferImage.HighBits = TRUE; + HBufferImage.BufferPosition.Row = 1; + HBufferImage.BufferPosition.Column = 1; + HBufferImage.BufferType = FileTypeFileBuffer; + + if (!Recover) { + UnicodeBuffer = CatSPrint (NULL, L"%d Lines Read", HBufferImage.NumLines); + if (UnicodeBuffer == NULL) { + SHELL_FREE_NON_NULL (Buffer); + return EFI_OUT_OF_RESOURCES; + } + + StatusBarSetStatusString (UnicodeBuffer); + FreePool (UnicodeBuffer); + + HMainEditor.SelectStart = 0; + HMainEditor.SelectEnd = 0; + } + + // + // has line + // + if (HBufferImage.Lines != 0) { + HBufferImage.CurrentLine = CR (HBufferImage.ListHead->ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); + } else { + // + // create a dummy line + // + Line = HBufferImageCreateLine (); + if (Line == NULL) { + SHELL_FREE_NON_NULL (Buffer); + return EFI_OUT_OF_RESOURCES; + } + + HBufferImage.CurrentLine = Line; + } + + HBufferImage.Modified = FALSE; + HBufferImageNeedRefresh = TRUE; + HBufferImageOnlyLineNeedRefresh = FALSE; + HBufferImageMouseNeedRefresh = TRUE; + + return EFI_SUCCESS; +} + +/** + Save lines in HBufferImage to disk. + + @param[in] FileName The file name. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HFileImageSave ( + IN CHAR16 *FileName + ) +{ + LIST_ENTRY *Link; + HEFI_EDITOR_LINE *Line; + CHAR16 *Str; + EFI_STATUS Status; + UINTN NumLines; + SHELL_FILE_HANDLE FileHandle; + UINTN TotalSize; + UINT8 *Buffer; + UINT8 *Ptr; + EDIT_FILE_TYPE BufferTypeBackup; + + BufferTypeBackup = HBufferImage.BufferType; + HBufferImage.BufferType = FileTypeFileBuffer; + + // + // if is the old file + // + if ((HFileImage.FileName != NULL) && (FileName != NULL) && (StrCmp (FileName, HFileImage.FileName) == 0)) { + // + // check whether file exists on disk + // + if (ShellIsFile (FileName) == EFI_SUCCESS) { + // + // current file exists on disk + // so if not modified, then not save + // + if (HBufferImage.Modified == FALSE) { + return EFI_SUCCESS; + } + + // + // if file is read-only, set error + // + if (HFileImage.ReadOnly == TRUE) { + StatusBarSetStatusString (L"Read Only File Can Not Be Saved"); + return EFI_SUCCESS; + } + } + } + + if (ShellIsDirectory (FileName) == EFI_SUCCESS) { + StatusBarSetStatusString (L"Directory Can Not Be Saved"); + return EFI_LOAD_ERROR; + } + + Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0); + + if (!EFI_ERROR (Status)) { + // + // the file exits, delete it + // + Status = ShellDeleteFile (&FileHandle); + if (EFI_ERROR (Status) || (Status == EFI_WARN_DELETE_FAILURE)) { + StatusBarSetStatusString (L"Write File Failed"); + return EFI_LOAD_ERROR; + } + } + + // + // write all the lines back to disk + // + NumLines = 0; + TotalSize = 0; + for (Link = HBufferImage.ListHead->ForwardLink; Link != HBufferImage.ListHead; Link = Link->ForwardLink) { + Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); + + if (Line->Size != 0) { + TotalSize += Line->Size; + } + + // + // end of if Line -> Size != 0 + // + NumLines++; + } + + // + // end of for Link + // + Buffer = AllocateZeroPool (TotalSize); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Ptr = Buffer; + for (Link = HBufferImage.ListHead->ForwardLink; Link != HBufferImage.ListHead; Link = Link->ForwardLink) { + Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); + + if (Line->Size != 0) { + CopyMem (Ptr, Line->Buffer, Line->Size); + Ptr += Line->Size; + } + + // + // end of if Line -> Size != 0 + // + } + + Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0); + + if (EFI_ERROR (Status)) { + StatusBarSetStatusString (L"Create File Failed"); + return EFI_LOAD_ERROR; + } + + Status = ShellWriteFile (FileHandle, &TotalSize, Buffer); + FreePool (Buffer); + if (EFI_ERROR (Status)) { + ShellDeleteFile (&FileHandle); + return EFI_LOAD_ERROR; + } + + ShellCloseFile (&FileHandle); + + HBufferImage.Modified = FALSE; + + // + // set status string + // + Str = CatSPrint (NULL, L"%d Lines Written", NumLines); + StatusBarSetStatusString (Str); + FreePool (Str); + + // + // now everything is ready , you can set the new file name to filebuffer + // + if (((BufferTypeBackup != FileTypeFileBuffer) && (FileName != NULL)) || + ((FileName != NULL) && (HFileImage.FileName != NULL) && (StringNoCaseCompare (&FileName, &HFileImage.FileName) != 0))) + { + // + // not the same + // + HFileImageSetFileName (FileName); + if (HFileImage.FileName == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + HFileImage.ReadOnly = FALSE; + + return EFI_SUCCESS; +} diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/FileImage.h b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/FileImage.h index 36ee989b2e..100fcaf865 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/FileImage.h +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/FileImage.h @@ -1,77 +1,77 @@ -/** @file
- Defines FileImage - the view of the file that is visible at any point,
- as well as the event handlers for editing the file
-
- Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _LIB_FILE_IMAGE_H_
-#define _LIB_FILE_IMAGE_H_
-
-#include "HexEditor.h"
-
-/**
- Initialization function for HFileImage
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HFileImageInit (
- VOID
- );
-
-/**
- Cleanup function for HFileImage.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HFileImageCleanup (
- VOID
- );
-
-/**
- Backup function for HFileImage. Only a few fields need to be backup.
- This is for making the file buffer refresh as few as possible.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
-**/
-EFI_STATUS
-HFileImageBackup (
- VOID
- );
-
-/**
- Read a file from disk into HBufferImage.
-
- @param[in] FileName filename to read.
- @param[in] Recover if is for recover, no information print.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
- @retval EFI_LOAD_ERROR A load error occurred.
-**/
-EFI_STATUS
-HFileImageRead (
- IN CONST CHAR16 *FileName,
- IN BOOLEAN Recover
- );
-
-/**
- Save lines in HBufferImage to disk.
-
- @param[in] FileName The file name.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
- @retval EFI_LOAD_ERROR A load error occurred.
-**/
-EFI_STATUS
-HFileImageSave (
- IN CHAR16 *FileName
- );
-
-#endif
+/** @file + Defines FileImage - the view of the file that is visible at any point, + as well as the event handlers for editing the file + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _LIB_FILE_IMAGE_H_ +#define _LIB_FILE_IMAGE_H_ + +#include "HexEditor.h" + +/** + Initialization function for HFileImage + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HFileImageInit ( + VOID + ); + +/** + Cleanup function for HFileImage. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HFileImageCleanup ( + VOID + ); + +/** + Backup function for HFileImage. Only a few fields need to be backup. + This is for making the file buffer refresh as few as possible. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HFileImageBackup ( + VOID + ); + +/** + Read a file from disk into HBufferImage. + + @param[in] FileName filename to read. + @param[in] Recover if is for recover, no information print. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HFileImageRead ( + IN CONST CHAR16 *FileName, + IN BOOLEAN Recover + ); + +/** + Save lines in HBufferImage to disk. + + @param[in] FileName The file name. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HFileImageSave ( + IN CHAR16 *FileName + ); + +#endif diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexEdit.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexEdit.c index 9ca675648d..69c02feace 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexEdit.c +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexEdit.c @@ -1,276 +1,276 @@ -/** @file
- Main entry point of editor
-
- (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR>
- Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UefiShellDebug1CommandsLib.h"
-#include "HexEditor.h"
-
-//
-// Global Variables
-//
-STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
- { L"-f", TypeFlag },
- { L"-d", TypeFlag },
- { L"-m", TypeFlag },
- { NULL, TypeMax }
-};
-
-/**
- Function for 'hexedit' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunHexEdit (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- CHAR16 *Buffer;
- CHAR16 *ProblemParam;
- SHELL_STATUS ShellStatus;
- LIST_ENTRY *Package;
- CHAR16 *NewName;
- CONST CHAR16 *Name;
- UINTN Offset;
- UINTN Size;
- EDIT_FILE_TYPE WhatToDo;
-
- Buffer = NULL;
- ShellStatus = SHELL_SUCCESS;
- NewName = NULL;
- Buffer = NULL;
- Name = NULL;
- Offset = 0;
- Size = 0;
- WhatToDo = FileTypeNone;
-
- //
- // initialize the shell lib (we must be in non-auto-init...)
- //
- Status = ShellInitialize ();
- ASSERT_EFI_ERROR (Status);
-
- Status = CommandInit ();
- ASSERT_EFI_ERROR (Status);
-
- //
- // parse the command line
- //
- Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
- if (EFI_ERROR (Status)) {
- if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"hexedit", ProblemParam);
- FreePool (ProblemParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- ASSERT (FALSE);
- }
- } else {
- //
- // Check for -d
- //
- if (ShellCommandLineGetFlag (Package, L"-d")) {
- if (ShellCommandLineGetCount (Package) < 4) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"hexedit");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else if (ShellCommandLineGetCount (Package) > 4) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"hexedit");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- WhatToDo = FileTypeDiskBuffer;
- Name = ShellCommandLineGetRawValue (Package, 1);
- Offset = ShellStrToUintn (ShellCommandLineGetRawValue (Package, 2));
- Size = ShellStrToUintn (ShellCommandLineGetRawValue (Package, 3));
- }
-
- if ((Offset == (UINTN)-1) || (Size == (UINTN)-1)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"hexedit", L"-d");
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
- }
-
- //
- // check for -f
- //
- if (ShellCommandLineGetFlag (Package, L"-f") && (WhatToDo == FileTypeNone)) {
- if (ShellCommandLineGetCount (Package) < 2) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"hexedit");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else if (ShellCommandLineGetCount (Package) > 2) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"hexedit");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- Name = ShellCommandLineGetRawValue (Package, 1);
- if ((Name == NULL) || !IsValidFileName (Name)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"hexedit", Name);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- WhatToDo = FileTypeFileBuffer;
- }
- }
- }
-
- //
- // check for -m
- //
- if (ShellCommandLineGetFlag (Package, L"-m") && (WhatToDo == FileTypeNone)) {
- if (ShellCommandLineGetCount (Package) < 3) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"hexedit");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else if (ShellCommandLineGetCount (Package) > 3) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"hexedit");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- WhatToDo = FileTypeMemBuffer;
- Offset = ShellStrToUintn (ShellCommandLineGetRawValue (Package, 1));
- Size = ShellStrToUintn (ShellCommandLineGetRawValue (Package, 2));
- }
- }
-
- Name = ShellCommandLineGetRawValue (Package, 1);
- if ((WhatToDo == FileTypeNone) && (Name != NULL)) {
- if (ShellCommandLineGetCount (Package) > 2) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"hexedit");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else if (!IsValidFileName (Name)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"hexedit", Name);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- WhatToDo = FileTypeFileBuffer;
- }
- } else if (WhatToDo == FileTypeNone) {
- if (gEfiShellProtocol->GetCurDir (NULL) == NULL) {
- ShellStatus = SHELL_NOT_FOUND;
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellDebug1HiiHandle, L"hexedit");
- } else {
- NewName = EditGetDefaultFileName (L"bin");
- Name = NewName;
- WhatToDo = FileTypeFileBuffer;
- }
- }
-
- if ((ShellStatus == SHELL_SUCCESS) && (WhatToDo == FileTypeNone)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"hexedit");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else if ((WhatToDo == FileTypeFileBuffer) && (ShellGetCurrentDir (NULL) == NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellDebug1HiiHandle, L"hexedit");
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
-
- if (ShellStatus == SHELL_SUCCESS) {
- //
- // Do the editor
- //
- Status = HMainEditorInit ();
- if (EFI_ERROR (Status)) {
- gST->ConOut->ClearScreen (gST->ConOut);
- gST->ConOut->EnableCursor (gST->ConOut, TRUE);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_INIT_FAILED), gShellDebug1HiiHandle);
- } else {
- HMainEditorBackup ();
- switch (WhatToDo) {
- case FileTypeFileBuffer:
- Status = HBufferImageRead (
- Name == NULL ? L"" : Name,
- NULL,
- 0,
- 0,
- 0,
- 0,
- FileTypeFileBuffer,
- FALSE
- );
- break;
-
- case FileTypeDiskBuffer:
- Status = HBufferImageRead (
- NULL,
- Name == NULL ? L"" : Name,
- Offset,
- Size,
- 0,
- 0,
- FileTypeDiskBuffer,
- FALSE
- );
- break;
-
- case FileTypeMemBuffer:
- Status = HBufferImageRead (
- NULL,
- NULL,
- 0,
- 0,
- (UINT32)Offset,
- Size,
- FileTypeMemBuffer,
- FALSE
- );
- break;
-
- default:
- Status = EFI_NOT_FOUND;
- break;
- }
-
- if (!EFI_ERROR (Status)) {
- HMainEditorRefresh ();
- Status = HMainEditorKeyInput ();
- }
-
- if (Status != EFI_OUT_OF_RESOURCES) {
- //
- // back up the status string
- //
- Buffer = CatSPrint (NULL, L"%s\r\n", StatusBarGetString ());
- }
- }
-
- //
- // cleanup
- //
- HMainEditorCleanup ();
-
- if (EFI_ERROR (Status)) {
- if (ShellStatus == SHELL_SUCCESS) {
- ShellStatus = SHELL_UNSUPPORTED;
- }
- }
-
- //
- // print editor exit code on screen
- //
- if (Status == EFI_OUT_OF_RESOURCES) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle, L"hexedit");
- } else if (EFI_ERROR (Status)) {
- if (Buffer != NULL) {
- if (StrCmp (Buffer, L"") != 0) {
- //
- // print out the status string
- //
- ShellPrintEx (-1, -1, L"%s", Buffer);
- } else {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_UNKNOWN_EDITOR), gShellDebug1HiiHandle);
- }
- } else {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_UNKNOWN_EDITOR), gShellDebug1HiiHandle);
- }
- }
- }
-
- ShellCommandLineFreeVarList (Package);
- }
-
- SHELL_FREE_NON_NULL (Buffer);
- SHELL_FREE_NON_NULL (NewName);
- return ShellStatus;
-}
+/** @file + Main entry point of editor + + (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellDebug1CommandsLib.h" +#include "HexEditor.h" + +// +// Global Variables +// +STATIC CONST SHELL_PARAM_ITEM ParamList[] = { + { L"-f", TypeFlag }, + { L"-d", TypeFlag }, + { L"-m", TypeFlag }, + { NULL, TypeMax } +}; + +/** + Function for 'hexedit' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunHexEdit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + CHAR16 *Buffer; + CHAR16 *ProblemParam; + SHELL_STATUS ShellStatus; + LIST_ENTRY *Package; + CHAR16 *NewName; + CONST CHAR16 *Name; + UINTN Offset; + UINTN Size; + EDIT_FILE_TYPE WhatToDo; + + Buffer = NULL; + ShellStatus = SHELL_SUCCESS; + NewName = NULL; + Buffer = NULL; + Name = NULL; + Offset = 0; + Size = 0; + WhatToDo = FileTypeNone; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize (); + ASSERT_EFI_ERROR (Status); + + Status = CommandInit (); + ASSERT_EFI_ERROR (Status); + + // + // parse the command line + // + Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE); + if (EFI_ERROR (Status)) { + if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"hexedit", ProblemParam); + FreePool (ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT (FALSE); + } + } else { + // + // Check for -d + // + if (ShellCommandLineGetFlag (Package, L"-d")) { + if (ShellCommandLineGetCount (Package) < 4) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"hexedit"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if (ShellCommandLineGetCount (Package) > 4) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"hexedit"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + WhatToDo = FileTypeDiskBuffer; + Name = ShellCommandLineGetRawValue (Package, 1); + Offset = ShellStrToUintn (ShellCommandLineGetRawValue (Package, 2)); + Size = ShellStrToUintn (ShellCommandLineGetRawValue (Package, 3)); + } + + if ((Offset == (UINTN)-1) || (Size == (UINTN)-1)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"hexedit", L"-d"); + ShellStatus = SHELL_INVALID_PARAMETER; + } + } + + // + // check for -f + // + if (ShellCommandLineGetFlag (Package, L"-f") && (WhatToDo == FileTypeNone)) { + if (ShellCommandLineGetCount (Package) < 2) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"hexedit"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if (ShellCommandLineGetCount (Package) > 2) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"hexedit"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + Name = ShellCommandLineGetRawValue (Package, 1); + if ((Name == NULL) || !IsValidFileName (Name)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"hexedit", Name); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + WhatToDo = FileTypeFileBuffer; + } + } + } + + // + // check for -m + // + if (ShellCommandLineGetFlag (Package, L"-m") && (WhatToDo == FileTypeNone)) { + if (ShellCommandLineGetCount (Package) < 3) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"hexedit"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if (ShellCommandLineGetCount (Package) > 3) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"hexedit"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + WhatToDo = FileTypeMemBuffer; + Offset = ShellStrToUintn (ShellCommandLineGetRawValue (Package, 1)); + Size = ShellStrToUintn (ShellCommandLineGetRawValue (Package, 2)); + } + } + + Name = ShellCommandLineGetRawValue (Package, 1); + if ((WhatToDo == FileTypeNone) && (Name != NULL)) { + if (ShellCommandLineGetCount (Package) > 2) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"hexedit"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if (!IsValidFileName (Name)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"hexedit", Name); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + WhatToDo = FileTypeFileBuffer; + } + } else if (WhatToDo == FileTypeNone) { + if (gEfiShellProtocol->GetCurDir (NULL) == NULL) { + ShellStatus = SHELL_NOT_FOUND; + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellDebug1HiiHandle, L"hexedit"); + } else { + NewName = EditGetDefaultFileName (L"bin"); + Name = NewName; + WhatToDo = FileTypeFileBuffer; + } + } + + if ((ShellStatus == SHELL_SUCCESS) && (WhatToDo == FileTypeNone)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"hexedit"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if ((WhatToDo == FileTypeFileBuffer) && (ShellGetCurrentDir (NULL) == NULL)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellDebug1HiiHandle, L"hexedit"); + ShellStatus = SHELL_INVALID_PARAMETER; + } + + if (ShellStatus == SHELL_SUCCESS) { + // + // Do the editor + // + Status = HMainEditorInit (); + if (EFI_ERROR (Status)) { + gST->ConOut->ClearScreen (gST->ConOut); + gST->ConOut->EnableCursor (gST->ConOut, TRUE); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_INIT_FAILED), gShellDebug1HiiHandle); + } else { + HMainEditorBackup (); + switch (WhatToDo) { + case FileTypeFileBuffer: + Status = HBufferImageRead ( + Name == NULL ? L"" : Name, + NULL, + 0, + 0, + 0, + 0, + FileTypeFileBuffer, + FALSE + ); + break; + + case FileTypeDiskBuffer: + Status = HBufferImageRead ( + NULL, + Name == NULL ? L"" : Name, + Offset, + Size, + 0, + 0, + FileTypeDiskBuffer, + FALSE + ); + break; + + case FileTypeMemBuffer: + Status = HBufferImageRead ( + NULL, + NULL, + 0, + 0, + (UINT32)Offset, + Size, + FileTypeMemBuffer, + FALSE + ); + break; + + default: + Status = EFI_NOT_FOUND; + break; + } + + if (!EFI_ERROR (Status)) { + HMainEditorRefresh (); + Status = HMainEditorKeyInput (); + } + + if (Status != EFI_OUT_OF_RESOURCES) { + // + // back up the status string + // + Buffer = CatSPrint (NULL, L"%s\r\n", StatusBarGetString ()); + } + } + + // + // cleanup + // + HMainEditorCleanup (); + + if (EFI_ERROR (Status)) { + if (ShellStatus == SHELL_SUCCESS) { + ShellStatus = SHELL_UNSUPPORTED; + } + } + + // + // print editor exit code on screen + // + if (Status == EFI_OUT_OF_RESOURCES) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle, L"hexedit"); + } else if (EFI_ERROR (Status)) { + if (Buffer != NULL) { + if (StrCmp (Buffer, L"") != 0) { + // + // print out the status string + // + ShellPrintEx (-1, -1, L"%s", Buffer); + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_UNKNOWN_EDITOR), gShellDebug1HiiHandle); + } + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_UNKNOWN_EDITOR), gShellDebug1HiiHandle); + } + } + } + + ShellCommandLineFreeVarList (Package); + } + + SHELL_FREE_NON_NULL (Buffer); + SHELL_FREE_NON_NULL (NewName); + return ShellStatus; +} diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexEditor.h b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexEditor.h index b13bc0e20d..e68937ea8e 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexEditor.h +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexEditor.h @@ -1,35 +1,35 @@ -/** @file
- Main include file for hex editor
-
- Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _EFI_SHELL_HEXEDIT_H_
-#define _EFI_SHELL_HEXEDIT_H_
-
-#include "UefiShellDebug1CommandsLib.h"
-#include "HexEditorTypes.h"
-
-#include "MainHexEditor.h"
-
-#include "BufferImage.h"
-#include "FileImage.h"
-#include "DiskImage.h"
-#include "MemImage.h"
-
-#include "EditTitleBar.h"
-#include "EditStatusBar.h"
-#include "EditInputBar.h"
-#include "EditMenuBar.h"
-
-#include "Misc.h"
-
-#include "Clipboard.h"
-
-extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditor;
-extern BOOLEAN HEditorFirst;
-extern BOOLEAN HEditorExit;
-
-#endif // _HEDITOR_H
+/** @file + Main include file for hex editor + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _EFI_SHELL_HEXEDIT_H_ +#define _EFI_SHELL_HEXEDIT_H_ + +#include "UefiShellDebug1CommandsLib.h" +#include "HexEditorTypes.h" + +#include "MainHexEditor.h" + +#include "BufferImage.h" +#include "FileImage.h" +#include "DiskImage.h" +#include "MemImage.h" + +#include "EditTitleBar.h" +#include "EditStatusBar.h" +#include "EditInputBar.h" +#include "EditMenuBar.h" + +#include "Misc.h" + +#include "Clipboard.h" + +extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditor; +extern BOOLEAN HEditorFirst; +extern BOOLEAN HEditorExit; + +#endif // _HEDITOR_H diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexEditorTypes.h b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexEditorTypes.h index 63a1d54965..9e7ccb647f 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexEditorTypes.h +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexEditorTypes.h @@ -1,117 +1,117 @@ -/** @file
- data types that are used by editor
-
- Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _HEDITOR_TYPE_H_
-#define _HEDITOR_TYPE_H_
-
-#include "UefiShellDebug1CommandsLib.h"
-#include "EditTitleBar.h"
-
-#define EFI_EDITOR_LINE_LIST SIGNATURE_32 ('e', 'e', 'l', 'l')
-
-#define ASCII_POSITION ((0x10 * 3) + 12)
-
-typedef struct {
- UINTN Row;
- UINTN Column;
-} HEFI_EDITOR_POSITION;
-
-typedef
-EFI_STATUS
-(*HEFI_MENU_ITEM_FUNCTION) (
- VOID
- );
-
-typedef struct {
- CHAR16 Name[50];
- CHAR16 Key[3];
- HEFI_MENU_ITEM_FUNCTION Function;
-} HMENU_ITEMS;
-
-typedef struct _HEFI_EDITOR_LINE {
- UINTN Signature;
- UINT8 Buffer[0x10];
- UINTN Size; // unit is Unicode
- LIST_ENTRY Link;
-} HEFI_EDITOR_LINE;
-
-typedef struct _HEFI_EDITOR_MENU_ITEM {
- CHAR16 NameToken;
- CHAR16 FunctionKeyToken;
- HEFI_MENU_ITEM_FUNCTION Function;
-} HEFI_EDITOR_MENU_ITEM;
-
-typedef struct {
- UINT32 Foreground : 4;
- UINT32 Background : 4;
-} HEFI_EDITOR_COLOR_ATTRIBUTES;
-
-typedef union {
- HEFI_EDITOR_COLOR_ATTRIBUTES Colors;
- UINTN Data;
-} HEFI_EDITOR_COLOR_UNION;
-
-typedef struct {
- UINTN Columns;
- UINTN Rows;
-} HEFI_EDITOR_TEXT_MODE;
-
-typedef struct {
- CHAR16 *Name;
-
- UINTN BlockSize;
- UINTN Size;
- UINTN Offset;
-} HEFI_EDITOR_DISK_IMAGE;
-
-typedef struct {
- EFI_CPU_IO2_PROTOCOL *IoFncs;
- UINTN Offset;
- UINTN Size;
-} HEFI_EDITOR_MEM_IMAGE;
-
-typedef struct {
- CHAR16 *FileName;
- UINTN Size; // file size
- BOOLEAN ReadOnly; // file is read-only or not
-} HEFI_EDITOR_FILE_IMAGE;
-
-typedef struct {
- LIST_ENTRY *ListHead; // list head of lines
- HEFI_EDITOR_LINE *Lines; // lines of current file
- UINTN NumLines; // number of lines
- HEFI_EDITOR_LINE *CurrentLine; // current line cursor is at
- HEFI_EDITOR_POSITION DisplayPosition; // cursor position in screen
- HEFI_EDITOR_POSITION MousePosition; // mouse position in screen
- HEFI_EDITOR_POSITION BufferPosition; // cursor position in buffer
- UINTN LowVisibleRow; // the lowest visible row of file position
- BOOLEAN HighBits; // cursor is at the high4 bits or low4 bits
- BOOLEAN Modified; // BUFFER is modified or not
- EDIT_FILE_TYPE BufferType;
-
- HEFI_EDITOR_FILE_IMAGE *FileImage;
- HEFI_EDITOR_DISK_IMAGE *DiskImage;
- HEFI_EDITOR_MEM_IMAGE *MemImage;
-} HEFI_EDITOR_BUFFER_IMAGE;
-
-typedef struct {
- HEFI_EDITOR_BUFFER_IMAGE *BufferImage;
-
- HEFI_EDITOR_COLOR_UNION ColorAttributes;
- HEFI_EDITOR_POSITION ScreenSize; // row number and column number
- EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInputEx;
- BOOLEAN MouseSupported;
- EFI_SIMPLE_POINTER_PROTOCOL *MouseInterface;
- INT32 MouseAccumulatorX;
- INT32 MouseAccumulatorY;
-
- UINTN SelectStart; // starting from 1
- UINTN SelectEnd; // starting from 1
-} HEFI_EDITOR_GLOBAL_EDITOR;
-
-#endif
+/** @file + data types that are used by editor + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _HEDITOR_TYPE_H_ +#define _HEDITOR_TYPE_H_ + +#include "UefiShellDebug1CommandsLib.h" +#include "EditTitleBar.h" + +#define EFI_EDITOR_LINE_LIST SIGNATURE_32 ('e', 'e', 'l', 'l') + +#define ASCII_POSITION ((0x10 * 3) + 12) + +typedef struct { + UINTN Row; + UINTN Column; +} HEFI_EDITOR_POSITION; + +typedef +EFI_STATUS +(*HEFI_MENU_ITEM_FUNCTION) ( + VOID + ); + +typedef struct { + CHAR16 Name[50]; + CHAR16 Key[3]; + HEFI_MENU_ITEM_FUNCTION Function; +} HMENU_ITEMS; + +typedef struct _HEFI_EDITOR_LINE { + UINTN Signature; + UINT8 Buffer[0x10]; + UINTN Size; // unit is Unicode + LIST_ENTRY Link; +} HEFI_EDITOR_LINE; + +typedef struct _HEFI_EDITOR_MENU_ITEM { + CHAR16 NameToken; + CHAR16 FunctionKeyToken; + HEFI_MENU_ITEM_FUNCTION Function; +} HEFI_EDITOR_MENU_ITEM; + +typedef struct { + UINT32 Foreground : 4; + UINT32 Background : 4; +} HEFI_EDITOR_COLOR_ATTRIBUTES; + +typedef union { + HEFI_EDITOR_COLOR_ATTRIBUTES Colors; + UINTN Data; +} HEFI_EDITOR_COLOR_UNION; + +typedef struct { + UINTN Columns; + UINTN Rows; +} HEFI_EDITOR_TEXT_MODE; + +typedef struct { + CHAR16 *Name; + + UINTN BlockSize; + UINTN Size; + UINTN Offset; +} HEFI_EDITOR_DISK_IMAGE; + +typedef struct { + EFI_CPU_IO2_PROTOCOL *IoFncs; + UINTN Offset; + UINTN Size; +} HEFI_EDITOR_MEM_IMAGE; + +typedef struct { + CHAR16 *FileName; + UINTN Size; // file size + BOOLEAN ReadOnly; // file is read-only or not +} HEFI_EDITOR_FILE_IMAGE; + +typedef struct { + LIST_ENTRY *ListHead; // list head of lines + HEFI_EDITOR_LINE *Lines; // lines of current file + UINTN NumLines; // number of lines + HEFI_EDITOR_LINE *CurrentLine; // current line cursor is at + HEFI_EDITOR_POSITION DisplayPosition; // cursor position in screen + HEFI_EDITOR_POSITION MousePosition; // mouse position in screen + HEFI_EDITOR_POSITION BufferPosition; // cursor position in buffer + UINTN LowVisibleRow; // the lowest visible row of file position + BOOLEAN HighBits; // cursor is at the high4 bits or low4 bits + BOOLEAN Modified; // BUFFER is modified or not + EDIT_FILE_TYPE BufferType; + + HEFI_EDITOR_FILE_IMAGE *FileImage; + HEFI_EDITOR_DISK_IMAGE *DiskImage; + HEFI_EDITOR_MEM_IMAGE *MemImage; +} HEFI_EDITOR_BUFFER_IMAGE; + +typedef struct { + HEFI_EDITOR_BUFFER_IMAGE *BufferImage; + + HEFI_EDITOR_COLOR_UNION ColorAttributes; + HEFI_EDITOR_POSITION ScreenSize; // row number and column number + EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInputEx; + BOOLEAN MouseSupported; + EFI_SIMPLE_POINTER_PROTOCOL *MouseInterface; + INT32 MouseAccumulatorX; + INT32 MouseAccumulatorY; + + UINTN SelectStart; // starting from 1 + UINTN SelectEnd; // starting from 1 +} HEFI_EDITOR_GLOBAL_EDITOR; + +#endif diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexeditStrings.uni b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexeditStrings.uni index 65d342fb55..9e04030752 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexeditStrings.uni +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexeditStrings.uni @@ -1,70 +1,70 @@ -// /**
-//
-// Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
-// (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// Abstract:
-//
-// Additional string definitions for UEFI Shell 2.0 Debug1 profile Edit command
-//
-//
-// **/
-
-/=#
-
-#langdef en-US "english"
-
-
-#string STR_HEXEDIT_USAGE #language en-US "\n\n %EHexEditor Usage%N\n"
-#string STR_HEXEDIT_FILENAME #language en-US " %H[-f] Filename%N Open File For Editing\n"
-#string STR_HEXEDIT_DISKNAME #language en-US " %H-d DiskName FirstBlockNo. BlockNumber%N Open Disk Block For Editing\n"
-#string STR_HEXEDIT_OFFSET_SIZE #language en-US " %H-m Offset Size%N Open Memory Region For Editing\n"
-#string STR_HEXEDIT_FILE_NAME #language en-US "%Hhexedit%N: Invalid File Name\n"
-#string STR_HEXEDIT_LIBEDITOR_MAINEDITOR_TITLE #language en-US "%EMainEditor init failed on TitleBar init\n%N"
-#string STR_HEXEDIT_LIBEDITOR_MAINEDITOR_MAINMENU #language en-US "%EMainEditor init failed on MainMenu init\n%N"
-#string STR_HEXEDIT_LIBEDITOR_MAINEDITOR_STATUS #language en-US "%EMainEditor init failed on StatusBar init\n%N"
-#string STR_HEXEDIT_LIBEDITOR_MAINEDITOR_INPUTBAR #language en-US "%EMainEditor init failed on InputBar init\n%N"
-#string STR_HEXEDIT_LIBEDITOR_MAINEDITOR_BUFFERIMAGE #language en-US "%EMainEditor init failed on BufferImage init\n%N"
-#string STR_HEXEDIT_LIBEDITOR_MAINEDITOR_CLIPBOARD #language en-US "%EMainEditor init failed on ClipBoard init\n%N"
-#string STR_HEXEDIT_LIBEDITOR_TITLEBAR_CLEAN #language en-US "TitleBar cleanup failed\n"
-#string STR_HEXEDIT_LIBEDITOR_MENUBAR_CLEAN #language en-US "MenuBar cleanup failed\n"
-#string STR_HEXEDIT_LIBEDITOR_STATUSBAR_CLEAN #language en-US "StatusBar cleanup failed\n"
-#string STR_HEXEDIT_LIBEDITOR_INPUTBAR_CLEAN #language en-US "InputBar cleanup failed\n"
-#string STR_HEXEDIT_LIBEDITOR_BUFFERIMAGE_CLEAN #language en-US "BufferImage cleanup failed\n"
-#string STR_HEXEDIT_LIBEDITOR_CLIPBOARD_CLEAN #language en-US "ClipBoard cleanup failed\n"
-#string STR_HEXEDIT_LIBINPUTBAR_MAININPUTBAR #language en-US "%s"
-#string STR_HEXEDIT_LIBMENUBAR_OPEN_FILE #language en-US "Open File"
-#string STR_HEXEDIT_LIBMENUBAR_OPEN_DISK #language en-US "Open Disk"
-#string STR_HEXEDIT_LIBMENUBAR_OPEN_MEMORY #language en-US "Open Memory"
-#string STR_HEXEDIT_LIBMENUBAR_SAVE_BUFFER #language en-US "Save Buffer"
-#string STR_HEXEDIT_LIBMENUBAR_SELECT_START #language en-US "Select Start"
-#string STR_HEXEDIT_LIBMENUBAR_SELECT_END #language en-US "Select End"
-#string STR_HEXEDIT_LIBMENUBAR_CUT #language en-US "Cut"
-#string STR_HEXEDIT_LIBMENUBAR_PASTE #language en-US "Paste"
-#string STR_HEXEDIT_LIBMENUBAR_GO_TO_OFFSET #language en-US "Go To Offset"
-#string STR_HEXEDIT_LIBTITLEBAR_MAINEDITOR #language en-US "%s"
-#string STR_HEXEDIT_LIBTITLEBAR_MAINEDITOR_C #language en-US "%c"
-#string STR_HEXEDIT_LIBTITLEBAR_MAINEDITOR_TWOVARS #language en-US "( %X ~ %X ) "
-#string STR_HEXEDIT_LIBTITLEBAR_FILE #language en-US " [FILE]"
-#string STR_HEXEDIT_LIBTITLEBAR_DISK #language en-US " [DISK]"
-#string STR_HEXEDIT_LIBTITLEBAR_MEM #language en-US " [MEM]"
-#string STR_HEXEDIT_HELP_TITLE #language en-US "Help \n"
-#string STR_HEXEDIT_HELP_BLANK #language en-US " \n"
-#string STR_HEXEDIT_HELP_LIST_TITLE #language en-US "Control Key Function Key Command \n"
-#string STR_HEXEDIT_HELP_DIV #language en-US "----------- ------------ ----------------- \n"
-#string STR_HEXEDIT_HELP_GO_TO_OFFSET #language en-US "Ctrl-G F1 Go To Offset \n"
-#string STR_HEXEDIT_HELP_SAVE_BUFFER #language en-US "Ctrl-S F2 Save Buffer \n"
-#string STR_HEXEDIT_HELP_EXIT #language en-US "Ctrl-Q F3 Exit \n"
-#string STR_HEXEDIT_HELP_SELECT_START #language en-US "Ctrl-T F4 Select Start \n"
-#string STR_HEXEDIT_HELP_SELECT_END #language en-US "Ctrl-D F5 Select End \n"
-#string STR_HEXEDIT_HELP_CUT #language en-US "Ctrl-X F6 Cut \n"
-#string STR_HEXEDIT_HELP_PASTE #language en-US "Ctrl-V F7 Paste \n"
-#string STR_HEXEDIT_HELP_OPEN_FILE #language en-US "Ctrl-O F8 Open File \n"
-#string STR_HEXEDIT_HELP_OPEN_DISK #language en-US "Ctrl-I F9 Open Disk \n"
-#string STR_HEXEDIT_HELP_OPEN_MEMORY #language en-US "Ctrl-M F10 Open Memory \n"
-#string STR_HEXEDIT_HELP_EXIT_HELP #language en-US "Use Ctrl-W to exit this help \n"
-#string STR_HEXEDIT_INIT_FAILED #language en-US "%Hhexedit%N: Initialization failed\n"
-#string STR_HEXEDIT_ONE_VAR #language en-US "%Hhexedit%N: %s\n"
-#string STR_HEXEDIT_UNKNOWN_EDITOR #language en-US "%Hhexedit%N: Unknown editor error\n"
-#string STR_HEXEDIT_NOREDIRECT #language en-US "%Hhexedit%N: Redirection is not allowed\n"
+// /** +// +// Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR> +// (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR> +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// Abstract: +// +// Additional string definitions for UEFI Shell 2.0 Debug1 profile Edit command +// +// +// **/ + +/=# + +#langdef en-US "english" + + +#string STR_HEXEDIT_USAGE #language en-US "\n\n %EHexEditor Usage%N\n" +#string STR_HEXEDIT_FILENAME #language en-US " %H[-f] Filename%N Open File For Editing\n" +#string STR_HEXEDIT_DISKNAME #language en-US " %H-d DiskName FirstBlockNo. BlockNumber%N Open Disk Block For Editing\n" +#string STR_HEXEDIT_OFFSET_SIZE #language en-US " %H-m Offset Size%N Open Memory Region For Editing\n" +#string STR_HEXEDIT_FILE_NAME #language en-US "%Hhexedit%N: Invalid File Name\n" +#string STR_HEXEDIT_LIBEDITOR_MAINEDITOR_TITLE #language en-US "%EMainEditor init failed on TitleBar init\n%N" +#string STR_HEXEDIT_LIBEDITOR_MAINEDITOR_MAINMENU #language en-US "%EMainEditor init failed on MainMenu init\n%N" +#string STR_HEXEDIT_LIBEDITOR_MAINEDITOR_STATUS #language en-US "%EMainEditor init failed on StatusBar init\n%N" +#string STR_HEXEDIT_LIBEDITOR_MAINEDITOR_INPUTBAR #language en-US "%EMainEditor init failed on InputBar init\n%N" +#string STR_HEXEDIT_LIBEDITOR_MAINEDITOR_BUFFERIMAGE #language en-US "%EMainEditor init failed on BufferImage init\n%N" +#string STR_HEXEDIT_LIBEDITOR_MAINEDITOR_CLIPBOARD #language en-US "%EMainEditor init failed on ClipBoard init\n%N" +#string STR_HEXEDIT_LIBEDITOR_TITLEBAR_CLEAN #language en-US "TitleBar cleanup failed\n" +#string STR_HEXEDIT_LIBEDITOR_MENUBAR_CLEAN #language en-US "MenuBar cleanup failed\n" +#string STR_HEXEDIT_LIBEDITOR_STATUSBAR_CLEAN #language en-US "StatusBar cleanup failed\n" +#string STR_HEXEDIT_LIBEDITOR_INPUTBAR_CLEAN #language en-US "InputBar cleanup failed\n" +#string STR_HEXEDIT_LIBEDITOR_BUFFERIMAGE_CLEAN #language en-US "BufferImage cleanup failed\n" +#string STR_HEXEDIT_LIBEDITOR_CLIPBOARD_CLEAN #language en-US "ClipBoard cleanup failed\n" +#string STR_HEXEDIT_LIBINPUTBAR_MAININPUTBAR #language en-US "%s" +#string STR_HEXEDIT_LIBMENUBAR_OPEN_FILE #language en-US "Open File" +#string STR_HEXEDIT_LIBMENUBAR_OPEN_DISK #language en-US "Open Disk" +#string STR_HEXEDIT_LIBMENUBAR_OPEN_MEMORY #language en-US "Open Memory" +#string STR_HEXEDIT_LIBMENUBAR_SAVE_BUFFER #language en-US "Save Buffer" +#string STR_HEXEDIT_LIBMENUBAR_SELECT_START #language en-US "Select Start" +#string STR_HEXEDIT_LIBMENUBAR_SELECT_END #language en-US "Select End" +#string STR_HEXEDIT_LIBMENUBAR_CUT #language en-US "Cut" +#string STR_HEXEDIT_LIBMENUBAR_PASTE #language en-US "Paste" +#string STR_HEXEDIT_LIBMENUBAR_GO_TO_OFFSET #language en-US "Go To Offset" +#string STR_HEXEDIT_LIBTITLEBAR_MAINEDITOR #language en-US "%s" +#string STR_HEXEDIT_LIBTITLEBAR_MAINEDITOR_C #language en-US "%c" +#string STR_HEXEDIT_LIBTITLEBAR_MAINEDITOR_TWOVARS #language en-US "( %X ~ %X ) " +#string STR_HEXEDIT_LIBTITLEBAR_FILE #language en-US " [FILE]" +#string STR_HEXEDIT_LIBTITLEBAR_DISK #language en-US " [DISK]" +#string STR_HEXEDIT_LIBTITLEBAR_MEM #language en-US " [MEM]" +#string STR_HEXEDIT_HELP_TITLE #language en-US "Help \n" +#string STR_HEXEDIT_HELP_BLANK #language en-US " \n" +#string STR_HEXEDIT_HELP_LIST_TITLE #language en-US "Control Key Function Key Command \n" +#string STR_HEXEDIT_HELP_DIV #language en-US "----------- ------------ ----------------- \n" +#string STR_HEXEDIT_HELP_GO_TO_OFFSET #language en-US "Ctrl-G F1 Go To Offset \n" +#string STR_HEXEDIT_HELP_SAVE_BUFFER #language en-US "Ctrl-S F2 Save Buffer \n" +#string STR_HEXEDIT_HELP_EXIT #language en-US "Ctrl-Q F3 Exit \n" +#string STR_HEXEDIT_HELP_SELECT_START #language en-US "Ctrl-T F4 Select Start \n" +#string STR_HEXEDIT_HELP_SELECT_END #language en-US "Ctrl-D F5 Select End \n" +#string STR_HEXEDIT_HELP_CUT #language en-US "Ctrl-X F6 Cut \n" +#string STR_HEXEDIT_HELP_PASTE #language en-US "Ctrl-V F7 Paste \n" +#string STR_HEXEDIT_HELP_OPEN_FILE #language en-US "Ctrl-O F8 Open File \n" +#string STR_HEXEDIT_HELP_OPEN_DISK #language en-US "Ctrl-I F9 Open Disk \n" +#string STR_HEXEDIT_HELP_OPEN_MEMORY #language en-US "Ctrl-M F10 Open Memory \n" +#string STR_HEXEDIT_HELP_EXIT_HELP #language en-US "Use Ctrl-W to exit this help \n" +#string STR_HEXEDIT_INIT_FAILED #language en-US "%Hhexedit%N: Initialization failed\n" +#string STR_HEXEDIT_ONE_VAR #language en-US "%Hhexedit%N: %s\n" +#string STR_HEXEDIT_UNKNOWN_EDITOR #language en-US "%Hhexedit%N: Unknown editor error\n" +#string STR_HEXEDIT_NOREDIRECT #language en-US "%Hhexedit%N: Redirection is not allowed\n" diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.c index 0eb917acf7..f23e997366 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.c +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.c @@ -1,2399 +1,2399 @@ -/** @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
- );
- ShellPrintEx (0, CurrentLine+1, L"%E%s%N", InfoString);
- }
-
- //
- // 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 ();
-}
+/** @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 + ); + ShellPrintEx (0, CurrentLine+1, L"%E%s%N", InfoString); + } + + // + // 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 (); +} diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.h b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.h index c77685c175..8cce1991aa 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.h +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.h @@ -1,69 +1,69 @@ -/** @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
-
-**/
-
-#ifndef _LIB_EDITOR_H_
-#define _LIB_EDITOR_H_
-
-#include "HexEditor.h"
-
-/**
- Init function for MainEditor
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_LOAD_ERROR A load error occurred.
-**/
-EFI_STATUS
-HMainEditorInit (
- VOID
- );
-
-/**
- Cleanup function for MainEditor.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_LOAD_ERROR A load error occurred.
-**/
-EFI_STATUS
-HMainEditorCleanup (
- VOID
- );
-
-/**
- Refresh function for MainEditor.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HMainEditorRefresh (
- VOID
- );
-
-/**
- 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
- );
-
-/**
- Backup function for MainEditor.
-**/
-VOID
-HMainEditorBackup (
- VOID
- );
-
-#endif
+/** @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 + +**/ + +#ifndef _LIB_EDITOR_H_ +#define _LIB_EDITOR_H_ + +#include "HexEditor.h" + +/** + Init function for MainEditor + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HMainEditorInit ( + VOID + ); + +/** + Cleanup function for MainEditor. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HMainEditorCleanup ( + VOID + ); + +/** + Refresh function for MainEditor. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HMainEditorRefresh ( + VOID + ); + +/** + 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 + ); + +/** + Backup function for MainEditor. +**/ +VOID +HMainEditorBackup ( + VOID + ); + +#endif diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MemImage.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MemImage.c index a7c80a4e96..8e85c70962 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MemImage.c +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MemImage.c @@ -1,273 +1,273 @@ -/** @file
- Functions to deal with Mem buffer
-
- Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "HexEditor.h"
-
-extern EFI_HANDLE HImageHandleBackup;
-
-extern HEFI_EDITOR_BUFFER_IMAGE HBufferImage;
-
-extern BOOLEAN HBufferImageNeedRefresh;
-extern BOOLEAN HBufferImageOnlyLineNeedRefresh;
-extern BOOLEAN HBufferImageMouseNeedRefresh;
-
-extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditor;
-
-HEFI_EDITOR_MEM_IMAGE HMemImage;
-HEFI_EDITOR_MEM_IMAGE HMemImageBackupVar;
-
-//
-// for basic initialization of HDiskImage
-//
-HEFI_EDITOR_MEM_IMAGE HMemImageConst = {
- NULL,
- 0,
- 0
-};
-
-/**
- Initialization function for HDiskImage.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_LOAD_ERROR A load error occurred.
-**/
-EFI_STATUS
-HMemImageInit (
- VOID
- )
-{
- EFI_STATUS Status;
-
- //
- // basically initialize the HMemImage
- //
- CopyMem (&HMemImage, &HMemImageConst, sizeof (HMemImage));
-
- Status = gBS->LocateProtocol (
- &gEfiCpuIo2ProtocolGuid,
- NULL,
- (VOID **)&HMemImage.IoFncs
- );
- if (!EFI_ERROR (Status)) {
- return EFI_SUCCESS;
- } else {
- return EFI_LOAD_ERROR;
- }
-}
-
-/**
- Backup function for HDiskImage. Only a few fields need to be backup.
- This is for making the Disk buffer refresh as few as possible.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HMemImageBackup (
- VOID
- )
-{
- HMemImageBackupVar.Offset = HMemImage.Offset;
- HMemImageBackupVar.Size = HMemImage.Size;
-
- return EFI_SUCCESS;
-}
-
-/**
- Set FileName field in HFileImage.
-
- @param[in] Offset The offset.
- @param[in] Size The size.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
-**/
-EFI_STATUS
-HMemImageSetMemOffsetSize (
- IN UINTN Offset,
- IN UINTN Size
- )
-{
- HMemImage.Offset = Offset;
- HMemImage.Size = Size;
-
- return EFI_SUCCESS;
-}
-
-/**
- Read a disk from disk into HBufferImage.
-
- @param[in] Offset The offset.
- @param[in] Size The size.
- @param[in] Recover if is for recover, no information print.
-
- @retval EFI_LOAD_ERROR A load error occurred.
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
-**/
-EFI_STATUS
-HMemImageRead (
- IN UINTN Offset,
- IN UINTN Size,
- IN BOOLEAN Recover
- )
-{
- EFI_STATUS Status;
- void *Buffer;
- CHAR16 *Str;
- HEFI_EDITOR_LINE *Line;
-
- HBufferImage.BufferType = FileTypeMemBuffer;
-
- Buffer = AllocateZeroPool (Size);
- if (Buffer == NULL) {
- StatusBarSetStatusString (L"Read Memory Failed");
- return EFI_OUT_OF_RESOURCES;
- }
-
- Status = HMemImage.IoFncs->Mem.Read (
- HMemImage.IoFncs,
- EfiCpuIoWidthUint8,
- Offset,
- Size,
- Buffer
- );
-
- if (EFI_ERROR (Status)) {
- FreePool (Buffer);
- StatusBarSetStatusString (L"Memory Specified Not Accessible");
- return EFI_LOAD_ERROR;
- }
-
- HBufferImageFree ();
-
- Status = HBufferImageBufferToList (Buffer, Size);
- FreePool (Buffer);
-
- if (EFI_ERROR (Status)) {
- StatusBarSetStatusString (L"Read Memory Failed");
- return Status;
- }
-
- Status = HMemImageSetMemOffsetSize (Offset, Size);
-
- HBufferImage.DisplayPosition.Row = 2;
- HBufferImage.DisplayPosition.Column = 10;
-
- HBufferImage.MousePosition.Row = 2;
- HBufferImage.MousePosition.Column = 10;
-
- HBufferImage.LowVisibleRow = 1;
- HBufferImage.HighBits = TRUE;
-
- HBufferImage.BufferPosition.Row = 1;
- HBufferImage.BufferPosition.Column = 1;
-
- if (!Recover) {
- Str = CatSPrint (NULL, L"%d Lines Read", HBufferImage.NumLines);
- if (Str == NULL) {
- StatusBarSetStatusString (L"Read Memory Failed");
- return EFI_OUT_OF_RESOURCES;
- }
-
- StatusBarSetStatusString (Str);
- SHELL_FREE_NON_NULL (Str);
-
- HMainEditor.SelectStart = 0;
- HMainEditor.SelectEnd = 0;
- }
-
- //
- // has line
- //
- if (HBufferImage.Lines != NULL) {
- HBufferImage.CurrentLine = CR (HBufferImage.ListHead->ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
- } else {
- //
- // create a dummy line
- //
- Line = HBufferImageCreateLine ();
- if (Line == NULL) {
- StatusBarSetStatusString (L"Read Memory Failed");
- return EFI_OUT_OF_RESOURCES;
- }
-
- HBufferImage.CurrentLine = Line;
- }
-
- HBufferImage.Modified = FALSE;
- HBufferImageNeedRefresh = TRUE;
- HBufferImageOnlyLineNeedRefresh = FALSE;
- HBufferImageMouseNeedRefresh = TRUE;
-
- return EFI_SUCCESS;
-}
-
-/**
- Save lines in HBufferImage to disk.
-
- @param[in] Offset The offset.
- @param[in] Size The size.
-
- @retval EFI_LOAD_ERROR A load error occurred.
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
-**/
-EFI_STATUS
-HMemImageSave (
- IN UINTN Offset,
- IN UINTN Size
- )
-{
- EFI_STATUS Status;
- VOID *Buffer;
-
- //
- // not modified, so directly return
- //
- if (HBufferImage.Modified == FALSE) {
- return EFI_SUCCESS;
- }
-
- HBufferImage.BufferType = FileTypeMemBuffer;
-
- Buffer = AllocateZeroPool (Size);
-
- if (Buffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Status = HBufferImageListToBuffer (Buffer, Size);
- if (EFI_ERROR (Status)) {
- FreePool (Buffer);
- return Status;
- }
-
- //
- // write back to memory
- //
- Status = HMemImage.IoFncs->Mem.Write (
- HMemImage.IoFncs,
- EfiCpuIoWidthUint8,
- Offset,
- Size,
- Buffer
- );
-
- FreePool (Buffer);
-
- if (EFI_ERROR (Status)) {
- return EFI_LOAD_ERROR;
- }
-
- //
- // now not modified
- //
- HBufferImage.Modified = FALSE;
-
- return EFI_SUCCESS;
-}
+/** @file + Functions to deal with Mem buffer + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "HexEditor.h" + +extern EFI_HANDLE HImageHandleBackup; + +extern HEFI_EDITOR_BUFFER_IMAGE HBufferImage; + +extern BOOLEAN HBufferImageNeedRefresh; +extern BOOLEAN HBufferImageOnlyLineNeedRefresh; +extern BOOLEAN HBufferImageMouseNeedRefresh; + +extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditor; + +HEFI_EDITOR_MEM_IMAGE HMemImage; +HEFI_EDITOR_MEM_IMAGE HMemImageBackupVar; + +// +// for basic initialization of HDiskImage +// +HEFI_EDITOR_MEM_IMAGE HMemImageConst = { + NULL, + 0, + 0 +}; + +/** + Initialization function for HDiskImage. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HMemImageInit ( + VOID + ) +{ + EFI_STATUS Status; + + // + // basically initialize the HMemImage + // + CopyMem (&HMemImage, &HMemImageConst, sizeof (HMemImage)); + + Status = gBS->LocateProtocol ( + &gEfiCpuIo2ProtocolGuid, + NULL, + (VOID **)&HMemImage.IoFncs + ); + if (!EFI_ERROR (Status)) { + return EFI_SUCCESS; + } else { + return EFI_LOAD_ERROR; + } +} + +/** + Backup function for HDiskImage. Only a few fields need to be backup. + This is for making the Disk buffer refresh as few as possible. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HMemImageBackup ( + VOID + ) +{ + HMemImageBackupVar.Offset = HMemImage.Offset; + HMemImageBackupVar.Size = HMemImage.Size; + + return EFI_SUCCESS; +} + +/** + Set FileName field in HFileImage. + + @param[in] Offset The offset. + @param[in] Size The size. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HMemImageSetMemOffsetSize ( + IN UINTN Offset, + IN UINTN Size + ) +{ + HMemImage.Offset = Offset; + HMemImage.Size = Size; + + return EFI_SUCCESS; +} + +/** + Read a disk from disk into HBufferImage. + + @param[in] Offset The offset. + @param[in] Size The size. + @param[in] Recover if is for recover, no information print. + + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HMemImageRead ( + IN UINTN Offset, + IN UINTN Size, + IN BOOLEAN Recover + ) +{ + EFI_STATUS Status; + void *Buffer; + CHAR16 *Str; + HEFI_EDITOR_LINE *Line; + + HBufferImage.BufferType = FileTypeMemBuffer; + + Buffer = AllocateZeroPool (Size); + if (Buffer == NULL) { + StatusBarSetStatusString (L"Read Memory Failed"); + return EFI_OUT_OF_RESOURCES; + } + + Status = HMemImage.IoFncs->Mem.Read ( + HMemImage.IoFncs, + EfiCpuIoWidthUint8, + Offset, + Size, + Buffer + ); + + if (EFI_ERROR (Status)) { + FreePool (Buffer); + StatusBarSetStatusString (L"Memory Specified Not Accessible"); + return EFI_LOAD_ERROR; + } + + HBufferImageFree (); + + Status = HBufferImageBufferToList (Buffer, Size); + FreePool (Buffer); + + if (EFI_ERROR (Status)) { + StatusBarSetStatusString (L"Read Memory Failed"); + return Status; + } + + Status = HMemImageSetMemOffsetSize (Offset, Size); + + HBufferImage.DisplayPosition.Row = 2; + HBufferImage.DisplayPosition.Column = 10; + + HBufferImage.MousePosition.Row = 2; + HBufferImage.MousePosition.Column = 10; + + HBufferImage.LowVisibleRow = 1; + HBufferImage.HighBits = TRUE; + + HBufferImage.BufferPosition.Row = 1; + HBufferImage.BufferPosition.Column = 1; + + if (!Recover) { + Str = CatSPrint (NULL, L"%d Lines Read", HBufferImage.NumLines); + if (Str == NULL) { + StatusBarSetStatusString (L"Read Memory Failed"); + return EFI_OUT_OF_RESOURCES; + } + + StatusBarSetStatusString (Str); + SHELL_FREE_NON_NULL (Str); + + HMainEditor.SelectStart = 0; + HMainEditor.SelectEnd = 0; + } + + // + // has line + // + if (HBufferImage.Lines != NULL) { + HBufferImage.CurrentLine = CR (HBufferImage.ListHead->ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); + } else { + // + // create a dummy line + // + Line = HBufferImageCreateLine (); + if (Line == NULL) { + StatusBarSetStatusString (L"Read Memory Failed"); + return EFI_OUT_OF_RESOURCES; + } + + HBufferImage.CurrentLine = Line; + } + + HBufferImage.Modified = FALSE; + HBufferImageNeedRefresh = TRUE; + HBufferImageOnlyLineNeedRefresh = FALSE; + HBufferImageMouseNeedRefresh = TRUE; + + return EFI_SUCCESS; +} + +/** + Save lines in HBufferImage to disk. + + @param[in] Offset The offset. + @param[in] Size The size. + + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HMemImageSave ( + IN UINTN Offset, + IN UINTN Size + ) +{ + EFI_STATUS Status; + VOID *Buffer; + + // + // not modified, so directly return + // + if (HBufferImage.Modified == FALSE) { + return EFI_SUCCESS; + } + + HBufferImage.BufferType = FileTypeMemBuffer; + + Buffer = AllocateZeroPool (Size); + + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = HBufferImageListToBuffer (Buffer, Size); + if (EFI_ERROR (Status)) { + FreePool (Buffer); + return Status; + } + + // + // write back to memory + // + Status = HMemImage.IoFncs->Mem.Write ( + HMemImage.IoFncs, + EfiCpuIoWidthUint8, + Offset, + Size, + Buffer + ); + + FreePool (Buffer); + + if (EFI_ERROR (Status)) { + return EFI_LOAD_ERROR; + } + + // + // now not modified + // + HBufferImage.Modified = FALSE; + + return EFI_SUCCESS; +} diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MemImage.h b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MemImage.h index 5e7fdc0b17..b44229ae83 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MemImage.h +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MemImage.h @@ -1,86 +1,86 @@ -/** @file
- Defines MemImage - the view of the file that is visible at any point,
- as well as the event handlers for editing the file
-
- Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _LIB_MEM_IMAGE_H_
-#define _LIB_MEM_IMAGE_H_
-
-#include "HexEditor.h"
-
-/**
- Initialization function for HDiskImage.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_LOAD_ERROR A load error occurred.
-**/
-EFI_STATUS
-HMemImageInit (
- VOID
- );
-
-/**
- Backup function for HDiskImage. Only a few fields need to be backup.
- This is for making the Disk buffer refresh as few as possible.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HMemImageBackup (
- VOID
- );
-
-/**
- Set FileName field in HFileImage.
-
- @param[in] Offset The offset.
- @param[in] Size The size.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
-**/
-EFI_STATUS
-HMemImageSetMemOffsetSize (
- IN UINTN Offset,
- IN UINTN Size
- );
-
-/**
- Read a disk from disk into HBufferImage.
-
- @param[in] Offset The offset.
- @param[in] Size The size.
- @param[in] Recover if is for recover, no information print.
-
- @retval EFI_LOAD_ERROR A load error occurred.
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
-**/
-EFI_STATUS
-HMemImageRead (
- IN UINTN Offset,
- IN UINTN Size,
- IN BOOLEAN Recover
- );
-
-/**
- Save lines in HBufferImage to disk.
-
- @param[in] Offset The offset.
- @param[in] Size The size.
-
- @retval EFI_LOAD_ERROR A load error occurred.
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
-**/
-EFI_STATUS
-HMemImageSave (
- IN UINTN Offset,
- IN UINTN Size
- );
-
-#endif
+/** @file + Defines MemImage - the view of the file that is visible at any point, + as well as the event handlers for editing the file + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _LIB_MEM_IMAGE_H_ +#define _LIB_MEM_IMAGE_H_ + +#include "HexEditor.h" + +/** + Initialization function for HDiskImage. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HMemImageInit ( + VOID + ); + +/** + Backup function for HDiskImage. Only a few fields need to be backup. + This is for making the Disk buffer refresh as few as possible. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HMemImageBackup ( + VOID + ); + +/** + Set FileName field in HFileImage. + + @param[in] Offset The offset. + @param[in] Size The size. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HMemImageSetMemOffsetSize ( + IN UINTN Offset, + IN UINTN Size + ); + +/** + Read a disk from disk into HBufferImage. + + @param[in] Offset The offset. + @param[in] Size The size. + @param[in] Recover if is for recover, no information print. + + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HMemImageRead ( + IN UINTN Offset, + IN UINTN Size, + IN BOOLEAN Recover + ); + +/** + Save lines in HBufferImage to disk. + + @param[in] Offset The offset. + @param[in] Size The size. + + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HMemImageSave ( + IN UINTN Offset, + IN UINTN Size + ); + +#endif diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Misc.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Misc.c index 9f96780372..91721db183 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Misc.c +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Misc.c @@ -1,253 +1,253 @@ -/** @file
- Implementation of various string and line routines
-
- Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "HexEditor.h"
-
-extern BOOLEAN HEditorMouseAction;
-
-/**
- Free a line and it's internal buffer.
-
- @param[in] Src The line to be freed.
-**/
-VOID
-HLineFree (
- IN HEFI_EDITOR_LINE *Src
- )
-{
- if (Src == NULL) {
- return;
- }
-
- SHELL_FREE_NON_NULL (Src);
-}
-
-/**
- Advance to the next Count lines.
-
- @param[in] Count The line number to advance.
-
- @retval NULL An error occurred.
- @return A pointer to the line after advance.
-**/
-HEFI_EDITOR_LINE *
-HLineAdvance (
- IN UINTN Count
- )
-{
- UINTN Index;
- HEFI_EDITOR_LINE *Line;
-
- Line = HMainEditor.BufferImage->CurrentLine;
- if (Line == NULL) {
- return NULL;
- }
-
- for (Index = 0; Index < Count; Index++) {
- //
- // if already last line
- //
- if (Line->Link.ForwardLink == HMainEditor.BufferImage->ListHead) {
- return NULL;
- }
-
- Line = CR (Line->Link.ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
- }
-
- return Line;
-}
-
-/**
- Retreat to the previous Count lines.
-
- @param[in] Count The line number to retreat.
-
- @retval NULL An error occurred.
- @return A pointer to the line after retreat.
-**/
-HEFI_EDITOR_LINE *
-HLineRetreat (
- IN UINTN Count
- )
-{
- UINTN Index;
- HEFI_EDITOR_LINE *Line;
-
- Line = HMainEditor.BufferImage->CurrentLine;
- if (Line == NULL) {
- return NULL;
- }
-
- for (Index = 0; Index < Count; Index++) {
- //
- // already the first line
- //
- if (Line->Link.BackLink == HMainEditor.BufferImage->ListHead) {
- return NULL;
- }
-
- Line = CR (Line->Link.BackLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
- }
-
- return Line;
-}
-
-/**
- Advance/Retreat lines.
-
- @param[in] Count The line number to advance/retreat.
- >0 : advance
- <0: retreat
-
- @retval NULL An error occurred.
- @return A pointer to the line after move.
-**/
-HEFI_EDITOR_LINE *
-HMoveLine (
- IN INTN Count
- )
-{
- HEFI_EDITOR_LINE *Line;
- UINTN AbsCount;
-
- //
- // difference with MoveCurrentLine
- // just return Line
- // do not set currentline to Line
- //
- if (Count <= 0) {
- AbsCount = (UINTN)ABS (Count);
- Line = HLineRetreat (AbsCount);
- } else {
- Line = HLineAdvance ((UINTN)Count);
- }
-
- return Line;
-}
-
-/**
- Advance/Retreat lines and set CurrentLine in BufferImage to it.
-
- @param[in] Count The line number to advance/retreat.
- >0 : advance
- <0: retreat
-
- @retval NULL An error occurred.
- @return A pointer to the line after move.
-**/
-HEFI_EDITOR_LINE *
-HMoveCurrentLine (
- IN INTN Count
- )
-{
- HEFI_EDITOR_LINE *Line;
- UINTN AbsCount;
-
- //
- // <0: retreat
- // >0: advance
- //
- if (Count <= 0) {
- AbsCount = (UINTN)ABS (Count);
- Line = HLineRetreat (AbsCount);
- } else {
- Line = HLineAdvance ((UINTN)Count);
- }
-
- if (Line == NULL) {
- return NULL;
- }
-
- HMainEditor.BufferImage->CurrentLine = Line;
-
- return Line;
-}
-
-/**
- Free all the lines in HBufferImage.
- Fields affected:
- Lines
- CurrentLine
- NumLines
- ListHead
-
- @param[in] ListHead The list head.
- @param[in] Lines The lines.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HFreeLines (
- IN LIST_ENTRY *ListHead,
- IN HEFI_EDITOR_LINE *Lines
- )
-{
- LIST_ENTRY *Link;
- HEFI_EDITOR_LINE *Line;
-
- //
- // release all the lines
- //
- if (Lines != NULL) {
- Line = Lines;
- Link = &(Line->Link);
- do {
- Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
- Link = Link->ForwardLink;
- HLineFree (Line);
- } while (Link != ListHead);
- }
-
- ListHead->ForwardLink = ListHead;
- ListHead->BackLink = ListHead;
-
- return EFI_SUCCESS;
-}
-
-/**
- Get the X information for the mouse.
-
- @param[in] GuidX The change.
-
- @return the new information.
-**/
-INT32
-HGetTextX (
- IN INT32 GuidX
- )
-{
- INT32 Gap;
-
- HMainEditor.MouseAccumulatorX += GuidX;
- Gap = (HMainEditor.MouseAccumulatorX * (INT32)HMainEditor.ScreenSize.Column) / (INT32)(50 * (INT32)HMainEditor.MouseInterface->Mode->ResolutionX);
- HMainEditor.MouseAccumulatorX = (HMainEditor.MouseAccumulatorX * (INT32)HMainEditor.ScreenSize.Column) % (INT32)(50 * (INT32)HMainEditor.MouseInterface->Mode->ResolutionX);
- HMainEditor.MouseAccumulatorX = HMainEditor.MouseAccumulatorX / (INT32)HMainEditor.ScreenSize.Column;
- return Gap;
-}
-
-/**
- Get the Y information for the mouse.
-
- @param[in] GuidY The change.
-
- @return the new information.
-**/
-INT32
-HGetTextY (
- IN INT32 GuidY
- )
-{
- INT32 Gap;
-
- HMainEditor.MouseAccumulatorY += GuidY;
- Gap = (HMainEditor.MouseAccumulatorY * (INT32)HMainEditor.ScreenSize.Row) / (INT32)(50 * (INT32)HMainEditor.MouseInterface->Mode->ResolutionY);
- HMainEditor.MouseAccumulatorY = (HMainEditor.MouseAccumulatorY * (INT32)HMainEditor.ScreenSize.Row) % (INT32)(50 * (INT32)HMainEditor.MouseInterface->Mode->ResolutionY);
- HMainEditor.MouseAccumulatorY = HMainEditor.MouseAccumulatorY / (INT32)HMainEditor.ScreenSize.Row;
-
- return Gap;
-}
+/** @file + Implementation of various string and line routines + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "HexEditor.h" + +extern BOOLEAN HEditorMouseAction; + +/** + Free a line and it's internal buffer. + + @param[in] Src The line to be freed. +**/ +VOID +HLineFree ( + IN HEFI_EDITOR_LINE *Src + ) +{ + if (Src == NULL) { + return; + } + + SHELL_FREE_NON_NULL (Src); +} + +/** + Advance to the next Count lines. + + @param[in] Count The line number to advance. + + @retval NULL An error occurred. + @return A pointer to the line after advance. +**/ +HEFI_EDITOR_LINE * +HLineAdvance ( + IN UINTN Count + ) +{ + UINTN Index; + HEFI_EDITOR_LINE *Line; + + Line = HMainEditor.BufferImage->CurrentLine; + if (Line == NULL) { + return NULL; + } + + for (Index = 0; Index < Count; Index++) { + // + // if already last line + // + if (Line->Link.ForwardLink == HMainEditor.BufferImage->ListHead) { + return NULL; + } + + Line = CR (Line->Link.ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); + } + + return Line; +} + +/** + Retreat to the previous Count lines. + + @param[in] Count The line number to retreat. + + @retval NULL An error occurred. + @return A pointer to the line after retreat. +**/ +HEFI_EDITOR_LINE * +HLineRetreat ( + IN UINTN Count + ) +{ + UINTN Index; + HEFI_EDITOR_LINE *Line; + + Line = HMainEditor.BufferImage->CurrentLine; + if (Line == NULL) { + return NULL; + } + + for (Index = 0; Index < Count; Index++) { + // + // already the first line + // + if (Line->Link.BackLink == HMainEditor.BufferImage->ListHead) { + return NULL; + } + + Line = CR (Line->Link.BackLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); + } + + return Line; +} + +/** + Advance/Retreat lines. + + @param[in] Count The line number to advance/retreat. + >0 : advance + <0: retreat + + @retval NULL An error occurred. + @return A pointer to the line after move. +**/ +HEFI_EDITOR_LINE * +HMoveLine ( + IN INTN Count + ) +{ + HEFI_EDITOR_LINE *Line; + UINTN AbsCount; + + // + // difference with MoveCurrentLine + // just return Line + // do not set currentline to Line + // + if (Count <= 0) { + AbsCount = (UINTN)ABS (Count); + Line = HLineRetreat (AbsCount); + } else { + Line = HLineAdvance ((UINTN)Count); + } + + return Line; +} + +/** + Advance/Retreat lines and set CurrentLine in BufferImage to it. + + @param[in] Count The line number to advance/retreat. + >0 : advance + <0: retreat + + @retval NULL An error occurred. + @return A pointer to the line after move. +**/ +HEFI_EDITOR_LINE * +HMoveCurrentLine ( + IN INTN Count + ) +{ + HEFI_EDITOR_LINE *Line; + UINTN AbsCount; + + // + // <0: retreat + // >0: advance + // + if (Count <= 0) { + AbsCount = (UINTN)ABS (Count); + Line = HLineRetreat (AbsCount); + } else { + Line = HLineAdvance ((UINTN)Count); + } + + if (Line == NULL) { + return NULL; + } + + HMainEditor.BufferImage->CurrentLine = Line; + + return Line; +} + +/** + Free all the lines in HBufferImage. + Fields affected: + Lines + CurrentLine + NumLines + ListHead + + @param[in] ListHead The list head. + @param[in] Lines The lines. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HFreeLines ( + IN LIST_ENTRY *ListHead, + IN HEFI_EDITOR_LINE *Lines + ) +{ + LIST_ENTRY *Link; + HEFI_EDITOR_LINE *Line; + + // + // release all the lines + // + if (Lines != NULL) { + Line = Lines; + Link = &(Line->Link); + do { + Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); + Link = Link->ForwardLink; + HLineFree (Line); + } while (Link != ListHead); + } + + ListHead->ForwardLink = ListHead; + ListHead->BackLink = ListHead; + + return EFI_SUCCESS; +} + +/** + Get the X information for the mouse. + + @param[in] GuidX The change. + + @return the new information. +**/ +INT32 +HGetTextX ( + IN INT32 GuidX + ) +{ + INT32 Gap; + + HMainEditor.MouseAccumulatorX += GuidX; + Gap = (HMainEditor.MouseAccumulatorX * (INT32)HMainEditor.ScreenSize.Column) / (INT32)(50 * (INT32)HMainEditor.MouseInterface->Mode->ResolutionX); + HMainEditor.MouseAccumulatorX = (HMainEditor.MouseAccumulatorX * (INT32)HMainEditor.ScreenSize.Column) % (INT32)(50 * (INT32)HMainEditor.MouseInterface->Mode->ResolutionX); + HMainEditor.MouseAccumulatorX = HMainEditor.MouseAccumulatorX / (INT32)HMainEditor.ScreenSize.Column; + return Gap; +} + +/** + Get the Y information for the mouse. + + @param[in] GuidY The change. + + @return the new information. +**/ +INT32 +HGetTextY ( + IN INT32 GuidY + ) +{ + INT32 Gap; + + HMainEditor.MouseAccumulatorY += GuidY; + Gap = (HMainEditor.MouseAccumulatorY * (INT32)HMainEditor.ScreenSize.Row) / (INT32)(50 * (INT32)HMainEditor.MouseInterface->Mode->ResolutionY); + HMainEditor.MouseAccumulatorY = (HMainEditor.MouseAccumulatorY * (INT32)HMainEditor.ScreenSize.Row) % (INT32)(50 * (INT32)HMainEditor.MouseInterface->Mode->ResolutionY); + HMainEditor.MouseAccumulatorY = HMainEditor.MouseAccumulatorY / (INT32)HMainEditor.ScreenSize.Row; + + return Gap; +} diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Misc.h b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Misc.h index f02324176a..ac6d05c82e 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Misc.h +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Misc.h @@ -1,87 +1,87 @@ -/** @file
- Definitions for various line and string routines
-
- Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _LIB_MISC_H_
-#define _LIB_MISC_H_
-
-#include "HexEditor.h"
-
-/**
- Advance/Retreat lines.
-
- @param[in] Count The line number to advance/retreat.
- >0 : advance
- <0: retreat
-
- @retval NULL An error occurred.
- @return A pointer to the line after move.
-**/
-HEFI_EDITOR_LINE *
-HMoveLine (
- IN INTN Count
- );
-
-/**
- Advance/Retreat lines and set CurrentLine in BufferImage to it.
-
- @param[in] Count The line number to advance/retreat.
- >0 : advance
- <0: retreat
-
- @retval NULL An error occurred.
- @return A pointer to the line after move.
-**/
-HEFI_EDITOR_LINE *
-HMoveCurrentLine (
- IN INTN Count
- );
-
-/**
- Free all the lines in HBufferImage.
- Fields affected:
- Lines
- CurrentLine
- NumLines
- ListHead
-
- @param[in] ListHead The list head.
- @param[in] Lines The lines.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-HFreeLines (
- IN LIST_ENTRY *ListHead,
- IN HEFI_EDITOR_LINE *Lines
- );
-
-/**
- Get the X information for the mouse.
-
- @param[in] GuidX The change.
-
- @return the new information.
-**/
-INT32
-HGetTextX (
- IN INT32 GuidX
- );
-
-/**
- Get the Y information for the mouse.
-
- @param[in] GuidY The change.
-
- @return the new information.
-**/
-INT32
-HGetTextY (
- IN INT32 GuidY
- );
-
-#endif
+/** @file + Definitions for various line and string routines + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _LIB_MISC_H_ +#define _LIB_MISC_H_ + +#include "HexEditor.h" + +/** + Advance/Retreat lines. + + @param[in] Count The line number to advance/retreat. + >0 : advance + <0: retreat + + @retval NULL An error occurred. + @return A pointer to the line after move. +**/ +HEFI_EDITOR_LINE * +HMoveLine ( + IN INTN Count + ); + +/** + Advance/Retreat lines and set CurrentLine in BufferImage to it. + + @param[in] Count The line number to advance/retreat. + >0 : advance + <0: retreat + + @retval NULL An error occurred. + @return A pointer to the line after move. +**/ +HEFI_EDITOR_LINE * +HMoveCurrentLine ( + IN INTN Count + ); + +/** + Free all the lines in HBufferImage. + Fields affected: + Lines + CurrentLine + NumLines + ListHead + + @param[in] ListHead The list head. + @param[in] Lines The lines. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HFreeLines ( + IN LIST_ENTRY *ListHead, + IN HEFI_EDITOR_LINE *Lines + ); + +/** + Get the X information for the mouse. + + @param[in] GuidX The change. + + @return the new information. +**/ +INT32 +HGetTextX ( + IN INT32 GuidX + ); + +/** + Get the Y information for the mouse. + + @param[in] GuidY The change. + + @return the new information. +**/ +INT32 +HGetTextY ( + IN INT32 GuidY + ); + +#endif |
