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