From 2165190709e0a1e0408b840bdd9033ec2cc0bd79 Mon Sep 17 00:00:00 2001 From: Ilya Date: Tue, 15 Sep 2020 16:46:02 +0500 Subject: [PATCH 1/6] Avoid an exception if file system does not support reparse points --- .../namespaces/FileSystemProvider.cs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs index be4b95dc935..212c2a23ed0 100644 --- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs +++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs @@ -7840,7 +7840,9 @@ public static class InternalSymbolicLinkLinkCodeMethods // data is 16KB, plus there's a header. private const int MAX_REPARSE_SIZE = (16 * 1024) + REPARSE_GUID_DATA_BUFFER_HEADER_SIZE; - private const int ERROR_NOT_A_REPARSE_POINT = 4390; + private const int ERROR_NOT_A_REPARSE_POINT = 0x00001126; + + private const int ERROR_INVALID_FUNCTION = 0x00000001; private const int FSCTL_GET_REPARSE_POINT = 0x000900A8; @@ -8162,10 +8164,15 @@ private static string WinInternalGetLinkType(string filePath) if (!result) { int lastError = Marshal.GetLastWin32Error(); - if (lastError == ERROR_NOT_A_REPARSE_POINT) + if (lastError == ERROR_NOT_A_REPARSE_POINT || lastError == ERROR_INVALID_FUNCTION) + { + // ERROR_INVALID_FUNCTION - underlying file system does not support reparse points linkType = null; + } else + { throw new Win32Exception(lastError); + } } REPARSE_DATA_BUFFER_SYMBOLICLINK reparseDataBuffer = Marshal.PtrToStructure(outBuffer); @@ -8408,8 +8415,11 @@ private static string WinInternalGetTarget(SafeFileHandle handle) if (!result) { int lastError = Marshal.GetLastWin32Error(); - if (lastError == ERROR_NOT_A_REPARSE_POINT) + if (lastError == ERROR_NOT_A_REPARSE_POINT || lastError == ERROR_INVALID_FUNCTION) + { + // ERROR_INVALID_FUNCTION - underlying file system does not support reparse points return null; + } throw new Win32Exception(lastError); } From c4125eb0565e818d978b85b7a2d28d5b357a199c Mon Sep 17 00:00:00 2001 From: Ilya Date: Thu, 8 Oct 2020 22:41:38 +0500 Subject: [PATCH 2/6] Fast return if it is not reparse point --- .../namespaces/FileSystemProvider.cs | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs index 212c2a23ed0..07afdb616e7 100644 --- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs +++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs @@ -8158,21 +8158,20 @@ private static string WinInternalGetLinkType(string filePath) // Get Buffer size IntPtr dangerousHandle = handle.DangerousGetHandle(); - bool result = DeviceIoControl(dangerousHandle, FSCTL_GET_REPARSE_POINT, - IntPtr.Zero, 0, outBuffer, outBufferSize, out bytesReturned, IntPtr.Zero); + bool result = DeviceIoControl( + dangerousHandle, + FSCTL_GET_REPARSE_POINT, + InBuffer: IntPtr.Zero, + nInBufferSize: 0, + outBuffer, + outBufferSize, + out bytesReturned, + lpOverlapped: IntPtr.Zero); if (!result) { - int lastError = Marshal.GetLastWin32Error(); - if (lastError == ERROR_NOT_A_REPARSE_POINT || lastError == ERROR_INVALID_FUNCTION) - { - // ERROR_INVALID_FUNCTION - underlying file system does not support reparse points - linkType = null; - } - else - { - throw new Win32Exception(lastError); - } + // It is not reparse point or the file system does't support reparse points. + return null; } REPARSE_DATA_BUFFER_SYMBOLICLINK reparseDataBuffer = Marshal.PtrToStructure(outBuffer); @@ -8409,19 +8408,20 @@ private static string WinInternalGetTarget(SafeFileHandle handle) // According to MSDN guidance DangerousAddRef() and DangerousRelease() have been used. handle.DangerousAddRef(ref success); - bool result = DeviceIoControl(handle.DangerousGetHandle(), FSCTL_GET_REPARSE_POINT, - IntPtr.Zero, 0, outBuffer, outBufferSize, out bytesReturned, IntPtr.Zero); + bool result = DeviceIoControl( + handle.DangerousGetHandle(), + FSCTL_GET_REPARSE_POINT, + InBuffer: IntPtr.Zero, + nInBufferSize: 0, + outBuffer, + outBufferSize, + out bytesReturned, + lpOverlapped: IntPtr.Zero); if (!result) { - int lastError = Marshal.GetLastWin32Error(); - if (lastError == ERROR_NOT_A_REPARSE_POINT || lastError == ERROR_INVALID_FUNCTION) - { - // ERROR_INVALID_FUNCTION - underlying file system does not support reparse points - return null; - } - - throw new Win32Exception(lastError); + // It is not reparse point or the file system does't support reparse points. + return null; } string targetDir = null; From f9c50d6290432429d14a8c05c9f394dfe592ec3c Mon Sep 17 00:00:00 2001 From: Ilya Date: Thu, 8 Oct 2020 22:43:28 +0500 Subject: [PATCH 3/6] Remove unused consts --- .../namespaces/FileSystemProvider.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs index 07afdb616e7..32865acab62 100644 --- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs +++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs @@ -7840,10 +7840,6 @@ public static class InternalSymbolicLinkLinkCodeMethods // data is 16KB, plus there's a header. private const int MAX_REPARSE_SIZE = (16 * 1024) + REPARSE_GUID_DATA_BUFFER_HEADER_SIZE; - private const int ERROR_NOT_A_REPARSE_POINT = 0x00001126; - - private const int ERROR_INVALID_FUNCTION = 0x00000001; - private const int FSCTL_GET_REPARSE_POINT = 0x000900A8; private const int FSCTL_SET_REPARSE_POINT = 0x000900A4; From 1f400c0ffa11be2c41c66d4946315a7429a54848 Mon Sep 17 00:00:00 2001 From: Ilya Date: Fri, 9 Oct 2020 08:08:02 +0500 Subject: [PATCH 4/6] Update src/System.Management.Automation/namespaces/FileSystemProvider.cs Co-authored-by: Robert Holt --- .../namespaces/FileSystemProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs index 32865acab62..e42c1e06cce 100644 --- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs +++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs @@ -8416,7 +8416,7 @@ private static string WinInternalGetTarget(SafeFileHandle handle) if (!result) { - // It is not reparse point or the file system does't support reparse points. + // It's not a reparse point or the file system doesn't support reparse points. return null; } From ad6996d9d99da4bb304e16bdc27585095a528273 Mon Sep 17 00:00:00 2001 From: Ilya Date: Fri, 9 Oct 2020 08:08:12 +0500 Subject: [PATCH 5/6] Update src/System.Management.Automation/namespaces/FileSystemProvider.cs Co-authored-by: Robert Holt --- .../namespaces/FileSystemProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs index e42c1e06cce..0aacf6babdc 100644 --- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs +++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs @@ -8166,7 +8166,7 @@ private static string WinInternalGetLinkType(string filePath) if (!result) { - // It is not reparse point or the file system does't support reparse points. + // It's not a reparse point or the file system doesn't support reparse points. return null; } From 9f5ef4221ef3c379db224ca7e87b8bfacd4173e4 Mon Sep 17 00:00:00 2001 From: Ilya Date: Fri, 9 Oct 2020 08:52:52 +0500 Subject: [PATCH 6/6] Fix hardlink detection --- .../namespaces/FileSystemProvider.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs index 0aacf6babdc..75921d838df 100644 --- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs +++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs @@ -8167,7 +8167,7 @@ private static string WinInternalGetLinkType(string filePath) if (!result) { // It's not a reparse point or the file system doesn't support reparse points. - return null; + return IsHardLink(ref dangerousHandle) ? "HardLink" : null; } REPARSE_DATA_BUFFER_SYMBOLICLINK reparseDataBuffer = Marshal.PtrToStructure(outBuffer); @@ -8187,7 +8187,7 @@ private static string WinInternalGetLinkType(string filePath) break; default: - linkType = IsHardLink(ref dangerousHandle) ? "HardLink" : null; + linkType = null; break; }