2 Main file for attrib shell level 2 function.
4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2009 - 2016, 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 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_OUT_MEM
), gShellLevel2HiiHandle
, L
"cd");
130 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
132 StrCpyS (Cwd
, StrSize (Directory
) / sizeof (CHAR16
) + 1, Directory
);
133 StrCatS (Cwd
, StrSize (Directory
) / sizeof (CHAR16
) + 1, L
"\\");
134 Drive
= GetFullyQualifiedPath (Cwd
);
135 PathRemoveLastItem (Drive
);
139 if (ShellStatus
== SHELL_SUCCESS
&& Drive
!= NULL
) {
141 // change directory on current drive letter
143 Status
= gEfiShellProtocol
->SetCurDir(NULL
, Drive
);
144 if (Status
== EFI_NOT_FOUND
) {
145 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"cd");
146 ShellStatus
= SHELL_NOT_FOUND
;
149 } else if (StrCmp(Param1Copy
, L
"\\") == 0) {
151 // Move to root of current drive
153 Directory
= ShellGetCurrentDir(NULL
);
154 if (Directory
== NULL
) {
155 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_CWD
), gShellLevel2HiiHandle
, L
"cd");
156 ShellStatus
= SHELL_NOT_FOUND
;
158 CwdSize
= StrSize(Directory
) + sizeof(CHAR16
);
159 Cwd
= AllocateZeroPool(CwdSize
);
161 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_OUT_MEM
), gShellLevel2HiiHandle
, L
"cd");
162 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
164 StrCpyS (Cwd
, StrSize (Directory
) / sizeof (CHAR16
) + 1, Directory
);
165 StrCatS (Cwd
, StrSize (Directory
) / sizeof (CHAR16
) + 1, L
"\\");
166 Drive
= GetFullyQualifiedPath (Cwd
);
167 while (PathRemoveLastItem (Drive
));
171 if (ShellStatus
== SHELL_SUCCESS
&& Drive
!= NULL
) {
173 // change directory on current drive letter
175 Status
= gEfiShellProtocol
->SetCurDir(NULL
, Drive
);
176 if (Status
== EFI_NOT_FOUND
) {
177 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"cd");
178 ShellStatus
= SHELL_NOT_FOUND
;
181 } else if (StrStr(Param1Copy
, L
":") == NULL
) {
183 // change directory without a drive identifier
185 if (ShellGetCurrentDir(NULL
) == NULL
) {
186 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_CWD
), gShellLevel2HiiHandle
, L
"cd");
187 ShellStatus
= SHELL_NOT_FOUND
;
189 ASSERT((Drive
== NULL
&& DriveSize
== 0) || (Drive
!= NULL
));
190 Drive
= StrnCatGrow(&Drive
, &DriveSize
, ShellGetCurrentDir(NULL
), 0);
191 Drive
= StrnCatGrow(&Drive
, &DriveSize
, L
"\\", 0);
192 if (*Param1Copy
== L
'\\') {
193 while (PathRemoveLastItem(Drive
)) ;
194 Drive
= StrnCatGrow(&Drive
, &DriveSize
, Param1Copy
+1, 0);
196 Drive
= StrnCatGrow(&Drive
, &DriveSize
, Param1Copy
, 0);
199 // Verify that this is a valid directory
201 Status
= gEfiShellProtocol
->OpenFileByName(Drive
, &Handle
, EFI_FILE_MODE_READ
);
202 if (EFI_ERROR(Status
)) {
203 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_DIR_NF
), gShellLevel2HiiHandle
, L
"cd", Drive
);
204 ShellStatus
= SHELL_NOT_FOUND
;
205 } else if (EFI_ERROR(FileHandleIsDirectory(Handle
))) {
206 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NOT_DIR
), gShellLevel2HiiHandle
, L
"cd", Drive
);
207 ShellStatus
= SHELL_NOT_FOUND
;
209 if (ShellStatus
== SHELL_SUCCESS
&& Drive
!= NULL
) {
211 // change directory on current drive letter
213 Status
= gEfiShellProtocol
->SetCurDir(NULL
, Drive
);
214 if (Status
== EFI_NOT_FOUND
) {
215 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"cd");
216 ShellStatus
= SHELL_NOT_FOUND
;
219 if (Handle
!= NULL
) {
220 gEfiShellProtocol
->CloseFile(Handle
);
221 DEBUG_CODE(Handle
= NULL
;);
226 // change directory with a drive letter
228 Drive
= AllocateCopyPool(StrSize(Param1Copy
), Param1Copy
);
230 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_MEM
), gShellLevel2HiiHandle
, L
"cd");
231 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
233 Path
= StrStr(Drive
, L
":");
234 ASSERT(Path
!= NULL
);
235 if (EFI_ERROR(ShellIsDirectory(Param1Copy
))) {
236 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NOT_DIR
), gShellLevel2HiiHandle
, L
"cd", Param1Copy
);
237 ShellStatus
= SHELL_NOT_FOUND
;
238 } else if (*(Path
+1) == CHAR_NULL
) {
239 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"cd");
240 ShellStatus
= SHELL_NOT_FOUND
;
242 *(Path
+1) = CHAR_NULL
;
243 if (Path
== Drive
+ StrLen(Drive
)) {
244 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"cd");
245 ShellStatus
= SHELL_NOT_FOUND
;
247 Status
= gEfiShellProtocol
->SetCurDir(Drive
, Path
+2);
248 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_PRINT
), gShellLevel2HiiHandle
, ShellGetCurrentDir(Drive
));
251 if (Status
== EFI_NOT_FOUND
) {
252 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
, L
"cd");
253 Status
= SHELL_NOT_FOUND
;
254 } else if (EFI_ERROR(Status
)) {
255 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_DIR_NF
), gShellLevel2HiiHandle
, L
"cd", Param1Copy
);
256 Status
= SHELL_NOT_FOUND
;
261 FreePool(Param1Copy
);
269 // free the command line package
271 ShellCommandLineFreeVarList (Package
);
276 return (ShellStatus
);