/* * DoSendString - actually sends a string to the X Window having input focus * * The main task of this function is to convert the ascii char values * into X KeyCodes. But they need to be converted to X KeySyms first * and then to the keycodes. The KeyCodes can have any random values * and are not contiguous like the ascii values are. * * Some escape sequences can be converted to the appropriate KeyCodes * by this function. See the code below for details */ void CKeySendImpl::DoSendString(const StringX& str, unsigned delayMS, bool emulateMods) { atGlobals.error_detected = false; atGlobals.errorString[0] = 0; AutotypeEvent event(m_display); // convert all the chars into keycodes and required shift states first // Abort if any of the characters cannot be converted typedef std::vector<KeyPressInfo> KeyPressInfoVector; KeyPressInfoVector keypresses; for (StringX::const_iterator srcIter = str.begin(); srcIter != str.end(); ++srcIter) { //throw away 'vertical tab' chars which are only used on Windows to send a shift+tab //as a workaround for some issues with IE if (*srcIter == _T('\v')) continue; //Try a regular conversion first KeySym sym = wchar2keysym(*srcIter); if (NoSymbol != sym) { KeyPressInfo keypress = {0, 0}; if ((keypress.code = XKeysymToKeycode(event.display, sym)) != 0) { //non-zero return value implies sym -> code was successful keypress.state |= CalcModifiersForKeysym(keypress.code, sym, event.display); keypresses.push_back(keypress); } else { const char* symStr = XKeysymToString(sym); snprintf(atGlobals.errorString, NumberOf(atGlobals.errorString), "Could not get keycode for key char(%s) - sym(%#X) - str(%s). Aborting autotype.\n\nIf \'xmodmap -pk\' does not list this KeySym, you probably need to install an appropriate keyboard layout.", wchar2bytes(*srcIter).str(), static_cast<int>(sym), symStr ? symStr : "NULL"); atGlobals.error_detected = True; return; } } else { snprintf(atGlobals.errorString, NumberOf(atGlobals.errorString), "Cannot convert '%s' [U+%04X] to keysym. Aborting autotype", wchar2bytes(*srcIter).str(), int(*srcIter)); atGlobals.error_detected = True; return; } } m_method->EmulateMods(emulateMods); for (KeyPressInfoVector::const_iterator itr = keypresses.begin(); itr != keypresses.end() && !atGlobals.error_detected; ++itr) { event.keycode = itr->code; event.state = itr->state; event.time = CurrentTime; (*m_method)(event); pws_os::sleep_ms(delayMS); } }
StringX CPasswordCharPool::MakePassword() const { // We don't care if the policy is inconsistent e.g. // number of lower case chars > 1 + make pronounceable // The individual routines (normal, hex, pronounceable) will // ignore what they don't need. // Saves an awful amount of bother with setting values to zero and // back as the user changes their minds! ASSERT(m_pwlen > 0); ASSERT(m_uselowercase || m_useuppercase || m_usedigits || m_usesymbols || m_usehexdigits || m_pronounceable); // pronounceable and hex passwords are handled separately: if (m_pronounceable) return MakePronounceable(); if (m_usehexdigits) return MakeHex(); vector<typeFreq_s> typeFreqs; if (m_uselowercase) typeFreqs.push_back(typeFreq_s(this, LOWERCASE, m_numlowercase)); if (m_useuppercase) typeFreqs.push_back(typeFreq_s(this, UPPERCASE, m_numuppercase)); if (m_usedigits) typeFreqs.push_back(typeFreq_s(this, DIGIT, m_numdigits)); if (m_usesymbols) typeFreqs.push_back(typeFreq_s(this, SYMBOL, m_numsymbols)); // Sort requested char type in decreasing order // of requested (at least) frequency: sort(typeFreqs.begin(), typeFreqs.end(), [](const typeFreq_s &a, const typeFreq_s &b) { return a.numchars > b.numchars; }); StringX temp; // First meet the 'at least' constraints for (auto iter = typeFreqs.begin(); iter != typeFreqs.end(); iter++) for (uint j = 0; j < iter->numchars; j++) { if (!iter->vchars.empty()) { temp.push_back(iter->vchars.back()); iter->vchars.pop_back(); if (temp.length() == m_pwlen) goto do_shuffle; // break out of two loops, goto needed } } // Now fill in the rest while (temp.length() != m_pwlen) { uint i = PWSrand::GetInstance()->RangeRand(typeFreqs.size()); if (!typeFreqs[i].vchars.empty()) { temp.push_back(typeFreqs[i].vchars.back()); typeFreqs[i].vchars.pop_back(); if (temp.length() == m_pwlen) goto do_shuffle; // break out of two loops, goto needed } } do_shuffle: // If 'at least' values were non-zero, we have some unwanted order, // se we mix things up a bit: RandomWrapper rnw; random_shuffle(temp.begin(), temp.end(), rnw); ASSERT(temp.length() == size_t(m_pwlen)); return temp; }
void CKeySend::SendString(const StringX &data) { for (StringX::const_iterator iter = data.begin(); iter != data.end(); iter++) m_impl->SendChar(*iter); }