\r
#include "UefiShellLevel2CommandsLib.h"\r
\r
+/**\r
+ function to determine if a move is between file systems.\r
+ \r
+ @param FullName [in] The name of the file to move.\r
+ @param Cwd [in] The current working directory\r
+ @param DestPath [in] The target location to move to\r
+\r
+ @retval TRUE The move is across file system.\r
+ @retval FALSE The move is within a file system.\r
+**/\r
+STATIC\r
+BOOLEAN\r
+EFIAPI\r
+IsBetweenFileSystem(\r
+ IN CONST CHAR16 *FullName,\r
+ IN CONST CHAR16 *Cwd,\r
+ IN CONST CHAR16 *DestPath\r
+ )\r
+{\r
+ CHAR16 *Test;\r
+ CHAR16 *Test1;\r
+ UINTN Result;\r
+\r
+ Test = StrStr(FullName, L":");\r
+ if (Test == NULL && Cwd != NULL) {\r
+ Test = StrStr(Cwd, L":");\r
+ }\r
+ Test1 = StrStr(DestPath, L":");\r
+ if (Test1 == NULL && Cwd != NULL) {\r
+ Test1 = StrStr(Cwd, L":");\r
+ }\r
+ if (Test1 != NULL && Test != NULL) {\r
+ *Test = CHAR_NULL;\r
+ *Test1 = CHAR_NULL;\r
+ Result = StringNoCaseCompare(&FullName, &DestPath);\r
+ *Test = L':';\r
+ *Test1 = L':';\r
+ if (Result != 0) {\r
+ return (TRUE);\r
+ }\r
+ }\r
+ return (FALSE);\r
+}\r
+\r
/**\r
Function to validate that moving a specific file (FileName) to a specific\r
location (DestPath) is valid.\r
@param Cwd [in] The current working directory\r
@param DestPath [in] The target location to move to\r
@param Attribute[in] The Attribute of the file\r
+ @param DestAttr [in] The Attribute of the destination\r
@param FileStatus[in] The Status of the file when opened\r
\r
@retval TRUE The move is valid\r
@retval FALSE The move is not\r
**/\r
+STATIC\r
BOOLEAN\r
EFIAPI\r
IsValidMove(\r
- IN CONST CHAR16 *FullName,\r
+ IN CONST CHAR16 *SourcePath,\r
IN CONST CHAR16 *Cwd,\r
IN CONST CHAR16 *DestPath,\r
IN CONST UINT64 Attribute,\r
+ IN CONST UINT64 DestAttr,\r
IN CONST EFI_STATUS FileStatus\r
)\r
{\r
- CHAR16 *Test;\r
- CHAR16 *Test1;\r
- CHAR16 *TestWalker;\r
- INTN Result;\r
- UINTN TempLen;\r
- if (Cwd != NULL && StrCmp(FullName, Cwd) == 0) {\r
+ CHAR16 *DestPathCopy;\r
+ CHAR16 *DestPathWalker;\r
+\r
+ if (Cwd != NULL && StrCmp(SourcePath, Cwd) == 0) {\r
//\r
// Invalid move\r
//\r
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MV_INV_CWD), gShellLevel2HiiHandle);\r
return (FALSE);\r
}\r
- Test = NULL;\r
- Test = StrnCatGrow(&Test, NULL, DestPath, 0);\r
- TestWalker = Test;\r
- ASSERT(TestWalker != NULL);\r
- while(*TestWalker == L'\\') {\r
- TestWalker++;\r
- }\r
- while(TestWalker != NULL && TestWalker[StrLen(TestWalker)-1] == L'\\') {\r
- TestWalker[StrLen(TestWalker)-1] = CHAR_NULL;\r
+\r
+ //\r
+ // invalid to move read only or move to a read only destination\r
+ //\r
+ if (((Attribute & EFI_FILE_READ_ONLY) != 0) \r
+ || (FileStatus == EFI_WRITE_PROTECTED)\r
+ || ((DestAttr & EFI_FILE_READ_ONLY) != 0)\r
+ ) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MV_INV_RO), gShellLevel2HiiHandle, SourcePath);\r
+ return (FALSE);\r
+ } \r
+ \r
+ DestPathCopy = AllocateCopyPool(StrSize(DestPath), DestPath);\r
+ if (DestPathCopy == NULL) {\r
+ return (FALSE);\r
}\r
- ASSERT(TestWalker != NULL);\r
- ASSERT(FullName != NULL);\r
- if (StrStr(FullName, TestWalker) != 0) {\r
- TempLen = StrLen(FullName);\r
- if (StrStr(FullName, TestWalker) != FullName // not the first items... (could below it)\r
- && TempLen <= (StrLen(TestWalker) + 1)\r
- && StrStr(FullName+StrLen(TestWalker) + 1, L"\\") == NULL) {\r
- //\r
- // Invalid move\r
- //\r
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MV_INV_SUB), gShellLevel2HiiHandle);\r
- FreePool(Test);\r
- return (FALSE);\r
- }\r
+\r
+ for (DestPathWalker = DestPathCopy; *DestPathWalker == L'\\'; DestPathWalker++) ;\r
+\r
+ while(DestPathWalker != NULL && DestPathWalker[StrLen(DestPathWalker)-1] == L'\\') {\r
+ DestPathWalker[StrLen(DestPathWalker)-1] = CHAR_NULL;\r
}\r
- FreePool(Test);\r
- if (StrStr(DestPath, FullName) != 0 && StrStr(DestPath, FullName) != DestPath) {\r
- //\r
- // Invalid move\r
- //\r
+\r
+ ASSERT(DestPathWalker != NULL);\r
+ ASSERT(SourcePath != NULL);\r
+\r
+ //\r
+ // If they're the same, or if source is "above" dest on file path tree\r
+ //\r
+ if ( StrCmp(DestPathWalker, SourcePath) == 0 \r
+ || StrStr(DestPathWalker, SourcePath) == DestPathWalker \r
+ ) {\r
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MV_INV_SUB), gShellLevel2HiiHandle);\r
+ FreePool(DestPathCopy);\r
return (FALSE);\r
}\r
- if (((Attribute & EFI_FILE_READ_ONLY) != 0) || (FileStatus == EFI_WRITE_PROTECTED)) {\r
- //\r
- // invalid to move read only\r
- //\r
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MV_INV_RO), gShellLevel2HiiHandle, FullName);\r
- return (FALSE);\r
- }\r
- Test = StrStr(FullName, L":");\r
- Test1 = StrStr(DestPath, L":");\r
- if (Test1 != NULL && Test != NULL) {\r
- *Test = CHAR_NULL;\r
- *Test1 = CHAR_NULL;\r
- Result = StringNoCaseCompare(&FullName, &DestPath);\r
- *Test = L':';\r
- *Test1 = L':';\r
- if (Result != 0) {\r
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MV_INV_FS), gShellLevel2HiiHandle);\r
- return (FALSE);\r
- }\r
- }\r
+ FreePool(DestPathCopy);\r
+\r
return (TRUE);\r
}\r
\r
\r
if the result is sucessful the caller must free *DestPathPointer.\r
\r
- @param[in] DestDir The original path to the destination.\r
+ @param[in] DestParameter The original path to the destination.\r
@param[in, out] DestPathPointer A pointer to the callee allocated final path.\r
@param[in] Cwd A pointer to the current working directory.\r
\r
- @retval SHELL_INVALID_PARAMETER The DestDir could not be resolved to a location.\r
- @retval SHELL_INVALID_PARAMETER The DestDir could be resolved to more than 1 location.\r
+ @retval SHELL_INVALID_PARAMETER The DestParameter could not be resolved to a location.\r
+ @retval SHELL_INVALID_PARAMETER The DestParameter could be resolved to more than 1 location.\r
@retval SHELL_INVALID_PARAMETER Cwd is required and is NULL.\r
@retval SHELL_SUCCESS The operation was sucessful.\r
**/\r
+STATIC\r
SHELL_STATUS\r
EFIAPI\r
GetDestinationLocation(\r
- IN CONST CHAR16 *DestDir,\r
+ IN CONST CHAR16 *DestParameter,\r
IN OUT CHAR16 **DestPathPointer,\r
- IN CONST CHAR16 *Cwd\r
+ IN CONST CHAR16 *Cwd,\r
+ IN CONST BOOLEAN SingleSource,\r
+ IN OUT UINT64 *DestAttr\r
)\r
{\r
EFI_SHELL_FILE_INFO *DestList;\r
DestList = NULL;\r
DestPath = NULL;\r
\r
- if (StrStr(DestDir, L"\\") == DestDir) {\r
+ ASSERT(DestAttr != NULL);\r
+\r
+ if (StrStr(DestParameter, L"\\") == DestParameter) {\r
if (Cwd == NULL) {\r
return SHELL_INVALID_PARAMETER;\r
}\r
while (PathRemoveLastItem(DestPath)) ;\r
\r
//\r
- // Append DestDir beyond '\' which may be present\r
+ // Append DestParameter beyond '\' which may be present\r
//\r
CurrentSize = StrSize(DestPath);\r
- StrnCatGrow(&DestPath, &CurrentSize, &DestDir[1], 0);\r
+ StrnCatGrow(&DestPath, &CurrentSize, &DestParameter[1], 0);\r
\r
*DestPathPointer = DestPath;\r
return (SHELL_SUCCESS);\r
//\r
// get the destination path\r
//\r
- ShellOpenFileMetaArg((CHAR16*)DestDir, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ|EFI_FILE_MODE_CREATE, &DestList);\r
+ ShellOpenFileMetaArg((CHAR16*)DestParameter, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ|EFI_FILE_MODE_CREATE, &DestList);\r
if (DestList == NULL || IsListEmpty(&DestList->Link)) {\r
//\r
// Not existing... must be renaming\r
//\r
- if (StrStr(DestDir, L":") == NULL) {\r
+ if (StrStr(DestParameter, L":") == NULL) {\r
if (Cwd == NULL) {\r
ShellCloseFileMetaArg(&DestList);\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle);\r
return (SHELL_INVALID_PARAMETER);\r
}\r
NewSize = StrSize(Cwd);\r
- NewSize += StrSize(DestDir);\r
+ NewSize += StrSize(DestParameter);\r
DestPath = AllocateZeroPool(NewSize);\r
if (DestPath == NULL) {\r
ShellCloseFileMetaArg(&DestList);\r
return (SHELL_OUT_OF_RESOURCES);\r
}\r
StrCpy(DestPath, Cwd);\r
- if (DestPath[StrLen(DestPath)-1] != L'\\' && DestDir[0] != L'\\') {\r
+ if (DestPath[StrLen(DestPath)-1] != L'\\' && DestParameter[0] != L'\\') {\r
StrCat(DestPath, L"\\");\r
- } else if (DestPath[StrLen(DestPath)-1] == L'\\' && DestDir[0] == L'\\') {\r
+ } else if (DestPath[StrLen(DestPath)-1] == L'\\' && DestParameter[0] == L'\\') {\r
((CHAR16*)DestPath)[StrLen(DestPath)-1] = CHAR_NULL;\r
}\r
- StrCat(DestPath, DestDir);\r
+ StrCat(DestPath, DestParameter);\r
} else {\r
ASSERT(DestPath == NULL);\r
- DestPath = StrnCatGrow(&DestPath, NULL, DestDir, 0);\r
+ DestPath = StrnCatGrow(&DestPath, NULL, DestParameter, 0);\r
if (DestPath == NULL) {\r
ShellCloseFileMetaArg(&DestList);\r
return (SHELL_OUT_OF_RESOURCES);\r
}\r
} else {\r
Node = (EFI_SHELL_FILE_INFO*)GetFirstNode(&DestList->Link);\r
+ *DestAttr = Node->Info->Attribute;\r
//\r
// Make sure there is only 1 node in the list.\r
//\r
if (!IsNodeAtEnd(&DestList->Link, &Node->Link)) {\r
ShellCloseFileMetaArg(&DestList);\r
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_MARG_ERROR), gShellLevel2HiiHandle, DestDir);\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_MARG_ERROR), gShellLevel2HiiHandle, DestParameter);\r
return (SHELL_INVALID_PARAMETER);\r
}\r
- if (ShellIsDirectory(Node->FullName)==EFI_SUCCESS) {\r
+\r
+ //\r
+ // If we are a directory or a single file, then one node is fine.\r
+ //\r
+ if (ShellIsDirectory(Node->FullName)==EFI_SUCCESS || SingleSource) {\r
DestPath = AllocateZeroPool(StrSize(Node->FullName)+sizeof(CHAR16));\r
if (DestPath == NULL) {\r
ShellCloseFileMetaArg(&DestList);\r
StrCat(DestPath, L"\\");\r
} else {\r
//\r
- // cant move onto another file.\r
+ // cant move multiple files onto a single file.\r
//\r
ShellCloseFileMetaArg(&DestList);\r
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_ERROR), gShellLevel2HiiHandle, DestDir);\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_ERROR), gShellLevel2HiiHandle, DestParameter);\r
return (SHELL_INVALID_PARAMETER);\r
}\r
}\r
return (SHELL_SUCCESS);\r
}\r
\r
+EFI_STATUS\r
+EFIAPI\r
+MoveBetweenFileSystems(\r
+ IN EFI_SHELL_FILE_INFO *Node,\r
+ IN CONST CHAR16 *DestPath,\r
+ OUT VOID **Resp\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // First we copy the file\r
+ //\r
+ Status = CopySingleFile(Node->FullName, DestPath, Resp, TRUE);\r
+\r
+ //\r
+ // Check our result\r
+ //\r
+ if (!EFI_ERROR(Status)) {\r
+ //\r
+ // The copy was successful. delete the source file.\r
+ //\r
+ CascadeDelete(Node, TRUE);\r
+ Node->Handle = NULL;\r
+ }\r
+\r
+ return (Status);\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CreateFullDestPath(\r
+ IN CONST CHAR16 **DestPath,\r
+ OUT CHAR16 **FullDestPath, \r
+ IN CONST CHAR16 *FileName\r
+ )\r
+{\r
+ UINTN Size;\r
+ if (FullDestPath == NULL || FileName == NULL || DestPath == NULL || *DestPath == NULL){\r
+ return (EFI_INVALID_PARAMETER);\r
+ }\r
+\r
+ Size = StrSize(*DestPath) + StrSize(FileName);\r
+\r
+ *FullDestPath = AllocateZeroPool(Size);\r
+ if (*FullDestPath == NULL){\r
+ return (EFI_OUT_OF_RESOURCES);\r
+ }\r
+\r
+ StrnCpy(*FullDestPath, *DestPath, Size / sizeof(CHAR16) - 1);\r
+ if ((*FullDestPath)[StrLen(*FullDestPath)-1] != L'\\' && FileName[0] != L'\\') {\r
+ StrnCat(*FullDestPath, L"\\",Size / sizeof(CHAR16) - 1 - StrLen(*FullDestPath));\r
+ }\r
+ StrnCat(*FullDestPath, FileName, Size / sizeof(CHAR16) - 1 - StrLen(*FullDestPath));\r
+\r
+ return (EFI_SUCCESS);\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+MoveWithinFileSystems(\r
+ IN EFI_SHELL_FILE_INFO *Node,\r
+ IN CHAR16 *DestPath,\r
+ OUT VOID **Resp\r
+ )\r
+{\r
+ EFI_FILE_INFO *NewFileInfo;\r
+ CHAR16 *TempLocation;\r
+ UINTN NewSize;\r
+ UINTN Length;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Chop off map info from DestPath\r
+ //\r
+ if ((TempLocation = StrStr(DestPath, L":")) != NULL) {\r
+ CopyMem(DestPath, TempLocation+1, StrSize(TempLocation+1));\r
+ }\r
+\r
+ //\r
+ // construct the new file info block\r
+ //\r
+ NewSize = StrSize(DestPath);\r
+ NewSize += StrSize(Node->FileName) + SIZE_OF_EFI_FILE_INFO + sizeof(CHAR16);\r
+ NewFileInfo = AllocateZeroPool(NewSize);\r
+ if (NewFileInfo == NULL) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellLevel2HiiHandle);\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ } else {\r
+ CopyMem(NewFileInfo, Node->Info, SIZE_OF_EFI_FILE_INFO);\r
+ if (DestPath[0] != L'\\') {\r
+ StrCpy(NewFileInfo->FileName, L"\\");\r
+ StrCat(NewFileInfo->FileName, DestPath);\r
+ } else {\r
+ StrCpy(NewFileInfo->FileName, DestPath);\r
+ }\r
+ Length = StrLen(NewFileInfo->FileName);\r
+ if (Length > 0) {\r
+ Length--;\r
+ }\r
+ if (NewFileInfo->FileName[Length] == L'\\') {\r
+ if (Node->FileName[0] == L'\\') {\r
+ //\r
+ // Don't allow for double slashes. Eliminate one of them.\r
+ //\r
+ NewFileInfo->FileName[Length] = CHAR_NULL;\r
+ }\r
+ StrCat(NewFileInfo->FileName, Node->FileName);\r
+ }\r
+ NewFileInfo->Size = SIZE_OF_EFI_FILE_INFO + StrSize(NewFileInfo->FileName);\r
+\r
+ //\r
+ // Perform the move operation\r
+ //\r
+ Status = ShellSetFileInfo(Node->Handle, NewFileInfo);\r
+\r
+ //\r
+ // Free the info object we used...\r
+ //\r
+ FreePool(NewFileInfo);\r
+ }\r
+\r
+ return (Status);\r
+}\r
/**\r
function to take a list of files to move and a destination location and do\r
the verification and moving of those files to that location. This function\r
\r
@param[in] FileList A LIST_ENTRY* based list of files to move\r
@param[out] Resp pointer to response from question. Pass back on looped calling\r
- @param[in] DestDir the destination location\r
+ @param[in] DestParameter the originally specified destination location\r
\r
@retval SHELL_SUCCESS the files were all moved.\r
@retval SHELL_INVALID_PARAMETER a parameter was invalid\r
@retval SHELL_WRITE_PROTECTED the destination was write protected\r
@retval SHELL_OUT_OF_RESOURCES a memory allocation failed\r
**/\r
+STATIC\r
SHELL_STATUS\r
EFIAPI\r
ValidateAndMoveFiles(\r
- IN CONST EFI_SHELL_FILE_INFO *FileList,\r
+ IN EFI_SHELL_FILE_INFO *FileList,\r
OUT VOID **Resp,\r
- IN CONST CHAR16 *DestDir\r
+ IN CONST CHAR16 *DestParameter\r
)\r
{\r
EFI_STATUS Status;\r
CHAR16 *HiiOutput;\r
CHAR16 *HiiResultOk;\r
CHAR16 *DestPath;\r
+ CHAR16 *FullDestPath;\r
CONST CHAR16 *Cwd;\r
SHELL_STATUS ShellStatus;\r
- CONST EFI_SHELL_FILE_INFO *Node;\r
- EFI_FILE_INFO *NewFileInfo;\r
- CHAR16 *TempLocation;\r
- UINTN NewSize;\r
- UINTN Length;\r
+ EFI_SHELL_FILE_INFO *Node;\r
VOID *Response;\r
- SHELL_FILE_HANDLE DestHandle;\r
+ UINT64 Attr;\r
CHAR16 *CleanFilePathStr;\r
\r
ASSERT(FileList != NULL);\r
- ASSERT(DestDir != NULL);\r
+ ASSERT(DestParameter != NULL);\r
\r
- DestPath = NULL;\r
- Cwd = ShellGetCurrentDir(NULL);\r
- Response = *Resp;\r
- CleanFilePathStr = NULL;\r
+ DestPath = NULL;\r
+ FullDestPath = NULL;\r
+ Cwd = ShellGetCurrentDir(NULL);\r
+ Response = *Resp;\r
+ Attr = 0;\r
+ CleanFilePathStr = NULL;\r
\r
- Status = ShellLevel2StripQuotes (DestDir, &CleanFilePathStr);\r
+ Status = ShellLevel2StripQuotes (DestParameter, &CleanFilePathStr);\r
if (EFI_ERROR (Status)) {\r
if (Status == EFI_OUT_OF_RESOURCES) {\r
return SHELL_OUT_OF_RESOURCES;\r
} else {\r
return SHELL_INVALID_PARAMETER;\r
}\r
- } \r
+ }\r
\r
ASSERT (CleanFilePathStr != NULL);\r
\r
//\r
// Get and validate the destination location\r
//\r
- ShellStatus = GetDestinationLocation(CleanFilePathStr, &DestPath, Cwd);\r
+ ShellStatus = GetDestinationLocation(CleanFilePathStr, &DestPath, Cwd, FileList->Link.ForwardLink == FileList->Link.BackLink, &Attr);\r
FreePool (CleanFilePathStr);\r
+\r
if (ShellStatus != SHELL_SUCCESS) {\r
return (ShellStatus);\r
}\r
DestPath = PathCleanUpDirectories(DestPath);\r
+ if (DestPath == NULL) {\r
+ return (SHELL_OUT_OF_RESOURCES);\r
+ }\r
\r
HiiOutput = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MV_OUTPUT), NULL);\r
HiiResultOk = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_GEN_RES_OK), NULL);\r
- ASSERT (DestPath != NULL);\r
- ASSERT (HiiResultOk != NULL);\r
- ASSERT (HiiOutput != NULL);\r
+ if (HiiOutput == NULL || HiiResultOk == NULL) {\r
+ SHELL_FREE_NON_NULL(DestPath);\r
+ SHELL_FREE_NON_NULL(HiiOutput);\r
+ SHELL_FREE_NON_NULL(HiiResultOk);\r
+ return (SHELL_OUT_OF_RESOURCES);\r
+ }\r
\r
//\r
// Go through the list of files and directories to move...\r
continue;\r
}\r
\r
+ SHELL_FREE_NON_NULL(FullDestPath);\r
+ FullDestPath = NULL;\r
+ if (ShellIsDirectory(DestPath)==EFI_SUCCESS) {\r
+ CreateFullDestPath(&DestPath, &FullDestPath, Node->FileName);\r
+ }\r
+\r
//\r
// Validate that the move is valid\r
//\r
- if (!IsValidMove(Node->FullName, Cwd, DestPath, Node->Info->Attribute, Node->Status)) {\r
+ if (!IsValidMove(Node->FullName, Cwd, FullDestPath?FullDestPath:DestPath, Node->Info->Attribute, Attr, Node->Status)) {\r
ShellStatus = SHELL_INVALID_PARAMETER;\r
continue;\r
}\r
\r
- //\r
- // Chop off map info from "DestPath"\r
- //\r
- if ((TempLocation = StrStr(DestPath, L":")) != NULL) {\r
- CopyMem(DestPath, TempLocation+1, StrSize(TempLocation+1));\r
- }\r
+ ShellPrintEx(-1, -1, HiiOutput, Node->FullName, FullDestPath?FullDestPath:DestPath);\r
\r
//\r
- // construct the new file info block\r
+ // See if destination exists\r
//\r
- NewSize = StrSize(DestPath);\r
- NewSize += StrSize(Node->FileName) + SIZE_OF_EFI_FILE_INFO + sizeof(CHAR16);\r
- NewFileInfo = AllocateZeroPool(NewSize);\r
- if (NewFileInfo == NULL) {\r
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellLevel2HiiHandle);\r
- ShellStatus = SHELL_OUT_OF_RESOURCES;\r
- } else {\r
- CopyMem(NewFileInfo, Node->Info, SIZE_OF_EFI_FILE_INFO);\r
- if (DestPath[0] != L'\\') {\r
- StrCpy(NewFileInfo->FileName, L"\\");\r
- StrCat(NewFileInfo->FileName, DestPath);\r
- } else {\r
- StrCpy(NewFileInfo->FileName, DestPath);\r
+ if (!EFI_ERROR(ShellFileExists(FullDestPath?FullDestPath:DestPath))) {\r
+ if (Response == NULL) {\r
+ ShellPromptForResponseHii(ShellPromptResponseTypeYesNoAllCancel, STRING_TOKEN (STR_GEN_DEST_EXIST_OVR), gShellLevel2HiiHandle, &Response);\r
}\r
- Length = StrLen(NewFileInfo->FileName);\r
- if (Length > 0) {\r
- Length--;\r
- }\r
- if (NewFileInfo->FileName[Length] == L'\\') {\r
- if (Node->FileName[0] == L'\\') {\r
+ switch (*(SHELL_PROMPT_RESPONSE*)Response) {\r
+ case ShellPromptResponseNo:\r
+ FreePool(Response);\r
+ Response = NULL;\r
+ continue;\r
+ case ShellPromptResponseCancel:\r
+ *Resp = Response;\r
//\r
- // Don't allow for double slashes. Eliminate one of them.\r
+ // indicate to stop everything\r
//\r
- NewFileInfo->FileName[Length] = CHAR_NULL;\r
- }\r
- StrCat(NewFileInfo->FileName, Node->FileName);\r
+ return (SHELL_ABORTED);\r
+ case ShellPromptResponseAll:\r
+ *Resp = Response;\r
+ break;\r
+ case ShellPromptResponseYes:\r
+ FreePool(Response);\r
+ Response = NULL;\r
+ break;\r
+ default:\r
+ FreePool(Response);\r
+ return SHELL_ABORTED;\r
}\r
- NewFileInfo->Size = SIZE_OF_EFI_FILE_INFO + StrSize(NewFileInfo->FileName);\r
- ShellPrintEx(-1, -1, HiiOutput, Node->FullName, NewFileInfo->FileName);\r
+ Status = ShellDeleteFileByName(FullDestPath?FullDestPath:DestPath);\r
+ }\r
\r
- if (!EFI_ERROR(ShellFileExists(NewFileInfo->FileName))) {\r
- if (Response == NULL) {\r
- ShellPromptForResponseHii(ShellPromptResponseTypeYesNoAllCancel, STRING_TOKEN (STR_GEN_DEST_EXIST_OVR), gShellLevel2HiiHandle, &Response);\r
- }\r
- switch (*(SHELL_PROMPT_RESPONSE*)Response) {\r
- case ShellPromptResponseNo:\r
- FreePool(NewFileInfo);\r
- continue;\r
- case ShellPromptResponseCancel:\r
- *Resp = Response;\r
- //\r
- // indicate to stop everything\r
- //\r
- FreePool(NewFileInfo);\r
- FreePool(DestPath);\r
- FreePool(HiiOutput);\r
- FreePool(HiiResultOk);\r
- return (SHELL_ABORTED);\r
- case ShellPromptResponseAll:\r
- *Resp = Response;\r
- break;\r
- case ShellPromptResponseYes:\r
- FreePool(Response);\r
- break;\r
- default:\r
- FreePool(Response);\r
- FreePool(NewFileInfo);\r
- FreePool(DestPath);\r
- FreePool(HiiOutput);\r
- FreePool(HiiResultOk);\r
- return SHELL_ABORTED;\r
- }\r
- Status = ShellOpenFileByName(NewFileInfo->FileName, &DestHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0);\r
- ShellDeleteFile(&DestHandle);\r
+ if (IsBetweenFileSystem(Node->FullName, Cwd, DestPath)) {\r
+ while (FullDestPath == NULL && DestPath != NULL && DestPath[0] != CHAR_NULL && DestPath[StrLen(DestPath) - 1] == L'\\') {\r
+ DestPath[StrLen(DestPath) - 1] = CHAR_NULL;\r
}\r
+ Status = MoveBetweenFileSystems(Node, FullDestPath?FullDestPath:DestPath, &Response);\r
+ } else {\r
+ Status = MoveWithinFileSystems(Node, DestPath, &Response);\r
+ }\r
\r
-\r
- //\r
- // Perform the move operation\r
- //\r
- Status = ShellSetFileInfo(Node->Handle, NewFileInfo);\r
-\r
- //\r
- // Free the info object we used...\r
- //\r
- FreePool(NewFileInfo);\r
-\r
- //\r
- // Check our result\r
- //\r
- if (EFI_ERROR(Status)) {\r
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, Status);\r
- ShellStatus = SHELL_INVALID_PARAMETER;\r
- if (Status == EFI_SECURITY_VIOLATION) {\r
- ShellStatus = SHELL_SECURITY_VIOLATION;\r
- } else if (Status == EFI_WRITE_PROTECTED) {\r
- ShellStatus = SHELL_WRITE_PROTECTED;\r
- } else if (Status == EFI_OUT_OF_RESOURCES) {\r
- ShellStatus = SHELL_OUT_OF_RESOURCES;\r
- } else if (Status == EFI_DEVICE_ERROR) {\r
- ShellStatus = SHELL_DEVICE_ERROR;\r
- } else if (Status == EFI_ACCESS_DENIED) {\r
- ShellStatus = SHELL_ACCESS_DENIED;\r
- }\r
- } else {\r
- ShellPrintEx(-1, -1, L"%s", HiiResultOk);\r
+ //\r
+ // Check our result\r
+ //\r
+ if (EFI_ERROR(Status)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, Status);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ if (Status == EFI_SECURITY_VIOLATION) {\r
+ ShellStatus = SHELL_SECURITY_VIOLATION;\r
+ } else if (Status == EFI_WRITE_PROTECTED) {\r
+ ShellStatus = SHELL_WRITE_PROTECTED;\r
+ } else if (Status == EFI_OUT_OF_RESOURCES) {\r
+ ShellStatus = SHELL_OUT_OF_RESOURCES;\r
+ } else if (Status == EFI_DEVICE_ERROR) {\r
+ ShellStatus = SHELL_DEVICE_ERROR;\r
+ } else if (Status == EFI_ACCESS_DENIED) {\r
+ ShellStatus = SHELL_ACCESS_DENIED;\r
}\r
+ } else {\r
+ ShellPrintEx(-1, -1, L"%s", HiiResultOk);\r
}\r
- } // for loop\r
\r
- FreePool(DestPath);\r
- FreePool(HiiOutput);\r
- FreePool(HiiResultOk);\r
+ } // main for loop\r
+\r
+ SHELL_FREE_NON_NULL(FullDestPath);\r
+ SHELL_FREE_NON_NULL(DestPath);\r
+ SHELL_FREE_NON_NULL(HiiOutput);\r
+ SHELL_FREE_NON_NULL(HiiResultOk);\r
return (ShellStatus);\r
}\r
\r