diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UnblockFile.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UnblockFile.cs
index 785d797d02..31c48d3300 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UnblockFile.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UnblockFile.cs
@@ -10,6 +10,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
+using System.IO;
using System.Management.Automation;
using System.Management.Automation.Internal;
@@ -119,18 +120,9 @@ namespace Microsoft.PowerShell.Commands
{
AlternateDataStreamUtilities.DeleteFileStream(path, "Zone.Identifier");
}
- catch (Win32Exception accessException)
+ catch (Exception e)
{
- // NativeErrorCode=2 - File not found.
- // If the block stream not found the 'path' was not blocked and we successfully return.
- if (accessException.NativeErrorCode != 2)
- {
- WriteError(new ErrorRecord(accessException, "RemoveItemUnauthorizedAccessError", ErrorCategory.PermissionDenied, path));
- }
- else
- {
- WriteVerbose(StringUtil.Format(UtilityCommonStrings.NoZoneIdentifierFileStream, path));
- }
+ WriteError(new ErrorRecord(e, "RemoveItemUnableToAccessFile", ErrorCategory.ResourceUnavailable, path));
}
}
}
diff --git a/src/Microsoft.PowerShell.Commands.Utility/resources/UtilityCommonStrings.resx b/src/Microsoft.PowerShell.Commands.Utility/resources/UtilityCommonStrings.resx
index ce98a18260..d11d22cfc9 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/resources/UtilityCommonStrings.resx
+++ b/src/Microsoft.PowerShell.Commands.Utility/resources/UtilityCommonStrings.resx
@@ -174,9 +174,6 @@
'{0}' is not supported in this system.
-
- The file is not blocked: {0}
-
Processing object of type [{0}] at depth {1}
diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs
index fd860cafd6..f9314b8649 100644
--- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs
+++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs
@@ -2874,41 +2874,20 @@ namespace Microsoft.PowerShell.Commands
continueRemoval = ShouldProcess(directory.FullName, action);
}
- if ((directory.Attributes & FileAttributes.ReparsePoint) != 0)
+ if (directory.Attributes.HasFlag(FileAttributes.ReparsePoint))
{
- bool success = InternalSymbolicLinkLinkCodeMethods.DeleteJunction(directory.FullName);
-
- if (!success)
- {
- string error = StringUtil.Format(FileSystemProviderStrings.CannotRemoveItem, directory.FullName);
- Exception e = new IOException(error);
- WriteError(new ErrorRecord(e, "DeleteJunctionFailed", ErrorCategory.WriteError, directory));
- return;
- }
-
try
{
- if (!Utils.ItemExists(directory.FullName, out bool _))
- {
- // Directory does not exist
- return;
- }
+ directory.Delete();
}
- catch (Exception accessException)
+ catch (Exception e)
{
- ErrorRecord errorRecord = new ErrorRecord(accessException, "RemoveFileSystemItemUnAuthorizedAccess", ErrorCategory.PermissionDenied, directory);
-
- ErrorDetails errorDetails =
- new ErrorDetails(this, "FileSystemProviderStrings",
- "CannotRemoveItem",
- directory.FullName,
- accessException.Message);
-
- errorRecord.ErrorDetails = errorDetails;
-
- WriteError(errorRecord);
- return;
+ string error = StringUtil.Format(FileSystemProviderStrings.CannotRemoveItem, directory.FullName);
+ Exception exception = new IOException(error, e);
+ WriteError(new ErrorRecord(exception, "DeleteSymbolicLinkFailed", ErrorCategory.WriteError, directory));
}
+
+ return;
}
if (continueRemoval)
@@ -8336,91 +8315,6 @@ namespace Microsoft.PowerShell.Commands
}
}
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods")]
- internal static bool DeleteJunction(string junctionPath)
- {
- bool result = false;
-
- if (!String.IsNullOrEmpty(junctionPath))
- {
- if (!Platform.IsWindows)
- {
- // For non-Windows platform, treat it as a file. Just delete it.
- try
- {
- File.Delete(junctionPath);
- return true;
- }
- catch
- {
- return false;
- }
- }
-
- using (SafeHandle handle = OpenReparsePoint(junctionPath, FileDesiredAccess.GenericWrite))
- {
- bool success = false;
- int inOutBufferSize = Marshal.SizeOf();
- IntPtr outBuffer = Marshal.AllocHGlobal(inOutBufferSize);
- IntPtr inBuffer = Marshal.AllocHGlobal(inOutBufferSize);
-
- try
- {
- handle.DangerousAddRef(ref success);
- IntPtr dangerousHandle = handle.DangerousGetHandle();
- int bytesReturned;
-
- // Do a FSCTL_GET_REPARSE_POINT first because the ReparseTag could be
- // IO_REPARSE_TAG_MOUNT_POINT or IO_REPARSE_TAG_SYMLINK.
- // Using the wrong one results in mismatched-tag error.
-
- REPARSE_GUID_DATA_BUFFER junctionData = new REPARSE_GUID_DATA_BUFFER();
- Marshal.StructureToPtr(junctionData, outBuffer, false);
-
- result = DeviceIoControl(dangerousHandle, FSCTL_GET_REPARSE_POINT, IntPtr.Zero, 0,
- outBuffer, inOutBufferSize, out bytesReturned, IntPtr.Zero);
- if (!result)
- {
- int lastError = Marshal.GetLastWin32Error();
- throw new Win32Exception(lastError);
- }
-
- junctionData = Marshal.PtrToStructure(outBuffer);
- junctionData.ReparseDataLength = 0;
- junctionData.DataBuffer = new char[MAX_REPARSE_SIZE];
-
- Marshal.StructureToPtr(junctionData, inBuffer, false);
-
- // To delete a reparse point:
- // ReparseDataLength must be 0
- // inBufferSize must be REPARSE_GUID_DATA_BUFFER_HEADER_SIZE
- result = DeviceIoControl(dangerousHandle, FSCTL_DELETE_REPARSE_POINT, inBuffer, REPARSE_GUID_DATA_BUFFER_HEADER_SIZE, IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero);
- if (!result)
- {
- int lastError = Marshal.GetLastWin32Error();
- throw new Win32Exception(lastError);
- }
- }
- finally
- {
- if (success)
- {
- handle.DangerousRelease();
- }
-
- Marshal.FreeHGlobal(outBuffer);
- Marshal.FreeHGlobal(inBuffer);
- }
- }
- }
- else
- {
- throw new ArgumentNullException("junctionPath");
- }
-
- return result;
- }
-
private static SafeFileHandle OpenReparsePoint(string reparsePoint, FileDesiredAccess accessMode)
{
#if UNIX
@@ -8585,11 +8479,7 @@ namespace System.Management.Automation.Internal
}
string resultPath = path + adjustedStreamName;
- if (!NativeMethods.DeleteFile(resultPath))
- {
- int error = Marshal.GetLastWin32Error();
- throw new Win32Exception(error);
- }
+ File.Delete(resultPath);
}
internal static void SetZoneOfOrigin(string path, SecurityZone securityZone)
@@ -8617,9 +8507,6 @@ namespace System.Management.Automation.Internal
IntPtr lpSecurityAttributes, FileMode dwCreationDisposition,
int dwFlagsAndAttributes, IntPtr hTemplateFile);
- [DllImport(PinvokeDllNames.DeleteFileDllName, CharSet = CharSet.Unicode, SetLastError = true)]
- internal static extern bool DeleteFile(string lpFileName);
-
[DllImport(PinvokeDllNames.FindFirstStreamDllName, ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
[SuppressMessage("Microsoft.Globalization", "CA2101:SpecifyMarshalingForPInvokeStringArguments", MessageId = "AlternateStreamNativeData.Name")]
internal static extern SafeFindHandle FindFirstStreamW(
diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1
index 3f4482e2e0..13d2421d5b 100644
--- a/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1
+++ b/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1
@@ -242,6 +242,8 @@ Describe "New-Item with links" -Tags @('CI', 'RequireAdminOnWindows') {
# Remove the link explicitly to avoid broken symlink issue
Remove-Item $FullyQualifiedLink -Force
+ # Test a code path removing a symbolic link (reparse point)
+ Test-Path $FullyQualifiedLink | Should -BeFalse
}
It "New-Item -ItemType SymbolicLink should understand directory path ending with slash" {
diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Unblock-File.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Unblock-File.Tests.ps1
index b85cb1156f..a62d38d4a7 100644
--- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Unblock-File.Tests.ps1
+++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Unblock-File.Tests.ps1
@@ -64,6 +64,6 @@ Describe "Unblock-File" -Tags "CI" {
$TestFileCreated = Get-ChildItem $TestFile
$TestFileCreated.IsReadOnly | Should -BeTrue
- { Unblock-File -LiteralPath $TestFile -ErrorAction Stop } | Should -Throw -ErrorId "RemoveItemUnauthorizedAccessError,Microsoft.PowerShell.Commands.UnblockFileCommand"
+ { Unblock-File -LiteralPath $TestFile -ErrorAction Stop } | Should -Throw -ErrorId "RemoveItemUnableToAccessFile,Microsoft.PowerShell.Commands.UnblockFileCommand"
}
}