123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- using System;
- using System.IO;
- using System.Reflection;
- using System.Runtime.InteropServices;
- using MonoMod.Utils;
- namespace BepInEx.Preloader.Core
- {
- internal static class PlatformUtils
- {
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct utsname_osx
- {
- private const int osx_utslen = 256;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = osx_utslen)]
- public string sysname;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = osx_utslen)]
- public string nodename;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = osx_utslen)]
- public string release;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = osx_utslen)]
- public string version;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = osx_utslen)]
- public string machine;
- }
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct utsname_linux
- {
- private const int linux_utslen = 65;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = linux_utslen)]
- public string sysname;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = linux_utslen)]
- public string nodename;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = linux_utslen)]
- public string release;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = linux_utslen)]
- public string version;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = linux_utslen)]
- public string machine;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = linux_utslen)]
- public string domainname;
- }
- [DllImport("libc.so.6", EntryPoint = "uname", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
- private static extern IntPtr uname_linux(ref utsname_linux utsname);
- [DllImport("/usr/lib/libSystem.dylib", EntryPoint = "uname", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
- private static extern IntPtr uname_osx(ref utsname_osx utsname);
- /// <summary>
- /// Recreation of MonoMod's PlatformHelper.DeterminePlatform method, but with libc calls instead of creating processes.
- /// </summary>
- public static void SetPlatform()
- {
- var current = Platform.Unknown;
- // For old Mono, get from a private property to accurately get the platform.
- // static extern PlatformID Platform
- PropertyInfo p_Platform = typeof(Environment).GetProperty("Platform", BindingFlags.NonPublic | BindingFlags.Static);
- string platID;
- if (p_Platform != null)
- {
- platID = p_Platform.GetValue(null, new object[0]).ToString();
- }
- else
- {
- // For .NET and newer Mono, use the usual value.
- platID = Environment.OSVersion.Platform.ToString();
- }
- platID = platID.ToLowerInvariant();
- if (platID.Contains("win"))
- {
- current = Platform.Windows;
- }
- else if (platID.Contains("mac") || platID.Contains("osx"))
- {
- current = Platform.MacOS;
- }
- else if (platID.Contains("lin") || platID.Contains("unix"))
- {
- current = Platform.Linux;
- }
- if (Is(current, Platform.Linux) && Directory.Exists("/data") && File.Exists("/system/build.prop"))
- {
- current = Platform.Android;
- }
- else if (Is(current, Platform.Unix) && Directory.Exists("/System/Library/AccessibilityBundles"))
- {
- current = Platform.iOS;
- }
- // Is64BitOperatingSystem has been added in .NET Framework 4.0
- MethodInfo m_get_Is64BitOperatingSystem = typeof(Environment).GetProperty("Is64BitOperatingSystem")?.GetGetMethod();
- if (m_get_Is64BitOperatingSystem != null)
- current |= (((bool)m_get_Is64BitOperatingSystem.Invoke(null, new object[0])) ? Platform.Bits64 : 0);
- else
- current |= (IntPtr.Size >= 8 ? Platform.Bits64 : 0);
- if ((Is(current, Platform.MacOS) || Is(current, Platform.Linux)) && Type.GetType("Mono.Runtime") != null)
- {
- string arch;
- IntPtr result;
- if (Is(current, Platform.MacOS))
- {
- utsname_osx utsname_osx = new utsname_osx();
- result = uname_osx(ref utsname_osx);
- arch = utsname_osx.machine;
- }
- else
- {
- // Linux
- utsname_linux utsname_linux = new utsname_linux();
- result = uname_linux(ref utsname_linux);
- arch = utsname_linux.machine;
- }
- if (result == IntPtr.Zero && (arch.StartsWith("aarch") || arch.StartsWith("arm")))
- current |= Platform.ARM;
- }
- else
- {
- // Detect ARM based on PE info or uname.
- typeof(object).Module.GetPEKind(out PortableExecutableKinds peKind, out ImageFileMachine machine);
- if (machine == (ImageFileMachine)0x01C4 /* ARM, .NET Framework 4.5 */)
- current |= Platform.ARM;
- }
- PlatformHelper.Current = current;
- }
- private static bool Is(Platform current, Platform expected)
- {
- return (current & expected) == expected;
- }
- }
- }
|