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