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