Simplify OSVERSIONINFOEX interop (#20111)
authorJan Kotas <jkotas@microsoft.com>
Mon, 24 Sep 2018 21:19:05 +0000 (14:19 -0700)
committerGitHub <noreply@github.com>
Mon, 24 Sep 2018 21:19:05 +0000 (14:19 -0700)
src/System.Private.CoreLib/src/Microsoft/Win32/Win32Native.cs
src/System.Private.CoreLib/src/System/Environment.cs

index 45ce42aeb0a0d7b267835f6c2667bd72c2469cbb..393d5633c75a8ea8f91847cdaa66c350d684bf3f 100644 (file)
@@ -116,27 +116,20 @@ namespace Microsoft.Win32
         internal const int LMEM_ZEROINIT = 0x0040;
         internal const int LPTR = (LMEM_FIXED | LMEM_ZEROINIT);
 
-        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
-        internal class OSVERSIONINFOEX
+        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+        internal unsafe struct OSVERSIONINFOEX
         {
-            public OSVERSIONINFOEX()
-            {
-                OSVersionInfoSize = (int)Marshal.SizeOf(this);
-            }
-
-            // The OSVersionInfoSize field must be set to Marshal.SizeOf(this)
-            internal int OSVersionInfoSize = 0;
-            internal int MajorVersion = 0;
-            internal int MinorVersion = 0;
-            internal int BuildNumber = 0;
-            internal int PlatformId = 0;
-            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
-            internal string CSDVersion = null;
-            internal ushort ServicePackMajor = 0;
-            internal ushort ServicePackMinor = 0;
-            internal short SuiteMask = 0;
-            internal byte ProductType = 0;
-            internal byte Reserved = 0;
+            internal int dwOSVersionInfoSize;
+            internal int dwMajorVersion;
+            internal int dwMinorVersion;
+            internal int dwBuildNumber;
+            internal int dwPlatformId;
+            internal fixed char szCSDVersion[128];
+            internal ushort wServicePackMajor;
+            internal ushort wServicePackMinor;
+            internal short wSuiteMask;
+            internal byte wProductType;
+            internal byte wReserved;
         }
 
         [StructLayout(LayoutKind.Sequential)]
@@ -290,8 +283,8 @@ namespace Microsoft.Win32
         internal const uint VER_SERVICEPACKMAJOR = 0x0000020;
         internal const uint VER_SERVICEPACKMINOR = 0x0000010;
         [DllImport("kernel32.dll")]
-        internal static extern bool VerifyVersionInfoW([In, Out] OSVERSIONINFOEX lpVersionInfo, uint dwTypeMask, ulong dwlConditionMask);
+        internal static extern bool VerifyVersionInfoW(ref OSVERSIONINFOEX lpVersionInfo, uint dwTypeMask, ulong dwlConditionMask);
         [DllImport("kernel32.dll")]
-        internal static extern ulong VerSetConditionMask(ulong dwlConditionMask, uint dwTypeBitMask, byte dwConditionMask);        
+        internal static extern ulong VerSetConditionMask(ulong dwlConditionMask, uint dwTypeBitMask, byte dwConditionMask);
     }
 }
index 4c65d770898eaa04f25a1b32cce0092e2f5c62b1..b1f6b3923f7b1befeb1b49cf833ad650b47339be 100644 (file)
@@ -280,17 +280,25 @@ namespace System
 #if !FEATURE_PAL
         private static Lazy<bool> s_IsWindows8OrAbove = new Lazy<bool>(() => 
         {
-            ulong conditionMask = Win32Native.VerSetConditionMask(0, Win32Native.VER_MAJORVERSION, Win32Native.VER_GREATER_EQUAL);
-            conditionMask = Win32Native.VerSetConditionMask(conditionMask, Win32Native.VER_MINORVERSION, Win32Native.VER_GREATER_EQUAL);
-            conditionMask = Win32Native.VerSetConditionMask(conditionMask, Win32Native.VER_SERVICEPACKMAJOR, Win32Native.VER_GREATER_EQUAL);
-            conditionMask = Win32Native.VerSetConditionMask(conditionMask, Win32Native.VER_SERVICEPACKMINOR, Win32Native.VER_GREATER_EQUAL);
-
-            // Windows 8 version is 6.2
-            var version = new Win32Native.OSVERSIONINFOEX { MajorVersion = 6, MinorVersion = 2, ServicePackMajor = 0, ServicePackMinor = 0 };
-                
-            return Win32Native.VerifyVersionInfoW(version, 
-                       Win32Native.VER_MAJORVERSION | Win32Native.VER_MINORVERSION | Win32Native.VER_SERVICEPACKMAJOR | Win32Native.VER_SERVICEPACKMINOR,
-                       conditionMask);
+            unsafe
+            {
+                ulong conditionMask = Win32Native.VerSetConditionMask(0, Win32Native.VER_MAJORVERSION, Win32Native.VER_GREATER_EQUAL);
+                conditionMask = Win32Native.VerSetConditionMask(conditionMask, Win32Native.VER_MINORVERSION, Win32Native.VER_GREATER_EQUAL);
+                conditionMask = Win32Native.VerSetConditionMask(conditionMask, Win32Native.VER_SERVICEPACKMAJOR, Win32Native.VER_GREATER_EQUAL);
+                conditionMask = Win32Native.VerSetConditionMask(conditionMask, Win32Native.VER_SERVICEPACKMINOR, Win32Native.VER_GREATER_EQUAL);
+
+                // Windows 8 version is 6.2
+                var version = new Win32Native.OSVERSIONINFOEX();
+                version.dwOSVersionInfoSize = sizeof(Win32Native.OSVERSIONINFOEX);
+                version.dwMajorVersion = 6;
+                version.dwMinorVersion = 2;
+                version.wServicePackMajor = 0;
+                version.wServicePackMinor = 0;
+
+                return Win32Native.VerifyVersionInfoW(ref version,
+                           Win32Native.VER_MAJORVERSION | Win32Native.VER_MINORVERSION | Win32Native.VER_SERVICEPACKMAJOR | Win32Native.VER_SERVICEPACKMINOR,
+                           conditionMask);
+            }
         });
         internal static bool IsWindows8OrAbove => s_IsWindows8OrAbove.Value;
 #endif