]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c
EmbeddedPkg/PrePiLib: Correct function name
[mirror_edk2.git] / ShellPkg / Library / UefiShellLevel2CommandsLib / Cd.c
CommitLineData
a405b86d 1/** @file\r
2 Main file for attrib shell level 2 function.\r
3\r
a7ea752e 4 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
c011b6c9 5 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>\r
630cb850 6 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
b1df6c25 7 Copyright (c) 2018, Dell Technologies. All rights reserved.<BR>\r
a405b86d 8 This program and the accompanying materials\r
9 are licensed and made available under the terms and conditions of the BSD License\r
10 which accompanies this distribution. The full text of the license may be found at\r
11 http://opensource.org/licenses/bsd-license.php\r
12\r
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
15\r
16**/\r
17\r
18#include "UefiShellLevel2CommandsLib.h"\r
19\r
d9bb3ca3
RN
20/**\r
21 Function will replace drive identifier with CWD.\r
22\r
23 If FullPath begining with ':' is invalid path, then ASSERT.\r
24 If FullPath not include dirve identifier , then do nothing.\r
25 If FullPath likes "fs0:\xx" or "fs0:/xx" , then do nothing.\r
26 If FullPath likes "fs0:xxx" or "fs0:", the drive replaced by CWD.\r
27\r
28 @param[in, out] FullPath The pointer to the string containing the path.\r
29 @param[in] Cwd Current directory.\r
30\r
31 @retval EFI_SUCCESS Success.\r
32 @retval EFI_OUT_OF_SOURCES A memory allocation failed.\r
33**/\r
34EFI_STATUS\r
35ReplaceDriveWithCwd (\r
36 IN OUT CHAR16 **FullPath,\r
37 IN CONST CHAR16 *Cwd\r
38 )\r
39{\r
40 CHAR16 *Splitter;\r
41 CHAR16 *TempBuffer;\r
42 UINTN TotalSize;\r
43\r
44 Splitter = NULL;\r
45 TempBuffer = NULL;\r
46 TotalSize = 0;\r
47\r
48 if (FullPath == NULL || *FullPath == NULL) {\r
49 return EFI_SUCCESS;\r
50 }\r
51\r
52 Splitter = StrStr (*FullPath, L":");\r
53 ASSERT(Splitter != *FullPath);\r
54\r
55 if (Splitter != NULL && *(Splitter + 1) != L'\\' && *(Splitter + 1) != L'/') {\r
56 TotalSize = StrSize (Cwd) + StrSize (Splitter + 1);\r
57 TempBuffer = AllocateZeroPool (TotalSize);\r
58 if (TempBuffer == NULL) {\r
59 return EFI_OUT_OF_RESOURCES;\r
60 }\r
61\r
62 StrCpyS (TempBuffer, TotalSize / sizeof(CHAR16), Cwd);\r
63 StrCatS (TempBuffer, TotalSize / sizeof(CHAR16), L"\\");\r
64 StrCatS (TempBuffer, TotalSize / sizeof(CHAR16), Splitter + 1);\r
65\r
66 FreePool(*FullPath);\r
67 *FullPath = TempBuffer;\r
68 }\r
69\r
70 return EFI_SUCCESS;\r
71}\r
72\r
73/**\r
74 function to determine if FullPath is under current filesystem.\r
75\r
76 @param[in] FullPath The target location to determine.\r
77 @param[in] Cwd Current directory.\r
78\r
79 @retval TRUE The FullPath is in the current filesystem.\r
80 @retval FALSE The FullPaht isn't in the current filesystem.\r
81**/\r
82BOOLEAN\r
83IsCurrentFileSystem (\r
84 IN CONST CHAR16 *FullPath,\r
85 IN CONST CHAR16 *Cwd\r
86 )\r
87{\r
88 CHAR16 *Splitter1;\r
89 CHAR16 *Splitter2;\r
90\r
91 Splitter1 = NULL;\r
92 Splitter2 = NULL;\r
93\r
94 ASSERT(FullPath != NULL);\r
95\r
96 Splitter1 = StrStr (FullPath, L":");\r
97 if (Splitter1 == NULL) {\r
98 return TRUE;\r
99 }\r
100\r
101 Splitter2 = StrStr (Cwd, L":");\r
102\r
810c635d 103 if (((UINTN) Splitter1 - (UINTN) FullPath) != ((UINTN) Splitter2 - (UINTN) Cwd)) {\r
d9bb3ca3
RN
104 return FALSE;\r
105 } else {\r
630cb850 106 if (StrniCmp (FullPath, Cwd, ((UINTN) Splitter1 - (UINTN) FullPath) / sizeof (CHAR16)) == 0) {\r
d9bb3ca3
RN
107 return TRUE;\r
108 } else {\r
109 return FALSE;\r
110 }\r
111 }\r
112}\r
113\r
114/**\r
115 Extract drive string and path string from FullPath.\r
116\r
117 The caller must be free Drive and Path.\r
118\r
119 @param[in] FullPath A path to be extracted.\r
120 @param[out] Drive Buffer to save drive identifier.\r
121 @param[out] Path Buffer to save path.\r
122\r
123 @retval EFI_SUCCESS Success.\r
124 @retval EFI_OUT_OF_RESOUCES A memory allocation failed.\r
125**/\r
126EFI_STATUS\r
127ExtractDriveAndPath (\r
128 IN CONST CHAR16 *FullPath,\r
129 OUT CHAR16 **Drive,\r
130 OUT CHAR16 **Path\r
131 )\r
132{\r
133 CHAR16 *Splitter;\r
134\r
135 ASSERT (FullPath != NULL);\r
136\r
137 Splitter = StrStr (FullPath, L":");\r
138\r
139 if (Splitter == NULL) {\r
140 *Drive = NULL;\r
141 *Path = AllocateCopyPool (StrSize (FullPath), FullPath);\r
142 if (*Path == NULL) {\r
143 return EFI_OUT_OF_RESOURCES;\r
144 }\r
145 } else {\r
146 if (*(Splitter + 1) == CHAR_NULL) {\r
147 *Drive = AllocateCopyPool (StrSize (FullPath), FullPath);\r
148 *Path = NULL;\r
149 if (*Drive == NULL) {\r
150 return EFI_OUT_OF_RESOURCES;\r
151 }\r
152 } else {\r
153 *Drive = AllocateCopyPool ((Splitter - FullPath + 2) * sizeof(CHAR16), FullPath);\r
154 if (*Drive == NULL) {\r
155 return EFI_OUT_OF_RESOURCES;\r
156 }\r
157 (*Drive)[Splitter - FullPath + 1] = CHAR_NULL;\r
158\r
159 *Path = AllocateCopyPool (StrSize (Splitter + 1), Splitter + 1);\r
160 if (*Path == NULL) {\r
161 FreePool (*Drive);\r
162 return EFI_OUT_OF_RESOURCES;\r
163 }\r
164 }\r
165 }\r
166\r
167 return EFI_SUCCESS;\r
168}\r
169\r
a405b86d 170/**\r
171 Function for 'cd' command.\r
172\r
173 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
174 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
175**/\r
176SHELL_STATUS\r
177EFIAPI\r
178ShellCommandRunCd (\r
179 IN EFI_HANDLE ImageHandle,\r
180 IN EFI_SYSTEM_TABLE *SystemTable\r
181 )\r
182{\r
183 EFI_STATUS Status;\r
184 LIST_ENTRY *Package;\r
d9bb3ca3 185 CONST CHAR16 *Cwd;\r
a405b86d 186 CHAR16 *Path;\r
187 CHAR16 *Drive;\r
a405b86d 188 CHAR16 *ProblemParam;\r
189 SHELL_STATUS ShellStatus;\r
a405b86d 190 CONST CHAR16 *Param1;\r
1fc3749d 191 CHAR16 *Param1Copy;\r
d9bb3ca3
RN
192 CHAR16 *Walker;\r
193 CHAR16 *Splitter;\r
194 CHAR16 *TempBuffer;\r
195 UINTN TotalSize;\r
a405b86d 196\r
d9bb3ca3
RN
197 ProblemParam = NULL;\r
198 ShellStatus = SHELL_SUCCESS;\r
199 Cwd = NULL;\r
200 Path = NULL;\r
201 Drive = NULL;\r
202 Splitter = NULL;\r
203 TempBuffer = NULL;\r
204 TotalSize = 0;\r
a405b86d 205\r
206 Status = CommandInit();\r
207 ASSERT_EFI_ERROR(Status);\r
208\r
209 //\r
210 // initialize the shell lib (we must be in non-auto-init...)\r
211 //\r
212 Status = ShellInitialize();\r
213 ASSERT_EFI_ERROR(Status);\r
214\r
215 //\r
216 // parse the command line\r
217 //\r
218 Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE);\r
219 if (EFI_ERROR(Status)) {\r
220 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
ba0014b9 221 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"cd", ProblemParam);\r
a405b86d 222 FreePool(ProblemParam);\r
223 ShellStatus = SHELL_INVALID_PARAMETER;\r
224 } else {\r
225 ASSERT(FALSE);\r
226 }\r
227 }\r
228\r
229 //\r
230 // check for "-?"\r
231 //\r
232 if (ShellCommandLineGetFlag(Package, L"-?")) {\r
233 ASSERT(FALSE);\r
234 } else if (ShellCommandLineGetRawValue(Package, 2) != NULL) {\r
ba0014b9 235 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"cd");\r
a405b86d 236 ShellStatus = SHELL_INVALID_PARAMETER;\r
237 } else {\r
238 //\r
239 // remember that param 0 is the command name\r
240 // If there are 0 value parameters, then print the current directory\r
241 // else If there are 2 value parameters, then print the error message\r
242 // else If there is 1 value paramerer , then change the directory\r
243 //\r
d9bb3ca3
RN
244 Cwd = ShellGetCurrentDir (NULL);\r
245 if (Cwd == NULL) {\r
246 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN(STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"cd");\r
247 ShellStatus = SHELL_NOT_FOUND;\r
a405b86d 248 } else {\r
d9bb3ca3
RN
249 Param1 = ShellCommandLineGetRawValue (Package, 1);\r
250 if (Param1 == NULL) {\r
251 //\r
252 // display the current directory\r
253 //\r
254 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN(STR_CD_PRINT), gShellLevel2HiiHandle, Cwd);\r
255 } else {\r
256 Param1Copy = CatSPrint (NULL, L"%s", Param1, NULL);\r
257 for (Walker = Param1Copy; Walker != NULL && *Walker != CHAR_NULL; Walker++) {\r
258 if (*Walker == L'\"') {\r
259 CopyMem (Walker, Walker + 1, StrSize(Walker) - sizeof(Walker[0]));\r
a405b86d 260 }\r
d9bb3ca3
RN
261 }\r
262\r
263 if (Param1Copy != NULL && IsCurrentFileSystem (Param1Copy, Cwd)) {\r
264 Status = ReplaceDriveWithCwd (&Param1Copy,Cwd);\r
d9bb3ca3 265 } else {\r
a405b86d 266 //\r
d9bb3ca3 267 // Can't use cd command to change filesystem.\r
a405b86d 268 //\r
d9bb3ca3
RN
269 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_CD_NF), gShellLevel2HiiHandle, L"cd");\r
270 Status = EFI_NOT_FOUND;\r
271 }\r
272\r
273 if (!EFI_ERROR(Status) && Param1Copy != NULL) {\r
274 Splitter = StrStr (Cwd, L":");\r
275 if (Param1Copy[0] == L'\\') {\r
a405b86d 276 //\r
d9bb3ca3 277 // Absolute Path on current drive letter.\r
a405b86d 278 //\r
d9bb3ca3
RN
279 TotalSize = ((Splitter - Cwd + 1) * sizeof(CHAR16)) + StrSize(Param1Copy);\r
280 TempBuffer = AllocateZeroPool (TotalSize);\r
281 if (TempBuffer == NULL) {\r
282 Status = EFI_OUT_OF_RESOURCES;\r
beab0fc5 283 } else {\r
d9bb3ca3
RN
284 StrnCpyS (TempBuffer, TotalSize / sizeof(CHAR16), Cwd, (Splitter - Cwd + 1));\r
285 StrCatS (TempBuffer, TotalSize / sizeof(CHAR16), Param1Copy);\r
286\r
287 FreePool (Param1Copy);\r
288 Param1Copy = TempBuffer;\r
289 TempBuffer = NULL;\r
beab0fc5 290 }\r
d9bb3ca3
RN
291 } else {\r
292 if (StrStr (Param1Copy,L":") == NULL) {\r
293 TotalSize = StrSize (Cwd) + StrSize (Param1Copy);\r
294 TempBuffer = AllocateZeroPool (TotalSize);\r
295 if (TempBuffer == NULL) {\r
296 Status = EFI_OUT_OF_RESOURCES;\r
297 } else {\r
298 StrCpyS (TempBuffer, TotalSize / sizeof (CHAR16), Cwd);\r
299 StrCatS (TempBuffer, TotalSize / sizeof (CHAR16), L"\\");\r
300 StrCatS (TempBuffer, TotalSize / sizeof (CHAR16), Param1Copy);\r
301\r
302 FreePool (Param1Copy);\r
b1df6c25
JD
303 Param1Copy = TempBuffer;\r
304 TempBuffer = NULL;\r
beab0fc5 305 }\r
306 }\r
a405b86d 307 }\r
d9bb3ca3
RN
308 }\r
309\r
310 if (!EFI_ERROR(Status)) {\r
b1df6c25 311 Param1Copy = PathCleanUpDirectories (Param1Copy);\r
d9bb3ca3
RN
312 Status = ExtractDriveAndPath (Param1Copy, &Drive, &Path);\r
313 }\r
314\r
315 if (!EFI_ERROR (Status) && Drive != NULL && Path != NULL) {\r
316 if (EFI_ERROR(ShellIsDirectory (Param1Copy))) {\r
317 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN(STR_GEN_NOT_DIR), gShellLevel2HiiHandle, L"cd", Param1Copy);\r
318 ShellStatus = SHELL_NOT_FOUND;\r
9ea69f8a 319 } else {\r
d9bb3ca3
RN
320 Status = gEfiShellProtocol->SetCurDir (Drive, Path + 1);\r
321 if (EFI_ERROR (Status)) {\r
322 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN(STR_GEN_DIR_NF), gShellLevel2HiiHandle, L"cd", Param1Copy);\r
b54fd049 323 ShellStatus = SHELL_NOT_FOUND;\r
b54fd049 324 }\r
9ea69f8a 325 }\r
a405b86d 326 }\r
d9bb3ca3
RN
327\r
328 if (Drive != NULL) {\r
329 FreePool (Drive);\r
330 }\r
331\r
332 if (Path != NULL) {\r
333 FreePool (Path);\r
334 }\r
335\r
336 FreePool (Param1Copy);\r
a405b86d 337 }\r
338 }\r
339 }\r
340\r
a405b86d 341 //\r
342 // free the command line package\r
343 //\r
344 ShellCommandLineFreeVarList (Package);\r
345\r
346 //\r
347 // return the status\r
348 //\r
349 return (ShellStatus);\r
350}\r
351\r