private void OnRegistryChanged(object sender = null, RegistryChangeEventArgs e = null) { QueryRegistry(); RefreshUI(); bool hasMoreThanFivePlaythroughs = bytes?.Length > 45; if (!showWarning && hasMoreThanFivePlaythroughs) { showWarning = true; MessageBox.Show("We detected you started more than 5 playthroughs. This tool can only unlock your first 5 " + "playthroughs. Therefore, the locked status shown may be incorrect. Check the readme for more details.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); } }
private void MonitorThread() { try { IntPtr ptr = IntPtr.Zero; lock (this) { if (this._registryPath.StartsWith("HKEY_CLASSES_ROOT")) { this._monitorKey = Registry.ClassesRoot.OpenSubKey(this._registryPath.Substring(18)); } else if (this._registryPath.StartsWith("HKCR")) { this._monitorKey = Registry.ClassesRoot.OpenSubKey(this._registryPath.Substring(5)); } else if (this._registryPath.StartsWith("HKEY_CURRENT_USER")) { this._monitorKey = Registry.CurrentUser.OpenSubKey(this._registryPath.Substring(18)); } else if (this._registryPath.StartsWith("HKCU")) { this._monitorKey = Registry.CurrentUser.OpenSubKey(this._registryPath.Substring(5)); } else if (this._registryPath.StartsWith("HKEY_LOCAL_MACHINE")) { this._monitorKey = Registry.LocalMachine.OpenSubKey(this._registryPath.Substring(19)); } else if (this._registryPath.StartsWith("HKLM")) { this._monitorKey = Registry.LocalMachine.OpenSubKey(this._registryPath.Substring(5)); } else if (this._registryPath.StartsWith("HKEY_USERS")) { this._monitorKey = Registry.Users.OpenSubKey(this._registryPath.Substring(11)); } else if (this._registryPath.StartsWith("HKU")) { this._monitorKey = Registry.Users.OpenSubKey(this._registryPath.Substring(4)); } else if (this._registryPath.StartsWith("HKEY_CURRENT_CONFIG")) { this._monitorKey = Registry.CurrentConfig.OpenSubKey(this._registryPath.Substring(20)); } else if (this._registryPath.StartsWith("HKCC")) { this._monitorKey = Registry.CurrentConfig.OpenSubKey(this._registryPath.Substring(5)); } // Fetch the native handle if (this._monitorKey != null) { object hkey = typeof(RegistryKey).InvokeMember( "hkey", BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic, null, this._monitorKey, null ); ptr = (IntPtr)typeof(SafeHandle).InvokeMember( "handle", BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic, null, hkey, null); } } if (ptr != IntPtr.Zero) { while (true) { // If this._monitorThread is null that probably means Dispose is being called. Don't monitor anymore. if ((this._monitorThread == null) || (this._monitorKey == null)) { break; } // RegNotifyChangeKeyValue blocks until a change occurs. int result = RegNotifyChangeKeyValue(ptr, true, this._filter, IntPtr.Zero, false); if ((this._monitorThread == null) || (this._monitorKey == null)) { break; } if (result == 0) { if (this.Changed != null) { RegistryChangeEventArgs e = new RegistryChangeEventArgs(this); this.Changed(this, e); if (e.Stop) { break; } } } else { if (this.Error != null) { Win32Exception ex = new Win32Exception(); // Unless the exception is thrown, nobody is nice enough to set a good stacktrace for us. Set it ourselves. typeof(Exception).InvokeMember( "_stackTrace", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.SetField, null, ex, new object[] { new StackTrace(true) } ); RegistryChangeEventArgs e = new RegistryChangeEventArgs(this); e.Exception = ex; this.Error(this, e); } break; } } } } catch (Exception ex) { if (this.Error != null) { RegistryChangeEventArgs e = new RegistryChangeEventArgs(this); e.Exception = ex; this.Error(this, e); } } finally { this.Stop(); } }