diff --git a/TrustedUninstaller.CLI/Properties/resources/CLI-Resources.7z b/TrustedUninstaller.CLI/Properties/resources/CLI-Resources.7z index d82b2f3..105bc89 100644 Binary files a/TrustedUninstaller.CLI/Properties/resources/CLI-Resources.7z and b/TrustedUninstaller.CLI/Properties/resources/CLI-Resources.7z differ diff --git a/TrustedUninstaller.Shared/Actions/CmdAction.cs b/TrustedUninstaller.Shared/Actions/CmdAction.cs index 739190a..fd348fd 100644 --- a/TrustedUninstaller.Shared/Actions/CmdAction.cs +++ b/TrustedUninstaller.Shared/Actions/CmdAction.cs @@ -18,7 +18,10 @@ namespace TrustedUninstaller.Shared.Actions if (InProgress) throw new TaskInProgressException("Another Cmd action was called while one was in progress."); InProgress = true; - Console.WriteLine($"Running cmd command '{Command}'..."); + var privilegeText = RunAs == Privilege.CurrentUser ? " as the current user" : RunAs == Privilege.CurrentUserElevated ? " as the current user elevated" : RunAs == Privilege.System ? + " as the system account" : ""; + + Console.WriteLine($"Running cmd command '{Command}'{privilegeText}..."); ExitCode = null; @@ -149,7 +152,7 @@ namespace TrustedUninstaller.Shared.Actions ErrorLogger.WriteToErrorLog("Error fetching process exit code. (1)", null, "CmdAction Error", Command); } - if (exitCode != 0) + if (exitCode != 0 && !Command.Contains("ProcessHacker\\x64\\ProcessHacker.exe")) { StandardError = error.ToString(); Console.WriteLine($"cmd instance exited with error code: {exitCode}"); @@ -189,7 +192,7 @@ namespace TrustedUninstaller.Shared.Actions { WindowStyle = ProcessWindowStyle.Normal, FileName = "cmd.exe", - Arguments = "/C " + $"\"{Environment.ExpandEnvironmentVariables(this.Command)}\"", + Arguments = "/C " + $"{this.Command}", UseShellExecute = false, RedirectStandardError = true, RedirectStandardOutput = true, diff --git a/TrustedUninstaller.Shared/Actions/FileAction.cs b/TrustedUninstaller.Shared/Actions/FileAction.cs index 706f0bd..f558843 100644 --- a/TrustedUninstaller.Shared/Actions/FileAction.cs +++ b/TrustedUninstaller.Shared/Actions/FileAction.cs @@ -388,12 +388,6 @@ namespace TrustedUninstaller.Shared.Actions } await DeleteFile(file, true); - - using (var writer = new StreamWriter("Logs\\FileChecklist.txt", true)) - { - writer.WriteLine($"File Path: {file}\r\nDeleted: {!File.Exists(file)}\r\n" + - $"======================"); - } } } //Loop through any subdirectories @@ -710,11 +704,6 @@ namespace TrustedUninstaller.Shared.Actions ErrorLogger.WriteToErrorLog(e.Message, e.StackTrace, $"FileAction Error: Error while trying to delete {realPath}."); } - using (var writer = new StreamWriter("Logs\\FileChecklist.txt", true)) - { - writer.WriteLine($"File Path: {realPath}\r\nDeleted: {!File.Exists(realPath)}\r\n" + - $"======================"); - } } else { diff --git a/TrustedUninstaller.Shared/Actions/PowershellAction.cs b/TrustedUninstaller.Shared/Actions/PowershellAction.cs index 3c47f0f..3241d95 100644 --- a/TrustedUninstaller.Shared/Actions/PowershellAction.cs +++ b/TrustedUninstaller.Shared/Actions/PowershellAction.cs @@ -19,7 +19,10 @@ namespace TrustedUninstaller.Shared.Actions if (InProgress) throw new TaskInProgressException("Another Powershell action was called while one was in progress."); InProgress = true; - Console.WriteLine($"Running PowerShell command '{Command}'..."); + var privilegeText = RunAs == Privilege.CurrentUser ? " as the current user" : RunAs == Privilege.CurrentUserElevated ? " as the current user elevated" : RunAs == Privilege.System ? + " as the system account" : ""; + + Console.WriteLine($"Running PowerShel command '{Command}'{privilegeText}..."); WinUtil.CheckKph(); @@ -153,7 +156,7 @@ namespace TrustedUninstaller.Shared.Actions if (exitCode != 0) { Console.WriteLine($"PowerShell instance exited with error code: {exitCode}"); - if (!String.IsNullOrEmpty(StandardError)) Console.WriteLine($"Error message: {StandardError}"); + if (!String.IsNullOrWhiteSpace(StandardError)) Console.WriteLine($"Error message: {StandardError}"); ErrorLogger.WriteToErrorLog("PowerShell exited with a non-zero exit code: " + exitCode, null, "PowerShellAction Error", Command); @@ -161,7 +164,7 @@ namespace TrustedUninstaller.Shared.Actions } else { - if (!String.IsNullOrEmpty(StandardError)) Console.WriteLine($"Error output: {StandardError}"); + if (!String.IsNullOrWhiteSpace(StandardError)) Console.WriteLine($"Error output: {StandardError}"); ExitCode = 0; } @@ -242,7 +245,7 @@ namespace TrustedUninstaller.Shared.Actions if (process.ExitCode != 0) { Console.WriteLine($"PowerShell instance exited with error code: {process.ExitCode}"); - if (!String.IsNullOrEmpty(StandardError)) Console.WriteLine($"Error message: {StandardError}"); + if (!String.IsNullOrWhiteSpace(StandardError)) Console.WriteLine($"Error message: {StandardError}"); ErrorLogger.WriteToErrorLog("PowerShell exited with a non-zero exit code: " + process.ExitCode, null, "PowerShellAction Error", Command); @@ -250,7 +253,7 @@ namespace TrustedUninstaller.Shared.Actions } else { - if (!String.IsNullOrEmpty(StandardError)) Console.WriteLine($"Error output: {StandardError}"); + if (!String.IsNullOrWhiteSpace(StandardError)) Console.WriteLine($"Error output: {StandardError}"); ExitCode = 0; } diff --git a/TrustedUninstaller.Shared/Actions/RunAction.cs b/TrustedUninstaller.Shared/Actions/RunAction.cs index 6744e55..8dfd76c 100644 --- a/TrustedUninstaller.Shared/Actions/RunAction.cs +++ b/TrustedUninstaller.Shared/Actions/RunAction.cs @@ -25,8 +25,11 @@ namespace TrustedUninstaller.Shared.Actions if (RawPath != null) RawPath = Environment.ExpandEnvironmentVariables(RawPath); InProgress = true; - if (Arguments == null) Console.WriteLine($"Running '{Exe}'..."); - else Console.WriteLine($"Running '{Exe}' with arguments '{Arguments}'..."); + var privilegeText = RunAs == Privilege.CurrentUser ? " as the current user" : RunAs == Privilege.CurrentUserElevated ? " as the current user elevated" : RunAs == Privilege.System ? + " as the system account" : ""; + + if (Arguments == null) Console.WriteLine($"Running '{Exe + privilegeText}'..."); + else Console.WriteLine($"Running '{Exe}' with arguments '{Arguments + privilegeText}'..."); WinUtil.CheckKph(); @@ -221,6 +224,8 @@ namespace TrustedUninstaller.Shared.Actions exeProcess.CancelOutputRead(); if (ShowError) exeProcess.CancelErrorRead(); + + exeProcess.Dispose(); } private void RunAsPrivilegedProcess(string file) { @@ -324,6 +329,8 @@ namespace TrustedUninstaller.Shared.Actions exeProcess.CancelOutputRead(); if (ShowError) exeProcess.CancelErrorRead(); + + exeProcess.Dispose(); } private static bool ExeRunning(string name, int id) @@ -340,40 +347,54 @@ namespace TrustedUninstaller.Shared.Actions private void PrivilegedProcOutputHandler(object sendingProcess, AugmentedProcess.DataReceivedEventArgs outLine) { - // Collect the sort command output. - if (!String.IsNullOrEmpty(outLine.Data)) + try { - var outputString = outLine.Data; + // Collect the sort command output. + if (!String.IsNullOrEmpty(outLine.Data)) + { + var outputString = outLine.Data; - if (outputString.Contains("\\AME")) + if (outputString.Contains("\\AME")) + { + outputString = outputString.Substring(outputString.IndexOf('>') + 1); + } + Console.WriteLine(outputString); + Output += outputString + Environment.NewLine; + } + else { - outputString = outputString.Substring(outputString.IndexOf('>') + 1); + Console.WriteLine(); } - Console.WriteLine(outputString); - Output += outputString + Environment.NewLine; } - else + catch (Exception e) { - Console.WriteLine(); + ErrorLogger.WriteToErrorLog("Error processing process output", e.StackTrace, "RunAction Error", Exe); } } private void ProcOutputHandler(object sendingProcess, DataReceivedEventArgs outLine) { - // Collect the sort command output. - if (!String.IsNullOrEmpty(outLine.Data)) + try { - var outputString = outLine.Data; + // Collect the sort command output. + if (!String.IsNullOrEmpty(outLine.Data)) + { + var outputString = outLine.Data; - if (outputString.Contains("\\AME")) + if (outputString.Contains("\\AME")) + { + outputString = outputString.Substring(outputString.IndexOf('>') + 1); + } + Console.WriteLine(outputString); + Output += outputString + Environment.NewLine; + } + else { - outputString = outputString.Substring(outputString.IndexOf('>') + 1); + Console.WriteLine(); } - Console.WriteLine(outputString); - Output += outputString + Environment.NewLine; } - else + catch (Exception e) { - Console.WriteLine(); + ErrorLogger.WriteToErrorLog("Error processing process output", e.StackTrace, "RunAction Error", Exe); } } } diff --git a/TrustedUninstaller.Shared/Actions/ServiceAction.cs b/TrustedUninstaller.Shared/Actions/ServiceAction.cs index a9d5105..cb77a18 100644 --- a/TrustedUninstaller.Shared/Actions/ServiceAction.cs +++ b/TrustedUninstaller.Shared/Actions/ServiceAction.cs @@ -17,7 +17,7 @@ using YamlDotNet.Serialization; namespace TrustedUninstaller.Shared.Actions { - internal enum ServiceOperation + public enum ServiceOperation { Stop, Continue, @@ -26,7 +26,7 @@ namespace TrustedUninstaller.Shared.Actions Delete, Change } - internal class ServiceAction : TaskAction, ITaskAction + public class ServiceAction : TaskAction, ITaskAction { public void RunTaskOnMainThread() { throw new NotImplementedException(); } [YamlMember(typeof(ServiceOperation), Alias = "operation")] @@ -175,6 +175,9 @@ namespace TrustedUninstaller.Shared.Actions { Console.WriteLine($"No services found matching '{ServiceName}'."); //ErrorLogger.WriteToErrorLog($"The service matching '{ServiceName}' does not exist.", Environment.StackTrace, "ServiceAction Error"); + if (Operation == ServiceOperation.Start) + throw new ArgumentException("Service " + ServiceName + " not found."); + return false; } @@ -182,98 +185,207 @@ namespace TrustedUninstaller.Shared.Actions var cmdAction = new CmdAction(); - if (Operation == ServiceOperation.Delete || Operation == ServiceOperation.Stop) + if ((Operation == ServiceOperation.Delete && DeleteStop) || Operation == ServiceOperation.Stop) { if (RegexNoKill.Any(regex => Regex.Match(ServiceName, regex, RegexOptions.IgnoreCase).Success)) { Console.WriteLine($"Skipping {ServiceName}..."); return false; } - - foreach (ServiceController dependentService in service.DependentServices) + + try + { + foreach (ServiceController dependentService in service.DependentServices.Where(x => x.Status != ServiceControllerStatus.Stopped)) + { + Console.WriteLine($"Killing dependent service {dependentService.ServiceName}..."); + + if (dependentService.Status != ServiceControllerStatus.StopPending && dependentService.Status != ServiceControllerStatus.Stopped) + { + try + { + dependentService.Stop(); + } + catch (Exception e) + { + dependentService.Refresh(); + if (dependentService.Status != ServiceControllerStatus.Stopped && dependentService.Status != ServiceControllerStatus.StopPending) + ErrorLogger.WriteToErrorLog("Dependent service stop failed: " + e.Message, e.StackTrace, "ServiceAction Warning", dependentService.ServiceName); + } + + cmdAction.Command = Environment.Is64BitOperatingSystem ? + $"ProcessHacker\\x64\\ProcessHacker.exe -s -elevate -c -ctype service -cobject {dependentService.ServiceName} -caction stop" : + $"ProcessHacker\\x86\\ProcessHacker.exe -s -elevate -c -ctype service -cobject {dependentService.ServiceName} -caction stop"; + if (AmeliorationUtil.UseKernelDriver) cmdAction.RunTaskOnMainThread(); + } + + Console.WriteLine("Waiting for the dependent service to stop..."); + try + { + dependentService.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromMilliseconds(5000)); + } + catch (Exception e) + { + dependentService.Refresh(); + if (service.Status != ServiceControllerStatus.Stopped) + ErrorLogger.WriteToErrorLog("Dependent service stop timeout exceeded.", e.StackTrace, "ServiceAction Warning", ServiceName); + } + + try + { + var killServ = new TaskKillAction() + { + ProcessID = Win32.ServiceEx.GetServiceProcessId(dependentService.ServiceName) + }; + await killServ.RunTask(); + } + catch (Exception e) + { + dependentService.Refresh(); + if (dependentService.Status != ServiceControllerStatus.Stopped) + ErrorLogger.WriteToErrorLog($"Could not kill dependent service {dependentService.ServiceName}.", + e.StackTrace, "ServiceAction Error", ServiceName); + } + } + } + catch (Exception e) + { + ErrorLogger.WriteToErrorLog($"Error killing dependent services: " + e.Message, + e.StackTrace, "ServiceAction Error", ServiceName); + } + } + + if (Operation == ServiceOperation.Delete) + { + + if (DeleteStop && service.Status != ServiceControllerStatus.StopPending && service.Status != ServiceControllerStatus.Stopped) { - Console.WriteLine($"Killing dependent service {dependentService.ServiceName}..."); - try { - dependentService.Stop(); + service.Stop(); } catch (Exception e) { - ErrorLogger.WriteToErrorLog("Service stop failed: " + e.Message, e.StackTrace, "ServiceAction Warning", ServiceName); + service.Refresh(); + if (service.Status != ServiceControllerStatus.Stopped && service.Status != ServiceControllerStatus.StopPending) + ErrorLogger.WriteToErrorLog("Service stop failed: " + e.Message, e.StackTrace, "ServiceAction Warning", ServiceName); } cmdAction.Command = Environment.Is64BitOperatingSystem ? - $"ProcessHacker\\x64\\ProcessHacker.exe -s -elevate -c -ctype service -cobject {dependentService.ServiceName} -caction stop" : - $"ProcessHacker\\x86\\ProcessHacker.exe -s -elevate -c -ctype service -cobject {dependentService.ServiceName} -caction stop"; + $"ProcessHacker\\x64\\ProcessHacker.exe -s -elevate -c -ctype service -cobject {service.ServiceName} -caction stop" : + $"ProcessHacker\\x86\\ProcessHacker.exe -s -elevate -c -ctype service -cobject {service.ServiceName} -caction stop"; if (AmeliorationUtil.UseKernelDriver) cmdAction.RunTaskOnMainThread(); Console.WriteLine("Waiting for the service to stop..."); - int delay = 100; - while (dependentService.Status != ServiceControllerStatus.Stopped && delay <= 1000) + try { - dependentService.Refresh(); - //Wait for the service to stop - Task.Delay(delay).Wait(); - delay += 100; + service.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromMilliseconds(5000)); } - if (delay >= 1000) + catch (Exception e) { - Console.WriteLine("\r\nService stop timeout exceeded."); + service.Refresh(); + if (service.Status != ServiceControllerStatus.Stopped) + ErrorLogger.WriteToErrorLog("Service stop timeout exceeded.", e.StackTrace, "ServiceAction Warning", ServiceName); } try { var killServ = new TaskKillAction() { - ProcessID = Win32.ServiceEx.GetServiceProcessId(dependentService.ServiceName) + ProcessID = Win32.ServiceEx.GetServiceProcessId(service.ServiceName) }; await killServ.RunTask(); } catch (Exception e) { - ErrorLogger.WriteToErrorLog($"Could not kill dependent service {dependentService.ServiceName}.", - e.StackTrace, "ServiceAction Error"); + service.Refresh(); + if (service.Status != ServiceControllerStatus.Stopped) + ErrorLogger.WriteToErrorLog($"Could not kill service {service.ServiceName}.", e.StackTrace, "ServiceAction Error"); } } - - if (service.ServiceName == "SgrmAgent" && ((Operation == ServiceOperation.Delete && DeleteStop) || Operation == ServiceOperation.Stop)) + + if (RegistryDelete) { - await new TaskKillAction() { ProcessName = "SgrmBroker" }.RunTask(); + var action = new RegistryKeyAction() + { + KeyName = $@"HKLM\SYSTEM\CurrentControlSet\Services\{ServiceName}", + Operation = RegistryKeyOperation.Delete + }; + await action.RunTask(); } - } - - if (Operation == ServiceOperation.Delete) - { - - if (DeleteStop && service.Status != ServiceControllerStatus.StopPending && service.Status != ServiceControllerStatus.Stopped) + else { try { - service.Stop(); + ServiceInstaller ServiceInstallerObj = new ServiceInstaller(); + ServiceInstallerObj.Context = new InstallContext(); + ServiceInstallerObj.ServiceName = service.ServiceName; + ServiceInstallerObj.Uninstall(null); } catch (Exception e) { - ErrorLogger.WriteToErrorLog("Service stop failed: " + e.Message, e.StackTrace, "ServiceAction Warning", ServiceName); + ErrorLogger.WriteToErrorLog("Service uninstall failed: " + e.Message, e.StackTrace, "ServiceAction Warning", ServiceName); } - cmdAction.Command = Environment.Is64BitOperatingSystem ? - $"ProcessHacker\\x64\\ProcessHacker.exe -s -elevate -c -ctype service -cobject {service.ServiceName} -caction stop" : - $"ProcessHacker\\x86\\ProcessHacker.exe -s -elevate -c -ctype service -cobject {service.ServiceName} -caction stop"; + $"ProcessHacker\\x64\\ProcessHacker.exe -s -elevate -c -ctype service -cobject {service.ServiceName} -caction delete" : + $"ProcessHacker\\x86\\ProcessHacker.exe -s -elevate -c -ctype service -cobject {service.ServiceName} -caction delete"; if (AmeliorationUtil.UseKernelDriver) cmdAction.RunTaskOnMainThread(); } - Console.WriteLine("Waiting for the service to stop..."); - int delay = 100; - while (DeleteStop && service.Status != ServiceControllerStatus.Stopped && delay <= 1500) + } else if (Operation == ServiceOperation.Start) + { + try + { + service.Start(); + } + catch (Exception e) + { + service.Refresh(); + if (service.Status != ServiceControllerStatus.Running) + ErrorLogger.WriteToErrorLog("Service start failed: " + e.Message, e.StackTrace, "ServiceAction Warning", ServiceName); + } + + cmdAction.Command = Environment.Is64BitOperatingSystem ? + $"ProcessHacker\\x64\\ProcessHacker.exe -s -elevate -c -ctype service -cobject {service.ServiceName} -caction start" : + $"ProcessHacker\\x86\\ProcessHacker.exe -s -elevate -c -ctype service -cobject {service.ServiceName} -caction start"; + if (AmeliorationUtil.UseKernelDriver) cmdAction.RunTaskOnMainThread(); + + try + { + service.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromMilliseconds(5000)); + } + catch (Exception e) { service.Refresh(); - //Wait for the service to stop - await Task.Delay(delay); - delay += 100; + if (service.Status != ServiceControllerStatus.Running) + ErrorLogger.WriteToErrorLog("Service start timeout exceeded.", e.StackTrace, "ServiceAction Warning", ServiceName); } - if (delay >= 1000) + } else if (Operation == ServiceOperation.Stop) + { + try { - Console.WriteLine("\r\nService stop timeout exceeded."); + service.Stop(); + } + catch (Exception e) + { + service.Refresh(); + if (service.Status != ServiceControllerStatus.Stopped && service.Status != ServiceControllerStatus.StopPending) + ErrorLogger.WriteToErrorLog("Service stop failed: " + e.Message, e.StackTrace, "ServiceAction Warning", ServiceName); + } + + cmdAction.Command = Environment.Is64BitOperatingSystem ? + $"ProcessHacker\\x64\\ProcessHacker.exe -s -elevate -c -ctype service -cobject {service.ServiceName} -caction stop" : + $"ProcessHacker\\x86\\ProcessHacker.exe -s -elevate -c -ctype service -cobject {service.ServiceName} -caction stop"; + if (AmeliorationUtil.UseKernelDriver) cmdAction.RunTaskOnMainThread(); + + Console.WriteLine("Waiting for the service to stop..."); + try + { + service.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromMilliseconds(5000)); + } + catch (Exception e) + { + service.Refresh(); + if (service.Status != ServiceControllerStatus.Stopped) + ErrorLogger.WriteToErrorLog("Service stop timeout exceeded.", e.StackTrace, "ServiceAction Warning", ServiceName); } try { @@ -285,53 +397,68 @@ namespace TrustedUninstaller.Shared.Actions } catch (Exception e) { - ErrorLogger.WriteToErrorLog($"Could not kill service {service.ServiceName}.", e.StackTrace, "ServiceAction Error"); + service.Refresh(); + if (service.Status != ServiceControllerStatus.Stopped) + ErrorLogger.WriteToErrorLog($"Could not kill dependent service {service.ServiceName}.", + e.StackTrace, "ServiceAction Error"); } - - if (RegistryDelete) + } else if (Operation == ServiceOperation.Pause) + { + try { - var action = new RegistryKeyAction() - { - KeyName = $@"HKLM\SYSTEM\CurrentControlSet\Services\{ServiceName}", - Operation = RegistryKeyOperation.Delete - }; - await action.RunTask(); + service.Pause(); } - else + catch (Exception e) { - try - { - ServiceInstaller ServiceInstallerObj = new ServiceInstaller(); - ServiceInstallerObj.Context = new InstallContext(); - ServiceInstallerObj.ServiceName = service.ServiceName; - ServiceInstallerObj.Uninstall(null); - } - catch (Exception e) - { - ErrorLogger.WriteToErrorLog("Service uninstall failed: " + e.Message, e.StackTrace, "ServiceAction Warning", ServiceName); - } - cmdAction.Command = Environment.Is64BitOperatingSystem ? - $"ProcessHacker\\x64\\ProcessHacker.exe -s -elevate -c -ctype service -cobject {service.ServiceName} -caction delete" : - $"ProcessHacker\\x86\\ProcessHacker.exe -s -elevate -c -ctype service -cobject {service.ServiceName} -caction delete"; - if (AmeliorationUtil.UseKernelDriver) cmdAction.RunTaskOnMainThread(); + service.Refresh(); + if (service.Status != ServiceControllerStatus.Paused) + ErrorLogger.WriteToErrorLog("Service pause failed: " + e.Message, e.StackTrace, "ServiceAction Warning", ServiceName); } + cmdAction.Command = Environment.Is64BitOperatingSystem ? + $"ProcessHacker\\x64\\ProcessHacker.exe -s -elevate -c -ctype service -cobject {service.ServiceName} -caction pause" : + $"ProcessHacker\\x86\\ProcessHacker.exe -s -elevate -c -ctype service -cobject {service.ServiceName} -caction pause"; + if (AmeliorationUtil.UseKernelDriver) cmdAction.RunTaskOnMainThread(); + + try + { + service.WaitForStatus(ServiceControllerStatus.Paused, TimeSpan.FromMilliseconds(5000)); + } + catch (Exception e) + { + service.Refresh(); + if (service.Status != ServiceControllerStatus.Paused) + ErrorLogger.WriteToErrorLog("Service pause timeout exceeded.", e.StackTrace, "ServiceAction Warning", ServiceName); + } } - else + else if (Operation == ServiceOperation.Continue) { try { - service.Stop(); + service.Pause(); } catch (Exception e) { - ErrorLogger.WriteToErrorLog("Service stop failed: " + e.Message, e.StackTrace, "ServiceAction Warning", ServiceName); + service.Refresh(); + if (service.Status != ServiceControllerStatus.Running) + ErrorLogger.WriteToErrorLog("Service continue failed: " + e.Message, e.StackTrace, "ServiceAction Warning", ServiceName); } cmdAction.Command = Environment.Is64BitOperatingSystem ? - $"ProcessHacker\\x64\\ProcessHacker.exe -s -elevate -c -ctype service -cobject {service.ServiceName} -caction {Operation.ToString().ToLower()}" : - $"ProcessHacker\\x86\\ProcessHacker.exe -s -elevate -c -ctype service -cobject {service.ServiceName} -caction {Operation.ToString().ToLower()}"; + $"ProcessHacker\\x64\\ProcessHacker.exe -s -elevate -c -ctype service -cobject {service.ServiceName} -caction continue" : + $"ProcessHacker\\x86\\ProcessHacker.exe -s -elevate -c -ctype service -cobject {service.ServiceName} -caction continue"; if (AmeliorationUtil.UseKernelDriver) cmdAction.RunTaskOnMainThread(); + + try + { + service.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromMilliseconds(5000)); + } + catch (Exception e) + { + service.Refresh(); + if (service.Status != ServiceControllerStatus.Running) + ErrorLogger.WriteToErrorLog("Service continue timeout exceeded.", e.StackTrace, "ServiceAction Warning", ServiceName); + } } service?.Dispose(); diff --git a/TrustedUninstaller.Shared/Actions/TaskKillAction.cs b/TrustedUninstaller.Shared/Actions/TaskKillAction.cs index 33e316c..cb5363c 100644 --- a/TrustedUninstaller.Shared/Actions/TaskKillAction.cs +++ b/TrustedUninstaller.Shared/Actions/TaskKillAction.cs @@ -221,11 +221,22 @@ namespace TrustedUninstaller.Shared.Actions var processes = GetProcess(); if (processes.Count > 0) Console.WriteLine("Processes:"); - foreach (var process in processes.Where(x => x.MainModule.FileName.Contains(PathContains))) + foreach (var process in processes.Where(x => + { + try + { + return x.MainModule.FileName.Contains(PathContains); + } + catch (Exception e) + { + return false; + } + })) { Console.WriteLine(process.ProcessName + " - " + process.Id); - if (!RegexNotCritical.Any(x => Regex.Match(process.ProcessName, x, RegexOptions.IgnoreCase).Success)) { + if (!RegexNotCritical.Any(x => Regex.Match(process.ProcessName, x, RegexOptions.IgnoreCase).Success)) + { bool isCritical = false; IntPtr hprocess = OpenProcess(ProcessAccessFlags.QueryLimitedInformation, false, process.Id); IsProcessCritical(hprocess, ref isCritical); @@ -236,36 +247,54 @@ namespace TrustedUninstaller.Shared.Actions continue; } } + try + { + if (!TerminateProcess(process.Handle, 1)) + ErrorLogger.WriteToErrorLog("TerminateProcess failed with error code: " + Marshal.GetLastWin32Error(), Environment.StackTrace, "TaskKill Error", ProcessName); + } + catch (Exception e) + { + ErrorLogger.WriteToErrorLog("Could not open process handle: " + e.Message, e.StackTrace, "TaskKillAction Error", process.ProcessName); + } + try + { + process.WaitForExit(1000); + } + catch (Exception e) + { + ErrorLogger.WriteToErrorLog("Error waiting for process exit: " + e.Message, e.StackTrace, "TaskKillAction Error", process.ProcessName); + } + + if (process.ProcessName == "explorer") continue; cmdAction.Command = Environment.Is64BitOperatingSystem ? $"ProcessHacker\\x64\\ProcessHacker.exe -s -elevate -c -ctype process -cobject {process.Id} -caction terminate" : $"ProcessHacker\\x86\\ProcessHacker.exe -s -elevate -c -ctype process -cobject {process.Id} -caction terminate"; - - if (AmeliorationUtil.UseKernelDriver) - cmdAction.RunTaskOnMainThread(); - else - TerminateProcess(process.Handle, 1); - + if (AmeliorationUtil.UseKernelDriver && process.ProcessName != "explorer") cmdAction.RunTaskOnMainThread(); + int i = 0; - while (i <= 5 && GetProcess().Any(x => x.Id == process.Id && x.ProcessName == process.ProcessName)) + + while (i <= 3 && GetProcess().Any(x => x.Id == process.Id && x.ProcessName == process.ProcessName)) { - await Task.Delay(300); - if (AmeliorationUtil.UseKernelDriver) - cmdAction.RunTaskOnMainThread(); - else - TerminateProcess(process.Handle, 1); + try + { + try + { + if (AmeliorationUtil.UseKernelDriver) + cmdAction.RunTaskOnMainThread(); + else + TerminateProcess(process.Handle, 1); + } + catch (Exception e) { } + + process.WaitForExit(500); + } + catch (Exception e) { } + await Task.Delay(100); i++; } - try { - if (!TerminateProcess(process.Handle, 1)) - ErrorLogger.WriteToErrorLog("TerminateProcess failed with error code: " + Marshal.GetLastWin32Error(), Environment.StackTrace, "TaskKill Error", ProcessName); - } - catch (Exception e) - { - ErrorLogger.WriteToErrorLog("Could not open process handle.", e.StackTrace, "TaskKillAction Error", process.ProcessName); - } - - if (i >= 5) ErrorLogger.WriteToErrorLog($"Task kill timeout exceeded.", Environment.StackTrace, "TaskKillAction Error"); + if (i >= 3) ErrorLogger.WriteToErrorLog($"Task kill timeout exceeded.", Environment.StackTrace, "TaskKillAction Error"); + } InProgress = false; return true; @@ -279,10 +308,19 @@ namespace TrustedUninstaller.Shared.Actions try { if (!TerminateProcess(process.Handle, 1)) ErrorLogger.WriteToErrorLog("TerminateProcess failed with error code: " + Marshal.GetLastWin32Error(), Environment.StackTrace, "TaskKill Error", ProcessName); + + try + { + process.WaitForExit(1000); + } + catch (Exception e) + { + ErrorLogger.WriteToErrorLog("Error waiting for process exit: " + e.Message, e.StackTrace, "TaskKillAction Error", process.ProcessName); + } } catch (Exception e) { - ErrorLogger.WriteToErrorLog("Could not open process handle.", e.StackTrace, "TaskKillAction Error", process.ProcessName); + ErrorLogger.WriteToErrorLog("Could not open process handle: " + e.Message, e.StackTrace, "TaskKillAction Error", process.ProcessName); } } else @@ -307,13 +345,22 @@ namespace TrustedUninstaller.Shared.Actions return false; } } - try { + try + { if (!TerminateProcess(process.Handle, 1)) ErrorLogger.WriteToErrorLog("TerminateProcess failed with error code: " + Marshal.GetLastWin32Error(), Environment.StackTrace, "TaskKill Error", ProcessName); } catch (Exception e) { - ErrorLogger.WriteToErrorLog("Could not open process handle.", e.StackTrace, "TaskKillAction Error", process.ProcessName); + ErrorLogger.WriteToErrorLog("Could not open process handle: " + e.Message, e.StackTrace, "TaskKillAction Error", process.ProcessName); + } + try + { + process.WaitForExit(1000); + } + catch (Exception e) + { + ErrorLogger.WriteToErrorLog("Error waiting for process exit: " + e.Message, e.StackTrace, "TaskKillAction Error", process.ProcessName); } cmdAction.Command = Environment.Is64BitOperatingSystem ? @@ -321,8 +368,33 @@ namespace TrustedUninstaller.Shared.Actions $"ProcessHacker\\x86\\ProcessHacker.exe -s -elevate -c -ctype process -cobject {ProcessID.Value} -caction terminate"; if (AmeliorationUtil.UseKernelDriver) cmdAction.RunTaskOnMainThread(); } + + int i = 0; + + while (i <= 3 && GetProcess().Any(x => x.Id == process.Id && x.ProcessName == process.ProcessName)) + { + try + { + try + { + if (AmeliorationUtil.UseKernelDriver) + cmdAction.RunTaskOnMainThread(); + else + TerminateProcess(process.Handle, 1); + } + catch (Exception e) + { + } - await Task.Delay(100); + process.WaitForExit(500); + } + catch (Exception e) + { + } + await Task.Delay(100); + i++; + } + if (i >= 3) ErrorLogger.WriteToErrorLog($"Task kill timeout exceeded.", Environment.StackTrace, "TaskKillAction Error"); } else { @@ -360,7 +432,15 @@ namespace TrustedUninstaller.Shared.Actions } catch (Exception e) { - ErrorLogger.WriteToErrorLog("Could not open process handle.", e.StackTrace, "TaskKillAction Error", process.ProcessName); + ErrorLogger.WriteToErrorLog("Could not open process handle: " + e.Message, e.StackTrace, "TaskKillAction Error", process.ProcessName); + } + try + { + process.WaitForExit(1000); + } + catch (Exception e) + { + ErrorLogger.WriteToErrorLog("Error waiting for process exit: " + e.Message, e.StackTrace, "TaskKillAction Error", process.ProcessName); } if (process.ProcessName == "explorer") continue; @@ -372,16 +452,30 @@ namespace TrustedUninstaller.Shared.Actions int i = 0; - while (i <= 5 && GetProcess().Any(x => x.Id == process.Id && x.ProcessName == process.ProcessName)) + while (i <= 3 && GetProcess().Any(x => x.Id == process.Id && x.ProcessName == process.ProcessName)) { - if (AmeliorationUtil.UseKernelDriver) - cmdAction.RunTaskOnMainThread(); - else - TerminateProcess(process.Handle, 1); - await Task.Delay(300); + try + { + try + { + if (AmeliorationUtil.UseKernelDriver) + cmdAction.RunTaskOnMainThread(); + else + TerminateProcess(process.Handle, 1); + } + catch (Exception e) + { + } + + process.WaitForExit(500); + } + catch (Exception e) + { + } + await Task.Delay(100); i++; } - if (i >= 5) ErrorLogger.WriteToErrorLog($"Task kill timeout exceeded.", Environment.StackTrace, "TaskKillAction Error"); + if (i >= 3) ErrorLogger.WriteToErrorLog($"Task kill timeout exceeded.", Environment.StackTrace, "TaskKillAction Error"); } } diff --git a/TrustedUninstaller.Shared/AmeliorationUtil.cs b/TrustedUninstaller.Shared/AmeliorationUtil.cs index 531b1f3..e589455 100644 --- a/TrustedUninstaller.Shared/AmeliorationUtil.cs +++ b/TrustedUninstaller.Shared/AmeliorationUtil.cs @@ -69,17 +69,6 @@ namespace TrustedUninstaller.Shared var currentTask = Parser.Tasks[Parser.Tasks.Count - 1]; - if (File.Exists("TasksAdded.txt")) - { - var doneTasks = File.ReadAllText("TasksAdded.txt").Split(new[] { "\r\n" }, StringSplitOptions.None); - - if (doneTasks.Contains(currentTask.Title)) - { - Parser.Tasks.Remove(currentTask); - return true; - } - } - if ((!IsApplicableOption(currentTask.Option, Playbook.Options) || !IsApplicableArch(currentTask.Arch)) || (currentTask.Builds != null && ( !currentTask.Builds.Where(build => !build.StartsWith("!")).Any(build => IsApplicableWindowsVersion(build)) @@ -302,8 +291,6 @@ namespace TrustedUninstaller.Shared Console.WriteLine("Task completed."); ProcessPrivilege.ResetTokens(); - - File.AppendAllText("TasksAdded.txt", task.Title + Environment.NewLine); } catch (Exception e) { @@ -354,11 +341,6 @@ namespace TrustedUninstaller.Shared //After the auto start up. Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory); - if (File.Exists("TasksAdded.txt") && !WinUtil.IsTrustedInstaller()) - { - File.Delete("TasksAdded.txt"); - } - if (Directory.Exists("Logs") && !WinUtil.IsTrustedInstaller()) { if (File.Exists("Logs\\AdminOutput.txt")) @@ -370,11 +352,6 @@ namespace TrustedUninstaller.Shared { File.Delete("Logs\\TIOutput.txt"); } - - if (File.Exists("Logs\\FileChecklist.txt")) - { - File.Delete("Logs\\FileChecklist.txt"); - } } //Check if KPH is installed. @@ -438,30 +415,6 @@ namespace TrustedUninstaller.Shared WinUtil.RegistryManager.UnhookUserHives(); - //Check how many files were successfully and unsuccessfully deleted. - var deletedItemsCount = 0; - var failedDeletedItemsCount = 0; - - if (File.Exists("Logs\\FileChecklist.txt")) - { - using (var reader = new StreamReader("Logs\\FileChecklist.txt")) - { - var data = reader.ReadToEnd(); - var listData = data.Split(new [] { Environment.NewLine }, StringSplitOptions.None).ToList(); - deletedItemsCount = listData.FindAll(s => s == "Deleted: True").Count(); - failedDeletedItemsCount = listData.FindAll(s => s == "Deleted: False").Count(); - } - - using (var writer = new StreamWriter("Logs\\FileChecklist.txt", true)) - { - writer.WriteLine($"{deletedItemsCount} files were deleted successfully. " + - $"{failedDeletedItemsCount} files couldn't be deleted."); - } - } - - Console.WriteLine($"{deletedItemsCount} files were deleted successfully. " + - $"{failedDeletedItemsCount} files couldn't be deleted."); - //Check if the kernel driver is installed. //service = ServiceController.GetDevices() //.FirstOrDefault(s => s.DisplayName == "KProcessHacker2"); @@ -476,8 +429,6 @@ namespace TrustedUninstaller.Shared }); } - File.Delete("TasksAdded.txt"); - Console.WriteLine(); Console.WriteLine("Playbook finished."); diff --git a/TrustedUninstaller.Shared/Globals.cs b/TrustedUninstaller.Shared/Globals.cs index fc98d44..716565d 100644 --- a/TrustedUninstaller.Shared/Globals.cs +++ b/TrustedUninstaller.Shared/Globals.cs @@ -9,8 +9,8 @@ namespace TrustedUninstaller.Shared { public class Globals { - public const string CurrentVersion = "0.7.3"; - public const double CurrentVersionNumber = 0.73; + public const string CurrentVersion = "0.7.4"; + public const double CurrentVersionNumber = 0.74; public static readonly int WinVer = Int32.Parse(Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion").GetValue("CurrentBuildNumber").ToString()); diff --git a/TrustedUninstaller.Shared/ProcessPrivilege.cs b/TrustedUninstaller.Shared/ProcessPrivilege.cs index 6a75791..eba6493 100644 --- a/TrustedUninstaller.Shared/ProcessPrivilege.cs +++ b/TrustedUninstaller.Shared/ProcessPrivilege.cs @@ -157,8 +157,7 @@ namespace TrustedUninstaller.Shared if (lsassToken.DangerousGetHandle() == IntPtr.Zero) { - - var processHandle = Process.GetProcessesByName("lsass").First().Handle; + var processHandle = Win32.Process.OpenProcess(Win32.Process.ProcessAccessFlags.QueryLimitedInformation, false, Process.GetProcessesByName("lsass").First().Id); if (!Win32.Tokens.OpenProcessToken(processHandle, Win32.Tokens.TokenAccessFlags.TOKEN_DUPLICATE | Win32.Tokens.TokenAccessFlags.TOKEN_ASSIGN_PRIMARY | @@ -383,7 +382,7 @@ namespace TrustedUninstaller.Shared try { - var processHandle = Process.GetProcessesByName("winlogon").First().Handle; + var processHandle = Win32.Process.OpenProcess(Win32.Process.ProcessAccessFlags.QueryLimitedInformation, false, Process.GetProcessesByName("winlogon").First().Id); if (!Win32.Tokens.OpenProcessToken(processHandle, Win32.Tokens.TokenAccessFlags.TOKEN_DUPLICATE | Win32.Tokens.TokenAccessFlags.TOKEN_ASSIGN_PRIMARY | Win32.Tokens.TokenAccessFlags.TOKEN_QUERY | Win32.Tokens.TokenAccessFlags.TOKEN_IMPERSONATE, diff --git a/TrustedUninstaller.Shared/Requirements.cs b/TrustedUninstaller.Shared/Requirements.cs index f894e5c..48c25cd 100644 --- a/TrustedUninstaller.Shared/Requirements.cs +++ b/TrustedUninstaller.Shared/Requirements.cs @@ -8,6 +8,8 @@ using System.Management; using System.Net; using System.Reflection; using System.Runtime.InteropServices; +using System.Text; +using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Xml.Serialization; @@ -15,6 +17,7 @@ using Microsoft.Win32; using TrustedUninstaller.Shared; using TrustedUninstaller.Shared.Actions; using TrustedUninstaller.Shared.Tasks; +using WUApiLib; namespace TrustedUninstaller.Shared { @@ -49,7 +52,7 @@ namespace TrustedUninstaller.Shared NoTweakware = 10, } - public static async Task MetRequirements(this Requirement[] requirements) + public static async Task MetRequirements(this Requirement[] requirements, bool checkNoPendingUpdate = false) { var requirementEnum = (Requirement[])Enum.GetValues(typeof(Requirement)); if (requirements == null) @@ -65,16 +68,26 @@ namespace TrustedUninstaller.Shared if (requirements.Contains(Requirement.NoAntivirus)) if (true) metRequirements.Add(Requirement.NoAntivirus); - - if (requirements.Contains(Requirement.NoPendingUpdates)) - if (await new NoPendingUpdates().IsMet()) metRequirements.Add(Requirement.NoPendingUpdates); + // Handled upstream if (requirements.Contains(Requirement.Activation)) - if (await new Activation().IsMet()) metRequirements.Add(Requirement.Activation); + if (true) metRequirements.Add(Requirement.Activation); if (requirements.Contains(Requirement.DefenderDisabled)) if (await new DefenderDisabled().IsMet()) metRequirements.Add(Requirement.DefenderDisabled); + if (requirements.Contains(Requirement.PluggedIn)) + if (await new Battery().IsMet()) metRequirements.Add(Requirement.PluggedIn); + + if (requirements.Contains(Requirement.NoPendingUpdates)) + if (!checkNoPendingUpdate || (new [] { + Requirement.Internet, + Requirement.NoInternet, + Requirement.PluggedIn, + Requirement.DefenderDisabled + }.All(metRequirements.Contains) && + await new NoPendingUpdates().IsMet())) metRequirements.Add(Requirement.NoPendingUpdates); + if (requirements.Contains(Requirement.DefenderToggled)) if (await new DefenderDisabled().IsMet()) metRequirements.Add(Requirement.DefenderToggled); @@ -83,9 +96,6 @@ namespace TrustedUninstaller.Shared if (requirements.Contains(Requirement.AdministratorPasswordSet)) metRequirements.Add(Requirement.AdministratorPasswordSet); - - if (requirements.Contains(Requirement.PluggedIn)) - if (await new Battery().IsMet()) metRequirements.Add(Requirement.PluggedIn); return metRequirements.ToArray(); } @@ -375,15 +385,124 @@ namespace TrustedUninstaller.Shared } } + class SearchCompletedCallback : ISearchCompletedCallback + { + public void Invoke(ISearchJob searchJob, ISearchCompletedCallbackArgs callbackArgs) + { + this.CompleteTask(); + } + + private TaskCompletionSource taskSource = new TaskCompletionSource(); + protected void CompleteTask() + { + taskSource.SetResult(true); + } + + public Task Task + { + get + { + return taskSource.Task; + } + } + } + + private static Process _pendingUpdateCheckProcess = null; public class NoPendingUpdates : RequirementBase, IRequirements { public async Task IsMet() { - //TODO: This - return true; + try + { + if (_pendingUpdateCheckProcess != null && !_pendingUpdateCheckProcess.HasExited) + { + _pendingUpdateCheckProcess.Kill(); + } + } + catch (Exception e) { } + + bool updatesFound = false; + try + { + // Using WUApiLib can crash the entire application if + // Windows Update is faulty. For that reason we use a + // separate process. To replicate, use an ameliorated + // system and copy wuapi.dll & wuaeng.dll to System32. + + _pendingUpdateCheckProcess = new Process(); + _pendingUpdateCheckProcess.StartInfo = new ProcessStartInfo + { + FileName = Assembly.GetEntryAssembly().Location, + Arguments = "-CheckPendingUpdates", + UseShellExecute = false, + RedirectStandardOutput = true, + CreateNoWindow = true + }; + + _pendingUpdateCheckProcess.OutputDataReceived += delegate(object sender, DataReceivedEventArgs args) + { + if (!string.IsNullOrWhiteSpace(args.Data)) + bool.TryParse(args.Data, out updatesFound); + }; + + _pendingUpdateCheckProcess.Start(); + + _pendingUpdateCheckProcess.BeginOutputReadLine(); + + if (!_pendingUpdateCheckProcess.WaitForExit(55000)) + { + _pendingUpdateCheckProcess.Kill(); + throw new TimeoutException(); + } + + _pendingUpdateCheckProcess.CancelOutputRead(); + _pendingUpdateCheckProcess.Dispose(); + } + catch (Exception e) { } + + return !updatesFound; } public Task Meet() => throw new NotImplementedException(); + + public static bool Check() + { + bool result = false; + try + { + var updateSession = new UpdateSession(); + var updateSearcher = updateSession.CreateUpdateSearcher(); + updateSearcher.Online = false; //set to true if you want to search online + + SearchCompletedCallback searchCompletedCallback = new SearchCompletedCallback(); + + ISearchJob searchJob = updateSearcher.BeginSearch( + "IsInstalled=0 And IsHidden=0 And Type='Software' And DeploymentAction=*", + searchCompletedCallback, null); + + try + { + searchCompletedCallback.Task.Wait(50000); + } + catch (OperationCanceledException) + { + searchJob.RequestAbort(); + } + + ISearchResult searchResult = updateSearcher.EndSearch(searchJob); + + if (searchResult.Updates.Cast().Any(x => x.IsDownloaded)) + { + result = true; + } + } + catch (Exception e) + { + result = false; + } + + return result; + } } public class NoAntivirus : RequirementBase, IRequirements diff --git a/TrustedUninstaller.Shared/TrustedUninstaller.Shared.csproj b/TrustedUninstaller.Shared/TrustedUninstaller.Shared.csproj index e294537..6141a9b 100644 --- a/TrustedUninstaller.Shared/TrustedUninstaller.Shared.csproj +++ b/TrustedUninstaller.Shared/TrustedUninstaller.Shared.csproj @@ -134,6 +134,15 @@ False True + + {B596CC9F-56E5-419E-A622-E01BB457431E} + 2 + 0 + 0 + tlbimp + False + True + diff --git a/TrustedUninstaller.Shared/Win32.cs b/TrustedUninstaller.Shared/Win32.cs index 7dbc1ab..bfc7be0 100644 --- a/TrustedUninstaller.Shared/Win32.cs +++ b/TrustedUninstaller.Shared/Win32.cs @@ -904,7 +904,29 @@ namespace TrustedUninstaller.Shared string lpApplicationName, string lpCommandLine, ProcessCreationFlags dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation); - + + [DllImport("kernel32.dll", SetLastError = true)] + internal static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, + bool bInheritHandle, int dwProcessId); + + [Flags] + internal enum ProcessAccessFlags : uint + { + All = 0x001F0FFF, + Terminate = 0x00000001, + CreateThread = 0x00000002, + VirtualMemoryOperation = 0x00000008, + VirtualMemoryRead = 0x00000010, + VirtualMemoryWrite = 0x00000020, + DuplicateHandle = 0x00000040, + CreateProcess = 0x000000080, + SetQuota = 0x00000100, + SetInformation = 0x00000200, + QueryInformation = 0x00000400, + QueryLimitedInformation = 0x00001000, + Synchronize = 0x00100000 + } + public enum LogonFlags { WithProfile = 1, diff --git a/TrustedUninstaller.Shared/WinUtil.cs b/TrustedUninstaller.Shared/WinUtil.cs index 162448a..33bbfd2 100644 --- a/TrustedUninstaller.Shared/WinUtil.cs +++ b/TrustedUninstaller.Shared/WinUtil.cs @@ -649,20 +649,27 @@ namespace TrustedUninstaller.Shared } } - public static async void CheckKph() + public static void CheckKph() { - if (!AmeliorationUtil.UseKernelDriver || new RegistryKeyAction() { KeyName = @"HKLM\SYSTEM\CurrentControlSet\Services\KProcessHacker2", Operation = RegistryKeyOperation.Add }.GetStatus() == UninstallTaskStatus.Completed) - return; + try + { + if (!AmeliorationUtil.UseKernelDriver || new RegistryKeyAction() { KeyName = @"HKLM\SYSTEM\CurrentControlSet\Services\KProcessHacker2", Operation = RegistryKeyOperation.Add }.GetStatus() == UninstallTaskStatus.Completed) + return; - Console.WriteLine(Environment.NewLine + "Installing driver..."); - var cmdAction = new CmdAction(); - cmdAction.Command = Environment.Is64BitOperatingSystem - ? $"ProcessHacker\\x64\\ProcessHacker.exe -s -installkph" - : $"ProcessHacker\\x86\\ProcessHacker.exe -s -installkph"; - cmdAction.RunTaskOnMainThread(); + Console.WriteLine(Environment.NewLine + "Installing driver..."); + var cmdAction = new CmdAction(); + cmdAction.Command = Environment.Is64BitOperatingSystem + ? $"ProcessHacker\\x64\\ProcessHacker.exe -s -installkph" + : $"ProcessHacker\\x86\\ProcessHacker.exe -s -installkph"; + cmdAction.RunTaskOnMainThread(); - await AmeliorationUtil.SafeRunAction(new RegistryValueAction() - { KeyName = @"HKLM\SYSTEM\CurrentControlSet\Services\KProcessHacker2", Value = "DeleteFlag", Type = RegistryValueType.REG_DWORD, Data = 1 }); + AmeliorationUtil.SafeRunAction(new RegistryValueAction() + { KeyName = @"HKLM\SYSTEM\CurrentControlSet\Services\KProcessHacker2", Value = "DeleteFlag", Type = RegistryValueType.REG_DWORD, Data = 1 }).Wait(); + } + catch (Exception e) + { + ErrorLogger.WriteToErrorLog("Error checking kernel driver: " + e.Message, e.StackTrace, "Warning"); + } } private const int GWL_STYLE = -16; @@ -755,11 +762,12 @@ namespace TrustedUninstaller.Shared string name; if (path.Contains("Users\\Default\\")) name = classHive ? "AME_UserHive_Default_Classes" : "AME_UserHive_Default"; - else name = classHive ? "AME_UserHive_" + (HivesLoaded + 1) + "_Classes" : "AME_UserHive_" + (HivesLoaded + 1); + else name = classHive ? "AME_UserHive_" + (HivesLoaded) + "_Classes" : "AME_UserHive_" + (HivesLoaded + 1); IntPtr parentHandle = parentKey.Handle.DangerousGetHandle(); RegLoadKey(parentHandle, name, path); - HivesLoaded++; + if (!path.Contains("Users\\Default\\")) + HivesLoaded++; } private static void AcquirePrivileges() { @@ -782,7 +790,7 @@ namespace TrustedUninstaller.Shared private static bool HivesHooked; private static int HivesLoaded; - public static async void HookUserHives() + public static void HookUserHives() { try { @@ -855,7 +863,7 @@ namespace TrustedUninstaller.Shared } } - public static async void UnhookUserHives() + public static void UnhookUserHives() { try {