blob: ce3d87ba502f745bf9e9a17f85e4c71c455bf053 [file] [log] [blame]
jcarseya405b862010-09-14 05:18:09 +00001/** @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,
jcarseyb54fd042011-03-25 20:58:08 +000019 timezone*,
20 vol
jcarseya405b862010-09-14 05:18:09 +000021
22 * functions are non-interactive only
23
24
jcarseyb54fd042011-03-25 20:58:08 +000025 Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
jcarseya405b862010-09-14 05:18:09 +000026 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
37CONST CHAR16 mFileName[] = L"ShellCommands";
38EFI_HANDLE gShellLevel2HiiHandle = NULL;
39CONST EFI_GUID gShellLevel2HiiGuid = \
40 { \
41 0xf95a7ccc, 0x4c55, 0x4426, { 0xa7, 0xb4, 0xdc, 0x89, 0x61, 0x95, 0xb, 0xae } \
42 };
43
jcarseyb54fd042011-03-25 20:58:08 +000044/**
45 Get the filename to get help text from if not using HII.
46
47 @retval The filename.
48**/
jcarseya405b862010-09-14 05:18:09 +000049CONST CHAR16*
50EFIAPI
51ShellCommandGetManFileNameLevel2 (
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**/
69EFI_STATUS
70EFIAPI
71ShellLevel2CommandsLibConstructor (
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) {
jcarsey82571fb2011-05-16 22:12:20 +000080 return (EFI_SUCCESS);
jcarseya405b862010-09-14 05:18:09 +000081 }
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) );
jcarseyb54fd042011-03-25 20:58:08 +0000103 ShellCommandRegisterCommandName(L"vol", ShellCommandRunVol , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_VOL) );
jcarseya405b862010-09-14 05:18:09 +0000104
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\\");
jcarseya49016b2011-04-13 23:35:59 +0000114 ShellCommandRegisterAlias(L"ren", L"mv");
jcarseya405b862010-09-14 05:18:09 +0000115 //
116 // These are installed in level 2 or 3...
117 //
118 if (PcdGet8(PcdShellSupportLevel) == 2 || PcdGet8(PcdShellSupportLevel) == 3) {
119 ShellCommandRegisterCommandName(L"date", ShellCommandRunDate , ShellCommandGetManFileNameLevel2, PcdGet8(PcdShellSupportLevel), L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_DATE) );
120 ShellCommandRegisterCommandName(L"time", ShellCommandRunTime , ShellCommandGetManFileNameLevel2, PcdGet8(PcdShellSupportLevel), L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_TIME) );
121 ShellCommandRegisterCommandName(L"timezone", ShellCommandRunTimeZone, ShellCommandGetManFileNameLevel2, PcdGet8(PcdShellSupportLevel), L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_TIMEZONE));
122 } else {
123 DEBUG_CODE_BEGIN();
124 //
125 // we want to be able to test these so install them under a different name in debug mode...
126 //
127 ShellCommandRegisterCommandName(L"l2date", ShellCommandRunDate , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_DATE) );
128 ShellCommandRegisterCommandName(L"l2time", ShellCommandRunTime , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_TIME) );
129 ShellCommandRegisterCommandName(L"l2timezone", ShellCommandRunTimeZone, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_TIMEZONE));
130 DEBUG_CODE_END();
131 }
132
133 return (EFI_SUCCESS);
134}
135
136/**
137 Destructor for the library. free any resources.
138
139 @param ImageHandle The image handle of the process.
140 @param SystemTable The EFI System Table pointer.
141
142 @retval EFI_SUCCESS Always returned.
143**/
144EFI_STATUS
145EFIAPI
146ShellLevel2CommandsLibDestructor (
147 IN EFI_HANDLE ImageHandle,
148 IN EFI_SYSTEM_TABLE *SystemTable
149 )
150{
151 if (gShellLevel2HiiHandle != NULL) {
152 HiiRemovePackages(gShellLevel2HiiHandle);
153 }
154 return (EFI_SUCCESS);
155}
156
157/**
jcarseya405b862010-09-14 05:18:09 +0000158 returns a fully qualified directory (contains a map drive at the begining)
159 path from a unknown directory path.
160
161 If Path is already fully qualified this will return a duplicat otherwise this
162 will use get the current directory and use that to build the fully qualified
163 version.
164
165 if the return value is not NULL it must be caller freed.
166
167 @param[in] Path The unknown Path Value
168
169 @retval NULL A memory allocation failed
170 @retval NULL a fully qualified path could not be discovered.
171 @retval other pointer to a fuly qualified path.
172**/
173CHAR16*
174EFIAPI
175GetFullyQualifiedPath(
176 IN CONST CHAR16* Path
177 )
178{
179 CHAR16 *PathToReturn;
180 UINTN Size;
181 CONST CHAR16 *CurDir;
182
183 PathToReturn = NULL;
184 Size = 0;
185
186 ASSERT((PathToReturn == NULL && Size == 0) || (PathToReturn != NULL));
187 //
188 // convert a local path to an absolute path
189 //
190 if (StrStr(Path, L":") == NULL) {
191 CurDir = gEfiShellProtocol->GetCurDir(NULL);
192 StrnCatGrow(&PathToReturn, &Size, CurDir, 0);
193 if (*Path == L'\\') {
194 Path++;
195 }
196 }
197 StrnCatGrow(&PathToReturn, &Size, Path, 0);
198
jcarseyab945872011-06-30 22:58:53 +0000199 PathCleanUpDirectories(PathToReturn);
jcarseya405b862010-09-14 05:18:09 +0000200
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**/
215EFI_STATUS
216EFIAPI
217VerifyIntermediateDirectories (
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 for (TempSpot = &PathCopy[StrLen(PathCopy)-1] ; *TempSpot != CHAR_NULL && *TempSpot != L'\\' ; TempSpot = &PathCopy[StrLen(PathCopy)-1]){
234 *TempSpot = CHAR_NULL;
235 }
236 if (*TempSpot == L'\\') {
237 *TempSpot = CHAR_NULL;
238 }
239
240 if (PathCopy != NULL && *PathCopy != CHAR_NULL) {
241 Status = VerifyIntermediateDirectories(PathCopy);
242
243 if (PathCopy[StrLen(PathCopy)-1] != L':') {
244 if (!EFI_ERROR(Status)) {
245 Status = ShellOpenFileByName(PathCopy, &FileHandle, EFI_FILE_MODE_READ, 0);
246 if (FileHandle != NULL) {
247 ShellCloseFile(&FileHandle);
248 }
249 }
250 }
251 }
252
253 SHELL_FREE_NON_NULL(PathCopy);
254
255 return (Status);
256}
257
jcarseyb54fd042011-03-25 20:58:08 +0000258/**
259 Be lazy and borrow from baselib.
260
261 @param[in] Char The character to convert to upper case.
262
263 @return Char as an upper case character.
264**/
jcarseya405b862010-09-14 05:18:09 +0000265CHAR16
266EFIAPI
267InternalCharToUpper (
268 IN CONST CHAR16 Char
269 );
270
jcarseyb54fd042011-03-25 20:58:08 +0000271/**
272 String comparison without regard to case for a limited number of characters.
273
274 @param[in] Source The first item to compare.
275 @param[in] Target The second item to compare.
276 @param[in] Count How many characters to compare.
277
278 @retval NULL Source and Target are identical strings without regard to case.
279 @return The location in Source where there is a difference.
280**/
jcarseya405b862010-09-14 05:18:09 +0000281CONST CHAR16*
282EFIAPI
283StrniCmp(
284 IN CONST CHAR16 *Source,
285 IN CONST CHAR16 *Target,
286 IN CONST UINTN Count
287 )
288{
289 UINTN LoopCount;
290 CHAR16 Char1;
291 CHAR16 Char2;
292
293 ASSERT(Source != NULL);
294 ASSERT(Target != NULL);
295
296 for (LoopCount = 0 ; LoopCount < Count ; LoopCount++) {
297 Char1 = InternalCharToUpper(Source[LoopCount]);
298 Char2 = InternalCharToUpper(Target[LoopCount]);
299 if (Char1 != Char2) {
300 return (&Source[LoopCount]);
301 }
302 }
303 return (NULL);
304}
305