Cp.c revision 427d61ad4ad1462b5f4370a78eb58c1ba73680b4
1a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey/** @file 2a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey Main file for cp shell level 2 function. 3a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 47282b505c5da686b95f6b2277bbd25a620d263edJaben Carsey Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR> 5a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey This program and the accompanying materials 6a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey are licensed and made available under the terms and conditions of the BSD License 7a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey which accompanies this distribution. The full text of the license may be found at 8a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey http://opensource.org/licenses/bsd-license.php 9a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 10a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 13a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey**/ 14a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 15a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey#include "UefiShellLevel2CommandsLib.h" 16f06be00e7aea1dc89c63728d20247a85f1511139jcarsey#include <Guid/FileSystemInfo.h> 17f06be00e7aea1dc89c63728d20247a85f1511139jcarsey#include <Guid/FileSystemVolumeLabelInfo.h> 18a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 19b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey/** 20b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey Function to take a list of files to copy and a destination location and do 21b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey the verification and copying of those files to that location. This function 22b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey will report any errors to the user and halt. 23b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey 24b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] FileList A LIST_ENTRY* based list of files to move. 25b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] DestDir The destination location. 26b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] SilentMode TRUE to eliminate screen output. 27b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] RecursiveMode TRUE to copy directories. 28b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] Resp The response to the overwrite query (if always). 29b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey 30b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @retval SHELL_SUCCESS the files were all moved. 31b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @retval SHELL_INVALID_PARAMETER a parameter was invalid 32b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @retval SHELL_SECURITY_VIOLATION a security violation ocurred 33b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @retval SHELL_WRITE_PROTECTED the destination was write protected 34b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @retval SHELL_OUT_OF_RESOURCES a memory allocation failed 35b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey**/ 36a405b86d274d32b92f69842bfb9a1ab143128f57jcarseySHELL_STATUS 37a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyEFIAPI 38a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyValidateAndCopyFiles( 39a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN CONST EFI_SHELL_FILE_INFO *FileList, 40a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN CONST CHAR16 *DestDir, 41a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN BOOLEAN SilentMode, 42a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN BOOLEAN RecursiveMode, 43a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN VOID **Resp 44a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ); 45a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 46a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey/** 47a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey Function to Copy one file to another location 48a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 49a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey If the destination exists the user will be prompted and the result put into *resp 50a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 51a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey @param[in] Source pointer to source file name 52a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey @param[in] Dest pointer to destination file name 53a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey @param[out] Resp pointer to response from question. Pass back on looped calling 54a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey @param[in] SilentMode whether to run in quiet mode or not 55a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 56a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey @retval SHELL_SUCCESS The source file was copied to the destination 57a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey**/ 58a405b86d274d32b92f69842bfb9a1ab143128f57jcarseySHELL_STATUS 59a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyEFIAPI 60a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyCopySingleFile( 61a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN CONST CHAR16 *Source, 62a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN CONST CHAR16 *Dest, 63a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey OUT VOID **Resp, 64a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN BOOLEAN SilentMode 65a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ) 66a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey{ 67f06be00e7aea1dc89c63728d20247a85f1511139jcarsey VOID *Response; 68f06be00e7aea1dc89c63728d20247a85f1511139jcarsey UINTN ReadSize; 69f06be00e7aea1dc89c63728d20247a85f1511139jcarsey SHELL_FILE_HANDLE SourceHandle; 70f06be00e7aea1dc89c63728d20247a85f1511139jcarsey SHELL_FILE_HANDLE DestHandle; 71f06be00e7aea1dc89c63728d20247a85f1511139jcarsey EFI_STATUS Status; 72f06be00e7aea1dc89c63728d20247a85f1511139jcarsey VOID *Buffer; 73f06be00e7aea1dc89c63728d20247a85f1511139jcarsey CHAR16 *TempName; 74f06be00e7aea1dc89c63728d20247a85f1511139jcarsey UINTN Size; 75f06be00e7aea1dc89c63728d20247a85f1511139jcarsey EFI_SHELL_FILE_INFO *List; 76f06be00e7aea1dc89c63728d20247a85f1511139jcarsey SHELL_STATUS ShellStatus; 77f06be00e7aea1dc89c63728d20247a85f1511139jcarsey UINT64 SourceFileSize; 78f06be00e7aea1dc89c63728d20247a85f1511139jcarsey UINT64 DestFileSize; 79f06be00e7aea1dc89c63728d20247a85f1511139jcarsey EFI_FILE_PROTOCOL *DestVolumeFP; 80f06be00e7aea1dc89c63728d20247a85f1511139jcarsey EFI_FILE_SYSTEM_INFO *DestVolumeInfo; 81f06be00e7aea1dc89c63728d20247a85f1511139jcarsey UINTN DestVolumeInfoSize; 82a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 83a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ASSERT(Resp != NULL); 84a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 85f06be00e7aea1dc89c63728d20247a85f1511139jcarsey SourceHandle = NULL; 86f06be00e7aea1dc89c63728d20247a85f1511139jcarsey DestHandle = NULL; 87f06be00e7aea1dc89c63728d20247a85f1511139jcarsey Response = *Resp; 88f06be00e7aea1dc89c63728d20247a85f1511139jcarsey List = NULL; 89f06be00e7aea1dc89c63728d20247a85f1511139jcarsey DestVolumeInfo = NULL; 90e755a4ca10aad316c3620223206d63982793b26cjcarsey ShellStatus = SHELL_SUCCESS; 91a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 92433a21cba1a6a825b9ec07f580164b84e5d41d3aEugene Cohen ReadSize = PcdGet32(PcdShellFileOperationSize); 93a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // Why bother copying a file to itself 94a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (StrCmp(Source, Dest) == 0) { 95a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey return (SHELL_SUCCESS); 96a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 97a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 98a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 99a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // if the destination file existed check response and possibly prompt user 100a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 101ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey if (ShellFileExists(Dest) == EFI_SUCCESS) { 102a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (Response == NULL && !SilentMode) { 103b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey Status = ShellPromptForResponseHii(ShellPromptResponseTypeYesNoAllCancel, STRING_TOKEN (STR_GEN_DEST_EXIST_OVR), gShellLevel2HiiHandle, &Response); 104a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 105a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 106a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // possibly return based on response 107a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 108a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (!SilentMode) { 109a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey switch (*(SHELL_PROMPT_RESPONSE*)Response) { 110a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey case ShellPromptResponseNo: 111a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 112a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // return success here so we dont stop the process 113a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 114a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey return (SHELL_SUCCESS); 115a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey case ShellPromptResponseCancel: 116a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey *Resp = Response; 117a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 118a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // indicate to stop everything 119a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 120a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey return (SHELL_ABORTED); 121a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey case ShellPromptResponseAll: 122a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey *Resp = Response; 123a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey case ShellPromptResponseYes: 124a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey break; 125e97233217ed6d37d7bb7fefb0ff0821515a23b48jljusten default: 126e97233217ed6d37d7bb7fefb0ff0821515a23b48jljusten return SHELL_ABORTED; 127a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 128a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 129a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 130a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 131a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (ShellIsDirectory(Source) == EFI_SUCCESS) { 132a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey Status = ShellCreateDirectory(Dest, &DestHandle); 133a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (EFI_ERROR(Status)) { 1347282b505c5da686b95f6b2277bbd25a620d263edJaben Carsey ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_DEST_DIR_FAIL), gShellLevel2HiiHandle, Dest); 135a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey return (SHELL_ACCESS_DENIED); 136a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 137a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 138a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 139a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // Now copy all the files under the directory... 140a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 141a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey TempName = NULL; 142f06be00e7aea1dc89c63728d20247a85f1511139jcarsey Size = 0; 143a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey StrnCatGrow(&TempName, &Size, Source, 0); 144a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey StrnCatGrow(&TempName, &Size, L"\\*", 0); 1457dd0562309ac668b7025023f05e79687fdf7a13ajcarsey if (TempName != NULL) { 1467dd0562309ac668b7025023f05e79687fdf7a13ajcarsey ShellOpenFileMetaArg((CHAR16*)TempName, EFI_FILE_MODE_READ, &List); 1477dd0562309ac668b7025023f05e79687fdf7a13ajcarsey *TempName = CHAR_NULL; 1487dd0562309ac668b7025023f05e79687fdf7a13ajcarsey StrnCatGrow(&TempName, &Size, Dest, 0); 1497dd0562309ac668b7025023f05e79687fdf7a13ajcarsey StrnCatGrow(&TempName, &Size, L"\\", 0); 1507dd0562309ac668b7025023f05e79687fdf7a13ajcarsey ShellStatus = ValidateAndCopyFiles(List, TempName, SilentMode, TRUE, Resp); 1517dd0562309ac668b7025023f05e79687fdf7a13ajcarsey ShellCloseFileMetaArg(&List); 1527dd0562309ac668b7025023f05e79687fdf7a13ajcarsey SHELL_FREE_NON_NULL(TempName); 1537dd0562309ac668b7025023f05e79687fdf7a13ajcarsey Size = 0; 1547dd0562309ac668b7025023f05e79687fdf7a13ajcarsey } 155a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } else { 156ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey Status = ShellDeleteFileByName(Dest); 157a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 158ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 159ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // open file with create enabled 160ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 161ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey Status = ShellOpenFileByName(Dest, &DestHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0); 162ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey if (EFI_ERROR(Status)) { 1637282b505c5da686b95f6b2277bbd25a620d263edJaben Carsey ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_DEST_OPEN_FAIL), gShellLevel2HiiHandle, Dest); 164ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey return (SHELL_ACCESS_DENIED); 165ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey } 166f06be00e7aea1dc89c63728d20247a85f1511139jcarsey 167ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 168ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // open source file 169ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 170ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey Status = ShellOpenFileByName(Source, &SourceHandle, EFI_FILE_MODE_READ, 0); 171ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey ASSERT_EFI_ERROR(Status); 172f06be00e7aea1dc89c63728d20247a85f1511139jcarsey 173ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 174ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey //get file size of source file and freespace available on destination volume 175ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 176ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey ShellGetFileSize(SourceHandle, &SourceFileSize); 177ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey ShellGetFileSize(DestHandle, &DestFileSize); 178f06be00e7aea1dc89c63728d20247a85f1511139jcarsey 179ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 180ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey //if the destination file already exists then it will be replaced, meaning the sourcefile effectively needs less storage space 181ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 182ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey if(DestFileSize < SourceFileSize){ 183ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey SourceFileSize -= DestFileSize; 184ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey } else { 185ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey SourceFileSize = 0; 186ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey } 187ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey 188ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 189ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey //get the system volume info to check the free space 190ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 191ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey DestVolumeFP = ConvertShellHandleToEfiFileProtocol(DestHandle); 192ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey DestVolumeInfo = NULL; 193ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey DestVolumeInfoSize = 0; 194ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey Status = DestVolumeFP->GetInfo( 195ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey DestVolumeFP, 196ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey &gEfiFileSystemInfoGuid, 197ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey &DestVolumeInfoSize, 198ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey DestVolumeInfo 199ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey ); 200ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey 201ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey if (Status == EFI_BUFFER_TOO_SMALL) { 202ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey DestVolumeInfo = AllocateZeroPool(DestVolumeInfoSize); 203f06be00e7aea1dc89c63728d20247a85f1511139jcarsey Status = DestVolumeFP->GetInfo( 204f06be00e7aea1dc89c63728d20247a85f1511139jcarsey DestVolumeFP, 205f06be00e7aea1dc89c63728d20247a85f1511139jcarsey &gEfiFileSystemInfoGuid, 206f06be00e7aea1dc89c63728d20247a85f1511139jcarsey &DestVolumeInfoSize, 207f06be00e7aea1dc89c63728d20247a85f1511139jcarsey DestVolumeInfo 208f06be00e7aea1dc89c63728d20247a85f1511139jcarsey ); 209ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey } 210f06be00e7aea1dc89c63728d20247a85f1511139jcarsey 211ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 212ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey //check if enough space available on destination drive to complete copy 213ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 214ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey if (DestVolumeInfo!= NULL && (DestVolumeInfo->FreeSpace < SourceFileSize)) { 215f06be00e7aea1dc89c63728d20247a85f1511139jcarsey // 216ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey //not enough space on destination directory to copy file 217f06be00e7aea1dc89c63728d20247a85f1511139jcarsey // 218f06be00e7aea1dc89c63728d20247a85f1511139jcarsey SHELL_FREE_NON_NULL(DestVolumeInfo); 219ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_CPY_FAIL), gShellLevel2HiiHandle); 220ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey return(SHELL_VOLUME_FULL); 221ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey } else { 222ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 223ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // copy data between files 224ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 225ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey Buffer = AllocateZeroPool(ReadSize); 226ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey ASSERT(Buffer != NULL); 227ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey while (ReadSize == PcdGet32(PcdShellFileOperationSize) && !EFI_ERROR(Status)) { 228ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey Status = ShellReadFile(SourceHandle, &ReadSize, Buffer); 229f3a14a0f575e7e856ff4d90d7d0ab73f7e02ae41Shumin Qiu if (!EFI_ERROR(Status)) { 230f3a14a0f575e7e856ff4d90d7d0ab73f7e02ae41Shumin Qiu Status = ShellWriteFile(DestHandle, &ReadSize, Buffer); 231f3a14a0f575e7e856ff4d90d7d0ab73f7e02ae41Shumin Qiu if (EFI_ERROR(Status)) { 232f3a14a0f575e7e856ff4d90d7d0ab73f7e02ae41Shumin Qiu ShellStatus = (SHELL_STATUS) (Status & (~MAX_BIT)); 233f3a14a0f575e7e856ff4d90d7d0ab73f7e02ae41Shumin Qiu ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_CPY_WRITE_ERROR), gShellLevel2HiiHandle, Dest); 234f3a14a0f575e7e856ff4d90d7d0ab73f7e02ae41Shumin Qiu break; 235f3a14a0f575e7e856ff4d90d7d0ab73f7e02ae41Shumin Qiu } 236f3a14a0f575e7e856ff4d90d7d0ab73f7e02ae41Shumin Qiu } else { 237f3a14a0f575e7e856ff4d90d7d0ab73f7e02ae41Shumin Qiu ShellStatus = (SHELL_STATUS) (Status & (~MAX_BIT)); 238f3a14a0f575e7e856ff4d90d7d0ab73f7e02ae41Shumin Qiu ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_CPY_READ_ERROR), gShellLevel2HiiHandle, Source); 239f3a14a0f575e7e856ff4d90d7d0ab73f7e02ae41Shumin Qiu break; 240f3a14a0f575e7e856ff4d90d7d0ab73f7e02ae41Shumin Qiu } 241ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey } 242a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 243ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey SHELL_FREE_NON_NULL(DestVolumeInfo); 244ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey } 245f3a14a0f575e7e856ff4d90d7d0ab73f7e02ae41Shumin Qiu 246a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 247a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // close files 248a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 249a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (DestHandle != NULL) { 250a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellCloseFile(&DestHandle); 251a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey DestHandle = NULL; 252a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 253a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (SourceHandle != NULL) { 254a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellCloseFile(&SourceHandle); 255a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey SourceHandle = NULL; 256a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 257a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 258a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 259a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // return 260a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 261e755a4ca10aad316c3620223206d63982793b26cjcarsey return ShellStatus; 262a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey} 263a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 264a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey/** 265a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey function to take a list of files to copy and a destination location and do 266a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey the verification and copying of those files to that location. This function 267a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey will report any errors to the user and halt. 268a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 269a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey The key is to have this function called ONLY once. this allows for the parameter 270a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey verification to happen correctly. 271a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 272b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] FileList A LIST_ENTRY* based list of files to move. 273b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] DestDir The destination location. 274b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] SilentMode TRUE to eliminate screen output. 275b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] RecursiveMode TRUE to copy directories. 276b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] Resp The response to the overwrite query (if always). 277a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 278a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey @retval SHELL_SUCCESS the files were all moved. 279a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey @retval SHELL_INVALID_PARAMETER a parameter was invalid 280a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey @retval SHELL_SECURITY_VIOLATION a security violation ocurred 281a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey @retval SHELL_WRITE_PROTECTED the destination was write protected 282a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey @retval SHELL_OUT_OF_RESOURCES a memory allocation failed 283a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey**/ 284a405b86d274d32b92f69842bfb9a1ab143128f57jcarseySHELL_STATUS 285a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyEFIAPI 286a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyValidateAndCopyFiles( 287a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN CONST EFI_SHELL_FILE_INFO *FileList, 288a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN CONST CHAR16 *DestDir, 289a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN BOOLEAN SilentMode, 290a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN BOOLEAN RecursiveMode, 291a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN VOID **Resp 292a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ) 293a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey{ 294a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey CHAR16 *HiiOutput; 295a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey CHAR16 *HiiResultOk; 296a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey CONST EFI_SHELL_FILE_INFO *Node; 297a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey SHELL_STATUS ShellStatus; 2980960ba17e596812f211ba334cc6699d45bada328Qiu Shumin EFI_STATUS Status; 299a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey CHAR16 *DestPath; 300a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey VOID *Response; 301e1044f8074836b74188a2371ba70be05d0e0482bJaben Carsey UINTN PathSize; 302a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey CONST CHAR16 *Cwd; 303a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey UINTN NewSize; 3040960ba17e596812f211ba334cc6699d45bada328Qiu Shumin CHAR16 *CleanFilePathStr; 305a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 306a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (Resp == NULL) { 307a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey Response = NULL; 308a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } else { 309a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey Response = *Resp; 310a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 311a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 312715096c2448412e54a95092942a397bd4d697524Qiu Shumin DestPath = NULL; 313715096c2448412e54a95092942a397bd4d697524Qiu Shumin ShellStatus = SHELL_SUCCESS; 314715096c2448412e54a95092942a397bd4d697524Qiu Shumin PathSize = 0; 315715096c2448412e54a95092942a397bd4d697524Qiu Shumin Cwd = ShellGetCurrentDir(NULL); 316715096c2448412e54a95092942a397bd4d697524Qiu Shumin CleanFilePathStr = NULL; 317a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 318a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ASSERT(FileList != NULL); 319a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ASSERT(DestDir != NULL); 320a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 3210960ba17e596812f211ba334cc6699d45bada328Qiu Shumin 3220960ba17e596812f211ba334cc6699d45bada328Qiu Shumin Status = ShellLevel2StripQuotes (DestDir, &CleanFilePathStr); 3230960ba17e596812f211ba334cc6699d45bada328Qiu Shumin if (EFI_ERROR (Status)) { 3240960ba17e596812f211ba334cc6699d45bada328Qiu Shumin if (Status == EFI_OUT_OF_RESOURCES) { 3250960ba17e596812f211ba334cc6699d45bada328Qiu Shumin return SHELL_OUT_OF_RESOURCES; 3260960ba17e596812f211ba334cc6699d45bada328Qiu Shumin } else { 3270960ba17e596812f211ba334cc6699d45bada328Qiu Shumin return SHELL_INVALID_PARAMETER; 3280960ba17e596812f211ba334cc6699d45bada328Qiu Shumin } 329427d61ad4ad1462b5f4370a78eb58c1ba73680b4Qiu Shumin } 330427d61ad4ad1462b5f4370a78eb58c1ba73680b4Qiu Shumin 331427d61ad4ad1462b5f4370a78eb58c1ba73680b4Qiu Shumin ASSERT (CleanFilePathStr != NULL); 3320960ba17e596812f211ba334cc6699d45bada328Qiu Shumin 333a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 334a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // If we are trying to copy multiple files... make sure we got a directory for the target... 335a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 3360960ba17e596812f211ba334cc6699d45bada328Qiu Shumin if (EFI_ERROR(ShellIsDirectory(CleanFilePathStr)) && FileList->Link.ForwardLink != FileList->Link.BackLink) { 337a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 338a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // Error for destination not a directory 339a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 3400960ba17e596812f211ba334cc6699d45bada328Qiu Shumin ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_DIR), gShellLevel2HiiHandle, CleanFilePathStr); 3410960ba17e596812f211ba334cc6699d45bada328Qiu Shumin FreePool (CleanFilePathStr); 342a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey return (SHELL_INVALID_PARAMETER); 343a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 344a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&FileList->Link) 345a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ; !IsNull(&FileList->Link, &Node->Link) 346a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&FileList->Link, &Node->Link) 347f06be00e7aea1dc89c63728d20247a85f1511139jcarsey ){ 348a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 349a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // skip the directory traversing stuff... 350a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 351a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (StrCmp(Node->FileName, L".") == 0 || StrCmp(Node->FileName, L"..") == 0) { 352a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey continue; 353a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 354a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 3550960ba17e596812f211ba334cc6699d45bada328Qiu Shumin NewSize = StrSize(CleanFilePathStr); 356b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey NewSize += StrSize(Node->FullName); 357ed053afece04120c1c62163475806d6aef3bc329Eric Dong NewSize += (Cwd == NULL)? 0 : StrSize(Cwd); 358e1044f8074836b74188a2371ba70be05d0e0482bJaben Carsey if (NewSize > PathSize) { 359e1044f8074836b74188a2371ba70be05d0e0482bJaben Carsey PathSize = NewSize; 360a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 361a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 362a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 363a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // Make sure got -r if required 364a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 365a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (!RecursiveMode && !EFI_ERROR(ShellIsDirectory(Node->FullName))) { 366a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_DIR_REQ), gShellLevel2HiiHandle); 3670960ba17e596812f211ba334cc6699d45bada328Qiu Shumin FreePool (CleanFilePathStr); 368a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey return (SHELL_INVALID_PARAMETER); 369a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 370a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 371a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 372a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // make sure got dest as dir if needed 373a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 3740960ba17e596812f211ba334cc6699d45bada328Qiu Shumin if (!EFI_ERROR(ShellIsDirectory(Node->FullName)) && EFI_ERROR(ShellIsDirectory(CleanFilePathStr))) { 375a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 376a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // Error for destination not a directory 377a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 3780960ba17e596812f211ba334cc6699d45bada328Qiu Shumin ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_DIR), gShellLevel2HiiHandle, CleanFilePathStr); 3790960ba17e596812f211ba334cc6699d45bada328Qiu Shumin FreePool (CleanFilePathStr); 380a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey return (SHELL_INVALID_PARAMETER); 381a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 382a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 383a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 384a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey HiiOutput = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_CP_OUTPUT), NULL); 385a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey HiiResultOk = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_GEN_RES_OK), NULL); 386e1044f8074836b74188a2371ba70be05d0e0482bJaben Carsey DestPath = AllocateZeroPool(PathSize); 387a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 3883e082d58262da4108a3f1f2ee8fa0a9441bb2a9bjcarsey if (DestPath == NULL || HiiOutput == NULL || HiiResultOk == NULL) { 3899ea69f8a05b808b4bab81b608436a02e2f2fba09jcarsey SHELL_FREE_NON_NULL(DestPath); 3909ea69f8a05b808b4bab81b608436a02e2f2fba09jcarsey SHELL_FREE_NON_NULL(HiiOutput); 3919ea69f8a05b808b4bab81b608436a02e2f2fba09jcarsey SHELL_FREE_NON_NULL(HiiResultOk); 3920960ba17e596812f211ba334cc6699d45bada328Qiu Shumin FreePool (CleanFilePathStr); 3939ea69f8a05b808b4bab81b608436a02e2f2fba09jcarsey return (SHELL_OUT_OF_RESOURCES); 3949ea69f8a05b808b4bab81b608436a02e2f2fba09jcarsey } 3959ea69f8a05b808b4bab81b608436a02e2f2fba09jcarsey 396a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 397a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // Go through the list of files to copy... 398a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 399a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&FileList->Link) 400a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ; !IsNull(&FileList->Link, &Node->Link) 401a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&FileList->Link, &Node->Link) 402f06be00e7aea1dc89c63728d20247a85f1511139jcarsey ){ 403a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (ShellGetExecutionBreakFlag()) { 404a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey break; 405a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 406a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ASSERT(Node->FileName != NULL); 407a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ASSERT(Node->FullName != NULL); 408a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 409a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 410a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // skip the directory traversing stuff... 411a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 412a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (StrCmp(Node->FileName, L".") == 0 || StrCmp(Node->FileName, L"..") == 0) { 413a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey continue; 414a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 415a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 416a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (FileList->Link.ForwardLink == FileList->Link.BackLink // 1 item 4170960ba17e596812f211ba334cc6699d45bada328Qiu Shumin && EFI_ERROR(ShellIsDirectory(CleanFilePathStr)) // not an existing directory 418f06be00e7aea1dc89c63728d20247a85f1511139jcarsey ) { 4190960ba17e596812f211ba334cc6699d45bada328Qiu Shumin if (StrStr(CleanFilePathStr, L":") == NULL) { 420b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey // 421b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey // simple copy of a single file 422b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey // 423ed053afece04120c1c62163475806d6aef3bc329Eric Dong if (Cwd != NULL) { 424e1044f8074836b74188a2371ba70be05d0e0482bJaben Carsey StrnCpy(DestPath, Cwd, PathSize/sizeof(CHAR16)-1); 425ed053afece04120c1c62163475806d6aef3bc329Eric Dong } else { 4260960ba17e596812f211ba334cc6699d45bada328Qiu Shumin ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, CleanFilePathStr); 4270960ba17e596812f211ba334cc6699d45bada328Qiu Shumin FreePool (CleanFilePathStr); 428ed053afece04120c1c62163475806d6aef3bc329Eric Dong return (SHELL_INVALID_PARAMETER); 429ed053afece04120c1c62163475806d6aef3bc329Eric Dong } 4300960ba17e596812f211ba334cc6699d45bada328Qiu Shumin if (DestPath[StrLen(DestPath)-1] != L'\\' && CleanFilePathStr[0] != L'\\') { 431e1044f8074836b74188a2371ba70be05d0e0482bJaben Carsey StrnCat(DestPath, L"\\", PathSize/sizeof(CHAR16) - StrLen(DestPath) -1); 4320960ba17e596812f211ba334cc6699d45bada328Qiu Shumin } else if (DestPath[StrLen(DestPath)-1] == L'\\' && CleanFilePathStr[0] == L'\\') { 433b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey ((CHAR16*)DestPath)[StrLen(DestPath)-1] = CHAR_NULL; 434b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey } 4350960ba17e596812f211ba334cc6699d45bada328Qiu Shumin StrnCat(DestPath, CleanFilePathStr, PathSize/sizeof(CHAR16) - StrLen(DestPath) -1); 436b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey } else { 4370960ba17e596812f211ba334cc6699d45bada328Qiu Shumin StrnCpy(DestPath, CleanFilePathStr, PathSize/sizeof(CHAR16) -1); 438a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 439a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } else { 440a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 441a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // we have multiple files or a directory in the DestDir 442a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 4431fc3749dad42e8d5caebf6e0e0327b713b6adaebjcarsey 4441fc3749dad42e8d5caebf6e0e0327b713b6adaebjcarsey // 4451fc3749dad42e8d5caebf6e0e0327b713b6adaebjcarsey // Check for leading slash 4461fc3749dad42e8d5caebf6e0e0327b713b6adaebjcarsey // 4470960ba17e596812f211ba334cc6699d45bada328Qiu Shumin if (CleanFilePathStr[0] == L'\\') { 448ed053afece04120c1c62163475806d6aef3bc329Eric Dong // 449ed053afece04120c1c62163475806d6aef3bc329Eric Dong // Copy to the root of CWD 450ed053afece04120c1c62163475806d6aef3bc329Eric Dong // 451ed053afece04120c1c62163475806d6aef3bc329Eric Dong if (Cwd != NULL) { 452e1044f8074836b74188a2371ba70be05d0e0482bJaben Carsey StrnCpy(DestPath, Cwd, PathSize/sizeof(CHAR16) -1); 453ed053afece04120c1c62163475806d6aef3bc329Eric Dong } else { 4540960ba17e596812f211ba334cc6699d45bada328Qiu Shumin ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, CleanFilePathStr); 4550960ba17e596812f211ba334cc6699d45bada328Qiu Shumin FreePool(CleanFilePathStr); 456ed053afece04120c1c62163475806d6aef3bc329Eric Dong return (SHELL_INVALID_PARAMETER); 457ed053afece04120c1c62163475806d6aef3bc329Eric Dong } 4581fc3749dad42e8d5caebf6e0e0327b713b6adaebjcarsey while (PathRemoveLastItem(DestPath)); 4590960ba17e596812f211ba334cc6699d45bada328Qiu Shumin StrnCat(DestPath, CleanFilePathStr+1, PathSize/sizeof(CHAR16) - StrLen(DestPath) -1); 460e1044f8074836b74188a2371ba70be05d0e0482bJaben Carsey StrnCat(DestPath, Node->FileName, PathSize/sizeof(CHAR16) - StrLen(DestPath) -1); 4610960ba17e596812f211ba334cc6699d45bada328Qiu Shumin } else if (StrStr(CleanFilePathStr, L":") == NULL) { 462ed053afece04120c1c62163475806d6aef3bc329Eric Dong if (Cwd != NULL) { 463e1044f8074836b74188a2371ba70be05d0e0482bJaben Carsey StrnCpy(DestPath, Cwd, PathSize/sizeof(CHAR16) -1); 464ed053afece04120c1c62163475806d6aef3bc329Eric Dong } else { 4650960ba17e596812f211ba334cc6699d45bada328Qiu Shumin ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, CleanFilePathStr); 4660960ba17e596812f211ba334cc6699d45bada328Qiu Shumin FreePool(CleanFilePathStr); 467ed053afece04120c1c62163475806d6aef3bc329Eric Dong return (SHELL_INVALID_PARAMETER); 468ed053afece04120c1c62163475806d6aef3bc329Eric Dong } 4690960ba17e596812f211ba334cc6699d45bada328Qiu Shumin if (DestPath[StrLen(DestPath)-1] != L'\\' && CleanFilePathStr[0] != L'\\') { 470e1044f8074836b74188a2371ba70be05d0e0482bJaben Carsey StrnCat(DestPath, L"\\", PathSize/sizeof(CHAR16) - StrLen(DestPath) -1); 4710960ba17e596812f211ba334cc6699d45bada328Qiu Shumin } else if (DestPath[StrLen(DestPath)-1] == L'\\' && CleanFilePathStr[0] == L'\\') { 472a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ((CHAR16*)DestPath)[StrLen(DestPath)-1] = CHAR_NULL; 473a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 4740960ba17e596812f211ba334cc6699d45bada328Qiu Shumin StrnCat(DestPath, CleanFilePathStr, PathSize/sizeof(CHAR16) - StrLen(DestPath) -1); 4750960ba17e596812f211ba334cc6699d45bada328Qiu Shumin if (CleanFilePathStr[StrLen(CleanFilePathStr)-1] != L'\\' && Node->FileName[0] != L'\\') { 476e1044f8074836b74188a2371ba70be05d0e0482bJaben Carsey StrnCat(DestPath, L"\\", PathSize/sizeof(CHAR16) - StrLen(DestPath) -1); 4770960ba17e596812f211ba334cc6699d45bada328Qiu Shumin } else if (CleanFilePathStr[StrLen(CleanFilePathStr)-1] == L'\\' && Node->FileName[0] == L'\\') { 478a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ((CHAR16*)DestPath)[StrLen(DestPath)-1] = CHAR_NULL; 479a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 480e1044f8074836b74188a2371ba70be05d0e0482bJaben Carsey StrnCat(DestPath, Node->FileName, PathSize/sizeof(CHAR16) - StrLen(DestPath) -1); 481a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 482a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } else { 4830960ba17e596812f211ba334cc6699d45bada328Qiu Shumin StrnCpy(DestPath, CleanFilePathStr, PathSize/sizeof(CHAR16) -1); 4840960ba17e596812f211ba334cc6699d45bada328Qiu Shumin if (CleanFilePathStr[StrLen(CleanFilePathStr)-1] != L'\\' && Node->FileName[0] != L'\\') { 485e1044f8074836b74188a2371ba70be05d0e0482bJaben Carsey StrnCat(DestPath, L"\\", PathSize/sizeof(CHAR16) - StrLen(DestPath) -1); 4860960ba17e596812f211ba334cc6699d45bada328Qiu Shumin } else if (CleanFilePathStr[StrLen(CleanFilePathStr)-1] == L'\\' && Node->FileName[0] == L'\\') { 4870960ba17e596812f211ba334cc6699d45bada328Qiu Shumin ((CHAR16*)CleanFilePathStr)[StrLen(CleanFilePathStr)-1] = CHAR_NULL; 488a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 489e1044f8074836b74188a2371ba70be05d0e0482bJaben Carsey StrnCat(DestPath, Node->FileName, PathSize/sizeof(CHAR16) - StrLen(DestPath) -1); 490a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 491a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 492a6e84d95f50a10e23ee9861270fb84057b5af2e9Ni Ruiyu 493a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 494a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // Make sure the path exists 495a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 496a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (EFI_ERROR(VerifyIntermediateDirectories(DestPath))) { 497a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_DIR_WNF), gShellLevel2HiiHandle); 498a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellStatus = SHELL_DEVICE_ERROR; 499a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey break; 500a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 501a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 502a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if ( !EFI_ERROR(ShellIsDirectory(Node->FullName)) 503a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey && !EFI_ERROR(ShellIsDirectory(DestPath)) 504a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey && StrniCmp(Node->FullName, DestPath, StrLen(DestPath)) == NULL 505f06be00e7aea1dc89c63728d20247a85f1511139jcarsey ){ 506a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_SD_PARENT), gShellLevel2HiiHandle); 507a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellStatus = SHELL_INVALID_PARAMETER; 508a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey break; 509a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 510a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (StringNoCaseCompare(&Node->FullName, &DestPath) == 0) { 511a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_SD_SAME), gShellLevel2HiiHandle); 512a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellStatus = SHELL_INVALID_PARAMETER; 513a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey break; 514a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 515a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 5165051c2873b78114da6349e1c7e0754233f6c0024Olivier Martin if ((StrniCmp(Node->FullName, DestPath, StrLen(Node->FullName)) == 0) 517a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey && (DestPath[StrLen(Node->FullName)] == CHAR_NULL || DestPath[StrLen(Node->FullName)] == L'\\') 518f06be00e7aea1dc89c63728d20247a85f1511139jcarsey ) { 519a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_SD_SAME), gShellLevel2HiiHandle); 520a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellStatus = SHELL_INVALID_PARAMETER; 521a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey break; 522a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 523a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 524ab94587a7d2cd89695f9190420daceae0d2b7446jcarsey PathCleanUpDirectories(DestPath); 525a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 526a737ea734b9d64d6b10e399d5d0a8539604decddJaben Carsey if (!SilentMode) { 527a737ea734b9d64d6b10e399d5d0a8539604decddJaben Carsey ShellPrintEx(-1, -1, HiiOutput, Node->FullName, DestPath); 528a737ea734b9d64d6b10e399d5d0a8539604decddJaben Carsey } 529a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 530a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 531a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // copy single file... 532a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 533a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellStatus = CopySingleFile(Node->FullName, DestPath, &Response, SilentMode); 534a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (ShellStatus != SHELL_SUCCESS) { 535a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey break; 536a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 537a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 538a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (ShellStatus == SHELL_SUCCESS && Resp == NULL) { 539a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellPrintEx(-1, -1, L"%s", HiiResultOk); 540a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 541a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 542a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey SHELL_FREE_NON_NULL(DestPath); 543a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey SHELL_FREE_NON_NULL(HiiOutput); 544a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey SHELL_FREE_NON_NULL(HiiResultOk); 545a6e84d95f50a10e23ee9861270fb84057b5af2e9Ni Ruiyu SHELL_FREE_NON_NULL(CleanFilePathStr); 546590c3cb14ad6547528ea13805817676e32c204aajcarsey if (Resp == NULL) { 547a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey SHELL_FREE_NON_NULL(Response); 548a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 549a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 550a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey return (ShellStatus); 551f06be00e7aea1dc89c63728d20247a85f1511139jcarsey 552a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey} 553a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 554b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey/** 555b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey Validate and if successful copy all the files from the list into 556b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey destination directory. 557b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey 558b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] FileList The list of files to copy. 559b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] DestDir The directory to copy files to. 560b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] SilentMode TRUE to eliminate screen output. 561b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] RecursiveMode TRUE to copy directories. 562b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey 563b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @retval SHELL_INVALID_PARAMETER A parameter was invalid. 564b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @retval SHELL_SUCCESS The operation was successful. 565b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey**/ 566a405b86d274d32b92f69842bfb9a1ab143128f57jcarseySHELL_STATUS 567a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyEFIAPI 568a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyProcessValidateAndCopyFiles( 569a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN EFI_SHELL_FILE_INFO *FileList, 570a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN CONST CHAR16 *DestDir, 571a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN BOOLEAN SilentMode, 572a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN BOOLEAN RecursiveMode 573a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ) 574a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey{ 575a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey SHELL_STATUS ShellStatus; 576a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey EFI_SHELL_FILE_INFO *List; 577a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey EFI_FILE_INFO *FileInfo; 578ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey CHAR16 *FullName; 579a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 580ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey List = NULL; 581ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey FullName = NULL; 5829f56625f2a904701f460c88a7dbfaf17c4c83a22Jaben Carsey FileInfo = NULL; 583a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 584e755a4ca10aad316c3620223206d63982793b26cjcarsey ShellOpenFileMetaArg((CHAR16*)DestDir, EFI_FILE_MODE_READ, &List); 585a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (List != NULL && List->Link.ForwardLink != List->Link.BackLink) { 586a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_MARG_ERROR), gShellLevel2HiiHandle, DestDir); 587a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellStatus = SHELL_INVALID_PARAMETER; 588a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellCloseFileMetaArg(&List); 589a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } else if (List != NULL) { 590a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ASSERT(((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink) != NULL); 591a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ASSERT(((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink)->FullName != NULL); 592a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey FileInfo = gEfiShellProtocol->GetFileInfo(((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink)->Handle); 593a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ASSERT(FileInfo != NULL); 594ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey StrnCatGrow(&FullName, NULL, ((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink)->FullName, 0); 595ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey ShellCloseFileMetaArg(&List); 596a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if ((FileInfo->Attribute & EFI_FILE_READ_ONLY) == 0) { 597ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey ShellStatus = ValidateAndCopyFiles(FileList, FullName, SilentMode, RecursiveMode, NULL); 598a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } else { 599a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_DEST_ERROR), gShellLevel2HiiHandle); 600a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellStatus = SHELL_ACCESS_DENIED; 601a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 602a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } else { 603ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey ShellCloseFileMetaArg(&List); 604ed053afece04120c1c62163475806d6aef3bc329Eric Dong ShellStatus = ValidateAndCopyFiles(FileList, DestDir, SilentMode, RecursiveMode, NULL); 605a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 606a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 607ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey SHELL_FREE_NON_NULL(FileInfo); 608ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey SHELL_FREE_NON_NULL(FullName); 609a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey return (ShellStatus); 610a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey} 611a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 612a405b86d274d32b92f69842bfb9a1ab143128f57jcarseySTATIC CONST SHELL_PARAM_ITEM ParamList[] = { 613a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey {L"-r", TypeFlag}, 614a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey {L"-q", TypeFlag}, 615a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey {NULL, TypeMax} 616a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey }; 617a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 618a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey/** 619a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey Function for 'cp' command. 620a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 621a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey @param[in] ImageHandle Handle to the Image (NULL if Internal). 622a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey @param[in] SystemTable Pointer to the System Table (NULL if Internal). 623a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey**/ 624a405b86d274d32b92f69842bfb9a1ab143128f57jcarseySHELL_STATUS 625a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyEFIAPI 626a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyShellCommandRunCp ( 627a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN EFI_HANDLE ImageHandle, 628a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN EFI_SYSTEM_TABLE *SystemTable 629a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ) 630a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey{ 631a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey EFI_STATUS Status; 632a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey LIST_ENTRY *Package; 633a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey CHAR16 *ProblemParam; 634a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey SHELL_STATUS ShellStatus; 635a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey UINTN ParamCount; 636a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey UINTN LoopCounter; 637a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey EFI_SHELL_FILE_INFO *FileList; 638a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey BOOLEAN SilentMode; 639a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey BOOLEAN RecursiveMode; 640a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey CONST CHAR16 *Cwd; 641a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 642a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ProblemParam = NULL; 643a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellStatus = SHELL_SUCCESS; 644a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ParamCount = 0; 645a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey FileList = NULL; 646a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 647a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 648a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // initialize the shell lib (we must be in non-auto-init...) 649a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 650a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey Status = ShellInitialize(); 651a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ASSERT_EFI_ERROR(Status); 652a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 653a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey Status = CommandInit(); 654a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ASSERT_EFI_ERROR(Status); 655a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 656a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 657a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // parse the command line 658a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 659a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE); 660a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (EFI_ERROR(Status)) { 661a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { 662a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ProblemParam); 663a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey FreePool(ProblemParam); 664a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellStatus = SHELL_INVALID_PARAMETER; 665a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } else { 666a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ASSERT(FALSE); 667a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 668a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } else { 669a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 670a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // check for "-?" 671a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 672a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (ShellCommandLineGetFlag(Package, L"-?")) { 673a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ASSERT(FALSE); 674a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 675a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 676a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 677a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // Initialize SilentMode and RecursiveMode 678a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 679a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (gEfiShellProtocol->BatchIsActive()) { 680a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey SilentMode = TRUE; 681a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } else { 682a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey SilentMode = ShellCommandLineGetFlag(Package, L"-q"); 683a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 684a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey RecursiveMode = ShellCommandLineGetFlag(Package, L"-r"); 685a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 686a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey switch (ParamCount = ShellCommandLineGetCount(Package)) { 687a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey case 0: 688a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey case 1: 689a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 690a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // we have insufficient parameters 691a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 692a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle); 693a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellStatus = SHELL_INVALID_PARAMETER; 694a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey break; 695a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey case 2: 696a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 697a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // must have valid CWD for single parameter... 698a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 699a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey Cwd = ShellGetCurrentDir(NULL); 700a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (Cwd == NULL){ 701a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle); 702a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellStatus = SHELL_INVALID_PARAMETER; 703a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } else { 704a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey Status = ShellOpenFileMetaArg((CHAR16*)ShellCommandLineGetRawValue(Package, 1), EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList); 705a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (FileList == NULL || IsListEmpty(&FileList->Link) || EFI_ERROR(Status)) { 706a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, ShellCommandLineGetRawValue(Package, 1)); 707a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellStatus = SHELL_NOT_FOUND; 708a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } else { 709a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellStatus = ProcessValidateAndCopyFiles(FileList, Cwd, SilentMode, RecursiveMode); 710a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 711a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 712a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 713a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey break; 714a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey default: 715a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 716a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // Make a big list of all the files... 717a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 718a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey for (ParamCount--, LoopCounter = 1 ; LoopCounter < ParamCount && ShellStatus == SHELL_SUCCESS ; LoopCounter++) { 719a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (ShellGetExecutionBreakFlag()) { 720a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey break; 721a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 722a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey Status = ShellOpenFileMetaArg((CHAR16*)ShellCommandLineGetRawValue(Package, LoopCounter), EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList); 723a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (EFI_ERROR(Status) || FileList == NULL || IsListEmpty(&FileList->Link)) { 724b2bf9735860994b4f4ae3904fd784bedcdd26da1jcarsey ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, ShellCommandLineGetRawValue(Package, LoopCounter)); 725a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellStatus = SHELL_NOT_FOUND; 726a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 727a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 728b2bf9735860994b4f4ae3904fd784bedcdd26da1jcarsey if (ShellStatus != SHELL_SUCCESS) { 729a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey Status = ShellCloseFileMetaArg(&FileList); 730b2bf9735860994b4f4ae3904fd784bedcdd26da1jcarsey } else { 731b2bf9735860994b4f4ae3904fd784bedcdd26da1jcarsey // 732b2bf9735860994b4f4ae3904fd784bedcdd26da1jcarsey // now copy them all... 733b2bf9735860994b4f4ae3904fd784bedcdd26da1jcarsey // 734b2bf9735860994b4f4ae3904fd784bedcdd26da1jcarsey if (FileList != NULL && !IsListEmpty(&FileList->Link)) { 735ab94587a7d2cd89695f9190420daceae0d2b7446jcarsey ShellStatus = ProcessValidateAndCopyFiles(FileList, PathCleanUpDirectories((CHAR16*)ShellCommandLineGetRawValue(Package, ParamCount)), SilentMode, RecursiveMode); 736b2bf9735860994b4f4ae3904fd784bedcdd26da1jcarsey Status = ShellCloseFileMetaArg(&FileList); 737b2bf9735860994b4f4ae3904fd784bedcdd26da1jcarsey if (EFI_ERROR(Status) && ShellStatus == SHELL_SUCCESS) { 738b2bf9735860994b4f4ae3904fd784bedcdd26da1jcarsey ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_FILE), gShellLevel2HiiHandle, ShellCommandLineGetRawValue(Package, ParamCount), ShellStatus|MAX_BIT); 739b2bf9735860994b4f4ae3904fd784bedcdd26da1jcarsey ShellStatus = SHELL_ACCESS_DENIED; 740b2bf9735860994b4f4ae3904fd784bedcdd26da1jcarsey } 741a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 742a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 743a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey break; 744a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } // switch on parameter count 745a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 746a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (FileList != NULL) { 747a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellCloseFileMetaArg(&FileList); 748a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 749a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 750a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 751a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // free the command line package 752a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 753a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellCommandLineFreeVarList (Package); 754a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 755a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 756a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (ShellGetExecutionBreakFlag()) { 757a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey return (SHELL_ABORTED); 758a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 759a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 760a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey return (ShellStatus); 761a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey} 762a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 763