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