CreateSymbolicLink PInvoke retval must be marshalled as U1 (#69150) (#73004)
authorDavid CantĂș <dacantu@microsoft.com>
Thu, 11 Aug 2022 20:24:54 +0000 (15:24 -0500)
committerGitHub <noreply@github.com>
Thu, 11 Aug 2022 20:24:54 +0000 (13:24 -0700)
* CreateSymbolicLink PInvoke retval must be marshalled as U1

* Fix redundant invocations of Environment.OSVersion.Version

src/installer/tests/TestUtils/SymbolicLinking.cs
src/libraries/Common/src/Interop/Windows/Kernel32/Interop.CreateSymbolicLink.cs

index bf7dbf4..50b4763 100644 (file)
@@ -64,6 +64,7 @@ namespace Microsoft.DotNet.CoreSetup.Test
         }
 
         [DllImport("kernel32.dll", SetLastError = true)]
+        [return: MarshalAs(UnmanagedType.U1)]
         private static extern bool CreateSymbolicLink(
             string symbolicLinkName,
             string targetFileName,
index 9ecd41c..2981c20 100644 (file)
@@ -21,6 +21,7 @@ internal static partial class Interop
         internal const int SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE = 0x2;
 
         [DllImport(Libraries.Kernel32, EntryPoint = "CreateSymbolicLinkW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false, ExactSpelling = true)]
+        [return: MarshalAs(UnmanagedType.U1)]
         private static extern bool CreateSymbolicLinkPrivate(string lpSymlinkFileName, string lpTargetFileName, int dwFlags);
 
         /// <summary>
@@ -38,9 +39,8 @@ internal static partial class Interop
 
             int flags = 0;
 
-            bool isAtLeastWin10Build14972 =
-                Environment.OSVersion.Version.Major == 10 && Environment.OSVersion.Version.Build >= 14972 ||
-                Environment.OSVersion.Version.Major >= 11;
+            Version osVersion = Environment.OSVersion.Version;
+            bool isAtLeastWin10Build14972 = osVersion.Major >= 11 || osVersion.Major == 10 && osVersion.Build >= 14972;
 
             if (isAtLeastWin10Build14972)
             {
@@ -54,17 +54,10 @@ internal static partial class Interop
 
             bool success = CreateSymbolicLinkPrivate(symlinkFileName, targetFileName, flags);
 
-            int error;
             if (!success)
             {
                 throw Win32Marshal.GetExceptionForLastWin32Error(originalPath);
             }
-            // In older versions we need to check GetLastWin32Error regardless of the return value of CreateSymbolicLink,
-            // e.g: if the user doesn't have enough privileges to create a symlink the method returns success which we can consider as a silent failure.
-            else if (!isAtLeastWin10Build14972 && (error = Marshal.GetLastWin32Error()) != 0)
-            {
-                throw Win32Marshal.GetExceptionForWin32Error(error, originalPath);
-            }
         }
     }
 }