]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.c
ShellPkg: Fixed build error 'variable set but not used'
[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
632820d1 601 LIST_ENTRY *Link;\r
602 UINT8 *Buffer;\r
603 UINTN Count;\r
604\r
605 //\r
606 // not select, so not allowed to cut\r
607 //\r
608 if (HMainEditor.SelectStart == 0) {\r
609 StatusBarSetStatusString (L"No Block is Selected");\r
610 return EFI_SUCCESS;\r
611 }\r
612 //\r
613 // not select, so not allowed to cut\r
614 //\r
615 if (HMainEditor.SelectEnd == 0) {\r
616 StatusBarSetStatusString (L"No Block is Selected");\r
617 return EFI_SUCCESS;\r
618 }\r
619\r
620 Link = HMainEditor.BufferImage->ListHead->ForwardLink;\r
621 for (Index = 0; Index < (HMainEditor.SelectEnd - 1) / 0x10; Index++) {\r
622 Link = Link->ForwardLink;\r
623 }\r
624\r
632820d1 625 Count = HMainEditor.SelectEnd - HMainEditor.SelectStart + 1;\r
626 Buffer = AllocateZeroPool (Count);\r
627 if (Buffer == NULL) {\r
628 return EFI_OUT_OF_RESOURCES;\r
629 }\r
630 //\r
631 // cut the selected area\r
632 //\r
633 HBufferImageDeleteCharacterFromBuffer (\r
634 HMainEditor.SelectStart - 1,\r
635 Count,\r
636 Buffer\r
637 );\r
638\r
639 //\r
640 // put to clipboard\r
641 //\r
642 HClipBoardSet (Buffer, Count);\r
643\r
644 HBufferImageNeedRefresh = TRUE;\r
645 HBufferImageOnlyLineNeedRefresh = FALSE;\r
646\r
647 if (!HMainEditor.BufferImage->Modified) {\r
648 HMainEditor.BufferImage->Modified = TRUE;\r
649 }\r
650\r
651 //\r
652 // now no select area\r
653 //\r
654 HMainEditor.SelectStart = 0;\r
655 HMainEditor.SelectEnd = 0;\r
656\r
657 return EFI_SUCCESS;\r
658}\r
659\r
a1d4bfcc 660/**\r
661 Paste line to file buffer.\r
662\r
663 @retval EFI_SUCCESS The operation was successful.\r
664 @retval EFI_OUT_OF_RESOURCES A memory allocation occured.\r
665 @retval EFI_LOAD_ERROR A load error occured.\r
666**/\r
632820d1 667EFI_STATUS\r
668HMainCommandPaste (\r
669 VOID\r
670 )\r
632820d1 671{\r
672\r
673 BOOLEAN OnlyLineRefresh;\r
674 HEFI_EDITOR_LINE *Line;\r
675 UINT8 *Buffer;\r
676 UINTN Count;\r
677 UINTN FPos;\r
678\r
679 Count = HClipBoardGet (&Buffer);\r
680 if (Count == 0 || Buffer == NULL) {\r
681 StatusBarSetStatusString (L"Nothing to Paste");\r
682 return EFI_SUCCESS;\r
683 }\r
684\r
685 Line = HMainEditor.BufferImage->CurrentLine;\r
686\r
687 OnlyLineRefresh = FALSE;\r
688 if (Line->Link.ForwardLink == HMainEditor.BufferImage->ListHead && Line->Size + Count < 0x10) {\r
689 //\r
690 // is at last line, and after paste will not exceed\r
691 // so only this line need to be refreshed\r
692 //\r
693 // if after add, the line is 0x10, then will append a new line\r
694 // so the whole page will need be refreshed\r
695 //\r
696 OnlyLineRefresh = TRUE;\r
697\r
698 }\r
699\r
700 FPos = 0x10 * (HMainEditor.BufferImage->BufferPosition.Row - 1) + HMainEditor.BufferImage->BufferPosition.Column - 1;\r
701\r
702 HBufferImageAddCharacterToBuffer (FPos, Count, Buffer);\r
703\r
704 if (OnlyLineRefresh) {\r
705 HBufferImageNeedRefresh = FALSE;\r
706 HBufferImageOnlyLineNeedRefresh = TRUE;\r
707 } else {\r
708 HBufferImageNeedRefresh = TRUE;\r
709 HBufferImageOnlyLineNeedRefresh = FALSE;\r
710 }\r
711\r
712 if (!HMainEditor.BufferImage->Modified) {\r
713 HMainEditor.BufferImage->Modified = TRUE;\r
714 }\r
715\r
716 return EFI_SUCCESS;\r
717\r
718}\r
719\r
a1d4bfcc 720/**\r
721 Exit editor.\r
722\r
723 @retval EFI_SUCCESS The operation was successful.\r
724 @retval EFI_OUT_OF_RESOURCES A memory allocation occured.\r
725 @retval EFI_LOAD_ERROR A load error occured.\r
726**/\r
632820d1 727EFI_STATUS\r
728HMainCommandExit (\r
729 VOID\r
730 )\r
632820d1 731{\r
732 EFI_STATUS Status;\r
733\r
734 //\r
735 // Below is the scenario of Exit command:\r
736 // 1. IF currently opened file is not modified, exit the editor and\r
737 // Exit command ends.\r
738 // IF currently opened file is modified, do Step 2\r
739 //\r
740 // 2. An Input Bar will be prompted:\r
741 // "File modified. Save ( Yes/No/Cancel )?"\r
742 // IF user press 'y' or 'Y', currently opened file will be saved and\r
743 // Editor exits\r
744 // IF user press 'n' or 'N', currently opened file will not be saved\r
745 // and Editor exits.\r
746 // IF user press 'c' or 'C' or ESC, Exit command ends.\r
747 //\r
748 //\r
749 // if file has been modified, so will prompt user\r
750 // whether to save the changes\r
751 //\r
752 if (HMainEditor.BufferImage->Modified) {\r
753\r
754 Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? ");\r
755 if (EFI_ERROR (Status)) {\r
756 return Status;\r
757 }\r
758\r
759 Status = InputBarSetStringSize (1);\r
760 if (EFI_ERROR (Status)) {\r
761 return Status;\r
762 }\r
763\r
764 while (1) {\r
765 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);\r
766\r
767 //\r
768 // ESC pressed\r
769 //\r
770 if (Status == EFI_NOT_READY) {\r
771 return EFI_SUCCESS;\r
772 }\r
773\r
774 switch (InputBarGetString()[0]) {\r
775 case L'y':\r
776 case L'Y':\r
777 //\r
778 // write file back to disk\r
779 //\r
780 Status = HBufferImageSave (\r
781 HMainEditor.BufferImage->FileImage->FileName,\r
782 HMainEditor.BufferImage->DiskImage->Name,\r
783 HMainEditor.BufferImage->DiskImage->Offset,\r
784 HMainEditor.BufferImage->DiskImage->Size,\r
785 HMainEditor.BufferImage->MemImage->Offset,\r
786 HMainEditor.BufferImage->MemImage->Size,\r
787 HMainEditor.BufferImage->BufferType\r
788 );\r
789 if (!EFI_ERROR (Status)) {\r
790 HEditorExit = TRUE;\r
791 }\r
792\r
793 return Status;\r
794\r
795 case L'n':\r
796 case L'N':\r
797 HEditorExit = TRUE;\r
798 return EFI_SUCCESS;\r
799\r
800 case L'c':\r
801 case L'C':\r
802 return EFI_SUCCESS;\r
803\r
804 }\r
805 }\r
806 }\r
807\r
808 HEditorExit = TRUE;\r
809 return EFI_SUCCESS;\r
810\r
811}\r
812\r
a1d4bfcc 813/**\r
814 Load a file from disk to editor.\r
815\r
816 @retval EFI_SUCCESS The operation was successful.\r
817 @retval EFI_OUT_OF_RESOURCES A memory allocation occured.\r
818 @retval EFI_LOAD_ERROR A load error occured.\r
819**/\r
632820d1 820EFI_STATUS\r
821HMainCommandOpenFile (\r
822 VOID\r
823 )\r
632820d1 824{\r
825 BOOLEAN Done;\r
826 EFI_STATUS Status;\r
827 EDIT_FILE_TYPE BufferType;\r
828\r
829 BufferType = HMainEditor.BufferImage->BufferType;\r
830\r
831 //\r
832 // This command will open a file from current working directory.\r
833 // Read-only file can also be opened. But it can not be modified.\r
834 // Below is the scenario of Open File command:\r
835 // 1. IF currently opened file has not been modified, directly go to step .\r
836 // IF currently opened file has been modified, an Input Bar will be\r
837 // prompted as :\r
838 // "File Modified. Save ( Yes/No/Cancel) ?"\r
839 // IF user press 'y' or 'Y', currently opened file will be saved.\r
840 // IF user press 'n' or 'N', currently opened file will\r
841 // not be saved.\r
842 // IF user press 'c' or 'C' or ESC, Open File command ends and\r
843 // currently opened file is still opened.\r
844 //\r
845 // 2. An Input Bar will be prompted as : "File Name to Open: "\r
846 // IF user press ESC, Open File command ends and\r
847 // currently opened file is still opened.\r
848 // Any other inputs with a Return will cause\r
849 // currently opened file close.\r
850 //\r
851 // 3. IF user input file name is an existing file ,\r
852 // this file will be read and opened.\r
853 // IF user input file name is a new file, this file will be created\r
854 // and opened. This file's type ( UNICODE or ASCII ) is the same with\r
855 // the old file.\r
856 //\r
857 //\r
858 // if current file is modified, so you need to choose whether to\r
859 // save it first.\r
860 //\r
861 if (HMainEditor.BufferImage->Modified) {\r
862\r
863 Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? ");\r
864 if (EFI_ERROR (Status)) {\r
865 return Status;\r
866 }\r
867 //\r
868 // the answer is just one character\r
869 //\r
870 Status = InputBarSetStringSize (1);\r
871 if (EFI_ERROR (Status)) {\r
872 return Status;\r
873 }\r
874 //\r
875 // loop for user's answer\r
876 // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'\r
877 //\r
878 Done = FALSE;\r
879 while (!Done) {\r
880 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);\r
881\r
882 //\r
883 // ESC pressed\r
884 //\r
885 if (Status == EFI_NOT_READY) {\r
886 return EFI_SUCCESS;\r
887 }\r
888\r
889 switch (InputBarGetString()[0]) {\r
890 case L'y':\r
891 case L'Y':\r
892 //\r
893 // want to save this buffer first\r
894 //\r
895 Status = HBufferImageSave (\r
896 HMainEditor.BufferImage->FileImage->FileName,\r
897 HMainEditor.BufferImage->DiskImage->Name,\r
898 HMainEditor.BufferImage->DiskImage->Offset,\r
899 HMainEditor.BufferImage->DiskImage->Size,\r
900 HMainEditor.BufferImage->MemImage->Offset,\r
901 HMainEditor.BufferImage->MemImage->Size,\r
902 HMainEditor.BufferImage->BufferType\r
903 );\r
904 if (EFI_ERROR (Status)) {\r
905 return Status;\r
906 }\r
907\r
908 MainTitleBarRefresh (\r
909 HMainEditor.BufferImage->BufferType == FileTypeFileBuffer?HMainEditor.BufferImage->FileImage->FileName:HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Name:NULL,\r
910 HMainEditor.BufferImage->BufferType,\r
911 HMainEditor.BufferImage->FileImage->ReadOnly,\r
912 FALSE,\r
913 HMainEditor.ScreenSize.Column,\r
980d554e 914 HMainEditor.ScreenSize.Row,\r
915 HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Offset:HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Offset:0,\r
916 HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Size :HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Size :0\r
632820d1 917 );\r
918 Done = TRUE;\r
919 break;\r
920\r
921 case L'n':\r
922 case L'N':\r
923 //\r
924 // the file won't be saved\r
925 //\r
926 Done = TRUE;\r
927 break;\r
928\r
929 case L'c':\r
930 case L'C':\r
931 return EFI_SUCCESS;\r
932 }\r
933 }\r
934 }\r
935 //\r
936 // TO get the open file name\r
937 //\r
938 Status = InputBarSetPrompt (L"File Name to Open: ");\r
939 if (EFI_ERROR (Status)) {\r
940 HBufferImageRead (\r
941 HMainEditor.BufferImage->FileImage->FileName,\r
942 HMainEditor.BufferImage->DiskImage->Name,\r
943 HMainEditor.BufferImage->DiskImage->Offset,\r
944 HMainEditor.BufferImage->DiskImage->Size,\r
945 HMainEditor.BufferImage->MemImage->Offset,\r
946 HMainEditor.BufferImage->MemImage->Size,\r
947 BufferType,\r
948 TRUE\r
949 );\r
950 return Status;\r
951 }\r
952\r
953 Status = InputBarSetStringSize (100);\r
954 if (EFI_ERROR (Status)) {\r
955 Status = HBufferImageRead (\r
956 HMainEditor.BufferImage->FileImage->FileName,\r
957 HMainEditor.BufferImage->DiskImage->Name,\r
958 HMainEditor.BufferImage->DiskImage->Offset,\r
959 HMainEditor.BufferImage->DiskImage->Size,\r
960 HMainEditor.BufferImage->MemImage->Offset,\r
961 HMainEditor.BufferImage->MemImage->Size,\r
962 BufferType,\r
963 TRUE\r
964 );\r
965 return Status;\r
966 }\r
967\r
968 while (1) {\r
969 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);\r
970\r
971 //\r
972 // ESC pressed\r
973 //\r
974 if (Status == EFI_NOT_READY) {\r
975 Status = HBufferImageRead (\r
976 HMainEditor.BufferImage->FileImage->FileName,\r
977 HMainEditor.BufferImage->DiskImage->Name,\r
978 HMainEditor.BufferImage->DiskImage->Offset,\r
979 HMainEditor.BufferImage->DiskImage->Size,\r
980 HMainEditor.BufferImage->MemImage->Offset,\r
981 HMainEditor.BufferImage->MemImage->Size,\r
982 BufferType,\r
983 TRUE\r
984 );\r
985\r
986 return Status;\r
987 }\r
988 //\r
989 // THE input string length should > 0\r
990 //\r
991 if (StrLen (InputBarGetString()) > 0) {\r
992 //\r
993 // CHECK if filename's valid\r
994 //\r
995 if (!IsValidFileName (InputBarGetString())) {\r
996 HBufferImageRead (\r
997 HMainEditor.BufferImage->FileImage->FileName,\r
998 HMainEditor.BufferImage->DiskImage->Name,\r
999 HMainEditor.BufferImage->DiskImage->Offset,\r
1000 HMainEditor.BufferImage->DiskImage->Size,\r
1001 HMainEditor.BufferImage->MemImage->Offset,\r
1002 HMainEditor.BufferImage->MemImage->Size,\r
1003 BufferType,\r
1004 TRUE\r
1005 );\r
1006\r
1007 StatusBarSetStatusString (L"Invalid File Name");\r
1008 return EFI_SUCCESS;\r
1009 }\r
1010\r
1011 break;\r
1012 }\r
1013 }\r
1014 //\r
1015 // read from disk\r
1016 //\r
1017 Status = HBufferImageRead (\r
1018 InputBarGetString(),\r
1019 HMainEditor.BufferImage->DiskImage->Name,\r
1020 HMainEditor.BufferImage->DiskImage->Offset,\r
1021 HMainEditor.BufferImage->DiskImage->Size,\r
1022 HMainEditor.BufferImage->MemImage->Offset,\r
1023 HMainEditor.BufferImage->MemImage->Size,\r
1024 FileTypeFileBuffer,\r
1025 FALSE\r
1026 );\r
1027\r
1028 if (EFI_ERROR (Status)) {\r
1029 HBufferImageRead (\r
1030 HMainEditor.BufferImage->FileImage->FileName,\r
1031 HMainEditor.BufferImage->DiskImage->Name,\r
1032 HMainEditor.BufferImage->DiskImage->Offset,\r
1033 HMainEditor.BufferImage->DiskImage->Size,\r
1034 HMainEditor.BufferImage->MemImage->Offset,\r
1035 HMainEditor.BufferImage->MemImage->Size,\r
1036 BufferType,\r
1037 TRUE\r
1038 );\r
1039\r
1040 return EFI_LOAD_ERROR;\r
1041 }\r
1042\r
1043 return EFI_SUCCESS;\r
1044}\r
1045\r
a1d4bfcc 1046/**\r
1047 Load a disk buffer editor.\r
1048\r
1049 @retval EFI_SUCCESS The operation was successful.\r
1050 @retval EFI_OUT_OF_RESOURCES A memory allocation occured.\r
1051 @retval EFI_LOAD_ERROR A load error occured.\r
1052 @retval EFI_NOT_FOUND The disk was not found.\r
1053**/\r
632820d1 1054EFI_STATUS\r
1055HMainCommandOpenDisk (\r
1056 VOID\r
1057 )\r
632820d1 1058{\r
1059 UINT64 Size;\r
1060 UINT64 Offset;\r
1061 CHAR16 *DeviceName;\r
1062 EFI_STATUS Status;\r
1063 BOOLEAN Done;\r
1064\r
1065 EDIT_FILE_TYPE BufferType;\r
1066\r
1067 //\r
1068 // variable initialization\r
1069 //\r
1070 Size = 0;\r
1071 Offset = 0;\r
1072 BufferType = HMainEditor.BufferImage->BufferType;\r
1073\r
1074 //\r
1075 // if current file is modified, so you need to choose\r
1076 // whether to save it first.\r
1077 //\r
1078 if (HMainEditor.BufferImage->Modified) {\r
1079\r
1080 Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? ");\r
1081 if (EFI_ERROR (Status)) {\r
1082 return Status;\r
1083 }\r
1084 //\r
1085 // the answer is just one character\r
1086 //\r
1087 Status = InputBarSetStringSize (1);\r
1088 if (EFI_ERROR (Status)) {\r
1089 return Status;\r
1090 }\r
1091 //\r
1092 // loop for user's answer\r
1093 // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'\r
1094 //\r
1095 Done = FALSE;\r
1096 while (!Done) {\r
1097 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);\r
1098\r
1099 //\r
1100 // ESC pressed\r
1101 //\r
1102 if (Status == EFI_NOT_READY) {\r
1103 return EFI_SUCCESS;\r
1104 }\r
1105\r
1106 switch (InputBarGetString()[0]) {\r
1107 case L'y':\r
1108 case L'Y':\r
1109 //\r
1110 // want to save this buffer first\r
1111 //\r
1112 Status = HBufferImageSave (\r
1113 HMainEditor.BufferImage->FileImage->FileName,\r
1114 HMainEditor.BufferImage->DiskImage->Name,\r
1115 HMainEditor.BufferImage->DiskImage->Offset,\r
1116 HMainEditor.BufferImage->DiskImage->Size,\r
1117 HMainEditor.BufferImage->MemImage->Offset,\r
1118 HMainEditor.BufferImage->MemImage->Size,\r
1119 BufferType\r
1120 );\r
1121 if (EFI_ERROR (Status)) {\r
1122 return Status;\r
1123 }\r
1124\r
1125 MainTitleBarRefresh (\r
1126 HMainEditor.BufferImage->BufferType == FileTypeFileBuffer?HMainEditor.BufferImage->FileImage->FileName:HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Name:NULL,\r
1127 HMainEditor.BufferImage->BufferType,\r
1128 HMainEditor.BufferImage->FileImage->ReadOnly,\r
1129 FALSE,\r
1130 HMainEditor.ScreenSize.Column,\r
980d554e 1131 HMainEditor.ScreenSize.Row,\r
1132 HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Offset:HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Offset:0,\r
1133 HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Size :HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Size :0\r
632820d1 1134 );\r
1135 Done = TRUE;\r
1136 break;\r
1137\r
1138 case L'n':\r
1139 case L'N':\r
1140 //\r
1141 // the file won't be saved\r
1142 //\r
1143 Done = TRUE;\r
1144 break;\r
1145\r
1146 case L'c':\r
1147 case L'C':\r
1148 return EFI_SUCCESS;\r
1149 }\r
1150 }\r
1151 }\r
1152 //\r
1153 // get disk block device name\r
1154 //\r
1155 Status = InputBarSetPrompt (L"Block Device to Open: ");\r
1156 if (EFI_ERROR (Status)) {\r
1157 return Status;\r
1158 }\r
1159\r
1160 Status = InputBarSetStringSize (100);\r
1161 if (EFI_ERROR (Status)) {\r
1162 return Status;\r
1163 }\r
1164\r
1165 while (1) {\r
1166 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);\r
1167\r
1168 //\r
1169 // ESC pressed\r
1170 //\r
1171 if (Status == EFI_NOT_READY) {\r
1172\r
1173 return EFI_SUCCESS;\r
1174 }\r
1175 //\r
1176 // THE input string length should > 0\r
1177 //\r
1178 if (StrLen (InputBarGetString()) > 0) {\r
1179 break;\r
1180 }\r
1181 }\r
1182\r
1183 DeviceName = CatSPrint(NULL, L"%s", InputBarGetString());\r
1184 if (DeviceName == NULL) {\r
1185 return EFI_OUT_OF_RESOURCES;\r
1186 }\r
1187 //\r
1188 // get starting offset\r
1189 //\r
1190 Status = InputBarSetPrompt (L"First Block No.: ");\r
1191 if (EFI_ERROR (Status)) {\r
1192 return Status;\r
1193 }\r
1194\r
1195 Status = InputBarSetStringSize (16);\r
1196 if (EFI_ERROR (Status)) {\r
1197 return Status;\r
1198 }\r
1199\r
1200 while (1) {\r
1201 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);\r
1202\r
1203 //\r
1204 // ESC pressed\r
1205 //\r
1206 if (Status == EFI_NOT_READY) {\r
1207\r
1208 return EFI_SUCCESS;\r
1209 }\r
1210 //\r
1211 // THE input string length should > 0\r
1212 //\r
1213 if (StrLen (InputBarGetString()) > 0) {\r
1214 Status = ShellConvertStringToUint64 (InputBarGetString(), &Offset, TRUE, FALSE);\r
1215 if (EFI_ERROR (Status)) {\r
1216 continue;\r
1217 }\r
1218\r
1219 break;\r
1220 }\r
1221 }\r
1222 //\r
1223 // get Number of Blocks:\r
1224 //\r
1225 Status = InputBarSetPrompt (L"Number of Blocks: ");\r
1226 if (EFI_ERROR (Status)) {\r
1227 return Status;\r
1228 }\r
1229\r
1230 Status = InputBarSetStringSize (8);\r
1231 if (EFI_ERROR (Status)) {\r
1232 return Status;\r
1233 }\r
1234\r
1235 while (1) {\r
1236 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);\r
1237\r
1238 //\r
1239 // ESC pressed\r
1240 //\r
1241 if (Status == EFI_NOT_READY) {\r
1242\r
1243 return EFI_SUCCESS;\r
1244 }\r
1245 //\r
1246 // THE input string length should > 0\r
1247 //\r
1248 if (StrLen (InputBarGetString()) > 0) {\r
1249 Status = ShellConvertStringToUint64 (InputBarGetString(), &Size, TRUE, FALSE);\r
1250 if (EFI_ERROR (Status)) {\r
1251 continue;\r
1252 }\r
1253\r
1254 if (Size == 0) {\r
1255 continue;\r
1256 }\r
1257\r
1258 break;\r
1259 }\r
1260 }\r
1261\r
1262 Status = HBufferImageRead (\r
1263 NULL,\r
1264 DeviceName,\r
1265 (UINTN)Offset,\r
1266 (UINTN)Size,\r
1267 0,\r
1268 0,\r
1269 FileTypeDiskBuffer,\r
1270 FALSE\r
1271 );\r
1272\r
1273 if (EFI_ERROR (Status)) {\r
1274\r
1275 HBufferImageRead (\r
1276 HMainEditor.BufferImage->FileImage->FileName,\r
1277 HMainEditor.BufferImage->DiskImage->Name,\r
1278 HMainEditor.BufferImage->DiskImage->Offset,\r
1279 HMainEditor.BufferImage->DiskImage->Size,\r
1280 HMainEditor.BufferImage->MemImage->Offset,\r
1281 HMainEditor.BufferImage->MemImage->Size,\r
1282 BufferType,\r
1283 TRUE\r
1284 );\r
1285 return EFI_NOT_FOUND;\r
1286 }\r
1287\r
1288 return EFI_SUCCESS;\r
1289}\r
1290\r
a1d4bfcc 1291/**\r
1292 Load memory content to editor\r
1293\r
1294 @retval EFI_SUCCESS The operation was successful.\r
1295 @retval EFI_OUT_OF_RESOURCES A memory allocation occured.\r
1296 @retval EFI_LOAD_ERROR A load error occured.\r
1297 @retval EFI_NOT_FOUND The disk was not found.\r
1298**/\r
632820d1 1299EFI_STATUS\r
1300HMainCommandOpenMemory (\r
1301 VOID\r
1302 )\r
632820d1 1303{\r
1304 UINT64 Size;\r
1305 UINT64 Offset;\r
1306 EFI_STATUS Status;\r
1307 BOOLEAN Done;\r
1308 EDIT_FILE_TYPE BufferType;\r
1309\r
1310 //\r
1311 // variable initialization\r
1312 //\r
1313 Size = 0;\r
1314 Offset = 0;\r
1315 BufferType = HMainEditor.BufferImage->BufferType;\r
1316\r
1317 //\r
1318 // if current buffer is modified, so you need to choose\r
1319 // whether to save it first.\r
1320 //\r
1321 if (HMainEditor.BufferImage->Modified) {\r
1322\r
1323 Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? ");\r
1324 if (EFI_ERROR (Status)) {\r
1325 return Status;\r
1326 }\r
1327 //\r
1328 // the answer is just one character\r
1329 //\r
1330 Status = InputBarSetStringSize (1);\r
1331 if (EFI_ERROR (Status)) {\r
1332 return Status;\r
1333 }\r
1334 //\r
1335 // loop for user's answer\r
1336 // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'\r
1337 //\r
1338 Done = FALSE;\r
1339 while (!Done) {\r
1340 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);\r
1341\r
1342 //\r
1343 // ESC pressed\r
1344 //\r
1345 if (Status == EFI_NOT_READY) {\r
1346 return EFI_SUCCESS;\r
1347 }\r
1348\r
1349 switch (InputBarGetString()[0]) {\r
1350 case L'y':\r
1351 case L'Y':\r
1352 //\r
1353 // want to save this buffer first\r
1354 //\r
1355 Status = HBufferImageSave (\r
1356 HMainEditor.BufferImage->FileImage->FileName,\r
1357 HMainEditor.BufferImage->DiskImage->Name,\r
1358 HMainEditor.BufferImage->DiskImage->Offset,\r
1359 HMainEditor.BufferImage->DiskImage->Size,\r
1360 HMainEditor.BufferImage->MemImage->Offset,\r
1361 HMainEditor.BufferImage->MemImage->Size,\r
1362 BufferType\r
1363 );\r
1364 if (EFI_ERROR (Status)) {\r
1365 return Status;\r
1366 }\r
1367\r
1368 MainTitleBarRefresh (\r
1369 HMainEditor.BufferImage->BufferType == FileTypeFileBuffer?HMainEditor.BufferImage->FileImage->FileName:HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Name:NULL,\r
1370 HMainEditor.BufferImage->BufferType,\r
1371 HMainEditor.BufferImage->FileImage->ReadOnly,\r
1372 FALSE,\r
1373 HMainEditor.ScreenSize.Column,\r
980d554e 1374 HMainEditor.ScreenSize.Row,\r
1375 HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Offset:HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Offset:0,\r
1376 HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Size :HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Size :0\r
632820d1 1377 );\r
1378 Done = TRUE;\r
1379 break;\r
1380\r
1381 case L'n':\r
1382 case L'N':\r
1383 //\r
1384 // the file won't be saved\r
1385 //\r
1386 Done = TRUE;\r
1387 break;\r
1388\r
1389 case L'c':\r
1390 case L'C':\r
1391 return EFI_SUCCESS;\r
1392 }\r
1393 }\r
1394 }\r
1395 //\r
1396 // get starting offset\r
1397 //\r
1398 Status = InputBarSetPrompt (L"Starting Offset: ");\r
1399 if (EFI_ERROR (Status)) {\r
1400 return Status;\r
1401 }\r
1402\r
1403 Status = InputBarSetStringSize (8);\r
1404 if (EFI_ERROR (Status)) {\r
1405 return Status;\r
1406 }\r
1407\r
1408 while (1) {\r
1409 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);\r
1410\r
1411 //\r
1412 // ESC pressed\r
1413 //\r
1414 if (Status == EFI_NOT_READY) {\r
1415\r
1416 return EFI_SUCCESS;\r
1417 }\r
1418 //\r
1419 // THE input string length should > 0\r
1420 //\r
1421 if (StrLen (InputBarGetString()) > 0) {\r
1422 Status = ShellConvertStringToUint64 (InputBarGetString(), &Offset, TRUE, FALSE);\r
1423 if (EFI_ERROR (Status)) {\r
1424 continue;\r
1425 }\r
1426\r
1427 break;\r
1428 }\r
1429 }\r
1430 //\r
1431 // get Number of Blocks:\r
1432 //\r
1433 Status = InputBarSetPrompt (L"Buffer Size: ");\r
1434 if (EFI_ERROR (Status)) {\r
1435 return Status;\r
1436 }\r
1437\r
1438 Status = InputBarSetStringSize (8);\r
1439 if (EFI_ERROR (Status)) {\r
1440 return Status;\r
1441 }\r
1442\r
1443 while (1) {\r
1444 Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);\r
1445\r
1446 //\r
1447 // ESC pressed\r
1448 //\r
1449 if (Status == EFI_NOT_READY) {\r
1450\r
1451 return EFI_SUCCESS;\r
1452 }\r
1453 //\r
1454 // THE input string length should > 0\r
1455 //\r
1456 if (StrLen (InputBarGetString()) > 0) {\r
1457 Status = ShellConvertStringToUint64 (InputBarGetString(), &Size, TRUE, FALSE);\r
1458 if (EFI_ERROR (Status)) {\r
1459 continue;\r
1460 }\r
1461\r
1462 if (Size == 0) {\r
1463 continue;\r
1464 }\r
1465\r
1466 break;\r
1467 }\r
1468 }\r
1469\r
1470 if ((Offset + Size - 1)> 0xffffffff) {\r
1471 StatusBarSetStatusString (L"Invalid parameter");\r
1472 return EFI_LOAD_ERROR;\r
1473 }\r
1474\r
1475 Status = HBufferImageRead (\r
1476 NULL,\r
1477 NULL,\r
1478 0,\r
1479 0,\r
1480 (UINTN)Offset,\r
1481 (UINTN)Size,\r
1482 FileTypeMemBuffer,\r
1483 FALSE\r
1484 );\r
1485\r
1486 if (EFI_ERROR (Status)) {\r
1487 StatusBarSetStatusString (L"Read Device Error!");\r
1488 HBufferImageRead (\r
1489 HMainEditor.BufferImage->FileImage->FileName,\r
1490 HMainEditor.BufferImage->DiskImage->Name,\r
1491 HMainEditor.BufferImage->DiskImage->Offset,\r
1492 HMainEditor.BufferImage->DiskImage->Size,\r
1493 HMainEditor.BufferImage->MemImage->Offset,\r
1494 HMainEditor.BufferImage->MemImage->Size,\r
1495 BufferType,\r
1496 TRUE\r
1497 );\r
1498 return EFI_NOT_FOUND;\r
1499 }\r
1500 return EFI_SUCCESS;\r
1501\r
1502}\r
1503\r
5a2beb74 1504MENU_ITEM_FUNCTION HexMainControlBasedMenuFunctions[] = {\r
1505 NULL,\r
1506 NULL, /* Ctrl - A */\r
1507 NULL, /* Ctrl - B */\r
1508 NULL, /* Ctrl - C */\r
1e2b43f1 1509 HMainCommandSelectEnd, /* Ctrl - D */\r
5a2beb74 1510 HMainCommandDisplayHelp, /* Ctrl - E */\r
1511 NULL, /* Ctrl - F */\r
1e2b43f1 1512 HMainCommandGoToOffset, /* Ctrl - G */\r
5a2beb74 1513 NULL, /* Ctrl - H */\r
1e2b43f1 1514 HMainCommandOpenDisk, /* Ctrl - I */\r
5a2beb74 1515 NULL, /* Ctrl - J */\r
1516 NULL, /* Ctrl - K */\r
1517 NULL, /* Ctrl - L */\r
1e2b43f1 1518 HMainCommandOpenMemory, /* Ctrl - M */\r
5a2beb74 1519 NULL, /* Ctrl - N */\r
1e2b43f1 1520 HMainCommandOpenFile, /* Ctrl - O */\r
5a2beb74 1521 NULL, /* Ctrl - P */\r
1e2b43f1 1522 HMainCommandExit, /* Ctrl - Q */\r
5a2beb74 1523 NULL, /* Ctrl - R */\r
1e2b43f1 1524 HMainCommandSaveBuffer, /* Ctrl - S */\r
1525 HMainCommandSelectStart, /* Ctrl - T */\r
5a2beb74 1526 NULL, /* Ctrl - U */\r
1e2b43f1 1527 HMainCommandPaste, /* Ctrl - V */\r
5a2beb74 1528 NULL, /* Ctrl - W */\r
1e2b43f1 1529 HMainCommandCut, /* Ctrl - X */\r
5a2beb74 1530 NULL, /* Ctrl - Y */\r
1531 NULL, /* Ctrl - Z */\r
1532};\r
1533\r
632820d1 1534CONST EDITOR_MENU_ITEM HexEditorMenuItems[] = {\r
1535 {\r
1536 STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_GO_TO_OFFSET),\r
1537 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F1),\r
1538 HMainCommandGoToOffset\r
1539 },\r
1540 {\r
1541 STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_SAVE_BUFFER),\r
1542 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F2),\r
1543 HMainCommandSaveBuffer\r
1544 },\r
1545 {\r
1546 STRING_TOKEN(STR_EDIT_LIBMENUBAR_EXIT),\r
1547 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F3),\r
1548 HMainCommandExit\r
1549 },\r
1550\r
1551 {\r
1552 STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_SELECT_START),\r
1553 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F4),\r
1554 HMainCommandSelectStart\r
1555 },\r
1556 {\r
1557 STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_SELECT_END),\r
1558 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F5),\r
1559 HMainCommandSelectEnd\r
1560 },\r
1561 {\r
1562 STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_CUT),\r
1563 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F6),\r
1564 HMainCommandCut\r
1565 },\r
1566 {\r
1567 STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_PASTE),\r
1568 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F7),\r
1569 HMainCommandPaste\r
1570 },\r
1571\r
1572 {\r
1573 STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_OPEN_FILE),\r
1574 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F8),\r
1575 HMainCommandOpenFile\r
1576 },\r
1577 {\r
1578 STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_OPEN_DISK),\r
1579 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F9),\r
1580 HMainCommandOpenDisk\r
1581 },\r
1582 {\r
1583 STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_OPEN_MEMORY),\r
1584 STRING_TOKEN(STR_EDIT_LIBMENUBAR_F10),\r
1585 HMainCommandOpenMemory\r
1586 },\r
1587\r
1588 {\r
1589 0,\r
1590 0,\r
1591 NULL\r
1592 }\r
1593};\r
1594\r
a1d4bfcc 1595/**\r
1596 Init function for MainEditor\r
632820d1 1597\r
a1d4bfcc 1598 @retval EFI_SUCCESS The operation was successful.\r
1599 @retval EFI_LOAD_ERROR A load error occured.\r
1600**/\r
632820d1 1601EFI_STATUS\r
1602HMainEditorInit (\r
1603 VOID\r
1604 )\r
632820d1 1605{\r
1606 EFI_STATUS Status;\r
1607 EFI_HANDLE *HandleBuffer;\r
1608 UINTN HandleCount;\r
1609 UINTN Index;\r
1610\r
1611 //\r
1612 // basic initialization\r
1613 //\r
1614 CopyMem (&HMainEditor, &HMainEditorConst, sizeof (HMainEditor));\r
1615\r
1616 //\r
1617 // set screen attributes\r
1618 //\r
1619 HMainEditor.ColorAttributes.Colors.Foreground = gST->ConOut->Mode->Attribute & 0x000000ff;\r
1620\r
1621 HMainEditor.ColorAttributes.Colors.Background = (UINT8) (gST->ConOut->Mode->Attribute >> 4);\r
1622\r
1623 HOriginalColors = HMainEditor.ColorAttributes.Colors;\r
1624\r
1625 HOriginalMode = gST->ConOut->Mode->Mode;\r
1626\r
1627 //\r
1628 // query screen size\r
1629 //\r
1630 gST->ConOut->QueryMode (\r
1631 gST->ConOut,\r
1632 gST->ConOut->Mode->Mode,\r
1633 &(HMainEditor.ScreenSize.Column),\r
1634 &(HMainEditor.ScreenSize.Row)\r
1635 );\r
1636\r
1637 //\r
1638 // Find mouse in System Table ConsoleInHandle\r
1639 //\r
1640 Status = gBS->HandleProtocol (\r
1641 gST->ConIn,\r
1642 &gEfiSimplePointerProtocolGuid,\r
1643 (VOID**)&HMainEditor.MouseInterface\r
1644 );\r
1645 if (EFI_ERROR (Status)) {\r
1646 //\r
1647 // If there is no Simple Pointer Protocol on System Table\r
1648 //\r
1649 HandleBuffer = NULL;\r
1650 HMainEditor.MouseInterface = NULL;\r
1651 Status = gBS->LocateHandleBuffer (\r
1652 ByProtocol,\r
1653 &gEfiSimplePointerProtocolGuid,\r
1654 NULL,\r
1655 &HandleCount,\r
1656 &HandleBuffer\r
1657 );\r
1658 if (!EFI_ERROR (Status) && HandleCount > 0) {\r
1659 //\r
1660 // Try to find the first available mouse device\r
1661 //\r
1662 for (Index = 0; Index < HandleCount; Index++) {\r
1663 Status = gBS->HandleProtocol (\r
1664 HandleBuffer[Index],\r
1665 &gEfiSimplePointerProtocolGuid,\r
1666 (VOID**)&HMainEditor.MouseInterface\r
1667 );\r
1668 if (!EFI_ERROR (Status)) {\r
1669 break;\r
1670 }\r
1671 }\r
1672 }\r
1673 if (HandleBuffer != NULL) {\r
1674 FreePool (HandleBuffer);\r
1675 }\r
1676 }\r
1677\r
1678 if (!EFI_ERROR (Status) && HMainEditor.MouseInterface != NULL) {\r
1679 HMainEditor.MouseAccumulatorX = 0;\r
1680 HMainEditor.MouseAccumulatorY = 0;\r
1681 HMainEditor.MouseSupported = TRUE;\r
1682 }\r
1683\r
1684 //\r
1685 // below will call the five components' init function\r
1686 //\r
caa6c0cc 1687 Status = MainTitleBarInit (L"UEFI HEXEDIT");\r
632820d1 1688 if (EFI_ERROR (Status)) {\r
1689 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_TITLE), gShellDebug1HiiHandle);\r
1690 return EFI_LOAD_ERROR;\r
1691 }\r
1692\r
5a2beb74 1693 Status = ControlHotKeyInit (HexMainControlBasedMenuFunctions);\r
1694 if (EFI_ERROR (Status)) {\r
1695 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_MAINMENU), gShellDebug1HiiHandle);\r
1696 return EFI_LOAD_ERROR;\r
1697 }\r
632820d1 1698 Status = MenuBarInit (HexEditorMenuItems);\r
1699 if (EFI_ERROR (Status)) {\r
1700 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_MAINMENU), gShellDebug1HiiHandle);\r
1701 return EFI_LOAD_ERROR;\r
1702 }\r
1703\r
1704 Status = StatusBarInit ();\r
1705 if (EFI_ERROR (Status)) {\r
1706 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_STATUS), gShellDebug1HiiHandle);\r
1707 return EFI_LOAD_ERROR;\r
1708 }\r
1709\r
1710 InputBarInit ();\r
1711\r
1712 Status = HBufferImageInit ();\r
1713 if (EFI_ERROR (Status)) {\r
1714 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_BUFFERIMAGE), gShellDebug1HiiHandle);\r
1715 return EFI_LOAD_ERROR;\r
1716 }\r
1717\r
1718 Status = HClipBoardInit ();\r
1719 if (EFI_ERROR (Status)) {\r
1720 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_CLIPBOARD), gShellDebug1HiiHandle);\r
1721 return EFI_LOAD_ERROR;\r
1722 }\r
1723 //\r
1724 // clear whole screen and enable cursor\r
1725 //\r
1726 gST->ConOut->ClearScreen (gST->ConOut);\r
1727 gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
1728\r
1729 //\r
1730 // initialize EditorFirst and EditorExit\r
1731 //\r
1732 HEditorFirst = TRUE;\r
1733 HEditorExit = FALSE;\r
1734 HEditorMouseAction = FALSE;\r
1735\r
1736 return EFI_SUCCESS;\r
1737}\r
1738\r
a1d4bfcc 1739/**\r
1740 Cleanup function for MainEditor.\r
1741\r
1742 @retval EFI_SUCCESS The operation was successful.\r
1743 @retval EFI_LOAD_ERROR A load error occured.\r
1744**/\r
632820d1 1745EFI_STATUS\r
1746HMainEditorCleanup (\r
1747 VOID\r
1748 )\r
632820d1 1749{\r
1750 EFI_STATUS Status;\r
1751\r
1752 //\r
1753 // call the five components' cleanup function\r
1754 //\r
1755 MainTitleBarCleanup ();\r
1756\r
1757 MenuBarCleanup ();\r
1758\r
1759 StatusBarCleanup ();\r
1760 \r
1761 InputBarCleanup ();\r
1762 \r
1763 Status = HBufferImageCleanup ();\r
1764 if (EFI_ERROR (Status)) {\r
1765 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_BUFFERIMAGE_CLEAN), gShellDebug1HiiHandle);\r
1766 }\r
1767\r
1768 Status = HClipBoardCleanup ();\r
1769 if (EFI_ERROR (Status)) {\r
1770 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_CLIPBOARD_CLEAN), gShellDebug1HiiHandle);\r
1771 }\r
1772 //\r
1773 // restore old mode\r
1774 //\r
1775 if (HOriginalMode != gST->ConOut->Mode->Mode) {\r
1776 gST->ConOut->SetMode (gST->ConOut, HOriginalMode);\r
1777 }\r
1778\r
1779 gST->ConOut->SetAttribute (\r
1780 gST->ConOut,\r
1781 EFI_TEXT_ATTR (HOriginalColors.Foreground, HOriginalColors.Background)\r
1782 );\r
1783 gST->ConOut->ClearScreen (gST->ConOut);\r
1784\r
1785 return EFI_SUCCESS;\r
1786}\r
1787\r
a1d4bfcc 1788/**\r
1789 Refresh function for MainEditor.\r
1790\r
1791 @retval EFI_SUCCESS The operation was successful.\r
1792**/\r
632820d1 1793EFI_STATUS\r
1794HMainEditorRefresh (\r
1795 VOID\r
1796 )\r
632820d1 1797{\r
980d554e 1798 BOOLEAN NameChange;\r
1799 BOOLEAN ReadChange;\r
1800\r
1801 NameChange = FALSE;\r
1802 ReadChange = FALSE;\r
1803\r
6878e7a7 1804 if (HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer) {\r
1805 if (HMainEditor.BufferImage->DiskImage != NULL &&\r
1806 HBufferImageBackupVar.DiskImage != NULL &&\r
1807 (HMainEditor.BufferImage->DiskImage->Offset != HBufferImageBackupVar.DiskImage->Offset || \r
1808 HMainEditor.BufferImage->DiskImage->Size != HBufferImageBackupVar.DiskImage->Size) ){\r
1809 NameChange = TRUE;\r
1810 }\r
1811 } else if (HMainEditor.BufferImage->BufferType == FileTypeMemBuffer) {\r
1812 if (HMainEditor.BufferImage->MemImage != NULL &&\r
1813 HBufferImageBackupVar.MemImage != NULL &&\r
1814 (HMainEditor.BufferImage->MemImage->Offset != HBufferImageBackupVar.MemImage->Offset || \r
1815 HMainEditor.BufferImage->MemImage->Size != HBufferImageBackupVar.MemImage->Size) ){\r
1816 NameChange = TRUE;\r
1817 }\r
1818 } else if (HMainEditor.BufferImage->BufferType == FileTypeFileBuffer) {\r
1819 if ( HMainEditor.BufferImage->FileImage != NULL && \r
1820 HMainEditor.BufferImage->FileImage->FileName != NULL && \r
1821 HBufferImageBackupVar.FileImage != NULL && \r
1822 HBufferImageBackupVar.FileImage->FileName != NULL && \r
1823 StrCmp (HMainEditor.BufferImage->FileImage->FileName, HBufferImageBackupVar.FileImage->FileName) != 0 ) {\r
1824 NameChange = TRUE;\r
1825 }\r
980d554e 1826 }\r
1827 if ( HMainEditor.BufferImage->FileImage != NULL && \r
1828 HBufferImageBackupVar.FileImage != NULL && \r
1829 HMainEditor.BufferImage->FileImage->ReadOnly != HBufferImageBackupVar.FileImage->ReadOnly ) {\r
1830 ReadChange = TRUE;\r
1831 }\r
1832\r
632820d1 1833 //\r
1834 // to aVOID screen flicker\r
1835 // the stall value is from experience\r
1836 //\r
1837 gBS->Stall (50);\r
1838\r
1839 //\r
980d554e 1840 // call the components refresh function\r
632820d1 1841 //\r
980d554e 1842 if (HEditorFirst \r
1843 || NameChange\r
1844 || HMainEditor.BufferImage->BufferType != HBufferImageBackupVar.BufferType \r
1845 || HBufferImageBackupVar.Modified != HMainEditor.BufferImage->Modified \r
1846 || ReadChange ) {\r
1847\r
1848 MainTitleBarRefresh (\r
ae724571 1849 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 1850 HMainEditor.BufferImage->BufferType,\r
ae724571 1851 (BOOLEAN)(HMainEditor.BufferImage->FileImage!=NULL?HMainEditor.BufferImage->FileImage->ReadOnly:FALSE),\r
980d554e 1852 HMainEditor.BufferImage->Modified,\r
1853 HMainEditor.ScreenSize.Column,\r
1854 HMainEditor.ScreenSize.Row,\r
a1d4bfcc 1855 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
1856 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 1857 );\r
1858 HBufferImageRefresh ();\r
1859 }\r
1860 if (HEditorFirst\r
1861 || HBufferImageBackupVar.DisplayPosition.Row != HMainEditor.BufferImage->DisplayPosition.Row \r
1862 || HBufferImageBackupVar.DisplayPosition.Column != HMainEditor.BufferImage->DisplayPosition.Column \r
1863 || StatusBarGetRefresh()) {\r
1864\r
1865 StatusBarRefresh (\r
1866 HEditorFirst,\r
1867 HMainEditor.ScreenSize.Row,\r
1868 HMainEditor.ScreenSize.Column,\r
6878e7a7 1869 (UINTN)(-1),\r
1870 (UINTN)(-1),\r
1871 FALSE\r
980d554e 1872 );\r
1873 HBufferImageRefresh ();\r
1874 }\r
1875\r
1876 if (HEditorFirst) {\r
980d554e 1877 HBufferImageRefresh ();\r
1878 }\r
632820d1 1879\r
1880 //\r
1881 // EditorFirst is now set to FALSE\r
1882 //\r
1883 HEditorFirst = FALSE;\r
1884\r
1885 return EFI_SUCCESS;\r
1886}\r
1887\r
a1d4bfcc 1888/**\r
1889 Handle the mouse input.\r
1890\r
1891 @param[in] MouseState The current mouse state.\r
1892 @param[out] BeforeLeftButtonDown helps with selections.\r
1893\r
1894 @retval EFI_SUCCESS The operation was successful.\r
1895 @retval EFI_OUT_OF_RESOURCES A memory allocation occured.\r
1896 @retval EFI_LOAD_ERROR A load error occured.\r
1897 @retval EFI_NOT_FOUND The disk was not found.\r
1898**/\r
632820d1 1899EFI_STATUS\r
1900HMainEditorHandleMouseInput (\r
1901 IN EFI_SIMPLE_POINTER_STATE MouseState,\r
1902 OUT BOOLEAN *BeforeLeftButtonDown\r
1903 )\r
1904{\r
1905\r
1906 INT32 TextX;\r
1907 INT32 TextY;\r
1908 UINTN FRow;\r
1909 UINTN FCol;\r
1910 BOOLEAN HighBits;\r
1911 LIST_ENTRY *Link;\r
1912 HEFI_EDITOR_LINE *Line;\r
1913 UINTN Index;\r
1914 BOOLEAN Action;\r
1915\r
1916 Action = FALSE;\r
1917\r
1918 //\r
1919 // have mouse movement\r
1920 //\r
1921 if (MouseState.RelativeMovementX || MouseState.RelativeMovementY) {\r
1922 //\r
1923 // handle\r
1924 //\r
1925 TextX = HGetTextX (MouseState.RelativeMovementX);\r
1926 TextY = HGetTextY (MouseState.RelativeMovementY);\r
1927\r
1928 HBufferImageAdjustMousePosition (TextX, TextY);\r
1929\r
1930 Action = TRUE;\r
1931\r
1932 }\r
1933\r
1934 if (MouseState.LeftButton) {\r
1935 HighBits = HBufferImageIsAtHighBits (\r
1936 HMainEditor.BufferImage->MousePosition.Column,\r
1937 &FCol\r
1938 );\r
1939\r
1940 //\r
1941 // not at an movable place\r
1942 //\r
1943 if (FCol == 0) {\r
1944 //\r
1945 // now just move mouse pointer to legal position\r
1946 //\r
1947 //\r
1948 // move mouse position to legal position\r
1949 //\r
1950 HMainEditor.BufferImage->MousePosition.Column -= 10;\r
1951 if (HMainEditor.BufferImage->MousePosition.Column > 24) {\r
1952 HMainEditor.BufferImage->MousePosition.Column--;\r
1953 FCol = HMainEditor.BufferImage->MousePosition.Column / 3 + 1 + 1;\r
1954 } else {\r
1955 if (HMainEditor.BufferImage->MousePosition.Column < 24) {\r
1956 FCol = HMainEditor.BufferImage->MousePosition.Column / 3 + 1 + 1;\r
1957 } else {\r
1958 //\r
1959 // == 24\r
1960 //\r
1961 FCol = 9;\r
1962 }\r
1963 }\r
1964\r
1965 HighBits = TRUE;\r
1966\r
1967 }\r
1968\r
1969 FRow = HMainEditor.BufferImage->BufferPosition.Row +\r
1970 HMainEditor.BufferImage->MousePosition.Row -\r
1971 HMainEditor.BufferImage->DisplayPosition.Row;\r
1972\r
1973 if (HMainEditor.BufferImage->NumLines < FRow) {\r
1974 //\r
1975 // dragging\r
1976 //\r
1977 //\r
1978 // now just move mouse pointer to legal position\r
1979 //\r
1980 FRow = HMainEditor.BufferImage->NumLines;\r
1981 HighBits = TRUE;\r
1982 }\r
1983\r
1984 Link = HMainEditor.BufferImage->ListHead->ForwardLink;\r
1985 for (Index = 0; Index < FRow - 1; Index++) {\r
1986 Link = Link->ForwardLink;\r
1987 }\r
1988\r
1989 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
1990\r
1991 //\r
1992 // dragging\r
1993 //\r
1994 //\r
1995 // now just move mouse pointer to legal position\r
1996 //\r
1997 if (FCol > Line->Size) {\r
1998 if (*BeforeLeftButtonDown) {\r
1999 HighBits = FALSE;\r
2000\r
2001 if (Line->Size == 0) {\r
2002 if (FRow > 1) {\r
2003 FRow--;\r
2004 FCol = 16;\r
2005 } else {\r
2006 FRow = 1;\r
2007 FCol = 1;\r
2008 }\r
2009\r
2010 } else {\r
2011 FCol = Line->Size;\r
2012 }\r
2013 } else {\r
2014 FCol = Line->Size + 1;\r
2015 HighBits = TRUE;\r
2016 }\r
2017 }\r
2018\r
2019 HBufferImageMovePosition (FRow, FCol, HighBits);\r
2020\r
2021 HMainEditor.BufferImage->MousePosition.Row = HMainEditor.BufferImage->DisplayPosition.Row;\r
2022\r
2023 HMainEditor.BufferImage->MousePosition.Column = HMainEditor.BufferImage->DisplayPosition.Column;\r
2024\r
2025 *BeforeLeftButtonDown = TRUE;\r
2026\r
2027 Action = TRUE;\r
2028 } else {\r
2029 //\r
2030 // else of if LButton\r
2031 //\r
2032 // release LButton\r
2033 //\r
a1d4bfcc 2034 if (*BeforeLeftButtonDown) {\r
632820d1 2035 Action = TRUE;\r
2036 }\r
2037 //\r
2038 // mouse up\r
2039 //\r
2040 *BeforeLeftButtonDown = FALSE;\r
2041 }\r
2042\r
2043 if (Action) {\r
2044 return EFI_SUCCESS;\r
2045 }\r
2046\r
2047 return EFI_NOT_FOUND;\r
2048}\r
2049\r
a1d4bfcc 2050/**\r
2051 Handle user key input. will route it to other components handle function.\r
2052\r
2053 @retval EFI_SUCCESS The operation was successful.\r
2054 @retval EFI_OUT_OF_RESOURCES A memory allocation occured.\r
2055 @retval EFI_LOAD_ERROR A load error occured.\r
2056**/\r
632820d1 2057EFI_STATUS\r
2058HMainEditorKeyInput (\r
2059 VOID\r
2060 )\r
632820d1 2061{\r
2062 EFI_INPUT_KEY Key;\r
2063 EFI_STATUS Status;\r
2064 EFI_SIMPLE_POINTER_STATE MouseState;\r
2065 BOOLEAN LengthChange;\r
2066 UINTN Size;\r
2067 UINTN OldSize;\r
2068 BOOLEAN BeforeMouseIsDown;\r
2069 BOOLEAN MouseIsDown;\r
2070 BOOLEAN FirstDown;\r
2071 BOOLEAN MouseDrag;\r
2072 UINTN FRow;\r
2073 UINTN FCol;\r
2074 UINTN SelectStartBackup;\r
2075 UINTN SelectEndBackup;\r
2076\r
2077 //\r
2078 // variable initialization\r
2079 //\r
2080 OldSize = 0;\r
2081 FRow = 0;\r
2082 FCol = 0;\r
2083 LengthChange = FALSE;\r
2084\r
2085 MouseIsDown = FALSE;\r
2086 FirstDown = FALSE;\r
2087 MouseDrag = FALSE;\r
2088\r
2089 do {\r
2090\r
2091 Status = EFI_SUCCESS;\r
2092\r
2093 HEditorMouseAction = FALSE;\r
2094\r
2095 //\r
2096 // backup some key elements, so that can aVOID some refresh work\r
2097 //\r
2098 HMainEditorBackup ();\r
2099\r
2100 //\r
2101 // wait for user key input\r
2102 //\r
2103 //\r
2104 // change priority of checking mouse/keyboard activity dynamically\r
2105 // so prevent starvation of keyboard.\r
2106 // if last time, mouse moves then this time check keyboard\r
2107 //\r
2108 if (HMainEditor.MouseSupported) {\r
2109 Status = HMainEditor.MouseInterface->GetState (\r
2110 HMainEditor.MouseInterface,\r
2111 &MouseState\r
2112 );\r
2113 if (!EFI_ERROR (Status)) {\r
2114\r
2115 BeforeMouseIsDown = MouseIsDown;\r
2116\r
2117 Status = HMainEditorHandleMouseInput (MouseState, &MouseIsDown);\r
2118\r
2119 if (!EFI_ERROR (Status)) {\r
a1d4bfcc 2120 if (!BeforeMouseIsDown) {\r
632820d1 2121 //\r
2122 // mouse down\r
2123 //\r
a1d4bfcc 2124 if (MouseIsDown) {\r
632820d1 2125 FRow = HBufferImage.BufferPosition.Row;\r
2126 FCol = HBufferImage.BufferPosition.Column;\r
2127 SelectStartBackup = HMainEditor.SelectStart;\r
2128 SelectEndBackup = HMainEditor.SelectEnd;\r
2129\r
2130 FirstDown = TRUE;\r
2131 }\r
2132 } else {\r
2133\r
2134 SelectStartBackup = HMainEditor.SelectStart;\r
2135 SelectEndBackup = HMainEditor.SelectEnd;\r
2136\r
2137 //\r
2138 // begin to drag\r
2139 //\r
a1d4bfcc 2140 if (MouseIsDown) {\r
2141 if (FirstDown) {\r
632820d1 2142 if (MouseState.RelativeMovementX || MouseState.RelativeMovementY) {\r
2143 HMainEditor.SelectStart = 0;\r
2144 HMainEditor.SelectEnd = 0;\r
2145 HMainEditor.SelectStart = (FRow - 1) * 0x10 + FCol;\r
2146\r
2147 MouseDrag = TRUE;\r
2148 FirstDown = FALSE;\r
2149 }\r
2150 } else {\r
2151 if ((\r
2152 (HBufferImage.BufferPosition.Row - 1) *\r
2153 0x10 +\r
2154 HBufferImage.BufferPosition.Column\r
2155 ) >= HMainEditor.SelectStart\r
2156 ) {\r
2157 HMainEditor.SelectEnd = (HBufferImage.BufferPosition.Row - 1) *\r
2158 0x10 +\r
2159 HBufferImage.BufferPosition.Column;\r
2160 } else {\r
2161 HMainEditor.SelectEnd = 0;\r
2162 }\r
2163 }\r
2164 //\r
2165 // end of if RelativeX/Y\r
2166 //\r
2167 } else {\r
2168 //\r
2169 // mouse is up\r
2170 //\r
2171 if (MouseDrag) {\r
2172 if (HBufferImageGetTotalSize () == 0) {\r
2173 HMainEditor.SelectStart = 0;\r
2174 HMainEditor.SelectEnd = 0;\r
2175 FirstDown = FALSE;\r
2176 MouseDrag = FALSE;\r
2177 }\r
2178\r
2179 if ((\r
2180 (HBufferImage.BufferPosition.Row - 1) *\r
2181 0x10 +\r
2182 HBufferImage.BufferPosition.Column\r
2183 ) >= HMainEditor.SelectStart\r
2184 ) {\r
2185 HMainEditor.SelectEnd = (HBufferImage.BufferPosition.Row - 1) *\r
2186 0x10 +\r
2187 HBufferImage.BufferPosition.Column;\r
2188 } else {\r
2189 HMainEditor.SelectEnd = 0;\r
2190 }\r
2191\r
2192 if (HMainEditor.SelectEnd == 0) {\r
2193 HMainEditor.SelectStart = 0;\r
2194 }\r
2195 }\r
2196\r
2197 FirstDown = FALSE;\r
2198 MouseDrag = FALSE;\r
2199 }\r
2200\r
2201 if (SelectStartBackup != HMainEditor.SelectStart || SelectEndBackup != HMainEditor.SelectEnd) {\r
2202 if ((SelectStartBackup - 1) / 0x10 != (HMainEditor.SelectStart - 1) / 0x10) {\r
2203 HBufferImageNeedRefresh = TRUE;\r
2204 } else {\r
2205 if ((SelectEndBackup - 1) / 0x10 != (HMainEditor.SelectEnd - 1) / 0x10) {\r
2206 HBufferImageNeedRefresh = TRUE;\r
2207 } else {\r
2208 HBufferImageOnlyLineNeedRefresh = TRUE;\r
2209 }\r
2210 }\r
2211 }\r
2212 }\r
2213\r
2214 HEditorMouseAction = TRUE;\r
2215 HBufferImageMouseNeedRefresh = TRUE;\r
2216\r
2217 } else if (Status == EFI_LOAD_ERROR) {\r
2218 StatusBarSetStatusString (L"Invalid Mouse Movement ");\r
2219 }\r
2220 }\r
2221 }\r
2222\r
2223 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
2224 if (!EFI_ERROR (Status)) {\r
2225 //\r
2226 // dispatch to different components' key handling function\r
2227 // so not everywhere has to set this variable\r
2228 //\r
2229 HBufferImageMouseNeedRefresh = TRUE;\r
2230\r
2231 //\r
2232 // clear previous status string\r
2233 //\r
2234 StatusBarSetRefresh();\r
5a2beb74 2235 if (EFI_SUCCESS == MenuBarDispatchControlHotKey(&Key)) {\r
2236 Status = EFI_SUCCESS;\r
2237 } else if (Key.ScanCode == SCAN_NULL) {\r
632820d1 2238 Status = HBufferImageHandleInput (&Key);\r
2239 } else if (((Key.ScanCode >= SCAN_UP) && (Key.ScanCode <= SCAN_PAGE_DOWN))) {\r
2240 Status = HBufferImageHandleInput (&Key);\r
2241 } else if (((Key.ScanCode >= SCAN_F1) && Key.ScanCode <= (SCAN_F12))) {\r
2242 Status = MenuBarDispatchFunctionKey (&Key);\r
2243 } else {\r
2244 StatusBarSetStatusString (L"Unknown Command");\r
2245\r
2246 HBufferImageMouseNeedRefresh = FALSE;\r
2247 }\r
2248\r
2249 if (Status != EFI_SUCCESS && Status != EFI_OUT_OF_RESOURCES) {\r
2250 //\r
2251 // not already has some error status\r
2252 //\r
2253 if (StrCmp (L"", StatusBarGetString()) == 0) {\r
2254 StatusBarSetStatusString (L"Disk Error. Try Again");\r
2255 }\r
2256 }\r
2257 }\r
2258 //\r
2259 // decide if has to set length warning\r
2260 //\r
2261 if (HBufferImage.BufferType != HBufferImageBackupVar.BufferType) {\r
2262 LengthChange = FALSE;\r
2263 } else {\r
2264 //\r
2265 // still the old buffer\r
2266 //\r
2267 if (HBufferImage.BufferType != FileTypeFileBuffer) {\r
2268 Size = HBufferImageGetTotalSize ();\r
2269\r
2270 switch (HBufferImage.BufferType) {\r
2271 case FileTypeDiskBuffer:\r
2272 OldSize = HBufferImage.DiskImage->Size * HBufferImage.DiskImage->BlockSize;\r
2273 break;\r
2274\r
2275 case FileTypeMemBuffer:\r
2276 OldSize = HBufferImage.MemImage->Size;\r
2277 break;\r
e0c2cc6f 2278 \r
2279 default:\r
2280 OldSize = 0;\r
2281 break;\r
632820d1 2282 }\r
2283\r
a1d4bfcc 2284 if (!LengthChange) {\r
632820d1 2285 if (OldSize != Size) {\r
2286 StatusBarSetStatusString (L"Disk/Mem Buffer Length should not be changed");\r
2287 }\r
2288 }\r
2289\r
2290 if (OldSize != Size) {\r
2291 LengthChange = TRUE;\r
2292 } else {\r
2293 LengthChange = FALSE;\r
2294 }\r
2295 }\r
2296 }\r
2297 //\r
2298 // after handling, refresh editor\r
2299 //\r
2300 HMainEditorRefresh ();\r
2301\r
2302 } while (Status != EFI_OUT_OF_RESOURCES && !HEditorExit);\r
2303\r
2304 return Status;\r
2305}\r
2306\r
2307/**\r
2308 Backup function for MainEditor.\r
2309**/\r
2310VOID\r
2311EFIAPI\r
2312HMainEditorBackup (\r
2313 VOID\r
2314 )\r
2315{\r
2316 HMainEditorBackupVar.SelectStart = HMainEditor.SelectStart;\r
2317 HMainEditorBackupVar.SelectEnd = HMainEditor.SelectEnd;\r
2318 HBufferImageBackup ();\r
2319}\r