2 Main file for attrib shell level 2 function.
4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2009 - 2015, 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
;
40 SHELL_STATUS ShellStatus
;
41 SHELL_FILE_HANDLE Handle
;
47 ShellStatus
= SHELL_SUCCESS
;
51 Status
= CommandInit();
52 ASSERT_EFI_ERROR(Status
);
55 // initialize the shell lib (we must be in non-auto-init...)
57 Status
= ShellInitialize();
58 ASSERT_EFI_ERROR(Status
);
61 // parse the command line
63 Status
= ShellCommandLineParse (EmptyParamList
, &Package
, &ProblemParam
, TRUE
);
64 if (EFI_ERROR(Status
)) {
65 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
66 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellLevel2HiiHandle
, L
"cd", ProblemParam
);
67 FreePool(ProblemParam
);
68 ShellStatus
= SHELL_INVALID_PARAMETER
;
77 if (ShellCommandLineGetFlag(Package
, L
"-?")) {
79 } else if (ShellCommandLineGetRawValue(Package
, 2) != NULL
) {
80 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel2HiiHandle
, L
"cd");
81 ShellStatus
= SHELL_INVALID_PARAMETER
;
84 // remember that param 0 is the command name
85 // If there are 0 value parameters, then print the current directory
86 // else If there are 2 value parameters, then print the error message
87 // else If there is 1 value paramerer , then change the directory
89 Param1
= ShellCommandLineGetRawValue(Package
, 1);
92 // display the current directory
94 Directory
= ShellGetCurrentDir(NULL
);
95 if (Directory
!= NULL
) {
96 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_PRINT
), gShellLevel2HiiHandle
, Directory
);
98 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_CWD
), gShellLevel2HiiHandle
, L
"cd");
99 ShellStatus
= SHELL_NOT_FOUND
;
102 Param1Copy
= CatSPrint(NULL
, L
"%s", Param1
, NULL
);
103 for (Walker
= Param1Copy
; Walker
!= NULL
&& *Walker
!= CHAR_NULL
; Walker
++) {
104 if (*Walker
== L
'\"') {
105 CopyMem(Walker
, Walker
+1, StrSize(Walker
) - sizeof(Walker
[0]));
109 if (Param1Copy
!= NULL
) {
110 Param1Copy
= PathCleanUpDirectories(Param1Copy
);
112 if (Param1Copy
!= NULL
) {
113 if (StrCmp(Param1Copy
, L
".") == 0) {
115 // nothing to do... change to current directory
117 } else if (StrCmp(Param1Copy
, L
"..") == 0) {
119 // Change up one directory...
121 Directory
= ShellGetCurrentDir(NULL
);
122 if (Directory
== NULL
) {
123 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_CWD
), gShellLevel2HiiHandle
, L
"cd");
124 ShellStatus
= SHELL_NOT_FOUND
;
126 CwdSize
= StrSize(Directory
) + sizeof(CHAR16
);
127 Cwd
= AllocateZeroPool(CwdSize
);
129 StrCpyS(Cwd
, StrSize(Directory
)/sizeof(CHAR16
)+1, Directory
);
130 StrCatS(Cwd
, StrSize(Directory
)/sizeof(CHAR16
)+1, L
"\\");
131 Drive
= GetFullyQualifiedPath(Cwd
);
132 PathRemoveLastItem(Drive
);
135 if (ShellStatus
== SHELL_SUCCESS
&& Drive
!= NULL
) {
137 // change directory on current drive letter
139 Status
= gEfiShellProtocol
->SetCurDir(NULL
, Drive
);
140 if (Status
== EFI_NOT_FOUND
) {
141 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"cd");
142 ShellStatus
= SHELL_NOT_FOUND
;
145 } else if (StrCmp(Param1Copy
, L
"\\") == 0) {
147 // Move to root of current drive
149 Directory
= ShellGetCurrentDir(NULL
);
150 if (Directory
== NULL
) {
151 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_CWD
), gShellLevel2HiiHandle
, L
"cd");
152 ShellStatus
= SHELL_NOT_FOUND
;
154 CwdSize
= StrSize(Directory
) + sizeof(CHAR16
);
155 Cwd
= AllocateZeroPool(CwdSize
);
157 StrCpyS(Cwd
, StrSize(Directory
)/sizeof(CHAR16
)+1, Directory
);
158 StrCatS(Cwd
, StrSize(Directory
)/sizeof(CHAR16
)+1, L
"\\");
159 Drive
= GetFullyQualifiedPath(Cwd
);
160 while (PathRemoveLastItem(Drive
));
163 if (ShellStatus
== SHELL_SUCCESS
&& Drive
!= NULL
) {
165 // change directory on current drive letter
167 Status
= gEfiShellProtocol
->SetCurDir(NULL
, Drive
);
168 if (Status
== EFI_NOT_FOUND
) {
169 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"cd");
170 ShellStatus
= SHELL_NOT_FOUND
;
173 } else if (StrStr(Param1Copy
, L
":") == NULL
) {
175 // change directory without a drive identifier
177 if (ShellGetCurrentDir(NULL
) == NULL
) {
178 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_CWD
), gShellLevel2HiiHandle
, L
"cd");
179 ShellStatus
= SHELL_NOT_FOUND
;
181 ASSERT((Drive
== NULL
&& DriveSize
== 0) || (Drive
!= NULL
));
182 Drive
= StrnCatGrow(&Drive
, &DriveSize
, ShellGetCurrentDir(NULL
), 0);
183 Drive
= StrnCatGrow(&Drive
, &DriveSize
, L
"\\", 0);
184 if (*Param1Copy
== L
'\\') {
185 while (PathRemoveLastItem(Drive
)) ;
186 Drive
= StrnCatGrow(&Drive
, &DriveSize
, Param1Copy
+1, 0);
188 Drive
= StrnCatGrow(&Drive
, &DriveSize
, Param1Copy
, 0);
191 // Verify that this is a valid directory
193 Status
= gEfiShellProtocol
->OpenFileByName(Drive
, &Handle
, EFI_FILE_MODE_READ
);
194 if (EFI_ERROR(Status
)) {
195 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_DIR_NF
), gShellLevel2HiiHandle
, L
"cd", Drive
);
196 ShellStatus
= SHELL_NOT_FOUND
;
197 } else if (EFI_ERROR(FileHandleIsDirectory(Handle
))) {
198 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NOT_DIR
), gShellLevel2HiiHandle
, L
"cd", Drive
);
199 ShellStatus
= SHELL_NOT_FOUND
;
201 if (ShellStatus
== SHELL_SUCCESS
&& Drive
!= NULL
) {
203 // change directory on current drive letter
205 Status
= gEfiShellProtocol
->SetCurDir(NULL
, Drive
);
206 if (Status
== EFI_NOT_FOUND
) {
207 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"cd");
208 ShellStatus
= SHELL_NOT_FOUND
;
211 if (Handle
!= NULL
) {
212 gEfiShellProtocol
->CloseFile(Handle
);
213 DEBUG_CODE(Handle
= NULL
;);
218 // change directory with a drive letter
220 Drive
= AllocateCopyPool(StrSize(Param1Copy
), Param1Copy
);
222 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_MEM
), gShellLevel2HiiHandle
, L
"cd");
223 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
225 Path
= StrStr(Drive
, L
":");
226 ASSERT(Path
!= NULL
);
227 if (EFI_ERROR(ShellIsDirectory(Param1Copy
))) {
228 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NOT_DIR
), gShellLevel2HiiHandle
, L
"cd", Param1Copy
);
229 ShellStatus
= SHELL_NOT_FOUND
;
230 } else if (*(Path
+1) == CHAR_NULL
) {
231 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"cd");
232 ShellStatus
= SHELL_NOT_FOUND
;
234 *(Path
+1) = CHAR_NULL
;
235 if (Path
== Drive
+ StrLen(Drive
)) {
236 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"cd");
237 ShellStatus
= SHELL_NOT_FOUND
;
239 Status
= gEfiShellProtocol
->SetCurDir(Drive
, Path
+2);
240 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_PRINT
), gShellLevel2HiiHandle
, ShellGetCurrentDir(Drive
));
243 if (Status
== EFI_NOT_FOUND
) {
244 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"cd");
245 Status
= SHELL_NOT_FOUND
;
246 } else if (EFI_ERROR(Status
)) {
247 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_DIR_NF
), gShellLevel2HiiHandle
, L
"cd", Param1Copy
);
248 Status
= SHELL_NOT_FOUND
;
253 FreePool(Param1Copy
);
261 // free the command line package
263 ShellCommandLineFreeVarList (Package
);
268 return (ShellStatus
);