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