2 Main file for attrib shell level 2 function.
4 Copyright (c) 2015, Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "UefiShellLevel2CommandsLib.h"
19 Function for 'cd' command.
21 @param[in] ImageHandle Handle to the Image (NULL if Internal).
22 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
27 IN EFI_HANDLE ImageHandle
,
28 IN EFI_SYSTEM_TABLE
*SystemTable
33 CONST CHAR16
*Directory
;
38 SHELL_STATUS ShellStatus
;
39 SHELL_FILE_HANDLE Handle
;
45 ShellStatus
= SHELL_SUCCESS
;
49 Status
= CommandInit();
50 ASSERT_EFI_ERROR(Status
);
53 // initialize the shell lib (we must be in non-auto-init...)
55 Status
= ShellInitialize();
56 ASSERT_EFI_ERROR(Status
);
59 // parse the command line
61 Status
= ShellCommandLineParse (EmptyParamList
, &Package
, &ProblemParam
, TRUE
);
62 if (EFI_ERROR(Status
)) {
63 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
64 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellLevel2HiiHandle
, L
"cd", ProblemParam
);
65 FreePool(ProblemParam
);
66 ShellStatus
= SHELL_INVALID_PARAMETER
;
75 if (ShellCommandLineGetFlag(Package
, L
"-?")) {
77 } else if (ShellCommandLineGetRawValue(Package
, 2) != NULL
) {
78 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel2HiiHandle
, L
"cd");
79 ShellStatus
= SHELL_INVALID_PARAMETER
;
82 // remember that param 0 is the command name
83 // If there are 0 value parameters, then print the current directory
84 // else If there are 2 value parameters, then print the error message
85 // else If there is 1 value paramerer , then change the directory
87 Param1
= ShellCommandLineGetRawValue(Package
, 1);
90 // display the current directory
92 Directory
= ShellGetCurrentDir(NULL
);
93 if (Directory
!= NULL
) {
94 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_PRINT
), gShellLevel2HiiHandle
, Directory
);
96 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_CWD
), gShellLevel2HiiHandle
, L
"cd");
97 ShellStatus
= SHELL_NOT_FOUND
;
100 Param1Copy
= CatSPrint(NULL
, L
"%s", Param1
, NULL
);
101 for (Walker
= Param1Copy
; Walker
!= NULL
&& *Walker
!= CHAR_NULL
; Walker
++) {
102 if (*Walker
== L
'\"') {
103 CopyMem(Walker
, Walker
+1, StrSize(Walker
) - sizeof(Walker
[0]));
107 if (Param1Copy
!= NULL
) {
108 Param1Copy
= PathCleanUpDirectories(Param1Copy
);
110 if (Param1Copy
!= NULL
) {
111 if (StrCmp(Param1Copy
, L
".") == 0) {
113 // nothing to do... change to current directory
115 } else if (StrCmp(Param1Copy
, L
"..") == 0) {
117 // Change up one directory...
119 Directory
= ShellGetCurrentDir(NULL
);
120 if (Directory
== NULL
) {
121 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_CWD
), gShellLevel2HiiHandle
, L
"cd");
122 ShellStatus
= SHELL_NOT_FOUND
;
124 Drive
= GetFullyQualifiedPath(Directory
);
125 PathRemoveLastItem(Drive
);
127 if (ShellStatus
== SHELL_SUCCESS
&& Drive
!= NULL
) {
129 // change directory on current drive letter
131 Status
= gEfiShellProtocol
->SetCurDir(NULL
, Drive
);
132 if (Status
== EFI_NOT_FOUND
) {
133 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"cd");
134 ShellStatus
= SHELL_NOT_FOUND
;
137 } else if (StrCmp(Param1Copy
, L
"\\") == 0) {
139 // Move to root of current drive
141 Directory
= ShellGetCurrentDir(NULL
);
142 if (Directory
== NULL
) {
143 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_CWD
), gShellLevel2HiiHandle
, L
"cd");
144 ShellStatus
= SHELL_NOT_FOUND
;
146 Drive
= GetFullyQualifiedPath(Directory
);
147 while (PathRemoveLastItem(Drive
)) ;
149 if (ShellStatus
== SHELL_SUCCESS
&& Drive
!= NULL
) {
151 // change directory on current drive letter
153 Status
= gEfiShellProtocol
->SetCurDir(NULL
, Drive
);
154 if (Status
== EFI_NOT_FOUND
) {
155 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"cd");
156 ShellStatus
= SHELL_NOT_FOUND
;
159 } else if (StrStr(Param1Copy
, L
":") == NULL
) {
161 // change directory without a drive identifier
163 if (ShellGetCurrentDir(NULL
) == NULL
) {
164 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_CWD
), gShellLevel2HiiHandle
, L
"cd");
165 ShellStatus
= SHELL_NOT_FOUND
;
167 ASSERT((Drive
== NULL
&& DriveSize
== 0) || (Drive
!= NULL
));
168 Drive
= StrnCatGrow(&Drive
, &DriveSize
, ShellGetCurrentDir(NULL
), 0);
169 if (*Param1Copy
== L
'\\') {
170 while (PathRemoveLastItem(Drive
)) ;
171 Drive
= StrnCatGrow(&Drive
, &DriveSize
, Param1Copy
+1, 0);
173 Drive
= StrnCatGrow(&Drive
, &DriveSize
, Param1Copy
, 0);
176 // Verify that this is a valid directory
178 Status
= gEfiShellProtocol
->OpenFileByName(Drive
, &Handle
, EFI_FILE_MODE_READ
);
179 if (EFI_ERROR(Status
)) {
180 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_DIR_NF
), gShellLevel2HiiHandle
, L
"cd", Drive
);
181 ShellStatus
= SHELL_NOT_FOUND
;
182 } else if (EFI_ERROR(FileHandleIsDirectory(Handle
))) {
183 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NOT_DIR
), gShellLevel2HiiHandle
, L
"cd", Drive
);
184 ShellStatus
= SHELL_NOT_FOUND
;
186 if (ShellStatus
== SHELL_SUCCESS
&& Drive
!= NULL
) {
188 // change directory on current drive letter
190 Status
= gEfiShellProtocol
->SetCurDir(NULL
, Drive
);
191 if (Status
== EFI_NOT_FOUND
) {
192 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"cd");
193 ShellStatus
= SHELL_NOT_FOUND
;
196 if (Handle
!= NULL
) {
197 gEfiShellProtocol
->CloseFile(Handle
);
198 DEBUG_CODE(Handle
= NULL
;);
203 // change directory with a drive letter
205 Drive
= AllocateCopyPool(StrSize(Param1Copy
), Param1Copy
);
207 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_MEM
), gShellLevel2HiiHandle
, L
"cd");
208 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
210 Path
= StrStr(Drive
, L
":");
211 ASSERT(Path
!= NULL
);
212 if (EFI_ERROR(ShellIsDirectory(Param1Copy
))) {
213 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NOT_DIR
), gShellLevel2HiiHandle
, L
"cd", Param1Copy
);
214 ShellStatus
= SHELL_NOT_FOUND
;
215 } else if (*(Path
+1) == CHAR_NULL
) {
216 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"cd");
217 ShellStatus
= SHELL_NOT_FOUND
;
219 *(Path
+1) = CHAR_NULL
;
220 if (Path
== Drive
+ StrLen(Drive
)) {
221 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"cd");
222 ShellStatus
= SHELL_NOT_FOUND
;
224 Status
= gEfiShellProtocol
->SetCurDir(Drive
, Path
+2);
225 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_PRINT
), gShellLevel2HiiHandle
, ShellGetCurrentDir(Drive
));
228 if (Status
== EFI_NOT_FOUND
) {
229 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"cd");
230 Status
= SHELL_NOT_FOUND
;
231 } else if (EFI_ERROR(Status
)) {
232 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_DIR_NF
), gShellLevel2HiiHandle
, L
"cd", Param1Copy
);
233 Status
= SHELL_NOT_FOUND
;
238 FreePool(Param1Copy
);
246 // free the command line package
248 ShellCommandLineFreeVarList (Package
);
253 return (ShellStatus
);