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