+/**\r
+ Function to do a move across file systems.\r
+\r
+ @param[in] Node A pointer to the file to be removed.\r
+ @param[in] DestPath A pointer to the destination file path.\r
+ @param[out] Resp A pointer to response from question. Pass back on looped calling\r
+\r
+ @retval SHELL_SUCCESS The source file was moved to the destination.\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
+/**\r
+ Function to take the destination path and target file name to generate the full destination path.\r
+\r
+ @param[in] DestPath A pointer to the destination file path string.\r
+ @param[out] FullDestPath A pointer to the full destination path string.\r
+ @param[in] FileName Name string of the targe file.\r
+\r
+ @retval SHELL_SUCCESS the files were all moved.\r
+ @retval SHELL_INVALID_PARAMETER a parameter was invalid\r
+ @retval SHELL_OUT_OF_RESOURCES a memory allocation failed\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
+/**\r
+ Function to do a move within a file system.\r
+\r
+ @param[in] Node A pointer to the file to be removed.\r
+ @param[in] DestPath A pointer to the destination file path.\r
+ @param[out] Resp A pointer to response from question. Pass back on looped calling.\r
+\r
+ @retval SHELL_SUCCESS The source file was moved to the destination.\r
+ @retval SHELL_OUT_OF_RESOURCES A memory allocation failed.\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