]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellLevel2CommandsLib/Cp.c
ShellPkg: Remove optimization disable compiler flag
[mirror_edk2.git] / ShellPkg / Library / UefiShellLevel2CommandsLib / Cp.c
CommitLineData
a405b86d 1/** @file\r
2 Main file for cp shell level 2 function.\r
3\r
4 Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
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// this is later in the file.\r
18SHELL_STATUS\r
19EFIAPI\r
20ValidateAndCopyFiles(\r
21 IN CONST EFI_SHELL_FILE_INFO *FileList,\r
22 IN CONST CHAR16 *DestDir,\r
23 IN BOOLEAN SilentMode,\r
24 IN BOOLEAN RecursiveMode,\r
25 IN VOID **Resp\r
26 );\r
27\r
28/**\r
29 Function to Copy one file to another location\r
30\r
31 If the destination exists the user will be prompted and the result put into *resp\r
32\r
33 @param[in] Source pointer to source file name\r
34 @param[in] Dest pointer to destination file name\r
35 @param[out] Resp pointer to response from question. Pass back on looped calling\r
36 @param[in] SilentMode whether to run in quiet mode or not\r
37\r
38 @retval SHELL_SUCCESS The source file was copied to the destination\r
39**/\r
40SHELL_STATUS\r
41EFIAPI\r
42CopySingleFile(\r
43 IN CONST CHAR16 *Source,\r
44 IN CONST CHAR16 *Dest,\r
45 OUT VOID **Resp,\r
46 IN BOOLEAN SilentMode\r
47 )\r
48{\r
49 VOID *Response;\r
50 UINTN ReadSize;\r
51 SHELL_FILE_HANDLE SourceHandle;\r
52 SHELL_FILE_HANDLE DestHandle;\r
53 EFI_STATUS Status;\r
54 VOID *Buffer;\r
55 CHAR16 *TempName;\r
56 UINTN Size;\r
57 EFI_SHELL_FILE_INFO *List;\r
58 SHELL_STATUS ShellStatus;\r
59\r
60\r
61 ASSERT(Resp != NULL);\r
62\r
63 SourceHandle = NULL;\r
64 DestHandle = NULL;\r
65 Response = *Resp;\r
66 List = NULL;\r
67\r
68 ReadSize = PcdGet16(PcdShellFileOperationSize);\r
69 // Why bother copying a file to itself\r
70 if (StrCmp(Source, Dest) == 0) {\r
71 return (SHELL_SUCCESS);\r
72 }\r
73\r
74 //\r
75 // Open destination file without create\r
76 //\r
77 Status = ShellOpenFileByName(Dest, &DestHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0);\r
78\r
79 //\r
80 // close file\r
81 //\r
82 if (DestHandle != NULL) {\r
83 ShellCloseFile(&DestHandle);\r
84 DestHandle = NULL;\r
85 }\r
86\r
87 //\r
88 // if the destination file existed check response and possibly prompt user\r
89 //\r
90 if (!EFI_ERROR(Status)) {\r
91 if (Response == NULL && !SilentMode) {\r
92 Status = ShellPromptForResponseHii(ShellPromptResponseTypeYesNoAllCancel, STRING_TOKEN (STR_CP_PROMPT), gShellLevel2HiiHandle, &Response);\r
93 }\r
94 //\r
95 // possibly return based on response\r
96 //\r
97 if (!SilentMode) {\r
98 switch (*(SHELL_PROMPT_RESPONSE*)Response) {\r
99 case ShellPromptResponseNo:\r
100 //\r
101 // return success here so we dont stop the process\r
102 //\r
103 return (SHELL_SUCCESS);\r
104 case ShellPromptResponseCancel:\r
105 *Resp = Response;\r
106 //\r
107 // indicate to stop everything\r
108 //\r
109 return (SHELL_ABORTED);\r
110 case ShellPromptResponseAll:\r
111 *Resp = Response;\r
112 case ShellPromptResponseYes:\r
113 break;\r
114 }\r
115 }\r
116 }\r
117\r
118 if (ShellIsDirectory(Source) == EFI_SUCCESS) {\r
119 Status = ShellCreateDirectory(Dest, &DestHandle);\r
120 if (EFI_ERROR(Status)) {\r
121 return (SHELL_ACCESS_DENIED);\r
122 }\r
123\r
124 //\r
125 // Now copy all the files under the directory...\r
126 //\r
127 TempName = NULL;\r
128 Size = 0;\r
129 StrnCatGrow(&TempName, &Size, Source, 0);\r
130 StrnCatGrow(&TempName, &Size, L"\\*", 0);\r
131 ShellOpenFileMetaArg((CHAR16*)TempName, EFI_FILE_MODE_READ, &List);\r
132 TempName = NULL;\r
133 StrnCatGrow(&TempName, &Size, Dest, 0);\r
134 StrnCatGrow(&TempName, &Size, L"\\", 0);\r
135 ShellStatus = ValidateAndCopyFiles(List, TempName, SilentMode, TRUE, Resp);\r
136 ShellCloseFileMetaArg(&List);\r
137 FreePool(TempName);\r
138 Size = 0;\r
139 } else {\r
140 //\r
141 // open file with create enabled\r
142 //\r
143 Status = ShellOpenFileByName(Dest, &DestHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);\r
144 if (EFI_ERROR(Status)) {\r
145 return (SHELL_ACCESS_DENIED);\r
146 }\r
147\r
148 //\r
149 // open source file\r
150 //\r
151 Status = ShellOpenFileByName(Source, &SourceHandle, EFI_FILE_MODE_READ, 0);\r
152 ASSERT_EFI_ERROR(Status);\r
153\r
154 //\r
155 // copy data between files\r
156 //\r
157 Buffer = AllocateZeroPool(ReadSize);\r
158 ASSERT(Buffer != NULL);\r
159 while (ReadSize == PcdGet16(PcdShellFileOperationSize) && !EFI_ERROR(Status)) {\r
160 Status = ShellReadFile(SourceHandle, &ReadSize, Buffer);\r
161 ASSERT_EFI_ERROR(Status);\r
162 Status = ShellWriteFile(DestHandle, &ReadSize, Buffer);\r
163 }\r
164 }\r
165\r
166 //\r
167 // close files\r
168 //\r
169 if (DestHandle != NULL) {\r
170 ShellCloseFile(&DestHandle);\r
171 DestHandle = NULL;\r
172 }\r
173 if (SourceHandle != NULL) {\r
174 ShellCloseFile(&SourceHandle);\r
175 SourceHandle = NULL;\r
176 }\r
177\r
178 //\r
179 // return\r
180 //\r
181 return (SHELL_SUCCESS);\r
182}\r
183\r
184/**\r
185 function to take a list of files to copy and a destination location and do\r
186 the verification and copying of those files to that location. This function\r
187 will report any errors to the user and halt.\r
188\r
189 The key is to have this function called ONLY once. this allows for the parameter\r
190 verification to happen correctly.\r
191\r
192 @param[in] FileList A LIST_ENTRY* based list of files to move\r
193 @param[in] DestDir the destination location\r
194\r
195 @retval SHELL_SUCCESS the files were all moved.\r
196 @retval SHELL_INVALID_PARAMETER a parameter was invalid\r
197 @retval SHELL_SECURITY_VIOLATION a security violation ocurred\r
198 @retval SHELL_WRITE_PROTECTED the destination was write protected\r
199 @retval SHELL_OUT_OF_RESOURCES a memory allocation failed\r
200**/\r
201SHELL_STATUS\r
202EFIAPI\r
203ValidateAndCopyFiles(\r
204 IN CONST EFI_SHELL_FILE_INFO *FileList,\r
205 IN CONST CHAR16 *DestDir,\r
206 IN BOOLEAN SilentMode,\r
207 IN BOOLEAN RecursiveMode,\r
208 IN VOID **Resp\r
209 )\r
210{\r
211 CHAR16 *HiiOutput;\r
212 CHAR16 *HiiResultOk;\r
213 CONST EFI_SHELL_FILE_INFO *Node;\r
214 SHELL_STATUS ShellStatus;\r
215 CHAR16 *DestPath;\r
216 VOID *Response;\r
217 UINTN PathLen;\r
218 CONST CHAR16 *Cwd;\r
219 CONST CHAR16 *TempLocation;\r
220 UINTN NewSize;\r
221\r
222 if (Resp == NULL) {\r
223 Response = NULL;\r
224 } else {\r
225 Response = *Resp;\r
226 }\r
227\r
228 DestPath = NULL;\r
229 ShellStatus = SHELL_SUCCESS;\r
230 PathLen = 0;\r
231 Cwd = ShellGetCurrentDir(NULL);\r
232\r
233 ASSERT(FileList != NULL);\r
234 ASSERT(DestDir != NULL);\r
235\r
236 //\r
237 // If we are trying to copy multiple files... make sure we got a directory for the target...\r
238 //\r
239 if (EFI_ERROR(ShellIsDirectory(DestDir)) && FileList->Link.ForwardLink != FileList->Link.BackLink) {\r
240 //\r
241 // Error for destination not a directory\r
242 //\r
243 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_DIR), gShellLevel2HiiHandle, DestDir);\r
244 return (SHELL_INVALID_PARAMETER);\r
245 }\r
246 for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&FileList->Link)\r
247 ; !IsNull(&FileList->Link, &Node->Link)\r
248 ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&FileList->Link, &Node->Link)\r
249 ){\r
250 //\r
251 // skip the directory traversing stuff...\r
252 //\r
253 if (StrCmp(Node->FileName, L".") == 0 || StrCmp(Node->FileName, L"..") == 0) {\r
254 continue;\r
255 }\r
256\r
257 NewSize = StrSize(DestDir);\r
258 NewSize += StrSize(Node->FileName);\r
259 NewSize += StrSize(Cwd);\r
260 if (NewSize > PathLen) {\r
261 PathLen = NewSize;\r
262 }\r
263\r
264 //\r
265 // Make sure got -r if required\r
266 //\r
267 if (!RecursiveMode && !EFI_ERROR(ShellIsDirectory(Node->FullName))) {\r
268 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_DIR_REQ), gShellLevel2HiiHandle);\r
269 return (SHELL_INVALID_PARAMETER);\r
270 }\r
271\r
272 //\r
273 // make sure got dest as dir if needed\r
274 //\r
275 if (!EFI_ERROR(ShellIsDirectory(Node->FullName)) && EFI_ERROR(ShellIsDirectory(DestDir))) {\r
276 //\r
277 // Error for destination not a directory\r
278 //\r
279 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_DIR), gShellLevel2HiiHandle, DestDir);\r
280 return (SHELL_INVALID_PARAMETER);\r
281 }\r
282 }\r
283\r
284 HiiOutput = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_CP_OUTPUT), NULL);\r
285 HiiResultOk = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_GEN_RES_OK), NULL);\r
286 DestPath = AllocatePool(PathLen);\r
287\r
288 //\r
289 // Go through the list of files to copy...\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 if (FileList->Link.ForwardLink == FileList->Link.BackLink // 1 item\r
309 && EFI_ERROR(ShellIsDirectory(DestDir)) // not an existing directory\r
310 ) {\r
311 ASSERT(StrStr(DestDir, L":") == NULL);\r
312 //\r
313 // simple copy of a single file\r
314 //\r
315 StrCpy(DestPath, Cwd);\r
316 if (DestPath[StrLen(DestPath)-1] != L'\\' && DestDir[0] != L'\\') {\r
317 StrCat(DestPath, L"\\");\r
318 } else if (DestPath[StrLen(DestPath)-1] == L'\\' && DestDir[0] == L'\\') {\r
319 ((CHAR16*)DestPath)[StrLen(DestPath)-1] = CHAR_NULL;\r
320 }\r
321 StrCat(DestPath, DestDir);\r
322 } else {\r
323 //\r
324 // we have multiple files or a directory in the DestDir\r
325 //\r
326 if (StrStr(DestDir, L":") == NULL) {\r
327 StrCpy(DestPath, Cwd);\r
328 if (DestPath[StrLen(DestPath)-1] != L'\\' && DestDir[0] != L'\\') {\r
329 StrCat(DestPath, L"\\");\r
330 } else if (DestPath[StrLen(DestPath)-1] == L'\\' && DestDir[0] == L'\\') {\r
331 ((CHAR16*)DestPath)[StrLen(DestPath)-1] = CHAR_NULL;\r
332 }\r
333 StrCat(DestPath, DestDir);\r
334 if (DestDir[StrLen(DestDir)-1] != L'\\' && Node->FileName[0] != L'\\') {\r
335 StrCat(DestPath, L"\\");\r
336 } else if (DestDir[StrLen(DestDir)-1] == L'\\' && Node->FileName[0] == L'\\') {\r
337 ((CHAR16*)DestPath)[StrLen(DestPath)-1] = CHAR_NULL;\r
338 }\r
339 StrCat(DestPath, Node->FileName);\r
340\r
341 } else {\r
342 StrCpy(DestPath, DestDir);\r
343 if (DestDir[StrLen(DestDir)-1] != L'\\' && Node->FileName[0] != L'\\') {\r
344 StrCat(DestPath, L"\\");\r
345 } else if (DestDir[StrLen(DestDir)-1] == L'\\' && Node->FileName[0] == L'\\') {\r
346 ((CHAR16*)DestDir)[StrLen(DestDir)-1] = CHAR_NULL;\r
347 }\r
348 StrCat(DestPath, Node->FileName);\r
349 }\r
350 }\r
351\r
352 //\r
353 // Make sure the path exists\r
354 //\r
355 if (EFI_ERROR(VerifyIntermediateDirectories(DestPath))) {\r
356 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_DIR_WNF), gShellLevel2HiiHandle);\r
357 ShellStatus = SHELL_DEVICE_ERROR;\r
358 break;\r
359 }\r
360\r
361 if ( !EFI_ERROR(ShellIsDirectory(Node->FullName))\r
362 && !EFI_ERROR(ShellIsDirectory(DestPath))\r
363 && StrniCmp(Node->FullName, DestPath, StrLen(DestPath)) == NULL\r
364 ){\r
365 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_SD_PARENT), gShellLevel2HiiHandle);\r
366 ShellStatus = SHELL_INVALID_PARAMETER;\r
367 break;\r
368 }\r
369 if (StringNoCaseCompare(&Node->FullName, &DestPath) == 0) {\r
370 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_SD_SAME), gShellLevel2HiiHandle);\r
371 ShellStatus = SHELL_INVALID_PARAMETER;\r
372 break;\r
373 }\r
374\r
375 if ((TempLocation = StrniCmp(Node->FullName, DestPath, StrLen(Node->FullName))) == 0\r
376 && (DestPath[StrLen(Node->FullName)] == CHAR_NULL || DestPath[StrLen(Node->FullName)] == L'\\')\r
377 ) {\r
378 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_SD_SAME), gShellLevel2HiiHandle);\r
379 ShellStatus = SHELL_INVALID_PARAMETER;\r
380 break;\r
381 }\r
382\r
383 CleanPath(DestPath);\r
384\r
385 ShellPrintEx(-1, -1, HiiOutput, Node->FullName, DestPath);\r
386\r
387 //\r
388 // copy single file...\r
389 //\r
390 ShellStatus = CopySingleFile(Node->FullName, DestPath, &Response, SilentMode);\r
391 if (ShellStatus != SHELL_SUCCESS) {\r
392 break;\r
393 }\r
394 }\r
395 if (ShellStatus == SHELL_SUCCESS && Resp == NULL) {\r
396 ShellPrintEx(-1, -1, L"%s", HiiResultOk);\r
397 }\r
398\r
399 SHELL_FREE_NON_NULL(DestPath);\r
400 SHELL_FREE_NON_NULL(HiiOutput);\r
401 SHELL_FREE_NON_NULL(HiiResultOk);\r
402 if (Resp != NULL) {\r
403 SHELL_FREE_NON_NULL(Response);\r
404 }\r
405\r
406 return (ShellStatus);\r
407}\r
408\r
409SHELL_STATUS\r
410EFIAPI\r
411ProcessValidateAndCopyFiles(\r
412 IN EFI_SHELL_FILE_INFO *FileList,\r
413 IN CONST CHAR16 *DestDir,\r
414 IN BOOLEAN SilentMode,\r
415 IN BOOLEAN RecursiveMode\r
416 )\r
417{\r
418 SHELL_STATUS ShellStatus;\r
419 EFI_SHELL_FILE_INFO *List;\r
420 EFI_STATUS Status;\r
421 EFI_FILE_INFO *FileInfo;\r
422\r
423 List = NULL;\r
424\r
425 Status = ShellOpenFileMetaArg((CHAR16*)DestDir, EFI_FILE_MODE_READ, &List);\r
426 if (List != NULL && List->Link.ForwardLink != List->Link.BackLink) {\r
427 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_MARG_ERROR), gShellLevel2HiiHandle, DestDir);\r
428 ShellStatus = SHELL_INVALID_PARAMETER;\r
429 ShellCloseFileMetaArg(&List);\r
430 } else if (List != NULL) {\r
431 ASSERT(List != NULL);\r
432 ASSERT(((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink) != NULL);\r
433 ASSERT(((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink)->FullName != NULL);\r
434 FileInfo = NULL;\r
435 FileInfo = gEfiShellProtocol->GetFileInfo(((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink)->Handle);\r
436 ASSERT(FileInfo != NULL);\r
437 if ((FileInfo->Attribute & EFI_FILE_READ_ONLY) == 0) {\r
438 ShellStatus = ValidateAndCopyFiles(FileList, ((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink)->FullName, SilentMode, RecursiveMode, NULL);\r
439 } else {\r
440 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_DEST_ERROR), gShellLevel2HiiHandle);\r
441 ShellStatus = SHELL_ACCESS_DENIED;\r
442 }\r
443 SHELL_FREE_NON_NULL(FileInfo);\r
444 ShellCloseFileMetaArg(&List);\r
445 } else {\r
446 ShellStatus = ValidateAndCopyFiles(FileList, DestDir, SilentMode, RecursiveMode, NULL);\r
447 }\r
448\r
449 return (ShellStatus);\r
450}\r
451\r
452STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
453 {L"-r", TypeFlag},\r
454 {L"-q", TypeFlag},\r
455 {NULL, TypeMax}\r
456 };\r
457\r
458/**\r
459 Function for 'cp' command.\r
460\r
461 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
462 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
463**/\r
464SHELL_STATUS\r
465EFIAPI\r
466ShellCommandRunCp (\r
467 IN EFI_HANDLE ImageHandle,\r
468 IN EFI_SYSTEM_TABLE *SystemTable\r
469 )\r
470{\r
471 EFI_STATUS Status;\r
472 LIST_ENTRY *Package;\r
473 CHAR16 *ProblemParam;\r
474 SHELL_STATUS ShellStatus;\r
475 UINTN ParamCount;\r
476 UINTN LoopCounter;\r
477 EFI_SHELL_FILE_INFO *FileList;\r
478 BOOLEAN SilentMode;\r
479 BOOLEAN RecursiveMode;\r
480 CONST CHAR16 *Cwd;\r
481\r
482 ProblemParam = NULL;\r
483 ShellStatus = SHELL_SUCCESS;\r
484 ParamCount = 0;\r
485 FileList = NULL;\r
486\r
487 //\r
488 // initialize the shell lib (we must be in non-auto-init...)\r
489 //\r
490 Status = ShellInitialize();\r
491 ASSERT_EFI_ERROR(Status);\r
492\r
493 Status = CommandInit();\r
494 ASSERT_EFI_ERROR(Status);\r
495\r
496 //\r
497 // parse the command line\r
498 //\r
499 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
500 if (EFI_ERROR(Status)) {\r
501 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
502 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ProblemParam);\r
503 FreePool(ProblemParam);\r
504 ShellStatus = SHELL_INVALID_PARAMETER;\r
505 } else {\r
506 ASSERT(FALSE);\r
507 }\r
508 } else {\r
509 //\r
510 // check for "-?"\r
511 //\r
512 if (ShellCommandLineGetFlag(Package, L"-?")) {\r
513 ASSERT(FALSE);\r
514 }\r
515\r
516 //\r
517 // Initialize SilentMode and RecursiveMode\r
518 //\r
519 if (gEfiShellProtocol->BatchIsActive()) {\r
520 SilentMode = TRUE;\r
521 } else {\r
522 SilentMode = ShellCommandLineGetFlag(Package, L"-q");\r
523 }\r
524 RecursiveMode = ShellCommandLineGetFlag(Package, L"-r");\r
525\r
526 switch (ParamCount = ShellCommandLineGetCount(Package)) {\r
527 case 0:\r
528 case 1:\r
529 //\r
530 // we have insufficient parameters\r
531 //\r
532 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle);\r
533 ShellStatus = SHELL_INVALID_PARAMETER;\r
534 break;\r
535 case 2:\r
536 //\r
537 // must have valid CWD for single parameter...\r
538 //\r
539 Cwd = ShellGetCurrentDir(NULL);\r
540 if (Cwd == NULL){\r
541 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle);\r
542 ShellStatus = SHELL_INVALID_PARAMETER;\r
543 } else {\r
544 Status = ShellOpenFileMetaArg((CHAR16*)ShellCommandLineGetRawValue(Package, 1), EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList);\r
545 if (FileList == NULL || IsListEmpty(&FileList->Link) || EFI_ERROR(Status)) {\r
546 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, ShellCommandLineGetRawValue(Package, 1));\r
547 ShellStatus = SHELL_NOT_FOUND;\r
548 } else {\r
549 ShellStatus = ProcessValidateAndCopyFiles(FileList, Cwd, SilentMode, RecursiveMode);\r
550 }\r
551 }\r
552\r
553 break;\r
554 default:\r
555 //\r
556 // Make a big list of all the files...\r
557 //\r
558 for (ParamCount--, LoopCounter = 1 ; LoopCounter < ParamCount && ShellStatus == SHELL_SUCCESS ; LoopCounter++) {\r
559 if (ShellGetExecutionBreakFlag()) {\r
560 break;\r
561 }\r
562 Status = ShellOpenFileMetaArg((CHAR16*)ShellCommandLineGetRawValue(Package, LoopCounter), EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList);\r
563 if (EFI_ERROR(Status) || FileList == NULL || IsListEmpty(&FileList->Link)) {\r
564 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, ShellCommandLineGetRawValue(Package, 1));\r
565 ShellStatus = SHELL_NOT_FOUND;\r
566 }\r
567 }\r
568 //\r
569 // now copy them all...\r
570 //\r
571 if (FileList != NULL && !IsListEmpty(&FileList->Link)) {\r
572 ShellStatus = ProcessValidateAndCopyFiles(FileList, ShellCommandCleanPath((CHAR16*)ShellCommandLineGetRawValue(Package, ParamCount)), SilentMode, RecursiveMode);\r
573 Status = ShellCloseFileMetaArg(&FileList);\r
574 if (EFI_ERROR(Status) && ShellStatus == SHELL_SUCCESS) {\r
575 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_FILE), gShellLevel2HiiHandle, ShellCommandLineGetRawValue(Package, 1), ShellStatus|MAX_BIT);\r
576 ShellStatus = SHELL_ACCESS_DENIED;\r
577 }\r
578 }\r
579\r
580 break;\r
581 } // switch on parameter count\r
582\r
583 if (FileList != NULL) {\r
584 ShellCloseFileMetaArg(&FileList);\r
585 }\r
586\r
587 //\r
588 // free the command line package\r
589 //\r
590 ShellCommandLineFreeVarList (Package);\r
591 }\r
592\r
593 if (ShellGetExecutionBreakFlag()) {\r
594 return (SHELL_ABORTED);\r
595 }\r
596\r
597 return (ShellStatus);\r
598}\r
599\r