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 SPDX-License-Identifier: BSD-2-Clause-Patent
12 #include "UefiShellLevel2CommandsLib.h"
15 Function will replace drive identifier with CWD.
17 If FullPath begining with ':' is invalid path, then ASSERT.
18 If FullPath not include dirve identifier , then do nothing.
19 If FullPath likes "fs0:\xx" or "fs0:/xx" , then do nothing.
20 If FullPath likes "fs0:xxx" or "fs0:", the drive replaced by CWD.
22 @param[in, out] FullPath The pointer to the string containing the path.
23 @param[in] Cwd Current directory.
25 @retval EFI_SUCCESS Success.
26 @retval EFI_OUT_OF_SOURCES A memory allocation failed.
30 IN OUT CHAR16
**FullPath
,
42 if ((FullPath
== NULL
) || (*FullPath
== NULL
)) {
46 Splitter
= StrStr (*FullPath
, L
":");
47 ASSERT (Splitter
!= *FullPath
);
49 if ((Splitter
!= NULL
) && (*(Splitter
+ 1) != L
'\\') && (*(Splitter
+ 1) != L
'/')) {
50 TotalSize
= StrSize (Cwd
) + StrSize (Splitter
+ 1);
51 TempBuffer
= AllocateZeroPool (TotalSize
);
52 if (TempBuffer
== NULL
) {
53 return EFI_OUT_OF_RESOURCES
;
56 StrCpyS (TempBuffer
, TotalSize
/ sizeof (CHAR16
), Cwd
);
57 StrCatS (TempBuffer
, TotalSize
/ sizeof (CHAR16
), L
"\\");
58 StrCatS (TempBuffer
, TotalSize
/ sizeof (CHAR16
), Splitter
+ 1);
61 *FullPath
= TempBuffer
;
68 function to determine if FullPath is under current filesystem.
70 @param[in] FullPath The target location to determine.
71 @param[in] Cwd Current directory.
73 @retval TRUE The FullPath is in the current filesystem.
74 @retval FALSE The FullPaht isn't in the current filesystem.
78 IN CONST CHAR16
*FullPath
,
88 ASSERT (FullPath
!= NULL
);
90 Splitter1
= StrStr (FullPath
, L
":");
91 if (Splitter1
== NULL
) {
95 Splitter2
= StrStr (Cwd
, L
":");
97 if (((UINTN
)Splitter1
- (UINTN
)FullPath
) != ((UINTN
)Splitter2
- (UINTN
)Cwd
)) {
100 if (StrniCmp (FullPath
, Cwd
, ((UINTN
)Splitter1
- (UINTN
)FullPath
) / sizeof (CHAR16
)) == 0) {
109 Extract drive string and path string from FullPath.
111 The caller must be free Drive and Path.
113 @param[in] FullPath A path to be extracted.
114 @param[out] Drive Buffer to save drive identifier.
115 @param[out] Path Buffer to save path.
117 @retval EFI_SUCCESS Success.
118 @retval EFI_OUT_OF_RESOUCES A memory allocation failed.
121 ExtractDriveAndPath (
122 IN CONST CHAR16
*FullPath
,
129 ASSERT (FullPath
!= NULL
);
131 Splitter
= StrStr (FullPath
, L
":");
133 if (Splitter
== NULL
) {
135 *Path
= AllocateCopyPool (StrSize (FullPath
), FullPath
);
137 return EFI_OUT_OF_RESOURCES
;
140 if (*(Splitter
+ 1) == CHAR_NULL
) {
141 *Drive
= AllocateCopyPool (StrSize (FullPath
), FullPath
);
143 if (*Drive
== NULL
) {
144 return EFI_OUT_OF_RESOURCES
;
147 *Drive
= AllocateCopyPool ((Splitter
- FullPath
+ 2) * sizeof (CHAR16
), FullPath
);
148 if (*Drive
== NULL
) {
149 return EFI_OUT_OF_RESOURCES
;
152 (*Drive
)[Splitter
- FullPath
+ 1] = CHAR_NULL
;
154 *Path
= AllocateCopyPool (StrSize (Splitter
+ 1), Splitter
+ 1);
157 return EFI_OUT_OF_RESOURCES
;
166 Function for 'cd' command.
168 @param[in] ImageHandle Handle to the Image (NULL if Internal).
169 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
174 IN EFI_HANDLE ImageHandle
,
175 IN EFI_SYSTEM_TABLE
*SystemTable
183 CHAR16
*ProblemParam
;
184 SHELL_STATUS ShellStatus
;
185 CONST CHAR16
*Param1
;
193 ShellStatus
= SHELL_SUCCESS
;
201 Status
= CommandInit ();
202 ASSERT_EFI_ERROR (Status
);
205 // initialize the shell lib (we must be in non-auto-init...)
207 Status
= ShellInitialize ();
208 ASSERT_EFI_ERROR (Status
);
211 // parse the command line
213 Status
= ShellCommandLineParse (EmptyParamList
, &Package
, &ProblemParam
, TRUE
);
214 if (EFI_ERROR (Status
)) {
215 if ((Status
== EFI_VOLUME_CORRUPTED
) && (ProblemParam
!= NULL
)) {
216 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellLevel2HiiHandle
, L
"cd", ProblemParam
);
217 FreePool (ProblemParam
);
218 ShellStatus
= SHELL_INVALID_PARAMETER
;
227 if (ShellCommandLineGetFlag (Package
, L
"-?")) {
229 } else if (ShellCommandLineGetRawValue (Package
, 2) != NULL
) {
230 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel2HiiHandle
, L
"cd");
231 ShellStatus
= SHELL_INVALID_PARAMETER
;
234 // remember that param 0 is the command name
235 // If there are 0 value parameters, then print the current directory
236 // else If there are 2 value parameters, then print the error message
237 // else If there is 1 value paramerer , then change the directory
239 Cwd
= ShellGetCurrentDir (NULL
);
241 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_CWD
), gShellLevel2HiiHandle
, L
"cd");
242 ShellStatus
= SHELL_NOT_FOUND
;
244 Param1
= ShellCommandLineGetRawValue (Package
, 1);
245 if (Param1
== NULL
) {
247 // display the current directory
249 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_CD_PRINT
), gShellLevel2HiiHandle
, Cwd
);
251 Param1Copy
= CatSPrint (NULL
, L
"%s", Param1
, NULL
);
252 for (Walker
= Param1Copy
; Walker
!= NULL
&& *Walker
!= CHAR_NULL
; Walker
++) {
253 if (*Walker
== L
'\"') {
254 CopyMem (Walker
, Walker
+ 1, StrSize (Walker
) - sizeof (Walker
[0]));
258 if ((Param1Copy
!= NULL
) && IsCurrentFileSystem (Param1Copy
, Cwd
)) {
259 Status
= ReplaceDriveWithCwd (&Param1Copy
, Cwd
);
262 // Can't use cd command to change filesystem.
264 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"cd");
265 Status
= EFI_NOT_FOUND
;
268 if (!EFI_ERROR (Status
) && (Param1Copy
!= NULL
)) {
269 Splitter
= StrStr (Cwd
, L
":");
270 if (Param1Copy
[0] == L
'\\') {
272 // Absolute Path on current drive letter.
274 TotalSize
= ((Splitter
- Cwd
+ 1) * sizeof (CHAR16
)) + StrSize (Param1Copy
);
275 TempBuffer
= AllocateZeroPool (TotalSize
);
276 if (TempBuffer
== NULL
) {
277 Status
= EFI_OUT_OF_RESOURCES
;
279 StrnCpyS (TempBuffer
, TotalSize
/ sizeof (CHAR16
), Cwd
, (Splitter
- Cwd
+ 1));
280 StrCatS (TempBuffer
, TotalSize
/ sizeof (CHAR16
), Param1Copy
);
282 FreePool (Param1Copy
);
283 Param1Copy
= TempBuffer
;
287 if (StrStr (Param1Copy
, L
":") == NULL
) {
288 TotalSize
= StrSize (Cwd
) + StrSize (Param1Copy
);
289 TempBuffer
= AllocateZeroPool (TotalSize
);
290 if (TempBuffer
== NULL
) {
291 Status
= EFI_OUT_OF_RESOURCES
;
293 StrCpyS (TempBuffer
, TotalSize
/ sizeof (CHAR16
), Cwd
);
294 StrCatS (TempBuffer
, TotalSize
/ sizeof (CHAR16
), L
"\\");
295 StrCatS (TempBuffer
, TotalSize
/ sizeof (CHAR16
), Param1Copy
);
297 FreePool (Param1Copy
);
298 Param1Copy
= TempBuffer
;
305 if (!EFI_ERROR (Status
)) {
306 Param1Copy
= PathCleanUpDirectories (Param1Copy
);
307 Status
= ExtractDriveAndPath (Param1Copy
, &Drive
, &Path
);
310 if (!EFI_ERROR (Status
) && (Drive
!= NULL
) && (Path
!= NULL
)) {
311 if (EFI_ERROR (ShellIsDirectory (Param1Copy
))) {
312 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_NOT_DIR
), gShellLevel2HiiHandle
, L
"cd", Param1Copy
);
313 ShellStatus
= SHELL_NOT_FOUND
;
315 Status
= gEfiShellProtocol
->SetCurDir (Drive
, Path
+ 1);
316 if (EFI_ERROR (Status
)) {
317 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_DIR_NF
), gShellLevel2HiiHandle
, L
"cd", Param1Copy
);
318 ShellStatus
= SHELL_NOT_FOUND
;
331 FreePool (Param1Copy
);
337 // free the command line package
339 ShellCommandLineFreeVarList (Package
);
344 return (ShellStatus
);