1a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey/** @file 2a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey Main file for cp shell level 2 function. 3a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 4c011b6c9e2baf57fc0557117e9875ceb3dca55a3Tapan Shah (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR> 5e75390f02971bcd4d67a9696508050bee4936a01Qiu Shumin Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR> 6a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey This program and the accompanying materials 7a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey are licensed and made available under the terms and conditions of the BSD License 8a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey which accompanies this distribution. The full text of the license may be found at 9a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey http://opensource.org/licenses/bsd-license.php 10a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 11a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 14a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey**/ 15a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 16a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey#include "UefiShellLevel2CommandsLib.h" 17f06be00e7aea1dc89c63728d20247a85f1511139jcarsey#include <Guid/FileSystemInfo.h> 18f06be00e7aea1dc89c63728d20247a85f1511139jcarsey#include <Guid/FileSystemVolumeLabelInfo.h> 19a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 20b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey/** 21b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey Function to take a list of files to copy and a destination location and do 22b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey the verification and copying of those files to that location. This function 23b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey will report any errors to the user and halt. 24b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey 25b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] FileList A LIST_ENTRY* based list of files to move. 26b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] DestDir The destination location. 27b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] SilentMode TRUE to eliminate screen output. 28b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] RecursiveMode TRUE to copy directories. 29b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] Resp The response to the overwrite query (if always). 30b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey 31b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @retval SHELL_SUCCESS the files were all moved. 32b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @retval SHELL_INVALID_PARAMETER a parameter was invalid 33b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @retval SHELL_SECURITY_VIOLATION a security violation ocurred 34b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @retval SHELL_WRITE_PROTECTED the destination was write protected 35b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @retval SHELL_OUT_OF_RESOURCES a memory allocation failed 36b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey**/ 37a405b86d274d32b92f69842bfb9a1ab143128f57jcarseySHELL_STATUS 38a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyEFIAPI 39a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyValidateAndCopyFiles( 40a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN CONST EFI_SHELL_FILE_INFO *FileList, 41a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN CONST CHAR16 *DestDir, 42a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN BOOLEAN SilentMode, 43a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN BOOLEAN RecursiveMode, 44a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN VOID **Resp 45a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ); 46a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 47a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey/** 48a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey Function to Copy one file to another location 49a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 50a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey If the destination exists the user will be prompted and the result put into *resp 51a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 52a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey @param[in] Source pointer to source file name 53a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey @param[in] Dest pointer to destination file name 54a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey @param[out] Resp pointer to response from question. Pass back on looped calling 55a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey @param[in] SilentMode whether to run in quiet mode or not 56bf6bbc212d77736c9f81d6877701d4cf86030349Tapan Shah @param[in] CmdName Source command name requesting single file copy 57a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 58a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey @retval SHELL_SUCCESS The source file was copied to the destination 59a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey**/ 60a405b86d274d32b92f69842bfb9a1ab143128f57jcarseySHELL_STATUS 61a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyEFIAPI 62a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyCopySingleFile( 63a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN CONST CHAR16 *Source, 64a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN CONST CHAR16 *Dest, 65a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey OUT VOID **Resp, 66bf6bbc212d77736c9f81d6877701d4cf86030349Tapan Shah IN BOOLEAN SilentMode, 67bf6bbc212d77736c9f81d6877701d4cf86030349Tapan Shah IN CONST CHAR16 *CmdName 68a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ) 69a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey{ 70f06be00e7aea1dc89c63728d20247a85f1511139jcarsey VOID *Response; 71f06be00e7aea1dc89c63728d20247a85f1511139jcarsey UINTN ReadSize; 72f06be00e7aea1dc89c63728d20247a85f1511139jcarsey SHELL_FILE_HANDLE SourceHandle; 73f06be00e7aea1dc89c63728d20247a85f1511139jcarsey SHELL_FILE_HANDLE DestHandle; 74f06be00e7aea1dc89c63728d20247a85f1511139jcarsey EFI_STATUS Status; 75f06be00e7aea1dc89c63728d20247a85f1511139jcarsey VOID *Buffer; 76f06be00e7aea1dc89c63728d20247a85f1511139jcarsey CHAR16 *TempName; 77f06be00e7aea1dc89c63728d20247a85f1511139jcarsey UINTN Size; 78f06be00e7aea1dc89c63728d20247a85f1511139jcarsey EFI_SHELL_FILE_INFO *List; 79f06be00e7aea1dc89c63728d20247a85f1511139jcarsey SHELL_STATUS ShellStatus; 80f06be00e7aea1dc89c63728d20247a85f1511139jcarsey UINT64 SourceFileSize; 81f06be00e7aea1dc89c63728d20247a85f1511139jcarsey UINT64 DestFileSize; 82f06be00e7aea1dc89c63728d20247a85f1511139jcarsey EFI_FILE_PROTOCOL *DestVolumeFP; 83f06be00e7aea1dc89c63728d20247a85f1511139jcarsey EFI_FILE_SYSTEM_INFO *DestVolumeInfo; 84f06be00e7aea1dc89c63728d20247a85f1511139jcarsey UINTN DestVolumeInfoSize; 85a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 86a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ASSERT(Resp != NULL); 87a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 88f06be00e7aea1dc89c63728d20247a85f1511139jcarsey SourceHandle = NULL; 89f06be00e7aea1dc89c63728d20247a85f1511139jcarsey DestHandle = NULL; 90f06be00e7aea1dc89c63728d20247a85f1511139jcarsey Response = *Resp; 91f06be00e7aea1dc89c63728d20247a85f1511139jcarsey List = NULL; 92f06be00e7aea1dc89c63728d20247a85f1511139jcarsey DestVolumeInfo = NULL; 93e755a4ca10aad316c3620223206d63982793b26cjcarsey ShellStatus = SHELL_SUCCESS; 94a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 95433a21cba1a6a825b9ec07f580164b84e5d41d3aEugene Cohen ReadSize = PcdGet32(PcdShellFileOperationSize); 96a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // Why bother copying a file to itself 97a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (StrCmp(Source, Dest) == 0) { 98a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey return (SHELL_SUCCESS); 99a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 100a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 101a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 102a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // if the destination file existed check response and possibly prompt user 103a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 104ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey if (ShellFileExists(Dest) == EFI_SUCCESS) { 105a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (Response == NULL && !SilentMode) { 106b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey Status = ShellPromptForResponseHii(ShellPromptResponseTypeYesNoAllCancel, STRING_TOKEN (STR_GEN_DEST_EXIST_OVR), gShellLevel2HiiHandle, &Response); 107a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 108a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 109a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // possibly return based on response 110a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 111a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (!SilentMode) { 112a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey switch (*(SHELL_PROMPT_RESPONSE*)Response) { 113a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey case ShellPromptResponseNo: 114a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 115a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // return success here so we dont stop the process 116a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 117a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey return (SHELL_SUCCESS); 118a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey case ShellPromptResponseCancel: 119a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey *Resp = Response; 120a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 121a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // indicate to stop everything 122a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 123a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey return (SHELL_ABORTED); 124a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey case ShellPromptResponseAll: 125a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey *Resp = Response; 126a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey case ShellPromptResponseYes: 127a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey break; 128e97233217ed6d37d7bb7fefb0ff0821515a23b48jljusten default: 129e97233217ed6d37d7bb7fefb0ff0821515a23b48jljusten return SHELL_ABORTED; 130a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 131a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 132a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 133a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 134a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (ShellIsDirectory(Source) == EFI_SUCCESS) { 135a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey Status = ShellCreateDirectory(Dest, &DestHandle); 136a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (EFI_ERROR(Status)) { 137bf6bbc212d77736c9f81d6877701d4cf86030349Tapan Shah ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_DEST_DIR_FAIL), gShellLevel2HiiHandle, CmdName, Dest); 138a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey return (SHELL_ACCESS_DENIED); 139a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 140a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 141a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 142a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // Now copy all the files under the directory... 143a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 144a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey TempName = NULL; 145f06be00e7aea1dc89c63728d20247a85f1511139jcarsey Size = 0; 146a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey StrnCatGrow(&TempName, &Size, Source, 0); 147a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey StrnCatGrow(&TempName, &Size, L"\\*", 0); 1487dd0562309ac668b7025023f05e79687fdf7a13ajcarsey if (TempName != NULL) { 1497dd0562309ac668b7025023f05e79687fdf7a13ajcarsey ShellOpenFileMetaArg((CHAR16*)TempName, EFI_FILE_MODE_READ, &List); 1507dd0562309ac668b7025023f05e79687fdf7a13ajcarsey *TempName = CHAR_NULL; 1517dd0562309ac668b7025023f05e79687fdf7a13ajcarsey StrnCatGrow(&TempName, &Size, Dest, 0); 1527dd0562309ac668b7025023f05e79687fdf7a13ajcarsey StrnCatGrow(&TempName, &Size, L"\\", 0); 1537dd0562309ac668b7025023f05e79687fdf7a13ajcarsey ShellStatus = ValidateAndCopyFiles(List, TempName, SilentMode, TRUE, Resp); 1547dd0562309ac668b7025023f05e79687fdf7a13ajcarsey ShellCloseFileMetaArg(&List); 1557dd0562309ac668b7025023f05e79687fdf7a13ajcarsey SHELL_FREE_NON_NULL(TempName); 1567dd0562309ac668b7025023f05e79687fdf7a13ajcarsey Size = 0; 1577dd0562309ac668b7025023f05e79687fdf7a13ajcarsey } 158a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } else { 159ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey Status = ShellDeleteFileByName(Dest); 160a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 161ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 162ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // open file with create enabled 163ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 164ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey Status = ShellOpenFileByName(Dest, &DestHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0); 165ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey if (EFI_ERROR(Status)) { 166bf6bbc212d77736c9f81d6877701d4cf86030349Tapan Shah ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_DEST_OPEN_FAIL), gShellLevel2HiiHandle, CmdName, Dest); 167ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey return (SHELL_ACCESS_DENIED); 168ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey } 169f06be00e7aea1dc89c63728d20247a85f1511139jcarsey 170ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 171ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // open source file 172ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 1732ce9792534cebf8a70b110094d4790783da0178bOlivier Martin Status = ShellOpenFileByName (Source, &SourceHandle, EFI_FILE_MODE_READ, 0); 1742ce9792534cebf8a70b110094d4790783da0178bOlivier Martin if (EFI_ERROR (Status)) { 1752ce9792534cebf8a70b110094d4790783da0178bOlivier Martin ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_CP_SRC_OPEN_FAIL), gShellLevel2HiiHandle, CmdName, Source); 1762ce9792534cebf8a70b110094d4790783da0178bOlivier Martin return (SHELL_ACCESS_DENIED); 1772ce9792534cebf8a70b110094d4790783da0178bOlivier Martin } 178f06be00e7aea1dc89c63728d20247a85f1511139jcarsey 179ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 180ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey //get file size of source file and freespace available on destination volume 181ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 182ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey ShellGetFileSize(SourceHandle, &SourceFileSize); 183ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey ShellGetFileSize(DestHandle, &DestFileSize); 184f06be00e7aea1dc89c63728d20247a85f1511139jcarsey 185ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 186ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey //if the destination file already exists then it will be replaced, meaning the sourcefile effectively needs less storage space 187ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 188ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey if(DestFileSize < SourceFileSize){ 189ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey SourceFileSize -= DestFileSize; 190ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey } else { 191ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey SourceFileSize = 0; 192ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey } 193ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey 194ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 195ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey //get the system volume info to check the free space 196ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 197ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey DestVolumeFP = ConvertShellHandleToEfiFileProtocol(DestHandle); 198ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey DestVolumeInfo = NULL; 199ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey DestVolumeInfoSize = 0; 200ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey Status = DestVolumeFP->GetInfo( 201ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey DestVolumeFP, 202ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey &gEfiFileSystemInfoGuid, 203ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey &DestVolumeInfoSize, 204ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey DestVolumeInfo 205ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey ); 206ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey 207ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey if (Status == EFI_BUFFER_TOO_SMALL) { 208ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey DestVolumeInfo = AllocateZeroPool(DestVolumeInfoSize); 209f06be00e7aea1dc89c63728d20247a85f1511139jcarsey Status = DestVolumeFP->GetInfo( 210f06be00e7aea1dc89c63728d20247a85f1511139jcarsey DestVolumeFP, 211f06be00e7aea1dc89c63728d20247a85f1511139jcarsey &gEfiFileSystemInfoGuid, 212f06be00e7aea1dc89c63728d20247a85f1511139jcarsey &DestVolumeInfoSize, 213f06be00e7aea1dc89c63728d20247a85f1511139jcarsey DestVolumeInfo 214f06be00e7aea1dc89c63728d20247a85f1511139jcarsey ); 215ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey } 216f06be00e7aea1dc89c63728d20247a85f1511139jcarsey 217ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 218ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey //check if enough space available on destination drive to complete copy 219ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 220ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey if (DestVolumeInfo!= NULL && (DestVolumeInfo->FreeSpace < SourceFileSize)) { 221f06be00e7aea1dc89c63728d20247a85f1511139jcarsey // 222ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey //not enough space on destination directory to copy file 223f06be00e7aea1dc89c63728d20247a85f1511139jcarsey // 224f06be00e7aea1dc89c63728d20247a85f1511139jcarsey SHELL_FREE_NON_NULL(DestVolumeInfo); 225bf6bbc212d77736c9f81d6877701d4cf86030349Tapan Shah ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_CPY_FAIL), gShellLevel2HiiHandle, CmdName); 226ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey return(SHELL_VOLUME_FULL); 227ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey } else { 228ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 229ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // copy data between files 230ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey // 231ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey Buffer = AllocateZeroPool(ReadSize); 232ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey ASSERT(Buffer != NULL); 233ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey while (ReadSize == PcdGet32(PcdShellFileOperationSize) && !EFI_ERROR(Status)) { 234ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey Status = ShellReadFile(SourceHandle, &ReadSize, Buffer); 235f3a14a0f575e7e856ff4d90d7d0ab73f7e02ae41Shumin Qiu if (!EFI_ERROR(Status)) { 236f3a14a0f575e7e856ff4d90d7d0ab73f7e02ae41Shumin Qiu Status = ShellWriteFile(DestHandle, &ReadSize, Buffer); 237f3a14a0f575e7e856ff4d90d7d0ab73f7e02ae41Shumin Qiu if (EFI_ERROR(Status)) { 238f3a14a0f575e7e856ff4d90d7d0ab73f7e02ae41Shumin Qiu ShellStatus = (SHELL_STATUS) (Status & (~MAX_BIT)); 239bf6bbc212d77736c9f81d6877701d4cf86030349Tapan Shah ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_CPY_WRITE_ERROR), gShellLevel2HiiHandle, CmdName, Dest); 240f3a14a0f575e7e856ff4d90d7d0ab73f7e02ae41Shumin Qiu break; 241f3a14a0f575e7e856ff4d90d7d0ab73f7e02ae41Shumin Qiu } 242f3a14a0f575e7e856ff4d90d7d0ab73f7e02ae41Shumin Qiu } else { 243f3a14a0f575e7e856ff4d90d7d0ab73f7e02ae41Shumin Qiu ShellStatus = (SHELL_STATUS) (Status & (~MAX_BIT)); 244bf6bbc212d77736c9f81d6877701d4cf86030349Tapan Shah ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_CPY_READ_ERROR), gShellLevel2HiiHandle, CmdName, Source); 245f3a14a0f575e7e856ff4d90d7d0ab73f7e02ae41Shumin Qiu break; 246f3a14a0f575e7e856ff4d90d7d0ab73f7e02ae41Shumin Qiu } 247ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey } 248a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 249ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey SHELL_FREE_NON_NULL(DestVolumeInfo); 250ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey } 251f3a14a0f575e7e856ff4d90d7d0ab73f7e02ae41Shumin Qiu 252a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 253a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // close files 254a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 255a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (DestHandle != NULL) { 256a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellCloseFile(&DestHandle); 257a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey DestHandle = NULL; 258a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 259a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (SourceHandle != NULL) { 260a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellCloseFile(&SourceHandle); 261a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey SourceHandle = NULL; 262a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 263a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 264a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 265a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // return 266a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 267e755a4ca10aad316c3620223206d63982793b26cjcarsey return ShellStatus; 268a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey} 269a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 270a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey/** 271a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey function to take a list of files to copy and a destination location and do 272a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey the verification and copying of those files to that location. This function 273a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey will report any errors to the user and halt. 274a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 275a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey The key is to have this function called ONLY once. this allows for the parameter 276a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey verification to happen correctly. 277a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 278b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] FileList A LIST_ENTRY* based list of files to move. 279b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] DestDir The destination location. 280b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] SilentMode TRUE to eliminate screen output. 281b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] RecursiveMode TRUE to copy directories. 282b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] Resp The response to the overwrite query (if always). 283a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 284a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey @retval SHELL_SUCCESS the files were all moved. 285a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey @retval SHELL_INVALID_PARAMETER a parameter was invalid 286a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey @retval SHELL_SECURITY_VIOLATION a security violation ocurred 287a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey @retval SHELL_WRITE_PROTECTED the destination was write protected 288a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey @retval SHELL_OUT_OF_RESOURCES a memory allocation failed 289a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey**/ 290a405b86d274d32b92f69842bfb9a1ab143128f57jcarseySHELL_STATUS 291a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyEFIAPI 292a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyValidateAndCopyFiles( 293a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN CONST EFI_SHELL_FILE_INFO *FileList, 294a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN CONST CHAR16 *DestDir, 295a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN BOOLEAN SilentMode, 296a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN BOOLEAN RecursiveMode, 297a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN VOID **Resp 298a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ) 299a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey{ 300a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey CHAR16 *HiiOutput; 301a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey CHAR16 *HiiResultOk; 302a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey CONST EFI_SHELL_FILE_INFO *Node; 303a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey SHELL_STATUS ShellStatus; 3040960ba17e596812f211ba334cc6699d45bada328Qiu Shumin EFI_STATUS Status; 305a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey CHAR16 *DestPath; 306a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey VOID *Response; 307e1044f8074836b74188a2371ba70be05d0e0482bJaben Carsey UINTN PathSize; 308a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey CONST CHAR16 *Cwd; 309a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey UINTN NewSize; 3100960ba17e596812f211ba334cc6699d45bada328Qiu Shumin CHAR16 *CleanFilePathStr; 311a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 312a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (Resp == NULL) { 313a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey Response = NULL; 314a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } else { 315a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey Response = *Resp; 316a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 317a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 318715096c2448412e54a95092942a397bd4d697524Qiu Shumin DestPath = NULL; 319715096c2448412e54a95092942a397bd4d697524Qiu Shumin ShellStatus = SHELL_SUCCESS; 320715096c2448412e54a95092942a397bd4d697524Qiu Shumin PathSize = 0; 321715096c2448412e54a95092942a397bd4d697524Qiu Shumin Cwd = ShellGetCurrentDir(NULL); 322715096c2448412e54a95092942a397bd4d697524Qiu Shumin CleanFilePathStr = NULL; 323a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 324a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ASSERT(FileList != NULL); 325a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ASSERT(DestDir != NULL); 326a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 3270960ba17e596812f211ba334cc6699d45bada328Qiu Shumin 3280960ba17e596812f211ba334cc6699d45bada328Qiu Shumin Status = ShellLevel2StripQuotes (DestDir, &CleanFilePathStr); 3290960ba17e596812f211ba334cc6699d45bada328Qiu Shumin if (EFI_ERROR (Status)) { 3300960ba17e596812f211ba334cc6699d45bada328Qiu Shumin if (Status == EFI_OUT_OF_RESOURCES) { 3310960ba17e596812f211ba334cc6699d45bada328Qiu Shumin return SHELL_OUT_OF_RESOURCES; 3320960ba17e596812f211ba334cc6699d45bada328Qiu Shumin } else { 3330960ba17e596812f211ba334cc6699d45bada328Qiu Shumin return SHELL_INVALID_PARAMETER; 3340960ba17e596812f211ba334cc6699d45bada328Qiu Shumin } 335427d61ad4ad1462b5f4370a78eb58c1ba73680b4Qiu Shumin } 336427d61ad4ad1462b5f4370a78eb58c1ba73680b4Qiu Shumin 337427d61ad4ad1462b5f4370a78eb58c1ba73680b4Qiu Shumin ASSERT (CleanFilePathStr != NULL); 3380960ba17e596812f211ba334cc6699d45bada328Qiu Shumin 339a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 340a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // If we are trying to copy multiple files... make sure we got a directory for the target... 341a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 3420960ba17e596812f211ba334cc6699d45bada328Qiu Shumin if (EFI_ERROR(ShellIsDirectory(CleanFilePathStr)) && FileList->Link.ForwardLink != FileList->Link.BackLink) { 343a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 344a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // Error for destination not a directory 345a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 346099e8ff5d2876b1d1606c3424114969946c15173Tapan Shah ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_DIR), gShellLevel2HiiHandle, L"cp", CleanFilePathStr); 3470960ba17e596812f211ba334cc6699d45bada328Qiu Shumin FreePool (CleanFilePathStr); 348a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey return (SHELL_INVALID_PARAMETER); 349a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 350a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&FileList->Link) 351a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ; !IsNull(&FileList->Link, &Node->Link) 352a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&FileList->Link, &Node->Link) 353f06be00e7aea1dc89c63728d20247a85f1511139jcarsey ){ 354a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 355a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // skip the directory traversing stuff... 356a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 357a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (StrCmp(Node->FileName, L".") == 0 || StrCmp(Node->FileName, L"..") == 0) { 358a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey continue; 359a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 360a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 3610960ba17e596812f211ba334cc6699d45bada328Qiu Shumin NewSize = StrSize(CleanFilePathStr); 362b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey NewSize += StrSize(Node->FullName); 363fbd2dfadfe6fb16ab7b49fca3764e05e65d97b8aQiu Shumin NewSize += (Cwd == NULL)? 0 : (StrSize(Cwd) + sizeof(CHAR16)); 364e1044f8074836b74188a2371ba70be05d0e0482bJaben Carsey if (NewSize > PathSize) { 365e1044f8074836b74188a2371ba70be05d0e0482bJaben Carsey PathSize = NewSize; 366a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 367a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 368a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 369a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // Make sure got -r if required 370a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 371a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (!RecursiveMode && !EFI_ERROR(ShellIsDirectory(Node->FullName))) { 372099e8ff5d2876b1d1606c3424114969946c15173Tapan Shah ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_DIR_REQ), gShellLevel2HiiHandle, L"cp"); 3730960ba17e596812f211ba334cc6699d45bada328Qiu Shumin FreePool (CleanFilePathStr); 374a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey return (SHELL_INVALID_PARAMETER); 375a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 376a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 377a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 378a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // make sure got dest as dir if needed 379a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 3800960ba17e596812f211ba334cc6699d45bada328Qiu Shumin if (!EFI_ERROR(ShellIsDirectory(Node->FullName)) && EFI_ERROR(ShellIsDirectory(CleanFilePathStr))) { 381a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 382a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // Error for destination not a directory 383a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 384099e8ff5d2876b1d1606c3424114969946c15173Tapan Shah ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_DIR), gShellLevel2HiiHandle, L"cp", CleanFilePathStr); 3850960ba17e596812f211ba334cc6699d45bada328Qiu Shumin FreePool (CleanFilePathStr); 386a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey return (SHELL_INVALID_PARAMETER); 387a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 388a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 389a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 390a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey HiiOutput = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_CP_OUTPUT), NULL); 391a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey HiiResultOk = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_GEN_RES_OK), NULL); 392e1044f8074836b74188a2371ba70be05d0e0482bJaben Carsey DestPath = AllocateZeroPool(PathSize); 393a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 3943e082d58262da4108a3f1f2ee8fa0a9441bb2a9bjcarsey if (DestPath == NULL || HiiOutput == NULL || HiiResultOk == NULL) { 3959ea69f8a05b808b4bab81b608436a02e2f2fba09jcarsey SHELL_FREE_NON_NULL(DestPath); 3969ea69f8a05b808b4bab81b608436a02e2f2fba09jcarsey SHELL_FREE_NON_NULL(HiiOutput); 3979ea69f8a05b808b4bab81b608436a02e2f2fba09jcarsey SHELL_FREE_NON_NULL(HiiResultOk); 3980960ba17e596812f211ba334cc6699d45bada328Qiu Shumin FreePool (CleanFilePathStr); 3999ea69f8a05b808b4bab81b608436a02e2f2fba09jcarsey return (SHELL_OUT_OF_RESOURCES); 4009ea69f8a05b808b4bab81b608436a02e2f2fba09jcarsey } 4019ea69f8a05b808b4bab81b608436a02e2f2fba09jcarsey 402a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 403a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // Go through the list of files to copy... 404a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 405a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&FileList->Link) 406a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ; !IsNull(&FileList->Link, &Node->Link) 407a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&FileList->Link, &Node->Link) 408f06be00e7aea1dc89c63728d20247a85f1511139jcarsey ){ 409a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (ShellGetExecutionBreakFlag()) { 410a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey break; 411a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 412a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ASSERT(Node->FileName != NULL); 413a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ASSERT(Node->FullName != NULL); 414a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 415a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 416a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // skip the directory traversing stuff... 417a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 418a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (StrCmp(Node->FileName, L".") == 0 || StrCmp(Node->FileName, L"..") == 0) { 419a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey continue; 420a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 421a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 422a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (FileList->Link.ForwardLink == FileList->Link.BackLink // 1 item 4230960ba17e596812f211ba334cc6699d45bada328Qiu Shumin && EFI_ERROR(ShellIsDirectory(CleanFilePathStr)) // not an existing directory 424f06be00e7aea1dc89c63728d20247a85f1511139jcarsey ) { 4250960ba17e596812f211ba334cc6699d45bada328Qiu Shumin if (StrStr(CleanFilePathStr, L":") == NULL) { 426b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey // 427b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey // simple copy of a single file 428b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey // 429ed053afece04120c1c62163475806d6aef3bc329Eric Dong if (Cwd != NULL) { 430e75390f02971bcd4d67a9696508050bee4936a01Qiu Shumin StrCpyS(DestPath, PathSize / sizeof(CHAR16), Cwd); 431fbd2dfadfe6fb16ab7b49fca3764e05e65d97b8aQiu Shumin StrCatS(DestPath, PathSize / sizeof(CHAR16), L"\\"); 432ed053afece04120c1c62163475806d6aef3bc329Eric Dong } else { 433099e8ff5d2876b1d1606c3424114969946c15173Tapan Shah ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, L"cp", CleanFilePathStr); 4340960ba17e596812f211ba334cc6699d45bada328Qiu Shumin FreePool (CleanFilePathStr); 435ed053afece04120c1c62163475806d6aef3bc329Eric Dong return (SHELL_INVALID_PARAMETER); 436ed053afece04120c1c62163475806d6aef3bc329Eric Dong } 4370960ba17e596812f211ba334cc6699d45bada328Qiu Shumin if (DestPath[StrLen(DestPath)-1] != L'\\' && CleanFilePathStr[0] != L'\\') { 438e75390f02971bcd4d67a9696508050bee4936a01Qiu Shumin StrCatS(DestPath, PathSize / sizeof(CHAR16), L"\\"); 4390960ba17e596812f211ba334cc6699d45bada328Qiu Shumin } else if (DestPath[StrLen(DestPath)-1] == L'\\' && CleanFilePathStr[0] == L'\\') { 440b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey ((CHAR16*)DestPath)[StrLen(DestPath)-1] = CHAR_NULL; 441b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey } 442e75390f02971bcd4d67a9696508050bee4936a01Qiu Shumin StrCatS(DestPath, PathSize/sizeof(CHAR16), CleanFilePathStr); 443b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey } else { 444e75390f02971bcd4d67a9696508050bee4936a01Qiu Shumin StrCpyS(DestPath, PathSize/sizeof(CHAR16), CleanFilePathStr); 445a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 446a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } else { 447a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 448a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // we have multiple files or a directory in the DestDir 449a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 4501fc3749dad42e8d5caebf6e0e0327b713b6adaebjcarsey 4511fc3749dad42e8d5caebf6e0e0327b713b6adaebjcarsey // 4521fc3749dad42e8d5caebf6e0e0327b713b6adaebjcarsey // Check for leading slash 4531fc3749dad42e8d5caebf6e0e0327b713b6adaebjcarsey // 4540960ba17e596812f211ba334cc6699d45bada328Qiu Shumin if (CleanFilePathStr[0] == L'\\') { 455ed053afece04120c1c62163475806d6aef3bc329Eric Dong // 456ed053afece04120c1c62163475806d6aef3bc329Eric Dong // Copy to the root of CWD 457ed053afece04120c1c62163475806d6aef3bc329Eric Dong // 458ed053afece04120c1c62163475806d6aef3bc329Eric Dong if (Cwd != NULL) { 459e75390f02971bcd4d67a9696508050bee4936a01Qiu Shumin StrCpyS(DestPath, PathSize/sizeof(CHAR16), Cwd); 460fbd2dfadfe6fb16ab7b49fca3764e05e65d97b8aQiu Shumin StrCatS(DestPath, PathSize/sizeof(CHAR16), L"\\"); 461ed053afece04120c1c62163475806d6aef3bc329Eric Dong } else { 462099e8ff5d2876b1d1606c3424114969946c15173Tapan Shah ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, L"cp", CleanFilePathStr); 4630960ba17e596812f211ba334cc6699d45bada328Qiu Shumin FreePool(CleanFilePathStr); 464ed053afece04120c1c62163475806d6aef3bc329Eric Dong return (SHELL_INVALID_PARAMETER); 465ed053afece04120c1c62163475806d6aef3bc329Eric Dong } 4661fc3749dad42e8d5caebf6e0e0327b713b6adaebjcarsey while (PathRemoveLastItem(DestPath)); 467e75390f02971bcd4d67a9696508050bee4936a01Qiu Shumin StrCatS(DestPath, PathSize/sizeof(CHAR16), CleanFilePathStr+1); 468e75390f02971bcd4d67a9696508050bee4936a01Qiu Shumin StrCatS(DestPath, PathSize/sizeof(CHAR16), Node->FileName); 4690960ba17e596812f211ba334cc6699d45bada328Qiu Shumin } else if (StrStr(CleanFilePathStr, L":") == NULL) { 470ed053afece04120c1c62163475806d6aef3bc329Eric Dong if (Cwd != NULL) { 471e75390f02971bcd4d67a9696508050bee4936a01Qiu Shumin StrCpyS(DestPath, PathSize/sizeof(CHAR16), Cwd); 472fbd2dfadfe6fb16ab7b49fca3764e05e65d97b8aQiu Shumin StrCatS(DestPath, PathSize/sizeof(CHAR16), L"\\"); 473ed053afece04120c1c62163475806d6aef3bc329Eric Dong } else { 474099e8ff5d2876b1d1606c3424114969946c15173Tapan Shah ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, L"cp", CleanFilePathStr); 4750960ba17e596812f211ba334cc6699d45bada328Qiu Shumin FreePool(CleanFilePathStr); 476ed053afece04120c1c62163475806d6aef3bc329Eric Dong return (SHELL_INVALID_PARAMETER); 477ed053afece04120c1c62163475806d6aef3bc329Eric Dong } 4780960ba17e596812f211ba334cc6699d45bada328Qiu Shumin if (DestPath[StrLen(DestPath)-1] != L'\\' && CleanFilePathStr[0] != L'\\') { 479e75390f02971bcd4d67a9696508050bee4936a01Qiu Shumin StrCatS(DestPath, PathSize/sizeof(CHAR16), L"\\"); 4800960ba17e596812f211ba334cc6699d45bada328Qiu Shumin } else if (DestPath[StrLen(DestPath)-1] == L'\\' && CleanFilePathStr[0] == L'\\') { 481a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ((CHAR16*)DestPath)[StrLen(DestPath)-1] = CHAR_NULL; 482a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 483e75390f02971bcd4d67a9696508050bee4936a01Qiu Shumin StrCatS(DestPath, PathSize/sizeof(CHAR16), CleanFilePathStr); 4840960ba17e596812f211ba334cc6699d45bada328Qiu Shumin if (CleanFilePathStr[StrLen(CleanFilePathStr)-1] != L'\\' && Node->FileName[0] != L'\\') { 485e75390f02971bcd4d67a9696508050bee4936a01Qiu Shumin StrCatS(DestPath, PathSize/sizeof(CHAR16), L"\\"); 4860960ba17e596812f211ba334cc6699d45bada328Qiu Shumin } else if (CleanFilePathStr[StrLen(CleanFilePathStr)-1] == L'\\' && Node->FileName[0] == L'\\') { 487a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ((CHAR16*)DestPath)[StrLen(DestPath)-1] = CHAR_NULL; 488a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 489e75390f02971bcd4d67a9696508050bee4936a01Qiu Shumin StrCatS(DestPath, PathSize/sizeof(CHAR16), Node->FileName); 490a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 491a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } else { 492e75390f02971bcd4d67a9696508050bee4936a01Qiu Shumin StrCpyS(DestPath, PathSize/sizeof(CHAR16), CleanFilePathStr); 4930960ba17e596812f211ba334cc6699d45bada328Qiu Shumin if (CleanFilePathStr[StrLen(CleanFilePathStr)-1] != L'\\' && Node->FileName[0] != L'\\') { 494e75390f02971bcd4d67a9696508050bee4936a01Qiu Shumin StrCatS(DestPath, PathSize/sizeof(CHAR16), L"\\"); 4950960ba17e596812f211ba334cc6699d45bada328Qiu Shumin } else if (CleanFilePathStr[StrLen(CleanFilePathStr)-1] == L'\\' && Node->FileName[0] == L'\\') { 4960960ba17e596812f211ba334cc6699d45bada328Qiu Shumin ((CHAR16*)CleanFilePathStr)[StrLen(CleanFilePathStr)-1] = CHAR_NULL; 497a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 498e75390f02971bcd4d67a9696508050bee4936a01Qiu Shumin StrCatS(DestPath, PathSize/sizeof(CHAR16), Node->FileName); 499a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 500a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 501a6e84d95f50a10e23ee9861270fb84057b5af2e9Ni Ruiyu 502a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 503a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // Make sure the path exists 504a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 505a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (EFI_ERROR(VerifyIntermediateDirectories(DestPath))) { 506099e8ff5d2876b1d1606c3424114969946c15173Tapan Shah ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_DIR_WNF), gShellLevel2HiiHandle, L"cp", DestPath); 507a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellStatus = SHELL_DEVICE_ERROR; 508a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey break; 509a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 510a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 511a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if ( !EFI_ERROR(ShellIsDirectory(Node->FullName)) 512a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey && !EFI_ERROR(ShellIsDirectory(DestPath)) 513a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey && StrniCmp(Node->FullName, DestPath, StrLen(DestPath)) == NULL 514f06be00e7aea1dc89c63728d20247a85f1511139jcarsey ){ 515099e8ff5d2876b1d1606c3424114969946c15173Tapan Shah ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_SD_PARENT), gShellLevel2HiiHandle, L"cp"); 516a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellStatus = SHELL_INVALID_PARAMETER; 517a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey break; 518a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 519a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (StringNoCaseCompare(&Node->FullName, &DestPath) == 0) { 520099e8ff5d2876b1d1606c3424114969946c15173Tapan Shah ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_SD_SAME), gShellLevel2HiiHandle, L"cp"); 521a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellStatus = SHELL_INVALID_PARAMETER; 522a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey break; 523a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 524a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 5255051c2873b78114da6349e1c7e0754233f6c0024Olivier Martin if ((StrniCmp(Node->FullName, DestPath, StrLen(Node->FullName)) == 0) 526a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey && (DestPath[StrLen(Node->FullName)] == CHAR_NULL || DestPath[StrLen(Node->FullName)] == L'\\') 527f06be00e7aea1dc89c63728d20247a85f1511139jcarsey ) { 528099e8ff5d2876b1d1606c3424114969946c15173Tapan Shah ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_SD_SAME), gShellLevel2HiiHandle, L"cp"); 529a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellStatus = SHELL_INVALID_PARAMETER; 530a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey break; 531a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 532a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 533ab94587a7d2cd89695f9190420daceae0d2b7446jcarsey PathCleanUpDirectories(DestPath); 534a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 535a737ea734b9d64d6b10e399d5d0a8539604decddJaben Carsey if (!SilentMode) { 536a737ea734b9d64d6b10e399d5d0a8539604decddJaben Carsey ShellPrintEx(-1, -1, HiiOutput, Node->FullName, DestPath); 537a737ea734b9d64d6b10e399d5d0a8539604decddJaben Carsey } 538a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 539a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 540a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // copy single file... 541a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 542bf6bbc212d77736c9f81d6877701d4cf86030349Tapan Shah ShellStatus = CopySingleFile(Node->FullName, DestPath, &Response, SilentMode, L"cp"); 543a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (ShellStatus != SHELL_SUCCESS) { 544a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey break; 545a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 546a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 547a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (ShellStatus == SHELL_SUCCESS && Resp == NULL) { 548a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellPrintEx(-1, -1, L"%s", HiiResultOk); 549a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 550a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 551a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey SHELL_FREE_NON_NULL(DestPath); 552a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey SHELL_FREE_NON_NULL(HiiOutput); 553a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey SHELL_FREE_NON_NULL(HiiResultOk); 554a6e84d95f50a10e23ee9861270fb84057b5af2e9Ni Ruiyu SHELL_FREE_NON_NULL(CleanFilePathStr); 555590c3cb14ad6547528ea13805817676e32c204aajcarsey if (Resp == NULL) { 556a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey SHELL_FREE_NON_NULL(Response); 557a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 558a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 559a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey return (ShellStatus); 560f06be00e7aea1dc89c63728d20247a85f1511139jcarsey 561a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey} 562a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 563b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey/** 564b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey Validate and if successful copy all the files from the list into 565b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey destination directory. 566b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey 567b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] FileList The list of files to copy. 568b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] DestDir The directory to copy files to. 569b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] SilentMode TRUE to eliminate screen output. 570b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @param[in] RecursiveMode TRUE to copy directories. 571b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey 572b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @retval SHELL_INVALID_PARAMETER A parameter was invalid. 573b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey @retval SHELL_SUCCESS The operation was successful. 574b54fd049bdfa0d9520a40d8a1783aa681b40d751jcarsey**/ 575a405b86d274d32b92f69842bfb9a1ab143128f57jcarseySHELL_STATUS 576a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyEFIAPI 577a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyProcessValidateAndCopyFiles( 578a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN EFI_SHELL_FILE_INFO *FileList, 579a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN CONST CHAR16 *DestDir, 580a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN BOOLEAN SilentMode, 581a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN BOOLEAN RecursiveMode 582a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ) 583a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey{ 584a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey SHELL_STATUS ShellStatus; 585a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey EFI_SHELL_FILE_INFO *List; 586a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey EFI_FILE_INFO *FileInfo; 587ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey CHAR16 *FullName; 588a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 589ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey List = NULL; 590ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey FullName = NULL; 5919f56625f2a904701f460c88a7dbfaf17c4c83a22Jaben Carsey FileInfo = NULL; 592a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 593e755a4ca10aad316c3620223206d63982793b26cjcarsey ShellOpenFileMetaArg((CHAR16*)DestDir, EFI_FILE_MODE_READ, &List); 594a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (List != NULL && List->Link.ForwardLink != List->Link.BackLink) { 595099e8ff5d2876b1d1606c3424114969946c15173Tapan Shah ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_MARG_ERROR), gShellLevel2HiiHandle, L"cp", DestDir); 596a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellStatus = SHELL_INVALID_PARAMETER; 597a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellCloseFileMetaArg(&List); 598a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } else if (List != NULL) { 599a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ASSERT(((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink) != NULL); 600a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ASSERT(((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink)->FullName != NULL); 601a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey FileInfo = gEfiShellProtocol->GetFileInfo(((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink)->Handle); 602a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ASSERT(FileInfo != NULL); 603ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey StrnCatGrow(&FullName, NULL, ((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink)->FullName, 0); 604ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey ShellCloseFileMetaArg(&List); 605a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if ((FileInfo->Attribute & EFI_FILE_READ_ONLY) == 0) { 606ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey ShellStatus = ValidateAndCopyFiles(FileList, FullName, SilentMode, RecursiveMode, NULL); 607a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } else { 608099e8ff5d2876b1d1606c3424114969946c15173Tapan Shah ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_DEST_ERROR), gShellLevel2HiiHandle, L"cp"); 609a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellStatus = SHELL_ACCESS_DENIED; 610a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 611a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } else { 612ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey ShellCloseFileMetaArg(&List); 613ed053afece04120c1c62163475806d6aef3bc329Eric Dong ShellStatus = ValidateAndCopyFiles(FileList, DestDir, SilentMode, RecursiveMode, NULL); 614a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 615a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 616ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey SHELL_FREE_NON_NULL(FileInfo); 617ac8783c8b162b9a3b1e2da222cf6d088fcf63cfbJaben Carsey SHELL_FREE_NON_NULL(FullName); 618a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey return (ShellStatus); 619a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey} 620a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 621a405b86d274d32b92f69842bfb9a1ab143128f57jcarseySTATIC CONST SHELL_PARAM_ITEM ParamList[] = { 622a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey {L"-r", TypeFlag}, 623a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey {L"-q", TypeFlag}, 624a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey {NULL, TypeMax} 625a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey }; 626a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 627a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey/** 628a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey Function for 'cp' command. 629a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 630a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey @param[in] ImageHandle Handle to the Image (NULL if Internal). 631a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey @param[in] SystemTable Pointer to the System Table (NULL if Internal). 632a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey**/ 633a405b86d274d32b92f69842bfb9a1ab143128f57jcarseySHELL_STATUS 634a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyEFIAPI 635a405b86d274d32b92f69842bfb9a1ab143128f57jcarseyShellCommandRunCp ( 636a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN EFI_HANDLE ImageHandle, 637a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey IN EFI_SYSTEM_TABLE *SystemTable 638a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ) 639a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey{ 640a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey EFI_STATUS Status; 641a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey LIST_ENTRY *Package; 642a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey CHAR16 *ProblemParam; 643a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey SHELL_STATUS ShellStatus; 644a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey UINTN ParamCount; 645a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey UINTN LoopCounter; 646a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey EFI_SHELL_FILE_INFO *FileList; 647a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey BOOLEAN SilentMode; 648a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey BOOLEAN RecursiveMode; 649a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey CONST CHAR16 *Cwd; 650fbd2dfadfe6fb16ab7b49fca3764e05e65d97b8aQiu Shumin CHAR16 *FullCwd; 651a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 652a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ProblemParam = NULL; 653a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellStatus = SHELL_SUCCESS; 654a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ParamCount = 0; 655a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey FileList = NULL; 656a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 657a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 658a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // initialize the shell lib (we must be in non-auto-init...) 659a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 660a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey Status = ShellInitialize(); 661a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ASSERT_EFI_ERROR(Status); 662a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 663a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey Status = CommandInit(); 664a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ASSERT_EFI_ERROR(Status); 665a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 666a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 667a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // parse the command line 668a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 669a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE); 670a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (EFI_ERROR(Status)) { 671a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { 672099e8ff5d2876b1d1606c3424114969946c15173Tapan Shah ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"cp", ProblemParam); 673a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey FreePool(ProblemParam); 674a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellStatus = SHELL_INVALID_PARAMETER; 675a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } else { 676a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ASSERT(FALSE); 677a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 678a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } else { 679a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 680a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // check for "-?" 681a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 682a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (ShellCommandLineGetFlag(Package, L"-?")) { 683a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ASSERT(FALSE); 684a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 685a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 686a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 687a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // Initialize SilentMode and RecursiveMode 688a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 689a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (gEfiShellProtocol->BatchIsActive()) { 690a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey SilentMode = TRUE; 691a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } else { 692a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey SilentMode = ShellCommandLineGetFlag(Package, L"-q"); 693a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 694a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey RecursiveMode = ShellCommandLineGetFlag(Package, L"-r"); 695a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 696a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey switch (ParamCount = ShellCommandLineGetCount(Package)) { 697a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey case 0: 698a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey case 1: 699a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 700a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // we have insufficient parameters 701a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 702099e8ff5d2876b1d1606c3424114969946c15173Tapan Shah ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"cp"); 703a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellStatus = SHELL_INVALID_PARAMETER; 704a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey break; 705a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey case 2: 706a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 707a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // must have valid CWD for single parameter... 708a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 709a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey Cwd = ShellGetCurrentDir(NULL); 710a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (Cwd == NULL){ 711099e8ff5d2876b1d1606c3424114969946c15173Tapan Shah ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"cp"); 712a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellStatus = SHELL_INVALID_PARAMETER; 713a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } else { 714a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey Status = ShellOpenFileMetaArg((CHAR16*)ShellCommandLineGetRawValue(Package, 1), EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList); 715a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (FileList == NULL || IsListEmpty(&FileList->Link) || EFI_ERROR(Status)) { 716099e8ff5d2876b1d1606c3424114969946c15173Tapan Shah ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, L"cp", ShellCommandLineGetRawValue(Package, 1)); 717a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellStatus = SHELL_NOT_FOUND; 718a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } else { 719fbd2dfadfe6fb16ab7b49fca3764e05e65d97b8aQiu Shumin FullCwd = AllocateZeroPool(StrSize(Cwd) + sizeof(CHAR16)); 720fbd2dfadfe6fb16ab7b49fca3764e05e65d97b8aQiu Shumin ASSERT (FullCwd != NULL); 721fbd2dfadfe6fb16ab7b49fca3764e05e65d97b8aQiu Shumin StrCpyS(FullCwd, StrSize(Cwd)/sizeof(CHAR16)+1, Cwd); 722fbd2dfadfe6fb16ab7b49fca3764e05e65d97b8aQiu Shumin ShellStatus = ProcessValidateAndCopyFiles(FileList, FullCwd, SilentMode, RecursiveMode); 723fbd2dfadfe6fb16ab7b49fca3764e05e65d97b8aQiu Shumin FreePool(FullCwd); 724a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 725a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 726a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 727a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey break; 728a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey default: 729a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 730a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // Make a big list of all the files... 731a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 732a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey for (ParamCount--, LoopCounter = 1 ; LoopCounter < ParamCount && ShellStatus == SHELL_SUCCESS ; LoopCounter++) { 733a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (ShellGetExecutionBreakFlag()) { 734a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey break; 735a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 736a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey Status = ShellOpenFileMetaArg((CHAR16*)ShellCommandLineGetRawValue(Package, LoopCounter), EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList); 737a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (EFI_ERROR(Status) || FileList == NULL || IsListEmpty(&FileList->Link)) { 738099e8ff5d2876b1d1606c3424114969946c15173Tapan Shah ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, L"cp", ShellCommandLineGetRawValue(Package, LoopCounter)); 739a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellStatus = SHELL_NOT_FOUND; 740a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 741a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 742b2bf9735860994b4f4ae3904fd784bedcdd26da1jcarsey if (ShellStatus != SHELL_SUCCESS) { 743a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey Status = ShellCloseFileMetaArg(&FileList); 744b2bf9735860994b4f4ae3904fd784bedcdd26da1jcarsey } else { 745b2bf9735860994b4f4ae3904fd784bedcdd26da1jcarsey // 746b2bf9735860994b4f4ae3904fd784bedcdd26da1jcarsey // now copy them all... 747b2bf9735860994b4f4ae3904fd784bedcdd26da1jcarsey // 748b2bf9735860994b4f4ae3904fd784bedcdd26da1jcarsey if (FileList != NULL && !IsListEmpty(&FileList->Link)) { 749ab94587a7d2cd89695f9190420daceae0d2b7446jcarsey ShellStatus = ProcessValidateAndCopyFiles(FileList, PathCleanUpDirectories((CHAR16*)ShellCommandLineGetRawValue(Package, ParamCount)), SilentMode, RecursiveMode); 750b2bf9735860994b4f4ae3904fd784bedcdd26da1jcarsey Status = ShellCloseFileMetaArg(&FileList); 751b2bf9735860994b4f4ae3904fd784bedcdd26da1jcarsey if (EFI_ERROR(Status) && ShellStatus == SHELL_SUCCESS) { 752099e8ff5d2876b1d1606c3424114969946c15173Tapan Shah ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_FILE), gShellLevel2HiiHandle, L"cp", ShellCommandLineGetRawValue(Package, ParamCount), ShellStatus|MAX_BIT); 753b2bf9735860994b4f4ae3904fd784bedcdd26da1jcarsey ShellStatus = SHELL_ACCESS_DENIED; 754b2bf9735860994b4f4ae3904fd784bedcdd26da1jcarsey } 755a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 756a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 757a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey break; 758a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } // switch on parameter count 759a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 760a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (FileList != NULL) { 761a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellCloseFileMetaArg(&FileList); 762a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 763a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 764a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 765a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // free the command line package 766a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey // 767a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey ShellCommandLineFreeVarList (Package); 768a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 769a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 770a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey if (ShellGetExecutionBreakFlag()) { 771a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey return (SHELL_ABORTED); 772a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey } 773a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 774a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey return (ShellStatus); 775a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey} 776a405b86d274d32b92f69842bfb9a1ab143128f57jcarsey 777