]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ShellPkg: Fixes CP function to prevent copying of files if destination does not have...
authorjcarsey <jcarsey@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 12 Mar 2013 20:56:36 +0000 (20:56 +0000)
committerjcarsey <jcarsey@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 12 Mar 2013 20:56:36 +0000 (20:56 +0000)
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Matt Stanbro <Matthew.A.Stanbro@intel.com>
Reviewed-by: Jaben Carsey <Jaben.carsey@intel.com>
Reviewed-by: Erik Bjorge <erik.c.bjorge@intel.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14203 6f19259b-4bc3-4df7-8a09-765794883524

ShellPkg/Library/UefiShellLevel2CommandsLib/Cp.c
ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.uni

index 86ac960d4265871ba8ca30c59d404cd980159343..eb2b2cc5f35dc83a48bf25e44d11868faa470f22 100644 (file)
@@ -13,6 +13,8 @@
 **/\r
 \r
 #include "UefiShellLevel2CommandsLib.h"\r
+#include <Guid/FileSystemInfo.h>\r
+#include <Guid/FileSystemVolumeLabelInfo.h>\r
 \r
 /**\r
   Function to take a list of files to copy and a destination location and do\r
@@ -62,24 +64,29 @@ CopySingleFile(
   IN BOOLEAN      SilentMode\r
   )\r
 {\r
-  VOID                *Response;\r
-  UINTN               ReadSize;\r
-  SHELL_FILE_HANDLE   SourceHandle;\r
-  SHELL_FILE_HANDLE   DestHandle;\r
-  EFI_STATUS          Status;\r
-  VOID                *Buffer;\r
-  CHAR16              *TempName;\r
-  UINTN               Size;\r
-  EFI_SHELL_FILE_INFO *List;\r
-  SHELL_STATUS        ShellStatus;\r
-\r
+  VOID                  *Response;\r
+  UINTN                 ReadSize;\r
+  SHELL_FILE_HANDLE     SourceHandle;\r
+  SHELL_FILE_HANDLE     DestHandle;\r
+  EFI_STATUS            Status;\r
+  VOID                  *Buffer;\r
+  CHAR16                *TempName;\r
+  UINTN                 Size;\r
+  EFI_SHELL_FILE_INFO   *List;\r
+  SHELL_STATUS          ShellStatus;\r
+  UINT64                SourceFileSize;\r
+  UINT64                DestFileSize;\r
+  EFI_FILE_PROTOCOL     *DestVolumeFP;\r
+  EFI_FILE_SYSTEM_INFO  *DestVolumeInfo;\r
+  UINTN                 DestVolumeInfoSize;\r
 \r
   ASSERT(Resp != NULL);\r
 \r
-  SourceHandle  = NULL;\r
-  DestHandle    = NULL;\r
-  Response      = *Resp;\r
-  List          = NULL;\r
+  SourceHandle    = NULL;\r
+  DestHandle      = NULL;\r
+  Response        = *Resp;\r
+  List            = NULL;\r
+  DestVolumeInfo  = NULL;\r
 \r
   ReadSize = PcdGet16(PcdShellFileOperationSize);\r
   // Why bother copying a file to itself\r
@@ -143,7 +150,7 @@ CopySingleFile(
     // Now copy all the files under the directory...\r
     //\r
     TempName    = NULL;\r
-    Size          = 0;\r
+    Size        = 0;\r
     StrnCatGrow(&TempName, &Size, Source, 0);\r
     StrnCatGrow(&TempName, &Size, L"\\*", 0);\r
     if (TempName != NULL) {\r
@@ -157,31 +164,81 @@ CopySingleFile(
       Size = 0;\r
     }\r
   } else {\r
-    //\r
-    // open file with create enabled\r
-    //\r
-    Status = ShellOpenFileByName(Dest, &DestHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);\r
-    if (EFI_ERROR(Status)) {\r
-      return (SHELL_ACCESS_DENIED);\r
-    }\r
-\r
-    //\r
-    // open source file\r
-    //\r
-    Status = ShellOpenFileByName(Source, &SourceHandle, EFI_FILE_MODE_READ, 0);\r
-    ASSERT_EFI_ERROR(Status);\r
+      //\r
+      // open file with create enabled\r
+      //\r
+      Status = ShellOpenFileByName(Dest, &DestHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);\r
+      if (EFI_ERROR(Status)) {\r
+        return (SHELL_ACCESS_DENIED);\r
+      }\r
 \r
-    //\r
-    // copy data between files\r
-    //\r
-    Buffer = AllocateZeroPool(ReadSize);\r
-    ASSERT(Buffer != NULL);\r
-    while (ReadSize == PcdGet16(PcdShellFileOperationSize) && !EFI_ERROR(Status)) {\r
-      Status = ShellReadFile(SourceHandle, &ReadSize, Buffer);\r
+      //\r
+      // open source file\r
+      //\r
+      Status = ShellOpenFileByName(Source, &SourceHandle, EFI_FILE_MODE_READ, 0);\r
       ASSERT_EFI_ERROR(Status);\r
-      Status = ShellWriteFile(DestHandle, &ReadSize, Buffer);\r
+\r
+      //\r
+      //get file size of source file and freespace available on destination volume\r
+      //\r
+      ShellGetFileSize(SourceHandle, &SourceFileSize);\r
+      ShellGetFileSize(DestHandle, &DestFileSize);\r
+\r
+      //\r
+      //if the destination file already exists then it will be replaced, meaning the sourcefile effectively needs less storage space\r
+      //\r
+      if(DestFileSize < SourceFileSize){\r
+        SourceFileSize -= DestFileSize;\r
+      } else {\r
+        SourceFileSize = 0;\r
+      }\r
+\r
+      //\r
+      //get the system volume info to check the free space\r
+      //\r
+      DestVolumeFP = ConvertShellHandleToEfiFileProtocol(DestHandle);\r
+      DestVolumeInfo = NULL;\r
+      DestVolumeInfoSize = 0;\r
+      Status = DestVolumeFP->GetInfo(\r
+        DestVolumeFP,\r
+        &gEfiFileSystemInfoGuid,\r
+        &DestVolumeInfoSize,\r
+        DestVolumeInfo\r
+        );\r
+\r
+      if (Status == EFI_BUFFER_TOO_SMALL) {\r
+        DestVolumeInfo = AllocateZeroPool(DestVolumeInfoSize);\r
+        Status = DestVolumeFP->GetInfo(\r
+          DestVolumeFP,\r
+          &gEfiFileSystemInfoGuid,\r
+          &DestVolumeInfoSize,\r
+          DestVolumeInfo\r
+          );\r
+      }\r
+\r
+      //\r
+      //check if enough space available on destination drive to complete copy\r
+      //\r
+      if (DestVolumeInfo->FreeSpace < SourceFileSize) {\r
+        //\r
+        //not enough space on destination directory to copy file\r
+        //\r
+        SHELL_FREE_NON_NULL(DestVolumeInfo);\r
+        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_CPY_FAIL), gShellLevel2HiiHandle);\r
+        return(SHELL_VOLUME_FULL);\r
+      } else {\r
+        //\r
+        // copy data between files\r
+        //\r
+        Buffer = AllocateZeroPool(ReadSize);\r
+        ASSERT(Buffer != NULL);\r
+        while (ReadSize == PcdGet16(PcdShellFileOperationSize) && !EFI_ERROR(Status)) {\r
+          Status = ShellReadFile(SourceHandle, &ReadSize, Buffer);\r
+          Status = ShellWriteFile(DestHandle, &ReadSize, Buffer);\r
+        }\r
+      }\r
+      SHELL_FREE_NON_NULL(DestVolumeInfo);\r
     }\r
-  }\r
 \r
   //\r
   // close files\r
@@ -274,7 +331,7 @@ ValidateAndCopyFiles(
   for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&FileList->Link)\r
     ;  !IsNull(&FileList->Link, &Node->Link)\r
     ;  Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&FileList->Link, &Node->Link)\r
-   ){\r
+    ){\r
     //\r
     // skip the directory traversing stuff...\r
     //\r
@@ -326,7 +383,7 @@ ValidateAndCopyFiles(
   for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&FileList->Link)\r
     ;  !IsNull(&FileList->Link, &Node->Link)\r
     ;  Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&FileList->Link, &Node->Link)\r
-   ){\r
+    ){\r
     if (ShellGetExecutionBreakFlag()) {\r
       break;\r
     }\r
@@ -342,7 +399,7 @@ ValidateAndCopyFiles(
 \r
     if (FileList->Link.ForwardLink == FileList->Link.BackLink // 1 item\r
       && EFI_ERROR(ShellIsDirectory(DestDir))                 // not an existing directory\r
-     ) {\r
+      ) {\r
       if (StrStr(DestDir, L":") == NULL) {\r
         //\r
         // simple copy of a single file\r
@@ -366,9 +423,9 @@ ValidateAndCopyFiles(
       // Check for leading slash\r
       //\r
       if (DestDir[0] == L'\\') {\r
-         //\r
-         // Copy to the root of CWD\r
-         //\r
+          //\r
+          // Copy to the root of CWD\r
+          //\r
         StrCpy(DestPath, Cwd);\r
         while (PathRemoveLastItem(DestPath));\r
         StrCat(DestPath, DestDir+1);\r
@@ -411,7 +468,7 @@ ValidateAndCopyFiles(
     if ( !EFI_ERROR(ShellIsDirectory(Node->FullName))\r
       && !EFI_ERROR(ShellIsDirectory(DestPath))\r
       && StrniCmp(Node->FullName, DestPath, StrLen(DestPath)) == NULL\r
-     ){\r
+      ){\r
       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_SD_PARENT), gShellLevel2HiiHandle);\r
       ShellStatus = SHELL_INVALID_PARAMETER;\r
       break;\r
@@ -424,7 +481,7 @@ ValidateAndCopyFiles(
 \r
     if ((TempLocation = StrniCmp(Node->FullName, DestPath, StrLen(Node->FullName))) == 0\r
       && (DestPath[StrLen(Node->FullName)] == CHAR_NULL || DestPath[StrLen(Node->FullName)] == L'\\')\r
-     ) {\r
+      ) {\r
       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_SD_SAME), gShellLevel2HiiHandle);\r
       ShellStatus = SHELL_INVALID_PARAMETER;\r
       break;\r
@@ -454,6 +511,7 @@ ValidateAndCopyFiles(
   }\r
 \r
   return (ShellStatus);\r
+\r
 }\r
 \r
 /**\r
index c2020ca7f7bc46868f9ad4dfda38fa0da5d1db89..08372d5ba36452e71fa8f2fe76b39a039dfd4111 100644 (file)
Binary files a/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.uni and b/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.uni differ