]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.c
7fe5a1102cab3fd3099d7226d847ca32709b264c
[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
21 * functions are non-interactive only
22
23
24 Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
25 This program and the accompanying materials
26 are licensed and made available under the terms and conditions of the BSD License
27 which accompanies this distribution. The full text of the license may be found at
28 http://opensource.org/licenses/bsd-license.php
29
30 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
31 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
32
33 **/
34 #include "UefiShellLevel2CommandsLib.h"
35
36 CONST CHAR16 mFileName[] = L"ShellCommands";
37 EFI_HANDLE gShellLevel2HiiHandle = NULL;
38 CONST EFI_GUID gShellLevel2HiiGuid = \
39 { \
40 0xf95a7ccc, 0x4c55, 0x4426, { 0xa7, 0xb4, 0xdc, 0x89, 0x61, 0x95, 0xb, 0xae } \
41 };
42
43 CONST CHAR16*
44 EFIAPI
45 ShellCommandGetManFileNameLevel2 (
46 VOID
47 )
48 {
49 return (mFileName);
50 }
51
52 /**
53 Constructor for the Shell Level 2 Commands library.
54
55 Install the handlers for level 2 UEFI Shell 2.0 commands.
56
57 @param ImageHandle the image handle of the process
58 @param SystemTable the EFI System Table pointer
59
60 @retval EFI_SUCCESS the shell command handlers were installed sucessfully
61 @retval EFI_UNSUPPORTED the shell level required was not found.
62 **/
63 EFI_STATUS
64 EFIAPI
65 ShellLevel2CommandsLibConstructor (
66 IN EFI_HANDLE ImageHandle,
67 IN EFI_SYSTEM_TABLE *SystemTable
68 )
69 {
70 //
71 // if shell level is less than 2 do nothing
72 //
73 if (PcdGet8(PcdShellSupportLevel) < 2) {
74 return (EFI_UNSUPPORTED);
75 }
76
77 gShellLevel2HiiHandle = HiiAddPackages (&gShellLevel2HiiGuid, gImageHandle, UefiShellLevel2CommandsLibStrings, NULL);
78 if (gShellLevel2HiiHandle == NULL) {
79 return (EFI_DEVICE_ERROR);
80 }
81
82 //
83 // install our shell command handlers that are always installed
84 //
85 ShellCommandRegisterCommandName(L"attrib", ShellCommandRunAttrib , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_ATTRIB) );
86 ShellCommandRegisterCommandName(L"cd", ShellCommandRunCd , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_CD) );
87 ShellCommandRegisterCommandName(L"cp", ShellCommandRunCp , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_CP) );
88 ShellCommandRegisterCommandName(L"load", ShellCommandRunLoad , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_LOAD) );
89 ShellCommandRegisterCommandName(L"map", ShellCommandRunMap , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_MAP) );
90 ShellCommandRegisterCommandName(L"mkdir", ShellCommandRunMkDir , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_MKDIR) );
91 ShellCommandRegisterCommandName(L"mv", ShellCommandRunMv , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_MV) );
92 ShellCommandRegisterCommandName(L"parse", ShellCommandRunParse , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_PARSE) );
93 ShellCommandRegisterCommandName(L"reset", ShellCommandRunReset , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_RESET) );
94 ShellCommandRegisterCommandName(L"set", ShellCommandRunSet , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_SET) );
95 ShellCommandRegisterCommandName(L"ls", ShellCommandRunLs , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_LS) );
96 ShellCommandRegisterCommandName(L"rm", ShellCommandRunRm , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_RM) );
97
98 //
99 // support for permenant (built in) aliases
100 //
101 ShellCommandRegisterAlias(L"rm", L"del");
102 ShellCommandRegisterAlias(L"ls", L"dir");
103 ShellCommandRegisterAlias(L"cp", L"copy");
104 ShellCommandRegisterAlias(L"mkdir", L"md");
105 ShellCommandRegisterAlias(L"cd ..", L"cd..");
106 ShellCommandRegisterAlias(L"cd \\", L"cd\\");
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 return (EFI_SUCCESS);
147 }
148
149 /**
150 Function to clean up paths. Removes the following items:
151 single periods in the path (no need for the current directory tag)
152 double periods in the path and removes a single parent directory.
153
154 This will be done inline and the resultant string may be be 'too big'.
155
156 @param[in] PathToReturn The pointer to the string containing the path.
157
158 @return PathToReturn is always returned.
159 **/
160 CHAR16*
161 EFIAPI
162 CleanPath(
163 IN CHAR16 *PathToReturn
164 )
165 {
166 CHAR16 *TempString;
167 UINTN TempSize;
168 if (PathToReturn==NULL) {
169 return(NULL);
170 }
171 //
172 // Fix up the directory name
173 //
174 while ((TempString = StrStr(PathToReturn, L"\\..\\")) != NULL) {
175 *TempString = CHAR_NULL;
176 TempString += 4;
177 ChopLastSlash(PathToReturn);
178 TempSize = StrSize(TempString);
179 CopyMem(PathToReturn+StrLen(PathToReturn), TempString, TempSize);
180 }
181 if ((TempString = StrStr(PathToReturn, L"\\..")) != NULL && *(TempString + 3) == CHAR_NULL) {
182 *TempString = CHAR_NULL;
183 ChopLastSlash(PathToReturn);
184 }
185 while ((TempString = StrStr(PathToReturn, L"\\.\\")) != NULL) {
186 *TempString = CHAR_NULL;
187 TempString += 2;
188 TempSize = StrSize(TempString);
189 CopyMem(PathToReturn+StrLen(PathToReturn), TempString, TempSize);
190 }
191 if ((TempString = StrStr(PathToReturn, L"\\.")) != NULL && *(TempString + 2) == CHAR_NULL) {
192 *TempString = CHAR_NULL;
193 }
194 return (PathToReturn);
195 }
196
197 /**
198 returns a fully qualified directory (contains a map drive at the begining)
199 path from a unknown directory path.
200
201 If Path is already fully qualified this will return a duplicat otherwise this
202 will use get the current directory and use that to build the fully qualified
203 version.
204
205 if the return value is not NULL it must be caller freed.
206
207 @param[in] Path The unknown Path Value
208
209 @retval NULL A memory allocation failed
210 @retval NULL a fully qualified path could not be discovered.
211 @retval other pointer to a fuly qualified path.
212 **/
213 CHAR16*
214 EFIAPI
215 GetFullyQualifiedPath(
216 IN CONST CHAR16* Path
217 )
218 {
219 CHAR16 *PathToReturn;
220 UINTN Size;
221 CONST CHAR16 *CurDir;
222
223 PathToReturn = NULL;
224 Size = 0;
225
226 ASSERT((PathToReturn == NULL && Size == 0) || (PathToReturn != NULL));
227 //
228 // convert a local path to an absolute path
229 //
230 if (StrStr(Path, L":") == NULL) {
231 CurDir = gEfiShellProtocol->GetCurDir(NULL);
232 StrnCatGrow(&PathToReturn, &Size, CurDir, 0);
233 if (*Path == L'\\') {
234 Path++;
235 }
236 }
237 StrnCatGrow(&PathToReturn, &Size, Path, 0);
238
239 CleanPath(PathToReturn);
240
241 while (PathToReturn[StrLen(PathToReturn)-1] == L'*') {
242 PathToReturn[StrLen(PathToReturn)-1] = CHAR_NULL;
243 }
244
245 return (PathToReturn);
246 }
247
248 /**
249 Function to verify all intermediate directories in the path.
250
251 @param[in] Path The pointer to the path to fix.
252
253 @retval EFI_SUCCESS The operation was successful.
254 **/
255 EFI_STATUS
256 EFIAPI
257 VerifyIntermediateDirectories (
258 IN CONST CHAR16 *Path
259 )
260 {
261 EFI_STATUS Status;
262 CHAR16 *PathCopy;
263 CHAR16 *TempSpot;
264 SHELL_FILE_HANDLE FileHandle;
265
266 ASSERT(Path != NULL);
267
268 Status = EFI_SUCCESS;
269 PathCopy = NULL;
270 PathCopy = StrnCatGrow(&PathCopy, NULL, Path, 0);
271 FileHandle = NULL;
272
273 for (TempSpot = &PathCopy[StrLen(PathCopy)-1] ; *TempSpot != CHAR_NULL && *TempSpot != L'\\' ; TempSpot = &PathCopy[StrLen(PathCopy)-1]){
274 *TempSpot = CHAR_NULL;
275 }
276 if (*TempSpot == L'\\') {
277 *TempSpot = CHAR_NULL;
278 }
279
280 if (PathCopy != NULL && *PathCopy != CHAR_NULL) {
281 Status = VerifyIntermediateDirectories(PathCopy);
282
283 if (PathCopy[StrLen(PathCopy)-1] != L':') {
284 if (!EFI_ERROR(Status)) {
285 Status = ShellOpenFileByName(PathCopy, &FileHandle, EFI_FILE_MODE_READ, 0);
286 if (FileHandle != NULL) {
287 ShellCloseFile(&FileHandle);
288 }
289 }
290 }
291 }
292
293 SHELL_FREE_NON_NULL(PathCopy);
294
295 return (Status);
296 }
297
298 // be lazy and borrow from baselib.
299 CHAR16
300 EFIAPI
301 InternalCharToUpper (
302 IN CONST CHAR16 Char
303 );
304
305 CONST CHAR16*
306 EFIAPI
307 StrniCmp(
308 IN CONST CHAR16 *Source,
309 IN CONST CHAR16 *Target,
310 IN CONST UINTN Count
311 )
312 {
313 UINTN LoopCount;
314 CHAR16 Char1;
315 CHAR16 Char2;
316
317 ASSERT(Source != NULL);
318 ASSERT(Target != NULL);
319
320 for (LoopCount = 0 ; LoopCount < Count ; LoopCount++) {
321 Char1 = InternalCharToUpper(Source[LoopCount]);
322 Char2 = InternalCharToUpper(Target[LoopCount]);
323 if (Char1 != Char2) {
324 return (&Source[LoopCount]);
325 }
326 }
327 return (NULL);
328 }
329