/** @file
  Main file for mv shell level 2 function.

  (C) Copyright 2013-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"

/**
  function to determine if a move is between file systems.

  @param FullName [in]    The name of the file to move.
  @param Cwd      [in]    The current working directory
  @param DestPath [in]    The target location to move to

  @retval TRUE            The move is across file system.
  @retval FALSE           The move is within a file system.
**/
BOOLEAN
IsBetweenFileSystem (
  IN CONST CHAR16  *FullName,
  IN CONST CHAR16  *Cwd,
  IN CONST CHAR16  *DestPath
  )
{
  CHAR16  *Test;
  CHAR16  *Test1;
  UINTN   Result;

  Test = StrStr (FullName, L":");
  if ((Test == NULL) && (Cwd != NULL)) {
    Test = StrStr (Cwd, L":");
  }

  Test1 = StrStr (DestPath, L":");
  if ((Test1 == NULL) && (Cwd != NULL)) {
    Test1 = StrStr (Cwd, L":");
  }

  if ((Test1 != NULL) && (Test != NULL)) {
    *Test  = CHAR_NULL;
    *Test1 = CHAR_NULL;
    Result = StringNoCaseCompare (&FullName, &DestPath);
    *Test  = L':';
    *Test1 = L':';
    if (Result != 0) {
      return (TRUE);
    }
  }

  return (FALSE);
}

/**
  function to determine if SrcPath is valid to mv.

  if SrcPath equal CWD then it's invalid.
  if SrcPath is the parent path of CWD then it's invalid.
  is SrcPath is NULL return FALSE.

  if CwdPath is NULL then ASSERT()

  @param SrcPath  [in]    The source path.
  @param CwdPath  [in]    The current working directory.

  @retval TRUE            The source path is valid.
  @retval FALSE           The source path is invalid.
**/
BOOLEAN
IsSoucePathValid (
  IN CONST CHAR16  *SrcPath,
  IN CONST CHAR16  *CwdPath
  )
{
  CHAR16   *SrcPathBuffer;
  CHAR16   *CwdPathBuffer;
  BOOLEAN  Ret;

  ASSERT (CwdPath != NULL);
  if (SrcPath == NULL) {
    return FALSE;
  }

  Ret = TRUE;

  SrcPathBuffer = AllocateCopyPool (StrSize (SrcPath), SrcPath);
  if (SrcPathBuffer == NULL) {
    return FALSE;
  }

  CwdPathBuffer = AllocateCopyPool (StrSize (CwdPath), CwdPath);
  if (CwdPathBuffer == NULL) {
    FreePool (SrcPathBuffer);
    return FALSE;
  }

  gUnicodeCollation->StrUpr (gUnicodeCollation, SrcPathBuffer);
  gUnicodeCollation->StrUpr (gUnicodeCollation, CwdPathBuffer);

  if (SrcPathBuffer[StrLen (SrcPathBuffer) -1] == L'\\') {
    SrcPathBuffer[StrLen (SrcPathBuffer) - 1] = CHAR_NULL;
  }

  if (CwdPathBuffer[StrLen (CwdPathBuffer) - 1] == L'\\') {
    CwdPathBuffer[StrLen (CwdPathBuffer) - 1] = CHAR_NULL;
  }

  if ((StrCmp (CwdPathBuffer, SrcPathBuffer) == 0) ||
      ((StrStr (CwdPathBuffer, SrcPathBuffer) == CwdPathBuffer) &&
       (CwdPathBuffer[StrLen (SrcPathBuffer)] == L'\\'))
      )
  {
    Ret = FALSE;
  }

  FreePool (SrcPathBuffer);
  FreePool (CwdPathBuffer);

  return Ret;
}

/**
  Function to validate that moving a specific file (FileName) to a specific
  location (DestPath) is valid.

  This function will verify that the destination is not a subdirectory of
  FullName, that the Current working Directory is not being moved, and that
  the directory is not read only.

  if the move is invalid this function will report the error to StdOut.

  @param SourcePath [in]    The name of the file to move.
  @param Cwd        [in]    The current working directory
  @param DestPath   [in]    The target location to move to
  @param Attribute  [in]    The Attribute of the file
  @param DestAttr   [in]    The Attribute of the destination
  @param FileStatus [in]    The Status of the file when opened

  @retval TRUE        The move is valid
  @retval FALSE       The move is not
**/
BOOLEAN
IsValidMove (
  IN CONST CHAR16      *SourcePath,
  IN CONST CHAR16      *Cwd,
  IN CONST CHAR16      *DestPath,
  IN CONST UINT64      Attribute,
  IN CONST UINT64      DestAttr,
  IN CONST EFI_STATUS  FileStatus
  )
{
  CHAR16  *DestPathCopy;
  CHAR16  *DestPathWalker;
  UINTN   WalkerLen;

  if ((Cwd != NULL) && ((Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY)) {
    if (!IsSoucePathValid (SourcePath, Cwd)) {
      //
      // Invalid move
      //
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_MV_INV_CWD), gShellLevel2HiiHandle);
      return FALSE;
    }
  }

  //
  // invalid to move read only or move to a read only destination
  //
  if (  ((Attribute & EFI_FILE_READ_ONLY) != 0)
     || (FileStatus == EFI_WRITE_PROTECTED)
     || ((DestAttr & EFI_FILE_READ_ONLY) != 0)
        )
  {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_MV_INV_RO), gShellLevel2HiiHandle, SourcePath);
    return (FALSE);
  }

  DestPathCopy = AllocateCopyPool (StrSize (DestPath), DestPath);
  if (DestPathCopy == NULL) {
    return (FALSE);
  }

  for (DestPathWalker = DestPathCopy; *DestPathWalker == L'\\'; DestPathWalker++) {
  }

  WalkerLen = StrLen (DestPathWalker);
  while ((WalkerLen > 0) && (DestPathWalker[WalkerLen - 1] == L'\\')) {
    DestPathWalker[WalkerLen - 1] = CHAR_NULL;
    WalkerLen--;
  }

  ASSERT (DestPathWalker != NULL);
  ASSERT (SourcePath   != NULL);

  //
  // If they're the same, or if source is "above" dest on file path tree
  //
  if ((StringNoCaseCompare (&DestPathWalker, &SourcePath) == 0) ||
      ((StrStr (DestPathWalker, SourcePath) == DestPathWalker) &&
       (DestPathWalker[StrLen (SourcePath)] == '\\')
      )
      )
  {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_MV_INV_SUB), gShellLevel2HiiHandle);
    FreePool (DestPathCopy);
    return (FALSE);
  }

  FreePool (DestPathCopy);

  return (TRUE);
}

/**
  Function to take a destination path that might contain wildcards and verify
  that there is only a single possible target (IE we cant have wildcards that
  have 2 possible destination).

  if the result is successful the caller must free *DestPathPointer.

  @param[in] DestParameter               The original path to the destination.
  @param[in, out] DestPathPointer  A pointer to the callee allocated final path.
  @param[in] Cwd                   A pointer to the current working directory.
  @param[in] SingleSource          TRUE to have only one source file.
  @param[in, out] DestAttr         A pointer to the destination information attribute.

  @retval SHELL_INVALID_PARAMETER  The DestParameter could not be resolved to a location.
  @retval SHELL_INVALID_PARAMETER  The DestParameter could be resolved to more than 1 location.
  @retval SHELL_INVALID_PARAMETER  Cwd is required and is NULL.
  @retval SHELL_SUCCESS            The operation was successful.
**/
SHELL_STATUS
GetDestinationLocation (
  IN CONST CHAR16   *DestParameter,
  IN OUT CHAR16     **DestPathPointer,
  IN CONST CHAR16   *Cwd,
  IN CONST BOOLEAN  SingleSource,
  IN OUT UINT64     *DestAttr
  )
{
  EFI_SHELL_FILE_INFO  *DestList;
  EFI_SHELL_FILE_INFO  *Node;
  CHAR16               *DestPath;
  UINTN                NewSize;
  UINTN                CurrentSize;

  DestList = NULL;
  DestPath = NULL;

  ASSERT (DestAttr != NULL);

  if (StrStr (DestParameter, L"\\") == DestParameter) {
    if (Cwd == NULL) {
      return SHELL_INVALID_PARAMETER;
    }

    DestPath = AllocateZeroPool (StrSize (Cwd));
    if (DestPath == NULL) {
      return (SHELL_OUT_OF_RESOURCES);
    }

    StrCpyS (DestPath, StrSize (Cwd) / sizeof (CHAR16), Cwd);
    while (PathRemoveLastItem (DestPath)) {
    }

    //
    // Append DestParameter beyond '\' which may be present
    //
    CurrentSize = StrSize (DestPath);
    StrnCatGrow (&DestPath, &CurrentSize, &DestParameter[1], 0);

    *DestPathPointer =  DestPath;
    return (SHELL_SUCCESS);
  }

  //
  // get the destination path
  //
  ShellOpenFileMetaArg ((CHAR16 *)DestParameter, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ|EFI_FILE_MODE_CREATE, &DestList);
  if ((DestList == NULL) || IsListEmpty (&DestList->Link)) {
    //
    // Not existing... must be renaming
    //
    if (StrStr (DestParameter, L":") == NULL) {
      if (Cwd == NULL) {
        ShellCloseFileMetaArg (&DestList);
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle);
        return (SHELL_INVALID_PARAMETER);
      }

      NewSize  = StrSize (Cwd);
      NewSize += StrSize (DestParameter);
      DestPath = AllocateZeroPool (NewSize);
      if (DestPath == NULL) {
        ShellCloseFileMetaArg (&DestList);
        return (SHELL_OUT_OF_RESOURCES);
      }

      StrCpyS (DestPath, NewSize / sizeof (CHAR16), Cwd);
      if ((DestPath[StrLen (DestPath)-1] != L'\\') && (DestParameter[0] != L'\\')) {
        StrCatS (DestPath, NewSize / sizeof (CHAR16), L"\\");
      } else if ((DestPath[StrLen (DestPath)-1] == L'\\') && (DestParameter[0] == L'\\')) {
        ((CHAR16 *)DestPath)[StrLen (DestPath)-1] = CHAR_NULL;
      }

      StrCatS (DestPath, NewSize / sizeof (CHAR16), DestParameter);
    } else {
      ASSERT (DestPath == NULL);
      DestPath = StrnCatGrow (&DestPath, NULL, DestParameter, 0);
      if (DestPath == NULL) {
        ShellCloseFileMetaArg (&DestList);
        return (SHELL_OUT_OF_RESOURCES);
      }
    }
  } else {
    Node      = (EFI_SHELL_FILE_INFO *)GetFirstNode (&DestList->Link);
    *DestAttr = Node->Info->Attribute;
    //
    // Make sure there is only 1 node in the list.
    //
    if (!IsNodeAtEnd (&DestList->Link, &Node->Link)) {
      ShellCloseFileMetaArg (&DestList);
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_MARG_ERROR), gShellLevel2HiiHandle, L"mv", DestParameter);
      return (SHELL_INVALID_PARAMETER);
    }

    //
    // If we are a directory or a single file, then one node is fine.
    //
    if ((ShellIsDirectory (Node->FullName) == EFI_SUCCESS) || SingleSource) {
      DestPath = AllocateZeroPool (StrSize (Node->FullName)+sizeof (CHAR16));
      if (DestPath == NULL) {
        ShellCloseFileMetaArg (&DestList);
        return (SHELL_OUT_OF_RESOURCES);
      }

      StrCpyS (DestPath, (StrSize (Node->FullName)+sizeof (CHAR16)) / sizeof (CHAR16), Node->FullName);
      StrCatS (DestPath, (StrSize (Node->FullName)+sizeof (CHAR16)) / sizeof (CHAR16), L"\\");
    } else {
      //
      // cant move multiple files onto a single file.
      //
      ShellCloseFileMetaArg (&DestList);
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_FILE_ERROR), gShellLevel2HiiHandle, L"mv", DestParameter);
      return (SHELL_INVALID_PARAMETER);
    }
  }

  *DestPathPointer =  DestPath;
  ShellCloseFileMetaArg (&DestList);

  return (SHELL_SUCCESS);
}

/**
  Function to do a move across file systems.

  @param[in] Node               A pointer to the file to be removed.
  @param[in] DestPath           A pointer to the destination file path.
  @param[out] Resp              A pointer to response from question.  Pass back on looped calling

  @retval SHELL_SUCCESS     The source file was moved to the destination.
**/
EFI_STATUS
MoveBetweenFileSystems (
  IN EFI_SHELL_FILE_INFO  *Node,
  IN CONST CHAR16         *DestPath,
  OUT VOID                **Resp
  )
{
  SHELL_STATUS  ShellStatus;

  //
  // First we copy the file
  //
  ShellStatus = CopySingleFile (Node->FullName, DestPath, Resp, TRUE, L"mv");

  //
  // Check our result
  //
  if (ShellStatus == SHELL_SUCCESS) {
    //
    // The copy was successful.  delete the source file.
    //
    CascadeDelete (Node, TRUE);
    Node->Handle = NULL;
  } else if (ShellStatus == SHELL_ABORTED) {
    return EFI_ABORTED;
  } else if (ShellStatus == SHELL_ACCESS_DENIED) {
    return EFI_ACCESS_DENIED;
  } else if (ShellStatus == SHELL_VOLUME_FULL) {
    return EFI_VOLUME_FULL;
  } else {
    return EFI_UNSUPPORTED;
  }

  return (EFI_SUCCESS);
}

/**
  Function to take the destination path and target file name to generate the full destination path.

  @param[in] DestPath           A pointer to the destination file path string.
  @param[out] FullDestPath      A pointer to the full destination path string.
  @param[in] FileName           Name string of  the targe file.

  @retval SHELL_SUCCESS             the files were all moved.
  @retval SHELL_INVALID_PARAMETER   a parameter was invalid
  @retval SHELL_OUT_OF_RESOURCES    a memory allocation failed
**/
EFI_STATUS
CreateFullDestPath (
  IN CONST CHAR16  **DestPath,
  OUT CHAR16       **FullDestPath,
  IN CONST CHAR16  *FileName
  )
{
  UINTN  Size;

  if ((FullDestPath == NULL) || (FileName == NULL) || (DestPath == NULL) || (*DestPath == NULL)) {
    return (EFI_INVALID_PARAMETER);
  }

  Size = StrSize (*DestPath) + StrSize (FileName);

  *FullDestPath = AllocateZeroPool (Size);
  if (*FullDestPath == NULL) {
    return (EFI_OUT_OF_RESOURCES);
  }

  StrCpyS (*FullDestPath, Size / sizeof (CHAR16), *DestPath);
  if (((*FullDestPath)[StrLen (*FullDestPath)-1] != L'\\') && (FileName[0] != L'\\')) {
    StrCatS (*FullDestPath, Size / sizeof (CHAR16), L"\\");
  }

  StrCatS (*FullDestPath, Size / sizeof (CHAR16), FileName);

  return (EFI_SUCCESS);
}

/**
  Function to do a move within a file system.

  @param[in] Node               A pointer to the file to be removed.
  @param[in] DestPath           A pointer to the destination file path.
  @param[out] Resp              A pointer to response from question.  Pass back on looped calling.

  @retval SHELL_SUCCESS           The source file was moved to the destination.
  @retval SHELL_OUT_OF_RESOURCES  A memory allocation failed.
**/
EFI_STATUS
MoveWithinFileSystems (
  IN EFI_SHELL_FILE_INFO  *Node,
  IN CHAR16               *DestPath,
  OUT VOID                **Resp
  )
{
  EFI_FILE_INFO  *NewFileInfo;
  CHAR16         *TempLocation;
  UINTN          NewSize;
  UINTN          Length;
  EFI_STATUS     Status;

  //
  // Chop off map info from DestPath
  //
  if ((TempLocation = StrStr (DestPath, L":")) != NULL) {
    CopyMem (DestPath, TempLocation+1, StrSize (TempLocation+1));
  }

  //
  // construct the new file info block
  //
  NewSize     = StrSize (DestPath);
  NewSize    += StrSize (Node->FileName) + SIZE_OF_EFI_FILE_INFO + sizeof (CHAR16);
  NewFileInfo = AllocateZeroPool (NewSize);
  if (NewFileInfo == NULL) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_NO_MEM), gShellLevel2HiiHandle);
    Status = EFI_OUT_OF_RESOURCES;
  } else {
    CopyMem (NewFileInfo, Node->Info, SIZE_OF_EFI_FILE_INFO);
    if (DestPath[0] != L'\\') {
      StrCpyS (NewFileInfo->FileName, (NewSize - SIZE_OF_EFI_FILE_INFO) / sizeof (CHAR16), L"\\");
      StrCatS (NewFileInfo->FileName, (NewSize - SIZE_OF_EFI_FILE_INFO) / sizeof (CHAR16), DestPath);
    } else {
      StrCpyS (NewFileInfo->FileName, (NewSize - SIZE_OF_EFI_FILE_INFO) / sizeof (CHAR16), DestPath);
    }

    Length = StrLen (NewFileInfo->FileName);
    if (Length > 0) {
      Length--;
    }

    if (NewFileInfo->FileName[Length] == L'\\') {
      if (Node->FileName[0] == L'\\') {
        //
        // Don't allow for double slashes. Eliminate one of them.
        //
        NewFileInfo->FileName[Length] = CHAR_NULL;
      }

      StrCatS (NewFileInfo->FileName, (NewSize - SIZE_OF_EFI_FILE_INFO) / sizeof (CHAR16), Node->FileName);
    }

    NewFileInfo->Size = SIZE_OF_EFI_FILE_INFO + StrSize (NewFileInfo->FileName);

    //
    // Perform the move operation
    //
    Status = ShellSetFileInfo (Node->Handle, NewFileInfo);

    //
    // Free the info object we used...
    //
    FreePool (NewFileInfo);
  }

  return (Status);
}

/**
  function to take a list of files to move and a destination location and do
  the verification and moving of those files to that location.  This function
  will report any errors to the user and continue to move the rest of the files.

  @param[in] FileList           A LIST_ENTRY* based list of files to move
  @param[out] Resp              pointer to response from question.  Pass back on looped calling
  @param[in] DestParameter      the originally specified destination location

  @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
ValidateAndMoveFiles (
  IN EFI_SHELL_FILE_INFO  *FileList,
  OUT VOID                **Resp,
  IN CONST CHAR16         *DestParameter
  )
{
  EFI_STATUS           Status;
  CHAR16               *HiiOutput;
  CHAR16               *HiiResultOk;
  CHAR16               *DestPath;
  UINTN                DestPathLen;
  CHAR16               *FullDestPath;
  CONST CHAR16         *Cwd;
  CHAR16               *FullCwd;
  SHELL_STATUS         ShellStatus;
  EFI_SHELL_FILE_INFO  *Node;
  VOID                 *Response;
  UINT64               Attr;
  CHAR16               *CleanFilePathStr;

  ASSERT (FileList != NULL);
  ASSERT (DestParameter  != NULL);

  DestPath         = NULL;
  FullDestPath     = NULL;
  Cwd              = ShellGetCurrentDir (NULL);
  Response         = *Resp;
  Attr             = 0;
  CleanFilePathStr = NULL;
  FullCwd          = NULL;

  if (Cwd != NULL) {
    FullCwd = AllocateZeroPool (StrSize (Cwd) + sizeof (CHAR16));
    if (FullCwd == NULL) {
      return SHELL_OUT_OF_RESOURCES;
    } else {
      StrCpyS (FullCwd, StrSize (Cwd)/sizeof (CHAR16)+1, Cwd);
      StrCatS (FullCwd, StrSize (Cwd)/sizeof (CHAR16)+1, L"\\");
    }
  }

  Status = ShellLevel2StripQuotes (DestParameter, &CleanFilePathStr);
  if (EFI_ERROR (Status)) {
    SHELL_FREE_NON_NULL (FullCwd);
    if (Status == EFI_OUT_OF_RESOURCES) {
      return SHELL_OUT_OF_RESOURCES;
    } else {
      return SHELL_INVALID_PARAMETER;
    }
  }

  ASSERT (CleanFilePathStr != NULL);

  //
  // Get and validate the destination location
  //
  ShellStatus = GetDestinationLocation (CleanFilePathStr, &DestPath, FullCwd, (BOOLEAN)(FileList->Link.ForwardLink == FileList->Link.BackLink), &Attr);
  FreePool (CleanFilePathStr);

  if (ShellStatus != SHELL_SUCCESS) {
    SHELL_FREE_NON_NULL (FullCwd);
    return (ShellStatus);
  }

  DestPath = PathCleanUpDirectories (DestPath);
  if (DestPath == NULL) {
    FreePool (FullCwd);
    return (SHELL_OUT_OF_RESOURCES);
  }

  HiiOutput   = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MV_OUTPUT), NULL);
  HiiResultOk = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_GEN_RES_OK), NULL);
  if ((HiiOutput == NULL) || (HiiResultOk == NULL)) {
    SHELL_FREE_NON_NULL (DestPath);
    SHELL_FREE_NON_NULL (HiiOutput);
    SHELL_FREE_NON_NULL (HiiResultOk);
    SHELL_FREE_NON_NULL (FullCwd);
    return (SHELL_OUT_OF_RESOURCES);
  }

  //
  // Go through the list of files and directories to move...
  //
  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;
    }

    //
    // These should never be NULL
    //
    ASSERT (Node->FileName != NULL);
    ASSERT (Node->FullName != NULL);
    ASSERT (Node->Info     != NULL);

    //
    // skip the directory traversing stuff...
    //
    if (IsDotOrDotDot (Node->FileName)) {
      continue;
    }

    SHELL_FREE_NON_NULL (FullDestPath);
    FullDestPath = NULL;
    if (ShellIsDirectory (DestPath) == EFI_SUCCESS) {
      CreateFullDestPath ((CONST CHAR16 **)&DestPath, &FullDestPath, Node->FileName);
    }

    //
    // Validate that the move is valid
    //
    if (!IsValidMove (Node->FullName, FullCwd, (FullDestPath != NULL) ? FullDestPath : DestPath, Node->Info->Attribute, Attr, Node->Status)) {
      ShellStatus = SHELL_INVALID_PARAMETER;
      continue;
    }

    ShellPrintDefaultEx (HiiOutput, Node->FullName, FullDestPath != NULL ? FullDestPath : DestPath);

    //
    // See if destination exists
    //
    if (!EFI_ERROR (ShellFileExists ((FullDestPath != NULL) ? FullDestPath : DestPath))) {
      if (Response == NULL) {
        ShellPromptForResponseHii (ShellPromptResponseTypeYesNoAllCancel, STRING_TOKEN (STR_GEN_DEST_EXIST_OVR), gShellLevel2HiiHandle, &Response);
      }

      if (Response == NULL) {
        return SHELL_ABORTED;
      }

      switch (*(SHELL_PROMPT_RESPONSE *)Response) {
        case ShellPromptResponseNo:
          FreePool (Response);
          Response = NULL;
          continue;
        case ShellPromptResponseCancel:
          *Resp = Response;
          //
          // indicate to stop everything
          //
          SHELL_FREE_NON_NULL (FullCwd);
          return (SHELL_ABORTED);
        case ShellPromptResponseAll:
          *Resp = Response;
          break;
        case ShellPromptResponseYes:
          FreePool (Response);
          Response = NULL;
          break;
        default:
          FreePool (Response);
          SHELL_FREE_NON_NULL (FullCwd);
          return SHELL_ABORTED;
      }

      Status = ShellDeleteFileByName (FullDestPath != NULL ? FullDestPath : DestPath);
    }

    if (IsBetweenFileSystem (Node->FullName, FullCwd, DestPath)) {
      if ((FullDestPath == NULL) && (DestPath != NULL)) {
        DestPathLen = StrLen (DestPath);
        while ((DestPathLen > 0) && (DestPath[DestPathLen - 1] == L'\\')) {
          DestPath[DestPathLen - 1] = CHAR_NULL;
          DestPathLen--;
        }
      }

      Status = MoveBetweenFileSystems (Node, FullDestPath != NULL ? FullDestPath : DestPath, &Response);
    } else {
      Status = MoveWithinFileSystems (Node, DestPath, &Response);
      //
      // Display error status
      //
      if (EFI_ERROR (Status)) {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"mv", Status);
      }
    }

    //
    // Check our result
    //
    if (EFI_ERROR (Status)) {
      ShellStatus = SHELL_INVALID_PARAMETER;
      if (Status == EFI_SECURITY_VIOLATION) {
        ShellStatus = SHELL_SECURITY_VIOLATION;
      } else if (Status == EFI_WRITE_PROTECTED) {
        ShellStatus = SHELL_WRITE_PROTECTED;
      } else if (Status == EFI_OUT_OF_RESOURCES) {
        ShellStatus = SHELL_OUT_OF_RESOURCES;
      } else if (Status == EFI_DEVICE_ERROR) {
        ShellStatus = SHELL_DEVICE_ERROR;
      } else if (Status == EFI_ACCESS_DENIED) {
        ShellStatus = SHELL_ACCESS_DENIED;
      }
    } else {
      ShellPrintDefaultEx (L"%s", HiiResultOk);
    }
  } // main for loop

  SHELL_FREE_NON_NULL (FullDestPath);
  SHELL_FREE_NON_NULL (DestPath);
  SHELL_FREE_NON_NULL (HiiOutput);
  SHELL_FREE_NON_NULL (HiiResultOk);
  SHELL_FREE_NON_NULL (FullCwd);
  return (ShellStatus);
}

/** Main function of the 'Mv' command.

  @param[in] Package    List of input parameter for the command.
**/
STATIC
SHELL_STATUS
MainCmdMv (
  LIST_ENTRY  *Package
  )
{
  EFI_STATUS           Status;
  CHAR16               *Cwd;
  UINTN                CwdSize;
  SHELL_STATUS         ShellStatus;
  UINTN                ParamCount;
  UINTN                LoopCounter;
  EFI_SHELL_FILE_INFO  *FileList;
  VOID                 *Response;

  ShellStatus = SHELL_SUCCESS;
  ParamCount  = 0;
  FileList    = NULL;
  Response    = NULL;

  //
  // check for "-?"
  //
  if (ShellCommandLineGetFlag (Package, L"-?")) {
    ASSERT (FALSE);
  }

  switch (ParamCount = ShellCommandLineGetCount (Package)) {
    case 0:
    case 1:
      //
      // we have insufficient parameters
      //
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"mv");
      ShellStatus = SHELL_INVALID_PARAMETER;
      break;
    case 2:
      //
      // must have valid CWD for single parameter...
      //
      if (ShellGetCurrentDir (NULL) == NULL) {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"mv");
        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"mv", ShellCommandLineGetRawValue (Package, 1));
          ShellStatus = SHELL_NOT_FOUND;
        } else {
          //
          // ValidateAndMoveFiles will report errors to the screen itself
          //
          CwdSize = StrSize (ShellGetCurrentDir (NULL)) + sizeof (CHAR16);
          Cwd     = AllocateZeroPool (CwdSize);
          if (Cwd == NULL) {
            ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_OUT_MEM), gShellLevel2HiiHandle, L"mv");
            ShellStatus = SHELL_OUT_OF_RESOURCES;
          } else {
            StrCpyS (Cwd, CwdSize / sizeof (CHAR16), ShellGetCurrentDir (NULL));
            StrCatS (Cwd, CwdSize / sizeof (CHAR16), L"\\");
            ShellStatus = ValidateAndMoveFiles (FileList, &Response, Cwd);
            FreePool (Cwd);
          }
        }
      }

      break;
    default:
      /// @todo make sure this works with error half way through and continues...
      for (ParamCount--, LoopCounter = 1; LoopCounter < ParamCount; LoopCounter++) {
        if (ShellGetExecutionBreakFlag ()) {
          break;
        }

        Status = ShellOpenFileMetaArg ((CHAR16 *)ShellCommandLineGetRawValue (Package, LoopCounter), 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"mv", ShellCommandLineGetRawValue (Package, LoopCounter));
          ShellStatus = SHELL_NOT_FOUND;
        } else {
          //
          // ValidateAndMoveFiles will report errors to the screen itself
          // Only change ShellStatus if it's successful
          //
          if (ShellStatus == SHELL_SUCCESS) {
            ShellStatus = ValidateAndMoveFiles (FileList, &Response, ShellCommandLineGetRawValue (Package, ParamCount));
          } else {
            ValidateAndMoveFiles (FileList, &Response, ShellCommandLineGetRawValue (Package, ParamCount));
          }
        }

        if ((FileList != NULL) && !IsListEmpty (&FileList->Link)) {
          Status = ShellCloseFileMetaArg (&FileList);
          if (EFI_ERROR (Status) && (ShellStatus == SHELL_SUCCESS)) {
            ShellStatus = SHELL_ACCESS_DENIED;
            ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_ERR_FILE), gShellLevel2HiiHandle, L"mv", ShellCommandLineGetRawValue (Package, 1), ShellStatus|MAX_BIT);
          }
        }
      }

      break;
  } // switch on parameter count

  if (FileList != NULL) {
    ShellCloseFileMetaArg (&FileList);
  }

  SHELL_FREE_NON_NULL (Response);

  return ShellStatus;
}

/**
  Function for 'mv' 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
ShellCommandRunMv (
  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);

  //
  // parse the command line
  //
  Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE);
  if (EFI_ERROR (Status)) {
    if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"mv", ProblemParam);
      FreePool (ProblemParam);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      ASSERT (FALSE);
    }

    return ShellStatus;
  }

  ShellStatus = MainCmdMv (Package);

  //
  // free the command line package
  //
  ShellCommandLineFreeVarList (Package);

  if (ShellGetExecutionBreakFlag ()) {
    return (SHELL_ABORTED);
  }

  return (ShellStatus);
}
