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