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