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