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