@@ -16,7 +16,19 @@ internal static class PlatformUtils
1616 CharSet = CharSet . Ansi ) ]
1717 private static extern IntPtr uname_osx ( ref utsname_osx utsname ) ;
1818
19+ [ DllImport ( "ntdll.dll" , SetLastError = true ) ]
20+ private static extern bool RtlGetVersion ( ref WindowsOSVersionInfoExW versionInfo ) ;
21+
22+
23+ private static bool Is ( this Platform current , Platform expected ) => ( current & expected ) == expected ;
24+
25+
1926 public static readonly bool ProcessIs64Bit = IntPtr . Size >= 8 ;
27+ public static Version WindowsVersion { get ; set ; }
28+
29+ public static string LinuxArchitecture { get ; set ; }
30+ public static string LinuxKernelVersion { get ; set ; }
31+
2032
2133 /// <summary>
2234 /// Recreation of MonoMod's PlatformHelper.DeterminePlatform method, but with libc calls instead of creating processes.
@@ -40,27 +52,36 @@ public static void SetPlatform()
4052 current = Platform . Windows ;
4153 else if ( platID . Contains ( "mac" ) || platID . Contains ( "osx" ) )
4254 current = Platform . MacOS ;
43- else if ( platID . Contains ( "lin" ) || platID . Contains ( "unix" ) ) current = Platform . Linux ;
55+ else if ( platID . Contains ( "lin" ) || platID . Contains ( "unix" ) )
56+ current = Platform . Linux ;
4457
45- if ( Is ( current , Platform . Linux ) && Directory . Exists ( "/data" ) && File . Exists ( "/system/build.prop" ) )
58+ if ( current . Is ( Platform . Linux ) && Directory . Exists ( "/data" ) && File . Exists ( "/system/build.prop" ) )
4659 current = Platform . Android ;
47- else if ( Is ( current , Platform . Unix ) && Directory . Exists ( "/System/Library/AccessibilityBundles" ) )
60+ else if ( current . Is ( Platform . Unix ) && Directory . Exists ( "/System/Library/AccessibilityBundles" ) )
4861 current = Platform . iOS ;
4962
63+ if ( current . Is ( Platform . Windows ) )
64+ {
65+ var windowsVersionInfo = new WindowsOSVersionInfoExW ( ) ;
66+ RtlGetVersion ( ref windowsVersionInfo ) ;
67+
68+ WindowsVersion = new Version ( ( int ) windowsVersionInfo . dwMajorVersion , ( int ) windowsVersionInfo . dwMinorVersion , 0 , ( int ) windowsVersionInfo . dwBuildNumber ) ;
69+ }
70+
5071 // Is64BitOperatingSystem has been added in .NET Framework 4.0
5172 var m_get_Is64BitOperatingSystem =
5273 typeof ( Environment ) . GetProperty ( "Is64BitOperatingSystem" ) ? . GetGetMethod ( ) ;
5374 if ( m_get_Is64BitOperatingSystem != null )
5475 current |= ( bool ) m_get_Is64BitOperatingSystem . Invoke ( null , new object [ 0 ] ) ? Platform . Bits64 : 0 ;
5576 else
5677 current |= IntPtr . Size >= 8 ? Platform . Bits64 : 0 ;
57-
58- if ( ( Is ( current , Platform . MacOS ) || Is ( current , Platform . Linux ) ) && Type . GetType ( "Mono.Runtime" ) != null )
78+
79+ if ( ( current . Is ( Platform . MacOS ) || current . Is ( Platform . Linux ) ) && Type . GetType ( "Mono.Runtime" ) != null )
5980 {
6081 string arch ;
6182 IntPtr result ;
6283
63- if ( Is ( current , Platform . MacOS ) )
84+ if ( current . Is ( Platform . MacOS ) )
6485 {
6586 var utsname_osx = new utsname_osx ( ) ;
6687 result = uname_osx ( ref utsname_osx ) ;
@@ -72,6 +93,9 @@ public static void SetPlatform()
7293 var utsname_linux = new utsname_linux ( ) ;
7394 result = uname_linux ( ref utsname_linux ) ;
7495 arch = utsname_linux . machine ;
96+
97+ LinuxArchitecture = utsname_linux . machine ;
98+ LinuxKernelVersion = utsname_linux . version ;
7599 }
76100
77101 if ( result == IntPtr . Zero && ( arch . StartsWith ( "aarch" ) || arch . StartsWith ( "arm" ) ) )
@@ -88,7 +112,23 @@ public static void SetPlatform()
88112 PlatformHelper . Current = current ;
89113 }
90114
91- private static bool Is ( Platform current , Platform expected ) => ( current & expected ) == expected ;
115+ [ StructLayout ( LayoutKind . Sequential , Pack = 1 , CharSet = CharSet . Unicode ) ]
116+ public struct WindowsOSVersionInfoExW
117+ {
118+ private static uint size = ( uint ) Marshal . SizeOf ( typeof ( WindowsOSVersionInfoExW ) ) ;
119+ public uint dwOSVersionInfoSize = size ;
120+ public uint dwMajorVersion ;
121+ public uint dwMinorVersion ;
122+ public uint dwBuildNumber ;
123+ public uint dwPlatformId ;
124+ [ MarshalAs ( UnmanagedType . ByValTStr , SizeConst = 128 ) ]
125+ public string szCSDVersion ;
126+ public ushort wServicePackMajor ;
127+ public ushort wServicePackMinor ;
128+ public ushort wSuiteMask ;
129+ public byte wProductType ;
130+ public byte wReserved ;
131+ }
92132
93133 [ StructLayout ( LayoutKind . Sequential , Pack = 1 ) ]
94134 public struct utsname_osx
0 commit comments