diff options
author | Jaben Carsey <Jaben.carsey@intel.com> | 2013-08-21 17:32:16 +0000 |
---|---|---|
committer | jcarsey <jcarsey@6f19259b-4bc3-4df7-8a09-765794883524> | 2013-08-21 17:32:16 +0000 |
commit | ac8783c8b162b9a3b1e2da222cf6d088fcf63cfb (patch) | |
tree | 7cfc2c5e7d93e3d310284e4d60e978954394a72d /ShellPkg/Library | |
parent | 18e44b07d4c1667ad49169810e1f2835f3534d13 (diff) | |
download | edk2-platforms-ac8783c8b162b9a3b1e2da222cf6d088fcf63cfb.tar.xz |
ShellPkg: Fix file size error upon copy operation.
There was a case where an copy operation of a small file overwriting a larger file would not correctly remove the extra space in the old file. The resultant file would have the entire source file and then what remained of the original file.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jaben Carsey <Jaben.carsey@intel.com>
reviewed-by: El-Haj-Mahmoud, Samer <samer.el-haj-mahmoud@hp.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14584 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'ShellPkg/Library')
-rw-r--r-- | ShellPkg/Library/UefiShellLevel2CommandsLib/Cp.c | 150 |
1 files changed, 72 insertions, 78 deletions
diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Cp.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/Cp.c index 05f3844966..a8c1f6697e 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Cp.c +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Cp.c @@ -96,22 +96,9 @@ CopySingleFile( }
//
- // Open destination file without create
- //
- Status = ShellOpenFileByName(Dest, &DestHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0);
-
- //
- // close file
- //
- if (DestHandle != NULL) {
- ShellCloseFile(&DestHandle);
- DestHandle = NULL;
- }
-
- //
// if the destination file existed check response and possibly prompt user
//
- if (!EFI_ERROR(Status)) {
+ if (ShellFileExists(Dest) == EFI_SUCCESS) {
if (Response == NULL && !SilentMode) {
Status = ShellPromptForResponseHii(ShellPromptResponseTypeYesNoAllCancel, STRING_TOKEN (STR_GEN_DEST_EXIST_OVR), gShellLevel2HiiHandle, &Response);
}
@@ -165,81 +152,83 @@ CopySingleFile( Size = 0;
}
} else {
- //
- // open file with create enabled
- //
- Status = ShellOpenFileByName(Dest, &DestHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);
- if (EFI_ERROR(Status)) {
- return (SHELL_ACCESS_DENIED);
- }
+ Status = ShellDeleteFileByName(Dest);
- //
- // open source file
- //
- Status = ShellOpenFileByName(Source, &SourceHandle, EFI_FILE_MODE_READ, 0);
- ASSERT_EFI_ERROR(Status);
+ //
+ // open file with create enabled
+ //
+ Status = ShellOpenFileByName(Dest, &DestHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);
+ if (EFI_ERROR(Status)) {
+ return (SHELL_ACCESS_DENIED);
+ }
- //
- //get file size of source file and freespace available on destination volume
- //
- ShellGetFileSize(SourceHandle, &SourceFileSize);
- ShellGetFileSize(DestHandle, &DestFileSize);
+ //
+ // open source file
+ //
+ Status = ShellOpenFileByName(Source, &SourceHandle, EFI_FILE_MODE_READ, 0);
+ ASSERT_EFI_ERROR(Status);
- //
- //if the destination file already exists then it will be replaced, meaning the sourcefile effectively needs less storage space
- //
- if(DestFileSize < SourceFileSize){
- SourceFileSize -= DestFileSize;
- } else {
- SourceFileSize = 0;
- }
+ //
+ //get file size of source file and freespace available on destination volume
+ //
+ ShellGetFileSize(SourceHandle, &SourceFileSize);
+ ShellGetFileSize(DestHandle, &DestFileSize);
- //
- //get the system volume info to check the free space
- //
- DestVolumeFP = ConvertShellHandleToEfiFileProtocol(DestHandle);
- DestVolumeInfo = NULL;
- DestVolumeInfoSize = 0;
+ //
+ //if the destination file already exists then it will be replaced, meaning the sourcefile effectively needs less storage space
+ //
+ if(DestFileSize < SourceFileSize){
+ SourceFileSize -= DestFileSize;
+ } else {
+ SourceFileSize = 0;
+ }
+
+ //
+ //get the system volume info to check the free space
+ //
+ DestVolumeFP = ConvertShellHandleToEfiFileProtocol(DestHandle);
+ DestVolumeInfo = NULL;
+ DestVolumeInfoSize = 0;
+ Status = DestVolumeFP->GetInfo(
+ DestVolumeFP,
+ &gEfiFileSystemInfoGuid,
+ &DestVolumeInfoSize,
+ DestVolumeInfo
+ );
+
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ DestVolumeInfo = AllocateZeroPool(DestVolumeInfoSize);
Status = DestVolumeFP->GetInfo(
DestVolumeFP,
&gEfiFileSystemInfoGuid,
&DestVolumeInfoSize,
DestVolumeInfo
);
+ }
- if (Status == EFI_BUFFER_TOO_SMALL) {
- DestVolumeInfo = AllocateZeroPool(DestVolumeInfoSize);
- Status = DestVolumeFP->GetInfo(
- DestVolumeFP,
- &gEfiFileSystemInfoGuid,
- &DestVolumeInfoSize,
- DestVolumeInfo
- );
- }
-
+ //
+ //check if enough space available on destination drive to complete copy
+ //
+ if (DestVolumeInfo!= NULL && (DestVolumeInfo->FreeSpace < SourceFileSize)) {
//
- //check if enough space available on destination drive to complete copy
+ //not enough space on destination directory to copy file
//
- if (DestVolumeInfo!= NULL && (DestVolumeInfo->FreeSpace < SourceFileSize)) {
- //
- //not enough space on destination directory to copy file
- //
- SHELL_FREE_NON_NULL(DestVolumeInfo);
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_CPY_FAIL), gShellLevel2HiiHandle);
- return(SHELL_VOLUME_FULL);
- } else {
- //
- // copy data between files
- //
- Buffer = AllocateZeroPool(ReadSize);
- ASSERT(Buffer != NULL);
- while (ReadSize == PcdGet32(PcdShellFileOperationSize) && !EFI_ERROR(Status)) {
- Status = ShellReadFile(SourceHandle, &ReadSize, Buffer);
- Status = ShellWriteFile(DestHandle, &ReadSize, Buffer);
- }
- }
SHELL_FREE_NON_NULL(DestVolumeInfo);
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_CPY_FAIL), gShellLevel2HiiHandle);
+ return(SHELL_VOLUME_FULL);
+ } else {
+ //
+ // copy data between files
+ //
+ Buffer = AllocateZeroPool(ReadSize);
+ ASSERT(Buffer != NULL);
+ while (ReadSize == PcdGet32(PcdShellFileOperationSize) && !EFI_ERROR(Status)) {
+ Status = ShellReadFile(SourceHandle, &ReadSize, Buffer);
+ Status = ShellWriteFile(DestHandle, &ReadSize, Buffer);
+ }
}
+ SHELL_FREE_NON_NULL(DestVolumeInfo);
+ }
//
// close files
@@ -549,8 +538,10 @@ ProcessValidateAndCopyFiles( SHELL_STATUS ShellStatus;
EFI_SHELL_FILE_INFO *List;
EFI_FILE_INFO *FileInfo;
+ CHAR16 *FullName;
- List = NULL;
+ List = NULL;
+ FullName = NULL;
ShellOpenFileMetaArg((CHAR16*)DestDir, EFI_FILE_MODE_READ, &List);
if (List != NULL && List->Link.ForwardLink != List->Link.BackLink) {
@@ -563,18 +554,21 @@ ProcessValidateAndCopyFiles( FileInfo = NULL;
FileInfo = gEfiShellProtocol->GetFileInfo(((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink)->Handle);
ASSERT(FileInfo != NULL);
+ StrnCatGrow(&FullName, NULL, ((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink)->FullName, 0);
+ ShellCloseFileMetaArg(&List);
if ((FileInfo->Attribute & EFI_FILE_READ_ONLY) == 0) {
- ShellStatus = ValidateAndCopyFiles(FileList, ((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink)->FullName, SilentMode, RecursiveMode, NULL);
+ ShellStatus = ValidateAndCopyFiles(FileList, FullName, SilentMode, RecursiveMode, NULL);
} else {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_DEST_ERROR), gShellLevel2HiiHandle);
ShellStatus = SHELL_ACCESS_DENIED;
}
- SHELL_FREE_NON_NULL(FileInfo);
- ShellCloseFileMetaArg(&List);
} else {
+ ShellCloseFileMetaArg(&List);
ShellStatus = ValidateAndCopyFiles(FileList, DestDir, SilentMode, RecursiveMode, NULL);
}
+ SHELL_FREE_NON_NULL(FileInfo);
+ SHELL_FREE_NON_NULL(FullName);
return (ShellStatus);
}
|