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