]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / ShellPkg / Library / UefiShellLevel2CommandsLib / UefiShellLevel2CommandsLib.c
1 /** @file
2 Main file for NULL named library for level 2 shell command functions.
3
4 these functions are:
5 attrib,
6 cd,
7 cp,
8 date*,
9 time*,
10 load,
11 ls,
12 map,
13 mkdir,
14 mv,
15 parse,
16 rm,
17 reset,
18 set,
19 timezone*,
20 vol
21
22 * functions are non-interactive only
23
24 Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
25 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
26 SPDX-License-Identifier: BSD-2-Clause-Patent
27
28 **/
29 #include "UefiShellLevel2CommandsLib.h"
30
31 CONST CHAR16 mFileName[] = L"ShellCommands";
32 EFI_HII_HANDLE gShellLevel2HiiHandle = NULL;
33
34 /**
35 Get the filename to get help text from if not using HII.
36
37 @retval The filename.
38 **/
39 CONST CHAR16 *
40 EFIAPI
41 ShellCommandGetManFileNameLevel2 (
42 VOID
43 )
44 {
45 return (mFileName);
46 }
47
48 /**
49 Constructor for the Shell Level 2 Commands library.
50
51 Install the handlers for level 2 UEFI Shell 2.0 commands.
52
53 @param ImageHandle the image handle of the process
54 @param SystemTable the EFI System Table pointer
55
56 @retval EFI_SUCCESS the shell command handlers were installed sucessfully
57 @retval EFI_UNSUPPORTED the shell level required was not found.
58 **/
59 EFI_STATUS
60 EFIAPI
61 ShellLevel2CommandsLibConstructor (
62 IN EFI_HANDLE ImageHandle,
63 IN EFI_SYSTEM_TABLE *SystemTable
64 )
65 {
66 //
67 // if shell level is less than 2 do nothing
68 //
69 if (PcdGet8 (PcdShellSupportLevel) < 2) {
70 return (EFI_SUCCESS);
71 }
72
73 gShellLevel2HiiHandle = HiiAddPackages (&gShellLevel2HiiGuid, gImageHandle, UefiShellLevel2CommandsLibStrings, NULL);
74 if (gShellLevel2HiiHandle == NULL) {
75 return (EFI_DEVICE_ERROR);
76 }
77
78 //
79 // install our shell command handlers that are always installed
80 //
81 ShellCommandRegisterCommandName (L"attrib", ShellCommandRunAttrib, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_ATTRIB));
82 ShellCommandRegisterCommandName (L"cd", ShellCommandRunCd, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_CD));
83 ShellCommandRegisterCommandName (L"cp", ShellCommandRunCp, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_CP));
84 ShellCommandRegisterCommandName (L"load", ShellCommandRunLoad, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_LOAD));
85 ShellCommandRegisterCommandName (L"map", ShellCommandRunMap, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_MAP));
86 ShellCommandRegisterCommandName (L"mkdir", ShellCommandRunMkDir, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_MKDIR));
87 ShellCommandRegisterCommandName (L"mv", ShellCommandRunMv, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_MV));
88 ShellCommandRegisterCommandName (L"parse", ShellCommandRunParse, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_PARSE));
89 ShellCommandRegisterCommandName (L"reset", ShellCommandRunReset, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_RESET));
90 ShellCommandRegisterCommandName (L"set", ShellCommandRunSet, ShellCommandGetManFileNameLevel2, 2, L"", FALSE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_SET));
91 ShellCommandRegisterCommandName (L"ls", ShellCommandRunLs, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_LS));
92 ShellCommandRegisterCommandName (L"rm", ShellCommandRunRm, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_RM));
93 ShellCommandRegisterCommandName (L"vol", ShellCommandRunVol, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_VOL));
94
95 //
96 // support for permanent (built in) aliases
97 //
98 ShellCommandRegisterAlias (L"rm", L"del");
99 ShellCommandRegisterAlias (L"ls", L"dir");
100 ShellCommandRegisterAlias (L"cp", L"copy");
101 ShellCommandRegisterAlias (L"mkdir", L"md");
102 ShellCommandRegisterAlias (L"cd ..", L"cd..");
103 ShellCommandRegisterAlias (L"cd \\", L"cd\\");
104 ShellCommandRegisterAlias (L"mv", L"ren");
105 ShellCommandRegisterAlias (L"mv", L"move");
106 ShellCommandRegisterAlias (L"map", L"mount");
107 //
108 // These are installed in level 2 or 3...
109 //
110 if ((PcdGet8 (PcdShellSupportLevel) == 2) || (PcdGet8 (PcdShellSupportLevel) == 3)) {
111 ShellCommandRegisterCommandName (L"date", ShellCommandRunDate, ShellCommandGetManFileNameLevel2, PcdGet8 (PcdShellSupportLevel), L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_DATE));
112 ShellCommandRegisterCommandName (L"time", ShellCommandRunTime, ShellCommandGetManFileNameLevel2, PcdGet8 (PcdShellSupportLevel), L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_TIME));
113 ShellCommandRegisterCommandName (L"timezone", ShellCommandRunTimeZone, ShellCommandGetManFileNameLevel2, PcdGet8 (PcdShellSupportLevel), L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_TIMEZONE));
114 } else {
115 DEBUG_CODE_BEGIN ();
116 //
117 // we want to be able to test these so install them under a different name in debug mode...
118 //
119 ShellCommandRegisterCommandName (L"l2date", ShellCommandRunDate, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_DATE));
120 ShellCommandRegisterCommandName (L"l2time", ShellCommandRunTime, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_TIME));
121 ShellCommandRegisterCommandName (L"l2timezone", ShellCommandRunTimeZone, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN (STR_GET_HELP_TIMEZONE));
122 DEBUG_CODE_END ();
123 }
124
125 return (EFI_SUCCESS);
126 }
127
128 /**
129 Destructor for the library. free any resources.
130
131 @param ImageHandle The image handle of the process.
132 @param SystemTable The EFI System Table pointer.
133
134 @retval EFI_SUCCESS Always returned.
135 **/
136 EFI_STATUS
137 EFIAPI
138 ShellLevel2CommandsLibDestructor (
139 IN EFI_HANDLE ImageHandle,
140 IN EFI_SYSTEM_TABLE *SystemTable
141 )
142 {
143 if (gShellLevel2HiiHandle != NULL) {
144 HiiRemovePackages (gShellLevel2HiiHandle);
145 }
146
147 return (EFI_SUCCESS);
148 }
149
150 /**
151 returns a fully qualified directory (contains a map drive at the begining)
152 path from a unknown directory path.
153
154 If Path is already fully qualified this will return a duplicat otherwise this
155 will use get the current directory and use that to build the fully qualified
156 version.
157
158 if the return value is not NULL it must be caller freed.
159
160 @param[in] Path The unknown Path Value
161
162 @retval NULL A memory allocation failed
163 @retval NULL A fully qualified path could not be discovered.
164 @retval other An allocated pointer to a fuly qualified path.
165 **/
166 CHAR16 *
167 GetFullyQualifiedPath (
168 IN CONST CHAR16 *Path
169 )
170 {
171 CHAR16 *PathToReturn;
172 UINTN Size;
173 CONST CHAR16 *CurDir;
174
175 PathToReturn = NULL;
176 Size = 0;
177
178 ASSERT ((PathToReturn == NULL && Size == 0) || (PathToReturn != NULL));
179 //
180 // convert a local path to an absolute path
181 //
182 if (StrStr (Path, L":") == NULL) {
183 CurDir = gEfiShellProtocol->GetCurDir (NULL);
184 StrnCatGrow (&PathToReturn, &Size, CurDir, 0);
185 StrnCatGrow (&PathToReturn, &Size, L"\\", 0);
186 if (*Path == L'\\') {
187 Path++;
188 }
189 }
190
191 StrnCatGrow (&PathToReturn, &Size, Path, 0);
192
193 PathCleanUpDirectories (PathToReturn);
194
195 if (PathToReturn == NULL) {
196 return NULL;
197 }
198
199 while (PathToReturn[StrLen (PathToReturn)-1] == L'*') {
200 PathToReturn[StrLen (PathToReturn)-1] = CHAR_NULL;
201 }
202
203 return (PathToReturn);
204 }
205
206 /**
207 Function to verify all intermediate directories in the path.
208
209 @param[in] Path The pointer to the path to fix.
210
211 @retval EFI_SUCCESS The operation was successful.
212 **/
213 EFI_STATUS
214 VerifyIntermediateDirectories (
215 IN CONST CHAR16 *Path
216 )
217 {
218 EFI_STATUS Status;
219 CHAR16 *PathCopy;
220 CHAR16 *TempSpot;
221 SHELL_FILE_HANDLE FileHandle;
222
223 ASSERT (Path != NULL);
224
225 Status = EFI_SUCCESS;
226 PathCopy = NULL;
227 PathCopy = StrnCatGrow (&PathCopy, NULL, Path, 0);
228 FileHandle = NULL;
229
230 if (PathCopy == NULL) {
231 return (EFI_OUT_OF_RESOURCES);
232 }
233
234 for (TempSpot = &PathCopy[StrLen (PathCopy)-1]; *TempSpot != CHAR_NULL && *TempSpot != L'\\'; TempSpot = &PathCopy[StrLen (PathCopy)-1]) {
235 *TempSpot = CHAR_NULL;
236 }
237
238 if (*TempSpot == L'\\') {
239 *TempSpot = CHAR_NULL;
240 }
241
242 if ((PathCopy != NULL) && (*PathCopy != CHAR_NULL)) {
243 Status = VerifyIntermediateDirectories (PathCopy);
244
245 if (PathCopy[StrLen (PathCopy)-1] != L':') {
246 if (!EFI_ERROR (Status)) {
247 Status = ShellOpenFileByName (PathCopy, &FileHandle, EFI_FILE_MODE_READ, 0);
248 if (FileHandle != NULL) {
249 ShellCloseFile (&FileHandle);
250 }
251 }
252 }
253 }
254
255 SHELL_FREE_NON_NULL (PathCopy);
256
257 return (Status);
258 }
259
260 /**
261 String comparison without regard to case for a limited number of characters.
262
263 @param[in] Source The first item to compare.
264 @param[in] Target The second item to compare.
265 @param[in] Count How many characters to compare.
266
267 @retval 0 Source and Target are identical strings without regard to case.
268 @retval !=0 Source is not identical to Target.
269
270 **/
271 INTN
272 StrniCmp (
273 IN CONST CHAR16 *Source,
274 IN CONST CHAR16 *Target,
275 IN CONST UINTN Count
276 )
277 {
278 CHAR16 *SourceCopy;
279 CHAR16 *TargetCopy;
280 UINTN SourceLength;
281 UINTN TargetLength;
282 INTN Result;
283
284 if (Count == 0) {
285 return 0;
286 }
287
288 SourceLength = StrLen (Source);
289 TargetLength = StrLen (Target);
290 SourceLength = MIN (SourceLength, Count);
291 TargetLength = MIN (TargetLength, Count);
292 SourceCopy = AllocateCopyPool ((SourceLength + 1) * sizeof (CHAR16), Source);
293 if (SourceCopy == NULL) {
294 return -1;
295 }
296
297 TargetCopy = AllocateCopyPool ((TargetLength + 1) * sizeof (CHAR16), Target);
298 if (TargetCopy == NULL) {
299 FreePool (SourceCopy);
300 return -1;
301 }
302
303 SourceCopy[SourceLength] = L'\0';
304 TargetCopy[TargetLength] = L'\0';
305 Result = gUnicodeCollation->StriColl (gUnicodeCollation, SourceCopy, TargetCopy);
306 FreePool (SourceCopy);
307 FreePool (TargetCopy);
308 return Result;
309 }
310
311 /**
312 Cleans off all the quotes in the string.
313
314 @param[in] OriginalString pointer to the string to be cleaned.
315 @param[out] CleanString The new string with all quotes removed.
316 Memory allocated in the function and free
317 by caller.
318
319 @retval EFI_SUCCESS The operation was successful.
320 **/
321 EFI_STATUS
322 ShellLevel2StripQuotes (
323 IN CONST CHAR16 *OriginalString,
324 OUT CHAR16 **CleanString
325 )
326 {
327 CHAR16 *Walker;
328
329 if ((OriginalString == NULL) || (CleanString == NULL)) {
330 return EFI_INVALID_PARAMETER;
331 }
332
333 *CleanString = AllocateCopyPool (StrSize (OriginalString), OriginalString);
334 if (*CleanString == NULL) {
335 return EFI_OUT_OF_RESOURCES;
336 }
337
338 for (Walker = *CleanString; Walker != NULL && *Walker != CHAR_NULL; Walker++) {
339 if (*Walker == L'\"') {
340 CopyMem (Walker, Walker+1, StrSize (Walker) - sizeof (Walker[0]));
341 }
342 }
343
344 return EFI_SUCCESS;
345 }