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