예제 #1
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);
            }
        }
        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();
        }