1 /** @file
2 Main file for Alias shell level 3 function.
3
4 (C) Copyright 2015 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 #include "UefiShellLevel3CommandsLib.h"
11
12 #include <Library/ShellLib.h>
13
14 /**
15 Print out single alias registered with the Shell.
16
17 @param[in] Alias Points to the NULL-terminated shell alias.
18 If this parameter is NULL, then all
19 aliases will be returned in ReturnedData.
20 @retval SHELL_SUCCESS the printout was sucessful
21 **/
22 SHELL_STATUS
PrintSingleShellAlias(IN CONST CHAR16 * Alias)23 PrintSingleShellAlias(
24 IN CONST CHAR16 *Alias
25 )
26 {
27 CONST CHAR16 *ConstAliasVal;
28 SHELL_STATUS ShellStatus;
29 BOOLEAN Volatile;
30
31 ShellStatus = SHELL_SUCCESS;
32 ConstAliasVal = gEfiShellProtocol->GetAlias (Alias, &Volatile);
33 if (ConstAliasVal == NULL) {
34 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel3HiiHandle, L"alias", Alias);
35 ShellStatus = SHELL_INVALID_PARAMETER;
36 } else {
37 if (ShellCommandIsOnAliasList (Alias)) {
38 Volatile = FALSE;
39 }
40 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_ALIAS_OUTPUT), gShellLevel3HiiHandle, !Volatile ? L' ' : L'*', Alias, ConstAliasVal);
41 }
42 return ShellStatus;
43 }
44
45 /**
46 Print out each alias registered with the Shell.
47
48 @retval STATUS_SUCCESS the printout was sucessful
49 @return any return code from GetNextVariableName except EFI_NOT_FOUND
50 **/
51 SHELL_STATUS
PrintAllShellAlias(VOID)52 PrintAllShellAlias(
53 VOID
54 )
55 {
56 CONST CHAR16 *ConstAllAliasList;
57 CHAR16 *Alias;
58 CHAR16 *Walker;
59
60 ConstAllAliasList = gEfiShellProtocol->GetAlias(NULL, NULL);
61 if (ConstAllAliasList == NULL) {
62 return (SHELL_SUCCESS);
63 }
64 Alias = AllocateZeroPool(StrSize(ConstAllAliasList));
65 if (Alias == NULL) {
66 return (SHELL_OUT_OF_RESOURCES);
67 }
68 Walker = (CHAR16*)ConstAllAliasList;
69
70 do {
71 CopyMem(Alias, Walker, StrSize(Walker));
72 Walker = StrStr(Alias, L";");
73 if (Walker != NULL) {
74 Walker[0] = CHAR_NULL;
75 Walker = Walker + 1;
76 }
77 PrintSingleShellAlias(Alias);
78 } while (Walker != NULL && Walker[0] != CHAR_NULL);
79
80 FreePool(Alias);
81
82 return (SHELL_SUCCESS);
83 }
84
85 /**
86 Changes a shell command alias.
87
88 This function creates an alias for a shell command or if Alias is NULL it will delete an existing alias.
89
90
91 @param[in] Command Points to the NULL-terminated shell command or existing alias.
92 @param[in] Alias Points to the NULL-terminated alias for the shell command. If this is NULL, and
93 Command refers to an alias, that alias will be deleted.
94 @param[in] Replace If TRUE and the alias already exists, then the existing alias will be replaced. If
95 FALSE and the alias already exists, then the existing alias is unchanged and
96 EFI_ACCESS_DENIED is returned.
97 @param[in] Volatile if TRUE the Alias being set will be stored in a volatile fashion. if FALSE the
98 Alias being set will be stored in a non-volatile fashion.
99
100 @retval SHELL_SUCCESS Alias created or deleted successfully.
101 @retval SHELL_NOT_FOUND the Alias intended to be deleted was not found
102 @retval SHELL_ACCESS_DENIED The alias is a built-in alias or already existed and Replace was set to
103 FALSE.
104 @retval SHELL_DEVICE_ERROR Command is null or the empty string.
105 **/
106 SHELL_STATUS
ShellLevel3CommandsLibSetAlias(IN CONST CHAR16 * Command,IN CONST CHAR16 * Alias,IN BOOLEAN Replace,IN BOOLEAN Volatile)107 ShellLevel3CommandsLibSetAlias(
108 IN CONST CHAR16 *Command,
109 IN CONST CHAR16 *Alias,
110 IN BOOLEAN Replace,
111 IN BOOLEAN Volatile
112 )
113 {
114 SHELL_STATUS ShellStatus;
115 EFI_STATUS Status;
116
117 ShellStatus = SHELL_SUCCESS;
118 Status = gEfiShellProtocol->SetAlias (Command, Alias, Replace, Volatile);
119 if (EFI_ERROR(Status)) {
120 if (Status == EFI_ACCESS_DENIED) {
121 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellLevel3HiiHandle, L"alias");
122 ShellStatus = SHELL_ACCESS_DENIED;
123 } else if (Status == EFI_NOT_FOUND) {
124 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_NOT_FOUND), gShellLevel3HiiHandle, L"alias", Command);
125 ShellStatus = SHELL_NOT_FOUND;
126 } else {
127 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel3HiiHandle, L"alias", Status);
128 ShellStatus = SHELL_DEVICE_ERROR;
129 }
130 }
131 return ShellStatus;
132 }
133
134 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
135 {L"-v", TypeFlag},
136 {L"-d", TypeValue},
137 {NULL, TypeMax}
138 };
139
140 /**
141 Function for 'alias' command.
142
143 @param[in] ImageHandle Handle to the Image (NULL if Internal).
144 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
145 **/
146 SHELL_STATUS
147 EFIAPI
ShellCommandRunAlias(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)148 ShellCommandRunAlias (
149 IN EFI_HANDLE ImageHandle,
150 IN EFI_SYSTEM_TABLE *SystemTable
151 )
152 {
153 EFI_STATUS Status;
154 LIST_ENTRY *Package;
155 CHAR16 *ProblemParam;
156 SHELL_STATUS ShellStatus;
157 CONST CHAR16 *Param1;
158 CONST CHAR16 *Param2;
159 CONST CHAR16 *ParamStrD;
160 CHAR16 *CleanParam2;
161 BOOLEAN DeleteFlag;
162 BOOLEAN VolatileFlag;
163
164 ProblemParam = NULL;
165 ShellStatus = SHELL_SUCCESS;
166 CleanParam2 = NULL;
167
168 //
169 // initialize the shell lib (we must be in non-auto-init...)
170 //
171 Status = ShellInitialize();
172 ASSERT_EFI_ERROR(Status);
173
174 Status = CommandInit();
175 ASSERT_EFI_ERROR(Status);
176
177 //
178 // parse the command line
179 //
180 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
181 if (EFI_ERROR(Status)) {
182 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
183 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel3HiiHandle, L"alias", ProblemParam);
184 FreePool(ProblemParam);
185 ShellStatus = SHELL_INVALID_PARAMETER;
186 } else {
187 ASSERT(FALSE);
188 }
189 } else {
190 Param1 = ShellCommandLineGetRawValue(Package, 1);
191 Param2 = ShellCommandLineGetRawValue(Package, 2);
192
193 DeleteFlag = ShellCommandLineGetFlag (Package, L"-d");
194 VolatileFlag = ShellCommandLineGetFlag (Package, L"-v");
195
196 if (Param2 != NULL) {
197 CleanParam2 = AllocateCopyPool (StrSize(Param2), Param2);
198 if (CleanParam2 == NULL) {
199 ShellCommandLineFreeVarList (Package);
200 return SHELL_OUT_OF_RESOURCES;
201 }
202
203 if (CleanParam2[0] == L'\"' && CleanParam2[StrLen(CleanParam2)-1] == L'\"') {
204 CleanParam2[StrLen(CleanParam2)-1] = L'\0';
205 CopyMem (CleanParam2, CleanParam2 + 1, StrSize(CleanParam2) - sizeof(CleanParam2[0]));
206 }
207 }
208
209 if (!DeleteFlag && !VolatileFlag) {
210 switch (ShellCommandLineGetCount (Package)) {
211 case 1:
212 //
213 // "alias"
214 //
215 ShellStatus = PrintAllShellAlias ();
216 break;
217 case 2:
218 //
219 // "alias Param1"
220 //
221 ShellStatus = PrintSingleShellAlias (Param1);
222 break;
223 case 3:
224 //
225 // "alias Param1 CleanParam2"
226 //
227 ShellStatus = ShellLevel3CommandsLibSetAlias (CleanParam2, Param1, FALSE, VolatileFlag);
228 break;
229 default:
230 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel3HiiHandle, L"alias");
231 ShellStatus = SHELL_INVALID_PARAMETER;
232 }
233 } else if (DeleteFlag) {
234 if (VolatileFlag || ShellCommandLineGetCount (Package) > 1) {
235 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel3HiiHandle, L"alias");
236 ShellStatus = SHELL_INVALID_PARAMETER;
237 } else {
238 ParamStrD = ShellCommandLineGetValue (Package, L"-d");
239 if (ParamStrD == NULL) {
240 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel3HiiHandle, L"alias");
241 ShellStatus = SHELL_INVALID_PARAMETER;
242 } else {
243 //
244 // Delete an alias: "alias -d ParamStrD"
245 //
246 ShellStatus = ShellLevel3CommandsLibSetAlias (ParamStrD, NULL, TRUE, FALSE);
247 }
248 }
249 } else {
250 //
251 // Set volatile alias.
252 //
253 ASSERT (VolatileFlag);
254 ASSERT (!DeleteFlag);
255 switch (ShellCommandLineGetCount (Package)) {
256 case 1:
257 case 2:
258 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel3HiiHandle, L"alias");
259 ShellStatus = SHELL_INVALID_PARAMETER;
260 break;
261 case 3:
262 //
263 // "alias -v Param1 CleanParam2"
264 //
265 ShellStatus = ShellLevel3CommandsLibSetAlias (CleanParam2, Param1, FALSE, VolatileFlag);
266 break;
267 default:
268 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel3HiiHandle, L"alias");
269 ShellStatus = SHELL_INVALID_PARAMETER;
270 }
271 }
272 //
273 // free the command line package
274 //
275 ShellCommandLineFreeVarList (Package);
276 }
277
278 SHELL_FREE_NON_NULL (CleanParam2);
279 return (ShellStatus);
280 }
281