2 Main file for cp shell level 2 function.
4 Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "UefiShellLevel2CommandsLib.h"
16 #include <Guid/FileSystemInfo.h>
17 #include <Guid/FileSystemVolumeLabelInfo.h>
20 Function to take a list of files to copy and a destination location and do
21 the verification and copying of those files to that location. This function
22 will report any errors to the user and halt.
24 @param[in] FileList A LIST_ENTRY* based list of files to move.
25 @param[in] DestDir The destination location.
26 @param[in] SilentMode TRUE to eliminate screen output.
27 @param[in] RecursiveMode TRUE to copy directories.
28 @param[in] Resp The response to the overwrite query (if always).
30 @retval SHELL_SUCCESS the files were all moved.
31 @retval SHELL_INVALID_PARAMETER a parameter was invalid
32 @retval SHELL_SECURITY_VIOLATION a security violation ocurred
33 @retval SHELL_WRITE_PROTECTED the destination was write protected
34 @retval SHELL_OUT_OF_RESOURCES a memory allocation failed
39 IN CONST EFI_SHELL_FILE_INFO
*FileList
,
40 IN CONST CHAR16
*DestDir
,
41 IN BOOLEAN SilentMode
,
42 IN BOOLEAN RecursiveMode
,
47 Function to Copy one file to another location
49 If the destination exists the user will be prompted and the result put into *resp
51 @param[in] Source pointer to source file name
52 @param[in] Dest pointer to destination file name
53 @param[out] Resp pointer to response from question. Pass back on looped calling
54 @param[in] SilentMode whether to run in quiet mode or not
56 @retval SHELL_SUCCESS The source file was copied to the destination
61 IN CONST CHAR16
*Source
,
62 IN CONST CHAR16
*Dest
,
69 SHELL_FILE_HANDLE SourceHandle
;
70 SHELL_FILE_HANDLE DestHandle
;
75 EFI_SHELL_FILE_INFO
*List
;
76 SHELL_STATUS ShellStatus
;
77 UINT64 SourceFileSize
;
79 EFI_FILE_PROTOCOL
*DestVolumeFP
;
80 EFI_FILE_SYSTEM_INFO
*DestVolumeInfo
;
81 UINTN DestVolumeInfoSize
;
89 DestVolumeInfo
= NULL
;
91 ReadSize
= PcdGet16(PcdShellFileOperationSize
);
92 // Why bother copying a file to itself
93 if (StrCmp(Source
, Dest
) == 0) {
94 return (SHELL_SUCCESS
);
98 // Open destination file without create
100 Status
= ShellOpenFileByName(Dest
, &DestHandle
, EFI_FILE_MODE_READ
|EFI_FILE_MODE_WRITE
, 0);
105 if (DestHandle
!= NULL
) {
106 ShellCloseFile(&DestHandle
);
111 // if the destination file existed check response and possibly prompt user
113 if (!EFI_ERROR(Status
)) {
114 if (Response
== NULL
&& !SilentMode
) {
115 Status
= ShellPromptForResponseHii(ShellPromptResponseTypeYesNoAllCancel
, STRING_TOKEN (STR_GEN_DEST_EXIST_OVR
), gShellLevel2HiiHandle
, &Response
);
118 // possibly return based on response
121 switch (*(SHELL_PROMPT_RESPONSE
*)Response
) {
122 case ShellPromptResponseNo
:
124 // return success here so we dont stop the process
126 return (SHELL_SUCCESS
);
127 case ShellPromptResponseCancel
:
130 // indicate to stop everything
132 return (SHELL_ABORTED
);
133 case ShellPromptResponseAll
:
135 case ShellPromptResponseYes
:
138 return SHELL_ABORTED
;
143 if (ShellIsDirectory(Source
) == EFI_SUCCESS
) {
144 Status
= ShellCreateDirectory(Dest
, &DestHandle
);
145 if (EFI_ERROR(Status
)) {
146 return (SHELL_ACCESS_DENIED
);
150 // Now copy all the files under the directory...
154 StrnCatGrow(&TempName
, &Size
, Source
, 0);
155 StrnCatGrow(&TempName
, &Size
, L
"\\*", 0);
156 if (TempName
!= NULL
) {
157 ShellOpenFileMetaArg((CHAR16
*)TempName
, EFI_FILE_MODE_READ
, &List
);
158 *TempName
= CHAR_NULL
;
159 StrnCatGrow(&TempName
, &Size
, Dest
, 0);
160 StrnCatGrow(&TempName
, &Size
, L
"\\", 0);
161 ShellStatus
= ValidateAndCopyFiles(List
, TempName
, SilentMode
, TRUE
, Resp
);
162 ShellCloseFileMetaArg(&List
);
163 SHELL_FREE_NON_NULL(TempName
);
168 // open file with create enabled
170 Status
= ShellOpenFileByName(Dest
, &DestHandle
, EFI_FILE_MODE_READ
|EFI_FILE_MODE_WRITE
|EFI_FILE_MODE_CREATE
, 0);
171 if (EFI_ERROR(Status
)) {
172 return (SHELL_ACCESS_DENIED
);
178 Status
= ShellOpenFileByName(Source
, &SourceHandle
, EFI_FILE_MODE_READ
, 0);
179 ASSERT_EFI_ERROR(Status
);
182 //get file size of source file and freespace available on destination volume
184 ShellGetFileSize(SourceHandle
, &SourceFileSize
);
185 ShellGetFileSize(DestHandle
, &DestFileSize
);
188 //if the destination file already exists then it will be replaced, meaning the sourcefile effectively needs less storage space
190 if(DestFileSize
< SourceFileSize
){
191 SourceFileSize
-= DestFileSize
;
197 //get the system volume info to check the free space
199 DestVolumeFP
= ConvertShellHandleToEfiFileProtocol(DestHandle
);
200 DestVolumeInfo
= NULL
;
201 DestVolumeInfoSize
= 0;
202 Status
= DestVolumeFP
->GetInfo(
204 &gEfiFileSystemInfoGuid
,
209 if (Status
== EFI_BUFFER_TOO_SMALL
) {
210 DestVolumeInfo
= AllocateZeroPool(DestVolumeInfoSize
);
211 Status
= DestVolumeFP
->GetInfo(
213 &gEfiFileSystemInfoGuid
,
220 //check if enough space available on destination drive to complete copy
222 if (DestVolumeInfo
->FreeSpace
< SourceFileSize
) {
224 //not enough space on destination directory to copy file
226 SHELL_FREE_NON_NULL(DestVolumeInfo
);
227 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_CPY_FAIL
), gShellLevel2HiiHandle
);
228 return(SHELL_VOLUME_FULL
);
231 // copy data between files
233 Buffer
= AllocateZeroPool(ReadSize
);
234 ASSERT(Buffer
!= NULL
);
235 while (ReadSize
== PcdGet16(PcdShellFileOperationSize
) && !EFI_ERROR(Status
)) {
236 Status
= ShellReadFile(SourceHandle
, &ReadSize
, Buffer
);
237 Status
= ShellWriteFile(DestHandle
, &ReadSize
, Buffer
);
240 SHELL_FREE_NON_NULL(DestVolumeInfo
);
246 if (DestHandle
!= NULL
) {
247 ShellCloseFile(&DestHandle
);
250 if (SourceHandle
!= NULL
) {
251 ShellCloseFile(&SourceHandle
);
258 return (SHELL_SUCCESS
);
262 function to take a list of files to copy and a destination location and do
263 the verification and copying of those files to that location. This function
264 will report any errors to the user and halt.
266 The key is to have this function called ONLY once. this allows for the parameter
267 verification to happen correctly.
269 @param[in] FileList A LIST_ENTRY* based list of files to move.
270 @param[in] DestDir The destination location.
271 @param[in] SilentMode TRUE to eliminate screen output.
272 @param[in] RecursiveMode TRUE to copy directories.
273 @param[in] Resp The response to the overwrite query (if always).
275 @retval SHELL_SUCCESS the files were all moved.
276 @retval SHELL_INVALID_PARAMETER a parameter was invalid
277 @retval SHELL_SECURITY_VIOLATION a security violation ocurred
278 @retval SHELL_WRITE_PROTECTED the destination was write protected
279 @retval SHELL_OUT_OF_RESOURCES a memory allocation failed
283 ValidateAndCopyFiles(
284 IN CONST EFI_SHELL_FILE_INFO
*FileList
,
285 IN CONST CHAR16
*DestDir
,
286 IN BOOLEAN SilentMode
,
287 IN BOOLEAN RecursiveMode
,
293 CONST EFI_SHELL_FILE_INFO
*Node
;
294 SHELL_STATUS ShellStatus
;
299 CONST CHAR16
*TempLocation
;
309 ShellStatus
= SHELL_SUCCESS
;
311 Cwd
= ShellGetCurrentDir(NULL
);
313 ASSERT(FileList
!= NULL
);
314 ASSERT(DestDir
!= NULL
);
317 // We already verified that this was present.
322 // If we are trying to copy multiple files... make sure we got a directory for the target...
324 if (EFI_ERROR(ShellIsDirectory(DestDir
)) && FileList
->Link
.ForwardLink
!= FileList
->Link
.BackLink
) {
326 // Error for destination not a directory
328 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NOT_DIR
), gShellLevel2HiiHandle
, DestDir
);
329 return (SHELL_INVALID_PARAMETER
);
331 for (Node
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&FileList
->Link
)
332 ; !IsNull(&FileList
->Link
, &Node
->Link
)
333 ; Node
= (EFI_SHELL_FILE_INFO
*)GetNextNode(&FileList
->Link
, &Node
->Link
)
336 // skip the directory traversing stuff...
338 if (StrCmp(Node
->FileName
, L
".") == 0 || StrCmp(Node
->FileName
, L
"..") == 0) {
342 NewSize
= StrSize(DestDir
);
343 NewSize
+= StrSize(Node
->FullName
);
344 NewSize
+= StrSize(Cwd
);
345 if (NewSize
> PathLen
) {
350 // Make sure got -r if required
352 if (!RecursiveMode
&& !EFI_ERROR(ShellIsDirectory(Node
->FullName
))) {
353 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CP_DIR_REQ
), gShellLevel2HiiHandle
);
354 return (SHELL_INVALID_PARAMETER
);
358 // make sure got dest as dir if needed
360 if (!EFI_ERROR(ShellIsDirectory(Node
->FullName
)) && EFI_ERROR(ShellIsDirectory(DestDir
))) {
362 // Error for destination not a directory
364 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NOT_DIR
), gShellLevel2HiiHandle
, DestDir
);
365 return (SHELL_INVALID_PARAMETER
);
369 HiiOutput
= HiiGetString (gShellLevel2HiiHandle
, STRING_TOKEN (STR_CP_OUTPUT
), NULL
);
370 HiiResultOk
= HiiGetString (gShellLevel2HiiHandle
, STRING_TOKEN (STR_GEN_RES_OK
), NULL
);
371 DestPath
= AllocateZeroPool(PathLen
);
373 if (DestPath
== NULL
|| HiiOutput
== NULL
|| HiiResultOk
== NULL
) {
374 SHELL_FREE_NON_NULL(DestPath
);
375 SHELL_FREE_NON_NULL(HiiOutput
);
376 SHELL_FREE_NON_NULL(HiiResultOk
);
377 return (SHELL_OUT_OF_RESOURCES
);
381 // Go through the list of files to copy...
383 for (Node
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&FileList
->Link
)
384 ; !IsNull(&FileList
->Link
, &Node
->Link
)
385 ; Node
= (EFI_SHELL_FILE_INFO
*)GetNextNode(&FileList
->Link
, &Node
->Link
)
387 if (ShellGetExecutionBreakFlag()) {
390 ASSERT(Node
->FileName
!= NULL
);
391 ASSERT(Node
->FullName
!= NULL
);
394 // skip the directory traversing stuff...
396 if (StrCmp(Node
->FileName
, L
".") == 0 || StrCmp(Node
->FileName
, L
"..") == 0) {
400 if (FileList
->Link
.ForwardLink
== FileList
->Link
.BackLink
// 1 item
401 && EFI_ERROR(ShellIsDirectory(DestDir
)) // not an existing directory
403 if (StrStr(DestDir
, L
":") == NULL
) {
405 // simple copy of a single file
407 StrCpy(DestPath
, Cwd
);
408 if (DestPath
[StrLen(DestPath
)-1] != L
'\\' && DestDir
[0] != L
'\\') {
409 StrCat(DestPath
, L
"\\");
410 } else if (DestPath
[StrLen(DestPath
)-1] == L
'\\' && DestDir
[0] == L
'\\') {
411 ((CHAR16
*)DestPath
)[StrLen(DestPath
)-1] = CHAR_NULL
;
413 StrCat(DestPath
, DestDir
);
415 StrCpy(DestPath
, DestDir
);
419 // we have multiple files or a directory in the DestDir
423 // Check for leading slash
425 if (DestDir
[0] == L
'\\') {
427 // Copy to the root of CWD
429 StrCpy(DestPath
, Cwd
);
430 while (PathRemoveLastItem(DestPath
));
431 StrCat(DestPath
, DestDir
+1);
432 StrCat(DestPath
, Node
->FileName
);
433 } else if (StrStr(DestDir
, L
":") == NULL
) {
434 StrCpy(DestPath
, Cwd
);
435 if (DestPath
[StrLen(DestPath
)-1] != L
'\\' && DestDir
[0] != L
'\\') {
436 StrCat(DestPath
, L
"\\");
437 } else if (DestPath
[StrLen(DestPath
)-1] == L
'\\' && DestDir
[0] == L
'\\') {
438 ((CHAR16
*)DestPath
)[StrLen(DestPath
)-1] = CHAR_NULL
;
440 StrCat(DestPath
, DestDir
);
441 if (DestDir
[StrLen(DestDir
)-1] != L
'\\' && Node
->FileName
[0] != L
'\\') {
442 StrCat(DestPath
, L
"\\");
443 } else if (DestDir
[StrLen(DestDir
)-1] == L
'\\' && Node
->FileName
[0] == L
'\\') {
444 ((CHAR16
*)DestPath
)[StrLen(DestPath
)-1] = CHAR_NULL
;
446 StrCat(DestPath
, Node
->FileName
);
449 StrCpy(DestPath
, DestDir
);
450 if (DestDir
[StrLen(DestDir
)-1] != L
'\\' && Node
->FileName
[0] != L
'\\') {
451 StrCat(DestPath
, L
"\\");
452 } else if (DestDir
[StrLen(DestDir
)-1] == L
'\\' && Node
->FileName
[0] == L
'\\') {
453 ((CHAR16
*)DestDir
)[StrLen(DestDir
)-1] = CHAR_NULL
;
455 StrCat(DestPath
, Node
->FileName
);
460 // Make sure the path exists
462 if (EFI_ERROR(VerifyIntermediateDirectories(DestPath
))) {
463 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CP_DIR_WNF
), gShellLevel2HiiHandle
);
464 ShellStatus
= SHELL_DEVICE_ERROR
;
468 if ( !EFI_ERROR(ShellIsDirectory(Node
->FullName
))
469 && !EFI_ERROR(ShellIsDirectory(DestPath
))
470 && StrniCmp(Node
->FullName
, DestPath
, StrLen(DestPath
)) == NULL
472 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CP_SD_PARENT
), gShellLevel2HiiHandle
);
473 ShellStatus
= SHELL_INVALID_PARAMETER
;
476 if (StringNoCaseCompare(&Node
->FullName
, &DestPath
) == 0) {
477 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CP_SD_SAME
), gShellLevel2HiiHandle
);
478 ShellStatus
= SHELL_INVALID_PARAMETER
;
482 if ((TempLocation
= StrniCmp(Node
->FullName
, DestPath
, StrLen(Node
->FullName
))) == 0
483 && (DestPath
[StrLen(Node
->FullName
)] == CHAR_NULL
|| DestPath
[StrLen(Node
->FullName
)] == L
'\\')
485 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CP_SD_SAME
), gShellLevel2HiiHandle
);
486 ShellStatus
= SHELL_INVALID_PARAMETER
;
490 PathCleanUpDirectories(DestPath
);
492 ShellPrintEx(-1, -1, HiiOutput
, Node
->FullName
, DestPath
);
495 // copy single file...
497 ShellStatus
= CopySingleFile(Node
->FullName
, DestPath
, &Response
, SilentMode
);
498 if (ShellStatus
!= SHELL_SUCCESS
) {
502 if (ShellStatus
== SHELL_SUCCESS
&& Resp
== NULL
) {
503 ShellPrintEx(-1, -1, L
"%s", HiiResultOk
);
506 SHELL_FREE_NON_NULL(DestPath
);
507 SHELL_FREE_NON_NULL(HiiOutput
);
508 SHELL_FREE_NON_NULL(HiiResultOk
);
510 SHELL_FREE_NON_NULL(Response
);
513 return (ShellStatus
);
518 Validate and if successful copy all the files from the list into
519 destination directory.
521 @param[in] FileList The list of files to copy.
522 @param[in] DestDir The directory to copy files to.
523 @param[in] SilentMode TRUE to eliminate screen output.
524 @param[in] RecursiveMode TRUE to copy directories.
526 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
527 @retval SHELL_SUCCESS The operation was successful.
531 ProcessValidateAndCopyFiles(
532 IN EFI_SHELL_FILE_INFO
*FileList
,
533 IN CONST CHAR16
*DestDir
,
534 IN BOOLEAN SilentMode
,
535 IN BOOLEAN RecursiveMode
538 SHELL_STATUS ShellStatus
;
539 EFI_SHELL_FILE_INFO
*List
;
541 EFI_FILE_INFO
*FileInfo
;
545 Status
= ShellOpenFileMetaArg((CHAR16
*)DestDir
, EFI_FILE_MODE_READ
, &List
);
546 if (List
!= NULL
&& List
->Link
.ForwardLink
!= List
->Link
.BackLink
) {
547 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_MARG_ERROR
), gShellLevel2HiiHandle
, DestDir
);
548 ShellStatus
= SHELL_INVALID_PARAMETER
;
549 ShellCloseFileMetaArg(&List
);
550 } else if (List
!= NULL
) {
551 ASSERT(((EFI_SHELL_FILE_INFO
*)List
->Link
.ForwardLink
) != NULL
);
552 ASSERT(((EFI_SHELL_FILE_INFO
*)List
->Link
.ForwardLink
)->FullName
!= NULL
);
554 FileInfo
= gEfiShellProtocol
->GetFileInfo(((EFI_SHELL_FILE_INFO
*)List
->Link
.ForwardLink
)->Handle
);
555 ASSERT(FileInfo
!= NULL
);
556 if ((FileInfo
->Attribute
& EFI_FILE_READ_ONLY
) == 0) {
557 ShellStatus
= ValidateAndCopyFiles(FileList
, ((EFI_SHELL_FILE_INFO
*)List
->Link
.ForwardLink
)->FullName
, SilentMode
, RecursiveMode
, NULL
);
559 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_CP_DEST_ERROR
), gShellLevel2HiiHandle
);
560 ShellStatus
= SHELL_ACCESS_DENIED
;
562 SHELL_FREE_NON_NULL(FileInfo
);
563 ShellCloseFileMetaArg(&List
);
565 ShellStatus
= ValidateAndCopyFiles(FileList
, DestDir
, SilentMode
, RecursiveMode
, NULL
);
568 return (ShellStatus
);
571 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
578 Function for 'cp' command.
580 @param[in] ImageHandle Handle to the Image (NULL if Internal).
581 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
586 IN EFI_HANDLE ImageHandle
,
587 IN EFI_SYSTEM_TABLE
*SystemTable
592 CHAR16
*ProblemParam
;
593 SHELL_STATUS ShellStatus
;
596 EFI_SHELL_FILE_INFO
*FileList
;
598 BOOLEAN RecursiveMode
;
602 ShellStatus
= SHELL_SUCCESS
;
607 // initialize the shell lib (we must be in non-auto-init...)
609 Status
= ShellInitialize();
610 ASSERT_EFI_ERROR(Status
);
612 Status
= CommandInit();
613 ASSERT_EFI_ERROR(Status
);
616 // parse the command line
618 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
619 if (EFI_ERROR(Status
)) {
620 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
621 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellLevel2HiiHandle
, ProblemParam
);
622 FreePool(ProblemParam
);
623 ShellStatus
= SHELL_INVALID_PARAMETER
;
631 if (ShellCommandLineGetFlag(Package
, L
"-?")) {
636 // Initialize SilentMode and RecursiveMode
638 if (gEfiShellProtocol
->BatchIsActive()) {
641 SilentMode
= ShellCommandLineGetFlag(Package
, L
"-q");
643 RecursiveMode
= ShellCommandLineGetFlag(Package
, L
"-r");
645 switch (ParamCount
= ShellCommandLineGetCount(Package
)) {
649 // we have insufficient parameters
651 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellLevel2HiiHandle
);
652 ShellStatus
= SHELL_INVALID_PARAMETER
;
656 // must have valid CWD for single parameter...
658 Cwd
= ShellGetCurrentDir(NULL
);
660 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_CWD
), gShellLevel2HiiHandle
);
661 ShellStatus
= SHELL_INVALID_PARAMETER
;
663 Status
= ShellOpenFileMetaArg((CHAR16
*)ShellCommandLineGetRawValue(Package
, 1), EFI_FILE_MODE_WRITE
|EFI_FILE_MODE_READ
, &FileList
);
664 if (FileList
== NULL
|| IsListEmpty(&FileList
->Link
) || EFI_ERROR(Status
)) {
665 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_NF
), gShellLevel2HiiHandle
, ShellCommandLineGetRawValue(Package
, 1));
666 ShellStatus
= SHELL_NOT_FOUND
;
668 ShellStatus
= ProcessValidateAndCopyFiles(FileList
, Cwd
, SilentMode
, RecursiveMode
);
675 // Make a big list of all the files...
677 for (ParamCount
--, LoopCounter
= 1 ; LoopCounter
< ParamCount
&& ShellStatus
== SHELL_SUCCESS
; LoopCounter
++) {
678 if (ShellGetExecutionBreakFlag()) {
681 Status
= ShellOpenFileMetaArg((CHAR16
*)ShellCommandLineGetRawValue(Package
, LoopCounter
), EFI_FILE_MODE_WRITE
|EFI_FILE_MODE_READ
, &FileList
);
682 if (EFI_ERROR(Status
) || FileList
== NULL
|| IsListEmpty(&FileList
->Link
)) {
683 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_NF
), gShellLevel2HiiHandle
, ShellCommandLineGetRawValue(Package
, LoopCounter
));
684 ShellStatus
= SHELL_NOT_FOUND
;
687 if (ShellStatus
!= SHELL_SUCCESS
) {
688 Status
= ShellCloseFileMetaArg(&FileList
);
691 // now copy them all...
693 if (FileList
!= NULL
&& !IsListEmpty(&FileList
->Link
)) {
694 ShellStatus
= ProcessValidateAndCopyFiles(FileList
, PathCleanUpDirectories((CHAR16
*)ShellCommandLineGetRawValue(Package
, ParamCount
)), SilentMode
, RecursiveMode
);
695 Status
= ShellCloseFileMetaArg(&FileList
);
696 if (EFI_ERROR(Status
) && ShellStatus
== SHELL_SUCCESS
) {
697 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_ERR_FILE
), gShellLevel2HiiHandle
, ShellCommandLineGetRawValue(Package
, ParamCount
), ShellStatus
|MAX_BIT
);
698 ShellStatus
= SHELL_ACCESS_DENIED
;
703 } // switch on parameter count
705 if (FileList
!= NULL
) {
706 ShellCloseFileMetaArg(&FileList
);
710 // free the command line package
712 ShellCommandLineFreeVarList (Package
);
715 if (ShellGetExecutionBreakFlag()) {
716 return (SHELL_ABORTED
);
719 return (ShellStatus
);