Internal
Public Access
Fix RDP connect crash on Windows: initialize FreeRDP signal handling
Every reference FreeRDP client (X11, Windows, macOS, SDL, Wayland, Android) calls freerdp_handle_signals() once at startup before connecting. OrbitHub never did. On Windows this is the only place that initializes a global CRITICAL_SECTION used internally by freerdp_add_signal_cleanup_handler(), which freerdp_connect() calls automatically. Skipping it leaves that lock zero-initialized -- invalid on Windows, but silently tolerated on POSIX, which is why this never surfaced in Linux testing. The result was a crash (access violation inside EnterCriticalSection) on every RDP connect attempt on Windows. Call it once, guarded, before the first connection. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <mutex>
|
||||
#include <new>
|
||||
#include <utility>
|
||||
|
||||
@@ -31,12 +32,32 @@
|
||||
#include <freerdp/locale/keyboard.h>
|
||||
#include <freerdp/scancode.h>
|
||||
#include <freerdp/settings.h>
|
||||
#include <freerdp/utils/signal.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/user.h>
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
#ifdef ORBITHUB_HAS_FREERDP
|
||||
// Every reference FreeRDP client (X11, Windows, macOS, SDL, Wayland,
|
||||
// Android) calls this once at startup before connecting. On Windows it's
|
||||
// the only place that initializes a global CRITICAL_SECTION used by
|
||||
// freerdp_add_signal_cleanup_handler(); skipping it leaves that lock
|
||||
// zero-initialized (invalid on Windows, tolerated on POSIX), so the first
|
||||
// freerdp_connect() crashes with a null-pointer dereference inside
|
||||
// EnterCriticalSection. Guarded so it only ever runs once.
|
||||
void ensureFreeRdpSignalHandlersInitialized()
|
||||
{
|
||||
static std::once_flag onceFlag;
|
||||
std::call_once(onceFlag, []() {
|
||||
const int rc = freerdp_handle_signals();
|
||||
Q_UNUSED(rc);
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
constexpr int kDefaultDesktopWidth = 1280;
|
||||
constexpr int kDefaultDesktopHeight = 720;
|
||||
constexpr int kMinDesktopWidth = 640;
|
||||
@@ -1472,6 +1493,8 @@ void RdpSessionBackend::workerMain()
|
||||
m_workerRunning.store(false);
|
||||
return;
|
||||
#else
|
||||
ensureFreeRdpSignalHandlersInitialized();
|
||||
|
||||
freerdp* instance = freerdp_new();
|
||||
if (instance == nullptr) {
|
||||
emitConnectionFailureAsync(QStringLiteral("Failed to initialize FreeRDP runtime."),
|
||||
|
||||
Reference in New Issue
Block a user