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