2022-11-15 17:00:13 +01:00
|
|
|
using System.Security.Principal;
|
|
|
|
|
using System.Security.AccessControl;
|
2022-12-11 02:35:46 +01:00
|
|
|
using Microsoft.Win32;
|
|
|
|
|
using System.Diagnostics;
|
2022-12-12 20:03:15 +01:00
|
|
|
using System.Reflection;
|
2022-11-15 17:00:13 +01:00
|
|
|
|
|
|
|
|
namespace CommonHelpers
|
|
|
|
|
{
|
|
|
|
|
public static class Instance
|
|
|
|
|
{
|
|
|
|
|
public static LibreHardwareMonitor.Hardware.Computer HardwareComputer = new LibreHardwareMonitor.Hardware.Computer
|
|
|
|
|
{
|
|
|
|
|
IsCpuEnabled = true,
|
|
|
|
|
IsGpuEnabled = true,
|
2022-11-15 19:18:44 +01:00
|
|
|
IsMemoryEnabled = true,
|
2022-11-15 17:00:13 +01:00
|
|
|
IsStorageEnabled = true,
|
|
|
|
|
IsBatteryEnabled = true
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
private static Mutex? runOnceMutex;
|
2022-11-20 21:17:21 +01:00
|
|
|
private static Mutex? globalLockMutex;
|
2022-11-26 20:09:30 +01:00
|
|
|
private static bool useKernelDrivers;
|
2022-11-15 17:00:13 +01:00
|
|
|
|
|
|
|
|
private const String GLOBAL_MUTEX_NAME = "Global\\SteamDeckToolsCommonHelpers";
|
2022-12-14 11:46:42 +01:00
|
|
|
private const int GLOBAL_DEFAULT_TIMEOUT = 10000;
|
2022-11-15 17:00:13 +01:00
|
|
|
|
2022-12-10 11:23:47 +01:00
|
|
|
public static bool WantsRunOnStartup
|
|
|
|
|
{
|
|
|
|
|
get { return Environment.GetCommandLineArgs().Contains("-run-on-startup"); }
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-11 13:26:46 +01:00
|
|
|
public static bool Uninstall
|
|
|
|
|
{
|
|
|
|
|
get { return Environment.GetCommandLineArgs().Contains("-uninstall"); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static bool IsDEBUG
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
#if DEBUG
|
|
|
|
|
return true;
|
|
|
|
|
#else
|
|
|
|
|
return false;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void OnUninstall(Action action)
|
|
|
|
|
{
|
|
|
|
|
if (Uninstall)
|
|
|
|
|
{
|
|
|
|
|
action();
|
|
|
|
|
Environment.Exit(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-26 20:09:30 +01:00
|
|
|
public static bool UseKernelDrivers
|
|
|
|
|
{
|
|
|
|
|
get { return useKernelDrivers; }
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (useKernelDrivers == value)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
useKernelDrivers = value;
|
|
|
|
|
|
|
|
|
|
if (value)
|
|
|
|
|
Vlv0100.Open();
|
|
|
|
|
else
|
|
|
|
|
Vlv0100.Close();
|
|
|
|
|
|
|
|
|
|
// CPU requires reading RyzenSMU
|
|
|
|
|
HardwareComputer.IsCpuEnabled = value;
|
|
|
|
|
HardwareComputer.Reset();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-20 21:17:21 +01:00
|
|
|
public static Mutex? WaitGlobalMutex(int timeoutMs)
|
|
|
|
|
{
|
|
|
|
|
if (globalLockMutex == null)
|
|
|
|
|
globalLockMutex = TryCreateOrOpenExistingMutex(GLOBAL_MUTEX_NAME);
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (globalLockMutex.WaitOne(timeoutMs))
|
|
|
|
|
return globalLockMutex;
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2022-11-23 10:13:16 +01:00
|
|
|
catch (AbandonedMutexException)
|
2022-11-20 21:17:21 +01:00
|
|
|
{
|
|
|
|
|
return globalLockMutex;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static T WithGlobalMutex<T>(int timeoutMs, Func<T> func)
|
|
|
|
|
{
|
|
|
|
|
var mutex = WaitGlobalMutex(timeoutMs);
|
|
|
|
|
if (mutex is null)
|
|
|
|
|
return default(T);
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
return func();
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
mutex.ReleaseMutex();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-26 20:09:30 +01:00
|
|
|
public static void Open(String title, bool useKernelDrivers, String? runOnce = null, int runOnceTimeout = 100)
|
2022-11-15 17:00:13 +01:00
|
|
|
{
|
|
|
|
|
if (runOnce is not null)
|
|
|
|
|
{
|
|
|
|
|
RunOnce(title, runOnce, runOnceTimeout);
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-20 21:17:21 +01:00
|
|
|
var mutex = WaitGlobalMutex(GLOBAL_DEFAULT_TIMEOUT);
|
|
|
|
|
|
2022-11-23 10:13:16 +01:00
|
|
|
if (mutex is null)
|
2022-11-15 17:00:13 +01:00
|
|
|
{
|
2022-11-23 10:13:16 +01:00
|
|
|
Fatal(title, "Failed to acquire global mutex.");
|
2022-11-26 20:09:30 +01:00
|
|
|
return;
|
2022-11-23 10:13:16 +01:00
|
|
|
}
|
2022-11-15 17:00:13 +01:00
|
|
|
|
2022-11-23 10:13:16 +01:00
|
|
|
try
|
|
|
|
|
{
|
2022-11-26 20:09:30 +01:00
|
|
|
UseKernelDrivers = useKernelDrivers;
|
|
|
|
|
|
|
|
|
|
if (Vlv0100.IsOpen && !Vlv0100.IsSupported)
|
2022-11-15 17:00:13 +01:00
|
|
|
{
|
|
|
|
|
String message = "";
|
|
|
|
|
message += "Current device is not supported.\n";
|
2022-11-26 20:09:30 +01:00
|
|
|
message += "FirmwareVersion: " + Vlv0100.FirmwareVersion.ToString("X") + "\n";
|
|
|
|
|
message += "BoardID: " + Vlv0100.BoardID.ToString("X") + "\n";
|
|
|
|
|
message += "PDCS: " + Vlv0100.PDCS.ToString("X") + "\n";
|
2022-11-15 17:00:13 +01:00
|
|
|
|
|
|
|
|
Fatal(title, message);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HardwareComputer.Open();
|
2022-11-20 21:17:21 +01:00
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
mutex.ReleaseMutex();
|
2022-11-15 17:00:13 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-11 02:35:46 +01:00
|
|
|
public static void RunOnce(String? title, String mutexName, int runOnceTimeout = 1000)
|
2022-11-15 17:00:13 +01:00
|
|
|
{
|
|
|
|
|
runOnceMutex = TryCreateOrOpenExistingMutex(mutexName);
|
|
|
|
|
|
2022-12-12 18:32:28 +01:00
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (!runOnceMutex.WaitOne(runOnceTimeout))
|
|
|
|
|
{
|
2022-12-14 11:48:02 +01:00
|
|
|
Fatal(title, "Run many times", false);
|
2022-12-12 18:32:28 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (AbandonedMutexException)
|
2022-11-15 17:00:13 +01:00
|
|
|
{
|
2022-12-12 18:32:28 +01:00
|
|
|
// it is still OK
|
2022-11-15 17:00:13 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-14 11:34:11 +01:00
|
|
|
public static void WithSentry(Action action, string? dsn = null)
|
2022-12-12 15:08:00 +01:00
|
|
|
{
|
2022-12-14 11:34:11 +01:00
|
|
|
// Overwrite DSN
|
|
|
|
|
if (dsn != null)
|
|
|
|
|
{
|
|
|
|
|
Log.SENTRY_DSN = dsn;
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-12 15:08:00 +01:00
|
|
|
using (Sentry.SentrySdk.Init(Log.SentryOptions))
|
|
|
|
|
{
|
|
|
|
|
action();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-12 20:03:15 +01:00
|
|
|
public static String ApplicationName
|
|
|
|
|
{
|
|
|
|
|
get { return Assembly.GetEntryAssembly()?.GetName().Name ?? "unknown"; }
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-11 02:35:46 +01:00
|
|
|
public static String MachineID
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2022-12-12 20:03:15 +01:00
|
|
|
using (var registryKey = Registry.CurrentUser.CreateSubKey(@"Software\SteamDeckTools", true))
|
2022-12-11 02:35:46 +01:00
|
|
|
{
|
|
|
|
|
var machineID = registryKey?.GetValue("MachineID") as string;
|
2022-12-12 15:08:00 +01:00
|
|
|
if (machineID is null)
|
|
|
|
|
{
|
|
|
|
|
registryKey?.SetValue("MachineID", Guid.NewGuid().ToString());
|
|
|
|
|
machineID = registryKey?.GetValue("MachineID") as string;
|
|
|
|
|
}
|
2022-12-11 02:35:46 +01:00
|
|
|
|
2022-12-12 15:08:00 +01:00
|
|
|
return machineID ?? "undefined";
|
2022-12-11 02:35:46 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception)
|
|
|
|
|
{
|
|
|
|
|
return "exception";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Version? ApplicationVersion
|
|
|
|
|
{
|
|
|
|
|
get => System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static String ProductVersion
|
|
|
|
|
{
|
|
|
|
|
get => Application.ProductVersion;
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-11 13:31:30 +01:00
|
|
|
private static System.Timers.Timer? updateTimer;
|
|
|
|
|
|
|
|
|
|
public static void RunUpdater(string Title, bool user = false, int recheckIntervalHours = 24)
|
2022-12-11 02:35:46 +01:00
|
|
|
{
|
2022-12-11 13:31:30 +01:00
|
|
|
// Schedule updater in 24h
|
|
|
|
|
if (updateTimer == null && !user && recheckIntervalHours > 0)
|
|
|
|
|
{
|
|
|
|
|
updateTimer = new System.Timers.Timer
|
|
|
|
|
{
|
|
|
|
|
Interval = recheckIntervalHours * 60 * 60 * 1000 // 24h
|
|
|
|
|
};
|
|
|
|
|
updateTimer.Elapsed += delegate { RunUpdater(Title, false); };
|
|
|
|
|
updateTimer.Start();
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-11 02:35:46 +01:00
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Process.Start(new ProcessStartInfo()
|
|
|
|
|
{
|
|
|
|
|
FileName = "Updater.exe",
|
2022-12-14 11:34:11 +01:00
|
|
|
ArgumentList = {
|
|
|
|
|
user ? "-user" : "-first",
|
|
|
|
|
"-app", ApplicationName,
|
|
|
|
|
"-version", ProductVersion
|
|
|
|
|
},
|
2022-12-11 02:35:46 +01:00
|
|
|
UseShellExecute = false
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
catch { }
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-14 11:48:02 +01:00
|
|
|
public static void Fatal(String? title, String message, bool capture = true)
|
2022-11-15 17:00:13 +01:00
|
|
|
{
|
2022-12-14 11:48:02 +01:00
|
|
|
if (capture)
|
|
|
|
|
Log.TraceError("FATAL: {0}", message);
|
2022-12-11 02:35:46 +01:00
|
|
|
if (title is not null)
|
|
|
|
|
MessageBox.Show(message, title, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
2022-11-15 17:00:13 +01:00
|
|
|
Environment.Exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static Mutex TryCreateOrOpenExistingMutex(string name)
|
|
|
|
|
{
|
|
|
|
|
MutexSecurity mutexSecurity = new();
|
|
|
|
|
SecurityIdentifier identity = new(WellKnownSidType.WorldSid, null);
|
|
|
|
|
mutexSecurity.AddAccessRule(new MutexAccessRule(identity, MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Allow));
|
|
|
|
|
|
|
|
|
|
var mutex = new Mutex(false, name, out _);
|
|
|
|
|
mutex.SetAccessControl(mutexSecurity);
|
|
|
|
|
return mutex;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|