using System; using System.Security.AccessControl; using System.Security.Principal; using System.Threading; namespace LibreHardwareMonitor.Hardware; internal static class Mutexes { private static Mutex _ecMutex; private static Mutex _isaBusMutex; private static Mutex _pciBusMutex; private static Mutex _razerMutex; private static Mutex _usbSensors; /// /// Opens the mutexes. /// public static void Open() { _isaBusMutex = CreateOrOpenExistingMutex("Global\\Access_ISABUS.HTP.Method"); _pciBusMutex = CreateOrOpenExistingMutex("Global\\Access_PCI"); _ecMutex = CreateOrOpenExistingMutex("Global\\Access_EC"); _razerMutex = CreateOrOpenExistingMutex("Global\\RazerReadWriteGuardMutex"); _usbSensors = CreateOrOpenExistingMutex("Global\\Access_USB_Sensors"); static Mutex CreateOrOpenExistingMutex(string name) { try { var worldRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow); var mutexSecurity = new MutexSecurity(); mutexSecurity.AddAccessRule(worldRule); #if NETFRAMEWORK return new Mutex(false, name, out _, mutexSecurity); #else return MutexAcl.Create(false, name, out _, mutexSecurity); #endif } catch (UnauthorizedAccessException) { try { return Mutex.OpenExisting(name); } catch { // Ignored. } } return null; } } /// /// Closes the mutexes. /// public static void Close() { _isaBusMutex?.Close(); _pciBusMutex?.Close(); _ecMutex?.Close(); _razerMutex?.Close(); _usbSensors?.Close(); } public static bool WaitIsaBus(int millisecondsTimeout) { return WaitMutex(_isaBusMutex, millisecondsTimeout); } public static void ReleaseIsaBus() { _isaBusMutex?.ReleaseMutex(); } public static bool WaitPciBus(int millisecondsTimeout) { return WaitMutex(_pciBusMutex, millisecondsTimeout); } public static void ReleasePciBus() { _pciBusMutex?.ReleaseMutex(); } public static bool WaitEc(int millisecondsTimeout) { return WaitMutex(_ecMutex, millisecondsTimeout); } public static void ReleaseEc() { _ecMutex?.ReleaseMutex(); } public static bool WaitRazer(int millisecondsTimeout) { return WaitMutex(_razerMutex, millisecondsTimeout); } public static void ReleaseRazer() { _razerMutex?.ReleaseMutex(); } public static bool WaitUsbSensors(int millisecondsTimeout) { return WaitMutex(_usbSensors, millisecondsTimeout); } public static void ReleaseUsbSensors() { _usbSensors?.ReleaseMutex(); } private static bool WaitMutex(Mutex mutex, int millisecondsTimeout) { if (mutex == null) return true; try { return mutex.WaitOne(millisecondsTimeout, false); } catch (AbandonedMutexException) { return true; } catch (InvalidOperationException) { return false; } } }