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