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