[client,SDL] remove goto usage, replace with RAII

* use std::uniqe_ptr to clean up malloced strings
* use ScopeGuard to run cleanup code whenever the function is exited
This commit is contained in:
akallabeth 2024-09-16 22:48:54 +02:00 committed by Armin Novak
parent ed2c5e9a5b
commit b7601ec755
No known key found for this signature in database
GPG Key ID: 2CF4A2D2D3D72105
4 changed files with 122 additions and 127 deletions

View File

@ -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;
}

View File

@ -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)
@ -1193,6 +1192,47 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
rdpSettings* settings = context->settings;
WINPR_ASSERT(settings);
ScopeGuard guard(
[&]()
{
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_USEREVENT_QUIT);
#if SDL_VERSION_ATLEAST(2, 0, 16)
SDL_TLSCleanup();
#endif
});
if (!rc)
{
UINT32 error = freerdp_get_last_error(context);
@ -1205,7 +1245,7 @@ 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)
@ -1231,7 +1271,7 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
}
sdl_hide_connection_dialog(sdl);
goto terminate;
return exit_code;
}
while (!freerdp_shall_disconnect_context(context))
@ -1313,44 +1353,6 @@ 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_USEREVENT_QUIT);
#if SDL_VERSION_ATLEAST(2, 0, 16)
SDL_TLSCleanup();
#endif
return 0;
}

View File

@ -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;
}

View File

@ -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)
@ -1180,6 +1177,45 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
rdpSettings* settings = context->settings;
WINPR_ASSERT(settings);
ScopeGuard guard(
[&]()
{
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();
});
if (!rc)
{
UINT32 error = freerdp_get_last_error(context);
@ -1192,7 +1228,7 @@ 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)
@ -1218,7 +1254,7 @@ static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
}
sdl_hide_connection_dialog(sdl);
goto terminate;
return exit_code;
}
while (!freerdp_shall_disconnect_context(context))
@ -1301,41 +1337,6 @@ 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;
}