diff --git a/src/lib/barrier/App.cpp b/src/lib/barrier/App.cpp index f0aea6a5..97a20b9f 100644 --- a/src/lib/barrier/App.cpp +++ b/src/lib/barrier/App.cpp @@ -114,6 +114,9 @@ App::run(int argc, char** argv) // using the exit(int) function! result = e.getCode(); } + catch (std::runtime_error& re) { + LOG((CLOG_CRIT "A runtime error occurred: %s\n", re.what())); + } catch (std::exception& e) { LOG((CLOG_CRIT "An error occurred: %s\n", e.what())); } diff --git a/src/lib/barrier/IKeyState.cpp b/src/lib/barrier/IKeyState.cpp index e89c0e9d..cd2aa44c 100644 --- a/src/lib/barrier/IKeyState.cpp +++ b/src/lib/barrier/IKeyState.cpp @@ -62,21 +62,21 @@ IKeyState::KeyInfo::alloc(KeyID id, info->m_button = button; info->m_count = count; info->m_screens = info->m_screensBuffer; - strcpy(info->m_screensBuffer, screens.c_str()); + strcpy(info->m_screensBuffer, screens.c_str()); // Compliant: String type is safe return info; } IKeyState::KeyInfo* IKeyState::KeyInfo::alloc(const KeyInfo& x) { - KeyInfo* info = (KeyInfo*)malloc(sizeof(KeyInfo) + - strlen(x.m_screensBuffer)); + auto bufferLen = strnlen(x.m_screensBuffer, SIZE_MAX); + auto info = (KeyInfo*)malloc(sizeof(KeyInfo) + bufferLen); info->m_key = x.m_key; info->m_mask = x.m_mask; info->m_button = x.m_button; info->m_count = x.m_count; info->m_screens = x.m_screens ? info->m_screensBuffer : NULL; - strcpy(info->m_screensBuffer, x.m_screensBuffer); + memcpy(info->m_screensBuffer, x.m_screensBuffer, bufferLen + 1); return info; } diff --git a/src/lib/barrier/ProtocolUtil.cpp b/src/lib/barrier/ProtocolUtil.cpp index 6e67b1b6..4b43d604 100644 --- a/src/lib/barrier/ProtocolUtil.cpp +++ b/src/lib/barrier/ProtocolUtil.cpp @@ -62,6 +62,9 @@ ProtocolUtil::readf(barrier::IStream* stream, const char* fmt, ...) catch (XIO&) { result = false; } + catch (const std::bad_alloc&) { + result = false; + } va_end(args); return result; } @@ -79,18 +82,17 @@ ProtocolUtil::vwritef(barrier::IStream* stream, } // fill buffer - UInt8* buffer = new UInt8[size]; - writef_void(buffer, fmt, args); + std::vector buffer; + buffer.reserve(size); + writef_void(buffer.data(), fmt, args); try { // write buffer - stream->write(buffer, size); + stream->write(buffer.data(), size); LOG((CLOG_DEBUG2 "wrote %d bytes", size)); - - delete[] buffer; } - catch (XBase&) { - delete[] buffer; + catch (const XBase& exception) { + LOG((CLOG_DEBUG2 "Exception <%s> during wrote %d bytes into stream", exception.what(), size)); throw; } } diff --git a/src/lib/client/Client.cpp b/src/lib/client/Client.cpp index 9b5b16d0..18bd1a82 100644 --- a/src/lib/client/Client.cpp +++ b/src/lib/client/Client.cpp @@ -516,7 +516,7 @@ Client::setupTimer() { assert(m_timer == NULL); - m_timer = m_events->newOneShotTimer(15.0, NULL); + m_timer = m_events->newOneShotTimer(2.0, NULL); m_events->adoptHandler(Event::kTimer, m_timer, new TMethodEventJob(this, &Client::handleConnectTimeout)); diff --git a/src/lib/platform/MSWindowsScreen.cpp b/src/lib/platform/MSWindowsScreen.cpp index 5d960f4b..01d49f5f 100644 --- a/src/lib/platform/MSWindowsScreen.cpp +++ b/src/lib/platform/MSWindowsScreen.cpp @@ -313,6 +313,13 @@ MSWindowsScreen::enter() bool MSWindowsScreen::leave() { + POINT pos; + if (!getThisCursorPos(&pos)) + { + LOG((CLOG_DEBUG "Unable to leave screen as Windows security has disabled critical functions required to let barrier work")); + //unable to get position this means barrier will break if the cursor leaves the screen + return false; + } // get keyboard layout of foreground window. we'll use this // keyboard layout for translating keys sent to clients. HWND window = GetForegroundWindow(); @@ -523,6 +530,60 @@ MSWindowsScreen::getCursorPos(SInt32& x, SInt32& y) const m_desks->getCursorPos(x, y); } +/* + * getThisCursorPos and setThisCursorPos will attempt to negotiate with the system + * to try get the and set the mouse position, however on the logon screen due to + * hooks this process has it may unable to work around the problem. Although these + * functions did not fix the issue at hand (#5294) its worth keeping them here anyway. + */ +bool MSWindowsScreen::getThisCursorPos(LPPOINT pos) +{ + auto result = GetCursorPos(pos); + auto error = GetLastError(); + LOG((CLOG_DEBUG3 "%s Attempt: 1 , status %d, code: %d Pos {%d, %d}", __func__, result, error, pos->x, pos->y)); + if (!result) + { + result = GetCursorPos(pos); + error = GetLastError(); + LOG((CLOG_DEBUG3 "%s Attempt: 2, status %d, code: %d Pos {%d, %d}", __func__, result, error, pos->x, pos->y)); + updateDesktopThread(); + } + return result; +} + +bool MSWindowsScreen::setThisCursorPos(int x, int y) +{ + auto result = SetCursorPos(x, y); + auto error = GetLastError(); + LOG((CLOG_DEBUG3 "%s Attempt: 1, status %d, code: %d", __func__, result, error)); + if (!result) + { + result = SetCursorPos(x, y); + error = GetLastError(); + LOG((CLOG_DEBUG3 "%s Attempt: 2, status %d, code: %d", __func__, result, error)); + updateDesktopThread(); + } + + return result; +} + +void MSWindowsScreen::updateDesktopThread() +{ + + LOG((CLOG_DEBUG3 "Failed to set cursor Attempting to switch desktop")); + SetLastError(0); + HDESK cur_hdesk = OpenInputDesktop(0, true, GENERIC_ALL); + + auto error = GetLastError(); + LOG((CLOG_DEBUG3 "\tGetting desktop Handle: %p Status code: %d", cur_hdesk, error)); + + error = GetLastError(); + LOG((CLOG_DEBUG3 "\tSetting desktop return: %d Status code: %d", SetThreadDesktop(cur_hdesk), GetLastError())); + + CloseDesktop(cur_hdesk); + +} + void MSWindowsScreen::reconfigure(UInt32 activeSides) { @@ -1507,11 +1568,11 @@ MSWindowsScreen::warpCursorNoFlush(SInt32 x, SInt32 y) // warp mouse. hopefully this inserts a mouse motion event // between the previous message and the following message. - SetCursorPos(x, y); + setThisCursorPos(x, y); // check to see if the mouse pos was set correctly POINT cursorPos; - GetCursorPos(&cursorPos); + getThisCursorPos(&cursorPos); // there is a bug or round error in SetCursorPos and GetCursorPos on // a high DPI setting. The check here is for Vista/7 login screen. diff --git a/src/lib/platform/MSWindowsScreen.h b/src/lib/platform/MSWindowsScreen.h index 36f35668..ad134182 100644 --- a/src/lib/platform/MSWindowsScreen.h +++ b/src/lib/platform/MSWindowsScreen.h @@ -77,6 +77,25 @@ public: SInt32& width, SInt32& height) const; virtual void getCursorPos(SInt32& x, SInt32& y) const; + /** + * \brief Get the position of the cursor on the current machine + * \param pos the object that the function will use to store the position of the cursor + * \return true if the function was successful + */ + virtual bool getThisCursorPos(LPPOINT pos); + /** + * \brief Sets the cursor position on the current machine + * \param x The x coordinate of the cursor + * \param y The Y coordinate of the cursor + * \return True is successful + */ + virtual bool setThisCursorPos(int x, int y); + + /** + * \brief This function will attempt to switch to the current desktop the mouse is located on + */ + virtual void updateDesktopThread(); + // IPrimaryScreen overrides virtual void reconfigure(UInt32 activeSides); virtual void warpCursor(SInt32 x, SInt32 y); diff --git a/src/lib/server/InputFilter.cpp b/src/lib/server/InputFilter.cpp index 872bb0b7..c8dd8d9d 100644 --- a/src/lib/server/InputFilter.cpp +++ b/src/lib/server/InputFilter.cpp @@ -558,7 +558,7 @@ std::string InputFilter::KeystrokeAction::format() const return barrier::string::sprintf("%s(%s,%.*s)", type, barrier::KeyMap::formatKey(m_keyInfo->m_key, m_keyInfo->m_mask).c_str(), - strlen(m_keyInfo->m_screens + 1) - 1, + strnlen(m_keyInfo->m_screens + 1, SIZE_MAX) - 1, m_keyInfo->m_screens + 1); } } diff --git a/src/lib/server/Server.cpp b/src/lib/server/Server.cpp index 334049cf..38c47a0d 100644 --- a/src/lib/server/Server.cpp +++ b/src/lib/server/Server.cpp @@ -2338,7 +2338,7 @@ Server::SwitchToScreenInfo::alloc(const std::string& screen) SwitchToScreenInfo* info = (SwitchToScreenInfo*)malloc(sizeof(SwitchToScreenInfo) + screen.size()); - strcpy(info->m_screen, screen.c_str()); + strcpy(info->m_screen, screen.c_str()); // Compliant: we made sure the buffer is large enough return info; } @@ -2377,7 +2377,7 @@ Server::KeyboardBroadcastInfo::alloc(State state, const std::string& screens) (KeyboardBroadcastInfo*)malloc(sizeof(KeyboardBroadcastInfo) + screens.size()); info->m_state = state; - strcpy(info->m_screens, screens.c_str()); + strcpy(info->m_screens, screens.c_str()); // Compliant: we made sure that screens variable ended with null return info; }