2 Main file for attrib shell level 2 function.
4 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
5 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
6 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
7 Copyright (c) 2018, Dell Technologies. All rights reserved.<BR>
8 This program and the accompanying materials
9 are licensed and made available under the terms and conditions of the BSD License
10 which accompanies this distribution. The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 #include "UefiShellLevel2CommandsLib.h"
21 Function will replace drive identifier with CWD.
23 If FullPath begining with ':' is invalid path, then ASSERT.
24 If FullPath not include dirve identifier , then do nothing.
25 If FullPath likes "fs0:\xx" or "fs0:/xx" , then do nothing.
26 If FullPath likes "fs0:xxx" or "fs0:", the drive replaced by CWD.
28 @param[in, out] FullPath The pointer to the string containing the path.
29 @param[in] Cwd Current directory.
31 @retval EFI_SUCCESS Success.
32 @retval EFI_OUT_OF_SOURCES A memory allocation failed.
36 IN OUT CHAR16
**FullPath
,
48 if (FullPath
== NULL
|| *FullPath
== NULL
) {
52 Splitter
= StrStr (*FullPath
, L
":");
53 ASSERT(Splitter
!= *FullPath
);
55 if (Splitter
!= NULL
&& *(Splitter
+ 1) != L
'\\' && *(Splitter
+ 1) != L
'/') {
56 TotalSize
= StrSize (Cwd
) + StrSize (Splitter
+ 1);
57 TempBuffer
= AllocateZeroPool (TotalSize
);
58 if (TempBuffer
== NULL
) {
59 return EFI_OUT_OF_RESOURCES
;
62 StrCpyS (TempBuffer
, TotalSize
/ sizeof(CHAR16
), Cwd
);
63 StrCatS (TempBuffer
, TotalSize
/ sizeof(CHAR16
), L
"\\");
64 StrCatS (TempBuffer
, TotalSize
/ sizeof(CHAR16
), Splitter
+ 1);
67 *FullPath
= TempBuffer
;
74 function to determine if FullPath is under current filesystem.
76 @param[in] FullPath The target location to determine.
77 @param[in] Cwd Current directory.
79 @retval TRUE The FullPath is in the current filesystem.
80 @retval FALSE The FullPaht isn't in the current filesystem.
84 IN CONST CHAR16
*FullPath
,
94 ASSERT(FullPath
!= NULL
);
96 Splitter1
= StrStr (FullPath
, L
":");
97 if (Splitter1
== NULL
) {
101 Splitter2
= StrStr (Cwd
, L
":");
103 if (((UINTN
) Splitter1
- (UINTN
) FullPath
) != ((UINTN
) Splitter2
- (UINTN
) Cwd
)) {
106 if (StrniCmp (FullPath
, Cwd
, ((UINTN
) Splitter1
- (UINTN
) FullPath
) / sizeof (CHAR16
)) == 0) {
115 Extract drive string and path string from FullPath.
117 The caller must be free Drive and Path.
119 @param[in] FullPath A path to be extracted.
120 @param[out] Drive Buffer to save drive identifier.
121 @param[out] Path Buffer to save path.
123 @retval EFI_SUCCESS Success.
124 @retval EFI_OUT_OF_RESOUCES A memory allocation failed.
127 ExtractDriveAndPath (
128 IN CONST CHAR16
*FullPath
,
135 ASSERT (FullPath
!= NULL
);
137 Splitter
= StrStr (FullPath
, L
":");
139 if (Splitter
== NULL
) {
141 *Path
= AllocateCopyPool (StrSize (FullPath
), FullPath
);
143 return EFI_OUT_OF_RESOURCES
;
146 if (*(Splitter
+ 1) == CHAR_NULL
) {
147 *Drive
= AllocateCopyPool (StrSize (FullPath
), FullPath
);
149 if (*Drive
== NULL
) {
150 return EFI_OUT_OF_RESOURCES
;
153 *Drive
= AllocateCopyPool ((Splitter
- FullPath
+ 2) * sizeof(CHAR16
), FullPath
);
154 if (*Drive
== NULL
) {
155 return EFI_OUT_OF_RESOURCES
;
157 (*Drive
)[Splitter
- FullPath
+ 1] = CHAR_NULL
;
159 *Path
= AllocateCopyPool (StrSize (Splitter
+ 1), Splitter
+ 1);
162 return EFI_OUT_OF_RESOURCES
;
171 Function for 'cd' command.
173 @param[in] ImageHandle Handle to the Image (NULL if Internal).
174 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
179 IN EFI_HANDLE ImageHandle
,
180 IN EFI_SYSTEM_TABLE
*SystemTable
188 CHAR16
*ProblemParam
;
189 SHELL_STATUS ShellStatus
;
190 CONST CHAR16
*Param1
;
198 ShellStatus
= SHELL_SUCCESS
;
206 Status
= CommandInit();
207 ASSERT_EFI_ERROR(Status
);
210 // initialize the shell lib (we must be in non-auto-init...)
212 Status
= ShellInitialize();
213 ASSERT_EFI_ERROR(Status
);
216 // parse the command line
218 Status
= ShellCommandLineParse (EmptyParamList
, &Package
, &ProblemParam
, TRUE
);
219 if (EFI_ERROR(Status
)) {
220 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
221 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellLevel2HiiHandle
, L
"cd", ProblemParam
);
222 FreePool(ProblemParam
);
223 ShellStatus
= SHELL_INVALID_PARAMETER
;
232 if (ShellCommandLineGetFlag(Package
, L
"-?")) {
234 } else if (ShellCommandLineGetRawValue(Package
, 2) != NULL
) {
235 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel2HiiHandle
, L
"cd");
236 ShellStatus
= SHELL_INVALID_PARAMETER
;
239 // remember that param 0 is the command name
240 // If there are 0 value parameters, then print the current directory
241 // else If there are 2 value parameters, then print the error message
242 // else If there is 1 value paramerer , then change the directory
244 Cwd
= ShellGetCurrentDir (NULL
);
246 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN(STR_GEN_NO_CWD
), gShellLevel2HiiHandle
, L
"cd");
247 ShellStatus
= SHELL_NOT_FOUND
;
249 Param1
= ShellCommandLineGetRawValue (Package
, 1);
250 if (Param1
== NULL
) {
252 // display the current directory
254 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN(STR_CD_PRINT
), gShellLevel2HiiHandle
, Cwd
);
256 Param1Copy
= CatSPrint (NULL
, L
"%s", Param1
, NULL
);
257 for (Walker
= Param1Copy
; Walker
!= NULL
&& *Walker
!= CHAR_NULL
; Walker
++) {
258 if (*Walker
== L
'\"') {
259 CopyMem (Walker
, Walker
+ 1, StrSize(Walker
) - sizeof(Walker
[0]));
263 if (Param1Copy
!= NULL
&& IsCurrentFileSystem (Param1Copy
, Cwd
)) {
264 Status
= ReplaceDriveWithCwd (&Param1Copy
,Cwd
);
267 // Can't use cd command to change filesystem.
269 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"cd");
270 Status
= EFI_NOT_FOUND
;
273 if (!EFI_ERROR(Status
) && Param1Copy
!= NULL
) {
274 Splitter
= StrStr (Cwd
, L
":");
275 if (Param1Copy
[0] == L
'\\') {
277 // Absolute Path on current drive letter.
279 TotalSize
= ((Splitter
- Cwd
+ 1) * sizeof(CHAR16
)) + StrSize(Param1Copy
);
280 TempBuffer
= AllocateZeroPool (TotalSize
);
281 if (TempBuffer
== NULL
) {
282 Status
= EFI_OUT_OF_RESOURCES
;
284 StrnCpyS (TempBuffer
, TotalSize
/ sizeof(CHAR16
), Cwd
, (Splitter
- Cwd
+ 1));
285 StrCatS (TempBuffer
, TotalSize
/ sizeof(CHAR16
), Param1Copy
);
287 FreePool (Param1Copy
);
288 Param1Copy
= TempBuffer
;
292 if (StrStr (Param1Copy
,L
":") == NULL
) {
293 TotalSize
= StrSize (Cwd
) + StrSize (Param1Copy
);
294 TempBuffer
= AllocateZeroPool (TotalSize
);
295 if (TempBuffer
== NULL
) {
296 Status
= EFI_OUT_OF_RESOURCES
;
298 StrCpyS (TempBuffer
, TotalSize
/ sizeof (CHAR16
), Cwd
);
299 StrCatS (TempBuffer
, TotalSize
/ sizeof (CHAR16
), L
"\\");
300 StrCatS (TempBuffer
, TotalSize
/ sizeof (CHAR16
), Param1Copy
);
302 FreePool (Param1Copy
);
303 Param1Copy
= TempBuffer
;
310 if (!EFI_ERROR(Status
)) {
311 Param1Copy
= PathCleanUpDirectories (Param1Copy
);
312 Status
= ExtractDriveAndPath (Param1Copy
, &Drive
, &Path
);
315 if (!EFI_ERROR (Status
) && Drive
!= NULL
&& Path
!= NULL
) {
316 if (EFI_ERROR(ShellIsDirectory (Param1Copy
))) {
317 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN(STR_GEN_NOT_DIR
), gShellLevel2HiiHandle
, L
"cd", Param1Copy
);
318 ShellStatus
= SHELL_NOT_FOUND
;
320 Status
= gEfiShellProtocol
->SetCurDir (Drive
, Path
+ 1);
321 if (EFI_ERROR (Status
)) {
322 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN(STR_GEN_DIR_NF
), gShellLevel2HiiHandle
, L
"cd", Param1Copy
);
323 ShellStatus
= SHELL_NOT_FOUND
;
336 FreePool (Param1Copy
);
342 // free the command line package
344 ShellCommandLineFreeVarList (Package
);
349 return (ShellStatus
);