/// <summary> /// Verifies installed programs in add/remove list /// </summary> public override void Scan() { try { Wizard.Report.WriteLine("Verifying programs in Add/Remove list"); using ( var regKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall")) { if (regKey == null) { return; } foreach ( var progName in regKey.GetSubKeyNames().TakeWhile(progName => !CancellationToken.IsCancellationRequested) ) { using (var regKey2 = regKey.OpenSubKey(progName)) { if (regKey2 == null) { continue; } var progInfo = new ProgramInfo(regKey2); if (regKey2.ValueCount <= 0) { Wizard.StoreInvalidKey(Strings.InvalidRegKey, regKey2.ToString()); continue; } if (progInfo.WindowsInstaller) { continue; } if (string.IsNullOrEmpty(progInfo.DisplayName) && !progInfo.Uninstallable) { Wizard.StoreInvalidKey(Strings.InvalidRegKey, regKey2.ToString()); continue; } // Check display icon if (!string.IsNullOrEmpty(progInfo.DisplayIcon)) { if (!ScanFunctions.IconExists(progInfo.DisplayIcon)) { Wizard.StoreInvalidKey(Strings.InvalidFile, regKey2.ToString(), "DisplayIcon"); } } // Check install location if (!string.IsNullOrEmpty(progInfo.InstallLocation)) { if (!ScanFunctions.DirExists(progInfo.InstallLocation) && !ScanFunctions.FileExists(progInfo.InstallLocation)) { if (!Wizard.IsOnIgnoreList(progInfo.InstallLocation)) { Wizard.StoreInvalidKey(Strings.InvalidFile, regKey2.ToString(), "InstallLocation"); } } } // Check install source if (!string.IsNullOrEmpty(progInfo.InstallSource)) { if (!ScanFunctions.DirExists(progInfo.InstallSource) && !ScanFunctions.FileExists(progInfo.InstallSource)) { if (!Wizard.IsOnIgnoreList(progInfo.InstallSource)) { Wizard.StoreInvalidKey(Strings.InvalidFile, regKey2.ToString(), "InstallSource"); } } } // Check ARP Cache if (!progInfo.SlowCache) { continue; } if (string.IsNullOrEmpty(progInfo.FileName)) { continue; } if (!ScanFunctions.FileExists(progInfo.FileName) && !Wizard.IsOnIgnoreList(progInfo.FileName)) { Wizard.StoreInvalidKey(Strings.InvalidRegKey, progInfo.SlowInfoCacheRegKey); } } } } Wizard.Report.WriteLine("Verifying registry entries in Add/Remove Cache"); CheckArpCache( Registry.LocalMachine.OpenSubKey( @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Management\ARPCache\")); CheckArpCache( Registry.CurrentUser.OpenSubKey( @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Management\ARPCache\")); } catch (SecurityException ex) { Debug.WriteLine(ex.Message); } }
private static void ValidateExplorerExt(RegistryKey regKey) { // Sees if icon file exists try { var hotIcon = regKey.GetValue("HotIcon") as string; if (!string.IsNullOrEmpty(hotIcon)) { if (!ScanFunctions.IconExists(hotIcon)) { Wizard.StoreInvalidKey(Strings.InvalidFile, regKey.ToString(), "HotIcon"); } } } catch (Exception ex) { Debug.WriteLine("The following error occurred: " + ex.Message + "\nUnable to check if HotIcon exists."); } try { var icon = regKey.GetValue("Icon") as string; if (!string.IsNullOrEmpty(icon)) { if (!ScanFunctions.IconExists(icon)) { Wizard.StoreInvalidKey(Strings.InvalidFile, regKey.ToString(), "Icon"); } } } catch (Exception ex) { Debug.WriteLine("The following error occurred: " + ex.Message + "\nUnable to check if Icon exists."); } try { // Lookup CLSID extension var clsidExit = regKey.GetValue("ClsidExtension") as string; if (!string.IsNullOrEmpty(clsidExit)) { Wizard.StoreInvalidKey(Strings.MissingCLSID, regKey.ToString(), "ClsidExtension"); } } catch (Exception ex) { Debug.WriteLine("The following error occurred: " + ex.Message + "\nUnable to check if ClsidExtension exists."); } try { // See if files exist var exec = regKey.GetValue("Exec") as string; if (!string.IsNullOrEmpty(exec)) { if (!ScanFunctions.FileExists(exec) && !Wizard.IsOnIgnoreList(exec)) { Wizard.StoreInvalidKey(Strings.InvalidFile, regKey.ToString(), "Exec"); } } } catch (Exception ex) { Debug.WriteLine("The following error occurred: " + ex.Message + "\nUnable to check if Exec exists."); } try { var script = regKey.GetValue("Script") as string; if (!string.IsNullOrEmpty(script)) { if (!ScanFunctions.FileExists(script) && !Wizard.IsOnIgnoreList(script)) { Wizard.StoreInvalidKey(Strings.InvalidFile, regKey.ToString(), "Script"); } } } catch (Exception ex) { Debug.WriteLine("The following error occurred: " + ex.Message + "\nUnable to check if Script exists."); } }
/// <summary> /// Scans for the CLSID subkey /// <param name="regKey">Location of CLSID Sub Key</param> /// </summary> private static void ScanClsidSubKey(RegistryKey regKey) { string[] clsids; if (regKey == null) { return; } Wizard.Report.WriteLine("Scanning " + regKey.Name + " for invalid CLSID's"); try { clsids = regKey.GetSubKeyNames(); } catch (Exception ex) { Debug.WriteLine("The following error occurred: " + ex.Message + "\nUnable to scan for invalid CLSID's"); return; } foreach (var clsid in clsids.TakeWhile(clsid => !CancellationToken.IsCancellationRequested)) { RegistryKey regKeyClsid, regKeyDefaultIcon = null, regKeyInprocSrvr = null, regKeyInprocSrvr32 = null; try { regKeyClsid = regKey.OpenSubKey(clsid); if (regKeyClsid == null) { continue; } } catch (Exception ex) { Debug.WriteLine("The following error occurred: " + ex.Message + "\nSkipping..."); continue; } // Check for valid AppID try { var appId = regKey.GetValue("AppID") as string; if (!string.IsNullOrEmpty(appId)) { if (!AppidExists(appId)) { Wizard.StoreInvalidKey(Strings.MissingAppID, regKeyClsid.ToString(), "AppID"); } } } catch (Exception ex) { Debug.WriteLine("The following error occurred: " + ex.Message + "\nUnable to check for valid AppID"); } // See if DefaultIcon exists try { regKeyDefaultIcon = regKeyClsid.OpenSubKey("DefaultIcon"); var iconPath = regKeyDefaultIcon?.GetValue("") as string; if (!string.IsNullOrEmpty(iconPath)) { if (!ScanFunctions.IconExists(iconPath)) { if (!Wizard.IsOnIgnoreList(iconPath)) { Wizard.StoreInvalidKey(Strings.InvalidFile, $"{regKeyClsid}\\DefaultIcon"); } } } } catch (Exception ex) { Debug.WriteLine("The following error occurred: " + ex.Message + "\nUnable to scan for DefaultIcon"); } finally { regKeyDefaultIcon?.Close(); } // Look for InprocServer files try { regKeyInprocSrvr = regKeyClsid.OpenSubKey("InprocServer"); if (regKeyInprocSrvr != null) { var inprocServer = regKeyInprocSrvr.GetValue("") as string; if (!string.IsNullOrEmpty(inprocServer)) { if (!ScanFunctions.FileExists(inprocServer) && !Wizard.IsOnIgnoreList(inprocServer)) { Wizard.StoreInvalidKey(Strings.InvalidInprocServer, regKeyInprocSrvr.ToString()); } } regKeyInprocSrvr.Close(); } } catch (Exception ex) { Debug.WriteLine("The following error occurred: " + ex.Message + "\nUnable to check for InprocServer files"); } finally { regKeyInprocSrvr?.Close(); } try { regKeyInprocSrvr32 = regKeyClsid.OpenSubKey("InprocServer32"); if (regKeyInprocSrvr32 != null) { var inprocServer32 = regKeyInprocSrvr32.GetValue("") as string; if (!string.IsNullOrEmpty(inprocServer32)) { if (!ScanFunctions.FileExists(inprocServer32) && !Wizard.IsOnIgnoreList(inprocServer32)) { Wizard.StoreInvalidKey(Strings.InvalidInprocServer32, regKeyInprocSrvr32.ToString()); } } regKeyInprocSrvr32.Close(); } } catch (Exception ex) { Debug.WriteLine("The following error occurred: " + ex.Message + "\nUnable to check for InprocServer32 files"); } finally { regKeyInprocSrvr32?.Close(); } regKeyClsid.Close(); } regKey.Close(); }
/// <summary> /// Finds invalid File extensions + ProgIDs referenced /// </summary> private static void ScanClasses(RegistryKey regKey) { if (regKey == null) { return; } Wizard.Report.WriteLine("Scanning " + regKey.Name + " for invalid Classes"); string[] classList; try { classList = regKey.GetSubKeyNames(); } catch (Exception ex) { Debug.WriteLine("The following error occurred: " + ex.Message + "\nUnable to check for invalid classes."); return; } foreach ( var subKey in classList.Where(subKey => subKey != "*") .TakeWhile(subKey => !CancellationToken.IsCancellationRequested)) { if (subKey[0] == '.') { // File Extension RegistryKey regKeyFileExt = null; try { regKeyFileExt = regKey.OpenSubKey(subKey); // Find reference to ProgID var progId = regKeyFileExt?.GetValue("") as string; if (!string.IsNullOrEmpty(progId)) { if (!ProgIdExists(progId)) { Wizard.StoreInvalidKey(Strings.MissingProgID, regKeyFileExt.ToString()); } } } catch (Exception ex) { Debug.WriteLine("The following error occurred: " + ex.Message + "\nUnable to check file extension."); } finally { regKeyFileExt?.Close(); } } else { // ProgID or file class // See if DefaultIcon exists RegistryKey regKeyDefaultIcon = null; try { regKeyDefaultIcon = regKey.OpenSubKey($"{subKey}\\DefaultIcon"); var iconPath = regKeyDefaultIcon?.GetValue("") as string; if (!string.IsNullOrEmpty(iconPath)) { if (!ScanFunctions.IconExists(iconPath)) { if (!Wizard.IsOnIgnoreList(iconPath)) { Wizard.StoreInvalidKey(Strings.InvalidFile, regKeyDefaultIcon.Name); } } } } catch (Exception ex) { Debug.WriteLine("The following error occurred: " + ex.Message + "\nUnable to check if DefaultIcon exists."); } finally { regKeyDefaultIcon?.Close(); } // Check referenced CLSID RegistryKey regKeyClsid = null; try { regKeyClsid = regKey.OpenSubKey($"{subKey}\\CLSID"); var guid = regKeyClsid?.GetValue("") as string; if (!string.IsNullOrEmpty(guid)) { if (!ClsidExists(guid)) { Wizard.StoreInvalidKey(Strings.MissingCLSID, $"{regKey.Name}\\{subKey}"); } } } catch (Exception ex) { Debug.WriteLine("The following error occurred: " + ex.Message + "\nUnable to check if referenced CLSID exists."); } finally { regKeyClsid?.Close(); } } // Check for unused progid/extension RegistryKey regKeyProgId = null; try { regKeyProgId = regKey.OpenSubKey(subKey); if (regKeyProgId?.ValueCount <= 0 && regKeyProgId.SubKeyCount <= 0) { Wizard.StoreInvalidKey(Strings.InvalidProgIDFileExt, regKeyProgId.Name); } } catch (Exception ex) { Debug.WriteLine("The following error occurred: " + ex.Message + "\nUnable to check for unused ProgID or file extension."); } finally { regKeyProgId?.Close(); } } regKey.Close(); }