From ce1984b4243aadf92241d4da4f701431f0f516b7 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Mon, 24 Sep 2018 12:34:07 -0700 Subject: [PATCH] Fix interop for RTL_OSVERSIONINFOEX (dotnet/corefx#32433) - Ensure that the OS version string is marshaled as Unicode - Avoid allocating the version string when it is not needed Fixes dotnet/corefx#32423 Commit migrated from https://github.com/dotnet/corefx/commit/1a7ef6f2ef077bb9a318ba0fca6fe9ce2e202d5b --- .../NtDll/Interop.RTL_OSVERSIONINFOEX.cs | 7 ++-- .../Windows/NtDll/Interop.RtlGetVersion.cs | 12 +++---- .../src/System/PlatformDetection.Windows.cs | 35 +++++++++---------- ....InteropServices.RuntimeInformation.csproj | 1 + 4 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/libraries/Common/src/Interop/Windows/NtDll/Interop.RTL_OSVERSIONINFOEX.cs b/src/libraries/Common/src/Interop/Windows/NtDll/Interop.RTL_OSVERSIONINFOEX.cs index 48c44fd7ff03bf..47a6b783564714 100644 --- a/src/libraries/Common/src/Interop/Windows/NtDll/Interop.RTL_OSVERSIONINFOEX.cs +++ b/src/libraries/Common/src/Interop/Windows/NtDll/Interop.RTL_OSVERSIONINFOEX.cs @@ -9,16 +9,15 @@ internal partial class Interop { internal partial class NtDll { - [StructLayout(LayoutKind.Sequential)] - internal struct RTL_OSVERSIONINFOEX + [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] + internal unsafe struct RTL_OSVERSIONINFOEX { internal uint dwOSVersionInfoSize; internal uint dwMajorVersion; internal uint dwMinorVersion; internal uint dwBuildNumber; internal uint dwPlatformId; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] - internal string szCSDVersion; + internal fixed char szCSDVersion[128]; } } } diff --git a/src/libraries/Common/src/Interop/Windows/NtDll/Interop.RtlGetVersion.cs b/src/libraries/Common/src/Interop/Windows/NtDll/Interop.RtlGetVersion.cs index 763a015641bf90..9f368565e77527 100644 --- a/src/libraries/Common/src/Interop/Windows/NtDll/Interop.RtlGetVersion.cs +++ b/src/libraries/Common/src/Interop/Windows/NtDll/Interop.RtlGetVersion.cs @@ -11,17 +11,17 @@ internal partial class Interop internal partial class NtDll { [DllImport(Libraries.NtDll, ExactSpelling=true)] - private static extern int RtlGetVersion(out RTL_OSVERSIONINFOEX lpVersionInformation); + private static extern int RtlGetVersion(ref RTL_OSVERSIONINFOEX lpVersionInformation); - internal static string RtlGetVersion() + internal static unsafe string RtlGetVersion() { - RTL_OSVERSIONINFOEX osvi = new RTL_OSVERSIONINFOEX(); - osvi.dwOSVersionInfoSize = (uint)Marshal.SizeOf(osvi); + var osvi = new RTL_OSVERSIONINFOEX(); + osvi.dwOSVersionInfoSize = (uint)sizeof(RTL_OSVERSIONINFOEX); const string version = "Microsoft Windows"; - if (RtlGetVersion(out osvi) == 0) + if (RtlGetVersion(ref osvi) == 0) { return string.Format("{0} {1}.{2}.{3} {4}", - version, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber, osvi.szCSDVersion); + version, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber, new string(&(osvi.szCSDVersion[0]))); } else { diff --git a/src/libraries/CoreFx.Private.TestUtilities/src/System/PlatformDetection.Windows.cs b/src/libraries/CoreFx.Private.TestUtilities/src/System/PlatformDetection.Windows.cs index 7d9bcbc9935b41..035cb4f4492040 100644 --- a/src/libraries/CoreFx.Private.TestUtilities/src/System/PlatformDetection.Windows.cs +++ b/src/libraries/CoreFx.Private.TestUtilities/src/System/PlatformDetection.Windows.cs @@ -219,19 +219,19 @@ private static int GetWindowsProductType() return productType; } - private static int GetWindowsMinorVersion() + private static unsafe int GetWindowsMinorVersion() { - RTL_OSVERSIONINFOEX osvi = new RTL_OSVERSIONINFOEX(); - osvi.dwOSVersionInfoSize = (uint)Marshal.SizeOf(osvi); - Assert.Equal(0, RtlGetVersion(out osvi)); + var osvi = new RTL_OSVERSIONINFOEX(); + osvi.dwOSVersionInfoSize = (uint)sizeof(RTL_OSVERSIONINFOEX); + Assert.Equal(0, RtlGetVersion(ref osvi)); return (int)osvi.dwMinorVersion; } - private static int GetWindowsBuildNumber() + private static unsafe int GetWindowsBuildNumber() { - RTL_OSVERSIONINFOEX osvi = new RTL_OSVERSIONINFOEX(); - osvi.dwOSVersionInfoSize = (uint)Marshal.SizeOf(osvi); - Assert.Equal(0, RtlGetVersion(out osvi)); + var osvi = new RTL_OSVERSIONINFOEX(); + osvi.dwOSVersionInfoSize = (uint)sizeof(RTL_OSVERSIONINFOEX); + Assert.Equal(0, RtlGetVersion(ref osvi)); return (int)osvi.dwBuildNumber; } @@ -269,25 +269,24 @@ out int pdwReturnedProductType ); [DllImport("ntdll.dll", ExactSpelling=true)] - private static extern int RtlGetVersion(out RTL_OSVERSIONINFOEX lpVersionInformation); + private static extern int RtlGetVersion(ref RTL_OSVERSIONINFOEX lpVersionInformation); - [StructLayout(LayoutKind.Sequential)] - private struct RTL_OSVERSIONINFOEX + [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] + private unsafe struct RTL_OSVERSIONINFOEX { internal uint dwOSVersionInfoSize; internal uint dwMajorVersion; internal uint dwMinorVersion; internal uint dwBuildNumber; internal uint dwPlatformId; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] - internal string szCSDVersion; + internal fixed char szCSDVersion[128]; } - private static int GetWindowsVersion() + private static unsafe int GetWindowsVersion() { - RTL_OSVERSIONINFOEX osvi = new RTL_OSVERSIONINFOEX(); - osvi.dwOSVersionInfoSize = (uint)Marshal.SizeOf(osvi); - Assert.Equal(0, RtlGetVersion(out osvi)); + var osvi = new RTL_OSVERSIONINFOEX(); + osvi.dwOSVersionInfoSize = (uint)sizeof(RTL_OSVERSIONINFOEX); + Assert.Equal(0, RtlGetVersion(ref osvi)); return (int)osvi.dwMajorVersion; } @@ -303,5 +302,5 @@ private static int GetWindowsVersion() // The process handle does NOT need closing [DllImport("kernel32.dll", ExactSpelling = true)] private static extern IntPtr GetCurrentProcess(); - } + } } diff --git a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System.Runtime.InteropServices.RuntimeInformation.csproj b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System.Runtime.InteropServices.RuntimeInformation.csproj index df0d6db1570b4d..e2b0639afdb061 100644 --- a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System.Runtime.InteropServices.RuntimeInformation.csproj +++ b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System.Runtime.InteropServices.RuntimeInformation.csproj @@ -2,6 +2,7 @@ System.Runtime.InteropServices {1CBC030D-B5D3-4AB5-A9FD-24EC5F6F38D2} + true netcoreapp-Unix-Debug;netcoreapp-Unix-Release;netcoreapp-Windows_NT-Debug;netcoreapp-Windows_NT-Release;uap-Windows_NT-Debug;uap-Windows_NT-Release;uapaot-Windows_NT-Debug;uapaot-Windows_NT-Release