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