]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.c
add Edit and HexEdit commands.
[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 );
938 Done = TRUE;
939 break;
940
941 case L'n':
942 case L'N':
943 //
944 // the file won't be saved
945 //
946 Done = TRUE;
947 break;
948
949 case L'c':
950 case L'C':
951 return EFI_SUCCESS;
952 }
953 }
954 }
955 //
956 // TO get the open file name
957 //
958 Status = InputBarSetPrompt (L"File Name to Open: ");
959 if (EFI_ERROR (Status)) {
960 HBufferImageRead (
961 HMainEditor.BufferImage->FileImage->FileName,
962 HMainEditor.BufferImage->DiskImage->Name,
963 HMainEditor.BufferImage->DiskImage->Offset,
964 HMainEditor.BufferImage->DiskImage->Size,
965 HMainEditor.BufferImage->MemImage->Offset,
966 HMainEditor.BufferImage->MemImage->Size,
967 BufferType,
968 TRUE
969 );
970 return Status;
971 }
972
973 Status = InputBarSetStringSize (100);
974 if (EFI_ERROR (Status)) {
975 Status = HBufferImageRead (
976 HMainEditor.BufferImage->FileImage->FileName,
977 HMainEditor.BufferImage->DiskImage->Name,
978 HMainEditor.BufferImage->DiskImage->Offset,
979 HMainEditor.BufferImage->DiskImage->Size,
980 HMainEditor.BufferImage->MemImage->Offset,
981 HMainEditor.BufferImage->MemImage->Size,
982 BufferType,
983 TRUE
984 );
985 return Status;
986 }
987
988 while (1) {
989 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
990
991 //
992 // ESC pressed
993 //
994 if (Status == EFI_NOT_READY) {
995 Status = HBufferImageRead (
996 HMainEditor.BufferImage->FileImage->FileName,
997 HMainEditor.BufferImage->DiskImage->Name,
998 HMainEditor.BufferImage->DiskImage->Offset,
999 HMainEditor.BufferImage->DiskImage->Size,
1000 HMainEditor.BufferImage->MemImage->Offset,
1001 HMainEditor.BufferImage->MemImage->Size,
1002 BufferType,
1003 TRUE
1004 );
1005
1006 return Status;
1007 }
1008 //
1009 // THE input string length should > 0
1010 //
1011 if (StrLen (InputBarGetString()) > 0) {
1012 //
1013 // CHECK if filename's valid
1014 //
1015 if (!IsValidFileName (InputBarGetString())) {
1016 HBufferImageRead (
1017 HMainEditor.BufferImage->FileImage->FileName,
1018 HMainEditor.BufferImage->DiskImage->Name,
1019 HMainEditor.BufferImage->DiskImage->Offset,
1020 HMainEditor.BufferImage->DiskImage->Size,
1021 HMainEditor.BufferImage->MemImage->Offset,
1022 HMainEditor.BufferImage->MemImage->Size,
1023 BufferType,
1024 TRUE
1025 );
1026
1027 StatusBarSetStatusString (L"Invalid File Name");
1028 return EFI_SUCCESS;
1029 }
1030
1031 break;
1032 }
1033 }
1034 //
1035 // read from disk
1036 //
1037 Status = HBufferImageRead (
1038 InputBarGetString(),
1039 HMainEditor.BufferImage->DiskImage->Name,
1040 HMainEditor.BufferImage->DiskImage->Offset,
1041 HMainEditor.BufferImage->DiskImage->Size,
1042 HMainEditor.BufferImage->MemImage->Offset,
1043 HMainEditor.BufferImage->MemImage->Size,
1044 FileTypeFileBuffer,
1045 FALSE
1046 );
1047
1048 if (EFI_ERROR (Status)) {
1049 HBufferImageRead (
1050 HMainEditor.BufferImage->FileImage->FileName,
1051 HMainEditor.BufferImage->DiskImage->Name,
1052 HMainEditor.BufferImage->DiskImage->Offset,
1053 HMainEditor.BufferImage->DiskImage->Size,
1054 HMainEditor.BufferImage->MemImage->Offset,
1055 HMainEditor.BufferImage->MemImage->Size,
1056 BufferType,
1057 TRUE
1058 );
1059
1060 return EFI_LOAD_ERROR;
1061 }
1062
1063 return EFI_SUCCESS;
1064 }
1065
1066 EFI_STATUS
1067 HMainCommandOpenDisk (
1068 VOID
1069 )
1070 /*++
1071
1072 Routine Description:
1073
1074 Load a disk buffer editor
1075
1076 Arguments:
1077
1078 None
1079
1080 Returns:
1081
1082 EFI_SUCCESS
1083 EFI_LOAD_ERROR
1084 EFI_OUT_OF_RESOURCES
1085 EFI_NOT_FOUND
1086
1087 --*/
1088 {
1089 UINT64 Size;
1090 UINT64 Offset;
1091 CHAR16 *DeviceName;
1092 EFI_STATUS Status;
1093 BOOLEAN Done;
1094
1095 EDIT_FILE_TYPE BufferType;
1096
1097 //
1098 // variable initialization
1099 //
1100 Size = 0;
1101 Offset = 0;
1102 BufferType = HMainEditor.BufferImage->BufferType;
1103
1104 //
1105 // if current file is modified, so you need to choose
1106 // whether to save it first.
1107 //
1108 if (HMainEditor.BufferImage->Modified) {
1109
1110 Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? ");
1111 if (EFI_ERROR (Status)) {
1112 return Status;
1113 }
1114 //
1115 // the answer is just one character
1116 //
1117 Status = InputBarSetStringSize (1);
1118 if (EFI_ERROR (Status)) {
1119 return Status;
1120 }
1121 //
1122 // loop for user's answer
1123 // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'
1124 //
1125 Done = FALSE;
1126 while (!Done) {
1127 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
1128
1129 //
1130 // ESC pressed
1131 //
1132 if (Status == EFI_NOT_READY) {
1133 return EFI_SUCCESS;
1134 }
1135
1136 switch (InputBarGetString()[0]) {
1137 case L'y':
1138 case L'Y':
1139 //
1140 // want to save this buffer first
1141 //
1142 Status = HBufferImageSave (
1143 HMainEditor.BufferImage->FileImage->FileName,
1144 HMainEditor.BufferImage->DiskImage->Name,
1145 HMainEditor.BufferImage->DiskImage->Offset,
1146 HMainEditor.BufferImage->DiskImage->Size,
1147 HMainEditor.BufferImage->MemImage->Offset,
1148 HMainEditor.BufferImage->MemImage->Size,
1149 BufferType
1150 );
1151 if (EFI_ERROR (Status)) {
1152 return Status;
1153 }
1154
1155 MainTitleBarRefresh (
1156 HMainEditor.BufferImage->BufferType == FileTypeFileBuffer?HMainEditor.BufferImage->FileImage->FileName:HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Name:NULL,
1157 HMainEditor.BufferImage->BufferType,
1158 HMainEditor.BufferImage->FileImage->ReadOnly,
1159 FALSE,
1160 HMainEditor.ScreenSize.Column,
1161 HMainEditor.ScreenSize.Row
1162 );
1163 Done = TRUE;
1164 break;
1165
1166 case L'n':
1167 case L'N':
1168 //
1169 // the file won't be saved
1170 //
1171 Done = TRUE;
1172 break;
1173
1174 case L'c':
1175 case L'C':
1176 return EFI_SUCCESS;
1177 }
1178 }
1179 }
1180 //
1181 // get disk block device name
1182 //
1183 Status = InputBarSetPrompt (L"Block Device to Open: ");
1184 if (EFI_ERROR (Status)) {
1185 return Status;
1186 }
1187
1188 Status = InputBarSetStringSize (100);
1189 if (EFI_ERROR (Status)) {
1190 return Status;
1191 }
1192
1193 while (1) {
1194 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
1195
1196 //
1197 // ESC pressed
1198 //
1199 if (Status == EFI_NOT_READY) {
1200
1201 return EFI_SUCCESS;
1202 }
1203 //
1204 // THE input string length should > 0
1205 //
1206 if (StrLen (InputBarGetString()) > 0) {
1207 break;
1208 }
1209 }
1210
1211 DeviceName = CatSPrint(NULL, L"%s", InputBarGetString());
1212 if (DeviceName == NULL) {
1213 return EFI_OUT_OF_RESOURCES;
1214 }
1215 //
1216 // get starting offset
1217 //
1218 Status = InputBarSetPrompt (L"First Block No.: ");
1219 if (EFI_ERROR (Status)) {
1220 return Status;
1221 }
1222
1223 Status = InputBarSetStringSize (16);
1224 if (EFI_ERROR (Status)) {
1225 return Status;
1226 }
1227
1228 while (1) {
1229 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
1230
1231 //
1232 // ESC pressed
1233 //
1234 if (Status == EFI_NOT_READY) {
1235
1236 return EFI_SUCCESS;
1237 }
1238 //
1239 // THE input string length should > 0
1240 //
1241 if (StrLen (InputBarGetString()) > 0) {
1242 Status = ShellConvertStringToUint64 (InputBarGetString(), &Offset, TRUE, FALSE);
1243 if (EFI_ERROR (Status)) {
1244 continue;
1245 }
1246
1247 break;
1248 }
1249 }
1250 //
1251 // get Number of Blocks:
1252 //
1253 Status = InputBarSetPrompt (L"Number of Blocks: ");
1254 if (EFI_ERROR (Status)) {
1255 return Status;
1256 }
1257
1258 Status = InputBarSetStringSize (8);
1259 if (EFI_ERROR (Status)) {
1260 return Status;
1261 }
1262
1263 while (1) {
1264 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
1265
1266 //
1267 // ESC pressed
1268 //
1269 if (Status == EFI_NOT_READY) {
1270
1271 return EFI_SUCCESS;
1272 }
1273 //
1274 // THE input string length should > 0
1275 //
1276 if (StrLen (InputBarGetString()) > 0) {
1277 Status = ShellConvertStringToUint64 (InputBarGetString(), &Size, TRUE, FALSE);
1278 if (EFI_ERROR (Status)) {
1279 continue;
1280 }
1281
1282 if (Size == 0) {
1283 continue;
1284 }
1285
1286 break;
1287 }
1288 }
1289
1290 Status = HBufferImageRead (
1291 NULL,
1292 DeviceName,
1293 (UINTN)Offset,
1294 (UINTN)Size,
1295 0,
1296 0,
1297 FileTypeDiskBuffer,
1298 FALSE
1299 );
1300
1301 if (EFI_ERROR (Status)) {
1302
1303 HBufferImageRead (
1304 HMainEditor.BufferImage->FileImage->FileName,
1305 HMainEditor.BufferImage->DiskImage->Name,
1306 HMainEditor.BufferImage->DiskImage->Offset,
1307 HMainEditor.BufferImage->DiskImage->Size,
1308 HMainEditor.BufferImage->MemImage->Offset,
1309 HMainEditor.BufferImage->MemImage->Size,
1310 BufferType,
1311 TRUE
1312 );
1313 return EFI_NOT_FOUND;
1314 }
1315
1316 return EFI_SUCCESS;
1317 }
1318
1319 EFI_STATUS
1320 HMainCommandOpenMemory (
1321 VOID
1322 )
1323 /*++
1324
1325 Routine Description:
1326
1327 Load memory content to editor
1328
1329 Arguments:
1330
1331 None
1332
1333 Returns:
1334
1335 EFI_SUCCESS
1336 EFI_LOAD_ERROR
1337 EFI_OUT_OF_RESOURCES
1338 EFI_NOT_FOUND
1339
1340 --*/
1341 {
1342 UINT64 Size;
1343 UINT64 Offset;
1344 EFI_STATUS Status;
1345 BOOLEAN Done;
1346 EDIT_FILE_TYPE BufferType;
1347
1348 //
1349 // variable initialization
1350 //
1351 Size = 0;
1352 Offset = 0;
1353 BufferType = HMainEditor.BufferImage->BufferType;
1354
1355 //
1356 // if current buffer is modified, so you need to choose
1357 // whether to save it first.
1358 //
1359 if (HMainEditor.BufferImage->Modified) {
1360
1361 Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? ");
1362 if (EFI_ERROR (Status)) {
1363 return Status;
1364 }
1365 //
1366 // the answer is just one character
1367 //
1368 Status = InputBarSetStringSize (1);
1369 if (EFI_ERROR (Status)) {
1370 return Status;
1371 }
1372 //
1373 // loop for user's answer
1374 // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'
1375 //
1376 Done = FALSE;
1377 while (!Done) {
1378 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
1379
1380 //
1381 // ESC pressed
1382 //
1383 if (Status == EFI_NOT_READY) {
1384 return EFI_SUCCESS;
1385 }
1386
1387 switch (InputBarGetString()[0]) {
1388 case L'y':
1389 case L'Y':
1390 //
1391 // want to save this buffer first
1392 //
1393 Status = HBufferImageSave (
1394 HMainEditor.BufferImage->FileImage->FileName,
1395 HMainEditor.BufferImage->DiskImage->Name,
1396 HMainEditor.BufferImage->DiskImage->Offset,
1397 HMainEditor.BufferImage->DiskImage->Size,
1398 HMainEditor.BufferImage->MemImage->Offset,
1399 HMainEditor.BufferImage->MemImage->Size,
1400 BufferType
1401 );
1402 if (EFI_ERROR (Status)) {
1403 return Status;
1404 }
1405
1406 MainTitleBarRefresh (
1407 HMainEditor.BufferImage->BufferType == FileTypeFileBuffer?HMainEditor.BufferImage->FileImage->FileName:HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Name:NULL,
1408 HMainEditor.BufferImage->BufferType,
1409 HMainEditor.BufferImage->FileImage->ReadOnly,
1410 FALSE,
1411 HMainEditor.ScreenSize.Column,
1412 HMainEditor.ScreenSize.Row
1413 );
1414 Done = TRUE;
1415 break;
1416
1417 case L'n':
1418 case L'N':
1419 //
1420 // the file won't be saved
1421 //
1422 Done = TRUE;
1423 break;
1424
1425 case L'c':
1426 case L'C':
1427 return EFI_SUCCESS;
1428 }
1429 }
1430 }
1431 //
1432 // get starting offset
1433 //
1434 Status = InputBarSetPrompt (L"Starting Offset: ");
1435 if (EFI_ERROR (Status)) {
1436 return Status;
1437 }
1438
1439 Status = InputBarSetStringSize (8);
1440 if (EFI_ERROR (Status)) {
1441 return Status;
1442 }
1443
1444 while (1) {
1445 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
1446
1447 //
1448 // ESC pressed
1449 //
1450 if (Status == EFI_NOT_READY) {
1451
1452 return EFI_SUCCESS;
1453 }
1454 //
1455 // THE input string length should > 0
1456 //
1457 if (StrLen (InputBarGetString()) > 0) {
1458 Status = ShellConvertStringToUint64 (InputBarGetString(), &Offset, TRUE, FALSE);
1459 if (EFI_ERROR (Status)) {
1460 continue;
1461 }
1462
1463 break;
1464 }
1465 }
1466 //
1467 // get Number of Blocks:
1468 //
1469 Status = InputBarSetPrompt (L"Buffer Size: ");
1470 if (EFI_ERROR (Status)) {
1471 return Status;
1472 }
1473
1474 Status = InputBarSetStringSize (8);
1475 if (EFI_ERROR (Status)) {
1476 return Status;
1477 }
1478
1479 while (1) {
1480 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
1481
1482 //
1483 // ESC pressed
1484 //
1485 if (Status == EFI_NOT_READY) {
1486
1487 return EFI_SUCCESS;
1488 }
1489 //
1490 // THE input string length should > 0
1491 //
1492 if (StrLen (InputBarGetString()) > 0) {
1493 Status = ShellConvertStringToUint64 (InputBarGetString(), &Size, TRUE, FALSE);
1494 if (EFI_ERROR (Status)) {
1495 continue;
1496 }
1497
1498 if (Size == 0) {
1499 continue;
1500 }
1501
1502 break;
1503 }
1504 }
1505
1506 if ((Offset + Size - 1)> 0xffffffff) {
1507 StatusBarSetStatusString (L"Invalid parameter");
1508 return EFI_LOAD_ERROR;
1509 }
1510
1511 Status = HBufferImageRead (
1512 NULL,
1513 NULL,
1514 0,
1515 0,
1516 (UINTN)Offset,
1517 (UINTN)Size,
1518 FileTypeMemBuffer,
1519 FALSE
1520 );
1521
1522 if (EFI_ERROR (Status)) {
1523 StatusBarSetStatusString (L"Read Device Error!");
1524 HBufferImageRead (
1525 HMainEditor.BufferImage->FileImage->FileName,
1526 HMainEditor.BufferImage->DiskImage->Name,
1527 HMainEditor.BufferImage->DiskImage->Offset,
1528 HMainEditor.BufferImage->DiskImage->Size,
1529 HMainEditor.BufferImage->MemImage->Offset,
1530 HMainEditor.BufferImage->MemImage->Size,
1531 BufferType,
1532 TRUE
1533 );
1534 return EFI_NOT_FOUND;
1535 }
1536 return EFI_SUCCESS;
1537
1538 }
1539
1540 CONST EDITOR_MENU_ITEM HexEditorMenuItems[] = {
1541 {
1542 STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_GO_TO_OFFSET),
1543 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F1),
1544 HMainCommandGoToOffset
1545 },
1546 {
1547 STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_SAVE_BUFFER),
1548 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F2),
1549 HMainCommandSaveBuffer
1550 },
1551 {
1552 STRING_TOKEN(STR_EDIT_LIBMENUBAR_EXIT),
1553 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F3),
1554 HMainCommandExit
1555 },
1556
1557 {
1558 STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_SELECT_START),
1559 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F4),
1560 HMainCommandSelectStart
1561 },
1562 {
1563 STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_SELECT_END),
1564 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F5),
1565 HMainCommandSelectEnd
1566 },
1567 {
1568 STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_CUT),
1569 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F6),
1570 HMainCommandCut
1571 },
1572 {
1573 STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_PASTE),
1574 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F7),
1575 HMainCommandPaste
1576 },
1577
1578 {
1579 STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_OPEN_FILE),
1580 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F8),
1581 HMainCommandOpenFile
1582 },
1583 {
1584 STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_OPEN_DISK),
1585 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F9),
1586 HMainCommandOpenDisk
1587 },
1588 {
1589 STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_OPEN_MEMORY),
1590 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F10),
1591 HMainCommandOpenMemory
1592 },
1593
1594 {
1595 0,
1596 0,
1597 NULL
1598 }
1599 };
1600
1601
1602 EFI_STATUS
1603 HMainEditorInit (
1604 VOID
1605 )
1606 /*++
1607
1608 Routine Description:
1609
1610 Init function for MainEditor
1611
1612 Arguments:
1613
1614 None
1615
1616 Returns:
1617
1618 EFI_SUCCESS
1619 EFI_LOAD_ERROR
1620
1621 --*/
1622 {
1623 EFI_STATUS Status;
1624 EFI_HANDLE *HandleBuffer;
1625 UINTN HandleCount;
1626 UINTN Index;
1627
1628 //
1629 // basic initialization
1630 //
1631 CopyMem (&HMainEditor, &HMainEditorConst, sizeof (HMainEditor));
1632
1633 //
1634 // set screen attributes
1635 //
1636 HMainEditor.ColorAttributes.Colors.Foreground = gST->ConOut->Mode->Attribute & 0x000000ff;
1637
1638 HMainEditor.ColorAttributes.Colors.Background = (UINT8) (gST->ConOut->Mode->Attribute >> 4);
1639
1640 HOriginalColors = HMainEditor.ColorAttributes.Colors;
1641
1642 HOriginalMode = gST->ConOut->Mode->Mode;
1643
1644 //
1645 // query screen size
1646 //
1647 gST->ConOut->QueryMode (
1648 gST->ConOut,
1649 gST->ConOut->Mode->Mode,
1650 &(HMainEditor.ScreenSize.Column),
1651 &(HMainEditor.ScreenSize.Row)
1652 );
1653
1654 //
1655 // Find mouse in System Table ConsoleInHandle
1656 //
1657 Status = gBS->HandleProtocol (
1658 gST->ConIn,
1659 &gEfiSimplePointerProtocolGuid,
1660 (VOID**)&HMainEditor.MouseInterface
1661 );
1662 if (EFI_ERROR (Status)) {
1663 //
1664 // If there is no Simple Pointer Protocol on System Table
1665 //
1666 HandleBuffer = NULL;
1667 HMainEditor.MouseInterface = NULL;
1668 Status = gBS->LocateHandleBuffer (
1669 ByProtocol,
1670 &gEfiSimplePointerProtocolGuid,
1671 NULL,
1672 &HandleCount,
1673 &HandleBuffer
1674 );
1675 if (!EFI_ERROR (Status) && HandleCount > 0) {
1676 //
1677 // Try to find the first available mouse device
1678 //
1679 for (Index = 0; Index < HandleCount; Index++) {
1680 Status = gBS->HandleProtocol (
1681 HandleBuffer[Index],
1682 &gEfiSimplePointerProtocolGuid,
1683 (VOID**)&HMainEditor.MouseInterface
1684 );
1685 if (!EFI_ERROR (Status)) {
1686 break;
1687 }
1688 }
1689 }
1690 if (HandleBuffer != NULL) {
1691 FreePool (HandleBuffer);
1692 }
1693 }
1694
1695 if (!EFI_ERROR (Status) && HMainEditor.MouseInterface != NULL) {
1696 HMainEditor.MouseAccumulatorX = 0;
1697 HMainEditor.MouseAccumulatorY = 0;
1698 HMainEditor.MouseSupported = TRUE;
1699 }
1700
1701 //
1702 // below will call the five components' init function
1703 //
1704 Status = MainTitleBarInit (NULL);
1705 if (EFI_ERROR (Status)) {
1706 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_TITLE), gShellDebug1HiiHandle);
1707 return EFI_LOAD_ERROR;
1708 }
1709
1710 Status = MenuBarInit (HexEditorMenuItems);
1711 if (EFI_ERROR (Status)) {
1712 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_MAINMENU), gShellDebug1HiiHandle);
1713 return EFI_LOAD_ERROR;
1714 }
1715
1716 Status = StatusBarInit ();
1717 if (EFI_ERROR (Status)) {
1718 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_STATUS), gShellDebug1HiiHandle);
1719 return EFI_LOAD_ERROR;
1720 }
1721
1722 InputBarInit ();
1723
1724 Status = HBufferImageInit ();
1725 if (EFI_ERROR (Status)) {
1726 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_BUFFERIMAGE), gShellDebug1HiiHandle);
1727 return EFI_LOAD_ERROR;
1728 }
1729
1730 Status = HClipBoardInit ();
1731 if (EFI_ERROR (Status)) {
1732 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_CLIPBOARD), gShellDebug1HiiHandle);
1733 return EFI_LOAD_ERROR;
1734 }
1735 //
1736 // clear whole screen and enable cursor
1737 //
1738 gST->ConOut->ClearScreen (gST->ConOut);
1739 gST->ConOut->EnableCursor (gST->ConOut, TRUE);
1740
1741 //
1742 // initialize EditorFirst and EditorExit
1743 //
1744 HEditorFirst = TRUE;
1745 HEditorExit = FALSE;
1746 HEditorMouseAction = FALSE;
1747
1748 return EFI_SUCCESS;
1749 }
1750
1751 EFI_STATUS
1752 HMainEditorCleanup (
1753 VOID
1754 )
1755 /*++
1756
1757 Routine Description:
1758
1759 cleanup function for MainEditor
1760
1761 Arguments:
1762
1763 None
1764
1765 Returns:
1766
1767 EFI_SUCCESS
1768 EFI_LOAD_ERROR
1769
1770 --*/
1771 {
1772 EFI_STATUS Status;
1773
1774 //
1775 // call the five components' cleanup function
1776 //
1777 MainTitleBarCleanup ();
1778
1779 MenuBarCleanup ();
1780
1781 StatusBarCleanup ();
1782
1783 InputBarCleanup ();
1784
1785 Status = HBufferImageCleanup ();
1786 if (EFI_ERROR (Status)) {
1787 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_BUFFERIMAGE_CLEAN), gShellDebug1HiiHandle);
1788 }
1789
1790 Status = HClipBoardCleanup ();
1791 if (EFI_ERROR (Status)) {
1792 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_CLIPBOARD_CLEAN), gShellDebug1HiiHandle);
1793 }
1794 //
1795 // restore old mode
1796 //
1797 if (HOriginalMode != gST->ConOut->Mode->Mode) {
1798 gST->ConOut->SetMode (gST->ConOut, HOriginalMode);
1799 }
1800
1801 gST->ConOut->SetAttribute (
1802 gST->ConOut,
1803 EFI_TEXT_ATTR (HOriginalColors.Foreground, HOriginalColors.Background)
1804 );
1805 gST->ConOut->ClearScreen (gST->ConOut);
1806
1807 return EFI_SUCCESS;
1808 }
1809
1810 EFI_STATUS
1811 HMainEditorRefresh (
1812 VOID
1813 )
1814 /*++
1815
1816 Routine Description:
1817
1818 Refresh function for MainEditor
1819
1820 Arguments:
1821
1822 None
1823
1824 Returns:
1825
1826 EFI_SUCCESS
1827
1828 --*/
1829 {
1830 //
1831 // to aVOID screen flicker
1832 // the stall value is from experience
1833 //
1834 gBS->Stall (50);
1835
1836 //
1837 // call the four components refresh function
1838 //
1839 MainTitleBarRefresh (
1840 HMainEditor.BufferImage->BufferType == FileTypeFileBuffer?HMainEditor.BufferImage->FileImage->FileName:HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Name:NULL,
1841 HMainEditor.BufferImage->BufferType,
1842 HMainEditor.BufferImage->FileImage->ReadOnly,
1843 HMainEditor.BufferImage->Modified,
1844 HMainEditor.ScreenSize.Column,
1845 HMainEditor.ScreenSize.Row
1846 );
1847 HBufferImageRefresh ();
1848 StatusBarRefresh (
1849 HEditorFirst,
1850 HMainEditor.ScreenSize.Row,
1851 HMainEditor.ScreenSize.Column,
1852 0,
1853 0,
1854 TRUE
1855 );
1856 MenuBarRefresh (
1857 HMainEditor.ScreenSize.Row,
1858 HMainEditor.ScreenSize.Column);
1859
1860 //
1861 // EditorFirst is now set to FALSE
1862 //
1863 HEditorFirst = FALSE;
1864
1865 return EFI_SUCCESS;
1866 }
1867
1868 STATIC
1869 EFI_STATUS
1870 HMainEditorHandleMouseInput (
1871 IN EFI_SIMPLE_POINTER_STATE MouseState,
1872 OUT BOOLEAN *BeforeLeftButtonDown
1873 )
1874 {
1875
1876 INT32 TextX;
1877 INT32 TextY;
1878 UINTN FRow;
1879 UINTN FCol;
1880 BOOLEAN HighBits;
1881 LIST_ENTRY *Link;
1882 HEFI_EDITOR_LINE *Line;
1883 UINTN Index;
1884 BOOLEAN Action;
1885
1886 Action = FALSE;
1887
1888 //
1889 // have mouse movement
1890 //
1891 if (MouseState.RelativeMovementX || MouseState.RelativeMovementY) {
1892 //
1893 // handle
1894 //
1895 TextX = HGetTextX (MouseState.RelativeMovementX);
1896 TextY = HGetTextY (MouseState.RelativeMovementY);
1897
1898 HBufferImageAdjustMousePosition (TextX, TextY);
1899
1900 Action = TRUE;
1901
1902 }
1903
1904 if (MouseState.LeftButton) {
1905 HighBits = HBufferImageIsAtHighBits (
1906 HMainEditor.BufferImage->MousePosition.Column,
1907 &FCol
1908 );
1909
1910 //
1911 // not at an movable place
1912 //
1913 if (FCol == 0) {
1914 //
1915 // now just move mouse pointer to legal position
1916 //
1917 //
1918 // move mouse position to legal position
1919 //
1920 HMainEditor.BufferImage->MousePosition.Column -= 10;
1921 if (HMainEditor.BufferImage->MousePosition.Column > 24) {
1922 HMainEditor.BufferImage->MousePosition.Column--;
1923 FCol = HMainEditor.BufferImage->MousePosition.Column / 3 + 1 + 1;
1924 } else {
1925 if (HMainEditor.BufferImage->MousePosition.Column < 24) {
1926 FCol = HMainEditor.BufferImage->MousePosition.Column / 3 + 1 + 1;
1927 } else {
1928 //
1929 // == 24
1930 //
1931 FCol = 9;
1932 }
1933 }
1934
1935 HighBits = TRUE;
1936
1937 }
1938
1939 FRow = HMainEditor.BufferImage->BufferPosition.Row +
1940 HMainEditor.BufferImage->MousePosition.Row -
1941 HMainEditor.BufferImage->DisplayPosition.Row;
1942
1943 if (HMainEditor.BufferImage->NumLines < FRow) {
1944 //
1945 // dragging
1946 //
1947 //
1948 // now just move mouse pointer to legal position
1949 //
1950 FRow = HMainEditor.BufferImage->NumLines;
1951 HighBits = TRUE;
1952 }
1953
1954 Link = HMainEditor.BufferImage->ListHead->ForwardLink;
1955 for (Index = 0; Index < FRow - 1; Index++) {
1956 Link = Link->ForwardLink;
1957 }
1958
1959 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
1960
1961 //
1962 // dragging
1963 //
1964 //
1965 // now just move mouse pointer to legal position
1966 //
1967 if (FCol > Line->Size) {
1968 if (*BeforeLeftButtonDown) {
1969 HighBits = FALSE;
1970
1971 if (Line->Size == 0) {
1972 if (FRow > 1) {
1973 FRow--;
1974 FCol = 16;
1975 } else {
1976 FRow = 1;
1977 FCol = 1;
1978 }
1979
1980 } else {
1981 FCol = Line->Size;
1982 }
1983 } else {
1984 FCol = Line->Size + 1;
1985 HighBits = TRUE;
1986 }
1987 }
1988
1989 HBufferImageMovePosition (FRow, FCol, HighBits);
1990
1991 HMainEditor.BufferImage->MousePosition.Row = HMainEditor.BufferImage->DisplayPosition.Row;
1992
1993 HMainEditor.BufferImage->MousePosition.Column = HMainEditor.BufferImage->DisplayPosition.Column;
1994
1995 *BeforeLeftButtonDown = TRUE;
1996
1997 Action = TRUE;
1998 } else {
1999 //
2000 // else of if LButton
2001 //
2002 // release LButton
2003 //
2004 if (*BeforeLeftButtonDown == TRUE) {
2005 Action = TRUE;
2006 }
2007 //
2008 // mouse up
2009 //
2010 *BeforeLeftButtonDown = FALSE;
2011 }
2012
2013 if (Action) {
2014 return EFI_SUCCESS;
2015 }
2016
2017 return EFI_NOT_FOUND;
2018 }
2019
2020 EFI_STATUS
2021 HMainEditorKeyInput (
2022 VOID
2023 )
2024 /*++
2025
2026 Routine Description:
2027
2028 Handle user key input. will route it to other components handle function
2029
2030 Arguments:
2031
2032 None
2033
2034 Returns:
2035
2036 EFI_SUCCESS
2037 EFI_LOAD_ERROR
2038 EFI_OUT_OF_RESOURCES
2039
2040 --*/
2041 {
2042 EFI_INPUT_KEY Key;
2043 EFI_STATUS Status;
2044 EFI_SIMPLE_POINTER_STATE MouseState;
2045 BOOLEAN LengthChange;
2046 UINTN Size;
2047 UINTN OldSize;
2048 BOOLEAN BeforeMouseIsDown;
2049 BOOLEAN MouseIsDown;
2050 BOOLEAN FirstDown;
2051 BOOLEAN MouseDrag;
2052 UINTN FRow;
2053 UINTN FCol;
2054 UINTN SelectStartBackup;
2055 UINTN SelectEndBackup;
2056
2057 //
2058 // variable initialization
2059 //
2060 OldSize = 0;
2061 FRow = 0;
2062 FCol = 0;
2063 LengthChange = FALSE;
2064
2065 MouseIsDown = FALSE;
2066 FirstDown = FALSE;
2067 MouseDrag = FALSE;
2068
2069 do {
2070
2071 Status = EFI_SUCCESS;
2072
2073 HEditorMouseAction = FALSE;
2074
2075 //
2076 // backup some key elements, so that can aVOID some refresh work
2077 //
2078 HMainEditorBackup ();
2079
2080 //
2081 // wait for user key input
2082 //
2083 //
2084 // change priority of checking mouse/keyboard activity dynamically
2085 // so prevent starvation of keyboard.
2086 // if last time, mouse moves then this time check keyboard
2087 //
2088 if (HMainEditor.MouseSupported) {
2089 Status = HMainEditor.MouseInterface->GetState (
2090 HMainEditor.MouseInterface,
2091 &MouseState
2092 );
2093 if (!EFI_ERROR (Status)) {
2094
2095 BeforeMouseIsDown = MouseIsDown;
2096
2097 Status = HMainEditorHandleMouseInput (MouseState, &MouseIsDown);
2098
2099 if (!EFI_ERROR (Status)) {
2100 if (BeforeMouseIsDown == FALSE) {
2101 //
2102 // mouse down
2103 //
2104 if (MouseIsDown == TRUE) {
2105 FRow = HBufferImage.BufferPosition.Row;
2106 FCol = HBufferImage.BufferPosition.Column;
2107 SelectStartBackup = HMainEditor.SelectStart;
2108 SelectEndBackup = HMainEditor.SelectEnd;
2109
2110 FirstDown = TRUE;
2111 }
2112 } else {
2113
2114 SelectStartBackup = HMainEditor.SelectStart;
2115 SelectEndBackup = HMainEditor.SelectEnd;
2116
2117 //
2118 // begin to drag
2119 //
2120 if (MouseIsDown == TRUE) {
2121 if (FirstDown == TRUE) {
2122 if (MouseState.RelativeMovementX || MouseState.RelativeMovementY) {
2123 HMainEditor.SelectStart = 0;
2124 HMainEditor.SelectEnd = 0;
2125 HMainEditor.SelectStart = (FRow - 1) * 0x10 + FCol;
2126
2127 MouseDrag = TRUE;
2128 FirstDown = FALSE;
2129 }
2130 } else {
2131 if ((
2132 (HBufferImage.BufferPosition.Row - 1) *
2133 0x10 +
2134 HBufferImage.BufferPosition.Column
2135 ) >= HMainEditor.SelectStart
2136 ) {
2137 HMainEditor.SelectEnd = (HBufferImage.BufferPosition.Row - 1) *
2138 0x10 +
2139 HBufferImage.BufferPosition.Column;
2140 } else {
2141 HMainEditor.SelectEnd = 0;
2142 }
2143 }
2144 //
2145 // end of if RelativeX/Y
2146 //
2147 } else {
2148 //
2149 // mouse is up
2150 //
2151 if (MouseDrag) {
2152 if (HBufferImageGetTotalSize () == 0) {
2153 HMainEditor.SelectStart = 0;
2154 HMainEditor.SelectEnd = 0;
2155 FirstDown = FALSE;
2156 MouseDrag = FALSE;
2157 }
2158
2159 if ((
2160 (HBufferImage.BufferPosition.Row - 1) *
2161 0x10 +
2162 HBufferImage.BufferPosition.Column
2163 ) >= HMainEditor.SelectStart
2164 ) {
2165 HMainEditor.SelectEnd = (HBufferImage.BufferPosition.Row - 1) *
2166 0x10 +
2167 HBufferImage.BufferPosition.Column;
2168 } else {
2169 HMainEditor.SelectEnd = 0;
2170 }
2171
2172 if (HMainEditor.SelectEnd == 0) {
2173 HMainEditor.SelectStart = 0;
2174 }
2175 }
2176
2177 FirstDown = FALSE;
2178 MouseDrag = FALSE;
2179 }
2180
2181 if (SelectStartBackup != HMainEditor.SelectStart || SelectEndBackup != HMainEditor.SelectEnd) {
2182 if ((SelectStartBackup - 1) / 0x10 != (HMainEditor.SelectStart - 1) / 0x10) {
2183 HBufferImageNeedRefresh = TRUE;
2184 } else {
2185 if ((SelectEndBackup - 1) / 0x10 != (HMainEditor.SelectEnd - 1) / 0x10) {
2186 HBufferImageNeedRefresh = TRUE;
2187 } else {
2188 HBufferImageOnlyLineNeedRefresh = TRUE;
2189 }
2190 }
2191 }
2192 }
2193
2194 HEditorMouseAction = TRUE;
2195 HBufferImageMouseNeedRefresh = TRUE;
2196
2197 } else if (Status == EFI_LOAD_ERROR) {
2198 StatusBarSetStatusString (L"Invalid Mouse Movement ");
2199 }
2200 }
2201 }
2202
2203 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
2204 if (!EFI_ERROR (Status)) {
2205 //
2206 // dispatch to different components' key handling function
2207 // so not everywhere has to set this variable
2208 //
2209 HBufferImageMouseNeedRefresh = TRUE;
2210
2211 //
2212 // clear previous status string
2213 //
2214 StatusBarSetRefresh();
2215
2216 if (Key.ScanCode == SCAN_NULL) {
2217 Status = HBufferImageHandleInput (&Key);
2218 } else if (((Key.ScanCode >= SCAN_UP) && (Key.ScanCode <= SCAN_PAGE_DOWN))) {
2219 Status = HBufferImageHandleInput (&Key);
2220 } else if (((Key.ScanCode >= SCAN_F1) && Key.ScanCode <= (SCAN_F12))) {
2221 Status = MenuBarDispatchFunctionKey (&Key);
2222 } else {
2223 StatusBarSetStatusString (L"Unknown Command");
2224
2225 HBufferImageMouseNeedRefresh = FALSE;
2226 }
2227
2228 if (Status != EFI_SUCCESS && Status != EFI_OUT_OF_RESOURCES) {
2229 //
2230 // not already has some error status
2231 //
2232 if (StrCmp (L"", StatusBarGetString()) == 0) {
2233 StatusBarSetStatusString (L"Disk Error. Try Again");
2234 }
2235 }
2236 }
2237 //
2238 // decide if has to set length warning
2239 //
2240 if (HBufferImage.BufferType != HBufferImageBackupVar.BufferType) {
2241 LengthChange = FALSE;
2242 } else {
2243 //
2244 // still the old buffer
2245 //
2246 if (HBufferImage.BufferType != FileTypeFileBuffer) {
2247 Size = HBufferImageGetTotalSize ();
2248
2249 switch (HBufferImage.BufferType) {
2250 case FileTypeDiskBuffer:
2251 OldSize = HBufferImage.DiskImage->Size * HBufferImage.DiskImage->BlockSize;
2252 break;
2253
2254 case FileTypeMemBuffer:
2255 OldSize = HBufferImage.MemImage->Size;
2256 break;
2257 }
2258
2259 if (LengthChange == FALSE) {
2260 if (OldSize != Size) {
2261 StatusBarSetStatusString (L"Disk/Mem Buffer Length should not be changed");
2262 }
2263 }
2264
2265 if (OldSize != Size) {
2266 LengthChange = TRUE;
2267 } else {
2268 LengthChange = FALSE;
2269 }
2270 }
2271 }
2272 //
2273 // after handling, refresh editor
2274 //
2275 HMainEditorRefresh ();
2276
2277 } while (Status != EFI_OUT_OF_RESOURCES && !HEditorExit);
2278
2279 return Status;
2280 }
2281
2282 /**
2283 Backup function for MainEditor.
2284 **/
2285 VOID
2286 EFIAPI
2287 HMainEditorBackup (
2288 VOID
2289 )
2290 {
2291 HMainEditorBackupVar.SelectStart = HMainEditor.SelectStart;
2292 HMainEditorBackupVar.SelectEnd = HMainEditor.SelectEnd;
2293 HBufferImageBackup ();
2294 }