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
;
151 (*Drive
)[Splitter
- FullPath
+ 1] = CHAR_NULL
;
153 *Path
= AllocateCopyPool (StrSize (Splitter
+ 1), Splitter
+ 1);
156 return EFI_OUT_OF_RESOURCES
;
165 Function for 'cd' command.
167 @param[in] ImageHandle Handle to the Image (NULL if Internal).
168 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
173 IN EFI_HANDLE ImageHandle
,
174 IN EFI_SYSTEM_TABLE
*SystemTable
182 CHAR16
*ProblemParam
;
183 SHELL_STATUS ShellStatus
;
184 CONST CHAR16
*Param1
;
192 ShellStatus
= SHELL_SUCCESS
;
200 Status
= CommandInit();
201 ASSERT_EFI_ERROR(Status
);
204 // initialize the shell lib (we must be in non-auto-init...)
206 Status
= ShellInitialize();
207 ASSERT_EFI_ERROR(Status
);
210 // parse the command line
212 Status
= ShellCommandLineParse (EmptyParamList
, &Package
, &ProblemParam
, TRUE
);
213 if (EFI_ERROR(Status
)) {
214 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
215 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellLevel2HiiHandle
, L
"cd", ProblemParam
);
216 FreePool(ProblemParam
);
217 ShellStatus
= SHELL_INVALID_PARAMETER
;
226 if (ShellCommandLineGetFlag(Package
, L
"-?")) {
228 } else if (ShellCommandLineGetRawValue(Package
, 2) != NULL
) {
229 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel2HiiHandle
, L
"cd");
230 ShellStatus
= SHELL_INVALID_PARAMETER
;
233 // remember that param 0 is the command name
234 // If there are 0 value parameters, then print the current directory
235 // else If there are 2 value parameters, then print the error message
236 // else If there is 1 value paramerer , then change the directory
238 Cwd
= ShellGetCurrentDir (NULL
);
240 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN(STR_GEN_NO_CWD
), gShellLevel2HiiHandle
, L
"cd");
241 ShellStatus
= SHELL_NOT_FOUND
;
243 Param1
= ShellCommandLineGetRawValue (Package
, 1);
244 if (Param1
== NULL
) {
246 // display the current directory
248 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN(STR_CD_PRINT
), gShellLevel2HiiHandle
, Cwd
);
250 Param1Copy
= CatSPrint (NULL
, L
"%s", Param1
, NULL
);
251 for (Walker
= Param1Copy
; Walker
!= NULL
&& *Walker
!= CHAR_NULL
; Walker
++) {
252 if (*Walker
== L
'\"') {
253 CopyMem (Walker
, Walker
+ 1, StrSize(Walker
) - sizeof(Walker
[0]));
257 if (Param1Copy
!= NULL
&& IsCurrentFileSystem (Param1Copy
, Cwd
)) {
258 Status
= ReplaceDriveWithCwd (&Param1Copy
,Cwd
);
261 // Can't use cd command to change filesystem.
263 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"cd");
264 Status
= EFI_NOT_FOUND
;
267 if (!EFI_ERROR(Status
) && Param1Copy
!= NULL
) {
268 Splitter
= StrStr (Cwd
, L
":");
269 if (Param1Copy
[0] == L
'\\') {
271 // Absolute Path on current drive letter.
273 TotalSize
= ((Splitter
- Cwd
+ 1) * sizeof(CHAR16
)) + StrSize(Param1Copy
);
274 TempBuffer
= AllocateZeroPool (TotalSize
);
275 if (TempBuffer
== NULL
) {
276 Status
= EFI_OUT_OF_RESOURCES
;
278 StrnCpyS (TempBuffer
, TotalSize
/ sizeof(CHAR16
), Cwd
, (Splitter
- Cwd
+ 1));
279 StrCatS (TempBuffer
, TotalSize
/ sizeof(CHAR16
), Param1Copy
);
281 FreePool (Param1Copy
);
282 Param1Copy
= TempBuffer
;
286 if (StrStr (Param1Copy
,L
":") == NULL
) {
287 TotalSize
= StrSize (Cwd
) + StrSize (Param1Copy
);
288 TempBuffer
= AllocateZeroPool (TotalSize
);
289 if (TempBuffer
== NULL
) {
290 Status
= EFI_OUT_OF_RESOURCES
;
292 StrCpyS (TempBuffer
, TotalSize
/ sizeof (CHAR16
), Cwd
);
293 StrCatS (TempBuffer
, TotalSize
/ sizeof (CHAR16
), L
"\\");
294 StrCatS (TempBuffer
, TotalSize
/ sizeof (CHAR16
), Param1Copy
);
296 FreePool (Param1Copy
);
297 Param1Copy
= TempBuffer
;
304 if (!EFI_ERROR(Status
)) {
305 Param1Copy
= PathCleanUpDirectories (Param1Copy
);
306 Status
= ExtractDriveAndPath (Param1Copy
, &Drive
, &Path
);
309 if (!EFI_ERROR (Status
) && Drive
!= NULL
&& Path
!= NULL
) {
310 if (EFI_ERROR(ShellIsDirectory (Param1Copy
))) {
311 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN(STR_GEN_NOT_DIR
), gShellLevel2HiiHandle
, L
"cd", Param1Copy
);
312 ShellStatus
= SHELL_NOT_FOUND
;
314 Status
= gEfiShellProtocol
->SetCurDir (Drive
, Path
+ 1);
315 if (EFI_ERROR (Status
)) {
316 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN(STR_GEN_DIR_NF
), gShellLevel2HiiHandle
, L
"cd", Param1Copy
);
317 ShellStatus
= SHELL_NOT_FOUND
;
330 FreePool (Param1Copy
);
336 // free the command line package
338 ShellCommandLineFreeVarList (Package
);
343 return (ShellStatus
);