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 } 2318