private void InitByProcessName(string strName) { if (g_vProcessNamesUni == null) { g_vProcessNamesUni = new string[] { "PuTTY", "KiTTY", "KiTTY_Portable", "KiTTY_NoTrans", "KiTTY_NoHyperlink", "KiTTY_NoCompress", "PuTTYjp", // "mRemoteNG", // No effect // "PuTTYNG", // No effect // SuperPuTTY spawns PuTTY processes whose windows are // displayed embedded in the SuperPuTTY window (without // window borders), thus the definition "PuTTY" also // fixes SuperPuTTY; no "SuperPuTTY" required // "SuperPuTTY", "MinTTY" // Cygwin window "~" } } ; foreach (string str in g_vProcessNamesUni) { if (ProcessNameMatches(strName, str)) { m_sm = SiSendMethod.UnicodePacket; return; } } if (g_vProcessNamesKeyRAlt == null) { g_vProcessNamesKeyRAlt = new string[] { "MSTSC", // Remote Desktop Connection client "VirtualBox", // Oracle VirtualBox <= 5 "VirtualBoxVM", // Oracle VirtualBox >= 6 "VpxClient", // VMware vSphere client // VMware Player; // https://sourceforge.net/p/keepass/discussion/329221/thread/c94e0f096e/ "VMware-VMX", "VMware-AuthD", "VMPlayer", "VMware-Unity-Helper", // VMware Remote Console; // https://sourceforge.net/p/keepass/bugs/1588/ "VMRC", // Dameware Mini Remote Control; // https://sourceforge.net/p/keepass/bugs/1874/ "DWRCC" } } ; foreach (string str in g_vProcessNamesKeyRAlt) { if (ProcessNameMatches(strName, str)) { m_sm = SiSendMethod.KeyEvent; m_bCharsRAltAsCtrlAlt = true; return; } } }
private bool TrySendCharByKeypresses(char ch, bool?bDown) { if (ch == char.MinValue) { Debug.Assert(false); return(false); } SiSendMethod sm = GetSendMethod(m_swiCurrent); if (sm == SiSendMethod.UnicodePacket) { return(false); } if (m_vForcedUniChars == null) { m_vForcedUniChars = new char[] { // All of the following diacritics are spacing / non-combining '\u005E', // Circumflex ^ '\u0060', // Grave accent '\u00A8', // Diaeresis '\u00AF', // Macron above, long '\u00B0', // Degree (e.g. for Czech) '\u00B4', // Acute accent '\u00B8', // Cedilla // E.g. for US-International; // https://sourceforge.net/p/keepass/discussion/329220/thread/5708e5ef/ '\u0022', // Quotation mark '\u0027', // Apostrophe '\u007E' // Tilde // Spacing Modifier Letters; see below // '\u02C7', // Caron (e.g. for Canadian Multilingual) // '\u02C9', // Macron above, modifier, short // '\u02CD', // Macron below, modifier, short // '\u02D8', // Breve // '\u02D9', // Dot above // '\u02DA', // Ring above // '\u02DB', // Ogonek // '\u02DC', // Small tilde // '\u02DD', // Double acute accent } } ; if (sm != SiSendMethod.KeyEvent) // If Unicode packets allowed { if (Array.IndexOf <char>(m_vForcedUniChars, ch) >= 0) { return(false); } // U+02B0 to U+02FF are Spacing Modifier Letters; // https://www.unicode.org/charts/PDF/U02B0.pdf // https://en.wikipedia.org/wiki/Spacing_Modifier_Letters if ((ch >= '\u02B0') && (ch <= '\u02FF')) { return(false); } } IntPtr hKL = m_swiCurrent.KeyboardLayout; ushort u = NativeMethods.VkKeyScan3(ch, hKL); if (u == 0xFFFFU) { return(false); } int vKey = (int)(u & 0xFFU); Keys kMod = Keys.None; int nMods = 0; if ((u & 0x100U) != 0U) { ++nMods; kMod |= Keys.Shift; } if ((u & 0x200U) != 0U) { ++nMods; kMod |= Keys.Control; } if ((u & 0x400U) != 0U) { ++nMods; kMod |= Keys.Alt; } if ((u & 0x800U) != 0U) { return(false); // Hankaku unsupported } // Do not send a key combination that is registered as hot key; // https://sourceforge.net/p/keepass/bugs/1235/ // Windows shortcut hot keys involve at least 2 modifiers if (nMods >= 2) { Keys kFull = (kMod | (Keys)vKey); if (HotKeyManager.IsHotKeyRegistered(kFull, true)) { return(false); } } bool bShift = ((kMod & Keys.Shift) != Keys.None); bool bCtrl = ((kMod & Keys.Control) != Keys.None); bool bAlt = ((kMod & Keys.Alt) != Keys.None); bool bCapsLock = false; // Windows' GetKeyboardState function does not return the // current virtual key array (especially not after changing // them below), thus we build the array on our own byte[] pbState = new byte[256]; if (bShift) { pbState[NativeMethods.VK_SHIFT] = 0x80; pbState[NativeMethods.VK_LSHIFT] = 0x80; } if (bCtrl && bAlt) // Use RAlt as Ctrl+Alt { pbState[NativeMethods.VK_CONTROL] = 0x80; pbState[NativeMethods.VK_MENU] = 0x80; pbState[NativeMethods.VK_RMENU] = 0x80; } else { if (bCtrl) { pbState[NativeMethods.VK_CONTROL] = 0x80; pbState[NativeMethods.VK_LCONTROL] = 0x80; } if (bAlt) { pbState[NativeMethods.VK_MENU] = 0x80; pbState[NativeMethods.VK_LMENU] = 0x80; } } pbState[NativeMethods.VK_NUMLOCK] = 0x01; // Toggled // The keypress that VkKeyScan returns may require a specific // state of toggle keys, on which it provides no information; // thus we now check whether the keypress will really result // in the character that we expect; // https://sourceforge.net/p/keepass/bugs/1594/ string strUni = NativeMethods.ToUnicode3(vKey, pbState, hKL); if ((strUni != null) && (strUni.Length == 0)) { } // Dead key else if (string.IsNullOrEmpty(strUni) || (strUni[strUni.Length - 1] != ch)) { // Among the keyboard layouts that were tested, the // Czech one was the only one where the translation // may fail (due to dependency on the Caps Lock state) Debug.Assert(NativeMethods.GetPrimaryLangID((ushort)(hKL.ToInt64() & 0xFFFFL)) == NativeMethods.LANG_CZECH); // Test whether Caps Lock is required pbState[NativeMethods.VK_CAPITAL] = 0x01; strUni = NativeMethods.ToUnicode3(vKey, pbState, hKL); if ((strUni != null) && (strUni.Length == 0)) { } // Dead key else if (string.IsNullOrEmpty(strUni) || (strUni[strUni.Length - 1] != ch)) { Debug.Assert(false); // An unknown key modifier is required return(false); } bCapsLock = true; } if (bCapsLock) { SendKeyImpl(NativeMethods.VK_CAPITAL, null, null); Thread.Sleep(1); Application.DoEvents(); } Keys kModDiff = (kMod & ~m_kModCur); if (kModDiff != Keys.None) { // Send RAlt for better AltGr compatibility; // https://sourceforge.net/p/keepass/bugs/1475/ SetKeyModifierImplEx(kModDiff, true, true); Thread.Sleep(1); Application.DoEvents(); } SendKeyImpl(vKey, null, bDown); if (kModDiff != Keys.None) { Thread.Sleep(1); Application.DoEvents(); SetKeyModifierImplEx(kModDiff, false, true); } if (bCapsLock) { Thread.Sleep(1); Application.DoEvents(); SendKeyImpl(NativeMethods.VK_CAPITAL, null, null); } return(true); }
private bool TrySendCharByKeypresses(char ch, bool?bDown, SiWindowInfo swi) { if (ch == char.MinValue) { Debug.Assert(false); return(false); } SiSendMethod sm = GetSendMethod(swi); if (sm == SiSendMethod.UnicodePacket) { return(false); } if (m_vForcedUniChars == null) { m_vForcedUniChars = new char[] { // All of the following diacritics are spacing / non-combining '\u00B4', // Acute accent '\u02DD', // Double acute accent '\u0060', // Grave accent '\u02D8', // Breve '\u00B8', // Cedilla '\u005E', // Circumflex ^ '\u00A8', // Diaeresis '\u02D9', // Dot above '\u00AF', // Macron above, long '\u02C9', // Macron above, modifier, short '\u02CD', // Macron below, modifier, short '\u02DB', // Ogonek // E.g. for US-International; // https://sourceforge.net/p/keepass/discussion/329220/thread/5708e5ef/ '\u0027', // Apostrophe '\u0022', // Quotation mark '\u007E' // Tilde } } ; if (sm != SiSendMethod.KeyEvent) // If Unicode packets allowed { if (Array.IndexOf <char>(m_vForcedUniChars, ch) >= 0) { return(false); } } IntPtr hKL = swi.KeyboardLayout; ushort u = ((hKL == IntPtr.Zero) ? NativeMethods.VkKeyScan(ch) : NativeMethods.VkKeyScanEx(ch, hKL)); if (u == 0xFFFFU) { return(false); } int vKey = (int)(u & 0xFFU); Keys kMod = Keys.None; int nMods = 0; if ((u & 0x100U) != 0U) { ++nMods; kMod |= Keys.Shift; } if ((u & 0x200U) != 0U) { ++nMods; kMod |= Keys.Control; } if ((u & 0x400U) != 0U) { ++nMods; kMod |= Keys.Alt; } if ((u & 0x800U) != 0U) { return(false); // Hankaku unsupported } // Do not send a key combination that is registered as hot key; // https://sourceforge.net/p/keepass/bugs/1235/ // Windows shortcut hot keys involve at least 2 modifiers if (nMods >= 2) { Keys kFull = (kMod | (Keys)vKey); if (HotKeyManager.IsHotKeyRegistered(kFull, true)) { return(false); } } Keys kModDiff = (kMod & ~m_kModCur); if (kModDiff != Keys.None) { // Send RAlt for better AltGr compatibility; // https://sourceforge.net/p/keepass/bugs/1475/ SetKeyModifierImplEx(kModDiff, true, true); Thread.Sleep(1); Application.DoEvents(); } SendKeyImpl(vKey, null, bDown); if (kModDiff != Keys.None) { Thread.Sleep(1); Application.DoEvents(); SetKeyModifierImplEx(kModDiff, false, true); } return(true); }