diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs index db619e3d15e..9499bf95289 100644 --- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs +++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs @@ -54,7 +54,10 @@ public sealed partial class FileSystemProvider : NavigationCmdletProvider, #if UNIX // This is the errno returned by the rename() syscall // when an item is attempted to be renamed across filesystem mount boundaries. - private const int UNIX_ERRNO_EXDEV = 18; + private const int MOVE_FAILED_ERROR = 18; +#else + // 0x80070005 ACCESS_DENIED is returned when trying to move files across volumes like DFS + private const int MOVE_FAILED_ERROR = -2147024891; #endif // 4MB gives the best results without spiking the resources on the remote connection for file transfers between pssessions. @@ -6071,35 +6074,22 @@ private void MoveDirectoryInfoItem( /// If true, force move the directory, overwriting anything at the destination. private void MoveDirectoryInfoUnchecked(DirectoryInfo directory, string destinationPath, bool force) { -#if UNIX try { if (InternalTestHooks.ThrowExdevErrorOnMoveDirectory) { - throw new IOException("Invalid cross-device link", hresult: UNIX_ERRNO_EXDEV); + throw new IOException("Invalid cross-device link", hresult: MOVE_FAILED_ERROR); } directory.MoveTo(destinationPath); } - catch (IOException e) when (e.HResult == UNIX_ERRNO_EXDEV) + catch (IOException e) when (e.HResult == MOVE_FAILED_ERROR) { // Rather than try to ascertain whether we can rename a directory ahead of time, // it's both faster and more correct to try to rename it and fall back to copy/deleting it // See also: https://github.com/coreutils/coreutils/blob/439741053256618eb651e6d43919df29625b8714/src/mv.c#L212-L216 CopyAndDelete(directory, destinationPath, force); } -#else - // On Windows, being able to rename vs copy/delete a file - // is just a question of the drive - if (IsSameWindowsVolume(directory.FullName, destinationPath)) - { - directory.MoveTo(destinationPath); - } - else - { - CopyAndDelete(directory, destinationPath, force); - } -#endif } private void CopyAndDelete(DirectoryInfo directory, string destination, bool force) @@ -6137,16 +6127,6 @@ private void CopyAndDelete(DirectoryInfo directory, string destination, bool for } } -#if !UNIX - private static bool IsSameWindowsVolume(string source, string destination) - { - FileInfo src = new FileInfo(source); - FileInfo dest = new FileInfo(destination); - - return (src.Directory.Root.Name == dest.Directory.Root.Name); - } -#endif - #endregion MoveItem #endregion NavigationCmdletProvider members diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/FileSystem.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/FileSystem.Tests.ps1 index 0e4adaeec70..a9d35d7f789 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/FileSystem.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/FileSystem.Tests.ps1 @@ -287,6 +287,13 @@ Describe "Basic FileSystem Provider Tests" -Tags "CI" { $newItemPath = Join-Path $protectedPath "foo" $shouldSkip = -not (Test-Path $protectedPath) } + + if ($IsWindows) { + $fqaccessdenied = "MoveDirectoryItemUnauthorizedAccessError,Microsoft.PowerShell.Commands.MoveItemCommand" + } + else { + $fqaccessdenied = "MoveDirectoryItemIOError,Microsoft.PowerShell.Commands.MoveItemCommand" + } } It "Access-denied test for " -Skip:(-not $IsWindows -or $shouldSkip) -TestCases @( @@ -296,7 +303,7 @@ Describe "Basic FileSystem Provider Tests" -Tags "CI" { # @{cmdline = "New-Item -Type File -Path $newItemPath -ErrorAction Stop"; expectedError = "NewItemUnauthorizedAccessError,Microsoft.PowerShell.Commands.NewItemCommand"} @{cmdline = "Get-ChildItem $protectedPath -ErrorAction Stop"; expectedError = "DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand"} @{cmdline = "Rename-Item -Path $protectedPath -NewName bar -ErrorAction Stop"; expectedError = "RenameItemIOError,Microsoft.PowerShell.Commands.RenameItemCommand"}, - @{cmdline = "Move-Item -Path $protectedPath -Destination bar -ErrorAction Stop"; expectedError = "MoveDirectoryItemIOError,Microsoft.PowerShell.Commands.MoveItemCommand"} + @{cmdline = "Move-Item -Path $protectedPath -Destination bar -ErrorAction Stop"; expectedError = $fqaccessdenied} ) { param ($cmdline, $expectedError)