]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellLevel2CommandsLib/Mv.c
BaseTools: Update nmake Makefile to handle the file path with “:\\”.
[mirror_edk2.git] / ShellPkg / Library / UefiShellLevel2CommandsLib / Mv.c
CommitLineData
a405b86d 1/** @file\r
2 Main file for mv shell level 2 function.\r
3\r
83c7a556
CP
4 (C) Copyright 2013-2014, Hewlett-Packard Development Company, L.P.\r
5 Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>\r
a405b86d 6 This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "UefiShellLevel2CommandsLib.h"\r
17\r
18/**\r
19 Function to validate that moving a specific file (FileName) to a specific\r
20 location (DestPath) is valid.\r
21\r
22 This function will verify that the destination is not a subdirectory of\r
23 FullName, that the Current working Directory is not being moved, and that\r
24 the directory is not read only.\r
25\r
26 if the move is invalid this function will report the error to StdOut.\r
27\r
28 @param FullName [in] The name of the file to move.\r
29 @param Cwd [in] The current working directory\r
30 @param DestPath [in] The target location to move to\r
31 @param Attribute[in] The Attribute of the file\r
83c7a556 32 @param FileStatus[in] The Status of the file when opened\r
a405b86d 33\r
34 @retval TRUE The move is valid\r
35 @retval FALSE The move is not\r
36**/\r
37BOOLEAN\r
38EFIAPI\r
39IsValidMove(\r
83c7a556
CP
40 IN CONST CHAR16 *FullName,\r
41 IN CONST CHAR16 *Cwd,\r
42 IN CONST CHAR16 *DestPath,\r
43 IN CONST UINT64 Attribute,\r
44 IN CONST EFI_STATUS FileStatus\r
a405b86d 45 )\r
46{\r
47 CHAR16 *Test;\r
48 CHAR16 *Test1;\r
49 CHAR16 *TestWalker;\r
3e082d58 50 INTN Result;\r
a405b86d 51 UINTN TempLen;\r
52 if (Cwd != NULL && StrCmp(FullName, Cwd) == 0) {\r
53 //\r
54 // Invalid move\r
55 //\r
56 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MV_INV_CWD), gShellLevel2HiiHandle);\r
57 return (FALSE);\r
58 }\r
59 Test = NULL;\r
60 Test = StrnCatGrow(&Test, NULL, DestPath, 0);\r
61 TestWalker = Test;\r
62 ASSERT(TestWalker != NULL);\r
63 while(*TestWalker == L'\\') {\r
64 TestWalker++;\r
65 }\r
66 while(TestWalker != NULL && TestWalker[StrLen(TestWalker)-1] == L'\\') {\r
67 TestWalker[StrLen(TestWalker)-1] = CHAR_NULL;\r
68 }\r
69 ASSERT(TestWalker != NULL);\r
70 ASSERT(FullName != NULL);\r
71 if (StrStr(FullName, TestWalker) != 0) {\r
72 TempLen = StrLen(FullName);\r
73 if (StrStr(FullName, TestWalker) != FullName // not the first items... (could below it)\r
74 && TempLen <= (StrLen(TestWalker) + 1)\r
75 && StrStr(FullName+StrLen(TestWalker) + 1, L"\\") == NULL) {\r
76 //\r
77 // Invalid move\r
78 //\r
79 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MV_INV_SUB), gShellLevel2HiiHandle);\r
80 FreePool(Test);\r
81 return (FALSE);\r
82 }\r
83 }\r
84 FreePool(Test);\r
85 if (StrStr(DestPath, FullName) != 0 && StrStr(DestPath, FullName) != DestPath) {\r
86 //\r
87 // Invalid move\r
88 //\r
89 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MV_INV_SUB), gShellLevel2HiiHandle);\r
90 return (FALSE);\r
91 }\r
83c7a556 92 if (((Attribute & EFI_FILE_READ_ONLY) != 0) || (FileStatus == EFI_WRITE_PROTECTED)) {\r
a405b86d 93 //\r
94 // invalid to move read only\r
95 //\r
83c7a556 96 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MV_INV_RO), gShellLevel2HiiHandle, FullName);\r
a405b86d 97 return (FALSE);\r
98 }\r
99 Test = StrStr(FullName, L":");\r
100 Test1 = StrStr(DestPath, L":");\r
101 if (Test1 != NULL && Test != NULL) {\r
102 *Test = CHAR_NULL;\r
103 *Test1 = CHAR_NULL;\r
104 Result = StringNoCaseCompare(&FullName, &DestPath);\r
105 *Test = L':';\r
106 *Test1 = L':';\r
107 if (Result != 0) {\r
108 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MV_INV_FS), gShellLevel2HiiHandle);\r
109 return (FALSE);\r
110 }\r
111 }\r
112 return (TRUE);\r
113}\r
114\r
115/**\r
116 Function to take a destination path that might contain wildcards and verify\r
117 that there is only a single possible target (IE we cant have wildcards that\r
118 have 2 possible destination).\r
119\r
120 if the result is sucessful the caller must free *DestPathPointer.\r
121\r
4ff7e37b
ED
122 @param[in] DestDir The original path to the destination.\r
123 @param[in, out] DestPathPointer A pointer to the callee allocated final path.\r
124 @param[in] Cwd A pointer to the current working directory.\r
a405b86d 125\r
beab0fc5 126 @retval SHELL_INVALID_PARAMETER The DestDir could not be resolved to a location.\r
127 @retval SHELL_INVALID_PARAMETER The DestDir could be resolved to more than 1 location.\r
128 @retval SHELL_INVALID_PARAMETER Cwd is required and is NULL.\r
129 @retval SHELL_SUCCESS The operation was sucessful.\r
a405b86d 130**/\r
131SHELL_STATUS\r
132EFIAPI\r
133GetDestinationLocation(\r
134 IN CONST CHAR16 *DestDir,\r
135 IN OUT CHAR16 **DestPathPointer,\r
136 IN CONST CHAR16 *Cwd\r
137 )\r
138{\r
139 EFI_SHELL_FILE_INFO *DestList;\r
140 EFI_SHELL_FILE_INFO *Node;\r
a405b86d 141 CHAR16 *DestPath;\r
a405b86d 142 UINTN NewSize;\r
c32ad351 143 UINTN CurrentSize;\r
a405b86d 144\r
145 DestList = NULL;\r
146 DestPath = NULL;\r
b54fd049 147\r
148 if (StrStr(DestDir, L"\\") == DestDir) {\r
beab0fc5 149 if (Cwd == NULL) {\r
150 return SHELL_INVALID_PARAMETER;\r
151 }\r
b54fd049 152 DestPath = AllocateZeroPool(StrSize(Cwd));\r
153 if (DestPath == NULL) {\r
154 return (SHELL_OUT_OF_RESOURCES);\r
155 }\r
156 StrCpy(DestPath, Cwd);\r
ab94587a 157 while (PathRemoveLastItem(DestPath)) ;\r
c32ad351
CP
158\r
159 //\r
160 // Append DestDir beyond '\' which may be present\r
161 //\r
162 CurrentSize = StrSize(DestPath);\r
163 StrnCatGrow(&DestPath, &CurrentSize, &DestDir[1], 0);\r
164\r
b54fd049 165 *DestPathPointer = DestPath;\r
166 return (SHELL_SUCCESS);\r
167 }\r
a405b86d 168 //\r
169 // get the destination path\r
170 //\r
e755a4ca 171 ShellOpenFileMetaArg((CHAR16*)DestDir, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ|EFI_FILE_MODE_CREATE, &DestList);\r
a405b86d 172 if (DestList == NULL || IsListEmpty(&DestList->Link)) {\r
173 //\r
174 // Not existing... must be renaming\r
175 //\r
5051c287 176 if (StrStr(DestDir, L":") == NULL) {\r
beab0fc5 177 if (Cwd == NULL) {\r
178 ShellCloseFileMetaArg(&DestList);\r
179 return (SHELL_INVALID_PARAMETER);\r
180 }\r
a405b86d 181 NewSize = StrSize(Cwd);\r
182 NewSize += StrSize(DestDir);\r
183 DestPath = AllocateZeroPool(NewSize);\r
9ea69f8a 184 if (DestPath == NULL) {\r
185 ShellCloseFileMetaArg(&DestList);\r
186 return (SHELL_OUT_OF_RESOURCES);\r
187 }\r
a405b86d 188 StrCpy(DestPath, Cwd);\r
189 if (DestPath[StrLen(DestPath)-1] != L'\\' && DestDir[0] != L'\\') {\r
190 StrCat(DestPath, L"\\");\r
191 } else if (DestPath[StrLen(DestPath)-1] == L'\\' && DestDir[0] == L'\\') {\r
192 ((CHAR16*)DestPath)[StrLen(DestPath)-1] = CHAR_NULL;\r
193 }\r
194 StrCat(DestPath, DestDir);\r
195 } else {\r
196 ASSERT(DestPath == NULL);\r
197 DestPath = StrnCatGrow(&DestPath, NULL, DestDir, 0);\r
9ea69f8a 198 if (DestPath == NULL) {\r
199 ShellCloseFileMetaArg(&DestList);\r
200 return (SHELL_OUT_OF_RESOURCES);\r
201 }\r
a405b86d 202 }\r
203 } else {\r
204 Node = (EFI_SHELL_FILE_INFO*)GetFirstNode(&DestList->Link);\r
205 //\r
206 // Make sure there is only 1 node in the list.\r
207 //\r
208 if (!IsNodeAtEnd(&DestList->Link, &Node->Link)) {\r
209 ShellCloseFileMetaArg(&DestList);\r
210 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_MARG_ERROR), gShellLevel2HiiHandle, DestDir);\r
211 return (SHELL_INVALID_PARAMETER);\r
212 }\r
213 if (ShellIsDirectory(Node->FullName)==EFI_SUCCESS) {\r
214 DestPath = AllocateZeroPool(StrSize(Node->FullName)+sizeof(CHAR16));\r
9ea69f8a 215 if (DestPath == NULL) {\r
216 ShellCloseFileMetaArg(&DestList);\r
217 return (SHELL_OUT_OF_RESOURCES);\r
218 }\r
a405b86d 219 StrCpy(DestPath, Node->FullName);\r
220 StrCat(DestPath, L"\\");\r
221 } else {\r
222 //\r
223 // cant move onto another file.\r
224 //\r
225 ShellCloseFileMetaArg(&DestList);\r
226 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_ERROR), gShellLevel2HiiHandle, DestDir);\r
227 return (SHELL_INVALID_PARAMETER);\r
228 }\r
229 }\r
230\r
231 *DestPathPointer = DestPath;\r
232 ShellCloseFileMetaArg(&DestList);\r
233\r
234 return (SHELL_SUCCESS);\r
235}\r
236\r
237/**\r
238 function to take a list of files to move and a destination location and do\r
239 the verification and moving of those files to that location. This function\r
240 will report any errors to the user and continue to move the rest of the files.\r
241\r
242 @param[in] FileList A LIST_ENTRY* based list of files to move\r
b54fd049 243 @param[out] Resp pointer to response from question. Pass back on looped calling\r
a405b86d 244 @param[in] DestDir the destination location\r
245\r
246 @retval SHELL_SUCCESS the files were all moved.\r
247 @retval SHELL_INVALID_PARAMETER a parameter was invalid\r
248 @retval SHELL_SECURITY_VIOLATION a security violation ocurred\r
249 @retval SHELL_WRITE_PROTECTED the destination was write protected\r
250 @retval SHELL_OUT_OF_RESOURCES a memory allocation failed\r
251**/\r
252SHELL_STATUS\r
253EFIAPI\r
254ValidateAndMoveFiles(\r
255 IN CONST EFI_SHELL_FILE_INFO *FileList,\r
b54fd049 256 OUT VOID **Resp,\r
a405b86d 257 IN CONST CHAR16 *DestDir\r
258 )\r
259{\r
260 EFI_STATUS Status;\r
261 CHAR16 *HiiOutput;\r
262 CHAR16 *HiiResultOk;\r
263 CHAR16 *DestPath;\r
264 CONST CHAR16 *Cwd;\r
265 SHELL_STATUS ShellStatus;\r
266 CONST EFI_SHELL_FILE_INFO *Node;\r
267 EFI_FILE_INFO *NewFileInfo;\r
268 CHAR16 *TempLocation;\r
269 UINTN NewSize;\r
3e082d58 270 UINTN Length;\r
b54fd049 271 VOID *Response;\r
272 SHELL_FILE_HANDLE DestHandle;\r
0960ba17 273 CHAR16 *CleanFilePathStr;\r
a405b86d 274\r
275 ASSERT(FileList != NULL);\r
276 ASSERT(DestDir != NULL);\r
277\r
715096c2
QS
278 DestPath = NULL;\r
279 Cwd = ShellGetCurrentDir(NULL);\r
280 Response = *Resp;\r
281 CleanFilePathStr = NULL;\r
a405b86d 282\r
0960ba17
QS
283 Status = ShellLevel2StripQuotes (DestDir, &CleanFilePathStr);\r
284 if (EFI_ERROR (Status)) {\r
285 if (Status == EFI_OUT_OF_RESOURCES) {\r
286 return SHELL_OUT_OF_RESOURCES;\r
287 } else {\r
288 return SHELL_INVALID_PARAMETER;\r
289 }\r
290 } \r
291\r
a405b86d 292 //\r
293 // Get and validate the destination location\r
294 //\r
0960ba17
QS
295 ShellStatus = GetDestinationLocation(CleanFilePathStr, &DestPath, Cwd);\r
296 FreePool (CleanFilePathStr);\r
a405b86d 297 if (ShellStatus != SHELL_SUCCESS) {\r
298 return (ShellStatus);\r
299 }\r
ab94587a 300 DestPath = PathCleanUpDirectories(DestPath);\r
a405b86d 301\r
302 HiiOutput = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MV_OUTPUT), NULL);\r
303 HiiResultOk = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_GEN_RES_OK), NULL);\r
304 ASSERT (DestPath != NULL);\r
305 ASSERT (HiiResultOk != NULL);\r
306 ASSERT (HiiOutput != NULL);\r
a405b86d 307\r
308 //\r
309 // Go through the list of files and directories to move...\r
310 //\r
311 for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&FileList->Link)\r
312 ; !IsNull(&FileList->Link, &Node->Link)\r
313 ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&FileList->Link, &Node->Link)\r
314 ){\r
315 if (ShellGetExecutionBreakFlag()) {\r
316 break;\r
317 }\r
83c7a556
CP
318\r
319 //\r
320 // These should never be NULL\r
321 //\r
a405b86d 322 ASSERT(Node->FileName != NULL);\r
323 ASSERT(Node->FullName != NULL);\r
83c7a556 324 ASSERT(Node->Info != NULL);\r
a405b86d 325\r
326 //\r
327 // skip the directory traversing stuff...\r
328 //\r
329 if (StrCmp(Node->FileName, L".") == 0 || StrCmp(Node->FileName, L"..") == 0) {\r
330 continue;\r
331 }\r
332\r
333 //\r
334 // Validate that the move is valid\r
335 //\r
83c7a556 336 if (!IsValidMove(Node->FullName, Cwd, DestPath, Node->Info->Attribute, Node->Status)) {\r
a405b86d 337 ShellStatus = SHELL_INVALID_PARAMETER;\r
338 continue;\r
339 }\r
340\r
341 //\r
342 // Chop off map info from "DestPath"\r
343 //\r
344 if ((TempLocation = StrStr(DestPath, L":")) != NULL) {\r
345 CopyMem(DestPath, TempLocation+1, StrSize(TempLocation+1));\r
346 }\r
347\r
348 //\r
349 // construct the new file info block\r
350 //\r
351 NewSize = StrSize(DestPath);\r
73c83c69 352 NewSize += StrSize(Node->FileName) + SIZE_OF_EFI_FILE_INFO + sizeof(CHAR16);\r
a405b86d 353 NewFileInfo = AllocateZeroPool(NewSize);\r
9ea69f8a 354 if (NewFileInfo == NULL) {\r
355 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellLevel2HiiHandle);\r
356 ShellStatus = SHELL_OUT_OF_RESOURCES;\r
a405b86d 357 } else {\r
73c83c69 358 CopyMem(NewFileInfo, Node->Info, SIZE_OF_EFI_FILE_INFO);\r
9ea69f8a 359 if (DestPath[0] != L'\\') {\r
360 StrCpy(NewFileInfo->FileName, L"\\");\r
361 StrCat(NewFileInfo->FileName, DestPath);\r
362 } else {\r
363 StrCpy(NewFileInfo->FileName, DestPath);\r
a405b86d 364 }\r
3e082d58 365 Length = StrLen(NewFileInfo->FileName);\r
366 if (Length > 0) {\r
367 Length--;\r
368 }\r
369 if (NewFileInfo->FileName[Length] == L'\\') {\r
9ea69f8a 370 if (Node->FileName[0] == L'\\') {\r
371 //\r
372 // Don't allow for double slashes. Eliminate one of them.\r
373 //\r
3e082d58 374 NewFileInfo->FileName[Length] = CHAR_NULL;\r
9ea69f8a 375 }\r
376 StrCat(NewFileInfo->FileName, Node->FileName);\r
377 }\r
73c83c69 378 NewFileInfo->Size = SIZE_OF_EFI_FILE_INFO + StrSize(NewFileInfo->FileName);\r
9ea69f8a 379 ShellPrintEx(-1, -1, HiiOutput, Node->FullName, NewFileInfo->FileName);\r
a405b86d 380\r
b54fd049 381 if (!EFI_ERROR(ShellFileExists(NewFileInfo->FileName))) {\r
382 if (Response == NULL) {\r
383 ShellPromptForResponseHii(ShellPromptResponseTypeYesNoAllCancel, STRING_TOKEN (STR_GEN_DEST_EXIST_OVR), gShellLevel2HiiHandle, &Response);\r
384 }\r
385 switch (*(SHELL_PROMPT_RESPONSE*)Response) {\r
386 case ShellPromptResponseNo:\r
387 FreePool(NewFileInfo);\r
388 continue;\r
389 case ShellPromptResponseCancel:\r
390 *Resp = Response;\r
391 //\r
392 // indicate to stop everything\r
393 //\r
394 FreePool(NewFileInfo);\r
395 FreePool(DestPath);\r
396 FreePool(HiiOutput);\r
397 FreePool(HiiResultOk);\r
398 return (SHELL_ABORTED);\r
399 case ShellPromptResponseAll:\r
400 *Resp = Response;\r
401 break;\r
402 case ShellPromptResponseYes:\r
403 FreePool(Response);\r
404 break;\r
405 default:\r
406 FreePool(Response);\r
407 FreePool(NewFileInfo);\r
408 FreePool(DestPath);\r
409 FreePool(HiiOutput);\r
410 FreePool(HiiResultOk);\r
411 return SHELL_ABORTED;\r
412 }\r
413 Status = ShellOpenFileByName(NewFileInfo->FileName, &DestHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0);\r
414 ShellDeleteFile(&DestHandle);\r
415 }\r
416\r
417\r
9ea69f8a 418 //\r
419 // Perform the move operation\r
420 //\r
421 Status = ShellSetFileInfo(Node->Handle, NewFileInfo);\r
a405b86d 422\r
9ea69f8a 423 //\r
424 // Free the info object we used...\r
425 //\r
9ea69f8a 426 FreePool(NewFileInfo);\r
a405b86d 427\r
a405b86d 428 //\r
9ea69f8a 429 // Check our result\r
a405b86d 430 //\r
9ea69f8a 431 if (EFI_ERROR(Status)) {\r
432 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, Status);\r
cbcccd2c
LG
433 ShellStatus = SHELL_INVALID_PARAMETER;\r
434 if (Status == EFI_SECURITY_VIOLATION) {\r
435 ShellStatus = SHELL_SECURITY_VIOLATION;\r
436 } else if (Status == EFI_WRITE_PROTECTED) {\r
437 ShellStatus = SHELL_WRITE_PROTECTED;\r
438 } else if (Status == EFI_OUT_OF_RESOURCES) {\r
439 ShellStatus = SHELL_OUT_OF_RESOURCES;\r
440 } else if (Status == EFI_DEVICE_ERROR) {\r
441 ShellStatus = SHELL_DEVICE_ERROR;\r
442 } else if (Status == EFI_ACCESS_DENIED) {\r
443 ShellStatus = SHELL_ACCESS_DENIED;\r
444 }\r
9ea69f8a 445 } else {\r
446 ShellPrintEx(-1, -1, L"%s", HiiResultOk);\r
447 }\r
a405b86d 448 }\r
449 } // for loop\r
450\r
451 FreePool(DestPath);\r
452 FreePool(HiiOutput);\r
453 FreePool(HiiResultOk);\r
454 return (ShellStatus);\r
455}\r
456\r
b54fd049 457/**\r
458 Function for 'mv' command.\r
459\r
460 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
461 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
462**/\r
a405b86d 463SHELL_STATUS\r
464EFIAPI\r
465ShellCommandRunMv (\r
466 IN EFI_HANDLE ImageHandle,\r
467 IN EFI_SYSTEM_TABLE *SystemTable\r
468 )\r
469{\r
470 EFI_STATUS Status;\r
471 LIST_ENTRY *Package;\r
472 CHAR16 *ProblemParam;\r
473 SHELL_STATUS ShellStatus;\r
474 UINTN ParamCount;\r
475 UINTN LoopCounter;\r
476 EFI_SHELL_FILE_INFO *FileList;\r
b54fd049 477 VOID *Response;\r
a405b86d 478\r
479 ProblemParam = NULL;\r
480 ShellStatus = SHELL_SUCCESS;\r
481 ParamCount = 0;\r
482 FileList = NULL;\r
b54fd049 483 Response = NULL;\r
a405b86d 484\r
485 //\r
486 // initialize the shell lib (we must be in non-auto-init...)\r
487 //\r
488 Status = ShellInitialize();\r
489 ASSERT_EFI_ERROR(Status);\r
490\r
491 //\r
492 // parse the command line\r
493 //\r
494 Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE);\r
495 if (EFI_ERROR(Status)) {\r
496 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
497 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ProblemParam);\r
498 FreePool(ProblemParam);\r
499 ShellStatus = SHELL_INVALID_PARAMETER;\r
500 } else {\r
501 ASSERT(FALSE);\r
502 }\r
503 } else {\r
504 //\r
505 // check for "-?"\r
506 //\r
507 if (ShellCommandLineGetFlag(Package, L"-?")) {\r
508 ASSERT(FALSE);\r
509 }\r
510\r
511 switch (ParamCount = ShellCommandLineGetCount(Package)) {\r
512 case 0:\r
513 case 1:\r
514 //\r
515 // we have insufficient parameters\r
516 //\r
517 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle);\r
518 ShellStatus = SHELL_INVALID_PARAMETER;\r
519 break;\r
520 case 2:\r
521 //\r
522 // must have valid CWD for single parameter...\r
523 //\r
524 if (ShellGetCurrentDir(NULL) == NULL){\r
525 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle);\r
526 ShellStatus = SHELL_INVALID_PARAMETER;\r
527 } else {\r
528 Status = ShellOpenFileMetaArg((CHAR16*)ShellCommandLineGetRawValue(Package, 1), EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList);\r
529 if (FileList == NULL || IsListEmpty(&FileList->Link) || EFI_ERROR(Status)) {\r
530 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, ShellCommandLineGetRawValue(Package, 1));\r
531 ShellStatus = SHELL_NOT_FOUND;\r
532 } else {\r
533 //\r
534 // ValidateAndMoveFiles will report errors to the screen itself\r
535 //\r
b54fd049 536 ShellStatus = ValidateAndMoveFiles(FileList, &Response, ShellGetCurrentDir(NULL));\r
a405b86d 537 }\r
538 }\r
539\r
540 break;\r
541 default:\r
542 ///@todo make sure this works with error half way through and continues...\r
b54fd049 543 for (ParamCount--, LoopCounter = 1 ; LoopCounter < ParamCount ; LoopCounter++) {\r
a405b86d 544 if (ShellGetExecutionBreakFlag()) {\r
545 break;\r
546 }\r
547 Status = ShellOpenFileMetaArg((CHAR16*)ShellCommandLineGetRawValue(Package, LoopCounter), EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList);\r
548 if (FileList == NULL || IsListEmpty(&FileList->Link) || EFI_ERROR(Status)) {\r
b54fd049 549 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, ShellCommandLineGetRawValue(Package, LoopCounter));\r
a405b86d 550 ShellStatus = SHELL_NOT_FOUND;\r
551 } else {\r
552 //\r
553 // ValidateAndMoveFiles will report errors to the screen itself\r
554 // Only change ShellStatus if it's sucessful\r
555 //\r
556 if (ShellStatus == SHELL_SUCCESS) {\r
b54fd049 557 ShellStatus = ValidateAndMoveFiles(FileList, &Response, ShellCommandLineGetRawValue(Package, ParamCount));\r
a405b86d 558 } else {\r
b54fd049 559 ValidateAndMoveFiles(FileList, &Response, ShellCommandLineGetRawValue(Package, ParamCount));\r
a405b86d 560 }\r
561 }\r
562 if (FileList != NULL && !IsListEmpty(&FileList->Link)) {\r
563 Status = ShellCloseFileMetaArg(&FileList);\r
564 if (EFI_ERROR(Status) && ShellStatus == SHELL_SUCCESS) {\r
565 ShellStatus = SHELL_ACCESS_DENIED;\r
566 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_FILE), gShellLevel2HiiHandle, ShellCommandLineGetRawValue(Package, 1), ShellStatus|MAX_BIT);\r
567 }\r
568 }\r
569 }\r
570 break;\r
571 } // switch on parameter count\r
572\r
573 if (FileList != NULL) {\r
574 ShellCloseFileMetaArg(&FileList);\r
575 }\r
576\r
577 //\r
578 // free the command line package\r
579 //\r
580 ShellCommandLineFreeVarList (Package);\r
581 }\r
582\r
b54fd049 583 SHELL_FREE_NON_NULL(Response);\r
584\r
a405b86d 585 if (ShellGetExecutionBreakFlag()) {\r
586 return (SHELL_ABORTED);\r
587 }\r
588\r
589 return (ShellStatus);\r
590}\r