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