예제 #1
0
        private void MainWindow_FormLoadPost(object sender, EventArgs e)
        {
            //Can be null if restart after upgrade is in progress
            //In this case, EarlyUpdateCheckExt.Terminate() might have been called already
            //RemoveAndBackupFormLoadPostHandlers and RestoreFormLoadPostHandlers should work around that, but you never know...
            if (m_host == null || m_host.MainWindow == null)
            {
                return;
            }
            if (m_host.MainWindow.IsDisposed || m_host.MainWindow.Disposing)
            {
                return;
            }

            m_host.MainWindow.FormLoadPost -= MainWindow_FormLoadPost;

            //Load plugins and check check for new translations if not already done
            if (PluginUpdateHandler.CheckTranslations && !m_bRestartInvoke)
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(CheckPluginLanguages));
            }
            else if (!m_bRestartInvoke)
            {
                //Only load plugins, do NOT check for new translations
                ThreadPool.QueueUserWorkItem(new WaitCallback((object o) => { PluginUpdateHandler.LoadPlugins(false); }));
            }
            PluginDebug.AddInfo("All plugins loaded", 0, DebugPrint);
            m_bRestartInvoke = false;
        }
예제 #2
0
        private void CheckPluginLanguages(object o)
        {
            PluginUpdateHandler.LoadPlugins(false);
            if (!PluginConfig.Active)
            {
                return;
            }
            if (m_bPluginLanguagesChecked)
            {
                return;
            }
            m_bPluginLanguagesChecked = true;
            string translations             = string.Empty;
            List <OwnPluginUpdate> lPlugins = new List <OwnPluginUpdate>();

            foreach (PluginUpdate pu in PluginUpdateHandler.Plugins)
            {
                if (!PluginUpdateHandler.VersionsEqual(pu.VersionInstalled, pu.VersionAvailable))
                {
                    continue;
                }
                foreach (var t in pu.Translations)
                {
                    if (t.NewTranslationAvailable || (PluginConfig.DownloadActiveLanguage && t.TranslationForCurrentLanguageAvailable))
                    {
                        lPlugins.Add(pu as OwnPluginUpdate);
                        break;
                    }
                }
            }
            if (lPlugins.Count == 0)
            {
                return;
            }
            var arrPlugins = lPlugins.ConvertAll(x => x.ToString()).ToArray();

            PluginDebug.AddInfo("Available translation updates", 0, arrPlugins);
            KeePassLib.Delegates.GAction DisplayTranslationForm = () =>
            {
                using (TranslationUpdateForm t = new TranslationUpdateForm())
                {
                    t.InitEx(lPlugins);
                    if (t.ShowDialog() == DialogResult.OK)
                    {
                        UpdatePluginTranslations(PluginConfig.DownloadActiveLanguage, t.SelectedPlugins);
                    }
                }
            };
            m_host.MainWindow.BeginInvoke(DisplayTranslationForm);
        }
예제 #3
0
        internal void InitEx(List <OwnPluginUpdate> lPlugins)
        {
            Text = PluginTranslate.TranslationUpdateForm;
            lSelectPlugins.Text = PluginTranslate.SelectPluginsForTranslationUpdate;
            bOK.Text            = PluginTranslate.TranslationDownload_Update;
            bOK.Text            = PluginTranslate.PluginUpdateSelected;
            bCancel.Text        = KPRes.Cancel;

            clbPlugins.Items.Clear();
            lPlugins.Sort(SortOwnPluginUpdate);
            foreach (OwnPluginUpdate plugin in lPlugins)
            {
                clbPlugins.Items.Add(plugin.Name, PluginUpdateHandler.VersionsEqual(plugin.VersionInstalled, plugin.VersionAvailable) ? CheckState.Checked : CheckState.Indeterminate);
            }
        }
예제 #4
0
        public override bool Initialize(IPluginHost host)
        {
            m_host = host;

            PluginTranslate.TranslationChanged += delegate(object sender, TranslationChangedEventArgs e)
            {
                if (!string.IsNullOrEmpty(KeePass.Program.Translation.Properties.Iso6391Code))
                {
                    PluginUpdateHandler.LanguageIso = KeePass.Program.Translation.Properties.Iso6391Code;
                }
                else
                {
                    PluginUpdateHandler.LanguageIso = e.NewLanguageIso6391;
                }
            };
            PluginTranslate.Init(this, KeePass.Program.Translation.Properties.Iso6391Code);
            Tools.DefaultCaption = PluginTranslate.PluginName;
            Tools.PluginURL      = "https://github.com/rookiestyle/earlyupdatecheck/";
            PluginConfig.Read();

            GlobalWindowManager.WindowAdded   += WindowAdded;
            GlobalWindowManager.WindowRemoved += WindowRemoved;
            m_tsMenu        = new ToolStripMenuItem(PluginTranslate.PluginName + "...");
            m_tsMenu.Click += (o, e) => Tools.ShowOptions();
            ToolStripMenuItem tsmiUpdate = Tools.FindToolStripMenuItem(m_host.MainWindow.MainMenu.Items, "m_menuHelpCheckForUpdates", true);

            if (tsmiUpdate != null)
            {
                m_tsMenu.Image = tsmiUpdate.Image;
            }
            else
            {
                m_tsMenu.Image = m_host.MainWindow.ClientIcons.Images[(int)KeePassLib.PwIcon.World];
            }
            m_host.MainWindow.ToolsMenu.DropDownItems.Add(m_tsMenu);

            Tools.OptionsFormShown  += OptionsFormShown;
            Tools.OptionsFormClosed += OptionsFormClosed;

            m_host.MainWindow.FormLoadPost += MainWindow_FormLoadPost;

            PluginUpdateHandler.Init();

            return(true);
        }
예제 #5
0
        private void bUpdateTranslations_Click(object sender, EventArgs e)
        {
            List <OwnPluginUpdate> lPlugins = new List <OwnPluginUpdate>();

            foreach (PluginUpdate pu in PluginUpdateHandler.Plugins)
            {
                OwnPluginUpdate opu = pu as OwnPluginUpdate;
                if (opu == null)
                {
                    continue;
                }
                if (!PluginUpdateHandler.VersionsEqual(pu.VersionInstalled, pu.VersionAvailable))
                {
                    continue;
                }
                if (opu.Translations.Count == 0)
                {
                    continue;
                }
                if (!lPlugins.Contains(opu))
                {
                    lPlugins.Add(opu);
                }
            }
            if (lPlugins.Count == 0)
            {
                PluginTools.PluginDebug.AddInfo("No plugins where translations can be updated", 0);
                return;
            }
            using (TranslationUpdateForm t = new TranslationUpdateForm())
            {
                t.InitEx(lPlugins);
                if (t.ShowDialog() == DialogResult.OK)
                {
                    Plugin.UpdatePluginTranslations(PluginConfig.DownloadActiveLanguage, t.SelectedPlugins);
                }
            }
        }
예제 #6
0
        private bool PostProcessDownload(string sTargetFolder, bool bProcessOK)
        {
            if (!bProcessOK)
            {
                return(false);
            }
            //Some plugins contain the plugin version in the filename
            //Identify this case and trigger deletion of old version
            string sNewFile = UrlUtil.GetFileName(MergeInVersion(true));
            string sOldFile = UrlUtil.GetFileName(MergeInVersion(false));

            if (string.Compare(sNewFile, sOldFile, true) == 0)
            {
                return(true);
            }

            string sNewFileFull = MergeInPluginFolder(PluginUpdateHandler.PluginsFolder) + sNewFile;
            string sOldFileFull = MergeInPluginFolder(PluginUpdateHandler.PluginsFolder) + sOldFile;

            //File.Exists is case sensitive if the OS is case sensitive
            //As ExternalPluginUpdates.xml may contain filenames that don't match because of this, don't rely on File.Exists here
            bool bExists = false;

            if (!KeePassLib.Native.NativeLib.IsUnix())
            {
                bExists = File.Exists(sOldFileFull);
            }
            else
            {
                bExists = UrlUtil.GetFilePaths(MergeInPluginFolder(PluginUpdateHandler.PluginsFolder), "*", SearchOption.TopDirectoryOnly).Find(x => string.Compare(UrlUtil.GetFileName(x), sOldFileFull, true) == 0) != null;
            }
            if (bExists && (string.Compare(sOldFileFull, PluginFile, true) == 0))
            {
                PluginUpdateHandler.DeleteSpecialFile(PluginFile);
            }
            return(true);
        }
예제 #7
0
        internal static int MoveFilesToTemp(params string[] files)
        {
            // 0 = success
            // -1 = aborted by user
            // other value = error

            string from = string.Empty;

            foreach (string file in files)
            {
                from += file + "\0";
            }
            from += "\0";

            string sTemp = PluginUpdateHandler.GetTempFolder() + "\0\0";

            SHFILEOPSTRUCT lpFileOp = new SHFILEOPSTRUCT();

            lpFileOp.hwnd   = IntPtr.Zero;
            lpFileOp.wFunc  = FILE_OP_TYPE.FO_MOVE;
            lpFileOp.pFrom  = from;
            lpFileOp.pTo    = sTemp;
            lpFileOp.fFlags = FILE_OP_FLAGS.FOF_NOCONFIRMMKDIR | FILE_OP_FLAGS.FOF_NOCONFIRMATION | FILE_OP_FLAGS.FOF_ALLOWUNDO;
            lpFileOp.fAnyOperationsAborted = false;
            lpFileOp.hNameMappings         = IntPtr.Zero;
            lpFileOp.lpszProgressTitle     = string.Empty;

            int result = SHFileOperation(ref lpFileOp);

            if (result == 0 && lpFileOp.fAnyOperationsAborted)
            {
                result = -1;
            }
            PluginDebug.AddInfo("Move in UAC mode: " + result.ToString());
            return(result);
        }
예제 #8
0
        private void UpdateAvailableTranslations()
        {
            Dictionary <string, List <UpdateComponentInfo> > dUpdateInfo = new Dictionary <string, List <UpdateComponentInfo> >();
            Dictionary <string, long> dResult = new Dictionary <string, long>();
            Type t = typeof(KeePass.Program).Assembly.GetType("KeePass.Util.UpdateCheckEx");

            if (t == null)
            {
                PluginDebug.AddError("Could not locate class 'UpdateCheckEx'", 0);
                return;
            }
            MethodInfo mi = t.GetMethod("DownloadInfoFiles", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Static);

            if (mi == null)
            {
                PluginDebug.AddError("Could not locate method 'DownloadInfoFiles'", 0);
                return;
            }

            if (string.IsNullOrEmpty(VersionURL))
            {
                PluginDebug.AddError("Could not read plugin update url", 0);
                return;
            }

            dUpdateInfo = mi.Invoke(null, new object[] { new List <string>()
                                                         {
                                                             VersionURL
                                                         }, null }) as Dictionary <string, List <UpdateComponentInfo> >;

            List <string> lTranslationsNew = new List <string>();

            string[] cSplit = new string[] { "!", "!!!" };
            foreach (KeyValuePair <string, List <UpdateComponentInfo> > kvp in dUpdateInfo)
            {
                if (kvp.Value == null)
                {
                    continue;
                }
                Version vCheck = null;
                foreach (UpdateComponentInfo uci in kvp.Value)
                {
                    //Github: <Plugin>!<language identifier>
                    string[] sParts = uci.Name.Split(cSplit, StringSplitOptions.RemoveEmptyEntries);
                    if (sParts.Length == 1)
                    {
                        vCheck = new Version(StrUtil.VersionToString(uci.VerAvailable, 2));
                        if (VersionAvailableIsUnknown())
                        {
                            VersionAvailable = vCheck;
                        }
                    }
                    if (!PluginUpdateHandler.VersionsEqual(VersionInstalled, vCheck))
                    {
                        return;                                                                                   //Different version might require different translation files
                    }
                    if (sParts.Length != 2)
                    {
                        continue;
                    }
                    long lVer = 0;
                    if (!long.TryParse(StrUtil.VersionToString(uci.VerAvailable), out lVer))
                    {
                        continue;
                    }
                    string sLang = Name + "." + sParts[1].ToLowerInvariant() + ".language.xml";
                    TranslationVersionCheck tvc = Translations.Find(x => x.LangugageFile == sLang);
                    if (tvc == null)
                    {
                        tvc = new TranslationVersionCheck()
                        {
                            LangugageFile = sLang
                        };
                        Translations.Add(tvc);
                    }
                    tvc.Available = lVer;
                }
            }
        }
예제 #9
0
        private void UpdatePlugins(bool bUpdateTranslationsOnly)
        {
            PluginDebug.AddInfo("UpdatePlugins start ", DebugPrint);
            Form fUpdateLog = null;

            m_slUpdatePlugins = StatusUtil.CreateStatusDialog(GlobalWindowManager.TopWindow, out fUpdateLog, PluginTranslate.PluginUpdateCaption, string.Empty, true, true);

            bool   success            = false;
            string sTempPluginsFolder = PluginUpdateHandler.GetTempFolder();

            ThreadStart ts = new ThreadStart(() =>
            {
                m_slUpdatePlugins.StartLogging(PluginTranslate.PluginUpdateCaption, false);

                PluginDebug.AddInfo("Use temp folder", PluginUpdateHandler.Shieldify.ToString(), sTempPluginsFolder, DebugPrint);

                //Download files
                foreach (PluginUpdate upd in PluginUpdateHandler.Plugins)
                {
                    if (!upd.Selected)
                    {
                        continue;
                    }
                    success |= UpdatePlugin(upd, sTempPluginsFolder, bUpdateTranslationsOnly);
                }
            });
            Thread t = new Thread(ts);

            t.IsBackground = true;
            t.Start();
            while (true && t.IsAlive)
            {
                if (!m_slUpdatePlugins.ContinueWork())
                {
                    t.Abort();
                    break;
                }
            }
            if (t != null && t.IsAlive)
            {
                t.Abort();
            }
            if (m_slUpdatePlugins != null)
            {
                m_slUpdatePlugins.EndLogging();
                m_slUpdatePlugins = null;
            }
            if (fUpdateLog != null)
            {
                fUpdateLog.Dispose();
            }

            //Move files from temp folder to plugin folder
            success &= PluginUpdateHandler.MoveAll(sTempPluginsFolder);
            foreach (var pu in PluginUpdateHandler.Plugins)
            {
                if (!pu.Selected)
                {
                    continue;
                }
                if (pu is OwnPluginUpdate)
                {
                    (pu as OwnPluginUpdate).UpdateTranslationInfo(true);
                }
            }
            if (success)
            {
                PluginUpdateHandler.Cleanup(sTempPluginsFolder);
            }
            success = true;
            //Restart KeePass to use new plugin versions
            PluginDebug.AddInfo("Update finished", "Succes: " + success.ToString(), DebugPrint);
            if (success && !bUpdateTranslationsOnly)
            {
                if (Tools.AskYesNo(PluginTranslate.PluginUpdateSuccess, PluginTranslate.PluginUpdateCaption) == DialogResult.Yes)
                {
                    if (m_bRestartInvoke)
                    {
                        m_host.MainWindow.Invoke(new KeePassLib.Delegates.GAction(() => { Restart(); }));
                    }
                    else
                    {
                        Restart();
                    }
                }
            }
        }
예제 #10
0
        private void OnUpdateCheckFormShown(object sender, EventArgs e)
        {
            m_lEventHandlerItemActivate = null;
            PluginDebug.AddSuccess("OUCFS 1", 0);
            if (!PluginConfig.Active || !PluginConfig.OneClickUpdate)
            {
                return;
            }
            PluginDebug.AddSuccess("OUCFS 2", 0);
            CustomListViewEx lvPlugins = (CustomListViewEx)Tools.GetControl("m_lvInfo", sender as UpdateCheckForm);

            if (lvPlugins == null)
            {
                PluginDebug.AddError("m_lvInfo not found", 0);
                return;
            }
            else
            {
                PluginDebug.AddSuccess("m_lvInfo found", 0);
            }
            PluginUpdateHandler.LoadPlugins(false);
            if (PluginUpdateHandler.Plugins.Count == 0)
            {
                return;
            }
            SetPluginSelectionStatus(false);
            bool bColumnAdded = false;

            m_lEventHandlerItemActivate = EventHelper.GetItemActivateHandlers(lvPlugins);
            if (m_lEventHandlerItemActivate.Count > 0)
            {
                EventHelper.RemoveItemActivateEventHandlers(lvPlugins, m_lEventHandlerItemActivate);
                lvPlugins.ItemActivate += LvPlugins_ItemActivate;
            }
            //https://github.com/mono/mono/issues/17747
            //Do NOT use ListView.SmallImageList
            if (m_ImgApply == null)
            {
                m_ImgApply = (Image)KeePass.Program.Resources.GetObject("B16x16_Apply");
            }
            if (m_ImgUnselected == null)
            {
                m_ImgUnselected = m_ImgApply == null ? null : UIUtil.CreateGrayImage(m_ImgApply);
            }
            foreach (ListViewItem item in lvPlugins.Items)
            {
                PluginDebug.AddInfo("Check plugin update status", 0, item.SubItems[0].Text, item.SubItems[1].Text);
                if (!item.SubItems[1].Text.Contains(KeePass.Resources.KPRes.NewVersionAvailable))
                {
                    continue;
                }
                foreach (PluginUpdate upd in PluginUpdateHandler.Plugins)
                {
                    if (item.SubItems[0].Text != upd.Title)
                    {
                        continue;
                    }
                    if (upd.UpdateMode == UpdateOtherPluginMode.Unknown)
                    {
                        continue;
                    }
                    if (!bColumnAdded)
                    {
                        lvPlugins.Columns.Add(PluginTranslate.PluginUpdate);
                        bColumnAdded = true;
                    }
                    ListViewItem.ListViewSubItem lvsiUpdate = new ListViewItem.ListViewSubItem(item, PluginTranslate.PluginUpdate);
                    lvsiUpdate.Tag = upd;
                    item.SubItems.Add(lvsiUpdate);
                    upd.Selected = true;
                    try
                    {
                        upd.VersionAvailable = new Version(item.SubItems[3].Text);
                    }
                    catch (Exception ex)
                    {
                        PluginDebug.AddError("Could not parse new version", 0, upd.Name, item.SubItems[3].Text, ex.Message);
                    }
                    break;
                }
            }
            if (bColumnAdded)
            {
                UIUtil.ResizeColumns(lvPlugins, new int[] { 3, 3, 2, 2, 1 }, true);
                lvPlugins.MouseClick       += OnUpdateCheckFormPluginMouseClick;
                lvPlugins.OwnerDraw         = true;
                lvPlugins.DrawSubItem      += LvPlugins_DrawSubItem;
                lvPlugins.DrawColumnHeader += LvPlugins_DrawColumnHeader;
                ShowUpdateButton(sender as Form, true);
            }
            if (m_lEventHandlerItemActivate.Count == 0)
            {
                if (lvPlugins.ContextMenuStrip == null)
                {
                    lvPlugins.ContextMenuStrip = new ContextMenuStrip();
                    string sMenuText = KeePass.Resources.KPRes.PluginsDesc;
                    try { sMenuText = Tools.GetControl("m_linkPlugins", sender as UpdateCheckForm).Text; }
                    catch { }
                    lvPlugins.ContextMenuStrip.Items.Add(new ToolStripMenuItem(sMenuText, null, OnReleasePageClick));
                    lvPlugins.ContextMenuStrip.Opening += ContextMenuStrip_Opening;
                }
                else
                {
                    PluginDebug.AddWarning("m_lvEntries.ContextMenuStrip already defined, special handling for added 'go to release page' to be defined", 0);
                }
            }
        }