diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/password.cpp | 47 | ||||
-rw-r--r-- | src/common/threadpool.cpp | 10 | ||||
-rw-r--r-- | src/common/util.cpp | 28 | ||||
-rw-r--r-- | src/common/util.h | 3 |
4 files changed, 76 insertions, 12 deletions
diff --git a/src/common/password.cpp b/src/common/password.cpp index b32bedae2..b3c51128f 100644 --- a/src/common/password.cpp +++ b/src/common/password.cpp @@ -56,43 +56,59 @@ namespace bool read_from_tty(epee::wipeable_string& pass, bool hide_input) { - static constexpr const char BACKSPACE = 8; - HANDLE h_cin = ::GetStdHandle(STD_INPUT_HANDLE); DWORD mode_old; ::GetConsoleMode(h_cin, &mode_old); - DWORD mode_new = mode_old & ~((hide_input ? ENABLE_ECHO_INPUT : 0) | ENABLE_LINE_INPUT); + DWORD mode_new = mode_old & ~(hide_input ? ENABLE_ECHO_INPUT : 0); ::SetConsoleMode(h_cin, mode_new); bool r = true; pass.reserve(tools::password_container::max_password_size); + std::vector<int> chlen; + chlen.reserve(tools::password_container::max_password_size); while (pass.size() < tools::password_container::max_password_size) { DWORD read; - char ch; - r = (TRUE == ::ReadConsoleA(h_cin, &ch, 1, &read, NULL)); + wchar_t ucs2_ch; + r = (TRUE == ::ReadConsoleW(h_cin, &ucs2_ch, 1, &read, NULL)); r &= (1 == read); + if (!r) { break; } - else if (ch == '\n' || ch == '\r') + else if (ucs2_ch == L'\r') + { + continue; + } + else if (ucs2_ch == L'\n') { std::cout << std::endl; break; } - else if (ch == BACKSPACE) + else if (ucs2_ch == L'\b') { if (!pass.empty()) { - pass.pop_back(); + int len = chlen.back(); + chlen.pop_back(); + while(len-- > 0) + pass.pop_back(); } + continue; } - else - { - pass.push_back(ch); - } + + char utf8_ch[8] = {0}; + int len; + if((len = WideCharToMultiByte(CP_UTF8, 0, &ucs2_ch, 1, utf8_ch, sizeof(utf8_ch), NULL, NULL)) <= 0) + break; + + if(pass.size() + len >= tools::password_container::max_password_size) + break; + + chlen.push_back(len); + pass += utf8_ch; } ::SetConsoleMode(h_cin, mode_old); @@ -146,6 +162,13 @@ namespace if (!aPass.empty()) { aPass.pop_back(); + if (!hide_input) + std::cout << "\b\b\b \b\b\b" << std::flush; + } + else + { + if (!hide_input) + std::cout << "\b\b \b\b" << std::flush; } } else diff --git a/src/common/threadpool.cpp b/src/common/threadpool.cpp index 5ea04a353..37825e31d 100644 --- a/src/common/threadpool.cpp +++ b/src/common/threadpool.cpp @@ -51,11 +51,19 @@ threadpool::threadpool(unsigned int max_threads) : running(true), active(0) { } threadpool::~threadpool() { + try { const boost::unique_lock<boost::mutex> lock(mutex); running = false; has_work.notify_all(); } + catch (...) + { + // if the lock throws, we're just do it without a lock and hope, + // since the alternative is terminate + running = false; + has_work.notify_all(); + } for (size_t i = 0; i<threads.size(); i++) { try { threads[i].join(); } catch (...) { /* ignore */ } @@ -91,11 +99,13 @@ unsigned int threadpool::get_max_concurrency() const { threadpool::waiter::~waiter() { + try { boost::unique_lock<boost::mutex> lock(mt); if (num) MERROR("wait should have been called before waiter dtor - waiting now"); } + catch (...) { /* ignore */ } try { wait(NULL); diff --git a/src/common/util.cpp b/src/common/util.cpp index c56c77505..2a1d49af0 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -939,4 +939,32 @@ std::string get_nix_version_display_string() } return newval; } + +#ifdef _WIN32 + std::string input_line_win() + { + HANDLE hConIn = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); + DWORD oldMode; + + FlushConsoleInputBuffer(hConIn); + GetConsoleMode(hConIn, &oldMode); + SetConsoleMode(hConIn, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT); + + wchar_t buffer[1024]; + DWORD read; + + ReadConsoleW(hConIn, buffer, sizeof(buffer)/sizeof(wchar_t)-1, &read, nullptr); + buffer[read] = 0; + + SetConsoleMode(hConIn, oldMode); + CloseHandle(hConIn); + + int size_needed = WideCharToMultiByte(CP_UTF8, 0, buffer, -1, NULL, 0, NULL, NULL); + std::string buf(size_needed, '\0'); + WideCharToMultiByte(CP_UTF8, 0, buffer, -1, &buf[0], size_needed, NULL, NULL); + buf.pop_back(); //size_needed includes null that we needed to have space for + return buf; + } +#endif + } diff --git a/src/common/util.h b/src/common/util.h index 0e0b50520..ce773bd38 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -235,4 +235,7 @@ namespace tools boost::optional<std::pair<uint32_t, uint32_t>> parse_subaddress_lookahead(const std::string& str); std::string glob_to_regex(const std::string &val); +#ifdef _WIN32 + std::string input_line_win(); +#endif } |