/** @file
  Main file for cp shell level 2 function.

  (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "UefiShellLevel2CommandsLib.h"
#include <Guid/FileSystemInfo.h>
#include <Guid/FileSystemVolumeLabelInfo.h>

/**
  Function to take a list of files to copy and a destination location and do
  the verification and copying of those files to that location.  This function
  will report any errors to the user and halt.

  @param[in] FileList           A LIST_ENTRY* based list of files to move.
  @param[in] DestDir            The destination location.
  @param[in] SilentMode         TRUE to eliminate screen output.
  @param[in] RecursiveMode      TRUE to copy directories.
  @param[in] Resp               The response to the overwrite query (if always).

  @retval SHELL_SUCCESS             the files were all moved.
  @retval SHELL_INVALID_PARAMETER   a parameter was invalid
  @retval SHELL_SECURITY_VIOLATION  a security violation ocurred
  @retval SHELL_WRITE_PROTECTED     the destination was write protected
  @retval SHELL_OUT_OF_RESOURCES    a memory allocation failed
**/
SHELL_STATUS
ValidateAndCopyFiles (
  IN CONST EFI_SHELL_FILE_INFO  *FileList,
  IN CONST CHAR16               *DestDir,
  IN BOOLEAN                    SilentMode,
  IN BOOLEAN                    RecursiveMode,
  IN VOID                       **Resp
  );

/**
  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
  @param[in] CmdName    Source command name requesting single file copy

  @retval SHELL_SUCCESS   The source file was copied to the destination
**/
SHELL_STATUS
CopySingleFile (
  IN CONST CHAR16  *Source,
  IN CONST CHAR16  *Dest,
  OUT VOID         **Resp,
  IN BOOLEAN       SilentMode,
  IN CONST CHAR16  *CmdName
  )
{
  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;
  ShellStatus    = SHELL_SUCCESS;

  ReadSize = PcdGet32 (PcdShellFileOperationSize);
  // Why bother copying a file to itself
  if (StrCmp (Source, Dest) == 0) {
    return (SHELL_SUCCESS);
  }

  //
  // if the destination file existed check response and possibly prompt user
  //
  if (ShellFileExists (Dest) == EFI_SUCCESS) {
    if ((Response == NULL) && !SilentMode) {
      Status = ShellPromptForResponseHii (ShellPromptResponseTypeYesNoAllCancel, STRING_TOKEN (STR_GEN_DEST_EXIST_OVR), gShellLevel2HiiHandle, &Response);
    }

    //
    // possibly return based on response
    //
    if (!SilentMode) {
      if (Response == NULL) {
        return SHELL_ABORTED;
      }

      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)) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_CP_DEST_DIR_FAIL), gShellLevel2HiiHandle, CmdName, Dest);
      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 {
    Status = ShellDeleteFileByName (Dest);

    //
    // 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)) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_CP_DEST_OPEN_FAIL), gShellLevel2HiiHandle, CmdName, Dest);
      return (SHELL_ACCESS_DENIED);
    }

    //
    // open source file
    //
    Status = ShellOpenFileByName (Source, &SourceHandle, EFI_FILE_MODE_READ, 0);
    if (EFI_ERROR (Status)) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_CP_SRC_OPEN_FAIL), gShellLevel2HiiHandle, CmdName, Source);
      return (SHELL_ACCESS_DENIED);
    }

    //
    // 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);
      if (DestVolumeInfo == NULL) {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_OUT_MEM), gShellLevel2HiiHandle, L"cp");
        ShellStatus = SHELL_OUT_OF_RESOURCES;
        goto Done;
      }

      Status = DestVolumeFP->GetInfo (
                               DestVolumeFP,
                               &gEfiFileSystemInfoGuid,
                               &DestVolumeInfoSize,
                               DestVolumeInfo
                               );
    }

    //
    // check if enough space available on destination drive to complete copy
    //
    if ((DestVolumeInfo != NULL) && (DestVolumeInfo->FreeSpace < SourceFileSize)) {
      //
      // not enough space on destination directory to copy file
      //
      SHELL_FREE_NON_NULL (DestVolumeInfo);
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_CPY_FAIL), gShellLevel2HiiHandle, CmdName);
      return (SHELL_VOLUME_FULL);
    } else {
      //
      // copy data between files
      //
      Buffer = AllocateZeroPool (ReadSize);
      if (Buffer == NULL) {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_OUT_MEM), gShellLevel2HiiHandle, CmdName);
        return SHELL_OUT_OF_RESOURCES;
      }

      while (ReadSize == PcdGet32 (PcdShellFileOperationSize) && !EFI_ERROR (Status)) {
        Status = ShellReadFile (SourceHandle, &ReadSize, Buffer);
        if (!EFI_ERROR (Status)) {
          Status = ShellWriteFile (DestHandle, &ReadSize, Buffer);
          if (EFI_ERROR (Status)) {
            ShellStatus = (SHELL_STATUS)(Status & (~MAX_BIT));
            ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_CPY_WRITE_ERROR), gShellLevel2HiiHandle, CmdName, Dest);
            break;
          }
        } else {
          ShellStatus = (SHELL_STATUS)(Status & (~MAX_BIT));
          ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_CPY_READ_ERROR), gShellLevel2HiiHandle, CmdName, Source);
          break;
        }
      }

      FreePool (Buffer);
    }

    SHELL_FREE_NON_NULL (DestVolumeInfo);
  }

Done:
  //
  // close files
  //
  if (DestHandle != NULL) {
    ShellCloseFile (&DestHandle);
    DestHandle = NULL;
  }

  if (SourceHandle != NULL) {
    ShellCloseFile (&SourceHandle);
    SourceHandle = NULL;
  }

  //
  // return
  //
  return ShellStatus;
}

/**
  function to take a list of files to copy and a destination location and do
  the verification and copying of those files to that location.  This function
  will report any errors to the user and halt.

  The key is to have this function called ONLY once.  this allows for the parameter
  verification to happen correctly.

  @param[in] FileList           A LIST_ENTRY* based list of files to move.
  @param[in] DestDir            The destination location.
  @param[in] SilentMode         TRUE to eliminate screen output.
  @param[in] RecursiveMode      TRUE to copy directories.
  @param[in] Resp               The response to the overwrite query (if always).

  @retval SHELL_SUCCESS             the files were all moved.
  @retval SHELL_INVALID_PARAMETER   a parameter was invalid
  @retval SHELL_SECURITY_VIOLATION  a security violation ocurred
  @retval SHELL_WRITE_PROTECTED     the destination was write protected
  @retval SHELL_OUT_OF_RESOURCES    a memory allocation failed
**/
SHELL_STATUS
ValidateAndCopyFiles (
  IN CONST EFI_SHELL_FILE_INFO  *FileList,
  IN CONST CHAR16               *DestDir,
  IN BOOLEAN                    SilentMode,
  IN BOOLEAN                    RecursiveMode,
  IN VOID                       **Resp
  )
{
  CHAR16                     *HiiOutput;
  CHAR16                     *HiiResultOk;
  CONST EFI_SHELL_FILE_INFO  *Node;
  SHELL_STATUS               ShellStatus;
  EFI_STATUS                 Status;
  CHAR16                     *DestPath;
  VOID                       *Response;
  UINTN                      PathSize;
  CONST CHAR16               *Cwd;
  UINTN                      NewSize;
  CHAR16                     *CleanFilePathStr;

  if (Resp == NULL) {
    Response = NULL;
  } else {
    Response = *Resp;
  }

  DestPath         = NULL;
  ShellStatus      = SHELL_SUCCESS;
  PathSize         = 0;
  Cwd              = ShellGetCurrentDir (NULL);
  CleanFilePathStr = NULL;

  ASSERT (FileList != NULL);
  ASSERT (DestDir  != NULL);

  Status = ShellLevel2StripQuotes (DestDir, &CleanFilePathStr);
  if (EFI_ERROR (Status)) {
    if (Status == EFI_OUT_OF_RESOURCES) {
      return SHELL_OUT_OF_RESOURCES;
    } else {
      return SHELL_INVALID_PARAMETER;
    }
  }

  ASSERT (CleanFilePathStr != NULL);

  //
  // If we are trying to copy multiple files... make sure we got a directory for the target...
  //
  if (EFI_ERROR (ShellIsDirectory (CleanFilePathStr)) && (FileList->Link.ForwardLink != FileList->Link.BackLink)) {
    //
    // Error for destination not a directory
    //
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_NOT_DIR), gShellLevel2HiiHandle, L"cp", CleanFilePathStr);
    FreePool (CleanFilePathStr);
    return (SHELL_INVALID_PARAMETER);
  }

  for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link)
       ; !IsNull (&FileList->Link, &Node->Link)
       ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&FileList->Link, &Node->Link)
       )
  {
    //
    // skip the directory traversing stuff...
    //
    if (IsDotOrDotDot (Node->FileName)) {
      continue;
    }

    NewSize  =  StrSize (CleanFilePathStr);
    NewSize += StrSize (Node->FullName);
    NewSize += (Cwd == NULL) ? 0 : (StrSize (Cwd) + sizeof (CHAR16));
    if (NewSize > PathSize) {
      PathSize = NewSize;
    }

    //
    // Make sure got -r if required
    //
    if (!RecursiveMode && !EFI_ERROR (ShellIsDirectory (Node->FullName))) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_CP_DIR_REQ), gShellLevel2HiiHandle, L"cp");
      FreePool (CleanFilePathStr);
      return (SHELL_INVALID_PARAMETER);
    }

    //
    // make sure got dest as dir if needed
    //
    if (!EFI_ERROR (ShellIsDirectory (Node->FullName)) && EFI_ERROR (ShellIsDirectory (CleanFilePathStr))) {
      //
      // Error for destination not a directory
      //
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_NOT_DIR), gShellLevel2HiiHandle, L"cp", CleanFilePathStr);
      FreePool (CleanFilePathStr);
      return (SHELL_INVALID_PARAMETER);
    }
  }

  HiiOutput   = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_CP_OUTPUT), NULL);
  HiiResultOk = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_GEN_RES_OK), NULL);
  DestPath    = AllocateZeroPool (PathSize);

  if ((DestPath == NULL) || (HiiOutput == NULL) || (HiiResultOk == NULL)) {
    SHELL_FREE_NON_NULL (DestPath);
    SHELL_FREE_NON_NULL (HiiOutput);
    SHELL_FREE_NON_NULL (HiiResultOk);
    FreePool (CleanFilePathStr);
    return (SHELL_OUT_OF_RESOURCES);
  }

  //
  // Go through the list of files to copy...
  //
  for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link)
       ; !IsNull (&FileList->Link, &Node->Link)
       ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&FileList->Link, &Node->Link)
       )
  {
    if (ShellGetExecutionBreakFlag ()) {
      break;
    }

    ASSERT (Node->FileName != NULL);
    ASSERT (Node->FullName != NULL);

    //
    // skip the directory traversing stuff...
    //
    if (IsDotOrDotDot (Node->FileName)) {
      continue;
    }

    if (  (FileList->Link.ForwardLink == FileList->Link.BackLink) // 1 item
       && EFI_ERROR (ShellIsDirectory (CleanFilePathStr))         // not an existing directory
          )
    {
      if (StrStr (CleanFilePathStr, L":") == NULL) {
        //
        // simple copy of a single file
        //
        if (Cwd != NULL) {
          StrCpyS (DestPath, PathSize / sizeof (CHAR16), Cwd);
          StrCatS (DestPath, PathSize / sizeof (CHAR16), L"\\");
        } else {
          ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, L"cp", CleanFilePathStr);
          FreePool (CleanFilePathStr);
          return (SHELL_INVALID_PARAMETER);
        }

        if ((DestPath[StrLen (DestPath)-1] != L'\\') && (CleanFilePathStr[0] != L'\\')) {
          StrCatS (DestPath, PathSize / sizeof (CHAR16), L"\\");
        } else if ((DestPath[StrLen (DestPath)-1] == L'\\') && (CleanFilePathStr[0] == L'\\')) {
          ((CHAR16 *)DestPath)[StrLen (DestPath)-1] = CHAR_NULL;
        }

        StrCatS (DestPath, PathSize/sizeof (CHAR16), CleanFilePathStr);
      } else {
        StrCpyS (DestPath, PathSize/sizeof (CHAR16), CleanFilePathStr);
      }
    } else {
      //
      // we have multiple files or a directory in the DestDir
      //

      //
      // Check for leading slash
      //
      if (CleanFilePathStr[0] == L'\\') {
        //
        // Copy to the root of CWD
        //
        if (Cwd != NULL) {
          StrCpyS (DestPath, PathSize/sizeof (CHAR16), Cwd);
          StrCatS (DestPath, PathSize/sizeof (CHAR16), L"\\");
        } else {
          ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, L"cp", CleanFilePathStr);
          FreePool (CleanFilePathStr);
          return (SHELL_INVALID_PARAMETER);
        }

        while (PathRemoveLastItem (DestPath)) {
        }

        StrCatS (DestPath, PathSize/sizeof (CHAR16), CleanFilePathStr+1);
        StrCatS (DestPath, PathSize/sizeof (CHAR16), Node->FileName);
      } else if (StrStr (CleanFilePathStr, L":") == NULL) {
        if (Cwd != NULL) {
          StrCpyS (DestPath, PathSize/sizeof (CHAR16), Cwd);
          StrCatS (DestPath, PathSize/sizeof (CHAR16), L"\\");
        } else {
          ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, L"cp", CleanFilePathStr);
          FreePool (CleanFilePathStr);
          return (SHELL_INVALID_PARAMETER);
        }

        if ((DestPath[StrLen (DestPath)-1] != L'\\') && (CleanFilePathStr[0] != L'\\')) {
          StrCatS (DestPath, PathSize/sizeof (CHAR16), L"\\");
        } else if ((DestPath[StrLen (DestPath)-1] == L'\\') && (CleanFilePathStr[0] == L'\\')) {
          ((CHAR16 *)DestPath)[StrLen (DestPath)-1] = CHAR_NULL;
        }

        StrCatS (DestPath, PathSize/sizeof (CHAR16), CleanFilePathStr);
        if ((CleanFilePathStr[StrLen (CleanFilePathStr)-1] != L'\\') && (Node->FileName[0] != L'\\')) {
          StrCatS (DestPath, PathSize/sizeof (CHAR16), L"\\");
        } else if ((CleanFilePathStr[StrLen (CleanFilePathStr)-1] == L'\\') && (Node->FileName[0] == L'\\')) {
          ((CHAR16 *)DestPath)[StrLen (DestPath)-1] = CHAR_NULL;
        }

        StrCatS (DestPath, PathSize/sizeof (CHAR16), Node->FileName);
      } else {
        StrCpyS (DestPath, PathSize/sizeof (CHAR16), CleanFilePathStr);
        if ((CleanFilePathStr[StrLen (CleanFilePathStr)-1] != L'\\') && (Node->FileName[0] != L'\\')) {
          StrCatS (DestPath, PathSize/sizeof (CHAR16), L"\\");
        } else if ((CleanFilePathStr[StrLen (CleanFilePathStr)-1] == L'\\') && (Node->FileName[0] == L'\\')) {
          ((CHAR16 *)CleanFilePathStr)[StrLen (CleanFilePathStr)-1] = CHAR_NULL;
        }

        StrCatS (DestPath, PathSize/sizeof (CHAR16), Node->FileName);
      }
    }

    //
    // Make sure the path exists
    //
    if (EFI_ERROR (VerifyIntermediateDirectories (DestPath))) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_CP_DIR_WNF), gShellLevel2HiiHandle, L"cp", DestPath);
      ShellStatus = SHELL_DEVICE_ERROR;
      break;
    }

    if (  !EFI_ERROR (ShellIsDirectory (Node->FullName))
       && !EFI_ERROR (ShellIsDirectory (DestPath))
       && (StrniCmp (Node->FullName, DestPath, StrLen (DestPath)) == 0)
          )
    {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_CP_SD_PARENT), gShellLevel2HiiHandle, L"cp");
      ShellStatus = SHELL_INVALID_PARAMETER;
      break;
    }

    if (StringNoCaseCompare (&Node->FullName, &DestPath) == 0) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_CP_SD_SAME), gShellLevel2HiiHandle, L"cp");
      ShellStatus = SHELL_INVALID_PARAMETER;
      break;
    }

    if (  (StrniCmp (Node->FullName, DestPath, StrLen (Node->FullName)) == 0)
       && ((DestPath[StrLen (Node->FullName)] == CHAR_NULL) || (DestPath[StrLen (Node->FullName)] == L'\\'))
          )
    {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_CP_SD_SAME), gShellLevel2HiiHandle, L"cp");
      ShellStatus = SHELL_INVALID_PARAMETER;
      break;
    }

    PathCleanUpDirectories (DestPath);

    if (!SilentMode) {
      ShellPrintDefaultEx (HiiOutput, Node->FullName, DestPath);
    }

    //
    // copy single file...
    //
    ShellStatus = CopySingleFile (Node->FullName, DestPath, &Response, SilentMode, L"cp");
    if (ShellStatus != SHELL_SUCCESS) {
      break;
    }
  }

  if ((ShellStatus == SHELL_SUCCESS) && (Resp == NULL)) {
    ShellPrintDefaultEx (L"%s", HiiResultOk);
  }

  SHELL_FREE_NON_NULL (DestPath);
  SHELL_FREE_NON_NULL (HiiOutput);
  SHELL_FREE_NON_NULL (HiiResultOk);
  SHELL_FREE_NON_NULL (CleanFilePathStr);
  if (Resp == NULL) {
    SHELL_FREE_NON_NULL (Response);
  }

  return (ShellStatus);
}

/**
  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
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)) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_MARG_ERROR), gShellLevel2HiiHandle, L"cp", 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 {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_CP_DEST_ERROR), gShellLevel2HiiHandle, L"cp");
      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);
}

STATIC CONST SHELL_PARAM_ITEM  ParamList[] = {
  { L"-r", TypeFlag },
  { L"-q", TypeFlag },
  { NULL,  TypeMax  }
};

/** Main function of the 'Cp' command.

  @param[in] Package    List of input parameter for the command.
**/
STATIC
SHELL_STATUS
MainCmdCp (
  LIST_ENTRY  *Package
  )
{
  EFI_STATUS           Status;
  SHELL_STATUS         ShellStatus;
  UINTN                ParamCount;
  UINTN                LoopCounter;
  EFI_SHELL_FILE_INFO  *FileList;
  BOOLEAN              SilentMode;
  BOOLEAN              RecursiveMode;
  CONST CHAR16         *Cwd;
  CHAR16               *FullCwd;

  ShellStatus = SHELL_SUCCESS;
  ParamCount  = 0;
  FileList    = NULL;

  //
  // check for "-?"
  //
  if (ShellCommandLineGetFlag (Package, L"-?")) {
    ASSERT (FALSE);
  }

  //
  // Initialize SilentMode and RecursiveMode
  //
  if (gEfiShellProtocol->BatchIsActive ()) {
    SilentMode = TRUE;
  } else {
    SilentMode = ShellCommandLineGetFlag (Package, L"-q");
  }

  RecursiveMode = ShellCommandLineGetFlag (Package, L"-r");

  switch (ParamCount = ShellCommandLineGetCount (Package)) {
    case 0:
    case 1:
      //
      // we have insufficient parameters
      //
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"cp");
      ShellStatus = SHELL_INVALID_PARAMETER;
      break;
    case 2:
      //
      // must have valid CWD for single parameter...
      //
      Cwd = ShellGetCurrentDir (NULL);
      if (Cwd == NULL) {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"cp");
        ShellStatus = SHELL_INVALID_PARAMETER;
      } else {
        Status = ShellOpenFileMetaArg ((CHAR16 *)ShellCommandLineGetRawValue (Package, 1), EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList);
        if ((FileList == NULL) || IsListEmpty (&FileList->Link) || EFI_ERROR (Status)) {
          ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, L"cp", ShellCommandLineGetRawValue (Package, 1));
          ShellStatus = SHELL_NOT_FOUND;
        } else {
          FullCwd = AllocateZeroPool (StrSize (Cwd) + sizeof (CHAR16));
          if (FullCwd == NULL) {
            ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_OUT_MEM), gShellLevel2HiiHandle, L"cp");
            ShellStatus = SHELL_OUT_OF_RESOURCES;
          } else {
            StrCpyS (FullCwd, StrSize (Cwd) / sizeof (CHAR16) + 1, Cwd);
            ShellStatus = ProcessValidateAndCopyFiles (FileList, FullCwd, SilentMode, RecursiveMode);
            FreePool (FullCwd);
          }
        }
      }

      break;
    default:
      //
      // Make a big list of all the files...
      //
      for (ParamCount--, LoopCounter = 1; LoopCounter < ParamCount && ShellStatus == SHELL_SUCCESS; LoopCounter++) {
        if (ShellGetExecutionBreakFlag ()) {
          break;
        }

        Status = ShellOpenFileMetaArg ((CHAR16 *)ShellCommandLineGetRawValue (Package, LoopCounter), EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList);
        if (EFI_ERROR (Status) || (FileList == NULL) || IsListEmpty (&FileList->Link)) {
          ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, L"cp", ShellCommandLineGetRawValue (Package, LoopCounter));
          ShellStatus = SHELL_NOT_FOUND;
        }
      }

      if (ShellStatus != SHELL_SUCCESS) {
        Status = ShellCloseFileMetaArg (&FileList);
      } else {
        //
        // now copy them all...
        //
        if ((FileList != NULL) && !IsListEmpty (&FileList->Link)) {
          ShellStatus = ProcessValidateAndCopyFiles (FileList, PathCleanUpDirectories ((CHAR16 *)ShellCommandLineGetRawValue (Package, ParamCount)), SilentMode, RecursiveMode);
          Status      = ShellCloseFileMetaArg (&FileList);
          if (EFI_ERROR (Status) && (ShellStatus == SHELL_SUCCESS)) {
            ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_ERR_FILE), gShellLevel2HiiHandle, L"cp", ShellCommandLineGetRawValue (Package, ParamCount), ShellStatus|MAX_BIT);
            ShellStatus = SHELL_ACCESS_DENIED;
          }
        }
      }

      break;
  } // switch on parameter count

  if (FileList != NULL) {
    ShellCloseFileMetaArg (&FileList);
  }

  return ShellStatus;
}

/**
  Function for 'cp' command.

  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
**/
SHELL_STATUS
EFIAPI
ShellCommandRunCp (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS    Status;
  LIST_ENTRY    *Package;
  CHAR16        *ProblemParam;
  SHELL_STATUS  ShellStatus;

  ProblemParam = NULL;
  ShellStatus  = SHELL_SUCCESS;

  //
  // initialize the shell lib (we must be in non-auto-init...)
  //
  Status = ShellInitialize ();
  ASSERT_EFI_ERROR (Status);

  Status = CommandInit ();
  ASSERT_EFI_ERROR (Status);

  //
  // parse the command line
  //
  Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
  if (EFI_ERROR (Status)) {
    if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"cp", ProblemParam);
      FreePool (ProblemParam);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      ASSERT (FALSE);
    }

    return ShellStatus;
  }

  ShellStatus = MainCmdCp (Package);

  //
  // free the command line package
  //
  ShellCommandLineFreeVarList (Package);

  if (ShellGetExecutionBreakFlag ()) {
    return (SHELL_ABORTED);
  }

  return (ShellStatus);
}
