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