]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.c
Update code to ensure the pointer ‘CurrentName’ in function ‘PerformSingleMappingDisp...
[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
40 /**
41 Get the filename to get help text from if not using HII.
42
43 @retval The filename.
44 **/
45 CONST CHAR16*
46 EFIAPI
47 ShellCommandGetManFileNameLevel2 (
48 VOID
49 )
50 {
51 return (mFileName);
52 }
53
54 /**
55 Constructor for the Shell Level 2 Commands library.
56
57 Install the handlers for level 2 UEFI Shell 2.0 commands.
58
59 @param ImageHandle the image handle of the process
60 @param SystemTable the EFI System Table pointer
61
62 @retval EFI_SUCCESS the shell command handlers were installed sucessfully
63 @retval EFI_UNSUPPORTED the shell level required was not found.
64 **/
65 EFI_STATUS
66 EFIAPI
67 ShellLevel2CommandsLibConstructor (
68 IN EFI_HANDLE ImageHandle,
69 IN EFI_SYSTEM_TABLE *SystemTable
70 )
71 {
72 //
73 // if shell level is less than 2 do nothing
74 //
75 if (PcdGet8(PcdShellSupportLevel) < 2) {
76 return (EFI_SUCCESS);
77 }
78
79 gShellLevel2HiiHandle = HiiAddPackages (&gShellLevel2HiiGuid, gImageHandle, UefiShellLevel2CommandsLibStrings, NULL);
80 if (gShellLevel2HiiHandle == NULL) {
81 return (EFI_DEVICE_ERROR);
82 }
83
84 //
85 // install our shell command handlers that are always installed
86 //
87 ShellCommandRegisterCommandName(L"attrib", ShellCommandRunAttrib , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_ATTRIB) );
88 ShellCommandRegisterCommandName(L"cd", ShellCommandRunCd , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_CD) );
89 ShellCommandRegisterCommandName(L"cp", ShellCommandRunCp , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_CP) );
90 ShellCommandRegisterCommandName(L"load", ShellCommandRunLoad , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_LOAD) );
91 ShellCommandRegisterCommandName(L"map", ShellCommandRunMap , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_MAP) );
92 ShellCommandRegisterCommandName(L"mkdir", ShellCommandRunMkDir , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_MKDIR) );
93 ShellCommandRegisterCommandName(L"mv", ShellCommandRunMv , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_MV) );
94 ShellCommandRegisterCommandName(L"parse", ShellCommandRunParse , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_PARSE) );
95 ShellCommandRegisterCommandName(L"reset", ShellCommandRunReset , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_RESET) );
96 ShellCommandRegisterCommandName(L"set", ShellCommandRunSet , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_SET) );
97 ShellCommandRegisterCommandName(L"ls", ShellCommandRunLs , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_LS) );
98 ShellCommandRegisterCommandName(L"rm", ShellCommandRunRm , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_RM) );
99 ShellCommandRegisterCommandName(L"vol", ShellCommandRunVol , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_VOL) );
100
101 //
102 // support for permenant (built in) aliases
103 //
104 ShellCommandRegisterAlias(L"rm", L"del");
105 ShellCommandRegisterAlias(L"ls", L"dir");
106 ShellCommandRegisterAlias(L"cp", L"copy");
107 ShellCommandRegisterAlias(L"mkdir", L"md");
108 ShellCommandRegisterAlias(L"cd ..", L"cd..");
109 ShellCommandRegisterAlias(L"cd \\", L"cd\\");
110 ShellCommandRegisterAlias(L"ren", L"mv");
111 //
112 // These are installed in level 2 or 3...
113 //
114 if (PcdGet8(PcdShellSupportLevel) == 2 || PcdGet8(PcdShellSupportLevel) == 3) {
115 ShellCommandRegisterCommandName(L"date", ShellCommandRunDate , ShellCommandGetManFileNameLevel2, PcdGet8(PcdShellSupportLevel), L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_DATE) );
116 ShellCommandRegisterCommandName(L"time", ShellCommandRunTime , ShellCommandGetManFileNameLevel2, PcdGet8(PcdShellSupportLevel), L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_TIME) );
117 ShellCommandRegisterCommandName(L"timezone", ShellCommandRunTimeZone, ShellCommandGetManFileNameLevel2, PcdGet8(PcdShellSupportLevel), L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_TIMEZONE));
118 } else {
119 DEBUG_CODE_BEGIN();
120 //
121 // we want to be able to test these so install them under a different name in debug mode...
122 //
123 ShellCommandRegisterCommandName(L"l2date", ShellCommandRunDate , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_DATE) );
124 ShellCommandRegisterCommandName(L"l2time", ShellCommandRunTime , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_TIME) );
125 ShellCommandRegisterCommandName(L"l2timezone", ShellCommandRunTimeZone, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_TIMEZONE));
126 DEBUG_CODE_END();
127 }
128
129 return (EFI_SUCCESS);
130 }
131
132 /**
133 Destructor for the library. free any resources.
134
135 @param ImageHandle The image handle of the process.
136 @param SystemTable The EFI System Table pointer.
137
138 @retval EFI_SUCCESS Always returned.
139 **/
140 EFI_STATUS
141 EFIAPI
142 ShellLevel2CommandsLibDestructor (
143 IN EFI_HANDLE ImageHandle,
144 IN EFI_SYSTEM_TABLE *SystemTable
145 )
146 {
147 if (gShellLevel2HiiHandle != NULL) {
148 HiiRemovePackages(gShellLevel2HiiHandle);
149 }
150 return (EFI_SUCCESS);
151 }
152
153 /**
154 returns a fully qualified directory (contains a map drive at the begining)
155 path from a unknown directory path.
156
157 If Path is already fully qualified this will return a duplicat otherwise this
158 will use get the current directory and use that to build the fully qualified
159 version.
160
161 if the return value is not NULL it must be caller freed.
162
163 @param[in] Path The unknown Path Value
164
165 @retval NULL A memory allocation failed
166 @retval NULL A fully qualified path could not be discovered.
167 @retval other An allocated pointer to a fuly qualified path.
168 **/
169 CHAR16*
170 EFIAPI
171 GetFullyQualifiedPath(
172 IN CONST CHAR16* Path
173 )
174 {
175 CHAR16 *PathToReturn;
176 UINTN Size;
177 CONST CHAR16 *CurDir;
178
179 PathToReturn = NULL;
180 Size = 0;
181
182 ASSERT((PathToReturn == NULL && Size == 0) || (PathToReturn != NULL));
183 //
184 // convert a local path to an absolute path
185 //
186 if (StrStr(Path, L":") == NULL) {
187 CurDir = gEfiShellProtocol->GetCurDir(NULL);
188 StrnCatGrow(&PathToReturn, &Size, CurDir, 0);
189 if (*Path == L'\\') {
190 Path++;
191 }
192 }
193 StrnCatGrow(&PathToReturn, &Size, Path, 0);
194
195 PathCleanUpDirectories(PathToReturn);
196
197 if (PathToReturn == NULL) {
198 return NULL;
199 }
200
201 while (PathToReturn[StrLen(PathToReturn)-1] == L'*') {
202 PathToReturn[StrLen(PathToReturn)-1] = CHAR_NULL;
203 }
204
205 return (PathToReturn);
206 }
207
208 /**
209 Function to verify all intermediate directories in the path.
210
211 @param[in] Path The pointer to the path to fix.
212
213 @retval EFI_SUCCESS The operation was successful.
214 **/
215 EFI_STATUS
216 EFIAPI
217 VerifyIntermediateDirectories (
218 IN CONST CHAR16 *Path
219 )
220 {
221 EFI_STATUS Status;
222 CHAR16 *PathCopy;
223 CHAR16 *TempSpot;
224 SHELL_FILE_HANDLE FileHandle;
225
226 ASSERT(Path != NULL);
227
228 Status = EFI_SUCCESS;
229 PathCopy = NULL;
230 PathCopy = StrnCatGrow(&PathCopy, NULL, Path, 0);
231 FileHandle = NULL;
232
233 if (PathCopy == NULL) {
234 return (EFI_OUT_OF_RESOURCES);
235 }
236
237 for (TempSpot = &PathCopy[StrLen(PathCopy)-1] ; *TempSpot != CHAR_NULL && *TempSpot != L'\\' ; TempSpot = &PathCopy[StrLen(PathCopy)-1]){
238 *TempSpot = CHAR_NULL;
239 }
240 if (*TempSpot == L'\\') {
241 *TempSpot = CHAR_NULL;
242 }
243
244 if (PathCopy != NULL && *PathCopy != CHAR_NULL) {
245 Status = VerifyIntermediateDirectories(PathCopy);
246
247 if (PathCopy[StrLen(PathCopy)-1] != L':') {
248 if (!EFI_ERROR(Status)) {
249 Status = ShellOpenFileByName(PathCopy, &FileHandle, EFI_FILE_MODE_READ, 0);
250 if (FileHandle != NULL) {
251 ShellCloseFile(&FileHandle);
252 }
253 }
254 }
255 }
256
257 SHELL_FREE_NON_NULL(PathCopy);
258
259 return (Status);
260 }
261
262 /**
263 Be lazy and borrow from baselib.
264
265 @param[in] Char The character to convert to upper case.
266
267 @return Char as an upper case character.
268 **/
269 CHAR16
270 EFIAPI
271 InternalCharToUpper (
272 IN CONST CHAR16 Char
273 );
274
275 /**
276 String comparison without regard to case for a limited number of characters.
277
278 @param[in] Source The first item to compare.
279 @param[in] Target The second item to compare.
280 @param[in] Count How many characters to compare.
281
282 @retval NULL Source and Target are identical strings without regard to case.
283 @return The location in Source where there is a difference.
284 **/
285 CONST CHAR16*
286 EFIAPI
287 StrniCmp(
288 IN CONST CHAR16 *Source,
289 IN CONST CHAR16 *Target,
290 IN CONST UINTN Count
291 )
292 {
293 UINTN LoopCount;
294 CHAR16 Char1;
295 CHAR16 Char2;
296
297 ASSERT(Source != NULL);
298 ASSERT(Target != NULL);
299
300 for (LoopCount = 0 ; LoopCount < Count ; LoopCount++) {
301 Char1 = InternalCharToUpper(Source[LoopCount]);
302 Char2 = InternalCharToUpper(Target[LoopCount]);
303 if (Char1 != Char2) {
304 return (&Source[LoopCount]);
305 }
306 }
307 return (NULL);
308 }
309