Merge pull request #10617 from akallabeth/sdl-scope-guard
Sdl scope guard
This commit is contained in:
commit
33a7bee4f9
@ -119,6 +119,7 @@ BOOL sdl_authenticate_ex(freerdp* instance, char** username, char** password, ch
|
||||
size_t titlesize = 0;
|
||||
winpr_asprintf(&title, &titlesize, "Credentials required for %s", target);
|
||||
|
||||
std::unique_ptr<char, decltype(&free)> scope(title, free);
|
||||
char* u = nullptr;
|
||||
char* d = nullptr;
|
||||
char* p = nullptr;
|
||||
@ -132,26 +133,22 @@ BOOL sdl_authenticate_ex(freerdp* instance, char** username, char** password, ch
|
||||
p = *password;
|
||||
|
||||
if (!sdl_push_user_event(SDL_USEREVENT_AUTH_DIALOG, title, u, d, p, reason))
|
||||
goto fail;
|
||||
return res;
|
||||
|
||||
if (!sdl_wait_for_result(instance->context, SDL_USEREVENT_AUTH_RESULT, &event))
|
||||
goto fail;
|
||||
else
|
||||
{
|
||||
auto arg = reinterpret_cast<SDL_UserAuthArg*>(event.padding);
|
||||
return res;
|
||||
|
||||
res = arg->result > 0 ? TRUE : FALSE;
|
||||
auto arg = reinterpret_cast<SDL_UserAuthArg*>(event.padding);
|
||||
|
||||
free(*username);
|
||||
free(*domain);
|
||||
free(*password);
|
||||
*username = arg->user;
|
||||
*domain = arg->domain;
|
||||
*password = arg->password;
|
||||
}
|
||||
res = arg->result > 0 ? TRUE : FALSE;
|
||||
|
||||
free(*username);
|
||||
free(*domain);
|
||||
free(*password);
|
||||
*username = arg->user;
|
||||
*domain = arg->domain;
|
||||
*password = arg->password;
|
||||
|
||||
fail:
|
||||
free(title);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -195,15 +192,14 @@ BOOL sdl_choose_smartcard(freerdp* instance, SmartcardCertInfo** cert_list, DWOR
|
||||
if (gateway)
|
||||
title = "Select a gateway logon smartcard certificate";
|
||||
if (!sdl_push_user_event(SDL_USEREVENT_SCARD_DIALOG, title, list.data(), count))
|
||||
goto fail;
|
||||
return res;
|
||||
|
||||
if (!sdl_wait_for_result(instance->context, SDL_USEREVENT_SCARD_RESULT, &event))
|
||||
goto fail;
|
||||
return res;
|
||||
|
||||
res = (event.user.code >= 0) ? TRUE : FALSE;
|
||||
*choice = static_cast<DWORD>(event.user.code);
|
||||
|
||||
fail:
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,7 @@
|
||||
#include "sdl_pointer.hpp"
|
||||
#include "sdl_prefs.hpp"
|
||||
#include "dialogs/sdl_dialogs.hpp"
|
||||
#include "scoped_guard.hpp"
|
||||
|
||||
#include <aad/sdl_webview.hpp>
|
||||
|
||||
@ -703,7 +704,6 @@ static BOOL sdl_create_windows(SdlContext* sdl)
|
||||
|
||||
auto settings = sdl->context()->settings;
|
||||
auto title = sdl_window_get_title(settings);
|
||||
BOOL rc = FALSE;
|
||||
|
||||
UINT32 windowCount = freerdp_settings_get_uint32(settings, FreeRDP_MonitorCount);
|
||||
|
||||
@ -755,8 +755,11 @@ static BOOL sdl_create_windows(SdlContext* sdl)
|
||||
static_cast<int>(w),
|
||||
static_cast<int>(h),
|
||||
flags };
|
||||
|
||||
ScopeGuard guard([&]() { sdl->windows_created.set(); });
|
||||
|
||||
if (!window.window())
|
||||
goto fail;
|
||||
return FALSE;
|
||||
|
||||
if (freerdp_settings_get_bool(settings, FreeRDP_UseMultimon))
|
||||
{
|
||||
@ -768,11 +771,7 @@ static BOOL sdl_create_windows(SdlContext* sdl)
|
||||
sdl->windows.insert({ window.id(), std::move(window) });
|
||||
}
|
||||
|
||||
rc = TRUE;
|
||||
fail:
|
||||
|
||||
sdl->windows_created.set();
|
||||
return rc;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL sdl_wait_create_windows(SdlContext* sdl)
|
||||
@ -1168,19 +1167,56 @@ static void sdl_post_final_disconnect(freerdp* instance)
|
||||
return;
|
||||
}
|
||||
|
||||
/* RDP main loop.
|
||||
* Connects RDP, loops while running and handles event and dispatch, cleans up
|
||||
* after the connection ends. */
|
||||
static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
static void sdl_client_cleanup(SdlContext* sdl, int exit_code, const std::string& error_msg)
|
||||
{
|
||||
DWORD nCount = 0;
|
||||
DWORD status = 0;
|
||||
int exit_code = SDL_EXIT_SUCCESS;
|
||||
char* error_msg = nullptr;
|
||||
size_t error_msg_len = 0;
|
||||
WINPR_ASSERT(sdl);
|
||||
|
||||
HANDLE handles[MAXIMUM_WAIT_OBJECTS] = {};
|
||||
rdpContext* context = sdl->context();
|
||||
WINPR_ASSERT(context);
|
||||
|
||||
rdpSettings* settings = context->settings;
|
||||
WINPR_ASSERT(settings);
|
||||
|
||||
sdl->rdp_thread_running = false;
|
||||
bool showError = false;
|
||||
if (freerdp_settings_get_bool(settings, FreeRDP_AuthenticationOnly))
|
||||
WLog_Print(sdl->log, WLOG_INFO, "Authentication only, exit status %s [%" PRId32 "]",
|
||||
sdl_map_to_code_tag(exit_code), exit_code);
|
||||
else
|
||||
{
|
||||
switch (exit_code)
|
||||
{
|
||||
case SDL_EXIT_SUCCESS:
|
||||
case SDL_EXIT_DISCONNECT:
|
||||
case SDL_EXIT_LOGOFF:
|
||||
case SDL_EXIT_DISCONNECT_BY_USER:
|
||||
case SDL_EXIT_CONNECT_CANCELLED:
|
||||
break;
|
||||
default:
|
||||
{
|
||||
std::lock_guard<CriticalSection> lock(sdl->critical);
|
||||
if (sdl->connection_dialog && !error_msg.empty())
|
||||
{
|
||||
sdl->connection_dialog->showError(error_msg.c_str());
|
||||
showError = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!showError)
|
||||
sdl_hide_connection_dialog(sdl);
|
||||
|
||||
sdl->exit_code = exit_code;
|
||||
sdl_push_user_event(SDL_USEREVENT_QUIT);
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 16)
|
||||
SDL_TLSCleanup();
|
||||
#endif
|
||||
}
|
||||
|
||||
static int sdl_client_thread_connect(SdlContext* sdl, std::string& error_msg)
|
||||
{
|
||||
WINPR_ASSERT(sdl);
|
||||
|
||||
auto instance = sdl->context()->instance;
|
||||
@ -1190,9 +1226,12 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
BOOL rc = freerdp_connect(instance);
|
||||
|
||||
rdpContext* context = sdl->context();
|
||||
WINPR_ASSERT(context);
|
||||
|
||||
rdpSettings* settings = context->settings;
|
||||
WINPR_ASSERT(settings);
|
||||
|
||||
int exit_code = SDL_EXIT_SUCCESS;
|
||||
if (!rc)
|
||||
{
|
||||
UINT32 error = freerdp_get_last_error(context);
|
||||
@ -1205,21 +1244,33 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
freerdp_abort_connect_context(context);
|
||||
WLog_Print(sdl->log, WLOG_ERROR, "Authentication only, %s [0x%08" PRIx32 "] %s",
|
||||
freerdp_get_last_error_name(code), code, freerdp_get_last_error_string(code));
|
||||
goto terminate;
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
if (!rc)
|
||||
{
|
||||
DWORD code = freerdp_error_info(instance);
|
||||
if (exit_code == SDL_EXIT_SUCCESS)
|
||||
exit_code = error_info_to_error(instance, &code, &error_msg, &error_msg_len);
|
||||
{
|
||||
char* msg = nullptr;
|
||||
size_t len = 0;
|
||||
exit_code = error_info_to_error(instance, &code, &msg, &len);
|
||||
if (msg)
|
||||
error_msg = msg;
|
||||
free(msg);
|
||||
}
|
||||
|
||||
auto last = freerdp_get_last_error(context);
|
||||
if (!error_msg)
|
||||
if (error_msg.empty())
|
||||
{
|
||||
winpr_asprintf(&error_msg, &error_msg_len, "%s [0x%08" PRIx32 "]\n%s",
|
||||
char* msg = nullptr;
|
||||
size_t len = 0;
|
||||
winpr_asprintf(&msg, &len, "%s [0x%08" PRIx32 "]\n%s",
|
||||
freerdp_get_last_error_name(last), last,
|
||||
freerdp_get_last_error_string(last));
|
||||
if (msg)
|
||||
error_msg = msg;
|
||||
free(msg);
|
||||
}
|
||||
|
||||
if (exit_code == SDL_EXIT_SUCCESS)
|
||||
@ -1231,11 +1282,24 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
}
|
||||
|
||||
sdl_hide_connection_dialog(sdl);
|
||||
goto terminate;
|
||||
}
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
static int sdl_client_thread_run(SdlContext* sdl, std::string& error_msg)
|
||||
{
|
||||
WINPR_ASSERT(sdl);
|
||||
|
||||
auto context = sdl->context();
|
||||
WINPR_ASSERT(context);
|
||||
|
||||
auto instance = context->instance;
|
||||
WINPR_ASSERT(instance);
|
||||
|
||||
int exit_code = SDL_EXIT_SUCCESS;
|
||||
while (!freerdp_shall_disconnect_context(context))
|
||||
{
|
||||
HANDLE handles[MAXIMUM_WAIT_OBJECTS] = {};
|
||||
/*
|
||||
* win8 and server 2k12 seem to have some timing issue/race condition
|
||||
* when a initial sync request is send to sync the keyboard indicators
|
||||
@ -1251,7 +1315,7 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
break;
|
||||
}
|
||||
|
||||
nCount = freerdp_get_event_handles(context, handles, ARRAYSIZE(handles));
|
||||
const DWORD nCount = freerdp_get_event_handles(context, handles, ARRAYSIZE(handles));
|
||||
|
||||
if (nCount == 0)
|
||||
{
|
||||
@ -1259,7 +1323,7 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
break;
|
||||
}
|
||||
|
||||
status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE);
|
||||
const DWORD status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE);
|
||||
|
||||
if (status == WAIT_FAILED)
|
||||
break;
|
||||
@ -1294,18 +1358,26 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
if (exit_code == SDL_EXIT_SUCCESS)
|
||||
{
|
||||
DWORD code = 0;
|
||||
exit_code = error_info_to_error(instance, &code, &error_msg, &error_msg_len);
|
||||
{
|
||||
char* msg = nullptr;
|
||||
size_t len = 0;
|
||||
exit_code = error_info_to_error(instance, &code, &msg, &len);
|
||||
if (msg)
|
||||
error_msg = msg;
|
||||
free(msg);
|
||||
}
|
||||
|
||||
if ((code == ERRINFO_LOGOFF_BY_USER) &&
|
||||
(freerdp_get_disconnect_ultimatum(context) == Disconnect_Ultimatum_user_requested))
|
||||
{
|
||||
const char* msg = "Error info says user did not initiate but disconnect ultimatum says "
|
||||
"they did; treat this as a user logoff";
|
||||
free(error_msg);
|
||||
error_msg = nullptr;
|
||||
error_msg_len = 0;
|
||||
winpr_asprintf(&error_msg, &error_msg_len, "%s", msg);
|
||||
|
||||
char* emsg = nullptr;
|
||||
size_t len = 0;
|
||||
winpr_asprintf(&emsg, &len, "%s", msg);
|
||||
if (emsg)
|
||||
error_msg = emsg;
|
||||
free(emsg);
|
||||
/* This situation might be limited to Windows XP. */
|
||||
WLog_Print(sdl->log, WLOG_INFO, "%s", msg);
|
||||
exit_code = SDL_EXIT_LOGOFF;
|
||||
@ -1313,45 +1385,26 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
}
|
||||
|
||||
freerdp_disconnect(instance);
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
terminate:
|
||||
sdl->rdp_thread_running = false;
|
||||
bool showError = false;
|
||||
if (freerdp_settings_get_bool(settings, FreeRDP_AuthenticationOnly))
|
||||
WLog_Print(sdl->log, WLOG_INFO, "Authentication only, exit status %s [%" PRId32 "]",
|
||||
sdl_map_to_code_tag(exit_code), exit_code);
|
||||
else
|
||||
{
|
||||
switch (exit_code)
|
||||
{
|
||||
case SDL_EXIT_SUCCESS:
|
||||
case SDL_EXIT_DISCONNECT:
|
||||
case SDL_EXIT_LOGOFF:
|
||||
case SDL_EXIT_DISCONNECT_BY_USER:
|
||||
case SDL_EXIT_CONNECT_CANCELLED:
|
||||
break;
|
||||
default:
|
||||
{
|
||||
std::lock_guard<CriticalSection> lock(sdl->critical);
|
||||
if (sdl->connection_dialog && error_msg)
|
||||
{
|
||||
sdl->connection_dialog->showError(error_msg);
|
||||
showError = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(error_msg);
|
||||
if (!showError)
|
||||
sdl_hide_connection_dialog(sdl);
|
||||
/* RDP main loop.
|
||||
* Connects RDP, loops while running and handles event and dispatch, cleans up
|
||||
* after the connection ends. */
|
||||
static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
{
|
||||
WINPR_ASSERT(sdl);
|
||||
|
||||
sdl->exit_code = exit_code;
|
||||
sdl_push_user_event(SDL_USEREVENT_QUIT);
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 16)
|
||||
SDL_TLSCleanup();
|
||||
#endif
|
||||
return 0;
|
||||
auto instance = sdl->context()->instance;
|
||||
WINPR_ASSERT(instance);
|
||||
|
||||
std::string error_msg;
|
||||
int exit_code = sdl_client_thread_connect(sdl, error_msg);
|
||||
if (exit_code == SDL_EXIT_SUCCESS)
|
||||
exit_code = sdl_client_thread_run(sdl, error_msg);
|
||||
sdl_client_cleanup(sdl, exit_code, error_msg);
|
||||
|
||||
return static_cast<DWORD>(exit_code);
|
||||
}
|
||||
|
||||
/* Optional global initializer.
|
||||
|
@ -119,6 +119,7 @@ BOOL sdl_authenticate_ex(freerdp* instance, char** username, char** password, ch
|
||||
size_t titlesize = 0;
|
||||
winpr_asprintf(&title, &titlesize, "Credentials required for %s", target);
|
||||
|
||||
std::unique_ptr<char, decltype(&free)> guard(title, free);
|
||||
char* u = nullptr;
|
||||
char* d = nullptr;
|
||||
char* p = nullptr;
|
||||
@ -132,26 +133,22 @@ BOOL sdl_authenticate_ex(freerdp* instance, char** username, char** password, ch
|
||||
p = *password;
|
||||
|
||||
if (!sdl_push_user_event(SDL_EVENT_USER_AUTH_DIALOG, title, u, d, p, reason))
|
||||
goto fail;
|
||||
return res;
|
||||
|
||||
if (!sdl_wait_for_result(instance->context, SDL_EVENT_USER_AUTH_RESULT, &event))
|
||||
goto fail;
|
||||
else
|
||||
{
|
||||
auto arg = reinterpret_cast<SDL_UserAuthArg*>(event.padding);
|
||||
return res;
|
||||
|
||||
res = arg->result > 0 ? TRUE : FALSE;
|
||||
auto arg = reinterpret_cast<SDL_UserAuthArg*>(event.padding);
|
||||
|
||||
free(*username);
|
||||
free(*domain);
|
||||
free(*password);
|
||||
*username = arg->user;
|
||||
*domain = arg->domain;
|
||||
*password = arg->password;
|
||||
}
|
||||
res = arg->result > 0 ? TRUE : FALSE;
|
||||
|
||||
free(*username);
|
||||
free(*domain);
|
||||
free(*password);
|
||||
*username = arg->user;
|
||||
*domain = arg->domain;
|
||||
*password = arg->password;
|
||||
|
||||
fail:
|
||||
free(title);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -195,15 +192,14 @@ BOOL sdl_choose_smartcard(freerdp* instance, SmartcardCertInfo** cert_list, DWOR
|
||||
if (gateway)
|
||||
title = "Select a gateway logon smartcard certificate";
|
||||
if (!sdl_push_user_event(SDL_EVENT_USER_SCARD_DIALOG, title, list.data(), count))
|
||||
goto fail;
|
||||
return res;
|
||||
|
||||
if (!sdl_wait_for_result(instance->context, SDL_EVENT_USER_SCARD_RESULT, &event))
|
||||
goto fail;
|
||||
return res;
|
||||
|
||||
res = (event.user.code >= 0) ? TRUE : FALSE;
|
||||
*choice = static_cast<DWORD>(event.user.code);
|
||||
|
||||
fail:
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -60,6 +60,7 @@
|
||||
#include "sdl_pointer.hpp"
|
||||
#include "sdl_prefs.hpp"
|
||||
#include "dialogs/sdl_dialogs.hpp"
|
||||
#include "scoped_guard.hpp"
|
||||
|
||||
#include <aad/sdl_webview.hpp>
|
||||
|
||||
@ -701,7 +702,6 @@ static BOOL sdl_create_windows(SdlContext* sdl)
|
||||
|
||||
auto settings = sdl->context()->settings;
|
||||
auto title = sdl_window_get_title(settings);
|
||||
BOOL rc = FALSE;
|
||||
|
||||
UINT32 windowCount = freerdp_settings_get_uint32(settings, FreeRDP_MonitorCount);
|
||||
|
||||
@ -752,8 +752,9 @@ static BOOL sdl_create_windows(SdlContext* sdl)
|
||||
static_cast<int>(w),
|
||||
static_cast<int>(h),
|
||||
flags };
|
||||
ScopeGuard guard1([&]() { sdl->windows_created.set(); });
|
||||
if (!window.window())
|
||||
goto fail;
|
||||
return FALSE;
|
||||
|
||||
if (freerdp_settings_get_bool(settings, FreeRDP_UseMultimon))
|
||||
{
|
||||
@ -765,11 +766,7 @@ static BOOL sdl_create_windows(SdlContext* sdl)
|
||||
sdl->windows.insert({ window.id(), std::move(window) });
|
||||
}
|
||||
|
||||
rc = TRUE;
|
||||
fail:
|
||||
|
||||
sdl->windows_created.set();
|
||||
return rc;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL sdl_wait_create_windows(SdlContext* sdl)
|
||||
@ -1155,19 +1152,53 @@ static void sdl_post_final_disconnect(freerdp* instance)
|
||||
return;
|
||||
}
|
||||
|
||||
/* RDP main loop.
|
||||
* Connects RDP, loops while running and handles event and dispatch, cleans up
|
||||
* after the connection ends. */
|
||||
static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
static void sdl_client_cleanup(SdlContext* sdl, int exit_code, const std::string& error_msg)
|
||||
{
|
||||
DWORD nCount = 0;
|
||||
DWORD status = 0;
|
||||
int exit_code = SDL_EXIT_SUCCESS;
|
||||
char* error_msg = nullptr;
|
||||
size_t error_msg_len = 0;
|
||||
WINPR_ASSERT(sdl);
|
||||
|
||||
HANDLE handles[MAXIMUM_WAIT_OBJECTS] = {};
|
||||
rdpContext* context = sdl->context();
|
||||
WINPR_ASSERT(context);
|
||||
rdpSettings* settings = context->settings;
|
||||
WINPR_ASSERT(settings);
|
||||
|
||||
sdl->rdp_thread_running = false;
|
||||
bool showError = false;
|
||||
if (freerdp_settings_get_bool(settings, FreeRDP_AuthenticationOnly))
|
||||
WLog_Print(sdl->log, WLOG_INFO, "Authentication only, exit status %s [%" PRId32 "]",
|
||||
sdl_map_to_code_tag(exit_code), exit_code);
|
||||
else
|
||||
{
|
||||
switch (exit_code)
|
||||
{
|
||||
case SDL_EXIT_SUCCESS:
|
||||
case SDL_EXIT_DISCONNECT:
|
||||
case SDL_EXIT_LOGOFF:
|
||||
case SDL_EXIT_DISCONNECT_BY_USER:
|
||||
case SDL_EXIT_CONNECT_CANCELLED:
|
||||
break;
|
||||
default:
|
||||
{
|
||||
std::lock_guard<CriticalSection> lock(sdl->critical);
|
||||
if (sdl->connection_dialog && !error_msg.empty())
|
||||
{
|
||||
sdl->connection_dialog->showError(error_msg.c_str());
|
||||
showError = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!showError)
|
||||
sdl_hide_connection_dialog(sdl);
|
||||
|
||||
sdl->exit_code = exit_code;
|
||||
sdl_push_user_event(SDL_EVENT_USER_QUIT);
|
||||
SDL_CleanupTLS();
|
||||
}
|
||||
|
||||
static int sdl_client_thread_connect(SdlContext* sdl, std::string& error_msg)
|
||||
{
|
||||
WINPR_ASSERT(sdl);
|
||||
|
||||
auto instance = sdl->context()->instance;
|
||||
@ -1180,6 +1211,7 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
rdpSettings* settings = context->settings;
|
||||
WINPR_ASSERT(settings);
|
||||
|
||||
int exit_code = SDL_EXIT_SUCCESS;
|
||||
if (!rc)
|
||||
{
|
||||
UINT32 error = freerdp_get_last_error(context);
|
||||
@ -1192,21 +1224,33 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
freerdp_abort_connect_context(context);
|
||||
WLog_Print(sdl->log, WLOG_ERROR, "Authentication only, %s [0x%08" PRIx32 "] %s",
|
||||
freerdp_get_last_error_name(code), code, freerdp_get_last_error_string(code));
|
||||
goto terminate;
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
if (!rc)
|
||||
{
|
||||
DWORD code = freerdp_error_info(instance);
|
||||
if (exit_code == SDL_EXIT_SUCCESS)
|
||||
exit_code = error_info_to_error(instance, &code, &error_msg, &error_msg_len);
|
||||
{
|
||||
char* msg = nullptr;
|
||||
size_t len = 0;
|
||||
exit_code = error_info_to_error(instance, &code, &msg, &len);
|
||||
if (msg)
|
||||
error_msg = msg;
|
||||
free(msg);
|
||||
}
|
||||
|
||||
auto last = freerdp_get_last_error(context);
|
||||
if (!error_msg)
|
||||
if (error_msg.empty())
|
||||
{
|
||||
winpr_asprintf(&error_msg, &error_msg_len, "%s [0x%08" PRIx32 "]\n%s",
|
||||
char* msg = nullptr;
|
||||
size_t len = 0;
|
||||
winpr_asprintf(&msg, &len, "%s [0x%08" PRIx32 "]\n%s",
|
||||
freerdp_get_last_error_name(last), last,
|
||||
freerdp_get_last_error_string(last));
|
||||
if (msg)
|
||||
error_msg = msg;
|
||||
free(msg);
|
||||
}
|
||||
|
||||
if (exit_code == SDL_EXIT_SUCCESS)
|
||||
@ -1218,11 +1262,25 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
}
|
||||
|
||||
sdl_hide_connection_dialog(sdl);
|
||||
goto terminate;
|
||||
}
|
||||
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
static int sdl_client_thread_run(SdlContext* sdl, std::string& error_msg)
|
||||
{
|
||||
WINPR_ASSERT(sdl);
|
||||
|
||||
auto context = sdl->context();
|
||||
WINPR_ASSERT(context);
|
||||
|
||||
auto instance = context->instance;
|
||||
WINPR_ASSERT(instance);
|
||||
|
||||
int exit_code = SDL_EXIT_SUCCESS;
|
||||
while (!freerdp_shall_disconnect_context(context))
|
||||
{
|
||||
HANDLE handles[MAXIMUM_WAIT_OBJECTS] = {};
|
||||
/*
|
||||
* win8 and server 2k12 seem to have some timing issue/race condition
|
||||
* when a initial sync request is send to sync the keyboard indicators
|
||||
@ -1238,7 +1296,7 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
break;
|
||||
}
|
||||
|
||||
nCount = freerdp_get_event_handles(context, handles, ARRAYSIZE(handles));
|
||||
const DWORD nCount = freerdp_get_event_handles(context, handles, ARRAYSIZE(handles));
|
||||
|
||||
if (nCount == 0)
|
||||
{
|
||||
@ -1246,7 +1304,7 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
break;
|
||||
}
|
||||
|
||||
status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE);
|
||||
const DWORD status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE);
|
||||
|
||||
if (status == WAIT_FAILED)
|
||||
break;
|
||||
@ -1281,17 +1339,27 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
if (exit_code == SDL_EXIT_SUCCESS)
|
||||
{
|
||||
DWORD code = 0;
|
||||
exit_code = error_info_to_error(instance, &code, &error_msg, &error_msg_len);
|
||||
{
|
||||
char* emsg = nullptr;
|
||||
size_t elen = 0;
|
||||
exit_code = error_info_to_error(instance, &code, &emsg, &elen);
|
||||
if (emsg)
|
||||
error_msg = emsg;
|
||||
free(emsg);
|
||||
}
|
||||
|
||||
if ((code == ERRINFO_LOGOFF_BY_USER) &&
|
||||
(freerdp_get_disconnect_ultimatum(context) == Disconnect_Ultimatum_user_requested))
|
||||
{
|
||||
const char* msg = "Error info says user did not initiate but disconnect ultimatum says "
|
||||
"they did; treat this as a user logoff";
|
||||
free(error_msg);
|
||||
error_msg = nullptr;
|
||||
error_msg_len = 0;
|
||||
winpr_asprintf(&error_msg, &error_msg_len, "%s", msg);
|
||||
|
||||
char* emsg = nullptr;
|
||||
size_t elen = 0;
|
||||
winpr_asprintf(&emsg, &elen, "%s", msg);
|
||||
if (emsg)
|
||||
error_msg = emsg;
|
||||
free(emsg);
|
||||
|
||||
/* This situation might be limited to Windows XP. */
|
||||
WLog_Print(sdl->log, WLOG_INFO, "%s", msg);
|
||||
@ -1301,44 +1369,28 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
|
||||
freerdp_disconnect(instance);
|
||||
|
||||
terminate:
|
||||
sdl->rdp_thread_running = false;
|
||||
bool showError = false;
|
||||
if (freerdp_settings_get_bool(settings, FreeRDP_AuthenticationOnly))
|
||||
WLog_Print(sdl->log, WLOG_INFO, "Authentication only, exit status %s [%" PRId32 "]",
|
||||
sdl_map_to_code_tag(exit_code), exit_code);
|
||||
else
|
||||
{
|
||||
switch (exit_code)
|
||||
{
|
||||
case SDL_EXIT_SUCCESS:
|
||||
case SDL_EXIT_DISCONNECT:
|
||||
case SDL_EXIT_LOGOFF:
|
||||
case SDL_EXIT_DISCONNECT_BY_USER:
|
||||
case SDL_EXIT_CONNECT_CANCELLED:
|
||||
break;
|
||||
default:
|
||||
{
|
||||
std::lock_guard<CriticalSection> lock(sdl->critical);
|
||||
if (sdl->connection_dialog && error_msg)
|
||||
{
|
||||
sdl->connection_dialog->showError(error_msg);
|
||||
showError = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(error_msg);
|
||||
if (!showError)
|
||||
sdl_hide_connection_dialog(sdl);
|
||||
|
||||
sdl->exit_code = exit_code;
|
||||
sdl_push_user_event(SDL_EVENT_USER_QUIT);
|
||||
SDL_CleanupTLS();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* RDP main loop.
|
||||
* Connects RDP, loops while running and handles event and dispatch, cleans up
|
||||
* after the connection ends. */
|
||||
static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
|
||||
{
|
||||
WINPR_ASSERT(sdl);
|
||||
|
||||
auto instance = sdl->context()->instance;
|
||||
WINPR_ASSERT(instance);
|
||||
|
||||
std::string error_msg;
|
||||
int exit_code = sdl_client_thread_connect(sdl, error_msg);
|
||||
if (exit_code == SDL_EXIT_SUCCESS)
|
||||
exit_code = sdl_client_thread_run(sdl, error_msg);
|
||||
sdl_client_cleanup(sdl, exit_code, error_msg);
|
||||
|
||||
return static_cast<DWORD>(exit_code);
|
||||
}
|
||||
|
||||
/* Optional global initializer.
|
||||
* Here we just register a signal handler to print out stack traces
|
||||
* if available. */
|
||||
|
@ -22,6 +22,7 @@ add_subdirectory(res)
|
||||
add_library(sdl-common-prefs STATIC
|
||||
sdl_prefs.hpp
|
||||
sdl_prefs.cpp
|
||||
scoped_guard.hpp
|
||||
)
|
||||
target_link_libraries(sdl-common-prefs winpr freerdp)
|
||||
|
||||
|
56
client/SDL/common/scoped_guard.hpp
Normal file
56
client/SDL/common/scoped_guard.hpp
Normal file
@ -0,0 +1,56 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* SDL ScopeGuard
|
||||
*
|
||||
* Copyright 2024 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2024 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
class ScopeGuard
|
||||
{
|
||||
public:
|
||||
template <class Callable> explicit ScopeGuard(Callable&& cleanupFunction)
|
||||
try : f(std::forward<Callable>(cleanupFunction))
|
||||
{
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
cleanupFunction();
|
||||
throw;
|
||||
}
|
||||
|
||||
~ScopeGuard()
|
||||
{
|
||||
if (f)
|
||||
f();
|
||||
}
|
||||
|
||||
void dismiss() noexcept
|
||||
{
|
||||
f = nullptr;
|
||||
}
|
||||
|
||||
ScopeGuard(const ScopeGuard&) = delete;
|
||||
ScopeGuard(ScopeGuard&& other) noexcept = delete;
|
||||
auto operator=(const ScopeGuard&) = delete;
|
||||
auto operator=(const ScopeGuard&&) = delete;
|
||||
|
||||
private:
|
||||
std::function<void()> f;
|
||||
};
|
Loading…
Reference in New Issue
Block a user