]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.c
ShellPkg: Fixed build error 'variable set but not used'
[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 LIST_ENTRY *Link;
602 UINT8 *Buffer;
603 UINTN Count;
604
605 //
606 // not select, so not allowed to cut
607 //
608 if (HMainEditor.SelectStart == 0) {
609 StatusBarSetStatusString (L"No Block is Selected");
610 return EFI_SUCCESS;
611 }
612 //
613 // not select, so not allowed to cut
614 //
615 if (HMainEditor.SelectEnd == 0) {
616 StatusBarSetStatusString (L"No Block is Selected");
617 return EFI_SUCCESS;
618 }
619
620 Link = HMainEditor.BufferImage->ListHead->ForwardLink;
621 for (Index = 0; Index < (HMainEditor.SelectEnd - 1) / 0x10; Index++) {
622 Link = Link->ForwardLink;
623 }
624
625 Count = HMainEditor.SelectEnd - HMainEditor.SelectStart + 1;
626 Buffer = AllocateZeroPool (Count);
627 if (Buffer == NULL) {
628 return EFI_OUT_OF_RESOURCES;
629 }
630 //
631 // cut the selected area
632 //
633 HBufferImageDeleteCharacterFromBuffer (
634 HMainEditor.SelectStart - 1,
635 Count,
636 Buffer
637 );
638
639 //
640 // put to clipboard
641 //
642 HClipBoardSet (Buffer, Count);
643
644 HBufferImageNeedRefresh = TRUE;
645 HBufferImageOnlyLineNeedRefresh = FALSE;
646
647 if (!HMainEditor.BufferImage->Modified) {
648 HMainEditor.BufferImage->Modified = TRUE;
649 }
650
651 //
652 // now no select area
653 //
654 HMainEditor.SelectStart = 0;
655 HMainEditor.SelectEnd = 0;
656
657 return EFI_SUCCESS;
658 }
659
660 /**
661 Paste line to file buffer.
662
663 @retval EFI_SUCCESS The operation was successful.
664 @retval EFI_OUT_OF_RESOURCES A memory allocation occured.
665 @retval EFI_LOAD_ERROR A load error occured.
666 **/
667 EFI_STATUS
668 HMainCommandPaste (
669 VOID
670 )
671 {
672
673 BOOLEAN OnlyLineRefresh;
674 HEFI_EDITOR_LINE *Line;
675 UINT8 *Buffer;
676 UINTN Count;
677 UINTN FPos;
678
679 Count = HClipBoardGet (&Buffer);
680 if (Count == 0 || Buffer == NULL) {
681 StatusBarSetStatusString (L"Nothing to Paste");
682 return EFI_SUCCESS;
683 }
684
685 Line = HMainEditor.BufferImage->CurrentLine;
686
687 OnlyLineRefresh = FALSE;
688 if (Line->Link.ForwardLink == HMainEditor.BufferImage->ListHead && Line->Size + Count < 0x10) {
689 //
690 // is at last line, and after paste will not exceed
691 // so only this line need to be refreshed
692 //
693 // if after add, the line is 0x10, then will append a new line
694 // so the whole page will need be refreshed
695 //
696 OnlyLineRefresh = TRUE;
697
698 }
699
700 FPos = 0x10 * (HMainEditor.BufferImage->BufferPosition.Row - 1) + HMainEditor.BufferImage->BufferPosition.Column - 1;
701
702 HBufferImageAddCharacterToBuffer (FPos, Count, Buffer);
703
704 if (OnlyLineRefresh) {
705 HBufferImageNeedRefresh = FALSE;
706 HBufferImageOnlyLineNeedRefresh = TRUE;
707 } else {
708 HBufferImageNeedRefresh = TRUE;
709 HBufferImageOnlyLineNeedRefresh = FALSE;
710 }
711
712 if (!HMainEditor.BufferImage->Modified) {
713 HMainEditor.BufferImage->Modified = TRUE;
714 }
715
716 return EFI_SUCCESS;
717
718 }
719
720 /**
721 Exit editor.
722
723 @retval EFI_SUCCESS The operation was successful.
724 @retval EFI_OUT_OF_RESOURCES A memory allocation occured.
725 @retval EFI_LOAD_ERROR A load error occured.
726 **/
727 EFI_STATUS
728 HMainCommandExit (
729 VOID
730 )
731 {
732 EFI_STATUS Status;
733
734 //
735 // Below is the scenario of Exit command:
736 // 1. IF currently opened file is not modified, exit the editor and
737 // Exit command ends.
738 // IF currently opened file is modified, do Step 2
739 //
740 // 2. An Input Bar will be prompted:
741 // "File modified. Save ( Yes/No/Cancel )?"
742 // IF user press 'y' or 'Y', currently opened file will be saved and
743 // Editor exits
744 // IF user press 'n' or 'N', currently opened file will not be saved
745 // and Editor exits.
746 // IF user press 'c' or 'C' or ESC, Exit command ends.
747 //
748 //
749 // if file has been modified, so will prompt user
750 // whether to save the changes
751 //
752 if (HMainEditor.BufferImage->Modified) {
753
754 Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? ");
755 if (EFI_ERROR (Status)) {
756 return Status;
757 }
758
759 Status = InputBarSetStringSize (1);
760 if (EFI_ERROR (Status)) {
761 return Status;
762 }
763
764 while (1) {
765 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
766
767 //
768 // ESC pressed
769 //
770 if (Status == EFI_NOT_READY) {
771 return EFI_SUCCESS;
772 }
773
774 switch (InputBarGetString()[0]) {
775 case L'y':
776 case L'Y':
777 //
778 // write file back to disk
779 //
780 Status = HBufferImageSave (
781 HMainEditor.BufferImage->FileImage->FileName,
782 HMainEditor.BufferImage->DiskImage->Name,
783 HMainEditor.BufferImage->DiskImage->Offset,
784 HMainEditor.BufferImage->DiskImage->Size,
785 HMainEditor.BufferImage->MemImage->Offset,
786 HMainEditor.BufferImage->MemImage->Size,
787 HMainEditor.BufferImage->BufferType
788 );
789 if (!EFI_ERROR (Status)) {
790 HEditorExit = TRUE;
791 }
792
793 return Status;
794
795 case L'n':
796 case L'N':
797 HEditorExit = TRUE;
798 return EFI_SUCCESS;
799
800 case L'c':
801 case L'C':
802 return EFI_SUCCESS;
803
804 }
805 }
806 }
807
808 HEditorExit = TRUE;
809 return EFI_SUCCESS;
810
811 }
812
813 /**
814 Load a file from disk to editor.
815
816 @retval EFI_SUCCESS The operation was successful.
817 @retval EFI_OUT_OF_RESOURCES A memory allocation occured.
818 @retval EFI_LOAD_ERROR A load error occured.
819 **/
820 EFI_STATUS
821 HMainCommandOpenFile (
822 VOID
823 )
824 {
825 BOOLEAN Done;
826 EFI_STATUS Status;
827 EDIT_FILE_TYPE BufferType;
828
829 BufferType = HMainEditor.BufferImage->BufferType;
830
831 //
832 // This command will open a file from current working directory.
833 // Read-only file can also be opened. But it can not be modified.
834 // Below is the scenario of Open File command:
835 // 1. IF currently opened file has not been modified, directly go to step .
836 // IF currently opened file has been modified, an Input Bar will be
837 // prompted as :
838 // "File Modified. Save ( Yes/No/Cancel) ?"
839 // IF user press 'y' or 'Y', currently opened file will be saved.
840 // IF user press 'n' or 'N', currently opened file will
841 // not be saved.
842 // IF user press 'c' or 'C' or ESC, Open File command ends and
843 // currently opened file is still opened.
844 //
845 // 2. An Input Bar will be prompted as : "File Name to Open: "
846 // IF user press ESC, Open File command ends and
847 // currently opened file is still opened.
848 // Any other inputs with a Return will cause
849 // currently opened file close.
850 //
851 // 3. IF user input file name is an existing file ,
852 // this file will be read and opened.
853 // IF user input file name is a new file, this file will be created
854 // and opened. This file's type ( UNICODE or ASCII ) is the same with
855 // the old file.
856 //
857 //
858 // if current file is modified, so you need to choose whether to
859 // save it first.
860 //
861 if (HMainEditor.BufferImage->Modified) {
862
863 Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? ");
864 if (EFI_ERROR (Status)) {
865 return Status;
866 }
867 //
868 // the answer is just one character
869 //
870 Status = InputBarSetStringSize (1);
871 if (EFI_ERROR (Status)) {
872 return Status;
873 }
874 //
875 // loop for user's answer
876 // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'
877 //
878 Done = FALSE;
879 while (!Done) {
880 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
881
882 //
883 // ESC pressed
884 //
885 if (Status == EFI_NOT_READY) {
886 return EFI_SUCCESS;
887 }
888
889 switch (InputBarGetString()[0]) {
890 case L'y':
891 case L'Y':
892 //
893 // want to save this buffer first
894 //
895 Status = HBufferImageSave (
896 HMainEditor.BufferImage->FileImage->FileName,
897 HMainEditor.BufferImage->DiskImage->Name,
898 HMainEditor.BufferImage->DiskImage->Offset,
899 HMainEditor.BufferImage->DiskImage->Size,
900 HMainEditor.BufferImage->MemImage->Offset,
901 HMainEditor.BufferImage->MemImage->Size,
902 HMainEditor.BufferImage->BufferType
903 );
904 if (EFI_ERROR (Status)) {
905 return Status;
906 }
907
908 MainTitleBarRefresh (
909 HMainEditor.BufferImage->BufferType == FileTypeFileBuffer?HMainEditor.BufferImage->FileImage->FileName:HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Name:NULL,
910 HMainEditor.BufferImage->BufferType,
911 HMainEditor.BufferImage->FileImage->ReadOnly,
912 FALSE,
913 HMainEditor.ScreenSize.Column,
914 HMainEditor.ScreenSize.Row,
915 HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Offset:HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Offset:0,
916 HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Size :HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Size :0
917 );
918 Done = TRUE;
919 break;
920
921 case L'n':
922 case L'N':
923 //
924 // the file won't be saved
925 //
926 Done = TRUE;
927 break;
928
929 case L'c':
930 case L'C':
931 return EFI_SUCCESS;
932 }
933 }
934 }
935 //
936 // TO get the open file name
937 //
938 Status = InputBarSetPrompt (L"File Name to Open: ");
939 if (EFI_ERROR (Status)) {
940 HBufferImageRead (
941 HMainEditor.BufferImage->FileImage->FileName,
942 HMainEditor.BufferImage->DiskImage->Name,
943 HMainEditor.BufferImage->DiskImage->Offset,
944 HMainEditor.BufferImage->DiskImage->Size,
945 HMainEditor.BufferImage->MemImage->Offset,
946 HMainEditor.BufferImage->MemImage->Size,
947 BufferType,
948 TRUE
949 );
950 return Status;
951 }
952
953 Status = InputBarSetStringSize (100);
954 if (EFI_ERROR (Status)) {
955 Status = HBufferImageRead (
956 HMainEditor.BufferImage->FileImage->FileName,
957 HMainEditor.BufferImage->DiskImage->Name,
958 HMainEditor.BufferImage->DiskImage->Offset,
959 HMainEditor.BufferImage->DiskImage->Size,
960 HMainEditor.BufferImage->MemImage->Offset,
961 HMainEditor.BufferImage->MemImage->Size,
962 BufferType,
963 TRUE
964 );
965 return Status;
966 }
967
968 while (1) {
969 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
970
971 //
972 // ESC pressed
973 //
974 if (Status == EFI_NOT_READY) {
975 Status = HBufferImageRead (
976 HMainEditor.BufferImage->FileImage->FileName,
977 HMainEditor.BufferImage->DiskImage->Name,
978 HMainEditor.BufferImage->DiskImage->Offset,
979 HMainEditor.BufferImage->DiskImage->Size,
980 HMainEditor.BufferImage->MemImage->Offset,
981 HMainEditor.BufferImage->MemImage->Size,
982 BufferType,
983 TRUE
984 );
985
986 return Status;
987 }
988 //
989 // THE input string length should > 0
990 //
991 if (StrLen (InputBarGetString()) > 0) {
992 //
993 // CHECK if filename's valid
994 //
995 if (!IsValidFileName (InputBarGetString())) {
996 HBufferImageRead (
997 HMainEditor.BufferImage->FileImage->FileName,
998 HMainEditor.BufferImage->DiskImage->Name,
999 HMainEditor.BufferImage->DiskImage->Offset,
1000 HMainEditor.BufferImage->DiskImage->Size,
1001 HMainEditor.BufferImage->MemImage->Offset,
1002 HMainEditor.BufferImage->MemImage->Size,
1003 BufferType,
1004 TRUE
1005 );
1006
1007 StatusBarSetStatusString (L"Invalid File Name");
1008 return EFI_SUCCESS;
1009 }
1010
1011 break;
1012 }
1013 }
1014 //
1015 // read from disk
1016 //
1017 Status = HBufferImageRead (
1018 InputBarGetString(),
1019 HMainEditor.BufferImage->DiskImage->Name,
1020 HMainEditor.BufferImage->DiskImage->Offset,
1021 HMainEditor.BufferImage->DiskImage->Size,
1022 HMainEditor.BufferImage->MemImage->Offset,
1023 HMainEditor.BufferImage->MemImage->Size,
1024 FileTypeFileBuffer,
1025 FALSE
1026 );
1027
1028 if (EFI_ERROR (Status)) {
1029 HBufferImageRead (
1030 HMainEditor.BufferImage->FileImage->FileName,
1031 HMainEditor.BufferImage->DiskImage->Name,
1032 HMainEditor.BufferImage->DiskImage->Offset,
1033 HMainEditor.BufferImage->DiskImage->Size,
1034 HMainEditor.BufferImage->MemImage->Offset,
1035 HMainEditor.BufferImage->MemImage->Size,
1036 BufferType,
1037 TRUE
1038 );
1039
1040 return EFI_LOAD_ERROR;
1041 }
1042
1043 return EFI_SUCCESS;
1044 }
1045
1046 /**
1047 Load a disk buffer editor.
1048
1049 @retval EFI_SUCCESS The operation was successful.
1050 @retval EFI_OUT_OF_RESOURCES A memory allocation occured.
1051 @retval EFI_LOAD_ERROR A load error occured.
1052 @retval EFI_NOT_FOUND The disk was not found.
1053 **/
1054 EFI_STATUS
1055 HMainCommandOpenDisk (
1056 VOID
1057 )
1058 {
1059 UINT64 Size;
1060 UINT64 Offset;
1061 CHAR16 *DeviceName;
1062 EFI_STATUS Status;
1063 BOOLEAN Done;
1064
1065 EDIT_FILE_TYPE BufferType;
1066
1067 //
1068 // variable initialization
1069 //
1070 Size = 0;
1071 Offset = 0;
1072 BufferType = HMainEditor.BufferImage->BufferType;
1073
1074 //
1075 // if current file is modified, so you need to choose
1076 // whether to save it first.
1077 //
1078 if (HMainEditor.BufferImage->Modified) {
1079
1080 Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? ");
1081 if (EFI_ERROR (Status)) {
1082 return Status;
1083 }
1084 //
1085 // the answer is just one character
1086 //
1087 Status = InputBarSetStringSize (1);
1088 if (EFI_ERROR (Status)) {
1089 return Status;
1090 }
1091 //
1092 // loop for user's answer
1093 // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'
1094 //
1095 Done = FALSE;
1096 while (!Done) {
1097 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
1098
1099 //
1100 // ESC pressed
1101 //
1102 if (Status == EFI_NOT_READY) {
1103 return EFI_SUCCESS;
1104 }
1105
1106 switch (InputBarGetString()[0]) {
1107 case L'y':
1108 case L'Y':
1109 //
1110 // want to save this buffer first
1111 //
1112 Status = HBufferImageSave (
1113 HMainEditor.BufferImage->FileImage->FileName,
1114 HMainEditor.BufferImage->DiskImage->Name,
1115 HMainEditor.BufferImage->DiskImage->Offset,
1116 HMainEditor.BufferImage->DiskImage->Size,
1117 HMainEditor.BufferImage->MemImage->Offset,
1118 HMainEditor.BufferImage->MemImage->Size,
1119 BufferType
1120 );
1121 if (EFI_ERROR (Status)) {
1122 return Status;
1123 }
1124
1125 MainTitleBarRefresh (
1126 HMainEditor.BufferImage->BufferType == FileTypeFileBuffer?HMainEditor.BufferImage->FileImage->FileName:HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Name:NULL,
1127 HMainEditor.BufferImage->BufferType,
1128 HMainEditor.BufferImage->FileImage->ReadOnly,
1129 FALSE,
1130 HMainEditor.ScreenSize.Column,
1131 HMainEditor.ScreenSize.Row,
1132 HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Offset:HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Offset:0,
1133 HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Size :HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Size :0
1134 );
1135 Done = TRUE;
1136 break;
1137
1138 case L'n':
1139 case L'N':
1140 //
1141 // the file won't be saved
1142 //
1143 Done = TRUE;
1144 break;
1145
1146 case L'c':
1147 case L'C':
1148 return EFI_SUCCESS;
1149 }
1150 }
1151 }
1152 //
1153 // get disk block device name
1154 //
1155 Status = InputBarSetPrompt (L"Block Device to Open: ");
1156 if (EFI_ERROR (Status)) {
1157 return Status;
1158 }
1159
1160 Status = InputBarSetStringSize (100);
1161 if (EFI_ERROR (Status)) {
1162 return Status;
1163 }
1164
1165 while (1) {
1166 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
1167
1168 //
1169 // ESC pressed
1170 //
1171 if (Status == EFI_NOT_READY) {
1172
1173 return EFI_SUCCESS;
1174 }
1175 //
1176 // THE input string length should > 0
1177 //
1178 if (StrLen (InputBarGetString()) > 0) {
1179 break;
1180 }
1181 }
1182
1183 DeviceName = CatSPrint(NULL, L"%s", InputBarGetString());
1184 if (DeviceName == NULL) {
1185 return EFI_OUT_OF_RESOURCES;
1186 }
1187 //
1188 // get starting offset
1189 //
1190 Status = InputBarSetPrompt (L"First Block No.: ");
1191 if (EFI_ERROR (Status)) {
1192 return Status;
1193 }
1194
1195 Status = InputBarSetStringSize (16);
1196 if (EFI_ERROR (Status)) {
1197 return Status;
1198 }
1199
1200 while (1) {
1201 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
1202
1203 //
1204 // ESC pressed
1205 //
1206 if (Status == EFI_NOT_READY) {
1207
1208 return EFI_SUCCESS;
1209 }
1210 //
1211 // THE input string length should > 0
1212 //
1213 if (StrLen (InputBarGetString()) > 0) {
1214 Status = ShellConvertStringToUint64 (InputBarGetString(), &Offset, TRUE, FALSE);
1215 if (EFI_ERROR (Status)) {
1216 continue;
1217 }
1218
1219 break;
1220 }
1221 }
1222 //
1223 // get Number of Blocks:
1224 //
1225 Status = InputBarSetPrompt (L"Number of Blocks: ");
1226 if (EFI_ERROR (Status)) {
1227 return Status;
1228 }
1229
1230 Status = InputBarSetStringSize (8);
1231 if (EFI_ERROR (Status)) {
1232 return Status;
1233 }
1234
1235 while (1) {
1236 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
1237
1238 //
1239 // ESC pressed
1240 //
1241 if (Status == EFI_NOT_READY) {
1242
1243 return EFI_SUCCESS;
1244 }
1245 //
1246 // THE input string length should > 0
1247 //
1248 if (StrLen (InputBarGetString()) > 0) {
1249 Status = ShellConvertStringToUint64 (InputBarGetString(), &Size, TRUE, FALSE);
1250 if (EFI_ERROR (Status)) {
1251 continue;
1252 }
1253
1254 if (Size == 0) {
1255 continue;
1256 }
1257
1258 break;
1259 }
1260 }
1261
1262 Status = HBufferImageRead (
1263 NULL,
1264 DeviceName,
1265 (UINTN)Offset,
1266 (UINTN)Size,
1267 0,
1268 0,
1269 FileTypeDiskBuffer,
1270 FALSE
1271 );
1272
1273 if (EFI_ERROR (Status)) {
1274
1275 HBufferImageRead (
1276 HMainEditor.BufferImage->FileImage->FileName,
1277 HMainEditor.BufferImage->DiskImage->Name,
1278 HMainEditor.BufferImage->DiskImage->Offset,
1279 HMainEditor.BufferImage->DiskImage->Size,
1280 HMainEditor.BufferImage->MemImage->Offset,
1281 HMainEditor.BufferImage->MemImage->Size,
1282 BufferType,
1283 TRUE
1284 );
1285 return EFI_NOT_FOUND;
1286 }
1287
1288 return EFI_SUCCESS;
1289 }
1290
1291 /**
1292 Load memory content to editor
1293
1294 @retval EFI_SUCCESS The operation was successful.
1295 @retval EFI_OUT_OF_RESOURCES A memory allocation occured.
1296 @retval EFI_LOAD_ERROR A load error occured.
1297 @retval EFI_NOT_FOUND The disk was not found.
1298 **/
1299 EFI_STATUS
1300 HMainCommandOpenMemory (
1301 VOID
1302 )
1303 {
1304 UINT64 Size;
1305 UINT64 Offset;
1306 EFI_STATUS Status;
1307 BOOLEAN Done;
1308 EDIT_FILE_TYPE BufferType;
1309
1310 //
1311 // variable initialization
1312 //
1313 Size = 0;
1314 Offset = 0;
1315 BufferType = HMainEditor.BufferImage->BufferType;
1316
1317 //
1318 // if current buffer is modified, so you need to choose
1319 // whether to save it first.
1320 //
1321 if (HMainEditor.BufferImage->Modified) {
1322
1323 Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? ");
1324 if (EFI_ERROR (Status)) {
1325 return Status;
1326 }
1327 //
1328 // the answer is just one character
1329 //
1330 Status = InputBarSetStringSize (1);
1331 if (EFI_ERROR (Status)) {
1332 return Status;
1333 }
1334 //
1335 // loop for user's answer
1336 // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'
1337 //
1338 Done = FALSE;
1339 while (!Done) {
1340 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
1341
1342 //
1343 // ESC pressed
1344 //
1345 if (Status == EFI_NOT_READY) {
1346 return EFI_SUCCESS;
1347 }
1348
1349 switch (InputBarGetString()[0]) {
1350 case L'y':
1351 case L'Y':
1352 //
1353 // want to save this buffer first
1354 //
1355 Status = HBufferImageSave (
1356 HMainEditor.BufferImage->FileImage->FileName,
1357 HMainEditor.BufferImage->DiskImage->Name,
1358 HMainEditor.BufferImage->DiskImage->Offset,
1359 HMainEditor.BufferImage->DiskImage->Size,
1360 HMainEditor.BufferImage->MemImage->Offset,
1361 HMainEditor.BufferImage->MemImage->Size,
1362 BufferType
1363 );
1364 if (EFI_ERROR (Status)) {
1365 return Status;
1366 }
1367
1368 MainTitleBarRefresh (
1369 HMainEditor.BufferImage->BufferType == FileTypeFileBuffer?HMainEditor.BufferImage->FileImage->FileName:HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Name:NULL,
1370 HMainEditor.BufferImage->BufferType,
1371 HMainEditor.BufferImage->FileImage->ReadOnly,
1372 FALSE,
1373 HMainEditor.ScreenSize.Column,
1374 HMainEditor.ScreenSize.Row,
1375 HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Offset:HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Offset:0,
1376 HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Size :HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Size :0
1377 );
1378 Done = TRUE;
1379 break;
1380
1381 case L'n':
1382 case L'N':
1383 //
1384 // the file won't be saved
1385 //
1386 Done = TRUE;
1387 break;
1388
1389 case L'c':
1390 case L'C':
1391 return EFI_SUCCESS;
1392 }
1393 }
1394 }
1395 //
1396 // get starting offset
1397 //
1398 Status = InputBarSetPrompt (L"Starting Offset: ");
1399 if (EFI_ERROR (Status)) {
1400 return Status;
1401 }
1402
1403 Status = InputBarSetStringSize (8);
1404 if (EFI_ERROR (Status)) {
1405 return Status;
1406 }
1407
1408 while (1) {
1409 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
1410
1411 //
1412 // ESC pressed
1413 //
1414 if (Status == EFI_NOT_READY) {
1415
1416 return EFI_SUCCESS;
1417 }
1418 //
1419 // THE input string length should > 0
1420 //
1421 if (StrLen (InputBarGetString()) > 0) {
1422 Status = ShellConvertStringToUint64 (InputBarGetString(), &Offset, TRUE, FALSE);
1423 if (EFI_ERROR (Status)) {
1424 continue;
1425 }
1426
1427 break;
1428 }
1429 }
1430 //
1431 // get Number of Blocks:
1432 //
1433 Status = InputBarSetPrompt (L"Buffer Size: ");
1434 if (EFI_ERROR (Status)) {
1435 return Status;
1436 }
1437
1438 Status = InputBarSetStringSize (8);
1439 if (EFI_ERROR (Status)) {
1440 return Status;
1441 }
1442
1443 while (1) {
1444 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
1445
1446 //
1447 // ESC pressed
1448 //
1449 if (Status == EFI_NOT_READY) {
1450
1451 return EFI_SUCCESS;
1452 }
1453 //
1454 // THE input string length should > 0
1455 //
1456 if (StrLen (InputBarGetString()) > 0) {
1457 Status = ShellConvertStringToUint64 (InputBarGetString(), &Size, TRUE, FALSE);
1458 if (EFI_ERROR (Status)) {
1459 continue;
1460 }
1461
1462 if (Size == 0) {
1463 continue;
1464 }
1465
1466 break;
1467 }
1468 }
1469
1470 if ((Offset + Size - 1)> 0xffffffff) {
1471 StatusBarSetStatusString (L"Invalid parameter");
1472 return EFI_LOAD_ERROR;
1473 }
1474
1475 Status = HBufferImageRead (
1476 NULL,
1477 NULL,
1478 0,
1479 0,
1480 (UINTN)Offset,
1481 (UINTN)Size,
1482 FileTypeMemBuffer,
1483 FALSE
1484 );
1485
1486 if (EFI_ERROR (Status)) {
1487 StatusBarSetStatusString (L"Read Device Error!");
1488 HBufferImageRead (
1489 HMainEditor.BufferImage->FileImage->FileName,
1490 HMainEditor.BufferImage->DiskImage->Name,
1491 HMainEditor.BufferImage->DiskImage->Offset,
1492 HMainEditor.BufferImage->DiskImage->Size,
1493 HMainEditor.BufferImage->MemImage->Offset,
1494 HMainEditor.BufferImage->MemImage->Size,
1495 BufferType,
1496 TRUE
1497 );
1498 return EFI_NOT_FOUND;
1499 }
1500 return EFI_SUCCESS;
1501
1502 }
1503
1504 MENU_ITEM_FUNCTION HexMainControlBasedMenuFunctions[] = {
1505 NULL,
1506 NULL, /* Ctrl - A */
1507 NULL, /* Ctrl - B */
1508 NULL, /* Ctrl - C */
1509 HMainCommandSelectEnd, /* Ctrl - D */
1510 HMainCommandDisplayHelp, /* Ctrl - E */
1511 NULL, /* Ctrl - F */
1512 HMainCommandGoToOffset, /* Ctrl - G */
1513 NULL, /* Ctrl - H */
1514 HMainCommandOpenDisk, /* Ctrl - I */
1515 NULL, /* Ctrl - J */
1516 NULL, /* Ctrl - K */
1517 NULL, /* Ctrl - L */
1518 HMainCommandOpenMemory, /* Ctrl - M */
1519 NULL, /* Ctrl - N */
1520 HMainCommandOpenFile, /* Ctrl - O */
1521 NULL, /* Ctrl - P */
1522 HMainCommandExit, /* Ctrl - Q */
1523 NULL, /* Ctrl - R */
1524 HMainCommandSaveBuffer, /* Ctrl - S */
1525 HMainCommandSelectStart, /* Ctrl - T */
1526 NULL, /* Ctrl - U */
1527 HMainCommandPaste, /* Ctrl - V */
1528 NULL, /* Ctrl - W */
1529 HMainCommandCut, /* Ctrl - X */
1530 NULL, /* Ctrl - Y */
1531 NULL, /* Ctrl - Z */
1532 };
1533
1534 CONST EDITOR_MENU_ITEM HexEditorMenuItems[] = {
1535 {
1536 STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_GO_TO_OFFSET),
1537 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F1),
1538 HMainCommandGoToOffset
1539 },
1540 {
1541 STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_SAVE_BUFFER),
1542 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F2),
1543 HMainCommandSaveBuffer
1544 },
1545 {
1546 STRING_TOKEN(STR_EDIT_LIBMENUBAR_EXIT),
1547 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F3),
1548 HMainCommandExit
1549 },
1550
1551 {
1552 STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_SELECT_START),
1553 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F4),
1554 HMainCommandSelectStart
1555 },
1556 {
1557 STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_SELECT_END),
1558 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F5),
1559 HMainCommandSelectEnd
1560 },
1561 {
1562 STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_CUT),
1563 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F6),
1564 HMainCommandCut
1565 },
1566 {
1567 STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_PASTE),
1568 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F7),
1569 HMainCommandPaste
1570 },
1571
1572 {
1573 STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_OPEN_FILE),
1574 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F8),
1575 HMainCommandOpenFile
1576 },
1577 {
1578 STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_OPEN_DISK),
1579 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F9),
1580 HMainCommandOpenDisk
1581 },
1582 {
1583 STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_OPEN_MEMORY),
1584 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F10),
1585 HMainCommandOpenMemory
1586 },
1587
1588 {
1589 0,
1590 0,
1591 NULL
1592 }
1593 };
1594
1595 /**
1596 Init function for MainEditor
1597
1598 @retval EFI_SUCCESS The operation was successful.
1599 @retval EFI_LOAD_ERROR A load error occured.
1600 **/
1601 EFI_STATUS
1602 HMainEditorInit (
1603 VOID
1604 )
1605 {
1606 EFI_STATUS Status;
1607 EFI_HANDLE *HandleBuffer;
1608 UINTN HandleCount;
1609 UINTN Index;
1610
1611 //
1612 // basic initialization
1613 //
1614 CopyMem (&HMainEditor, &HMainEditorConst, sizeof (HMainEditor));
1615
1616 //
1617 // set screen attributes
1618 //
1619 HMainEditor.ColorAttributes.Colors.Foreground = gST->ConOut->Mode->Attribute & 0x000000ff;
1620
1621 HMainEditor.ColorAttributes.Colors.Background = (UINT8) (gST->ConOut->Mode->Attribute >> 4);
1622
1623 HOriginalColors = HMainEditor.ColorAttributes.Colors;
1624
1625 HOriginalMode = gST->ConOut->Mode->Mode;
1626
1627 //
1628 // query screen size
1629 //
1630 gST->ConOut->QueryMode (
1631 gST->ConOut,
1632 gST->ConOut->Mode->Mode,
1633 &(HMainEditor.ScreenSize.Column),
1634 &(HMainEditor.ScreenSize.Row)
1635 );
1636
1637 //
1638 // Find mouse in System Table ConsoleInHandle
1639 //
1640 Status = gBS->HandleProtocol (
1641 gST->ConIn,
1642 &gEfiSimplePointerProtocolGuid,
1643 (VOID**)&HMainEditor.MouseInterface
1644 );
1645 if (EFI_ERROR (Status)) {
1646 //
1647 // If there is no Simple Pointer Protocol on System Table
1648 //
1649 HandleBuffer = NULL;
1650 HMainEditor.MouseInterface = NULL;
1651 Status = gBS->LocateHandleBuffer (
1652 ByProtocol,
1653 &gEfiSimplePointerProtocolGuid,
1654 NULL,
1655 &HandleCount,
1656 &HandleBuffer
1657 );
1658 if (!EFI_ERROR (Status) && HandleCount > 0) {
1659 //
1660 // Try to find the first available mouse device
1661 //
1662 for (Index = 0; Index < HandleCount; Index++) {
1663 Status = gBS->HandleProtocol (
1664 HandleBuffer[Index],
1665 &gEfiSimplePointerProtocolGuid,
1666 (VOID**)&HMainEditor.MouseInterface
1667 );
1668 if (!EFI_ERROR (Status)) {
1669 break;
1670 }
1671 }
1672 }
1673 if (HandleBuffer != NULL) {
1674 FreePool (HandleBuffer);
1675 }
1676 }
1677
1678 if (!EFI_ERROR (Status) && HMainEditor.MouseInterface != NULL) {
1679 HMainEditor.MouseAccumulatorX = 0;
1680 HMainEditor.MouseAccumulatorY = 0;
1681 HMainEditor.MouseSupported = TRUE;
1682 }
1683
1684 //
1685 // below will call the five components' init function
1686 //
1687 Status = MainTitleBarInit (L"UEFI HEXEDIT");
1688 if (EFI_ERROR (Status)) {
1689 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_TITLE), gShellDebug1HiiHandle);
1690 return EFI_LOAD_ERROR;
1691 }
1692
1693 Status = ControlHotKeyInit (HexMainControlBasedMenuFunctions);
1694 if (EFI_ERROR (Status)) {
1695 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_MAINMENU), gShellDebug1HiiHandle);
1696 return EFI_LOAD_ERROR;
1697 }
1698 Status = MenuBarInit (HexEditorMenuItems);
1699 if (EFI_ERROR (Status)) {
1700 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_MAINMENU), gShellDebug1HiiHandle);
1701 return EFI_LOAD_ERROR;
1702 }
1703
1704 Status = StatusBarInit ();
1705 if (EFI_ERROR (Status)) {
1706 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_STATUS), gShellDebug1HiiHandle);
1707 return EFI_LOAD_ERROR;
1708 }
1709
1710 InputBarInit ();
1711
1712 Status = HBufferImageInit ();
1713 if (EFI_ERROR (Status)) {
1714 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_BUFFERIMAGE), gShellDebug1HiiHandle);
1715 return EFI_LOAD_ERROR;
1716 }
1717
1718 Status = HClipBoardInit ();
1719 if (EFI_ERROR (Status)) {
1720 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_CLIPBOARD), gShellDebug1HiiHandle);
1721 return EFI_LOAD_ERROR;
1722 }
1723 //
1724 // clear whole screen and enable cursor
1725 //
1726 gST->ConOut->ClearScreen (gST->ConOut);
1727 gST->ConOut->EnableCursor (gST->ConOut, TRUE);
1728
1729 //
1730 // initialize EditorFirst and EditorExit
1731 //
1732 HEditorFirst = TRUE;
1733 HEditorExit = FALSE;
1734 HEditorMouseAction = FALSE;
1735
1736 return EFI_SUCCESS;
1737 }
1738
1739 /**
1740 Cleanup function for MainEditor.
1741
1742 @retval EFI_SUCCESS The operation was successful.
1743 @retval EFI_LOAD_ERROR A load error occured.
1744 **/
1745 EFI_STATUS
1746 HMainEditorCleanup (
1747 VOID
1748 )
1749 {
1750 EFI_STATUS Status;
1751
1752 //
1753 // call the five components' cleanup function
1754 //
1755 MainTitleBarCleanup ();
1756
1757 MenuBarCleanup ();
1758
1759 StatusBarCleanup ();
1760
1761 InputBarCleanup ();
1762
1763 Status = HBufferImageCleanup ();
1764 if (EFI_ERROR (Status)) {
1765 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_BUFFERIMAGE_CLEAN), gShellDebug1HiiHandle);
1766 }
1767
1768 Status = HClipBoardCleanup ();
1769 if (EFI_ERROR (Status)) {
1770 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_CLIPBOARD_CLEAN), gShellDebug1HiiHandle);
1771 }
1772 //
1773 // restore old mode
1774 //
1775 if (HOriginalMode != gST->ConOut->Mode->Mode) {
1776 gST->ConOut->SetMode (gST->ConOut, HOriginalMode);
1777 }
1778
1779 gST->ConOut->SetAttribute (
1780 gST->ConOut,
1781 EFI_TEXT_ATTR (HOriginalColors.Foreground, HOriginalColors.Background)
1782 );
1783 gST->ConOut->ClearScreen (gST->ConOut);
1784
1785 return EFI_SUCCESS;
1786 }
1787
1788 /**
1789 Refresh function for MainEditor.
1790
1791 @retval EFI_SUCCESS The operation was successful.
1792 **/
1793 EFI_STATUS
1794 HMainEditorRefresh (
1795 VOID
1796 )
1797 {
1798 BOOLEAN NameChange;
1799 BOOLEAN ReadChange;
1800
1801 NameChange = FALSE;
1802 ReadChange = FALSE;
1803
1804 if (HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer) {
1805 if (HMainEditor.BufferImage->DiskImage != NULL &&
1806 HBufferImageBackupVar.DiskImage != NULL &&
1807 (HMainEditor.BufferImage->DiskImage->Offset != HBufferImageBackupVar.DiskImage->Offset ||
1808 HMainEditor.BufferImage->DiskImage->Size != HBufferImageBackupVar.DiskImage->Size) ){
1809 NameChange = TRUE;
1810 }
1811 } else if (HMainEditor.BufferImage->BufferType == FileTypeMemBuffer) {
1812 if (HMainEditor.BufferImage->MemImage != NULL &&
1813 HBufferImageBackupVar.MemImage != NULL &&
1814 (HMainEditor.BufferImage->MemImage->Offset != HBufferImageBackupVar.MemImage->Offset ||
1815 HMainEditor.BufferImage->MemImage->Size != HBufferImageBackupVar.MemImage->Size) ){
1816 NameChange = TRUE;
1817 }
1818 } else if (HMainEditor.BufferImage->BufferType == FileTypeFileBuffer) {
1819 if ( HMainEditor.BufferImage->FileImage != NULL &&
1820 HMainEditor.BufferImage->FileImage->FileName != NULL &&
1821 HBufferImageBackupVar.FileImage != NULL &&
1822 HBufferImageBackupVar.FileImage->FileName != NULL &&
1823 StrCmp (HMainEditor.BufferImage->FileImage->FileName, HBufferImageBackupVar.FileImage->FileName) != 0 ) {
1824 NameChange = TRUE;
1825 }
1826 }
1827 if ( HMainEditor.BufferImage->FileImage != NULL &&
1828 HBufferImageBackupVar.FileImage != NULL &&
1829 HMainEditor.BufferImage->FileImage->ReadOnly != HBufferImageBackupVar.FileImage->ReadOnly ) {
1830 ReadChange = TRUE;
1831 }
1832
1833 //
1834 // to aVOID screen flicker
1835 // the stall value is from experience
1836 //
1837 gBS->Stall (50);
1838
1839 //
1840 // call the components refresh function
1841 //
1842 if (HEditorFirst
1843 || NameChange
1844 || HMainEditor.BufferImage->BufferType != HBufferImageBackupVar.BufferType
1845 || HBufferImageBackupVar.Modified != HMainEditor.BufferImage->Modified
1846 || ReadChange ) {
1847
1848 MainTitleBarRefresh (
1849 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,
1850 HMainEditor.BufferImage->BufferType,
1851 (BOOLEAN)(HMainEditor.BufferImage->FileImage!=NULL?HMainEditor.BufferImage->FileImage->ReadOnly:FALSE),
1852 HMainEditor.BufferImage->Modified,
1853 HMainEditor.ScreenSize.Column,
1854 HMainEditor.ScreenSize.Row,
1855 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,
1856 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
1857 );
1858 HBufferImageRefresh ();
1859 }
1860 if (HEditorFirst
1861 || HBufferImageBackupVar.DisplayPosition.Row != HMainEditor.BufferImage->DisplayPosition.Row
1862 || HBufferImageBackupVar.DisplayPosition.Column != HMainEditor.BufferImage->DisplayPosition.Column
1863 || StatusBarGetRefresh()) {
1864
1865 StatusBarRefresh (
1866 HEditorFirst,
1867 HMainEditor.ScreenSize.Row,
1868 HMainEditor.ScreenSize.Column,
1869 (UINTN)(-1),
1870 (UINTN)(-1),
1871 FALSE
1872 );
1873 HBufferImageRefresh ();
1874 }
1875
1876 if (HEditorFirst) {
1877 HBufferImageRefresh ();
1878 }
1879
1880 //
1881 // EditorFirst is now set to FALSE
1882 //
1883 HEditorFirst = FALSE;
1884
1885 return EFI_SUCCESS;
1886 }
1887
1888 /**
1889 Handle the mouse input.
1890
1891 @param[in] MouseState The current mouse state.
1892 @param[out] BeforeLeftButtonDown helps with selections.
1893
1894 @retval EFI_SUCCESS The operation was successful.
1895 @retval EFI_OUT_OF_RESOURCES A memory allocation occured.
1896 @retval EFI_LOAD_ERROR A load error occured.
1897 @retval EFI_NOT_FOUND The disk was not found.
1898 **/
1899 EFI_STATUS
1900 HMainEditorHandleMouseInput (
1901 IN EFI_SIMPLE_POINTER_STATE MouseState,
1902 OUT BOOLEAN *BeforeLeftButtonDown
1903 )
1904 {
1905
1906 INT32 TextX;
1907 INT32 TextY;
1908 UINTN FRow;
1909 UINTN FCol;
1910 BOOLEAN HighBits;
1911 LIST_ENTRY *Link;
1912 HEFI_EDITOR_LINE *Line;
1913 UINTN Index;
1914 BOOLEAN Action;
1915
1916 Action = FALSE;
1917
1918 //
1919 // have mouse movement
1920 //
1921 if (MouseState.RelativeMovementX || MouseState.RelativeMovementY) {
1922 //
1923 // handle
1924 //
1925 TextX = HGetTextX (MouseState.RelativeMovementX);
1926 TextY = HGetTextY (MouseState.RelativeMovementY);
1927
1928 HBufferImageAdjustMousePosition (TextX, TextY);
1929
1930 Action = TRUE;
1931
1932 }
1933
1934 if (MouseState.LeftButton) {
1935 HighBits = HBufferImageIsAtHighBits (
1936 HMainEditor.BufferImage->MousePosition.Column,
1937 &FCol
1938 );
1939
1940 //
1941 // not at an movable place
1942 //
1943 if (FCol == 0) {
1944 //
1945 // now just move mouse pointer to legal position
1946 //
1947 //
1948 // move mouse position to legal position
1949 //
1950 HMainEditor.BufferImage->MousePosition.Column -= 10;
1951 if (HMainEditor.BufferImage->MousePosition.Column > 24) {
1952 HMainEditor.BufferImage->MousePosition.Column--;
1953 FCol = HMainEditor.BufferImage->MousePosition.Column / 3 + 1 + 1;
1954 } else {
1955 if (HMainEditor.BufferImage->MousePosition.Column < 24) {
1956 FCol = HMainEditor.BufferImage->MousePosition.Column / 3 + 1 + 1;
1957 } else {
1958 //
1959 // == 24
1960 //
1961 FCol = 9;
1962 }
1963 }
1964
1965 HighBits = TRUE;
1966
1967 }
1968
1969 FRow = HMainEditor.BufferImage->BufferPosition.Row +
1970 HMainEditor.BufferImage->MousePosition.Row -
1971 HMainEditor.BufferImage->DisplayPosition.Row;
1972
1973 if (HMainEditor.BufferImage->NumLines < FRow) {
1974 //
1975 // dragging
1976 //
1977 //
1978 // now just move mouse pointer to legal position
1979 //
1980 FRow = HMainEditor.BufferImage->NumLines;
1981 HighBits = TRUE;
1982 }
1983
1984 Link = HMainEditor.BufferImage->ListHead->ForwardLink;
1985 for (Index = 0; Index < FRow - 1; Index++) {
1986 Link = Link->ForwardLink;
1987 }
1988
1989 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
1990
1991 //
1992 // dragging
1993 //
1994 //
1995 // now just move mouse pointer to legal position
1996 //
1997 if (FCol > Line->Size) {
1998 if (*BeforeLeftButtonDown) {
1999 HighBits = FALSE;
2000
2001 if (Line->Size == 0) {
2002 if (FRow > 1) {
2003 FRow--;
2004 FCol = 16;
2005 } else {
2006 FRow = 1;
2007 FCol = 1;
2008 }
2009
2010 } else {
2011 FCol = Line->Size;
2012 }
2013 } else {
2014 FCol = Line->Size + 1;
2015 HighBits = TRUE;
2016 }
2017 }
2018
2019 HBufferImageMovePosition (FRow, FCol, HighBits);
2020
2021 HMainEditor.BufferImage->MousePosition.Row = HMainEditor.BufferImage->DisplayPosition.Row;
2022
2023 HMainEditor.BufferImage->MousePosition.Column = HMainEditor.BufferImage->DisplayPosition.Column;
2024
2025 *BeforeLeftButtonDown = TRUE;
2026
2027 Action = TRUE;
2028 } else {
2029 //
2030 // else of if LButton
2031 //
2032 // release LButton
2033 //
2034 if (*BeforeLeftButtonDown) {
2035 Action = TRUE;
2036 }
2037 //
2038 // mouse up
2039 //
2040 *BeforeLeftButtonDown = FALSE;
2041 }
2042
2043 if (Action) {
2044 return EFI_SUCCESS;
2045 }
2046
2047 return EFI_NOT_FOUND;
2048 }
2049
2050 /**
2051 Handle user key input. will route it to other components handle function.
2052
2053 @retval EFI_SUCCESS The operation was successful.
2054 @retval EFI_OUT_OF_RESOURCES A memory allocation occured.
2055 @retval EFI_LOAD_ERROR A load error occured.
2056 **/
2057 EFI_STATUS
2058 HMainEditorKeyInput (
2059 VOID
2060 )
2061 {
2062 EFI_INPUT_KEY Key;
2063 EFI_STATUS Status;
2064 EFI_SIMPLE_POINTER_STATE MouseState;
2065 BOOLEAN LengthChange;
2066 UINTN Size;
2067 UINTN OldSize;
2068 BOOLEAN BeforeMouseIsDown;
2069 BOOLEAN MouseIsDown;
2070 BOOLEAN FirstDown;
2071 BOOLEAN MouseDrag;
2072 UINTN FRow;
2073 UINTN FCol;
2074 UINTN SelectStartBackup;
2075 UINTN SelectEndBackup;
2076
2077 //
2078 // variable initialization
2079 //
2080 OldSize = 0;
2081 FRow = 0;
2082 FCol = 0;
2083 LengthChange = FALSE;
2084
2085 MouseIsDown = FALSE;
2086 FirstDown = FALSE;
2087 MouseDrag = FALSE;
2088
2089 do {
2090
2091 Status = EFI_SUCCESS;
2092
2093 HEditorMouseAction = FALSE;
2094
2095 //
2096 // backup some key elements, so that can aVOID some refresh work
2097 //
2098 HMainEditorBackup ();
2099
2100 //
2101 // wait for user key input
2102 //
2103 //
2104 // change priority of checking mouse/keyboard activity dynamically
2105 // so prevent starvation of keyboard.
2106 // if last time, mouse moves then this time check keyboard
2107 //
2108 if (HMainEditor.MouseSupported) {
2109 Status = HMainEditor.MouseInterface->GetState (
2110 HMainEditor.MouseInterface,
2111 &MouseState
2112 );
2113 if (!EFI_ERROR (Status)) {
2114
2115 BeforeMouseIsDown = MouseIsDown;
2116
2117 Status = HMainEditorHandleMouseInput (MouseState, &MouseIsDown);
2118
2119 if (!EFI_ERROR (Status)) {
2120 if (!BeforeMouseIsDown) {
2121 //
2122 // mouse down
2123 //
2124 if (MouseIsDown) {
2125 FRow = HBufferImage.BufferPosition.Row;
2126 FCol = HBufferImage.BufferPosition.Column;
2127 SelectStartBackup = HMainEditor.SelectStart;
2128 SelectEndBackup = HMainEditor.SelectEnd;
2129
2130 FirstDown = TRUE;
2131 }
2132 } else {
2133
2134 SelectStartBackup = HMainEditor.SelectStart;
2135 SelectEndBackup = HMainEditor.SelectEnd;
2136
2137 //
2138 // begin to drag
2139 //
2140 if (MouseIsDown) {
2141 if (FirstDown) {
2142 if (MouseState.RelativeMovementX || MouseState.RelativeMovementY) {
2143 HMainEditor.SelectStart = 0;
2144 HMainEditor.SelectEnd = 0;
2145 HMainEditor.SelectStart = (FRow - 1) * 0x10 + FCol;
2146
2147 MouseDrag = TRUE;
2148 FirstDown = FALSE;
2149 }
2150 } else {
2151 if ((
2152 (HBufferImage.BufferPosition.Row - 1) *
2153 0x10 +
2154 HBufferImage.BufferPosition.Column
2155 ) >= HMainEditor.SelectStart
2156 ) {
2157 HMainEditor.SelectEnd = (HBufferImage.BufferPosition.Row - 1) *
2158 0x10 +
2159 HBufferImage.BufferPosition.Column;
2160 } else {
2161 HMainEditor.SelectEnd = 0;
2162 }
2163 }
2164 //
2165 // end of if RelativeX/Y
2166 //
2167 } else {
2168 //
2169 // mouse is up
2170 //
2171 if (MouseDrag) {
2172 if (HBufferImageGetTotalSize () == 0) {
2173 HMainEditor.SelectStart = 0;
2174 HMainEditor.SelectEnd = 0;
2175 FirstDown = FALSE;
2176 MouseDrag = FALSE;
2177 }
2178
2179 if ((
2180 (HBufferImage.BufferPosition.Row - 1) *
2181 0x10 +
2182 HBufferImage.BufferPosition.Column
2183 ) >= HMainEditor.SelectStart
2184 ) {
2185 HMainEditor.SelectEnd = (HBufferImage.BufferPosition.Row - 1) *
2186 0x10 +
2187 HBufferImage.BufferPosition.Column;
2188 } else {
2189 HMainEditor.SelectEnd = 0;
2190 }
2191
2192 if (HMainEditor.SelectEnd == 0) {
2193 HMainEditor.SelectStart = 0;
2194 }
2195 }
2196
2197 FirstDown = FALSE;
2198 MouseDrag = FALSE;
2199 }
2200
2201 if (SelectStartBackup != HMainEditor.SelectStart || SelectEndBackup != HMainEditor.SelectEnd) {
2202 if ((SelectStartBackup - 1) / 0x10 != (HMainEditor.SelectStart - 1) / 0x10) {
2203 HBufferImageNeedRefresh = TRUE;
2204 } else {
2205 if ((SelectEndBackup - 1) / 0x10 != (HMainEditor.SelectEnd - 1) / 0x10) {
2206 HBufferImageNeedRefresh = TRUE;
2207 } else {
2208 HBufferImageOnlyLineNeedRefresh = TRUE;
2209 }
2210 }
2211 }
2212 }
2213
2214 HEditorMouseAction = TRUE;
2215 HBufferImageMouseNeedRefresh = TRUE;
2216
2217 } else if (Status == EFI_LOAD_ERROR) {
2218 StatusBarSetStatusString (L"Invalid Mouse Movement ");
2219 }
2220 }
2221 }
2222
2223 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
2224 if (!EFI_ERROR (Status)) {
2225 //
2226 // dispatch to different components' key handling function
2227 // so not everywhere has to set this variable
2228 //
2229 HBufferImageMouseNeedRefresh = TRUE;
2230
2231 //
2232 // clear previous status string
2233 //
2234 StatusBarSetRefresh();
2235 if (EFI_SUCCESS == MenuBarDispatchControlHotKey(&Key)) {
2236 Status = EFI_SUCCESS;
2237 } else if (Key.ScanCode == SCAN_NULL) {
2238 Status = HBufferImageHandleInput (&Key);
2239 } else if (((Key.ScanCode >= SCAN_UP) && (Key.ScanCode <= SCAN_PAGE_DOWN))) {
2240 Status = HBufferImageHandleInput (&Key);
2241 } else if (((Key.ScanCode >= SCAN_F1) && Key.ScanCode <= (SCAN_F12))) {
2242 Status = MenuBarDispatchFunctionKey (&Key);
2243 } else {
2244 StatusBarSetStatusString (L"Unknown Command");
2245
2246 HBufferImageMouseNeedRefresh = FALSE;
2247 }
2248
2249 if (Status != EFI_SUCCESS && Status != EFI_OUT_OF_RESOURCES) {
2250 //
2251 // not already has some error status
2252 //
2253 if (StrCmp (L"", StatusBarGetString()) == 0) {
2254 StatusBarSetStatusString (L"Disk Error. Try Again");
2255 }
2256 }
2257 }
2258 //
2259 // decide if has to set length warning
2260 //
2261 if (HBufferImage.BufferType != HBufferImageBackupVar.BufferType) {
2262 LengthChange = FALSE;
2263 } else {
2264 //
2265 // still the old buffer
2266 //
2267 if (HBufferImage.BufferType != FileTypeFileBuffer) {
2268 Size = HBufferImageGetTotalSize ();
2269
2270 switch (HBufferImage.BufferType) {
2271 case FileTypeDiskBuffer:
2272 OldSize = HBufferImage.DiskImage->Size * HBufferImage.DiskImage->BlockSize;
2273 break;
2274
2275 case FileTypeMemBuffer:
2276 OldSize = HBufferImage.MemImage->Size;
2277 break;
2278
2279 default:
2280 OldSize = 0;
2281 break;
2282 }
2283
2284 if (!LengthChange) {
2285 if (OldSize != Size) {
2286 StatusBarSetStatusString (L"Disk/Mem Buffer Length should not be changed");
2287 }
2288 }
2289
2290 if (OldSize != Size) {
2291 LengthChange = TRUE;
2292 } else {
2293 LengthChange = FALSE;
2294 }
2295 }
2296 }
2297 //
2298 // after handling, refresh editor
2299 //
2300 HMainEditorRefresh ();
2301
2302 } while (Status != EFI_OUT_OF_RESOURCES && !HEditorExit);
2303
2304 return Status;
2305 }
2306
2307 /**
2308 Backup function for MainEditor.
2309 **/
2310 VOID
2311 EFIAPI
2312 HMainEditorBackup (
2313 VOID
2314 )
2315 {
2316 HMainEditorBackupVar.SelectStart = HMainEditor.SelectStart;
2317 HMainEditorBackupVar.SelectEnd = HMainEditor.SelectEnd;
2318 HBufferImageBackup ();
2319 }