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