private void SecureDialogThread(object oParam) { try { SecureThreadParams stp = oParam as SecureThreadParams; if (stp == null) { Debug.Assert(false); return; } NativeMethods.SetThreadDesktop(stp.ThreadDesktop); BackgroundForm formBack = new BackgroundForm( stp.BackgroundBitmap); formBack.Show(); NativeMethods.SwitchDesktop(stp.ThreadDesktop); stp.Result = m_form.ShowDialog(formBack); formBack.Hide(); } catch (Exception) { Debug.Assert(false); } }
private void SecureDialogThread(object oParam) { SecureThreadInfo stp = (oParam as SecureThreadInfo); if (stp == null) { Debug.Assert(false); return; } List <BackgroundForm> lBackForms = new List <BackgroundForm>(); BackgroundForm formBackPrimary = null; // bool bLangBar = false; try { if (!NativeMethods.SetThreadDesktop(stp.ThreadDesktop)) { Debug.Assert(false); return; } ProcessMessagesEx(); // Test whether we're really on the secure desktop if (NativeMethods.GetThreadDesktop(NativeMethods.GetCurrentThreadId()) != stp.ThreadDesktop) { Debug.Assert(false); return; } // Disabling IME is not required anymore; we terminate // CtfMon.exe child processes manually // try { NativeMethods.ImmDisableIME(0); } // Always false on 2000/XP // catch(Exception) { Debug.Assert(!WinUtil.IsAtLeastWindows2000); } ProcessMessagesEx(); Screen[] vScreens = Screen.AllScreens; Screen scPrimary = Screen.PrimaryScreen; Debug.Assert(vScreens.Length == stp.BackgroundBitmaps.Count); int sMin = Math.Min(vScreens.Length, stp.BackgroundBitmaps.Count); for (int i = sMin - 1; i >= 0; --i) { Bitmap bmpBack = stp.BackgroundBitmaps[i]; if (bmpBack == null) { continue; } Debug.Assert(bmpBack.Size == vScreens[i].Bounds.Size); BackgroundForm formBack = new BackgroundForm(bmpBack, vScreens[i]); lBackForms.Add(formBack); if (vScreens[i].Equals(scPrimary)) { formBackPrimary = formBack; } formBack.Show(); } if (formBackPrimary == null) { Debug.Assert(false); if (lBackForms.Count > 0) { formBackPrimary = lBackForms[lBackForms.Count - 1]; } } ProcessMessagesEx(); if (!NativeMethods.SwitchDesktop(stp.ThreadDesktop)) { Debug.Assert(false); } ProcessMessagesEx(); Form f = m_fnConstruct(stp.FormConstructParam); if (f == null) { Debug.Assert(false); return; } if (Program.Config.UI.SecureDesktopPlaySound) { UIUtil.PlayUacSound(); } // bLangBar = ShowLangBar(true); lock (stp) { stp.State = SecureThreadState.ShowingDialog; } stp.DialogResult = f.ShowDialog(formBackPrimary); stp.ResultObject = m_fnResultBuilder(f); UIUtil.DestroyForm(f); } catch (Exception) { Debug.Assert(false); } finally { // if(bLangBar) ShowLangBar(false); foreach (BackgroundForm formBack in lBackForms) { try { formBack.Close(); UIUtil.DestroyForm(formBack); } catch (Exception) { Debug.Assert(false); } } lock (stp) { stp.State = SecureThreadState.Terminated; } } }
private void SecureDialogThread(object oParam) { BackgroundForm formBack = null; try { SecureThreadParams stp = (oParam as SecureThreadParams); if(stp == null) { Debug.Assert(false); return; } if(!NativeMethods.SetThreadDesktop(stp.ThreadDesktop)) { Debug.Assert(false); return; } ProcessMessagesEx(); // Test whether we're really on the secure desktop if(NativeMethods.GetThreadDesktop(NativeMethods.GetCurrentThreadId()) != stp.ThreadDesktop) { Debug.Assert(false); return; } // Creating a window on the new desktop spawns a CtfMon.exe child // process by default. On Windows Vista, this process is terminated // correctly when the desktop is closed. However, on Windows 7 it // isn't terminated (probably a bug); creating multiple desktops // accumulates CtfMon.exe child processes. In order to prevent this, // we simply disable IME for the new desktop thread (CtfMon.exe then // isn't loaded automatically). try { NativeMethods.ImmDisableIME(0); } // Always false on 2000/XP catch(Exception) { Debug.Assert(!WinUtil.IsAtLeastWindows2000); } ProcessMessagesEx(); formBack = new BackgroundForm(stp.BackgroundBitmap); formBack.Show(); ProcessMessagesEx(); if(!NativeMethods.SwitchDesktop(stp.ThreadDesktop)) { Debug.Assert(false); } ProcessMessagesEx(); Form f = m_fnConstruct(stp.FormConstructParam); if(f == null) { Debug.Assert(false); return; } if(Program.Config.UI.SecureDesktopPlaySound) UIUtil.PlayUacSound(); stp.DialogResult = f.ShowDialog(formBack); stp.ResultObject = m_fnResultBuilder(f); UIUtil.DestroyForm(f); } catch(Exception) { Debug.Assert(false); } finally { if(formBack != null) { try { formBack.Close(); UIUtil.DestroyForm(formBack); } catch(Exception) { Debug.Assert(false); } } } }
private void SecureDialogThread(object oParam) { try { SecureThreadParams stp = oParam as SecureThreadParams; if(stp == null) { Debug.Assert(false); return; } NativeMethods.SetThreadDesktop(stp.ThreadDesktop); BackgroundForm formBack = new BackgroundForm( stp.BackgroundBitmap); formBack.Show(); NativeMethods.SwitchDesktop(stp.ThreadDesktop); stp.Result = m_form.ShowDialog(formBack); formBack.Hide(); } catch(Exception) { Debug.Assert(false); } }
private void SecureDialogThread(object oParam) { BackgroundForm formBack = null; try { SecureThreadParams stp = (oParam as SecureThreadParams); if (stp == null) { Debug.Assert(false); return; } if (!NativeMethods.SetThreadDesktop(stp.ThreadDesktop)) { Debug.Assert(false); return; } ProcessMessagesEx(); // Test whether we're really on the secure desktop if (NativeMethods.GetThreadDesktop(NativeMethods.GetCurrentThreadId()) != stp.ThreadDesktop) { Debug.Assert(false); return; } // Creating a window on the new desktop spawns a CtfMon.exe child // process by default. On Windows Vista, this process is terminated // correctly when the desktop is closed. However, on Windows 7 it // isn't terminated (probably a bug); creating multiple desktops // accumulates CtfMon.exe child processes. In order to prevent this, // we simply disable IME for the new desktop thread (CtfMon.exe then // isn't loaded automatically). try { NativeMethods.ImmDisableIME(0); } // Always false on 2000/XP catch (Exception) { Debug.Assert(!WinUtil.IsAtLeastWindows2000); } ProcessMessagesEx(); formBack = new BackgroundForm(stp.BackgroundBitmap); formBack.Show(); ProcessMessagesEx(); if (!NativeMethods.SwitchDesktop(stp.ThreadDesktop)) { Debug.Assert(false); } ProcessMessagesEx(); Form f = m_fnConstruct(stp.FormConstructParam); if (f == null) { Debug.Assert(false); return; } if (Program.Config.UI.SecureDesktopPlaySound) { UIUtil.PlayUacSound(); } stp.DialogResult = f.ShowDialog(formBack); stp.ResultObject = m_fnResultBuilder(f); UIUtil.DestroyForm(f); } catch (Exception) { Debug.Assert(false); } finally { if (formBack != null) { try { formBack.Close(); UIUtil.DestroyForm(formBack); } catch (Exception) { Debug.Assert(false); } } } }
private void SecureDialogThread(object oParam) { BackgroundForm formBack = null; SecureThreadInfo stp = (oParam as SecureThreadInfo); if (stp == null) { Debug.Assert(false); return; } try { if (!NativeMethods.SetThreadDesktop(stp.ThreadDesktop)) { Debug.Assert(false); return; } ProcessMessagesEx(); // Test whether we're really on the secure desktop if (NativeMethods.GetThreadDesktop(NativeMethods.GetCurrentThreadId()) != stp.ThreadDesktop) { Debug.Assert(false); return; } // Disabling IME is not required anymore; we terminate // CtfMon.exe child processes manually // try { NativeMethods.ImmDisableIME(0); } // Always false on 2000/XP // catch(Exception) { Debug.Assert(!WinUtil.IsAtLeastWindows2000); } ProcessMessagesEx(); formBack = new BackgroundForm(stp.BackgroundBitmap); formBack.Show(); ProcessMessagesEx(); if (!NativeMethods.SwitchDesktop(stp.ThreadDesktop)) { Debug.Assert(false); } ProcessMessagesEx(); Form f = m_fnConstruct(stp.FormConstructParam); if (f == null) { Debug.Assert(false); return; } if (Program.Config.UI.SecureDesktopPlaySound) { UIUtil.PlayUacSound(); } lock (stp) { stp.State = SecureThreadState.ShowingDialog; } stp.DialogResult = f.ShowDialog(formBack); stp.ResultObject = m_fnResultBuilder(f); UIUtil.DestroyForm(f); } catch (Exception) { Debug.Assert(false); } finally { if (formBack != null) { try { formBack.Close(); UIUtil.DestroyForm(formBack); } catch (Exception) { Debug.Assert(false); } } lock (stp) { stp.State = SecureThreadState.Terminated; } } }
private void SecureDialogThread(object oParam) { SecureThreadInfo stp = (oParam as SecureThreadInfo); if(stp == null) { Debug.Assert(false); return; } List<BackgroundForm> lBackForms = new List<BackgroundForm>(); BackgroundForm formBackPrimary = null; // bool bLangBar = false; try { if(!NativeMethods.SetThreadDesktop(stp.ThreadDesktop)) { Debug.Assert(false); return; } ProcessMessagesEx(); // Test whether we're really on the secure desktop if(NativeMethods.GetThreadDesktop(NativeMethods.GetCurrentThreadId()) != stp.ThreadDesktop) { Debug.Assert(false); return; } // Disabling IME is not required anymore; we terminate // CtfMon.exe child processes manually // try { NativeMethods.ImmDisableIME(0); } // Always false on 2000/XP // catch(Exception) { Debug.Assert(!WinUtil.IsAtLeastWindows2000); } ProcessMessagesEx(); Screen[] vScreens = Screen.AllScreens; Screen scPrimary = Screen.PrimaryScreen; Debug.Assert(vScreens.Length == stp.BackgroundBitmaps.Count); int sMin = Math.Min(vScreens.Length, stp.BackgroundBitmaps.Count); for(int i = sMin - 1; i >= 0; --i) { Bitmap bmpBack = stp.BackgroundBitmaps[i]; if(bmpBack == null) continue; Debug.Assert(bmpBack.Size == vScreens[i].Bounds.Size); BackgroundForm formBack = new BackgroundForm(bmpBack, vScreens[i]); lBackForms.Add(formBack); if(vScreens[i].Equals(scPrimary)) formBackPrimary = formBack; formBack.Show(); } if(formBackPrimary == null) { Debug.Assert(false); if(lBackForms.Count > 0) formBackPrimary = lBackForms[lBackForms.Count - 1]; } ProcessMessagesEx(); if(!NativeMethods.SwitchDesktop(stp.ThreadDesktop)) { Debug.Assert(false); } ProcessMessagesEx(); Form f = m_fnConstruct(stp.FormConstructParam); if(f == null) { Debug.Assert(false); return; } if(Program.Config.UI.SecureDesktopPlaySound) UIUtil.PlayUacSound(); // bLangBar = ShowLangBar(true); lock(stp) { stp.State = SecureThreadState.ShowingDialog; } stp.DialogResult = f.ShowDialog(formBackPrimary); stp.ResultObject = m_fnResultBuilder(f); UIUtil.DestroyForm(f); } catch(Exception) { Debug.Assert(false); } finally { // if(bLangBar) ShowLangBar(false); foreach(BackgroundForm formBack in lBackForms) { try { formBack.Close(); UIUtil.DestroyForm(formBack); } catch(Exception) { Debug.Assert(false); } } lock(stp) { stp.State = SecureThreadState.Terminated; } } }
private void SecureDialogThread(object oParam) { SecureThreadInfo stp = (oParam as SecureThreadInfo); if (stp == null) { Debug.Assert(false); return; } List <BackgroundForm> lBackForms = new List <BackgroundForm>(); BackgroundForm formBackPrimary = null; // bool bLangBar = false; try { if (!NativeMethods.SetThreadDesktop(stp.ThreadDesktop)) { Debug.Assert(false); return; } ProcessMessagesEx(); // Test whether we're really on the secure desktop if (NativeMethods.GetThreadDesktop(NativeMethods.GetCurrentThreadId()) != stp.ThreadDesktop) { Debug.Assert(false); return; } // Disabling the IME was not required, because we terminate // CtfMon.exe child processes manually. However, since Sept. 2019, // there is an IME bug resulting in a black screen and/or an // IME/CTF process with high CPU load; // https://sourceforge.net/p/keepass/bugs/1881/ // https://keepass.info/help/kb/sec_desk.html#ime try { ulong uif = Program.Config.UI.UIFlags; if ((uif & (ulong)AceUIFlags.SecureDesktopIme) == 0) { NativeMethods.ImmDisableIME(0); // Always false on 2000/XP } } catch (Exception) { Debug.Assert(!WinUtil.IsAtLeastWindows2000); } ProcessMessagesEx(); Screen[] vScreens = Screen.AllScreens; Screen scPrimary = Screen.PrimaryScreen; Debug.Assert(vScreens.Length == stp.BackgroundBitmaps.Count); int sMin = Math.Min(vScreens.Length, stp.BackgroundBitmaps.Count); for (int i = sMin - 1; i >= 0; --i) { Bitmap bmpBack = stp.BackgroundBitmaps[i]; if (bmpBack == null) { continue; } Debug.Assert(bmpBack.Size == vScreens[i].Bounds.Size); BackgroundForm formBack = new BackgroundForm(bmpBack, vScreens[i]); lBackForms.Add(formBack); if (vScreens[i].Equals(scPrimary)) { formBackPrimary = formBack; } formBack.Show(); } if (formBackPrimary == null) { Debug.Assert(false); if (lBackForms.Count > 0) { formBackPrimary = lBackForms[lBackForms.Count - 1]; } } ProcessMessagesEx(); if (!NativeMethods.SwitchDesktop(stp.ThreadDesktop)) { Debug.Assert(false); } ProcessMessagesEx(); Form f = m_fnConstruct(stp.FormConstructParam); if (f == null) { Debug.Assert(false); return; } if (Program.Config.UI.SecureDesktopPlaySound) { UIUtil.PlayUacSound(); } // bLangBar = ShowLangBar(true); lock (stp) { stp.State = SecureThreadState.ShowingDialog; } stp.DialogResult = f.ShowDialog(formBackPrimary); stp.ResultObject = m_fnResultBuilder(f); UIUtil.DestroyForm(f); } catch (Exception) { Debug.Assert(false); } finally { // if(bLangBar) ShowLangBar(false); foreach (BackgroundForm formBack in lBackForms) { try { formBack.Close(); UIUtil.DestroyForm(formBack); } catch (Exception) { Debug.Assert(false); } } lock (stp) { stp.State = SecureThreadState.Terminated; } } }
private void SecureDialogThread(object oParam) { BackgroundForm formBack = null; // bool bLangBar = false; SecureThreadInfo stp = (oParam as SecureThreadInfo); if(stp == null) { Debug.Assert(false); return; } try { if(!NativeMethods.SetThreadDesktop(stp.ThreadDesktop)) { Debug.Assert(false); return; } ProcessMessagesEx(); // Test whether we're really on the secure desktop if(NativeMethods.GetThreadDesktop(NativeMethods.GetCurrentThreadId()) != stp.ThreadDesktop) { Debug.Assert(false); return; } // Disabling IME is not required anymore; we terminate // CtfMon.exe child processes manually // try { NativeMethods.ImmDisableIME(0); } // Always false on 2000/XP // catch(Exception) { Debug.Assert(!WinUtil.IsAtLeastWindows2000); } ProcessMessagesEx(); formBack = new BackgroundForm(stp.BackgroundBitmap); formBack.Show(); ProcessMessagesEx(); if(!NativeMethods.SwitchDesktop(stp.ThreadDesktop)) { Debug.Assert(false); } ProcessMessagesEx(); Form f = m_fnConstruct(stp.FormConstructParam); if(f == null) { Debug.Assert(false); return; } if(Program.Config.UI.SecureDesktopPlaySound) UIUtil.PlayUacSound(); // bLangBar = ShowLangBar(true); lock(stp) { stp.State = SecureThreadState.ShowingDialog; } stp.DialogResult = f.ShowDialog(formBack); stp.ResultObject = m_fnResultBuilder(f); UIUtil.DestroyForm(f); } catch(Exception) { Debug.Assert(false); } finally { // if(bLangBar) ShowLangBar(false); if(formBack != null) { try { formBack.Close(); UIUtil.DestroyForm(formBack); } catch(Exception) { Debug.Assert(false); } } lock(stp) { stp.State = SecureThreadState.Terminated; } } }