Esempio n. 1
0
File: Cp.c Progetto: jian-tian/UEFI
/**
  Validate and if successful copy all the files from the list into
  destination directory.

  @param[in] FileList       The list of files to copy.
  @param[in] DestDir        The directory to copy files to.
  @param[in] SilentMode     TRUE to eliminate screen output.
  @param[in] RecursiveMode  TRUE to copy directories.

  @retval SHELL_INVALID_PARAMETER   A parameter was invalid.
  @retval SHELL_SUCCESS             The operation was successful.
**/
SHELL_STATUS
EFIAPI
ProcessValidateAndCopyFiles(
    IN       EFI_SHELL_FILE_INFO  *FileList,
    IN CONST CHAR16               *DestDir,
    IN BOOLEAN                    SilentMode,
    IN BOOLEAN                    RecursiveMode
)
{
    SHELL_STATUS        ShellStatus;
    EFI_SHELL_FILE_INFO *List;
    EFI_FILE_INFO       *FileInfo;
    CHAR16              *FullName;

    List      = NULL;
    FullName  = NULL;
    FileInfo  = NULL;

    ShellOpenFileMetaArg((CHAR16*)DestDir, EFI_FILE_MODE_READ, &List);
    if (List != NULL && List->Link.ForwardLink != List->Link.BackLink) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_MARG_ERROR), gShellLevel2HiiHandle, DestDir);
        ShellStatus = SHELL_INVALID_PARAMETER;
        ShellCloseFileMetaArg(&List);
    } else if (List != NULL) {
        ASSERT(((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink) != NULL);
        ASSERT(((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink)->FullName != 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, FullName, SilentMode, RecursiveMode, NULL);
        } else {
            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_DEST_ERROR), gShellLevel2HiiHandle);
            ShellStatus = SHELL_ACCESS_DENIED;
        }
    } else {
        ShellCloseFileMetaArg(&List);
        ShellStatus = ValidateAndCopyFiles(FileList, DestDir, SilentMode, RecursiveMode, NULL);
    }

    SHELL_FREE_NON_NULL(FileInfo);
    SHELL_FREE_NON_NULL(FullName);
    return (ShellStatus);
}
Esempio n. 2
0
File: Cp.c Progetto: Cutty/edk2
/**
  Function to Copy one file to another location

  If the destination exists the user will be prompted and the result put into *resp

  @param[in] Source     pointer to source file name
  @param[in] Dest       pointer to destination file name
  @param[out] Resp      pointer to response from question.  Pass back on looped calling
  @param[in] SilentMode whether to run in quiet mode or not

  @retval SHELL_SUCCESS   The source file was copied to the destination
**/
SHELL_STATUS
EFIAPI
CopySingleFile(
  IN CONST CHAR16 *Source,
  IN CONST CHAR16 *Dest,
  OUT VOID        **Resp,
  IN BOOLEAN      SilentMode
  )
{
  VOID                  *Response;
  UINTN                 ReadSize;
  SHELL_FILE_HANDLE     SourceHandle;
  SHELL_FILE_HANDLE     DestHandle;
  EFI_STATUS            Status;
  VOID                  *Buffer;
  CHAR16                *TempName;
  UINTN                 Size;
  EFI_SHELL_FILE_INFO   *List;
  SHELL_STATUS          ShellStatus;
  UINT64                SourceFileSize;
  UINT64                DestFileSize;
  EFI_FILE_PROTOCOL     *DestVolumeFP;
  EFI_FILE_SYSTEM_INFO  *DestVolumeInfo;
  UINTN                 DestVolumeInfoSize;

  ASSERT(Resp != NULL);

  SourceHandle    = NULL;
  DestHandle      = NULL;
  Response        = *Resp;
  List            = NULL;
  DestVolumeInfo  = NULL;

  ReadSize = PcdGet16(PcdShellFileOperationSize);
  // Why bother copying a file to itself
  if (StrCmp(Source, Dest) == 0) {
    return (SHELL_SUCCESS);
  }

  //
  // 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 (Response == NULL && !SilentMode) {
      Status = ShellPromptForResponseHii(ShellPromptResponseTypeYesNoAllCancel, STRING_TOKEN (STR_GEN_DEST_EXIST_OVR), gShellLevel2HiiHandle, &Response);
    }
    //
    // possibly return based on response
    //
    if (!SilentMode) {
      switch (*(SHELL_PROMPT_RESPONSE*)Response) {
        case ShellPromptResponseNo:
          //
          // return success here so we dont stop the process
          //
          return (SHELL_SUCCESS);
        case ShellPromptResponseCancel:
          *Resp = Response;
          //
          // indicate to stop everything
          //
          return (SHELL_ABORTED);
        case ShellPromptResponseAll:
          *Resp = Response;
        case ShellPromptResponseYes:
          break;
        default:
          return SHELL_ABORTED;
      }
    }
  }

  if (ShellIsDirectory(Source) == EFI_SUCCESS) {
    Status = ShellCreateDirectory(Dest, &DestHandle);
    if (EFI_ERROR(Status)) {
      return (SHELL_ACCESS_DENIED);
    }

    //
    // Now copy all the files under the directory...
    //
    TempName    = NULL;
    Size        = 0;
    StrnCatGrow(&TempName, &Size, Source, 0);
    StrnCatGrow(&TempName, &Size, L"\\*", 0);
    if (TempName != NULL) {
      ShellOpenFileMetaArg((CHAR16*)TempName, EFI_FILE_MODE_READ, &List);
      *TempName = CHAR_NULL;
      StrnCatGrow(&TempName, &Size, Dest, 0);
      StrnCatGrow(&TempName, &Size, L"\\", 0);
      ShellStatus = ValidateAndCopyFiles(List, TempName, SilentMode, TRUE, Resp);
      ShellCloseFileMetaArg(&List);
      SHELL_FREE_NON_NULL(TempName);
      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);
      }

      //
      // open source file
      //
      Status = ShellOpenFileByName(Source, &SourceHandle, EFI_FILE_MODE_READ, 0);
      ASSERT_EFI_ERROR(Status);

      //
      //get file size of source file and freespace available on destination volume
      //
      ShellGetFileSize(SourceHandle, &SourceFileSize);
      ShellGetFileSize(DestHandle, &DestFileSize);

      //
      //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
          );
      }

      //
      //check if enough space available on destination drive to complete copy
      //
      if (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 == PcdGet16(PcdShellFileOperationSize) && !EFI_ERROR(Status)) {
          Status = ShellReadFile(SourceHandle, &ReadSize, Buffer);
          Status = ShellWriteFile(DestHandle, &ReadSize, Buffer);
        }
      }
      SHELL_FREE_NON_NULL(DestVolumeInfo);
    }

  //
  // close files
  //
  if (DestHandle != NULL) {
    ShellCloseFile(&DestHandle);
    DestHandle   = NULL;
  }
  if (SourceHandle != NULL) {
    ShellCloseFile(&SourceHandle);
    SourceHandle = NULL;
  }

  //
  // return
  //
  return (SHELL_SUCCESS);
}