diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Navigation.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Navigation.cs index d2ba941ee..fb58250d3 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Navigation.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Navigation.cs @@ -3562,7 +3562,22 @@ namespace Microsoft.PowerShell.Commands } bool shouldRecurse = Recurse; - if (!Recurse && hasChildren) + bool treatAsFile = false; + try + { + System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(providerPath); + if (!Platform.IsWindows && di != null && (di.Attributes & System.IO.FileAttributes.ReparsePoint) != 0) + { + shouldRecurse = false; + treatAsFile = true; + } + } + catch (System.IO.FileNotFoundException) + { + // not a directory + } + + if (!treatAsFile && !Recurse && hasChildren) { // Get the localized prompt string diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs index 79e92e995..6dc033623 100644 --- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs +++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs @@ -2858,7 +2858,7 @@ namespace Microsoft.PowerShell.Commands } //if this is a reparse point and force is not specified then warn user but dont remove the directory. - if (((directory.Attributes & FileAttributes.ReparsePoint) != 0) && !Force) + if (Platform.IsWindows && ((directory.Attributes & FileAttributes.ReparsePoint) != 0) && !Force) { String error = StringUtil.Format(FileSystemProviderStrings.DirectoryReparsePoint, directory.FullName); Exception e = new IOException(error); @@ -8452,10 +8452,24 @@ namespace Microsoft.PowerShell.Commands 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(); + ClrFacade.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 = ClrFacade.PtrToStructure(outBuffer); junctionData.ReparseDataLength = 0; junctionData.DataBuffer = new char[MAX_REPARSE_SIZE]; - junctionData.ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; ClrFacade.StructureToPtr(junctionData, inBuffer, false);