1 /** @file
2   Main entry point of editor
3 
4   (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR>
5   Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved. <BR>
6   This program and the accompanying materials
7   are licensed and made available under the terms and conditions of the BSD License
8   which accompanies this distribution.  The full text of the license may be found at
9   http://opensource.org/licenses/bsd-license.php
10 
11   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 
14 **/
15 
16 #include "UefiShellDebug1CommandsLib.h"
17 #include "HexEditor.h"
18 
19 //
20 // Global Variables
21 //
22 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
23   {L"-f", TypeFlag},
24   {L"-d", TypeFlag},
25   {L"-m", TypeFlag},
26   {NULL, TypeMax}
27   };
28 
29 /**
30   Function for 'hexedit' command.
31 
32   @param[in] ImageHandle  Handle to the Image (NULL if Internal).
33   @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
34 **/
35 SHELL_STATUS
36 EFIAPI
ShellCommandRunHexEdit(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)37 ShellCommandRunHexEdit (
38   IN EFI_HANDLE        ImageHandle,
39   IN EFI_SYSTEM_TABLE  *SystemTable
40   )
41 {
42   EFI_STATUS              Status;
43   CHAR16                  *Buffer;
44   CHAR16                  *ProblemParam;
45   SHELL_STATUS            ShellStatus;
46   LIST_ENTRY              *Package;
47   CHAR16                  *NewName;
48   CONST CHAR16            *Name;
49   UINTN                   Offset;
50   UINTN                   Size;
51   EDIT_FILE_TYPE          WhatToDo;
52 
53   Buffer      = NULL;
54   ShellStatus = SHELL_SUCCESS;
55   NewName         = NULL;
56   Buffer      = NULL;
57   Name        = NULL;
58   Offset      = 0;
59   Size        = 0;
60   WhatToDo    = FileTypeNone;
61 
62   //
63   // initialize the shell lib (we must be in non-auto-init...)
64   //
65   Status = ShellInitialize();
66   ASSERT_EFI_ERROR(Status);
67 
68   Status = CommandInit();
69   ASSERT_EFI_ERROR(Status);
70 
71   //
72   // parse the command line
73   //
74   Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
75   if (EFI_ERROR(Status)) {
76     if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
77       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"hexedit", ProblemParam);
78       FreePool(ProblemParam);
79       ShellStatus = SHELL_INVALID_PARAMETER;
80     } else {
81       ASSERT(FALSE);
82     }
83   } else {
84     //
85     // Check for -d
86     //
87     if (ShellCommandLineGetFlag(Package, L"-d")){
88       if (ShellCommandLineGetCount(Package) < 4) {
89         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"hexedit");
90         ShellStatus = SHELL_INVALID_PARAMETER;
91       } else if (ShellCommandLineGetCount(Package) > 4) {
92         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"hexedit");
93         ShellStatus = SHELL_INVALID_PARAMETER;
94       } else {
95         WhatToDo = FileTypeDiskBuffer;
96         Name    = ShellCommandLineGetRawValue(Package, 1);
97         Offset  = ShellStrToUintn(ShellCommandLineGetRawValue(Package, 2));
98         Size    = ShellStrToUintn(ShellCommandLineGetRawValue(Package, 3));
99       }
100       if (Offset == (UINTN)-1 || Size == (UINTN)-1) {
101         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"hexedit", L"-d");
102         ShellStatus = SHELL_INVALID_PARAMETER;
103       }
104     }
105 
106     //
107     // check for -f
108     //
109     if (ShellCommandLineGetFlag(Package, L"-f") && (WhatToDo == FileTypeNone)){
110       if (ShellCommandLineGetCount(Package) < 2) {
111         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"hexedit");
112         ShellStatus = SHELL_INVALID_PARAMETER;
113       } else if (ShellCommandLineGetCount(Package) > 2) {
114         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"hexedit");
115         ShellStatus = SHELL_INVALID_PARAMETER;
116       } else {
117         Name      = ShellCommandLineGetRawValue(Package, 1);
118         if (Name == NULL || !IsValidFileName(Name)) {
119           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"hexedit", Name);
120           ShellStatus = SHELL_INVALID_PARAMETER;
121         } else {
122           WhatToDo  = FileTypeFileBuffer;
123         }
124       }
125     }
126 
127     //
128     // check for -m
129     //
130     if (ShellCommandLineGetFlag(Package, L"-m") && (WhatToDo == FileTypeNone)){
131       if (ShellCommandLineGetCount(Package) < 3) {
132         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"hexedit");
133         ShellStatus = SHELL_INVALID_PARAMETER;
134       } else if (ShellCommandLineGetCount(Package) > 3) {
135         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"hexedit");
136         ShellStatus = SHELL_INVALID_PARAMETER;
137       } else {
138         WhatToDo = FileTypeMemBuffer;
139         Offset  = ShellStrToUintn(ShellCommandLineGetRawValue(Package, 1));
140         Size    = ShellStrToUintn(ShellCommandLineGetRawValue(Package, 2));
141       }
142     }
143     Name = ShellCommandLineGetRawValue(Package, 1);
144     if (WhatToDo == FileTypeNone && Name != NULL) {
145       if (ShellCommandLineGetCount(Package) > 2) {
146         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"hexedit");
147         ShellStatus = SHELL_INVALID_PARAMETER;
148       } else if (!IsValidFileName(Name)) {
149         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"hexedit", Name);
150         ShellStatus = SHELL_INVALID_PARAMETER;
151       } else {
152         WhatToDo  = FileTypeFileBuffer;
153       }
154     } else if (WhatToDo == FileTypeNone) {
155       if (gEfiShellProtocol->GetCurDir(NULL) == NULL) {
156         ShellStatus = SHELL_NOT_FOUND;
157         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellDebug1HiiHandle, L"hexedit");
158       } else {
159         NewName = EditGetDefaultFileName(L"bin");
160         Name = NewName;
161         WhatToDo  = FileTypeFileBuffer;
162       }
163     }
164 
165     if (ShellStatus == SHELL_SUCCESS && WhatToDo == FileTypeNone) {
166       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"hexedit");
167       ShellStatus = SHELL_INVALID_PARAMETER;
168     } else if (WhatToDo == FileTypeFileBuffer && ShellGetCurrentDir(NULL) == NULL) {
169       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellDebug1HiiHandle, L"hexedit");
170       ShellStatus = SHELL_INVALID_PARAMETER;
171     }
172 
173     if (ShellStatus == SHELL_SUCCESS) {
174       //
175       // Do the editor
176       //
177       Status = HMainEditorInit ();
178       if (EFI_ERROR (Status)) {
179         gST->ConOut->ClearScreen (gST->ConOut);
180         gST->ConOut->EnableCursor (gST->ConOut, TRUE);
181         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_INIT_FAILED), gShellDebug1HiiHandle);
182       } else {
183         HMainEditorBackup ();
184         switch (WhatToDo) {
185         case FileTypeFileBuffer:
186           Status = HBufferImageRead (
187                     Name==NULL?L"":Name,
188                     NULL,
189                     0,
190                     0,
191                     0,
192                     0,
193                     FileTypeFileBuffer,
194                     FALSE
195                     );
196           break;
197 
198         case FileTypeDiskBuffer:
199           Status = HBufferImageRead (
200                     NULL,
201                     Name==NULL?L"":Name,
202                     Offset,
203                     Size,
204                     0,
205                     0,
206                     FileTypeDiskBuffer,
207                     FALSE
208                     );
209           break;
210 
211         case FileTypeMemBuffer:
212           Status = HBufferImageRead (
213                     NULL,
214                     NULL,
215                     0,
216                     0,
217                     (UINT32) Offset,
218                     Size,
219                     FileTypeMemBuffer,
220                     FALSE
221                     );
222           break;
223 
224         default:
225           Status = EFI_NOT_FOUND;
226           break;
227         }
228         if (!EFI_ERROR (Status)) {
229           HMainEditorRefresh ();
230           Status = HMainEditorKeyInput ();
231         }
232         if (Status != EFI_OUT_OF_RESOURCES) {
233           //
234           // back up the status string
235           //
236           Buffer = CatSPrint (NULL, L"%s\r\n", StatusBarGetString());
237         }
238       }
239 
240       //
241       // cleanup
242       //
243       HMainEditorCleanup ();
244 
245       if (EFI_ERROR (Status)) {
246         if (ShellStatus == SHELL_SUCCESS) {
247           ShellStatus = SHELL_UNSUPPORTED;
248         }
249       }
250 
251       //
252       // print editor exit code on screen
253       //
254       if (Status == EFI_OUT_OF_RESOURCES) {
255         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle, L"hexedit");
256       } else if (EFI_ERROR(Status)){
257         if (Buffer != NULL) {
258           if (StrCmp (Buffer, L"") != 0) {
259             //
260             // print out the status string
261             //
262             ShellPrintEx(-1, -1, L"%s", Buffer);
263           } else {
264             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_UNKNOWN_EDITOR), gShellDebug1HiiHandle);
265           }
266         } else {
267           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_UNKNOWN_EDITOR), gShellDebug1HiiHandle);
268         }
269       }
270     }
271     ShellCommandLineFreeVarList (Package);
272   }
273 
274   SHELL_FREE_NON_NULL (Buffer);
275   SHELL_FREE_NON_NULL (NewName);
276   return ShellStatus;
277 }
278