/// <summary>
        ///     Scan for missing links to DLLS
        /// </summary>
        public override void Scan()
        {
            try
            {
                var regKey = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\SharedDLLs");

                if (regKey == null)
                {
                    return;
                }

                Wizard.Report.WriteLine("Scanning for missing shared DLLs");

                // Validate Each DLL from the value names
                foreach (var filePath in regKey.GetValueNames()
                         .Where(filePath => !string.IsNullOrWhiteSpace(filePath))
                         .Where(filePath => !ScanFunctions.FileExists(filePath) && !Wizard.IsOnIgnoreList(filePath))
                         .TakeWhile(filePath => !CancellationToken.IsCancellationRequested))
                {
                    Wizard.StoreInvalidKey(Strings.InvalidFile, regKey.Name, filePath);
                }

                regKey.Close();
            }
            catch (SecurityException ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }
        /// <summary>
        ///     Goes deep into sub keys to see if files exist
        /// </summary>
        /// <param name="rk">Registry subkey</param>
        private static void ParseSoundKeys(RegistryKey rk)
        {
            foreach (
                var subKey in rk.GetSubKeyNames().TakeWhile(subKey => !CancellationToken.IsCancellationRequested))
            {
                // Ignores ".Default" Subkey
                if ((string.Compare(subKey, ".Current", StringComparison.Ordinal) == 0) ||
                    (string.Compare(subKey, ".Modified", StringComparison.Ordinal) == 0))
                {
                    // Gets the (default) key and sees if the file exists
                    var rk2 = rk.OpenSubKey(subKey);

                    var soundPath = rk2?.GetValue("") as string;

                    if (string.IsNullOrEmpty(soundPath))
                    {
                        continue;
                    }

                    if (!ScanFunctions.FileExists(soundPath) && !Wizard.IsOnIgnoreList(soundPath))
                    {
                        Wizard.StoreInvalidKey(Strings.InvalidFile, rk2.Name, "(default)");
                    }
                }
                else if (!string.IsNullOrEmpty(subKey))
                {
                    var rk2 = rk.OpenSubKey(subKey);
                    if (rk2 != null)
                    {
                        ParseSoundKeys(rk2);
                    }
                }
            }
        }
        /// <summary>
        ///     Scans for invalid references to drivers
        /// </summary>
        public override void Scan()
        {
            try
            {
                using (
                    var regKey =
                        Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32"))
                {
                    if (regKey == null)
                    {
                        return;
                    }

                    Wizard.Report.WriteLine("Scanning for missing drivers");

                    foreach (
                        var driverName in
                        regKey.GetValueNames()
                        .Select(
                            driverName => new { Name = driverName, Value = regKey.GetValue(driverName) as string })
                        .Where(o => !string.IsNullOrEmpty(o.Value))
                        .Where(o => !ScanFunctions.FileExists(o.Value) && !Wizard.IsOnIgnoreList(o.Value))
                        .Select(o => o.Name)
                        .TakeWhile(driverName => !CancellationToken.IsCancellationRequested))
                    {
                        Wizard.StoreInvalidKey(Strings.InvalidFile, regKey.Name,
                                               string.IsNullOrWhiteSpace(driverName) ? "(default)" : driverName);
                    }
                }
            }
            catch (SecurityException ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }
Esempio n. 4
0
        /// <summary>
        ///     Checks MUI Cache for invalid file references (XP Only)
        /// </summary>
        private static void ScanMuiCache()
        {
            try
            {
                using (var regKey = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\ShellNoRoam\MUICache"))
                {
                    if (regKey == null)
                    {
                        return;
                    }

                    foreach (var valueName in regKey.GetValueNames()
                             .Where(valueName => !string.IsNullOrWhiteSpace(valueName))
                             .Where(valueName => !valueName.StartsWith("@") && valueName != "LangID")
                             .Where(valueName => !ScanFunctions.FileExists(valueName) && !Wizard.IsOnIgnoreList(valueName))
                             .TakeWhile(valueName => !ScanFunctions.FileExists(valueName) && !Wizard.IsOnIgnoreList(valueName)))
                    {
                        Wizard.StoreInvalidKey(Strings.InvalidFile, regKey.Name, valueName);
                    }
                }
            }
            catch (SecurityException ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }
Esempio n. 5
0
        /// <summary>
        ///     Constructor for new bad registry key
        /// </summary>
        /// <param name="sectionName">Section name</param>
        /// <param name="problem">Reason registry key is invalid</param>
        /// <param name="baseKey">Registry hive</param>
        /// <param name="subKey">Path to registry key (excluding registry hive)</param>
        /// <param name="valueName">Value Name (can be null)</param>
        /// <param name="severity">The severity (between 1-5) of the problem</param>
        public BadRegistryKey(string sectionName, string problem, string baseKey, string subKey, string valueName,
                              int severity)
        {
            SectionName = sectionName;
            Problem     = problem;
            BaseRegKey  = baseKey;
            SubRegKey   = subKey;
            _nSeverity  = severity;

            if (string.IsNullOrEmpty(valueName))
            {
                return;
            }

            ValueName = valueName;

            // Open registry key
            var regKey = Utils.RegOpenKey(baseKey, subKey);

            // Convert value to string
            if (regKey != null)
            {
                Data = ScanFunctions.RegConvertXValueToString(regKey, valueName);
            }
        }
        /// <summary>
        ///     Checks for inprocserver file
        /// </summary>
        /// <param name="regKey">The registry key contain Inprocserver subkey</param>
        /// <returns>False if Inprocserver is null or doesnt exist</returns>
        private static bool InprocServerExists(RegistryKey regKey)
        {
            if (regKey == null)
            {
                return(false);
            }

            RegistryKey regKeyInprocSrvr = null, regKeyInprocSrvr32 = null;

            try
            {
                regKeyInprocSrvr = regKey.OpenSubKey("InprocServer");

                var inprocServer = regKeyInprocSrvr?.GetValue("") as string;

                if (!string.IsNullOrEmpty(inprocServer))
                {
                    if (ScanFunctions.FileExists(inprocServer) || Wizard.IsOnIgnoreList(inprocServer))
                    {
                        return(true);
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("The following error occurred: " + ex.Message +
                                "\nUnable to check if InprocServer exists.");
            }
            finally
            {
                regKeyInprocSrvr?.Close();
            }

            try
            {
                regKeyInprocSrvr32 = regKey.OpenSubKey("InprocServer32");

                var inprocServer32 = regKeyInprocSrvr32?.GetValue("") as string;

                if (!string.IsNullOrEmpty(inprocServer32))
                {
                    if (ScanFunctions.FileExists(inprocServer32) || Wizard.IsOnIgnoreList(inprocServer32))
                    {
                        return(true);
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("The following error occurred: " + ex.Message +
                                "\nUnable to check if InprocServer32 exists.");
            }
            finally
            {
                regKeyInprocSrvr32?.Close();
            }

            return(false);
        }
Esempio n. 7
0
        /// <summary>
        ///     Checks for invalid files in startup registry key
        /// </summary>
        /// <param name="regKey">The registry key to scan</param>
        private static void CheckAutoRun(RegistryKey regKey)
        {
            if (regKey == null)
            {
                return;
            }

            Wizard.Report.WriteLine("Checking for invalid files in " + regKey.Name);

            foreach (
                var progName in regKey.GetValueNames().TakeWhile(progName => !CancellationToken.IsCancellationRequested)
                )
            {
                var runPath = regKey.GetValue(progName) as string;

                if (string.IsNullOrEmpty(runPath))
                {
                    continue;
                }

                // Check run path by itself
                if (ScanFunctions.FileExists(runPath) || Wizard.IsOnIgnoreList(runPath))
                {
                    continue;
                }

                // See if file exists (also checks if string is null)
                string filePath, args;

                if (Utils.ExtractArguments(runPath, out filePath, out args))
                {
                    continue;
                }

                if (Wizard.IsOnIgnoreList(filePath))
                {
                    continue;
                }

                if (Utils.ExtractArguments2(runPath, out filePath, out args))
                {
                    continue;
                }

                if (Wizard.IsOnIgnoreList(filePath))
                {
                    continue;
                }

                Wizard.StoreInvalidKey(Strings.InvalidFile, regKey.Name,
                                       string.IsNullOrWhiteSpace(progName) ? "(default)" : progName);
            }

            regKey.Close();
        }
        /// <summary>
        ///     Finds invalid font references
        /// </summary>
        public override void Scan()
        {
            var path = new StringBuilder(260);

            try
            {
                using (
                    var regKey =
                        Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"))
                {
                    if (regKey == null)
                    {
                        return;
                    }

                    Wizard.Report.WriteLine("Scanning for invalid fonts");

                    if (!SHGetSpecialFolderPath(IntPtr.Zero, path, CSIDL_FONTS, false))
                    {
                        return;
                    }

                    foreach (var fontName in
                             regKey.GetValueNames()
                             .Select(valueName => new { Name = valueName, Value = regKey.GetValue(valueName) as string })
                             // Skip if value is empty
                             .Where(o => !string.IsNullOrEmpty(o.Value))
                             // Check value by itself
                             .Where(o => !ScanFunctions.FileExists(o.Value))
                             .Where(o => !Wizard.IsOnIgnoreList(o.Value))
                             .Select(o => new { o.Name, o.Value, Path = $"{path.ToString()}\\{o.Value}" })
                             // Check for font in fonts folder
                             .Where(o => !File.Exists(o.Path) && !Wizard.IsOnIgnoreList(o.Path))
                             .Select(o => o.Name)
                             .TakeWhile(fontName => !CancellationToken.IsCancellationRequested)
                             )
                    {
                        Wizard.StoreInvalidKey(Strings.InvalidFile, regKey.ToString(),
                                               string.IsNullOrWhiteSpace(fontName) ? "(default)" : fontName);
                    }
                }
            }
            catch (SecurityException ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }
Esempio n. 9
0
        private static void ScanInstallFolders()
        {
            var regKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\Folders");

            if (regKey == null)
            {
                return;
            }

            foreach (var folder in regKey.GetValueNames()
                     .Where(folder => !string.IsNullOrWhiteSpace(folder))
                     .Where(folder => !ScanFunctions.DirExists(folder) && !Wizard.IsOnIgnoreList(folder))
                     .TakeWhile(folder => !CancellationToken.IsCancellationRequested))
            {
                Wizard.StoreInvalidKey(Strings.InvalidFile, regKey.Name, folder);
            }
        }
Esempio n. 10
0
        private static void EnumMruList(RegistryKey regKey)
        {
            foreach (var valueName in regKey.GetValueNames())
            {
                var    filePath = "";
                string fileArgs;

                // Skip if value name is null/empty
                if (string.IsNullOrWhiteSpace(valueName))
                {
                    continue;
                }

                // Ignore MRUListEx and others
                if (!Regex.IsMatch(valueName, "[0-9]"))
                {
                    continue;
                }

                var value = regKey.GetValue(valueName);

                var    fileName     = ExtractUnicodeStringFromBinary(value);
                string shortcutPath = $"{Environment.GetFolderPath(Environment.SpecialFolder.Recent)}\\{fileName}.lnk";

                // See if file exists in Recent Docs folder
                if (!string.IsNullOrEmpty(fileName))
                {
                    Wizard.StoreInvalidKey(Strings.InvalidRegKey, regKey.ToString(), valueName);
                    continue;
                }

                if (ScanFunctions.FileExists(shortcutPath) && Utils.ResolveShortcut(shortcutPath, out filePath, out fileArgs))
                {
                    continue;
                }

                if (!Wizard.IsOnIgnoreList(shortcutPath) && !Wizard.IsOnIgnoreList(filePath))
                {
                    Wizard.StoreInvalidKey(Strings.InvalidFile, regKey.ToString(), valueName);
                }
            }
        }
        /// <summary>
        ///     Sees if the help file exists
        /// </summary>
        /// <param name="helpFile">Should contain the filename</param>
        /// <param name="helpPath">Should be the path to file</param>
        /// <returns>True if it exists</returns>
        private static bool HelpFileExists(string helpFile, string helpPath)
        {
            if (string.IsNullOrEmpty(helpFile) || string.IsNullOrEmpty(helpPath))
            {
                return(true);
            }

            if (ScanFunctions.FileExists(helpPath) || Wizard.IsOnIgnoreList(helpPath))
            {
                return(true);
            }

            if (ScanFunctions.FileExists(helpFile) || Wizard.IsOnIgnoreList(helpFile))
            {
                return(true);
            }

            var combinedPath = Path.Combine(helpPath, helpFile);

            return(ScanFunctions.FileExists(combinedPath) || Wizard.IsOnIgnoreList(combinedPath));
        }
Esempio n. 12
0
        /// <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);
            }
        }
Esempio n. 13
0
        /// <summary>
        ///     <para>Stores an invalid registry key to array list</para>
        ///     <para>Use IsOnIgnoreList to check for ignored registry keys and paths</para>
        /// </summary>
        /// <param name="problem">Reason its invalid</param>
        /// <param name="regPath">The path to registry key (including registry hive)</param>
        /// <param name="valueName">Value name (See remarks)</param>
        /// <remarks>Set value name to null/empty for no value name or (default) to use default value</remarks>
        /// <returns>True if it was added. Otherwise, false.</returns>
        internal static bool StoreInvalidKey(string problem, string regPath, string valueName)
        {
            string baseKey, subKey;

            // Check for null parameters
            if (string.IsNullOrEmpty(problem) || string.IsNullOrEmpty(regPath))
            {
                return(false);
            }

            // Make sure registry key isnt already in array
            if (BadRegKeyArray.Contains(regPath, valueName))
            {
                return(false);
            }

            // Make sure registry key exists
            if (!Utils.RegKeyExists(regPath))
            {
                return(false);
            }

            // Parse registry key to base and subkey
            if (!Utils.ParseRegKeyPath(regPath, out baseKey, out subKey))
            {
                return(false);
            }

            // Check for ignored registry path
            if (IsOnIgnoreList(regPath))
            {
                return(false);
            }

            using (var regKey = Utils.RegOpenKey(regPath, false))
            {
                // Can we get write access?
                if (regKey == null)
                {
                    return(false);
                }

                // Can we delete it?
                if (!ScanFunctions.CanDeleteKey(regKey))
                {
                    return(false);
                }
            }

            // If value name is specified, see if it exists
            if (!string.IsNullOrEmpty(valueName))
            {
                if (!ScanFunctions.ValueNameExists(baseKey, subKey, valueName))
                {
                    return(false);
                }
            }

            var severity = 1;

            if (problem == Strings.InvalidFile)
            {
                severity = 5;
            }
            else if (problem == Strings.InvalidFileExt)
            {
                severity = 2;
            }
            else if (problem == Strings.InvalidInprocServer)
            {
                severity = 4;
            }
            else if (problem == Strings.InvalidInprocServer32)
            {
                severity = 4;
            }
            else if (problem == Strings.InvalidProgIDFileExt)
            {
                severity = 3;
            }
            else if (problem == Strings.InvalidRegKey)
            {
                severity = 2;
            }
            else if (problem == Strings.InvalidToolbar)
            {
                severity = 4;
            }
            else if (problem == Strings.MissingAppID)
            {
                severity = 5;
            }
            else if (problem == Strings.MissingCLSID)
            {
                severity = 5;
            }
            else if (problem == Strings.MissingProgID)
            {
                severity = 5;
            }
            else if (problem == Strings.NoRegKey)
            {
                severity = 1;
            }
            else if (problem == Strings.ObsoleteRegKey)
            {
                severity = 1;
            }

            BadRegKeyArray.Add(new BadRegistryKey(CurrentScannerName, problem, baseKey, subKey, valueName, severity));

            Report.WriteLine(!string.IsNullOrEmpty(valueName)
                ? $"Bad Registry Value Found! Problem: \"{problem}\" Path: \"{regPath}\" Value Name: \"{valueName}\""
                : $"Bad Registry Key Found! Problem: \"{problem}\" Path: \"{regPath}\"");

            return(true);
        }
Esempio n. 14
0
        private static void ScanAppPaths()
        {
            var regKey = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\App Paths");

            if (regKey == null)
            {
                return;
            }

            foreach (
                var subKey in
                regKey.GetSubKeyNames().TakeWhile(subKey => !CancellationToken.IsCancellationRequested))
            {
                var regKey2 = regKey.OpenSubKey(subKey);

                if (regKey2 == null)
                {
                    continue;
                }

                if (Convert.ToInt32(regKey2.GetValue("BlockOnTSNonInstallMode")) == 1)
                {
                    continue;
                }

                var appPath = regKey2.GetValue("") as string;
                var appDir  = regKey2.GetValue("Path") as string;

                if (string.IsNullOrEmpty(appPath))
                {
                    Wizard.StoreInvalidKey(Strings.InvalidRegKey, regKey2.ToString());
                    continue;
                }

                if (!string.IsNullOrEmpty(appDir))
                {
                    if (Wizard.IsOnIgnoreList(appDir))
                    {
                        continue;
                    }
                    if (Utils.SearchPath(appPath, appDir))
                    {
                        continue;
                    }
                    if (Utils.SearchPath(subKey, appDir))
                    {
                        continue;
                    }
                }
                else
                {
                    if (ScanFunctions.FileExists(appPath) || Wizard.IsOnIgnoreList(appPath))
                    {
                        continue;
                    }
                }

                Wizard.StoreInvalidKey(Strings.InvalidFile, regKey2.Name);
            }

            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();
        }
        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();
        }