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 - 2016, Intel Corporation. All rights reserved.<BR>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include "UefiShellLevel2CommandsLib.h"
20 Function for 'cd' command.
22 @param[in] ImageHandle Handle to the Image (NULL if Internal).
23 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
28 IN EFI_HANDLE ImageHandle
,
29 IN EFI_SYSTEM_TABLE
*SystemTable
34 CONST CHAR16
*Directory
;
41 SHELL_STATUS ShellStatus
;
42 SHELL_FILE_HANDLE Handle
;
48 ShellStatus
= SHELL_SUCCESS
;
52 Status
= CommandInit();
53 ASSERT_EFI_ERROR(Status
);
56 // initialize the shell lib (we must be in non-auto-init...)
58 Status
= ShellInitialize();
59 ASSERT_EFI_ERROR(Status
);
62 // parse the command line
64 Status
= ShellCommandLineParse (EmptyParamList
, &Package
, &ProblemParam
, TRUE
);
65 if (EFI_ERROR(Status
)) {
66 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
67 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellLevel2HiiHandle
, L
"cd", ProblemParam
);
68 FreePool(ProblemParam
);
69 ShellStatus
= SHELL_INVALID_PARAMETER
;
78 if (ShellCommandLineGetFlag(Package
, L
"-?")) {
80 } else if (ShellCommandLineGetRawValue(Package
, 2) != NULL
) {
81 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel2HiiHandle
, L
"cd");
82 ShellStatus
= SHELL_INVALID_PARAMETER
;
85 // remember that param 0 is the command name
86 // If there are 0 value parameters, then print the current directory
87 // else If there are 2 value parameters, then print the error message
88 // else If there is 1 value paramerer , then change the directory
90 Param1
= ShellCommandLineGetRawValue(Package
, 1);
93 // display the current directory
95 Directory
= ShellGetCurrentDir(NULL
);
96 if (Directory
!= NULL
) {
97 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_PRINT
), gShellLevel2HiiHandle
, Directory
);
99 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_CWD
), gShellLevel2HiiHandle
, L
"cd");
100 ShellStatus
= SHELL_NOT_FOUND
;
103 Param1Copy
= CatSPrint(NULL
, L
"%s", Param1
, NULL
);
104 for (Walker
= Param1Copy
; Walker
!= NULL
&& *Walker
!= CHAR_NULL
; Walker
++) {
105 if (*Walker
== L
'\"') {
106 CopyMem(Walker
, Walker
+1, StrSize(Walker
) - sizeof(Walker
[0]));
110 if (Param1Copy
!= NULL
) {
111 Param1Copy
= PathCleanUpDirectories(Param1Copy
);
113 if (Param1Copy
!= NULL
) {
114 if (StrCmp(Param1Copy
, L
".") == 0) {
116 // nothing to do... change to current directory
118 } else if (StrCmp(Param1Copy
, L
"..") == 0) {
120 // Change up one directory...
122 Directory
= ShellGetCurrentDir(NULL
);
123 if (Directory
== NULL
) {
124 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_CWD
), gShellLevel2HiiHandle
, L
"cd");
125 ShellStatus
= SHELL_NOT_FOUND
;
127 CwdSize
= StrSize(Directory
) + sizeof(CHAR16
);
128 Cwd
= AllocateZeroPool(CwdSize
);
130 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_OUT_MEM
), gShellLevel2HiiHandle
, L
"cd");
131 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
133 StrCpyS (Cwd
, StrSize (Directory
) / sizeof (CHAR16
) + 1, Directory
);
134 StrCatS (Cwd
, StrSize (Directory
) / sizeof (CHAR16
) + 1, L
"\\");
135 Drive
= GetFullyQualifiedPath (Cwd
);
136 PathRemoveLastItem (Drive
);
140 if (ShellStatus
== SHELL_SUCCESS
&& Drive
!= NULL
) {
142 // change directory on current drive letter
144 Status
= gEfiShellProtocol
->SetCurDir(NULL
, Drive
);
145 if (Status
== EFI_NOT_FOUND
) {
146 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"cd");
147 ShellStatus
= SHELL_NOT_FOUND
;
150 } else if (StrCmp(Param1Copy
, L
"\\") == 0) {
152 // Move to root of current drive
154 Directory
= ShellGetCurrentDir(NULL
);
155 if (Directory
== NULL
) {
156 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_CWD
), gShellLevel2HiiHandle
, L
"cd");
157 ShellStatus
= SHELL_NOT_FOUND
;
159 CwdSize
= StrSize(Directory
) + sizeof(CHAR16
);
160 Cwd
= AllocateZeroPool(CwdSize
);
162 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_OUT_MEM
), gShellLevel2HiiHandle
, L
"cd");
163 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
165 StrCpyS (Cwd
, StrSize (Directory
) / sizeof (CHAR16
) + 1, Directory
);
166 StrCatS (Cwd
, StrSize (Directory
) / sizeof (CHAR16
) + 1, L
"\\");
167 Drive
= GetFullyQualifiedPath (Cwd
);
168 while (PathRemoveLastItem (Drive
)) {
170 // Check if Drive contains 'fsx:\' only or still points to a sub-directory.
171 // Don't remove trailing '\' from Drive if it points to the root directory.
173 Path
= StrStr (Drive
, L
":\\");
174 if ((Path
!= NULL
) && (*(Path
+ 2) == CHAR_NULL
)) {
181 if (ShellStatus
== SHELL_SUCCESS
&& Drive
!= NULL
) {
183 // change directory on current drive letter
185 Status
= gEfiShellProtocol
->SetCurDir(NULL
, Drive
);
186 if (Status
== EFI_NOT_FOUND
) {
187 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"cd");
188 ShellStatus
= SHELL_NOT_FOUND
;
191 } else if (StrStr(Param1Copy
, L
":") == NULL
) {
193 // change directory without a drive identifier
195 if (ShellGetCurrentDir(NULL
) == NULL
) {
196 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_CWD
), gShellLevel2HiiHandle
, L
"cd");
197 ShellStatus
= SHELL_NOT_FOUND
;
199 ASSERT((Drive
== NULL
&& DriveSize
== 0) || (Drive
!= NULL
));
200 Drive
= StrnCatGrow(&Drive
, &DriveSize
, ShellGetCurrentDir(NULL
), 0);
201 Drive
= StrnCatGrow(&Drive
, &DriveSize
, L
"\\", 0);
202 if (*Param1Copy
== L
'\\') {
203 while (PathRemoveLastItem(Drive
)) ;
204 Drive
= StrnCatGrow(&Drive
, &DriveSize
, Param1Copy
+1, 0);
206 Drive
= StrnCatGrow(&Drive
, &DriveSize
, Param1Copy
, 0);
209 // Verify that this is a valid directory
211 Status
= gEfiShellProtocol
->OpenFileByName(Drive
, &Handle
, EFI_FILE_MODE_READ
);
212 if (EFI_ERROR(Status
)) {
213 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_DIR_NF
), gShellLevel2HiiHandle
, L
"cd", Drive
);
214 ShellStatus
= SHELL_NOT_FOUND
;
215 } else if (EFI_ERROR(FileHandleIsDirectory(Handle
))) {
216 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NOT_DIR
), gShellLevel2HiiHandle
, L
"cd", Drive
);
217 ShellStatus
= SHELL_NOT_FOUND
;
219 if (ShellStatus
== SHELL_SUCCESS
&& Drive
!= NULL
) {
221 // change directory on current drive letter
223 Status
= gEfiShellProtocol
->SetCurDir(NULL
, Drive
);
224 if (Status
== EFI_NOT_FOUND
) {
225 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"cd");
226 ShellStatus
= SHELL_NOT_FOUND
;
229 if (Handle
!= NULL
) {
230 gEfiShellProtocol
->CloseFile(Handle
);
231 DEBUG_CODE(Handle
= NULL
;);
236 // change directory with a drive letter
238 Drive
= AllocateCopyPool(StrSize(Param1Copy
), Param1Copy
);
240 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_MEM
), gShellLevel2HiiHandle
, L
"cd");
241 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
243 Path
= StrStr(Drive
, L
":");
244 ASSERT(Path
!= NULL
);
245 if (EFI_ERROR(ShellIsDirectory(Param1Copy
))) {
246 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NOT_DIR
), gShellLevel2HiiHandle
, L
"cd", Param1Copy
);
247 ShellStatus
= SHELL_NOT_FOUND
;
248 } else if (*(Path
+1) == CHAR_NULL
) {
249 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"cd");
250 ShellStatus
= SHELL_NOT_FOUND
;
252 *(Path
+1) = CHAR_NULL
;
253 if (Path
== Drive
+ StrLen(Drive
)) {
254 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"cd");
255 ShellStatus
= SHELL_NOT_FOUND
;
257 Status
= gEfiShellProtocol
->SetCurDir(Drive
, Path
+2);
258 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_PRINT
), gShellLevel2HiiHandle
, ShellGetCurrentDir(Drive
));
261 if (Status
== EFI_NOT_FOUND
) {
262 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"cd");
263 Status
= SHELL_NOT_FOUND
;
264 } else if (EFI_ERROR(Status
)) {
265 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_DIR_NF
), gShellLevel2HiiHandle
, L
"cd", Param1Copy
);
266 Status
= SHELL_NOT_FOUND
;
271 FreePool(Param1Copy
);
279 // free the command line package
281 ShellCommandLineFreeVarList (Package
);
286 return (ShellStatus
);