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