1 /** @file
2   function definitions for internal to shell functions.
3 
4   (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
5   Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
6   SPDX-License-Identifier: BSD-2-Clause-Patent
7 
8 **/
9 
10 #ifndef _SHELL_INTERNAL_HEADER_
11 #define _SHELL_INTERNAL_HEADER_
12 
13 #include <Uefi.h>
14 
15 #include <Guid/ShellVariableGuid.h>
16 #include <Guid/ShellAliasGuid.h>
17 
18 #include <Protocol/LoadedImage.h>
19 #include <Protocol/SimpleTextOut.h>
20 #include <Protocol/Shell.h>
21 #include <Protocol/EfiShellInterface.h>
22 #include <Protocol/EfiShellEnvironment2.h>
23 #include <Protocol/ShellParameters.h>
24 #include <Protocol/BlockIo.h>
25 #include <Protocol/HiiPackageList.h>
26 
27 #include <Library/BaseLib.h>
28 #include <Library/UefiApplicationEntryPoint.h>
29 #include <Library/UefiLib.h>
30 #include <Library/DebugLib.h>
31 #include <Library/MemoryAllocationLib.h>
32 #include <Library/ShellCommandLib.h>
33 #include <Library/UefiRuntimeServicesTableLib.h>
34 #include <Library/UefiBootServicesTableLib.h>
35 #include <Library/DevicePathLib.h>
36 #include <Library/BaseMemoryLib.h>
37 #include <Library/PcdLib.h>
38 #include <Library/ShellLib.h>
39 #include <Library/SortLib.h>
40 #include <Library/HiiLib.h>
41 #include <Library/PrintLib.h>
42 #include <Library/HandleParsingLib.h>
43 #include <Library/FileHandleLib.h>
44 #include <Library/UefiHiiServicesLib.h>
45 
46 #include "ShellParametersProtocol.h"
47 #include "ShellProtocol.h"
48 #include "ShellEnvVar.h"
49 #include "ConsoleLogger.h"
50 #include "ShellManParser.h"
51 #include "ConsoleWrappers.h"
52 #include "FileHandleWrappers.h"
53 
54 extern CONST CHAR16 mNoNestingEnvVarName[];
55 extern CONST CHAR16 mNoNestingTrue[];
56 extern CONST CHAR16 mNoNestingFalse[];
57 
58 typedef struct {
59   LIST_ENTRY        Link;           ///< Standard linked list handler.
60   SHELL_FILE_HANDLE SplitStdOut;    ///< ConsoleOut for use in the split.
61   SHELL_FILE_HANDLE SplitStdIn;     ///< ConsoleIn for use in the split.
62 } SPLIT_LIST;
63 
64 typedef struct {
65   UINT32  Startup:1;      ///< Was "-startup"       found on command line.
66   UINT32  NoStartup:1;    ///< Was "-nostartup"     found on command line.
67   UINT32  NoConsoleOut:1; ///< Was "-noconsoleout"  found on command line.
68   UINT32  NoConsoleIn:1;  ///< Was "-noconsolein"   found on command line.
69   UINT32  NoInterrupt:1;  ///< Was "-nointerrupt"   found on command line.
70   UINT32  NoMap:1;        ///< Was "-nomap"         found on command line.
71   UINT32  NoVersion:1;    ///< Was "-noversion"     found on command line.
72   UINT32  Delay:1;        ///< Was "-delay[:n]      found on command line
73   UINT32  Exit:1;         ///< Was "-_exit"         found on command line
74   UINT32  NoNest:1;       ///< Was "-nonest"        found on command line
75   UINT32  Reserved:7;     ///< Extra bits
76 } SHELL_BITS;
77 
78 typedef union {
79   SHELL_BITS  Bits;
80   UINT16      AllBits;
81 } SHELL_BIT_UNION;
82 
83 typedef struct {
84   SHELL_BIT_UNION BitUnion;
85   UINTN           Delay;          ///< Seconds of delay default:5.
86   CHAR16          *FileName;      ///< Filename to run upon successful initialization.
87   CHAR16          *FileOptions;   ///< Options to pass to FileName.
88 } SHELL_INIT_SETTINGS;
89 
90 typedef struct {
91   BUFFER_LIST                 CommandHistory;
92   UINTN                       VisibleRowNumber;
93   UINTN                       OriginalVisibleRowNumber;
94   BOOLEAN                     InsertMode;           ///< Is the current typing mode insert (FALSE = overwrite).
95 } SHELL_VIEWING_SETTINGS;
96 
97 typedef struct {
98   EFI_SHELL_PARAMETERS_PROTOCOL *NewShellParametersProtocol;
99   EFI_SHELL_PROTOCOL            *NewEfiShellProtocol;
100   BOOLEAN                       PageBreakEnabled;
101   BOOLEAN                       RootShellInstance;
102   SHELL_INIT_SETTINGS           ShellInitSettings;
103   BUFFER_LIST                   BufferToFreeList;     ///< List of buffers that were returned to the user to free.
104   SHELL_VIEWING_SETTINGS        ViewingSettings;
105   EFI_HII_HANDLE                HiiHandle;            ///< Handle from HiiLib.
106   UINTN                         LogScreenCount;       ///< How many screens of log information to save.
107   EFI_EVENT                     UserBreakTimer;       ///< Timer event for polling for CTRL-C.
108   EFI_DEVICE_PATH_PROTOCOL      *ImageDevPath;        ///< DevicePath for ourselves.
109   EFI_DEVICE_PATH_PROTOCOL      *FileDevPath;         ///< DevicePath for ourselves.
110   CONSOLE_LOGGER_PRIVATE_DATA   *ConsoleInfo;         ///< Pointer for ConsoleInformation.
111   EFI_SHELL_PARAMETERS_PROTOCOL *OldShellParameters;  ///< old shell parameters to reinstall upon exiting.
112   SHELL_PROTOCOL_HANDLE_LIST    OldShellList;         ///< List of other instances to reinstall when closing.
113   SPLIT_LIST                    SplitList;            ///< List of Splits in FILO stack.
114   VOID                          *CtrlCNotifyHandle1;  ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
115   VOID                          *CtrlCNotifyHandle2;  ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
116   VOID                          *CtrlCNotifyHandle3;  ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
117   VOID                          *CtrlCNotifyHandle4;  ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
118   VOID                          *CtrlSNotifyHandle1;  ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
119   VOID                          *CtrlSNotifyHandle2;  ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
120   VOID                          *CtrlSNotifyHandle3;  ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
121   VOID                          *CtrlSNotifyHandle4;  ///< The NotifyHandle returned from SimpleTextInputEx.RegisterKeyNotify.
122   BOOLEAN                       HaltOutput;           ///< TRUE to start a CTRL-S halt.
123 } SHELL_INFO;
124 
125 #pragma pack(1)
126 ///
127 /// HII specific Vendor Device Path definition.
128 ///
129 typedef struct {
130   VENDOR_DEVICE_PATH             VendorDevicePath;
131   EFI_DEVICE_PATH_PROTOCOL       End;
132 } SHELL_MAN_HII_VENDOR_DEVICE_PATH;
133 #pragma pack()
134 
135 extern SHELL_INFO ShellInfoObject;
136 
137 /**
138   Converts the command line to its post-processed form.  this replaces variables and alias' per UEFI Shell spec.
139 
140   @param[in,out] CmdLine        pointer to the command line to update
141 
142   @retval EFI_SUCCESS           The operation was successful
143   @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
144   @return                       some other error occurred
145 **/
146 EFI_STATUS
147 ProcessCommandLineToFinal(
148   IN OUT CHAR16 **CmdLine
149   );
150 
151 /**
152   Function to update the shell variable "lasterror".
153 
154   @param[in] ErrorCode      the error code to put into lasterror
155 **/
156 EFI_STATUS
157 SetLastError(
158   IN CONST SHELL_STATUS   ErrorCode
159   );
160 
161 /**
162   Sets all the alias' that were registered with the ShellCommandLib library.
163 
164   @retval EFI_SUCCESS           all init commands were run successfully.
165 **/
166 EFI_STATUS
167 SetBuiltInAlias(
168   VOID
169   );
170 
171 /**
172   This function will populate the 2 device path protocol parameters based on the
173   global gImageHandle.  the DevPath will point to the device path for the handle that has
174   loaded image protocol installed on it.  the FilePath will point to the device path
175   for the file that was loaded.
176 
177   @param[in, out] DevPath       on a successful return the device path to the loaded image
178   @param[in, out] FilePath      on a successful return the device path to the file
179 
180   @retval EFI_SUCCESS           the 2 device paths were successfully returned.
181   @return other                 a error from gBS->HandleProtocol
182 
183   @sa HandleProtocol
184 **/
185 EFI_STATUS
186 GetDevicePathsForImageAndFile (
187   IN OUT EFI_DEVICE_PATH_PROTOCOL **DevPath,
188   IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath
189   );
190 
191 /**
192   Process all Uefi Shell 2.0 command line options.
193 
194   see Uefi Shell 2.0 section 3.2 for full details.
195 
196   the command line should resemble the following:
197 
198   shell.efi [ShellOpt-options] [options] [file-name [file-name-options]]
199 
200   ShellOpt options  Options which control the initialization behavior of the shell.
201                     These options are read from the EFI global variable "ShellOpt"
202                     and are processed before options or file-name.
203 
204   options           Options which control the initialization behavior of the shell.
205 
206   file-name         The name of a UEFI shell application or script to be executed
207                     after initialization is complete. By default, if file-name is
208                     specified, then -nostartup is implied. Scripts are not supported
209                     by level 0.
210 
211   file-nameoptions  The command-line options that are passed to file-name when it
212                     is invoked.
213 
214   This will initialize the ShellInitSettings global variable.
215 
216   @retval EFI_SUCCESS           the variable is initialized.
217 **/
218 EFI_STATUS
219 ProcessCommandLine(
220   VOID
221   );
222 
223 /**
224   Handles all interaction with the default startup script.
225 
226   this will check that the correct command line parameters were passed, handle the delay, and then start running the script.
227 
228   @param[in] ImagePath          The path to the image for shell.  The first place to look for the startup script.
229   @param[in] FilePath           The path to the file for shell.  The second place to look for the startup script.
230 
231   @retval EFI_SUCCESS           The variable is initialized.
232 **/
233 EFI_STATUS
234 DoStartupScript(
235   IN EFI_DEVICE_PATH_PROTOCOL *ImagePath,
236   IN EFI_DEVICE_PATH_PROTOCOL *FilePath
237   );
238 
239 /**
240   Function to perform the shell prompt looping.  It will do a single prompt,
241   dispatch the result, and then return.  It is expected that the caller will
242   call this function in a loop many times.
243 
244   @retval EFI_SUCCESS
245   @retval RETURN_ABORTED
246 **/
247 EFI_STATUS
248 DoShellPrompt (
249   VOID
250   );
251 
252 /**
253   Add a buffer to the Buffer To Free List for safely returning buffers to other
254   places without risking letting them modify internal shell information.
255 
256   @param Buffer   Something to pass to FreePool when the shell is exiting.
257 **/
258 VOID*
259 AddBufferToFreeList(
260   VOID *Buffer
261   );
262 
263 /**
264   Add a buffer to the Command History List.
265 
266   @param Buffer[in]     The line buffer to add.
267 **/
268 VOID
269 AddLineToCommandHistory(
270   IN CONST CHAR16 *Buffer
271   );
272 
273 /**
274   Function will process and run a command line.
275 
276   This will determine if the command line represents an internal shell command or dispatch an external application.
277 
278   @param[in] CmdLine  the command line to parse
279 
280   @retval EFI_SUCCESS     the command was completed
281   @retval EFI_ABORTED     the command's operation was aborted
282 **/
283 EFI_STATUS
284 RunCommand(
285   IN CONST CHAR16   *CmdLine
286   );
287 
288 /**
289   Function will process and run a command line.
290 
291   This will determine if the command line represents an internal shell
292   command or dispatch an external application.
293 
294   @param[in] CmdLine      The command line to parse.
295   @param[out] CommandStatus   The status from the command line.
296 
297   @retval EFI_SUCCESS     The command was completed.
298   @retval EFI_ABORTED     The command's operation was aborted.
299 **/
300 EFI_STATUS
301 RunShellCommand(
302   IN CONST CHAR16   *CmdLine,
303   OUT EFI_STATUS    *CommandStatus
304   );
305 
306 
307 /**
308   Function to process a NSH script file via SHELL_FILE_HANDLE.
309 
310   @param[in] Handle             The handle to the already opened file.
311   @param[in] Name               The name of the script file.
312 
313   @retval EFI_SUCCESS           the script completed successfully
314 **/
315 EFI_STATUS
316 RunScriptFileHandle (
317   IN SHELL_FILE_HANDLE  Handle,
318   IN CONST CHAR16       *Name
319   );
320 
321 /**
322   Function to process a NSH script file.
323 
324   @param[in] ScriptPath         Pointer to the script file name (including file system path).
325   @param[in] Handle             the handle of the script file already opened.
326   @param[in] CmdLine            the command line to run.
327   @param[in] ParamProtocol      the shell parameters protocol pointer
328 
329   @retval EFI_SUCCESS           the script completed successfully
330 **/
331 EFI_STATUS
332 RunScriptFile (
333   IN CONST CHAR16                   *ScriptPath,
334   IN SHELL_FILE_HANDLE              Handle OPTIONAL,
335   IN CONST CHAR16                   *CmdLine,
336   IN EFI_SHELL_PARAMETERS_PROTOCOL  *ParamProtocol
337   );
338 
339 /**
340   Return the pointer to the first occurrence of any character from a list of characters.
341 
342   @param[in] String           the string to parse
343   @param[in] CharacterList    the list of character to look for
344   @param[in] EscapeCharacter  An escape character to skip
345 
346   @return the location of the first character in the string
347   @retval CHAR_NULL no instance of any character in CharacterList was found in String
348 **/
349 CONST CHAR16*
350 FindFirstCharacter(
351   IN CONST CHAR16 *String,
352   IN CONST CHAR16 *CharacterList,
353   IN CONST CHAR16 EscapeCharacter
354   );
355 
356 /**
357   Cleans off leading and trailing spaces and tabs.
358 
359   @param[in] String pointer to the string to trim them off.
360 **/
361 EFI_STATUS
362 TrimSpaces(
363   IN CHAR16 **String
364   );
365 
366 /**
367 
368   Create a new buffer list and stores the old one to OldBufferList
369 
370   @param OldBufferList   The temporary list head used to store the nodes in BufferToFreeList.
371 **/
372 VOID
373 SaveBufferList (
374   OUT LIST_ENTRY     *OldBufferList
375   );
376 
377 /**
378   Restore previous nodes into BufferToFreeList .
379 
380   @param OldBufferList   The temporary list head used to store the nodes in BufferToFreeList.
381 **/
382 VOID
383 RestoreBufferList (
384   IN OUT LIST_ENTRY     *OldBufferList
385   );
386 
387 
388 
389 #endif //_SHELL_INTERNAL_HEADER_
390 
391