-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #24 from BUTR/dev
v1.2.2
- Loading branch information
Showing
8 changed files
with
282 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
using Bannerlord.BUTR.Shared.Helpers; | ||
|
||
using System.IO; | ||
|
||
namespace Bannerlord.BLSE.Shared.Utils; | ||
|
||
internal static class PlatformHelper | ||
{ | ||
private static string ConfigName = Path.GetFileName(Directory.GetCurrentDirectory()); | ||
private static string GameBasePath = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), "../", "../")); | ||
|
||
public static bool IsSteam() => ConfigName == "Win64_Shipping_Client" && File.Exists(Path.Combine(GameBasePath, ModuleInfoHelper.ModulesFolder, "Native", "steam.target")); | ||
public static bool IsGog() => ConfigName == "Win64_Shipping_Client" && File.Exists(Path.Combine(GameBasePath, ModuleInfoHelper.ModulesFolder, "Native", "gog.target")); | ||
public static bool IsGdk() => ConfigName == "Gaming.Desktop.x64_Shipping_Client" && File.Exists(Path.Combine(GameBasePath, "appxmanifest.xml")); | ||
public static bool IsEpic() => ConfigName == "Win64_Shipping_Client" && File.Exists(Path.Combine(GameBasePath, ModuleInfoHelper.ModulesFolder, "Native", "epic.target")); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
using Microsoft.Win32.SafeHandles; | ||
|
||
using System; | ||
using System.Runtime.InteropServices; | ||
|
||
namespace Bannerlord.BLSE.Shared.Utils; | ||
|
||
file static class SafeNativeMethods | ||
{ | ||
internal const int ERROR_SUCCESS = 0; | ||
|
||
internal const int KEY_QUERY_VALUE = 1; | ||
internal const int KEY_SET_VALUE = 2; | ||
internal const int KEY_CREATE_SUB_KEY = 4; | ||
internal const int KEY_ENUMERATE_SUB_KEYS = 8; | ||
internal const int KEY_NOTIFY = 16; | ||
internal const int KEY_CREATE_LINK = 32; | ||
internal const int KEY_READ = 131097; | ||
internal const int KEY_WRITE = 131078; | ||
|
||
internal const int REG_NONE = 0; | ||
internal const int REG_SZ = 1; | ||
internal const int REG_EXPAND_SZ = 2; | ||
internal const int REG_BINARY = 3; | ||
internal const int REG_DWORD = 4; | ||
internal const int REG_DWORD_LITTLE_ENDIAN = 4; | ||
internal const int REG_DWORD_BIG_ENDIAN = 5; | ||
internal const int REG_LINK = 6; | ||
internal const int REG_MULTI_SZ = 7; | ||
internal const int REG_RESOURCE_LIST = 8; | ||
internal const int REG_FULL_RESOURCE_DESCRIPTOR = 9; | ||
internal const int REG_RESOURCE_REQUIREMENTS_LIST = 10; | ||
internal const int REG_QWORD = 11; | ||
|
||
internal const string ADVAPI32 = "advapi32.dll"; | ||
|
||
[DllImport(ADVAPI32, BestFitMapping = false, CharSet = CharSet.Unicode)] | ||
internal static extern int RegOpenKeyEx(RegistryHandle hKey, string lpSubKey, int ulOptions, int samDesired, out RegistryHandle? hkResult); | ||
|
||
/* | ||
[DllImport(ADVAPI32, BestFitMapping = false, CharSet = CharSet.Unicode)] | ||
internal static extern int RegSetValueEx(RegistryHandle hKey, string lpValueName, int Reserved, int dwType, string val, int cbData); | ||
[DllImport(ADVAPI32, BestFitMapping = false, CharSet = CharSet.Unicode)] | ||
internal static extern int RegCreateKeyEx(RegistryHandle hKey, string lpSubKey, int Reserved, string? lpClass, int dwOptions, int samDesigner, IntPtr lpSecurityAttributes, out RegistryHandle hkResult, out int lpdwDisposition); | ||
*/ | ||
|
||
[DllImport(ADVAPI32)] | ||
internal static extern int RegCloseKey(IntPtr handle); | ||
|
||
[DllImport(ADVAPI32, BestFitMapping = false, CharSet = CharSet.Unicode)] | ||
internal static extern int RegQueryValueEx(RegistryHandle hKey, string lpValueName, int lpReserved, ref int lpType, [Out] byte[]? lpData, ref int lpcbData); | ||
|
||
/* | ||
[DllImport(ADVAPI32, BestFitMapping = false, CharSet = CharSet.Unicode)] | ||
internal static extern int RegDeleteKey(RegistryHandle hKey, string lpValueName); | ||
*/ | ||
} | ||
|
||
internal class RegistryHandle : SafeHandleZeroOrMinusOneIsInvalid | ||
{ | ||
public static readonly RegistryHandle HKEY_CLASSES_ROOT = new(new IntPtr(int.MinValue), ownHandle: false); | ||
public static readonly RegistryHandle HKEY_CURRENT_USER = new(new IntPtr(-2147483647), ownHandle: false); | ||
public static readonly RegistryHandle HKEY_LOCAL_MACHINE = new(new IntPtr(-2147483646), ownHandle: false); | ||
public static readonly RegistryHandle HKEY_USERS = new(new IntPtr(-2147483645), ownHandle: false); | ||
public static readonly RegistryHandle HKEY_PERFORMANCE_DATA = new(new IntPtr(-2147483644), ownHandle: false); | ||
public static readonly RegistryHandle HKEY_CURRENT_CONFIG = new(new IntPtr(-2147483643), ownHandle: false); | ||
public static readonly RegistryHandle HKEY_DYN_DATA = new(new IntPtr(-2147483642), ownHandle: false); | ||
|
||
public static int TryGetHKLMSubkey(string key, out RegistryHandle? regHandle) | ||
{ | ||
return SafeNativeMethods.RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, SafeNativeMethods.KEY_READ, out regHandle); | ||
} | ||
|
||
public static RegistryHandle? GetHKLMSubkey(string key) | ||
{ | ||
if (SafeNativeMethods.RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, SafeNativeMethods.KEY_READ, out var hkResult) != SafeNativeMethods.ERROR_SUCCESS || hkResult == null || hkResult.IsInvalid) | ||
return null; | ||
return hkResult; | ||
} | ||
|
||
public RegistryHandle(IntPtr hKey, bool ownHandle) : base(ownHandle) => handle = hKey; | ||
public RegistryHandle() : base(ownsHandle: true) { } | ||
|
||
/* | ||
public bool DeleteKey(string key) | ||
{ | ||
if (SafeNativeMethods.RegDeleteKey(this, key) == SafeNativeMethods.ERROR_SUCCESS) | ||
{ | ||
return true; | ||
} | ||
return false; | ||
} | ||
public RegistryHandle? CreateSubKey(string subKey) | ||
{ | ||
if (SafeNativeMethods.RegCreateKeyEx(this, subKey, 0, null, 0, SafeNativeMethods.KEY_CREATE_SUB_KEY, IntPtr.Zero, out var hkResult, out _) != SafeNativeMethods.ERROR_SUCCESS || hkResult == null || hkResult.IsInvalid) | ||
return null; | ||
return hkResult; | ||
} | ||
public bool SetValue(string valName, string value) | ||
{ | ||
if (SafeNativeMethods.RegSetValueEx(this, valName, 0, SafeNativeMethods.REG_SZ, value, value.Length * 2 + 2) != SafeNativeMethods.ERROR_SUCCESS) | ||
return false; | ||
return true; | ||
} | ||
public string? GetStringValue(string valName) | ||
{ | ||
var lpType = 0; | ||
var lpcbData = 0; | ||
if (SafeNativeMethods.RegQueryValueEx(this, valName, 0, ref lpType, null, ref lpcbData) == SafeNativeMethods.ERROR_SUCCESS && lpType == 1) | ||
{ | ||
var array = new byte[lpcbData]; | ||
var num = SafeNativeMethods.RegQueryValueEx(this, valName, 0, ref lpType, array, ref lpcbData); | ||
return new UnicodeEncoding().GetString(array); | ||
} | ||
return null; | ||
} | ||
*/ | ||
|
||
public int? GetDwordValue(string valName) | ||
{ | ||
var lpType = 4; | ||
var arraySize = 4; | ||
var array = new byte[arraySize]; | ||
if (SafeNativeMethods.RegQueryValueEx(this, valName, 0, ref lpType, array, ref arraySize) == SafeNativeMethods.ERROR_SUCCESS && lpType == 4) | ||
return BitConverter.ToInt32(array, 0); | ||
return null; | ||
} | ||
|
||
protected override bool ReleaseHandle() => SafeNativeMethods.RegCloseKey(handle) == SafeNativeMethods.ERROR_SUCCESS; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
using Microsoft.Win32.SafeHandles; | ||
|
||
using System; | ||
using System.Diagnostics; | ||
using System.Linq; | ||
|
||
using Windows.Win32; | ||
using Windows.Win32.Foundation; | ||
using Windows.Win32.Security; | ||
|
||
namespace Bannerlord.BLSE.Shared.Utils; | ||
|
||
public static class UacHelper | ||
{ | ||
private const string uacRegistryKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"; | ||
private const string uacRegistryValue = "EnableLUA"; | ||
|
||
private static uint STANDARD_RIGHTS_READ = 0x00020000; | ||
private static uint TOKEN_QUERY = 0x0008; | ||
|
||
public enum TOKEN_ELEVATION_TYPE | ||
{ | ||
TokenElevationTypeDefault = 1, | ||
TokenElevationTypeFull, | ||
TokenElevationTypeLimited | ||
} | ||
|
||
public static bool IsUacEnabled | ||
{ | ||
get | ||
{ | ||
using var key = RegistryHandle.GetHKLMSubkey(uacRegistryKey); | ||
return key?.GetDwordValue(uacRegistryValue)?.Equals(1) == true; | ||
} | ||
} | ||
|
||
public static unsafe bool? IsProcessElevated(SafeProcessHandle processHandle) | ||
{ | ||
try | ||
{ | ||
if (IsUacEnabled) | ||
{ | ||
if (!PInvoke.OpenProcessToken(processHandle, TOKEN_ACCESS_MASK.TOKEN_READ, out var tokenHandle) || tokenHandle.IsClosed || tokenHandle.IsInvalid) | ||
return null; | ||
using var __ = tokenHandle; | ||
|
||
var elevationResult = TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault; | ||
const uint elevationResultSize = sizeof(TOKEN_ELEVATION_TYPE); | ||
uint result = 0; | ||
if (PInvoke.GetTokenInformation((HANDLE) tokenHandle.DangerousGetHandle(), TOKEN_INFORMATION_CLASS.TokenElevationType, &elevationResult, elevationResultSize, &result)) | ||
return elevationResult == TOKEN_ELEVATION_TYPE.TokenElevationTypeFull; | ||
|
||
return null; | ||
} | ||
} | ||
catch (Exception) | ||
{ | ||
return null; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
public static void CheckSteam() | ||
{ | ||
var thisProcess = Process.GetCurrentProcess(); | ||
|
||
var steamProcesses = Process.GetProcessesByName("steam"); | ||
if (steamProcesses.Length != 1) return; | ||
var steamProcess = steamProcesses.First(); | ||
|
||
using var steamProcessHandle = steamProcess.SafeHandle; | ||
var steamElevated = IsProcessElevated(steamProcessHandle); | ||
if (steamElevated is null) return; | ||
|
||
using var thisProcessHandle = thisProcess.SafeHandle; | ||
var thisElevated = IsProcessElevated(thisProcessHandle); | ||
if (thisElevated is null) return; | ||
|
||
if (steamElevated == true && thisElevated != true) | ||
{ | ||
MessageBoxDialog.Show(@"Steam is launched as Admin, but BLSE is not! | ||
The game won't work if Steam has higher privileges than the game! | ||
Please run Steam as a user or run the game as Admin!", "Error from BLSE!", MessageBoxButtons.Ok, MessageBoxIcon.Error); | ||
Environment.Exit(1); | ||
} | ||
} | ||
} |