]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellLevel2CommandsLib/Cp.c
Add code to check whether the pointer 'CorrectedPath' and 'FullPath' are NULL before...
[mirror_edk2.git] / ShellPkg / Library / UefiShellLevel2CommandsLib / Cp.c
index 876cb9d3ef8c0cacd0e99c60e88356ed8103b5e4..8fc263f6ba377ca79f24764a02612ea16a111759 100644 (file)
@@ -87,30 +87,18 @@ CopySingleFile(
   Response        = *Resp;\r
   List            = NULL;\r
   DestVolumeInfo  = NULL;\r
+  ShellStatus     = SHELL_SUCCESS;\r
 \r
-  ReadSize = PcdGet16(PcdShellFileOperationSize);\r
+  ReadSize = PcdGet32(PcdShellFileOperationSize);\r
   // Why bother copying a file to itself\r
   if (StrCmp(Source, Dest) == 0) {\r
     return (SHELL_SUCCESS);\r
   }\r
 \r
-  //\r
-  // Open destination file without create\r
-  //\r
-  Status = ShellOpenFileByName(Dest, &DestHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0);\r
-\r
-  //\r
-  // close file\r
-  //\r
-  if (DestHandle != NULL) {\r
-    ShellCloseFile(&DestHandle);\r
-    DestHandle   = NULL;\r
-  }\r
-\r
   //\r
   // if the destination file existed check response and possibly prompt user\r
   //\r
-  if (!EFI_ERROR(Status)) {\r
+  if (ShellFileExists(Dest) == EFI_SUCCESS) {\r
     if (Response == NULL && !SilentMode) {\r
       Status = ShellPromptForResponseHii(ShellPromptResponseTypeYesNoAllCancel, STRING_TOKEN (STR_GEN_DEST_EXIST_OVR), gShellLevel2HiiHandle, &Response);\r
     }\r
@@ -164,82 +152,95 @@ 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
+    Status = ShellDeleteFileByName(Dest);\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
-      //get file size of source file and freespace available on destination volume\r
-      //\r
-      ShellGetFileSize(SourceHandle, &SourceFileSize);\r
-      ShellGetFileSize(DestHandle, &DestFileSize);\r
+    //\r
+    // open source file\r
+    //\r
+    Status = ShellOpenFileByName(Source, &SourceHandle, EFI_FILE_MODE_READ, 0);\r
+    ASSERT_EFI_ERROR(Status);\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
+    //get file size of source file and freespace available on destination volume\r
+    //\r
+    ShellGetFileSize(SourceHandle, &SourceFileSize);\r
+    ShellGetFileSize(DestHandle, &DestFileSize);\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
+    //\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
-      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!= NULL && (DestVolumeInfo->FreeSpace < SourceFileSize)) {\r
       //\r
-      //check if enough space available on destination drive to complete copy\r
+      //not enough space on destination directory to copy file\r
       //\r
-      if (DestVolumeInfo!= NULL && (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
+      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 == PcdGet32(PcdShellFileOperationSize) && !EFI_ERROR(Status)) {\r
+        Status = ShellReadFile(SourceHandle, &ReadSize, Buffer);\r
+        if (!EFI_ERROR(Status)) {\r
           Status = ShellWriteFile(DestHandle, &ReadSize, Buffer);\r
+          if (EFI_ERROR(Status)) {\r
+            ShellStatus = (SHELL_STATUS) (Status & (~MAX_BIT));\r
+            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_CPY_WRITE_ERROR), gShellLevel2HiiHandle, Dest);\r
+            break;\r
+          }\r
+        } else {\r
+          ShellStatus = (SHELL_STATUS) (Status & (~MAX_BIT));\r
+          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_CPY_READ_ERROR), gShellLevel2HiiHandle, Source);\r
+          break;\r
         }\r
       }\r
-      SHELL_FREE_NON_NULL(DestVolumeInfo);\r
     }\r
-\r
+    SHELL_FREE_NON_NULL(DestVolumeInfo);\r
+  }\r
+  \r
   //\r
   // close files\r
   //\r
@@ -255,7 +256,7 @@ CopySingleFile(
   //\r
   // return\r
   //\r
-  return (SHELL_SUCCESS);\r
+  return ShellStatus;\r
 }\r
 \r
 /**\r
@@ -296,7 +297,6 @@ ValidateAndCopyFiles(
   VOID                      *Response;\r
   UINTN                     PathLen;\r
   CONST CHAR16              *Cwd;\r
-  CONST CHAR16              *TempLocation;\r
   UINTN                     NewSize;\r
 \r
   if (Resp == NULL) {\r
@@ -313,11 +313,6 @@ ValidateAndCopyFiles(
   ASSERT(FileList != NULL);\r
   ASSERT(DestDir  != NULL);\r
 \r
-  //\r
-  // We already verified that this was present.\r
-  //\r
-  ASSERT(Cwd      != NULL);\r
-\r
   //\r
   // If we are trying to copy multiple files... make sure we got a directory for the target...\r
   //\r
@@ -341,7 +336,7 @@ ValidateAndCopyFiles(
 \r
     NewSize =  StrSize(DestDir);\r
     NewSize += StrSize(Node->FullName);\r
-    NewSize += StrSize(Cwd);\r
+    NewSize += (Cwd == NULL)? 0 : StrSize(Cwd);\r
     if (NewSize > PathLen) {\r
       PathLen = NewSize;\r
     }\r
@@ -404,7 +399,12 @@ ValidateAndCopyFiles(
         //\r
         // simple copy of a single file\r
         //\r
-        StrCpy(DestPath, Cwd);\r
+        if (Cwd != NULL) {\r
+          StrCpy(DestPath, Cwd);\r
+        } else {\r
+          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, DestDir);\r
+          return (SHELL_INVALID_PARAMETER);\r
+        }\r
         if (DestPath[StrLen(DestPath)-1] != L'\\' && DestDir[0] != L'\\') {\r
           StrCat(DestPath, L"\\");\r
         } else if (DestPath[StrLen(DestPath)-1] == L'\\' && DestDir[0] == L'\\') {\r
@@ -423,15 +423,25 @@ ValidateAndCopyFiles(
       // Check for leading slash\r
       //\r
       if (DestDir[0] == L'\\') {\r
-          //\r
-          // Copy to the root of CWD\r
-          //\r
-        StrCpy(DestPath, Cwd);\r
+         //\r
+         // Copy to the root of CWD\r
+         //\r
+        if (Cwd != NULL) {\r
+          StrCpy(DestPath, Cwd);\r
+        } else {\r
+          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, DestDir);\r
+          return (SHELL_INVALID_PARAMETER);\r
+        }\r
         while (PathRemoveLastItem(DestPath));\r
         StrCat(DestPath, DestDir+1);\r
         StrCat(DestPath, Node->FileName);\r
       } else if (StrStr(DestDir, L":") == NULL) {\r
-        StrCpy(DestPath, Cwd);\r
+        if (Cwd != NULL) {\r
+          StrCpy(DestPath, Cwd);\r
+        } else {\r
+          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, DestDir);\r
+          return (SHELL_INVALID_PARAMETER);\r
+        }\r
         if (DestPath[StrLen(DestPath)-1] != L'\\' && DestDir[0] != L'\\') {\r
           StrCat(DestPath, L"\\");\r
         } else if (DestPath[StrLen(DestPath)-1] == L'\\' && DestDir[0] == L'\\') {\r
@@ -479,7 +489,7 @@ ValidateAndCopyFiles(
       break;\r
     }\r
 \r
-    if ((TempLocation = StrniCmp(Node->FullName, DestPath, StrLen(Node->FullName))) == 0\r
+    if ((StrniCmp(Node->FullName, DestPath, StrLen(Node->FullName)) == 0)\r
       && (DestPath[StrLen(Node->FullName)] == CHAR_NULL || DestPath[StrLen(Node->FullName)] == L'\\')\r
       ) {\r
       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_SD_SAME), gShellLevel2HiiHandle);\r
@@ -537,12 +547,14 @@ ProcessValidateAndCopyFiles(
 {\r
   SHELL_STATUS        ShellStatus;\r
   EFI_SHELL_FILE_INFO *List;\r
-  EFI_STATUS          Status;\r
   EFI_FILE_INFO       *FileInfo;\r
+  CHAR16              *FullName;\r
 \r
-  List = NULL;\r
+  List      = NULL;\r
+  FullName  = NULL;\r
+  FileInfo  = NULL;\r
 \r
-  Status = ShellOpenFileMetaArg((CHAR16*)DestDir, EFI_FILE_MODE_READ, &List);\r
+  ShellOpenFileMetaArg((CHAR16*)DestDir, EFI_FILE_MODE_READ, &List);\r
   if (List != NULL && List->Link.ForwardLink != List->Link.BackLink) {\r
     ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_MARG_ERROR), gShellLevel2HiiHandle, DestDir);\r
     ShellStatus = SHELL_INVALID_PARAMETER;\r
@@ -550,21 +562,23 @@ ProcessValidateAndCopyFiles(
   } else if (List != NULL) {\r
     ASSERT(((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink) != NULL);\r
     ASSERT(((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink)->FullName != NULL);\r
-    FileInfo    = NULL;\r
     FileInfo = gEfiShellProtocol->GetFileInfo(((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink)->Handle);\r
     ASSERT(FileInfo != NULL);\r
+    StrnCatGrow(&FullName, NULL, ((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink)->FullName, 0);\r
+    ShellCloseFileMetaArg(&List);\r
     if ((FileInfo->Attribute & EFI_FILE_READ_ONLY) == 0) {\r
-      ShellStatus = ValidateAndCopyFiles(FileList, ((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink)->FullName, SilentMode, RecursiveMode, NULL);\r
+      ShellStatus = ValidateAndCopyFiles(FileList, FullName, SilentMode, RecursiveMode, NULL);\r
     } else {\r
       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_DEST_ERROR), gShellLevel2HiiHandle);\r
       ShellStatus = SHELL_ACCESS_DENIED;\r
     }\r
-    SHELL_FREE_NON_NULL(FileInfo);\r
-    ShellCloseFileMetaArg(&List);\r
   } else {\r
-      ShellStatus = ValidateAndCopyFiles(FileList, DestDir, SilentMode, RecursiveMode, NULL);\r
+    ShellCloseFileMetaArg(&List);\r
+    ShellStatus = ValidateAndCopyFiles(FileList, DestDir, SilentMode, RecursiveMode, NULL);\r
   }\r
 \r
+  SHELL_FREE_NON_NULL(FileInfo);\r
+  SHELL_FREE_NON_NULL(FullName);\r
   return (ShellStatus);\r
 }\r
 \r