]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / HexEdit / MainHexEditor.c
1 /** @file
2 Defines the Main Editor data type -
3 - Global variables
4 - Instances of the other objects of the editor
5 - Main Interfaces
6
7 Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
8 SPDX-License-Identifier: BSD-2-Clause-Patent
9
10 **/
11
12 #include "HexEditor.h"
13 #include "EditStatusBar.h"
14 #include "EditInputBar.h"
15
16 HEFI_EDITOR_COLOR_ATTRIBUTES HOriginalColors;
17 INTN HOriginalMode;
18
19 //
20 // the first time editor launch
21 //
22 BOOLEAN HEditorFirst;
23
24 //
25 // it's time editor should exit
26 //
27 BOOLEAN HEditorExit;
28
29 BOOLEAN HEditorMouseAction;
30
31 extern HEFI_EDITOR_BUFFER_IMAGE HBufferImage;
32 extern HEFI_EDITOR_BUFFER_IMAGE HBufferImageBackupVar;
33
34 extern BOOLEAN HBufferImageMouseNeedRefresh;
35 extern BOOLEAN HBufferImageNeedRefresh;
36 extern BOOLEAN HBufferImageOnlyLineNeedRefresh;
37
38 HEFI_EDITOR_GLOBAL_EDITOR HMainEditor;
39 HEFI_EDITOR_GLOBAL_EDITOR HMainEditorBackupVar;
40
41 //
42 // basic initialization for MainEditor
43 //
44 HEFI_EDITOR_GLOBAL_EDITOR HMainEditorConst = {
45 &HBufferImage,
46 {
47 { 0, 0}
48 },
49 {
50 0,
51 0
52 },
53 NULL,
54 FALSE,
55 NULL,
56 0,
57 0,
58 1,
59 1
60 };
61
62 /**
63 Help info that will be displayed.
64 **/
65 EFI_STRING_ID HexMainMenuHelpInfo[] = {
66 STRING_TOKEN (STR_HEXEDIT_HELP_TITLE),
67 STRING_TOKEN (STR_HEXEDIT_HELP_BLANK),
68 STRING_TOKEN (STR_HEXEDIT_HELP_LIST_TITLE),
69 STRING_TOKEN (STR_HEXEDIT_HELP_DIV),
70 STRING_TOKEN (STR_HEXEDIT_HELP_GO_TO_OFFSET),
71 STRING_TOKEN (STR_HEXEDIT_HELP_SAVE_BUFFER),
72 STRING_TOKEN (STR_HEXEDIT_HELP_EXIT),
73 STRING_TOKEN (STR_HEXEDIT_HELP_SELECT_START),
74 STRING_TOKEN (STR_HEXEDIT_HELP_SELECT_END),
75 STRING_TOKEN (STR_HEXEDIT_HELP_CUT),
76 STRING_TOKEN (STR_HEXEDIT_HELP_PASTE),
77 STRING_TOKEN (STR_HEXEDIT_HELP_OPEN_FILE),
78 STRING_TOKEN (STR_HEXEDIT_HELP_OPEN_DISK),
79 STRING_TOKEN (STR_HEXEDIT_HELP_OPEN_MEMORY),
80 STRING_TOKEN (STR_HEXEDIT_HELP_BLANK),
81 STRING_TOKEN (STR_HEXEDIT_HELP_EXIT_HELP),
82 STRING_TOKEN (STR_HEXEDIT_HELP_BLANK),
83 STRING_TOKEN (STR_HEXEDIT_HELP_BLANK),
84 STRING_TOKEN (STR_HEXEDIT_HELP_BLANK),
85 STRING_TOKEN (STR_HEXEDIT_HELP_BLANK),
86 STRING_TOKEN (STR_HEXEDIT_HELP_BLANK),
87 STRING_TOKEN (STR_HEXEDIT_HELP_BLANK),
88 STRING_TOKEN (STR_HEXEDIT_HELP_DIV),
89 0
90 };
91
92 /**
93 show help menu.
94
95 @retval EFI_SUCCESS The operation was successful.
96 **/
97 EFI_STATUS
98 HMainCommandDisplayHelp (
99 VOID
100 )
101 {
102 INT32 CurrentLine;
103 CHAR16 *InfoString;
104 EFI_KEY_DATA KeyData;
105 EFI_STATUS Status;
106 UINTN EventIndex;
107
108 //
109 // print helpInfo
110 //
111 for (CurrentLine = 0; 0 != HexMainMenuHelpInfo[CurrentLine]; CurrentLine++) {
112 InfoString = HiiGetString (
113 gShellDebug1HiiHandle,
114 HexMainMenuHelpInfo[CurrentLine]
115 ,
116 NULL
117 );
118 ShellPrintEx (0, CurrentLine+1, L"%E%s%N", InfoString);
119 }
120
121 //
122 // scan for ctrl+w
123 //
124 while (TRUE) {
125 Status = gBS->WaitForEvent (1, &HMainEditor.TextInputEx->WaitForKeyEx, &EventIndex);
126 if (EFI_ERROR (Status) || (EventIndex != 0)) {
127 continue;
128 }
129
130 Status = HMainEditor.TextInputEx->ReadKeyStrokeEx (HMainEditor.TextInputEx, &KeyData);
131 if (EFI_ERROR (Status)) {
132 continue;
133 }
134
135 if (((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) ||
136 (KeyData.KeyState.KeyShiftState == EFI_SHIFT_STATE_VALID))
137 {
138 //
139 // For consoles that don't support/report shift state,
140 // CTRL+W is translated to L'W' - L'A' + 1.
141 //
142 if (KeyData.Key.UnicodeChar == L'W' - L'A' + 1) {
143 break;
144 }
145 } else if (((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) &&
146 ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) &&
147 ((KeyData.KeyState.KeyShiftState & ~(EFI_SHIFT_STATE_VALID | EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) == 0))
148 {
149 //
150 // For consoles that supports/reports shift state,
151 // make sure that only CONTROL shift key is pressed.
152 //
153 if ((KeyData.Key.UnicodeChar == 'w') || (KeyData.Key.UnicodeChar == 'W')) {
154 break;
155 }
156 }
157 }
158
159 // update screen with buffer's info
160 HBufferImageNeedRefresh = TRUE;
161 HBufferImageOnlyLineNeedRefresh = FALSE;
162 HBufferImageRefresh ();
163
164 return EFI_SUCCESS;
165 }
166
167 /**
168 Move cursor to specified lines.
169
170 @retval EFI_SUCCESS The operation was successful.
171 **/
172 EFI_STATUS
173 HMainCommandGoToOffset (
174 VOID
175 )
176 {
177 UINTN Size;
178 UINT64 Offset;
179 EFI_STATUS Status;
180 UINTN FRow;
181 UINTN FCol;
182
183 //
184 // variable initialization
185 //
186 Size = 0;
187 Offset = 0;
188 FRow = 0;
189 FCol = 0;
190
191 //
192 // get offset
193 //
194 Status = InputBarSetPrompt (L"Go To Offset: ");
195 if (EFI_ERROR (Status)) {
196 return Status;
197 }
198
199 Status = InputBarSetStringSize (8);
200 if (EFI_ERROR (Status)) {
201 return Status;
202 }
203
204 while (1) {
205 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
206
207 //
208 // ESC pressed
209 //
210 if (Status == EFI_NOT_READY) {
211 return EFI_SUCCESS;
212 }
213
214 //
215 // THE input string length should > 0
216 //
217 if (StrLen (InputBarGetString ()) > 0) {
218 Status = ShellConvertStringToUint64 (InputBarGetString (), &Offset, TRUE, FALSE);
219 if (EFI_ERROR (Status)) {
220 StatusBarSetStatusString (L"Invalid Offset");
221 return EFI_SUCCESS;
222 }
223
224 break;
225 }
226 }
227
228 Size = HBufferImageGetTotalSize ();
229 if (Offset >= Size) {
230 StatusBarSetStatusString (L"Invalid Offset");
231 return EFI_SUCCESS;
232 }
233
234 FRow = (UINTN)DivU64x32 (Offset, 0x10) + 1;
235 FCol = (UINTN)ModU64x32 (Offset, 0x10) + 1;
236
237 HBufferImageMovePosition (FRow, FCol, TRUE);
238
239 HBufferImageNeedRefresh = TRUE;
240 HBufferImageOnlyLineNeedRefresh = FALSE;
241 HBufferImageMouseNeedRefresh = TRUE;
242
243 return EFI_SUCCESS;
244 }
245
246 /**
247 Save current opened buffer.
248 If is file buffer, you can save to current file name or
249 save to another file name.
250
251 @retval EFI_SUCCESS The operation was successful.
252 @retval EFI_OUT_OF_RESOURCES A memory allocation occurred.
253 @retval EFI_LOAD_ERROR A load error occurred.
254 **/
255 EFI_STATUS
256 HMainCommandSaveBuffer (
257 VOID
258 )
259 {
260 EFI_STATUS Status;
261 BOOLEAN Done;
262 CHAR16 *FileName;
263 BOOLEAN OldFile;
264 CHAR16 *Str;
265 EFI_FILE_INFO *Info;
266 SHELL_FILE_HANDLE ShellFileHandle;
267
268 if (HMainEditor.BufferImage->BufferType != FileTypeFileBuffer) {
269 if (!HMainEditor.BufferImage->Modified) {
270 return EFI_SUCCESS;
271 }
272
273 Status = InputBarSetPrompt (L"Dangerous to save disk/mem buffer. Save (Yes/No/Cancel) ? ");
274 if (EFI_ERROR (Status)) {
275 return Status;
276 }
277
278 //
279 // the answer is just one character
280 //
281 Status = InputBarSetStringSize (1);
282 if (EFI_ERROR (Status)) {
283 return Status;
284 }
285
286 //
287 // loop for user's answer
288 // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'
289 //
290 while (1) {
291 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
292
293 //
294 // ESC pressed
295 //
296 if (Status == EFI_NOT_READY) {
297 return EFI_SUCCESS;
298 }
299
300 switch (InputBarGetString ()[0]) {
301 case L'y':
302 case L'Y':
303 //
304 // want to save this buffer first
305 //
306 Status = HBufferImageSave (
307 NULL,
308 HMainEditor.BufferImage->DiskImage->Name,
309 HMainEditor.BufferImage->DiskImage->Offset,
310 HMainEditor.BufferImage->DiskImage->Size,
311 HMainEditor.BufferImage->MemImage->Offset,
312 HMainEditor.BufferImage->MemImage->Size,
313 HMainEditor.BufferImage->BufferType
314 );
315
316 if (EFI_ERROR (Status)) {
317 StatusBarSetStatusString (L"BufferSave: Problems Writing");
318 return Status;
319 }
320
321 return EFI_SUCCESS;
322
323 case L'n':
324 case L'N':
325 //
326 // the file won't be saved
327 //
328 return EFI_SUCCESS;
329
330 case L'c':
331 case L'C':
332 return EFI_SUCCESS;
333 }
334
335 //
336 // end of switch
337 //
338 }
339
340 //
341 // ENDOF WHILE
342 //
343 }
344
345 //
346 // ENDOF != FILEBUFFER
347 //
348 // This command will save currently opened file to disk.
349 // You can choose save to another file name or just save to
350 // current file name.
351 // Below is the scenario of Save File command: (
352 // Suppose the old file name is A )
353 // 1. An Input Bar will be prompted: "File To Save: [ old file name]"
354 // IF user press ESC, Save File command ends .
355 // IF user press Enter, input file name will be A.
356 // IF user inputs a new file name B, input file name will be B.
357 //
358 // 2. IF input file name is A, go to do Step 3.
359 // IF input file name is B, go to do Step 4.
360 //
361 // 3. IF A is read only, Status Bar will show "Access Denied"
362 // and Save File commands ends.
363 // IF A is not read only, save file buffer to disk
364 // and remove Modified flag in Title Bar , then Save File command ends.
365 //
366 // 4. IF B does not exist, create this file and save file buffer to it.
367 // Go to do Step 7.
368 // IF B exits, do Step 5.
369 //
370 // 5. An Input Bar will be prompted:
371 // "File Exists. Overwrite ( Yes/No/Cancel ) ?"
372 // IF user press 'y' or 'Y', do Step 6.
373 // IF user press 'n' or 'N', Save File commands ends.
374 // IF user press 'c' or 'C' or ESC, Save File commands ends.
375 //
376 // 6. IF B is a read-only file, Status Bar will show "Access Denied"
377 // and Save File commands ends.
378 // IF B can be read and write, save file buffer to B.
379 //
380 // 7. Update File Name field in Title Bar to B
381 // and remove the Modified flag in Title Bar.
382 //
383 Str = CatSPrint (
384 NULL,
385 L"File to Save: [%s]",
386 HMainEditor.BufferImage->FileImage->FileName
387 );
388 if (Str == NULL) {
389 return EFI_OUT_OF_RESOURCES;
390 }
391
392 if (StrLen (Str) >= 50) {
393 //
394 // replace the long file name with "..."
395 //
396 Str[46] = L'.';
397 Str[47] = L'.';
398 Str[48] = L'.';
399 Str[49] = L']';
400 Str[50] = L'\0';
401 }
402
403 Status = InputBarSetPrompt (Str);
404 if (EFI_ERROR (Status)) {
405 return Status;
406 }
407
408 Status = InputBarSetStringSize (100);
409 if (EFI_ERROR (Status)) {
410 return Status;
411 }
412
413 //
414 // get new file name
415 //
416 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
417
418 //
419 // if user pressed ESC
420 //
421 if (Status == EFI_NOT_READY) {
422 SHELL_FREE_NON_NULL (Str);
423 return EFI_SUCCESS;
424 }
425
426 SHELL_FREE_NON_NULL (Str);
427
428 //
429 // if just enter pressed, so think save to current file name
430 //
431 if (StrLen (InputBarGetString ()) == 0) {
432 FileName = CatSPrint (
433 NULL,
434 L"%s",
435 HMainEditor.BufferImage->FileImage->FileName
436 );
437 } else {
438 FileName = CatSPrint (NULL, L"%s", InputBarGetString ());
439 }
440
441 if (FileName == NULL) {
442 return EFI_OUT_OF_RESOURCES;
443 }
444
445 if (!IsValidFileName (FileName)) {
446 StatusBarSetStatusString (L"Invalid File Name");
447 SHELL_FREE_NON_NULL (FileName);
448 return EFI_SUCCESS;
449 }
450
451 OldFile = FALSE;
452
453 //
454 // save to the old file
455 //
456 if (StringNoCaseCompare (
457 &FileName,
458 &HMainEditor.BufferImage->FileImage->FileName
459 ) == 0)
460 {
461 OldFile = TRUE;
462 }
463
464 if (OldFile) {
465 //
466 // if the file is read only, so can not write back to it.
467 //
468 if (HMainEditor.BufferImage->FileImage->ReadOnly) {
469 StatusBarSetStatusString (L"Access Denied");
470 SHELL_FREE_NON_NULL (FileName);
471 return EFI_SUCCESS;
472 }
473 } else {
474 Status = ShellOpenFileByName (FileName, &ShellFileHandle, EFI_FILE_MODE_READ, 0);
475
476 if (!EFI_ERROR (Status)) {
477 Info = ShellGetFileInfo (ShellFileHandle);
478
479 ShellCloseFile (&ShellFileHandle);
480 //
481 // check if read only
482 //
483 if (Info->Attribute & EFI_FILE_READ_ONLY) {
484 StatusBarSetStatusString (L"Access Denied");
485 SHELL_FREE_NON_NULL (FileName);
486 return EFI_SUCCESS;
487 }
488
489 SHELL_FREE_NON_NULL (Info);
490 //
491 // ask user whether to overwrite this file
492 //
493 Status = InputBarSetPrompt (L"File exists. Overwrite (Yes/No/Cancel) ? ");
494 if (EFI_ERROR (Status)) {
495 SHELL_FREE_NON_NULL (FileName);
496 return Status;
497 }
498
499 Status = InputBarSetStringSize (1);
500 if (EFI_ERROR (Status)) {
501 SHELL_FREE_NON_NULL (FileName);
502 return Status;
503 }
504
505 Done = FALSE;
506 while (!Done) {
507 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
508
509 if (Status == EFI_NOT_READY) {
510 SHELL_FREE_NON_NULL (FileName);
511 return EFI_SUCCESS;
512 }
513
514 switch (InputBarGetString ()[0]) {
515 case L'y':
516 case L'Y':
517 Done = TRUE;
518 break;
519 case L'n':
520 case L'N':
521 SHELL_FREE_NON_NULL (FileName);
522 return EFI_SUCCESS;
523 case L'c':
524 case L'C':
525 SHELL_FREE_NON_NULL (FileName);
526 return EFI_SUCCESS;
527 } // switch
528 } // while
529 } // if opened existing file
530 } // if OldFile
531
532 //
533 // save file back to disk
534 //
535 Status = HBufferImageSave (
536 FileName,
537 HMainEditor.BufferImage->DiskImage->Name,
538 HMainEditor.BufferImage->DiskImage->Offset,
539 HMainEditor.BufferImage->DiskImage->Size,
540 HMainEditor.BufferImage->MemImage->Offset,
541 HMainEditor.BufferImage->MemImage->Size,
542 FileTypeFileBuffer
543 );
544 SHELL_FREE_NON_NULL (FileName);
545
546 if (EFI_ERROR (Status)) {
547 return EFI_LOAD_ERROR;
548 }
549
550 return EFI_SUCCESS;
551 }
552
553 /**
554 Load a disk buffer editor.
555
556 @retval EFI_SUCCESS The operation was successful.
557 @retval EFI_OUT_OF_RESOURCES A memory allocation occurred.
558 @retval EFI_LOAD_ERROR A load error occurred.
559 **/
560 EFI_STATUS
561 HMainCommandSelectStart (
562 VOID
563 )
564 {
565 UINTN Start;
566
567 Start = (HMainEditor.BufferImage->BufferPosition.Row - 1) * 0x10 + HMainEditor.BufferImage->BufferPosition.Column;
568
569 //
570 // last line
571 //
572 if (HMainEditor.BufferImage->CurrentLine->Link.ForwardLink == HMainEditor.BufferImage->ListHead) {
573 if (HMainEditor.BufferImage->BufferPosition.Column > HMainEditor.BufferImage->CurrentLine->Size) {
574 StatusBarSetStatusString (L"Invalid Block Start");
575 return EFI_LOAD_ERROR;
576 }
577 }
578
579 if ((HMainEditor.SelectEnd != 0) && (Start > HMainEditor.SelectEnd)) {
580 StatusBarSetStatusString (L"Invalid Block Start");
581 return EFI_LOAD_ERROR;
582 }
583
584 HMainEditor.SelectStart = Start;
585
586 HBufferImageNeedRefresh = TRUE;
587
588 return EFI_SUCCESS;
589 }
590
591 /**
592 Load a disk buffer editor.
593
594 @retval EFI_SUCCESS The operation was successful.
595 @retval EFI_OUT_OF_RESOURCES A memory allocation occurred.
596 @retval EFI_LOAD_ERROR A load error occurred.
597 **/
598 EFI_STATUS
599 HMainCommandSelectEnd (
600 VOID
601 )
602 {
603 UINTN End;
604
605 End = (HMainEditor.BufferImage->BufferPosition.Row - 1) * 0x10 + HMainEditor.BufferImage->BufferPosition.Column;
606
607 //
608 // last line
609 //
610 if (HMainEditor.BufferImage->CurrentLine->Link.ForwardLink == HMainEditor.BufferImage->ListHead) {
611 if (HMainEditor.BufferImage->BufferPosition.Column > HMainEditor.BufferImage->CurrentLine->Size) {
612 StatusBarSetStatusString (L"Invalid Block End");
613 return EFI_LOAD_ERROR;
614 }
615 }
616
617 if ((HMainEditor.SelectStart != 0) && (End < HMainEditor.SelectStart)) {
618 StatusBarSetStatusString (L"Invalid Block End");
619 return EFI_SUCCESS;
620 }
621
622 HMainEditor.SelectEnd = End;
623
624 HBufferImageNeedRefresh = TRUE;
625
626 return EFI_SUCCESS;
627 }
628
629 /**
630 Cut current line to clipboard.
631
632 @retval EFI_SUCCESS The operation was successful.
633 @retval EFI_OUT_OF_RESOURCES A memory allocation occurred.
634 @retval EFI_LOAD_ERROR A load error occurred.
635 **/
636 EFI_STATUS
637 HMainCommandCut (
638 VOID
639 )
640 {
641 UINTN Index;
642 LIST_ENTRY *Link;
643 UINT8 *Buffer;
644 UINTN Count;
645
646 //
647 // not select, so not allowed to cut
648 //
649 if (HMainEditor.SelectStart == 0) {
650 StatusBarSetStatusString (L"No Block is Selected");
651 return EFI_SUCCESS;
652 }
653
654 //
655 // not select, so not allowed to cut
656 //
657 if (HMainEditor.SelectEnd == 0) {
658 StatusBarSetStatusString (L"No Block is Selected");
659 return EFI_SUCCESS;
660 }
661
662 Link = HMainEditor.BufferImage->ListHead->ForwardLink;
663 for (Index = 0; Index < (HMainEditor.SelectEnd - 1) / 0x10; Index++) {
664 Link = Link->ForwardLink;
665 }
666
667 Count = HMainEditor.SelectEnd - HMainEditor.SelectStart + 1;
668 Buffer = AllocateZeroPool (Count);
669 if (Buffer == NULL) {
670 return EFI_OUT_OF_RESOURCES;
671 }
672
673 //
674 // cut the selected area
675 //
676 HBufferImageDeleteCharacterFromBuffer (
677 HMainEditor.SelectStart - 1,
678 Count,
679 Buffer
680 );
681
682 //
683 // put to clipboard
684 //
685 HClipBoardSet (Buffer, Count);
686
687 HBufferImageNeedRefresh = TRUE;
688 HBufferImageOnlyLineNeedRefresh = FALSE;
689
690 if (!HMainEditor.BufferImage->Modified) {
691 HMainEditor.BufferImage->Modified = TRUE;
692 }
693
694 //
695 // now no select area
696 //
697 HMainEditor.SelectStart = 0;
698 HMainEditor.SelectEnd = 0;
699
700 return EFI_SUCCESS;
701 }
702
703 /**
704 Paste line to file buffer.
705
706 @retval EFI_SUCCESS The operation was successful.
707 @retval EFI_OUT_OF_RESOURCES A memory allocation occurred.
708 @retval EFI_LOAD_ERROR A load error occurred.
709 **/
710 EFI_STATUS
711 HMainCommandPaste (
712 VOID
713 )
714 {
715 BOOLEAN OnlyLineRefresh;
716 HEFI_EDITOR_LINE *Line;
717 UINT8 *Buffer;
718 UINTN Count;
719 UINTN FPos;
720
721 Count = HClipBoardGet (&Buffer);
722 if ((Count == 0) || (Buffer == NULL)) {
723 StatusBarSetStatusString (L"Nothing to Paste");
724 return EFI_SUCCESS;
725 }
726
727 Line = HMainEditor.BufferImage->CurrentLine;
728
729 OnlyLineRefresh = FALSE;
730 if ((Line->Link.ForwardLink == HMainEditor.BufferImage->ListHead) && (Line->Size + Count < 0x10)) {
731 //
732 // is at last line, and after paste will not exceed
733 // so only this line need to be refreshed
734 //
735 // if after add, the line is 0x10, then will append a new line
736 // so the whole page will need be refreshed
737 //
738 OnlyLineRefresh = TRUE;
739 }
740
741 FPos = 0x10 * (HMainEditor.BufferImage->BufferPosition.Row - 1) + HMainEditor.BufferImage->BufferPosition.Column - 1;
742
743 HBufferImageAddCharacterToBuffer (FPos, Count, Buffer);
744
745 if (OnlyLineRefresh) {
746 HBufferImageNeedRefresh = FALSE;
747 HBufferImageOnlyLineNeedRefresh = TRUE;
748 } else {
749 HBufferImageNeedRefresh = TRUE;
750 HBufferImageOnlyLineNeedRefresh = FALSE;
751 }
752
753 if (!HMainEditor.BufferImage->Modified) {
754 HMainEditor.BufferImage->Modified = TRUE;
755 }
756
757 return EFI_SUCCESS;
758 }
759
760 /**
761 Exit editor.
762
763 @retval EFI_SUCCESS The operation was successful.
764 @retval EFI_OUT_OF_RESOURCES A memory allocation occurred.
765 @retval EFI_LOAD_ERROR A load error occurred.
766 **/
767 EFI_STATUS
768 HMainCommandExit (
769 VOID
770 )
771 {
772 EFI_STATUS Status;
773
774 //
775 // Below is the scenario of Exit command:
776 // 1. IF currently opened file is not modified, exit the editor and
777 // Exit command ends.
778 // IF currently opened file is modified, do Step 2
779 //
780 // 2. An Input Bar will be prompted:
781 // "File modified. Save ( Yes/No/Cancel )?"
782 // IF user press 'y' or 'Y', currently opened file will be saved and
783 // Editor exits
784 // IF user press 'n' or 'N', currently opened file will not be saved
785 // and Editor exits.
786 // IF user press 'c' or 'C' or ESC, Exit command ends.
787 //
788 //
789 // if file has been modified, so will prompt user
790 // whether to save the changes
791 //
792 if (HMainEditor.BufferImage->Modified) {
793 Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? ");
794 if (EFI_ERROR (Status)) {
795 return Status;
796 }
797
798 Status = InputBarSetStringSize (1);
799 if (EFI_ERROR (Status)) {
800 return Status;
801 }
802
803 while (1) {
804 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
805
806 //
807 // ESC pressed
808 //
809 if (Status == EFI_NOT_READY) {
810 return EFI_SUCCESS;
811 }
812
813 switch (InputBarGetString ()[0]) {
814 case L'y':
815 case L'Y':
816 //
817 // write file back to disk
818 //
819 Status = HBufferImageSave (
820 HMainEditor.BufferImage->FileImage->FileName,
821 HMainEditor.BufferImage->DiskImage->Name,
822 HMainEditor.BufferImage->DiskImage->Offset,
823 HMainEditor.BufferImage->DiskImage->Size,
824 HMainEditor.BufferImage->MemImage->Offset,
825 HMainEditor.BufferImage->MemImage->Size,
826 HMainEditor.BufferImage->BufferType
827 );
828 if (!EFI_ERROR (Status)) {
829 HEditorExit = TRUE;
830 }
831
832 return Status;
833
834 case L'n':
835 case L'N':
836 HEditorExit = TRUE;
837 return EFI_SUCCESS;
838
839 case L'c':
840 case L'C':
841 return EFI_SUCCESS;
842 }
843 }
844 }
845
846 HEditorExit = TRUE;
847 return EFI_SUCCESS;
848 }
849
850 /**
851 Load a file from disk to editor.
852
853 @retval EFI_SUCCESS The operation was successful.
854 @retval EFI_OUT_OF_RESOURCES A memory allocation occurred.
855 @retval EFI_LOAD_ERROR A load error occurred.
856 **/
857 EFI_STATUS
858 HMainCommandOpenFile (
859 VOID
860 )
861 {
862 BOOLEAN Done;
863 EFI_STATUS Status;
864 EDIT_FILE_TYPE BufferType;
865
866 BufferType = HMainEditor.BufferImage->BufferType;
867
868 //
869 // This command will open a file from current working directory.
870 // Read-only file can also be opened. But it can not be modified.
871 // Below is the scenario of Open File command:
872 // 1. IF currently opened file has not been modified, directly go to step .
873 // IF currently opened file has been modified, an Input Bar will be
874 // prompted as :
875 // "File Modified. Save ( Yes/No/Cancel) ?"
876 // IF user press 'y' or 'Y', currently opened file will be saved.
877 // IF user press 'n' or 'N', currently opened file will
878 // not be saved.
879 // IF user press 'c' or 'C' or ESC, Open File command ends and
880 // currently opened file is still opened.
881 //
882 // 2. An Input Bar will be prompted as : "File Name to Open: "
883 // IF user press ESC, Open File command ends and
884 // currently opened file is still opened.
885 // Any other inputs with a Return will cause
886 // currently opened file close.
887 //
888 // 3. IF user input file name is an existing file ,
889 // this file will be read and opened.
890 // IF user input file name is a new file, this file will be created
891 // and opened. This file's type ( UNICODE or ASCII ) is the same with
892 // the old file.
893 //
894 //
895 // if current file is modified, so you need to choose whether to
896 // save it first.
897 //
898 if (HMainEditor.BufferImage->Modified) {
899 Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? ");
900 if (EFI_ERROR (Status)) {
901 return Status;
902 }
903
904 //
905 // the answer is just one character
906 //
907 Status = InputBarSetStringSize (1);
908 if (EFI_ERROR (Status)) {
909 return Status;
910 }
911
912 //
913 // loop for user's answer
914 // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'
915 //
916 Done = FALSE;
917 while (!Done) {
918 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
919
920 //
921 // ESC pressed
922 //
923 if (Status == EFI_NOT_READY) {
924 return EFI_SUCCESS;
925 }
926
927 switch (InputBarGetString ()[0]) {
928 case L'y':
929 case L'Y':
930 //
931 // want to save this buffer first
932 //
933 Status = HBufferImageSave (
934 HMainEditor.BufferImage->FileImage->FileName,
935 HMainEditor.BufferImage->DiskImage->Name,
936 HMainEditor.BufferImage->DiskImage->Offset,
937 HMainEditor.BufferImage->DiskImage->Size,
938 HMainEditor.BufferImage->MemImage->Offset,
939 HMainEditor.BufferImage->MemImage->Size,
940 HMainEditor.BufferImage->BufferType
941 );
942 if (EFI_ERROR (Status)) {
943 return Status;
944 }
945
946 MainTitleBarRefresh (
947 HMainEditor.BufferImage->BufferType == FileTypeFileBuffer ? HMainEditor.BufferImage->FileImage->FileName : HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer ? HMainEditor.BufferImage->DiskImage->Name : NULL,
948 HMainEditor.BufferImage->BufferType,
949 HMainEditor.BufferImage->FileImage->ReadOnly,
950 FALSE,
951 HMainEditor.ScreenSize.Column,
952 HMainEditor.ScreenSize.Row,
953 HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer ? HMainEditor.BufferImage->DiskImage->Offset : HMainEditor.BufferImage->BufferType == FileTypeMemBuffer ? HMainEditor.BufferImage->MemImage->Offset : 0,
954 HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer ? HMainEditor.BufferImage->DiskImage->Size : HMainEditor.BufferImage->BufferType == FileTypeMemBuffer ? HMainEditor.BufferImage->MemImage->Size : 0
955 );
956 Done = TRUE;
957 break;
958
959 case L'n':
960 case L'N':
961 //
962 // the file won't be saved
963 //
964 Done = TRUE;
965 break;
966
967 case L'c':
968 case L'C':
969 return EFI_SUCCESS;
970 }
971 }
972 }
973
974 //
975 // TO get the open file name
976 //
977 Status = InputBarSetPrompt (L"File Name to Open: ");
978 if (EFI_ERROR (Status)) {
979 HBufferImageRead (
980 HMainEditor.BufferImage->FileImage->FileName,
981 HMainEditor.BufferImage->DiskImage->Name,
982 HMainEditor.BufferImage->DiskImage->Offset,
983 HMainEditor.BufferImage->DiskImage->Size,
984 HMainEditor.BufferImage->MemImage->Offset,
985 HMainEditor.BufferImage->MemImage->Size,
986 BufferType,
987 TRUE
988 );
989 return Status;
990 }
991
992 Status = InputBarSetStringSize (100);
993 if (EFI_ERROR (Status)) {
994 Status = HBufferImageRead (
995 HMainEditor.BufferImage->FileImage->FileName,
996 HMainEditor.BufferImage->DiskImage->Name,
997 HMainEditor.BufferImage->DiskImage->Offset,
998 HMainEditor.BufferImage->DiskImage->Size,
999 HMainEditor.BufferImage->MemImage->Offset,
1000 HMainEditor.BufferImage->MemImage->Size,
1001 BufferType,
1002 TRUE
1003 );
1004 return Status;
1005 }
1006
1007 while (1) {
1008 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
1009
1010 //
1011 // ESC pressed
1012 //
1013 if (Status == EFI_NOT_READY) {
1014 Status = HBufferImageRead (
1015 HMainEditor.BufferImage->FileImage->FileName,
1016 HMainEditor.BufferImage->DiskImage->Name,
1017 HMainEditor.BufferImage->DiskImage->Offset,
1018 HMainEditor.BufferImage->DiskImage->Size,
1019 HMainEditor.BufferImage->MemImage->Offset,
1020 HMainEditor.BufferImage->MemImage->Size,
1021 BufferType,
1022 TRUE
1023 );
1024
1025 return Status;
1026 }
1027
1028 //
1029 // THE input string length should > 0
1030 //
1031 if (StrLen (InputBarGetString ()) > 0) {
1032 //
1033 // CHECK if filename's valid
1034 //
1035 if (!IsValidFileName (InputBarGetString ())) {
1036 HBufferImageRead (
1037 HMainEditor.BufferImage->FileImage->FileName,
1038 HMainEditor.BufferImage->DiskImage->Name,
1039 HMainEditor.BufferImage->DiskImage->Offset,
1040 HMainEditor.BufferImage->DiskImage->Size,
1041 HMainEditor.BufferImage->MemImage->Offset,
1042 HMainEditor.BufferImage->MemImage->Size,
1043 BufferType,
1044 TRUE
1045 );
1046
1047 StatusBarSetStatusString (L"Invalid File Name");
1048 return EFI_SUCCESS;
1049 }
1050
1051 break;
1052 }
1053 }
1054
1055 //
1056 // read from disk
1057 //
1058 Status = HBufferImageRead (
1059 InputBarGetString (),
1060 HMainEditor.BufferImage->DiskImage->Name,
1061 HMainEditor.BufferImage->DiskImage->Offset,
1062 HMainEditor.BufferImage->DiskImage->Size,
1063 HMainEditor.BufferImage->MemImage->Offset,
1064 HMainEditor.BufferImage->MemImage->Size,
1065 FileTypeFileBuffer,
1066 FALSE
1067 );
1068
1069 if (EFI_ERROR (Status)) {
1070 HBufferImageRead (
1071 HMainEditor.BufferImage->FileImage->FileName,
1072 HMainEditor.BufferImage->DiskImage->Name,
1073 HMainEditor.BufferImage->DiskImage->Offset,
1074 HMainEditor.BufferImage->DiskImage->Size,
1075 HMainEditor.BufferImage->MemImage->Offset,
1076 HMainEditor.BufferImage->MemImage->Size,
1077 BufferType,
1078 TRUE
1079 );
1080
1081 return EFI_LOAD_ERROR;
1082 }
1083
1084 return EFI_SUCCESS;
1085 }
1086
1087 /**
1088 Load a disk buffer editor.
1089
1090 @retval EFI_SUCCESS The operation was successful.
1091 @retval EFI_OUT_OF_RESOURCES A memory allocation occurred.
1092 @retval EFI_LOAD_ERROR A load error occurred.
1093 @retval EFI_NOT_FOUND The disk was not found.
1094 **/
1095 EFI_STATUS
1096 HMainCommandOpenDisk (
1097 VOID
1098 )
1099 {
1100 UINT64 Size;
1101 UINT64 Offset;
1102 CHAR16 *DeviceName;
1103 EFI_STATUS Status;
1104 BOOLEAN Done;
1105
1106 EDIT_FILE_TYPE BufferType;
1107
1108 //
1109 // variable initialization
1110 //
1111 Size = 0;
1112 Offset = 0;
1113 BufferType = HMainEditor.BufferImage->BufferType;
1114
1115 //
1116 // if current file is modified, so you need to choose
1117 // whether to save it first.
1118 //
1119 if (HMainEditor.BufferImage->Modified) {
1120 Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? ");
1121 if (EFI_ERROR (Status)) {
1122 return Status;
1123 }
1124
1125 //
1126 // the answer is just one character
1127 //
1128 Status = InputBarSetStringSize (1);
1129 if (EFI_ERROR (Status)) {
1130 return Status;
1131 }
1132
1133 //
1134 // loop for user's answer
1135 // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'
1136 //
1137 Done = FALSE;
1138 while (!Done) {
1139 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
1140
1141 //
1142 // ESC pressed
1143 //
1144 if (Status == EFI_NOT_READY) {
1145 return EFI_SUCCESS;
1146 }
1147
1148 switch (InputBarGetString ()[0]) {
1149 case L'y':
1150 case L'Y':
1151 //
1152 // want to save this buffer first
1153 //
1154 Status = HBufferImageSave (
1155 HMainEditor.BufferImage->FileImage->FileName,
1156 HMainEditor.BufferImage->DiskImage->Name,
1157 HMainEditor.BufferImage->DiskImage->Offset,
1158 HMainEditor.BufferImage->DiskImage->Size,
1159 HMainEditor.BufferImage->MemImage->Offset,
1160 HMainEditor.BufferImage->MemImage->Size,
1161 BufferType
1162 );
1163 if (EFI_ERROR (Status)) {
1164 return Status;
1165 }
1166
1167 MainTitleBarRefresh (
1168 HMainEditor.BufferImage->BufferType == FileTypeFileBuffer ? HMainEditor.BufferImage->FileImage->FileName : HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer ? HMainEditor.BufferImage->DiskImage->Name : NULL,
1169 HMainEditor.BufferImage->BufferType,
1170 HMainEditor.BufferImage->FileImage->ReadOnly,
1171 FALSE,
1172 HMainEditor.ScreenSize.Column,
1173 HMainEditor.ScreenSize.Row,
1174 HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer ? HMainEditor.BufferImage->DiskImage->Offset : HMainEditor.BufferImage->BufferType == FileTypeMemBuffer ? HMainEditor.BufferImage->MemImage->Offset : 0,
1175 HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer ? HMainEditor.BufferImage->DiskImage->Size : HMainEditor.BufferImage->BufferType == FileTypeMemBuffer ? HMainEditor.BufferImage->MemImage->Size : 0
1176 );
1177 Done = TRUE;
1178 break;
1179
1180 case L'n':
1181 case L'N':
1182 //
1183 // the file won't be saved
1184 //
1185 Done = TRUE;
1186 break;
1187
1188 case L'c':
1189 case L'C':
1190 return EFI_SUCCESS;
1191 }
1192 }
1193 }
1194
1195 //
1196 // get disk block device name
1197 //
1198 Status = InputBarSetPrompt (L"Block Device to Open: ");
1199 if (EFI_ERROR (Status)) {
1200 return Status;
1201 }
1202
1203 Status = InputBarSetStringSize (100);
1204 if (EFI_ERROR (Status)) {
1205 return Status;
1206 }
1207
1208 while (1) {
1209 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
1210
1211 //
1212 // ESC pressed
1213 //
1214 if (Status == EFI_NOT_READY) {
1215 return EFI_SUCCESS;
1216 }
1217
1218 //
1219 // THE input string length should > 0
1220 //
1221 if (StrLen (InputBarGetString ()) > 0) {
1222 break;
1223 }
1224 }
1225
1226 DeviceName = CatSPrint (NULL, L"%s", InputBarGetString ());
1227 if (DeviceName == NULL) {
1228 return EFI_OUT_OF_RESOURCES;
1229 }
1230
1231 //
1232 // get starting offset
1233 //
1234 Status = InputBarSetPrompt (L"First Block No.: ");
1235 if (EFI_ERROR (Status)) {
1236 return Status;
1237 }
1238
1239 Status = InputBarSetStringSize (16);
1240 if (EFI_ERROR (Status)) {
1241 return Status;
1242 }
1243
1244 while (1) {
1245 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
1246
1247 //
1248 // ESC pressed
1249 //
1250 if (Status == EFI_NOT_READY) {
1251 return EFI_SUCCESS;
1252 }
1253
1254 //
1255 // THE input string length should > 0
1256 //
1257 if (StrLen (InputBarGetString ()) > 0) {
1258 Status = ShellConvertStringToUint64 (InputBarGetString (), &Offset, TRUE, FALSE);
1259 if (EFI_ERROR (Status)) {
1260 continue;
1261 }
1262
1263 break;
1264 }
1265 }
1266
1267 //
1268 // get Number of Blocks:
1269 //
1270 Status = InputBarSetPrompt (L"Number of Blocks: ");
1271 if (EFI_ERROR (Status)) {
1272 return Status;
1273 }
1274
1275 Status = InputBarSetStringSize (8);
1276 if (EFI_ERROR (Status)) {
1277 return Status;
1278 }
1279
1280 while (1) {
1281 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
1282
1283 //
1284 // ESC pressed
1285 //
1286 if (Status == EFI_NOT_READY) {
1287 return EFI_SUCCESS;
1288 }
1289
1290 //
1291 // THE input string length should > 0
1292 //
1293 if (StrLen (InputBarGetString ()) > 0) {
1294 Status = ShellConvertStringToUint64 (InputBarGetString (), &Size, TRUE, FALSE);
1295 if (EFI_ERROR (Status)) {
1296 continue;
1297 }
1298
1299 if (Size == 0) {
1300 continue;
1301 }
1302
1303 break;
1304 }
1305 }
1306
1307 Status = HBufferImageRead (
1308 NULL,
1309 DeviceName,
1310 (UINTN)Offset,
1311 (UINTN)Size,
1312 0,
1313 0,
1314 FileTypeDiskBuffer,
1315 FALSE
1316 );
1317
1318 if (EFI_ERROR (Status)) {
1319 HBufferImageRead (
1320 HMainEditor.BufferImage->FileImage->FileName,
1321 HMainEditor.BufferImage->DiskImage->Name,
1322 HMainEditor.BufferImage->DiskImage->Offset,
1323 HMainEditor.BufferImage->DiskImage->Size,
1324 HMainEditor.BufferImage->MemImage->Offset,
1325 HMainEditor.BufferImage->MemImage->Size,
1326 BufferType,
1327 TRUE
1328 );
1329 return EFI_NOT_FOUND;
1330 }
1331
1332 return EFI_SUCCESS;
1333 }
1334
1335 /**
1336 Load memory content to editor
1337
1338 @retval EFI_SUCCESS The operation was successful.
1339 @retval EFI_OUT_OF_RESOURCES A memory allocation occurred.
1340 @retval EFI_LOAD_ERROR A load error occurred.
1341 @retval EFI_NOT_FOUND The disk was not found.
1342 **/
1343 EFI_STATUS
1344 HMainCommandOpenMemory (
1345 VOID
1346 )
1347 {
1348 UINT64 Size;
1349 UINT64 Offset;
1350 EFI_STATUS Status;
1351 BOOLEAN Done;
1352 EDIT_FILE_TYPE BufferType;
1353
1354 //
1355 // variable initialization
1356 //
1357 Size = 0;
1358 Offset = 0;
1359 BufferType = HMainEditor.BufferImage->BufferType;
1360
1361 //
1362 // if current buffer is modified, so you need to choose
1363 // whether to save it first.
1364 //
1365 if (HMainEditor.BufferImage->Modified) {
1366 Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? ");
1367 if (EFI_ERROR (Status)) {
1368 return Status;
1369 }
1370
1371 //
1372 // the answer is just one character
1373 //
1374 Status = InputBarSetStringSize (1);
1375 if (EFI_ERROR (Status)) {
1376 return Status;
1377 }
1378
1379 //
1380 // loop for user's answer
1381 // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'
1382 //
1383 Done = FALSE;
1384 while (!Done) {
1385 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
1386
1387 //
1388 // ESC pressed
1389 //
1390 if (Status == EFI_NOT_READY) {
1391 return EFI_SUCCESS;
1392 }
1393
1394 switch (InputBarGetString ()[0]) {
1395 case L'y':
1396 case L'Y':
1397 //
1398 // want to save this buffer first
1399 //
1400 Status = HBufferImageSave (
1401 HMainEditor.BufferImage->FileImage->FileName,
1402 HMainEditor.BufferImage->DiskImage->Name,
1403 HMainEditor.BufferImage->DiskImage->Offset,
1404 HMainEditor.BufferImage->DiskImage->Size,
1405 HMainEditor.BufferImage->MemImage->Offset,
1406 HMainEditor.BufferImage->MemImage->Size,
1407 BufferType
1408 );
1409 if (EFI_ERROR (Status)) {
1410 return Status;
1411 }
1412
1413 MainTitleBarRefresh (
1414 HMainEditor.BufferImage->BufferType == FileTypeFileBuffer ? HMainEditor.BufferImage->FileImage->FileName : HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer ? HMainEditor.BufferImage->DiskImage->Name : NULL,
1415 HMainEditor.BufferImage->BufferType,
1416 HMainEditor.BufferImage->FileImage->ReadOnly,
1417 FALSE,
1418 HMainEditor.ScreenSize.Column,
1419 HMainEditor.ScreenSize.Row,
1420 HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer ? HMainEditor.BufferImage->DiskImage->Offset : HMainEditor.BufferImage->BufferType == FileTypeMemBuffer ? HMainEditor.BufferImage->MemImage->Offset : 0,
1421 HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer ? HMainEditor.BufferImage->DiskImage->Size : HMainEditor.BufferImage->BufferType == FileTypeMemBuffer ? HMainEditor.BufferImage->MemImage->Size : 0
1422 );
1423 Done = TRUE;
1424 break;
1425
1426 case L'n':
1427 case L'N':
1428 //
1429 // the file won't be saved
1430 //
1431 Done = TRUE;
1432 break;
1433
1434 case L'c':
1435 case L'C':
1436 return EFI_SUCCESS;
1437 }
1438 }
1439 }
1440
1441 //
1442 // get starting offset
1443 //
1444 Status = InputBarSetPrompt (L"Starting Offset: ");
1445 if (EFI_ERROR (Status)) {
1446 return Status;
1447 }
1448
1449 Status = InputBarSetStringSize (8);
1450 if (EFI_ERROR (Status)) {
1451 return Status;
1452 }
1453
1454 while (1) {
1455 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
1456
1457 //
1458 // ESC pressed
1459 //
1460 if (Status == EFI_NOT_READY) {
1461 return EFI_SUCCESS;
1462 }
1463
1464 //
1465 // THE input string length should > 0
1466 //
1467 if (StrLen (InputBarGetString ()) > 0) {
1468 Status = ShellConvertStringToUint64 (InputBarGetString (), &Offset, TRUE, FALSE);
1469 if (EFI_ERROR (Status)) {
1470 continue;
1471 }
1472
1473 break;
1474 }
1475 }
1476
1477 //
1478 // get Number of Blocks:
1479 //
1480 Status = InputBarSetPrompt (L"Buffer Size: ");
1481 if (EFI_ERROR (Status)) {
1482 return Status;
1483 }
1484
1485 Status = InputBarSetStringSize (8);
1486 if (EFI_ERROR (Status)) {
1487 return Status;
1488 }
1489
1490 while (1) {
1491 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
1492
1493 //
1494 // ESC pressed
1495 //
1496 if (Status == EFI_NOT_READY) {
1497 return EFI_SUCCESS;
1498 }
1499
1500 //
1501 // THE input string length should > 0
1502 //
1503 if (StrLen (InputBarGetString ()) > 0) {
1504 Status = ShellConvertStringToUint64 (InputBarGetString (), &Size, TRUE, FALSE);
1505 if (EFI_ERROR (Status)) {
1506 continue;
1507 }
1508
1509 if (Size == 0) {
1510 continue;
1511 }
1512
1513 break;
1514 }
1515 }
1516
1517 if ((Offset + Size - 1) > 0xffffffff) {
1518 StatusBarSetStatusString (L"Invalid parameter");
1519 return EFI_LOAD_ERROR;
1520 }
1521
1522 Status = HBufferImageRead (
1523 NULL,
1524 NULL,
1525 0,
1526 0,
1527 (UINTN)Offset,
1528 (UINTN)Size,
1529 FileTypeMemBuffer,
1530 FALSE
1531 );
1532
1533 if (EFI_ERROR (Status)) {
1534 StatusBarSetStatusString (L"Read Device Error!");
1535 HBufferImageRead (
1536 HMainEditor.BufferImage->FileImage->FileName,
1537 HMainEditor.BufferImage->DiskImage->Name,
1538 HMainEditor.BufferImage->DiskImage->Offset,
1539 HMainEditor.BufferImage->DiskImage->Size,
1540 HMainEditor.BufferImage->MemImage->Offset,
1541 HMainEditor.BufferImage->MemImage->Size,
1542 BufferType,
1543 TRUE
1544 );
1545 return EFI_NOT_FOUND;
1546 }
1547
1548 return EFI_SUCCESS;
1549 }
1550
1551 MENU_ITEM_FUNCTION HexMainControlBasedMenuFunctions[] = {
1552 NULL,
1553 NULL, /* Ctrl - A */
1554 NULL, /* Ctrl - B */
1555 NULL, /* Ctrl - C */
1556 HMainCommandSelectEnd, /* Ctrl - D */
1557 HMainCommandDisplayHelp, /* Ctrl - E */
1558 NULL, /* Ctrl - F */
1559 HMainCommandGoToOffset, /* Ctrl - G */
1560 NULL, /* Ctrl - H */
1561 HMainCommandOpenDisk, /* Ctrl - I */
1562 NULL, /* Ctrl - J */
1563 NULL, /* Ctrl - K */
1564 NULL, /* Ctrl - L */
1565 HMainCommandOpenMemory, /* Ctrl - M */
1566 NULL, /* Ctrl - N */
1567 HMainCommandOpenFile, /* Ctrl - O */
1568 NULL, /* Ctrl - P */
1569 HMainCommandExit, /* Ctrl - Q */
1570 NULL, /* Ctrl - R */
1571 HMainCommandSaveBuffer, /* Ctrl - S */
1572 HMainCommandSelectStart, /* Ctrl - T */
1573 NULL, /* Ctrl - U */
1574 HMainCommandPaste, /* Ctrl - V */
1575 NULL, /* Ctrl - W */
1576 HMainCommandCut, /* Ctrl - X */
1577 NULL, /* Ctrl - Y */
1578 NULL, /* Ctrl - Z */
1579 };
1580
1581 CONST EDITOR_MENU_ITEM HexEditorMenuItems[] = {
1582 {
1583 STRING_TOKEN (STR_HEXEDIT_LIBMENUBAR_GO_TO_OFFSET),
1584 STRING_TOKEN (STR_EDIT_LIBMENUBAR_F1),
1585 HMainCommandGoToOffset
1586 },
1587 {
1588 STRING_TOKEN (STR_HEXEDIT_LIBMENUBAR_SAVE_BUFFER),
1589 STRING_TOKEN (STR_EDIT_LIBMENUBAR_F2),
1590 HMainCommandSaveBuffer
1591 },
1592 {
1593 STRING_TOKEN (STR_EDIT_LIBMENUBAR_EXIT),
1594 STRING_TOKEN (STR_EDIT_LIBMENUBAR_F3),
1595 HMainCommandExit
1596 },
1597
1598 {
1599 STRING_TOKEN (STR_HEXEDIT_LIBMENUBAR_SELECT_START),
1600 STRING_TOKEN (STR_EDIT_LIBMENUBAR_F4),
1601 HMainCommandSelectStart
1602 },
1603 {
1604 STRING_TOKEN (STR_HEXEDIT_LIBMENUBAR_SELECT_END),
1605 STRING_TOKEN (STR_EDIT_LIBMENUBAR_F5),
1606 HMainCommandSelectEnd
1607 },
1608 {
1609 STRING_TOKEN (STR_HEXEDIT_LIBMENUBAR_CUT),
1610 STRING_TOKEN (STR_EDIT_LIBMENUBAR_F6),
1611 HMainCommandCut
1612 },
1613 {
1614 STRING_TOKEN (STR_HEXEDIT_LIBMENUBAR_PASTE),
1615 STRING_TOKEN (STR_EDIT_LIBMENUBAR_F7),
1616 HMainCommandPaste
1617 },
1618
1619 {
1620 STRING_TOKEN (STR_HEXEDIT_LIBMENUBAR_OPEN_FILE),
1621 STRING_TOKEN (STR_EDIT_LIBMENUBAR_F8),
1622 HMainCommandOpenFile
1623 },
1624 {
1625 STRING_TOKEN (STR_HEXEDIT_LIBMENUBAR_OPEN_DISK),
1626 STRING_TOKEN (STR_EDIT_LIBMENUBAR_F9),
1627 HMainCommandOpenDisk
1628 },
1629 {
1630 STRING_TOKEN (STR_HEXEDIT_LIBMENUBAR_OPEN_MEMORY),
1631 STRING_TOKEN (STR_EDIT_LIBMENUBAR_F10),
1632 HMainCommandOpenMemory
1633 },
1634
1635 {
1636 0,
1637 0,
1638 NULL
1639 }
1640 };
1641
1642 /**
1643 Init function for MainEditor
1644
1645 @retval EFI_SUCCESS The operation was successful.
1646 @retval EFI_LOAD_ERROR A load error occurred.
1647 **/
1648 EFI_STATUS
1649 HMainEditorInit (
1650 VOID
1651 )
1652 {
1653 EFI_STATUS Status;
1654 EFI_HANDLE *HandleBuffer;
1655 UINTN HandleCount;
1656 UINTN Index;
1657
1658 //
1659 // basic initialization
1660 //
1661 CopyMem (&HMainEditor, &HMainEditorConst, sizeof (HMainEditor));
1662
1663 //
1664 // set screen attributes
1665 //
1666 HMainEditor.ColorAttributes.Colors.Foreground = gST->ConOut->Mode->Attribute & 0x000000ff;
1667
1668 HMainEditor.ColorAttributes.Colors.Background = (UINT8)(gST->ConOut->Mode->Attribute >> 4);
1669
1670 HOriginalColors = HMainEditor.ColorAttributes.Colors;
1671
1672 HOriginalMode = gST->ConOut->Mode->Mode;
1673
1674 //
1675 // query screen size
1676 //
1677 gST->ConOut->QueryMode (
1678 gST->ConOut,
1679 gST->ConOut->Mode->Mode,
1680 &(HMainEditor.ScreenSize.Column),
1681 &(HMainEditor.ScreenSize.Row)
1682 );
1683
1684 //
1685 // Find TextInEx in System Table ConsoleInHandle
1686 // Per UEFI Spec, TextInEx is required for a console capable platform.
1687 //
1688 Status = gBS->HandleProtocol (
1689 gST->ConsoleInHandle,
1690 &gEfiSimpleTextInputExProtocolGuid,
1691 (VOID **)&HMainEditor.TextInputEx
1692 );
1693 if (EFI_ERROR (Status)) {
1694 return Status;
1695 }
1696
1697 //
1698 // Find mouse in System Table ConsoleInHandle
1699 //
1700 Status = gBS->HandleProtocol (
1701 gST->ConsoleInHandle,
1702 &gEfiSimplePointerProtocolGuid,
1703 (VOID **)&HMainEditor.MouseInterface
1704 );
1705 if (EFI_ERROR (Status)) {
1706 //
1707 // If there is no Simple Pointer Protocol on System Table
1708 //
1709 HandleBuffer = NULL;
1710 HMainEditor.MouseInterface = NULL;
1711 Status = gBS->LocateHandleBuffer (
1712 ByProtocol,
1713 &gEfiSimplePointerProtocolGuid,
1714 NULL,
1715 &HandleCount,
1716 &HandleBuffer
1717 );
1718 if (!EFI_ERROR (Status) && (HandleCount > 0)) {
1719 //
1720 // Try to find the first available mouse device
1721 //
1722 for (Index = 0; Index < HandleCount; Index++) {
1723 Status = gBS->HandleProtocol (
1724 HandleBuffer[Index],
1725 &gEfiSimplePointerProtocolGuid,
1726 (VOID **)&HMainEditor.MouseInterface
1727 );
1728 if (!EFI_ERROR (Status)) {
1729 break;
1730 }
1731 }
1732 }
1733
1734 if (HandleBuffer != NULL) {
1735 FreePool (HandleBuffer);
1736 }
1737 }
1738
1739 if (!EFI_ERROR (Status) && (HMainEditor.MouseInterface != NULL)) {
1740 HMainEditor.MouseAccumulatorX = 0;
1741 HMainEditor.MouseAccumulatorY = 0;
1742 HMainEditor.MouseSupported = TRUE;
1743 }
1744
1745 //
1746 // below will call the five components' init function
1747 //
1748 Status = MainTitleBarInit (L"UEFI HEXEDIT");
1749 if (EFI_ERROR (Status)) {
1750 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_TITLE), gShellDebug1HiiHandle);
1751 return EFI_LOAD_ERROR;
1752 }
1753
1754 Status = ControlHotKeyInit (HexMainControlBasedMenuFunctions);
1755 if (EFI_ERROR (Status)) {
1756 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_MAINMENU), gShellDebug1HiiHandle);
1757 return EFI_LOAD_ERROR;
1758 }
1759
1760 Status = MenuBarInit (HexEditorMenuItems);
1761 if (EFI_ERROR (Status)) {
1762 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_MAINMENU), gShellDebug1HiiHandle);
1763 return EFI_LOAD_ERROR;
1764 }
1765
1766 Status = StatusBarInit ();
1767 if (EFI_ERROR (Status)) {
1768 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_STATUS), gShellDebug1HiiHandle);
1769 return EFI_LOAD_ERROR;
1770 }
1771
1772 InputBarInit (HMainEditor.TextInputEx);
1773
1774 Status = HBufferImageInit ();
1775 if (EFI_ERROR (Status)) {
1776 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_BUFFERIMAGE), gShellDebug1HiiHandle);
1777 return EFI_LOAD_ERROR;
1778 }
1779
1780 Status = HClipBoardInit ();
1781 if (EFI_ERROR (Status)) {
1782 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_CLIPBOARD), gShellDebug1HiiHandle);
1783 return EFI_LOAD_ERROR;
1784 }
1785
1786 //
1787 // clear whole screen and enable cursor
1788 //
1789 gST->ConOut->ClearScreen (gST->ConOut);
1790 gST->ConOut->EnableCursor (gST->ConOut, TRUE);
1791
1792 //
1793 // initialize EditorFirst and EditorExit
1794 //
1795 HEditorFirst = TRUE;
1796 HEditorExit = FALSE;
1797 HEditorMouseAction = FALSE;
1798
1799 return EFI_SUCCESS;
1800 }
1801
1802 /**
1803 Cleanup function for MainEditor.
1804
1805 @retval EFI_SUCCESS The operation was successful.
1806 @retval EFI_LOAD_ERROR A load error occurred.
1807 **/
1808 EFI_STATUS
1809 HMainEditorCleanup (
1810 VOID
1811 )
1812 {
1813 EFI_STATUS Status;
1814
1815 //
1816 // call the five components' cleanup function
1817 //
1818 MainTitleBarCleanup ();
1819
1820 MenuBarCleanup ();
1821
1822 StatusBarCleanup ();
1823
1824 InputBarCleanup ();
1825
1826 Status = HBufferImageCleanup ();
1827 if (EFI_ERROR (Status)) {
1828 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_BUFFERIMAGE_CLEAN), gShellDebug1HiiHandle);
1829 }
1830
1831 Status = HClipBoardCleanup ();
1832 if (EFI_ERROR (Status)) {
1833 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_CLIPBOARD_CLEAN), gShellDebug1HiiHandle);
1834 }
1835
1836 //
1837 // restore old mode
1838 //
1839 if (HOriginalMode != gST->ConOut->Mode->Mode) {
1840 gST->ConOut->SetMode (gST->ConOut, HOriginalMode);
1841 }
1842
1843 gST->ConOut->SetAttribute (
1844 gST->ConOut,
1845 EFI_TEXT_ATTR (HOriginalColors.Foreground, HOriginalColors.Background)
1846 );
1847 gST->ConOut->ClearScreen (gST->ConOut);
1848
1849 return EFI_SUCCESS;
1850 }
1851
1852 /**
1853 Refresh function for MainEditor.
1854
1855 @retval EFI_SUCCESS The operation was successful.
1856 **/
1857 EFI_STATUS
1858 HMainEditorRefresh (
1859 VOID
1860 )
1861 {
1862 BOOLEAN NameChange;
1863 BOOLEAN ReadChange;
1864
1865 NameChange = FALSE;
1866 ReadChange = FALSE;
1867
1868 if (HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer) {
1869 if ((HMainEditor.BufferImage->DiskImage != NULL) &&
1870 (HBufferImageBackupVar.DiskImage != NULL) &&
1871 ((HMainEditor.BufferImage->DiskImage->Offset != HBufferImageBackupVar.DiskImage->Offset) ||
1872 (HMainEditor.BufferImage->DiskImage->Size != HBufferImageBackupVar.DiskImage->Size)))
1873 {
1874 NameChange = TRUE;
1875 }
1876 } else if (HMainEditor.BufferImage->BufferType == FileTypeMemBuffer) {
1877 if ((HMainEditor.BufferImage->MemImage != NULL) &&
1878 (HBufferImageBackupVar.MemImage != NULL) &&
1879 ((HMainEditor.BufferImage->MemImage->Offset != HBufferImageBackupVar.MemImage->Offset) ||
1880 (HMainEditor.BufferImage->MemImage->Size != HBufferImageBackupVar.MemImage->Size)))
1881 {
1882 NameChange = TRUE;
1883 }
1884 } else if (HMainEditor.BufferImage->BufferType == FileTypeFileBuffer) {
1885 if ((HMainEditor.BufferImage->FileImage != NULL) &&
1886 (HMainEditor.BufferImage->FileImage->FileName != NULL) &&
1887 (HBufferImageBackupVar.FileImage != NULL) &&
1888 (HBufferImageBackupVar.FileImage->FileName != NULL) &&
1889 (StrCmp (HMainEditor.BufferImage->FileImage->FileName, HBufferImageBackupVar.FileImage->FileName) != 0))
1890 {
1891 NameChange = TRUE;
1892 }
1893 }
1894
1895 if ((HMainEditor.BufferImage->FileImage != NULL) &&
1896 (HBufferImageBackupVar.FileImage != NULL) &&
1897 (HMainEditor.BufferImage->FileImage->ReadOnly != HBufferImageBackupVar.FileImage->ReadOnly))
1898 {
1899 ReadChange = TRUE;
1900 }
1901
1902 //
1903 // to aVOID screen flicker
1904 // the stall value is from experience
1905 //
1906 gBS->Stall (50);
1907
1908 //
1909 // call the components refresh function
1910 //
1911 if ( HEditorFirst
1912 || NameChange
1913 || (HMainEditor.BufferImage->BufferType != HBufferImageBackupVar.BufferType)
1914 || (HBufferImageBackupVar.Modified != HMainEditor.BufferImage->Modified)
1915 || ReadChange )
1916 {
1917 MainTitleBarRefresh (
1918 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,
1919 HMainEditor.BufferImage->BufferType,
1920 (BOOLEAN)(HMainEditor.BufferImage->FileImage != NULL ? HMainEditor.BufferImage->FileImage->ReadOnly : FALSE),
1921 HMainEditor.BufferImage->Modified,
1922 HMainEditor.ScreenSize.Column,
1923 HMainEditor.ScreenSize.Row,
1924 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,
1925 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
1926 );
1927 HBufferImageRefresh ();
1928 }
1929
1930 if ( HEditorFirst
1931 || (HBufferImageBackupVar.DisplayPosition.Row != HMainEditor.BufferImage->DisplayPosition.Row)
1932 || (HBufferImageBackupVar.DisplayPosition.Column != HMainEditor.BufferImage->DisplayPosition.Column)
1933 || StatusBarGetRefresh ())
1934 {
1935 StatusBarRefresh (
1936 HEditorFirst,
1937 HMainEditor.ScreenSize.Row,
1938 HMainEditor.ScreenSize.Column,
1939 (UINTN)(-1),
1940 (UINTN)(-1),
1941 FALSE
1942 );
1943 HBufferImageRefresh ();
1944 }
1945
1946 if (HEditorFirst) {
1947 HBufferImageRefresh ();
1948 }
1949
1950 //
1951 // EditorFirst is now set to FALSE
1952 //
1953 HEditorFirst = FALSE;
1954
1955 return EFI_SUCCESS;
1956 }
1957
1958 /**
1959 Handle the mouse input.
1960
1961 @param[in] MouseState The current mouse state.
1962 @param[out] BeforeLeftButtonDown helps with selections.
1963
1964 @retval EFI_SUCCESS The operation was successful.
1965 @retval EFI_OUT_OF_RESOURCES A memory allocation occurred.
1966 @retval EFI_LOAD_ERROR A load error occurred.
1967 @retval EFI_NOT_FOUND The disk was not found.
1968 **/
1969 EFI_STATUS
1970 HMainEditorHandleMouseInput (
1971 IN EFI_SIMPLE_POINTER_STATE MouseState,
1972 OUT BOOLEAN *BeforeLeftButtonDown
1973 )
1974 {
1975 INT32 TextX;
1976 INT32 TextY;
1977 UINTN FRow;
1978 UINTN FCol;
1979 BOOLEAN HighBits;
1980 LIST_ENTRY *Link;
1981 HEFI_EDITOR_LINE *Line;
1982 UINTN Index;
1983 BOOLEAN Action;
1984
1985 Action = FALSE;
1986
1987 //
1988 // have mouse movement
1989 //
1990 if (MouseState.RelativeMovementX || MouseState.RelativeMovementY) {
1991 //
1992 // handle
1993 //
1994 TextX = HGetTextX (MouseState.RelativeMovementX);
1995 TextY = HGetTextY (MouseState.RelativeMovementY);
1996
1997 HBufferImageAdjustMousePosition (TextX, TextY);
1998
1999 Action = TRUE;
2000 }
2001
2002 if (MouseState.LeftButton) {
2003 HighBits = HBufferImageIsAtHighBits (
2004 HMainEditor.BufferImage->MousePosition.Column,
2005 &FCol
2006 );
2007
2008 //
2009 // not at an movable place
2010 //
2011 if (FCol == 0) {
2012 //
2013 // now just move mouse pointer to legal position
2014 //
2015 //
2016 // move mouse position to legal position
2017 //
2018 HMainEditor.BufferImage->MousePosition.Column -= 10;
2019 if (HMainEditor.BufferImage->MousePosition.Column > 24) {
2020 HMainEditor.BufferImage->MousePosition.Column--;
2021 FCol = HMainEditor.BufferImage->MousePosition.Column / 3 + 1 + 1;
2022 } else {
2023 if (HMainEditor.BufferImage->MousePosition.Column < 24) {
2024 FCol = HMainEditor.BufferImage->MousePosition.Column / 3 + 1 + 1;
2025 } else {
2026 //
2027 // == 24
2028 //
2029 FCol = 9;
2030 }
2031 }
2032
2033 HighBits = TRUE;
2034 }
2035
2036 FRow = HMainEditor.BufferImage->BufferPosition.Row +
2037 HMainEditor.BufferImage->MousePosition.Row -
2038 HMainEditor.BufferImage->DisplayPosition.Row;
2039
2040 if (HMainEditor.BufferImage->NumLines < FRow) {
2041 //
2042 // dragging
2043 //
2044 //
2045 // now just move mouse pointer to legal position
2046 //
2047 FRow = HMainEditor.BufferImage->NumLines;
2048 HighBits = TRUE;
2049 }
2050
2051 Link = HMainEditor.BufferImage->ListHead->ForwardLink;
2052 for (Index = 0; Index < FRow - 1; Index++) {
2053 Link = Link->ForwardLink;
2054 }
2055
2056 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
2057
2058 //
2059 // dragging
2060 //
2061 //
2062 // now just move mouse pointer to legal position
2063 //
2064 if (FCol > Line->Size) {
2065 if (*BeforeLeftButtonDown) {
2066 HighBits = FALSE;
2067
2068 if (Line->Size == 0) {
2069 if (FRow > 1) {
2070 FRow--;
2071 FCol = 16;
2072 } else {
2073 FRow = 1;
2074 FCol = 1;
2075 }
2076 } else {
2077 FCol = Line->Size;
2078 }
2079 } else {
2080 FCol = Line->Size + 1;
2081 HighBits = TRUE;
2082 }
2083 }
2084
2085 HBufferImageMovePosition (FRow, FCol, HighBits);
2086
2087 HMainEditor.BufferImage->MousePosition.Row = HMainEditor.BufferImage->DisplayPosition.Row;
2088
2089 HMainEditor.BufferImage->MousePosition.Column = HMainEditor.BufferImage->DisplayPosition.Column;
2090
2091 *BeforeLeftButtonDown = TRUE;
2092
2093 Action = TRUE;
2094 } else {
2095 //
2096 // else of if LButton
2097 //
2098 // release LButton
2099 //
2100 if (*BeforeLeftButtonDown) {
2101 Action = TRUE;
2102 }
2103
2104 //
2105 // mouse up
2106 //
2107 *BeforeLeftButtonDown = FALSE;
2108 }
2109
2110 if (Action) {
2111 return EFI_SUCCESS;
2112 }
2113
2114 return EFI_NOT_FOUND;
2115 }
2116
2117 /**
2118 Handle user key input. will route it to other components handle function.
2119
2120 @retval EFI_SUCCESS The operation was successful.
2121 @retval EFI_OUT_OF_RESOURCES A memory allocation occurred.
2122 @retval EFI_LOAD_ERROR A load error occurred.
2123 **/
2124 EFI_STATUS
2125 HMainEditorKeyInput (
2126 VOID
2127 )
2128 {
2129 EFI_KEY_DATA KeyData;
2130 EFI_STATUS Status;
2131 EFI_SIMPLE_POINTER_STATE MouseState;
2132 BOOLEAN NoShiftState;
2133 BOOLEAN LengthChange;
2134 UINTN Size;
2135 UINTN OldSize;
2136 BOOLEAN BeforeMouseIsDown;
2137 BOOLEAN MouseIsDown;
2138 BOOLEAN FirstDown;
2139 BOOLEAN MouseDrag;
2140 UINTN FRow;
2141 UINTN FCol;
2142 UINTN SelectStartBackup;
2143 UINTN SelectEndBackup;
2144
2145 //
2146 // variable initialization
2147 //
2148 OldSize = 0;
2149 FRow = 0;
2150 FCol = 0;
2151 LengthChange = FALSE;
2152
2153 MouseIsDown = FALSE;
2154 FirstDown = FALSE;
2155 MouseDrag = FALSE;
2156
2157 do {
2158 Status = EFI_SUCCESS;
2159
2160 HEditorMouseAction = FALSE;
2161
2162 //
2163 // backup some key elements, so that can aVOID some refresh work
2164 //
2165 HMainEditorBackup ();
2166
2167 //
2168 // wait for user key input
2169 //
2170 //
2171 // change priority of checking mouse/keyboard activity dynamically
2172 // so prevent starvation of keyboard.
2173 // if last time, mouse moves then this time check keyboard
2174 //
2175 if (HMainEditor.MouseSupported) {
2176 Status = HMainEditor.MouseInterface->GetState (
2177 HMainEditor.MouseInterface,
2178 &MouseState
2179 );
2180 if (!EFI_ERROR (Status)) {
2181 BeforeMouseIsDown = MouseIsDown;
2182
2183 Status = HMainEditorHandleMouseInput (MouseState, &MouseIsDown);
2184
2185 if (!EFI_ERROR (Status)) {
2186 if (!BeforeMouseIsDown) {
2187 //
2188 // mouse down
2189 //
2190 if (MouseIsDown) {
2191 FRow = HBufferImage.BufferPosition.Row;
2192 FCol = HBufferImage.BufferPosition.Column;
2193 SelectStartBackup = HMainEditor.SelectStart;
2194 SelectEndBackup = HMainEditor.SelectEnd;
2195
2196 FirstDown = TRUE;
2197 }
2198 } else {
2199 SelectStartBackup = HMainEditor.SelectStart;
2200 SelectEndBackup = HMainEditor.SelectEnd;
2201
2202 //
2203 // begin to drag
2204 //
2205 if (MouseIsDown) {
2206 if (FirstDown) {
2207 if (MouseState.RelativeMovementX || MouseState.RelativeMovementY) {
2208 HMainEditor.SelectStart = 0;
2209 HMainEditor.SelectEnd = 0;
2210 HMainEditor.SelectStart = (FRow - 1) * 0x10 + FCol;
2211
2212 MouseDrag = TRUE;
2213 FirstDown = FALSE;
2214 }
2215 } else {
2216 if ((
2217 (HBufferImage.BufferPosition.Row - 1) *
2218 0x10 +
2219 HBufferImage.BufferPosition.Column
2220 ) >= HMainEditor.SelectStart
2221 )
2222 {
2223 HMainEditor.SelectEnd = (HBufferImage.BufferPosition.Row - 1) *
2224 0x10 +
2225 HBufferImage.BufferPosition.Column;
2226 } else {
2227 HMainEditor.SelectEnd = 0;
2228 }
2229 }
2230
2231 //
2232 // end of if RelativeX/Y
2233 //
2234 } else {
2235 //
2236 // mouse is up
2237 //
2238 if (MouseDrag) {
2239 if (HBufferImageGetTotalSize () == 0) {
2240 HMainEditor.SelectStart = 0;
2241 HMainEditor.SelectEnd = 0;
2242 FirstDown = FALSE;
2243 MouseDrag = FALSE;
2244 }
2245
2246 if ((
2247 (HBufferImage.BufferPosition.Row - 1) *
2248 0x10 +
2249 HBufferImage.BufferPosition.Column
2250 ) >= HMainEditor.SelectStart
2251 )
2252 {
2253 HMainEditor.SelectEnd = (HBufferImage.BufferPosition.Row - 1) *
2254 0x10 +
2255 HBufferImage.BufferPosition.Column;
2256 } else {
2257 HMainEditor.SelectEnd = 0;
2258 }
2259
2260 if (HMainEditor.SelectEnd == 0) {
2261 HMainEditor.SelectStart = 0;
2262 }
2263 }
2264
2265 FirstDown = FALSE;
2266 MouseDrag = FALSE;
2267 }
2268
2269 if ((SelectStartBackup != HMainEditor.SelectStart) || (SelectEndBackup != HMainEditor.SelectEnd)) {
2270 if ((SelectStartBackup - 1) / 0x10 != (HMainEditor.SelectStart - 1) / 0x10) {
2271 HBufferImageNeedRefresh = TRUE;
2272 } else {
2273 if ((SelectEndBackup - 1) / 0x10 != (HMainEditor.SelectEnd - 1) / 0x10) {
2274 HBufferImageNeedRefresh = TRUE;
2275 } else {
2276 HBufferImageOnlyLineNeedRefresh = TRUE;
2277 }
2278 }
2279 }
2280 }
2281
2282 HEditorMouseAction = TRUE;
2283 HBufferImageMouseNeedRefresh = TRUE;
2284 } else if (Status == EFI_LOAD_ERROR) {
2285 StatusBarSetStatusString (L"Invalid Mouse Movement ");
2286 }
2287 }
2288 }
2289
2290 //
2291 // CheckEvent() returns Success when non-partial key is pressed.
2292 //
2293 Status = gBS->CheckEvent (HMainEditor.TextInputEx->WaitForKeyEx);
2294 if (!EFI_ERROR (Status)) {
2295 Status = HMainEditor.TextInputEx->ReadKeyStrokeEx (HMainEditor.TextInputEx, &KeyData);
2296 if (!EFI_ERROR (Status)) {
2297 //
2298 // dispatch to different components' key handling function
2299 // so not everywhere has to set this variable
2300 //
2301 HBufferImageMouseNeedRefresh = TRUE;
2302
2303 //
2304 // clear previous status string
2305 //
2306 StatusBarSetRefresh ();
2307 //
2308 // NoShiftState: TRUE when no shift key is pressed.
2309 //
2310 NoShiftState = ((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) || (KeyData.KeyState.KeyShiftState == EFI_SHIFT_STATE_VALID);
2311 //
2312 // dispatch to different components' key handling function
2313 //
2314 if (EFI_SUCCESS == MenuBarDispatchControlHotKey (&KeyData)) {
2315 Status = EFI_SUCCESS;
2316 } else if (NoShiftState && (KeyData.Key.ScanCode == SCAN_NULL)) {
2317 Status = HBufferImageHandleInput (&KeyData.Key);
2318 } else if (NoShiftState && ((KeyData.Key.ScanCode >= SCAN_UP) && (KeyData.Key.ScanCode <= SCAN_PAGE_DOWN))) {
2319 Status = HBufferImageHandleInput (&KeyData.Key);
2320 } else if (NoShiftState && ((KeyData.Key.ScanCode >= SCAN_F1) && (KeyData.Key.ScanCode <= SCAN_F12))) {
2321 Status = MenuBarDispatchFunctionKey (&KeyData.Key);
2322 } else {
2323 StatusBarSetStatusString (L"Unknown Command");
2324
2325 HBufferImageMouseNeedRefresh = FALSE;
2326 }
2327
2328 if ((Status != EFI_SUCCESS) && (Status != EFI_OUT_OF_RESOURCES)) {
2329 //
2330 // not already has some error status
2331 //
2332 if (StrCmp (L"", StatusBarGetString ()) == 0) {
2333 StatusBarSetStatusString (L"Disk Error. Try Again");
2334 }
2335 }
2336 }
2337
2338 //
2339 // decide if has to set length warning
2340 //
2341 if (HBufferImage.BufferType != HBufferImageBackupVar.BufferType) {
2342 LengthChange = FALSE;
2343 } else {
2344 //
2345 // still the old buffer
2346 //
2347 if (HBufferImage.BufferType != FileTypeFileBuffer) {
2348 Size = HBufferImageGetTotalSize ();
2349
2350 switch (HBufferImage.BufferType) {
2351 case FileTypeDiskBuffer:
2352 OldSize = HBufferImage.DiskImage->Size * HBufferImage.DiskImage->BlockSize;
2353 break;
2354
2355 case FileTypeMemBuffer:
2356 OldSize = HBufferImage.MemImage->Size;
2357 break;
2358
2359 default:
2360 OldSize = 0;
2361 break;
2362 }
2363
2364 if (!LengthChange) {
2365 if (OldSize != Size) {
2366 StatusBarSetStatusString (L"Disk/Mem Buffer Length should not be changed");
2367 }
2368 }
2369
2370 if (OldSize != Size) {
2371 LengthChange = TRUE;
2372 } else {
2373 LengthChange = FALSE;
2374 }
2375 }
2376 }
2377 }
2378
2379 //
2380 // after handling, refresh editor
2381 //
2382 HMainEditorRefresh ();
2383 } while (Status != EFI_OUT_OF_RESOURCES && !HEditorExit);
2384
2385 return Status;
2386 }
2387
2388 /**
2389 Backup function for MainEditor.
2390 **/
2391 VOID
2392 HMainEditorBackup (
2393 VOID
2394 )
2395 {
2396 HMainEditorBackupVar.SelectStart = HMainEditor.SelectStart;
2397 HMainEditorBackupVar.SelectEnd = HMainEditor.SelectEnd;
2398 HBufferImageBackup ();
2399 }