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