Add uname libc call on Unix systems as platform check

Rebase of 7647862
This commit is contained in:
Bepis committed 2020-11-09 00:55:16 +11:00
1 parent d2bfb22947
commit c2ecb50a22
14 files changed
+184 -83

No files matched your search

@@ -41,6 +41,7 @@
<Compile Include="Patching\AssemblyPatcher.cs" />
<Compile Include="Patching\PatcherPlugin.cs" />
<Compile Include="InternalPreloaderLogger.cs" />
<Compile Include="PlatformUtils.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RuntimeFixes\ConsoleSetOutFix.cs" />
</ItemGroup>
@@ -1,7 +1,6 @@
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Linq;
using BepInEx.Logging;
using MonoMod.Utils;
namespace BepInEx.Preloader.Core.Logging
{
@@ -23,6 +22,8 @@ namespace BepInEx.Preloader.Core.Logging
var attribute = (BuildInfoAttribute)attributes[0];
log.LogMessage(attribute.Info);
}
Logger.LogInfo($"System platform: {PlatformHelper.Current}");
}
public static void RewritePreloaderLogs()
+151
View File
@@ -0,0 +1,151 @@
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;
}
}
}
@@ -22,6 +22,10 @@ using System.Runtime.InteropServices;
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("15f8bc38-a761-4f93-8903-1b531ac5d9f9")]
[assembly: InternalsVisibleTo("BepInEx.Preloader.Unity")]
[assembly: InternalsVisibleTo("BepInEx.NetLauncher")]
[assembly: InternalsVisibleTo("BepInEx.IL2CPP")]
// Version information for an assembly consists of the following four values:
//
// Major Version