2 Main file for attrib shell level 2 function.
4 Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "UefiShellLevel2CommandsLib.h"
18 Function for 'cd' command.
20 @param[in] ImageHandle Handle to the Image (NULL if Internal).
21 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
26 IN EFI_HANDLE ImageHandle
,
27 IN EFI_SYSTEM_TABLE
*SystemTable
32 CONST CHAR16
*Directory
;
37 SHELL_STATUS ShellStatus
;
38 SHELL_FILE_HANDLE Handle
;
44 ShellStatus
= SHELL_SUCCESS
;
48 Status
= CommandInit();
49 ASSERT_EFI_ERROR(Status
);
52 // initialize the shell lib (we must be in non-auto-init...)
54 Status
= ShellInitialize();
55 ASSERT_EFI_ERROR(Status
);
58 // parse the command line
60 Status
= ShellCommandLineParse (EmptyParamList
, &Package
, &ProblemParam
, TRUE
);
61 if (EFI_ERROR(Status
)) {
62 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
63 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellLevel2HiiHandle
, ProblemParam
);
64 FreePool(ProblemParam
);
65 ShellStatus
= SHELL_INVALID_PARAMETER
;
74 if (ShellCommandLineGetFlag(Package
, L
"-?")) {
76 } else if (ShellCommandLineGetRawValue(Package
, 2) != NULL
) {
77 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellLevel2HiiHandle
);
78 ShellStatus
= SHELL_INVALID_PARAMETER
;
81 // remember that param 0 is the command name
82 // If there are 0 value parameters, then print the current directory
83 // else If there are 2 value parameters, then print the error message
84 // else If there is 1 value paramerer , then change the directory
86 Param1
= ShellCommandLineGetRawValue(Package
, 1);
89 // display the current directory
91 Directory
= ShellGetCurrentDir(NULL
);
92 if (Directory
!= NULL
) {
93 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_PRINT
), gShellLevel2HiiHandle
, Directory
);
95 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_CWD
), gShellLevel2HiiHandle
);
96 ShellStatus
= SHELL_NOT_FOUND
;
99 Param1Copy
= CatSPrint(NULL
, L
"%s", Param1
, NULL
);
100 for (Walker
= Param1Copy
; Walker
!= NULL
&& *Walker
!= CHAR_NULL
; Walker
++) {
101 if (*Walker
== L
'\"') {
102 CopyMem(Walker
, Walker
+1, StrSize(Walker
) - sizeof(Walker
[0]));
106 if (Param1Copy
!= NULL
) {
107 Param1Copy
= PathCleanUpDirectories(Param1Copy
);
109 if (Param1Copy
!= NULL
) {
110 if (StrCmp(Param1Copy
, L
".") == 0) {
112 // nothing to do... change to current directory
114 } else if (StrCmp(Param1Copy
, L
"..") == 0) {
116 // Change up one directory...
118 Directory
= ShellGetCurrentDir(NULL
);
119 if (Directory
== NULL
) {
120 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_CWD
), gShellLevel2HiiHandle
);
121 ShellStatus
= SHELL_NOT_FOUND
;
123 Drive
= GetFullyQualifiedPath(Directory
);
124 PathRemoveLastItem(Drive
);
126 if (ShellStatus
== SHELL_SUCCESS
&& Drive
!= NULL
) {
128 // change directory on current drive letter
130 Status
= gEfiShellProtocol
->SetCurDir(NULL
, Drive
);
131 if (Status
== EFI_NOT_FOUND
) {
132 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
);
133 ShellStatus
= SHELL_NOT_FOUND
;
136 } else if (StrCmp(Param1Copy
, L
"\\") == 0) {
138 // Move to root of current drive
140 Directory
= ShellGetCurrentDir(NULL
);
141 if (Directory
== NULL
) {
142 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_CWD
), gShellLevel2HiiHandle
);
143 ShellStatus
= SHELL_NOT_FOUND
;
145 Drive
= GetFullyQualifiedPath(Directory
);
146 while (PathRemoveLastItem(Drive
)) ;
148 if (ShellStatus
== SHELL_SUCCESS
&& Drive
!= NULL
) {
150 // change directory on current drive letter
152 Status
= gEfiShellProtocol
->SetCurDir(NULL
, Drive
);
153 if (Status
== EFI_NOT_FOUND
) {
154 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
);
155 ShellStatus
= SHELL_NOT_FOUND
;
158 } else if (StrStr(Param1Copy
, L
":") == NULL
) {
160 // change directory without a drive identifier
162 if (ShellGetCurrentDir(NULL
) == NULL
) {
163 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_CWD
), gShellLevel2HiiHandle
);
164 ShellStatus
= SHELL_NOT_FOUND
;
166 ASSERT((Drive
== NULL
&& DriveSize
== 0) || (Drive
!= NULL
));
167 Drive
= StrnCatGrow(&Drive
, &DriveSize
, ShellGetCurrentDir(NULL
), 0);
168 if (*Param1Copy
== L
'\\') {
169 while (PathRemoveLastItem(Drive
)) ;
170 Drive
= StrnCatGrow(&Drive
, &DriveSize
, Param1Copy
+1, 0);
172 Drive
= StrnCatGrow(&Drive
, &DriveSize
, Param1Copy
, 0);
175 // Verify that this is a valid directory
177 Status
= gEfiShellProtocol
->OpenFileByName(Drive
, &Handle
, EFI_FILE_MODE_READ
);
178 if (EFI_ERROR(Status
)) {
179 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_DIR_NF
), gShellLevel2HiiHandle
, Drive
);
180 ShellStatus
= SHELL_NOT_FOUND
;
181 } else if (EFI_ERROR(FileHandleIsDirectory(Handle
))) {
182 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NOT_DIR
), gShellLevel2HiiHandle
, Drive
);
183 ShellStatus
= SHELL_NOT_FOUND
;
185 if (ShellStatus
== SHELL_SUCCESS
&& Drive
!= NULL
) {
187 // change directory on current drive letter
189 Status
= gEfiShellProtocol
->SetCurDir(NULL
, Drive
);
190 if (Status
== EFI_NOT_FOUND
) {
191 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
);
192 ShellStatus
= SHELL_NOT_FOUND
;
195 if (Handle
!= NULL
) {
196 gEfiShellProtocol
->CloseFile(Handle
);
197 DEBUG_CODE(Handle
= NULL
;);
202 // change directory with a drive letter
204 Drive
= AllocateCopyPool(StrSize(Param1Copy
), Param1Copy
);
206 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_MEM
), gShellLevel2HiiHandle
);
207 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
209 Path
= StrStr(Drive
, L
":");
210 ASSERT(Path
!= NULL
);
211 if (EFI_ERROR(ShellIsDirectory(Param1Copy
))) {
212 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NOT_DIR
), gShellLevel2HiiHandle
, Param1Copy
);
213 ShellStatus
= SHELL_NOT_FOUND
;
214 } else if (*(Path
+1) == CHAR_NULL
) {
215 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
);
216 ShellStatus
= SHELL_NOT_FOUND
;
218 *(Path
+1) = CHAR_NULL
;
219 if (Path
== Drive
+ StrLen(Drive
)) {
220 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
);
221 ShellStatus
= SHELL_NOT_FOUND
;
223 Status
= gEfiShellProtocol
->SetCurDir(Drive
, Path
+2);
224 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_PRINT
), gShellLevel2HiiHandle
, ShellGetCurrentDir(Drive
));
227 if (Status
== EFI_NOT_FOUND
) {
228 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CD_NF
), gShellLevel2HiiHandle
);
229 Status
= SHELL_NOT_FOUND
;
230 } else if (EFI_ERROR(Status
)) {
231 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_DIR_NF
), gShellLevel2HiiHandle
, Param1Copy
);
232 Status
= SHELL_NOT_FOUND
;
237 FreePool(Param1Copy
);
245 // free the command line package
247 ShellCommandLineFreeVarList (Package
);
252 return (ShellStatus
);