From 2bba8c37070ad960be77a3280b430cb0b1adb3f4 Mon Sep 17 00:00:00 2001 From: rookiestyle Date: Sun, 20 Mar 2022 14:16:06 +0100 Subject: [PATCH] Add compatibility with secure desktop mode EarlyUpdateCheck now properly detects usage of secure desktop and delays displaying the update form. Using secure desktop does not allow to show the update form right away. Closes #49 --- Translations/EarlyUpdateCheck.de.language.xml | 9 +- .../EarlyUpdateCheck.template.language.xml | 7 + src/EarlyUpdateCheck.cs | 149 ++++++++++++------ src/Properties/AssemblyInfo.cs | 4 +- src/Utilities/PluginTranslation.cs | 10 ++ version.info | 4 +- 6 files changed, 132 insertions(+), 51 deletions(-) diff --git a/Translations/EarlyUpdateCheck.de.language.xml b/Translations/EarlyUpdateCheck.de.language.xml index cdf9a85..5c1fc0e 100644 --- a/Translations/EarlyUpdateCheck.de.language.xml +++ b/Translations/EarlyUpdateCheck.de.language.xml @@ -4,7 +4,7 @@ Increment the TranslationVersion every time the translation file is updated Also update the version.info file --> - 8 + 9 Active Aktiv @@ -144,4 +144,11 @@ KeePass bietet folgende Installationsmethoden: - MSI: KeePass-<Version>.msi - Portabel: KeePass-<Version>.zip + + SecureDesktopMode + EarlyUpdateCheck hat verfügbare Updates von Plugins und/oder KeePass erkannt. + +Da die Option '{0}' aktiv ist, kann das Updatefenster jetzt nicht angezeigt werden. +Es wird angezeigt NACHDEM das '{1}' Fenster geschlossen wurde. + \ No newline at end of file diff --git a/Translations/EarlyUpdateCheck.template.language.xml b/Translations/EarlyUpdateCheck.template.language.xml index 9ab3bd4..d012f85 100644 --- a/Translations/EarlyUpdateCheck.template.language.xml +++ b/Translations/EarlyUpdateCheck.template.language.xml @@ -143,4 +143,11 @@ Different installation types offered: - MSI: KeePass-<Version>.msi is used to install KeePass - Portable: KeePass-<Version>.zip is used to download and extract KeePass + + SecureDesktopMode + EarlyUpdateCheck detected available updates of plugins and/or KeePass. + +As option '{0}' is active, the update form cannot be displayed now. +It will be shown AFTER you close the '{1}' form. + \ No newline at end of file diff --git a/src/EarlyUpdateCheck.cs b/src/EarlyUpdateCheck.cs index 7a8cf49..9c313da 100644 --- a/src/EarlyUpdateCheck.cs +++ b/src/EarlyUpdateCheck.cs @@ -39,7 +39,7 @@ public override bool Initialize(IPluginHost host) { m_host = host; - PluginTranslate.TranslationChanged += delegate (object sender, TranslationChangedEventArgs e) + PluginTranslate.TranslationChanged += delegate (object sender, TranslationChangedEventArgs e) { if (!string.IsNullOrEmpty(KeePass.Program.Translation.Properties.Iso6391Code)) PluginUpdateHandler.LanguageIso = KeePass.Program.Translation.Properties.Iso6391Code; @@ -123,8 +123,8 @@ private void MainWindow_FormLoadPost(object sender, EventArgs e) else if (!m_bRestartTriggered) { //Only load plugins, do NOT check for new translations - ThreadPool.QueueUserWorkItem(new WaitCallback((object o) => - { + ThreadPool.QueueUserWorkItem(new WaitCallback((object o) => + { PluginUpdateHandler.LoadPlugins(false); CheckExternalPluginUpdate(); })); @@ -180,7 +180,7 @@ private void LanguageFormAdded(object sender, EventArgs e) private void WindowRemoved(object sender, GwmWindowEventArgs e) { - if ((m_kpf != null) && (e.Form is KeyPromptForm)) m_kpf = null; + if ((m_kpf != null) && (e.Form is KeyPromptForm)) m_kpf = null; } #region Check for updates @@ -281,7 +281,8 @@ private void UpdateCheckBackground() if (m_slUpdateCheck != null) { - m_host.MainWindow.Invoke(new KeePassLib.Delegates.GAction(() => { m_slUpdateCheck.EndLogging(); })); + if (bUpdAvail) UpdateStatusLogger(); + EndLogging(); m_slUpdateCheck = null; } @@ -313,8 +314,8 @@ private void UpdateCheckBackground() } finally { - try { if (m_slUpdateCheck != null) m_slUpdateCheck.EndLogging(); } - catch (Exception) { } + try { if (m_slUpdateCheck != null) EndLogging(); } + catch (Exception ex) { lMsg.Add(ex.Message); } if (bOK) lock (m_lock) { m_UpdateCheckStatus = UpdateCheckStatus.Checked; } else @@ -336,14 +337,14 @@ private void UpdateCheckBackground() } while (true) { - if ((m_slUpdateCheck != null) && !m_slUpdateCheck.ContinueWork()) break; + if ((m_slUpdateCheck != null) && !ContinueWork()) break; lock (m_lock) { if (m_UpdateCheckStatus == UpdateCheckStatus.Checked) break; if (m_UpdateCheckStatus == UpdateCheckStatus.Error) break; } } - if (m_slUpdateCheck != null) m_slUpdateCheck.EndLogging(); + if (m_slUpdateCheck != null) EndLogging(); if (bOK) return; } catch (Exception ex) @@ -359,6 +360,61 @@ private void UpdateCheckBackground() } } + private bool ContinueWork() + { + try + { + var c = UIThread(() => + { + bool cw = false; + lock (m_slUpdateCheck) + { + if (m_slUpdateCheck == null) cw = false; + else cw = m_slUpdateCheck.ContinueWork(); + } + return cw; + }); + if (c != null) return (bool)c; + } + catch { } + return true; + } + + private void EndLogging() + { + UIThread(() => + { + lock (m_slUpdateCheck) + { + if (m_slUpdateCheck != null) m_slUpdateCheck.EndLogging(); + m_slUpdateCheck = null; + } + return null; + }); + } + + private object UIThread(KeePassLib.Delegates.GFunc a) + { + try + { + return m_bCancel.Invoke(a); + } + catch (Exception ex) + { + PluginDebug.AddError("Show SecureDesktopHint", 0, ex.Message); + } + return null; + } + + private void UpdateStatusLogger() + { + if (!m_kpf.SecureDesktopMode) return; + UIThread(() => { + Tools.ShowInfo(string.Format(PluginTranslate.SecureDesktopMode, KeePass.Resources.KPRes.MasterKeyOnSecureDesktop, KeePass.Resources.KPRes.OpenDatabase)); + return null; + }); + } + /// /// Check whether searching for updates of plugins or translations shall be done /// @@ -383,17 +439,18 @@ private UpdateCheckType UpdateCheckRequired() return UpdateCheckType.Required; } + private Button m_bCancel = null; private IStatusLogger CreateUpdateCheckLogger() { IStatusLogger sl = StatusUtil.CreateStatusDialog(null, out m_CheckProgress, KeePass.Resources.KPRes.UpdateCheck, KeePass.Resources.KPRes.CheckingForUpd + "...", true, true); - Button btnCancel = (Button)Tools.GetControl("m_btnCancel", m_CheckProgress); - if (btnCancel != null) + m_bCancel = (Button)Tools.GetControl("m_btnCancel", m_CheckProgress); + if (m_bCancel != null) { - int x = btnCancel.Right; - btnCancel.AutoSize = true; - btnCancel.Text = PluginTranslate.EnterBackgroundMode; - btnCancel.Left = x - btnCancel.Width; + int x = m_bCancel.Right; + m_bCancel.AutoSize = true; + m_bCancel.Text = PluginTranslate.EnterBackgroundMode; + m_bCancel.Left = x - m_bCancel.Width; } return sl; } @@ -496,14 +553,14 @@ private void OnUpdateCheckFormShown(object sender, EventArgs e) } //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_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); PluginDebug.AddInfo("Installed updatable plugins", 0, PluginUpdateHandler.Plugins.ConvertAll(x => x.Name + " / " + x.Title + " / " + x.UpdateMode.ToString() + " / " + x.UpdatePossible.ToString()).ToArray()); KeePass_Update kpu = null; foreach (ListViewItem item in lvPlugins.Items) { PluginDebug.AddInfo("Check plugin update status", 0, item.SubItems[0].Text, item.SubItems[1].Text); - string sHelp = "-"+item.SubItems[0].Text+"-"+item.SubItems[1].Text + "- " + (!item.SubItems[1].Text.Contains(KeePass.Resources.KPRes.NewVersionAvailable)).ToString(); + string sHelp = "-" + item.SubItems[0].Text + "-" + item.SubItems[1].Text + "- " + (!item.SubItems[1].Text.Contains(KeePass.Resources.KPRes.NewVersionAvailable)).ToString(); if (!item.SubItems[1].Text.Contains(KeePass.Resources.KPRes.NewVersionAvailable)) continue; if (item.Index == 0 && item.Text == "KeePass") { @@ -537,7 +594,7 @@ private void OnUpdateCheckFormShown(object sender, EventArgs e) if (!bColumnAdded) { lvPlugins.Columns.Add(PluginTranslate.PluginUpdate); - lvPlugins.KeyPress += LvPlugins_KeyPress; + lvPlugins.KeyPress += LvPlugins_KeyPress; bColumnAdded = true; } ListViewItem.ListViewSubItem lvsiUpdate = new ListViewItem.ListViewSubItem(item, PluginTranslate.PluginUpdate); @@ -562,7 +619,7 @@ private void OnUpdateCheckFormShown(object sender, EventArgs e) break; } } - if (bColumnAdded) + if (bColumnAdded) { UIUtil.ResizeColumns(lvPlugins, new int[] { 3, 3, 2, 2, 1 }, true); lvPlugins.MouseClick += OnUpdateCheckFormPluginMouseClick; @@ -571,7 +628,7 @@ private void OnUpdateCheckFormShown(object sender, EventArgs e) lvPlugins.DrawColumnHeader += LvPlugins_DrawColumnHeader; ShowUpdateButton(sender as Form, true, kpu); } - + if (m_lEventHandlerItemActivate.Count == 0) { if (lvPlugins.ContextMenuStrip == null) @@ -588,8 +645,8 @@ private void OnUpdateCheckFormShown(object sender, EventArgs e) } private bool m_bActivateKeePassUpdateTab = false; - private void CheckKeePassInstallType(bool bShowOptions) - { + private void CheckKeePassInstallType(bool bShowOptions) + { if (PluginConfig.KeePassInstallTypeConfigured) return; m_bActivateKeePassUpdateTab = true; if (!bShowOptions) Tools.ShowInfo(PluginTranslate.KeePassUpdate_RequestInstallType); @@ -597,7 +654,7 @@ private void CheckKeePassInstallType(bool bShowOptions) } private void LvPlugins_KeyPress(object sender, KeyPressEventArgs e) - { + { if (e.KeyChar != (char)Keys.Space) return; var lv = sender as ListView; if (lv == null || lv.SelectedItems.Count < 0) return; @@ -663,17 +720,17 @@ private void OnUpdateCheckFormPluginMouseClick(object sender, MouseEventArgs e) ToggleUpdateFlag(sender as ListView, info.SubItem.Tag as PluginUpdate); } - private void ToggleUpdateFlag(ListView lv, PluginUpdate upd) - { + private void ToggleUpdateFlag(ListView lv, PluginUpdate upd) + { if (lv == null || upd == null) return; upd.Selected = !upd.Selected; bool bAtLeast1Selected = PluginUpdateHandler.Plugins.Find(x => x.Selected == true) != null; if (!bAtLeast1Selected) - { + { //Check whether KeePass itself is selected for update bAtLeast1Selected = lv.Items[0].SubItems[lv.Items[0].SubItems.Count - 1].Tag is KeePass_Update; if (bAtLeast1Selected) bAtLeast1Selected = (lv.Items[0].SubItems[lv.Items[0].SubItems.Count - 1].Tag as KeePass_Update).Selected; - } + } if (!ShowUpdateButton(lv.FindForm(), bAtLeast1Selected, lv.Items[0].SubItems[lv.Items[0].SubItems.Count - 1].Tag)) { upd.Selected = !upd.Selected; @@ -736,13 +793,13 @@ private bool ShowUpdateButton(Form form, bool enable, object oKeePassUpdate) } bUpdate.Tag = oKeePassUpdate; bUpdate.Enabled = enable; - + SetUpdateButtonText(bUpdate, oKeePassUpdate); return true; } - private void SetUpdateButtonText(Button bUpdate, object oKeePassUpdate) - { + private void SetUpdateButtonText(Button bUpdate, object oKeePassUpdate) + { bool bAtLeast1PluginSelected = PluginUpdateHandler.Plugins.FindAll(x => x.Selected).Count > 0; if (!bUpdate.Enabled) { @@ -758,7 +815,7 @@ private void SetUpdateButtonText(Button bUpdate, object oKeePassUpdate) else if (bAtLeast1PluginSelected) bUpdate.Text = PluginTranslate.PluginUpdateSelected; else if (kpu != null & kpu.Selected) bUpdate.Text = PluginTranslate.PluginUpdateKeePass; else - { + { bUpdate.Enabled = false; bUpdate.Text = PluginTranslate.PluginUpdate; } @@ -776,9 +833,9 @@ private void LvPlugins_DrawSubItem(object sender, DrawListViewSubItemEventArgs e int iMaxColumns = -1; foreach (ListViewItem lvi in lvPlugins.Items) - { + { if (iMaxColumns < lvi.SubItems.Count) iMaxColumns = lvi.SubItems.Count; - } + } if (e.ColumnIndex + 1 != iMaxColumns) return; PluginUpdate upd = PluginUpdateHandler.Plugins.Find(x => x.Title == e.Item.SubItems[0].Text); if (upd == null) upd = PluginUpdateHandler.Plugins.Find(x => x.Title + "*" == e.Item.SubItems[0].Text); //* is used to indicate a rename @@ -886,34 +943,34 @@ private void DoUpdateKeePass(KeePass_Update kpu) //Start installation of update or open download folder (zip / portable) success &= kpu.Execute(); - + //Restart KeePass to use new plugin versions PluginDebug.AddInfo("KeePass update/download finished", "Succes: " + success.ToString(), DebugPrint); } private void bUpdatePlugins_Click(object sender, EventArgs e) { - KeePass_Update kpu = null; + KeePass_Update kpu = null; Button bUpdate = sender as Button; if (bUpdate != null && bUpdate.Tag is KeePass_Update) kpu = bUpdate.Tag as KeePass_Update; UpdatePlugins(UpdateFlags.All, kpu); } private void UpdatePlugins(UpdateFlags uf, KeePass_Update kpu) - { + { UpdatePlugins(uf, false, kpu); - } + } private void UpdatePlugins(UpdateFlags uf, bool bForceExternalPluginUpdatesDownload, KeePass_Update kpu) { if (kpu != null) DoUpdateKeePass(kpu); //Check whether anything needs to be done if (uf != UpdateFlags.ExternalUpdateInfo && PluginUpdateHandler.Plugins.FindAll(x => x.Selected).Count == 0) return; - + 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(); @@ -1036,7 +1093,7 @@ private void Restart() if (m_slUpdateCheck != null) { PluginDebug.AddInfo("Closing update check progress form", 0, DebugPrint); - m_slUpdateCheck.EndLogging(); + EndLogging(); } if (MonoWorkarounds.IsRequired(620618)) @@ -1109,11 +1166,11 @@ private void HandleMutex(bool release) lStrings.Add("Success: See next entry"); PluginDebug.AddInfo("Handle global mutex", 0, lStrings.ToArray()); Thread t = new Thread(new ThreadStart(() => - { - Thread.Sleep(PluginConfig.RestoreMutexThreshold); - bool bSuccess = GlobalMutexPool.CreateMutex(KeePass.App.AppDefs.MutexName, true); - PluginDebug.AddInfo("Handle global mutex", 0, "Recreate mutex sucessful: " + bSuccess.ToString()); - })); + { + Thread.Sleep(PluginConfig.RestoreMutexThreshold); + bool bSuccess = GlobalMutexPool.CreateMutex(KeePass.App.AppDefs.MutexName, true); + PluginDebug.AddInfo("Handle global mutex", 0, "Recreate mutex sucessful: " + bSuccess.ToString()); + })); t.IsBackground = true; t.Start(); return; @@ -1195,7 +1252,7 @@ private string DebugPrint get { string result = "DifferentThread: {0}, Check status: {1}, UI interaction blocked: {2}"; - lock(m_lock) + lock (m_lock) { result = string.Format(result, m_bRestartInvoke.ToString(), m_UpdateCheckStatus.ToString(), KeePass.Program.MainForm.UIIsInteractionBlocked().ToString()); } diff --git a/src/Properties/AssemblyInfo.cs b/src/Properties/AssemblyInfo.cs index ef8b8c4..8b38fa2 100644 --- a/src/Properties/AssemblyInfo.cs +++ b/src/Properties/AssemblyInfo.cs @@ -26,6 +26,6 @@ // // You can specify all the values or you can use the default the Revision and // Build Numbers by using the '*' as shown below: -[assembly: AssemblyVersion("4.1.2.0")] -[assembly: AssemblyFileVersion("4.1.2.0")] +[assembly: AssemblyVersion("4.1.3")] +[assembly: AssemblyFileVersion("4.1.3")] [assembly: Guid("672570AF-CC57-4980-86F9-D48FD1CC707D")] \ No newline at end of file diff --git a/src/Utilities/PluginTranslation.cs b/src/Utilities/PluginTranslation.cs index 3023584..5a42367 100644 --- a/src/Utilities/PluginTranslation.cs +++ b/src/Utilities/PluginTranslation.cs @@ -201,6 +201,16 @@ This question will not be asked again. - Setup: KeePass--Setup.exe is used to install KeePass - MSI: KeePass-.msi is used to install KeePass - Portable: KeePass-.zip is used to download and extract KeePass"; + /// + /// EarlyUpdateCheck detected available updates of plugins and/or KeePass. + /// + /// As option '{0}' is active, the update form cannot be displayed now. + /// It will be shown AFTER you close the '{1}' form. + /// + public static readonly string SecureDesktopMode = @"EarlyUpdateCheck detected available updates of plugins and/or KeePass. + +As option '{0}' is active, the update form cannot be displayed now. +It will be shown AFTER you close the '{1}' form."; #endregion #region NO changes in this area diff --git a/version.info b/version.info index bb3130c..7d95119 100644 --- a/version.info +++ b/version.info @@ -1,6 +1,6 @@ : -Early update check:4.1.2 -Early update check!de:7 +Early update check:4.1.3 +Early update check!de:9 Early update check!ru:2 Early update check!fr:1 Early update check!pt:3