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