22#include <freerdp/config.h>
35#include "connection.h"
37#include <freerdp/buildflags.h>
38#include "gateway/rpc_fault.h"
40#include <winpr/assert.h>
43#include <winpr/string.h>
44#include <winpr/stream.h>
45#include <winpr/wtsapi.h>
47#include <winpr/debug.h>
49#include <freerdp/freerdp.h>
50#include <freerdp/streamdump.h>
51#include <freerdp/error.h>
52#include <freerdp/event.h>
53#include <freerdp/locale/keyboard.h>
54#include <freerdp/locale/locale.h>
55#include <freerdp/channels/channels.h>
56#include <freerdp/version.h>
57#include <freerdp/log.h>
58#include <freerdp/utils/signal.h>
60#include "../cache/pointer.h"
63#define TAG FREERDP_TAG("core")
65static void sig_abort_connect(
int signum,
const char* signame,
void* ctx)
67 rdpContext* context = (rdpContext*)ctx;
69 WLog_INFO(TAG,
"Signal %s [%d], terminating session %p", signame, signum, context);
71 freerdp_abort_connect_context(context);
85static int freerdp_connect_begin(freerdp* instance)
90 rdpSettings* settings = NULL;
95 WINPR_ASSERT(instance->context);
98 instance->ConnectionCallbackState = CLIENT_STATE_INITIAL;
99 freerdp_set_last_error_log(instance->context, FREERDP_ERROR_SUCCESS);
100 clearChannelError(instance->context);
101 if (!utils_reset_abort(instance->context->rdp))
104 rdp = instance->context->rdp;
107 settings = instance->context->settings;
108 WINPR_ASSERT(settings);
110 freerdp_channels_register_instance(instance->context->channels, instance);
112 if (!freerdp_settings_set_default_order_support(settings))
115 freerdp_add_signal_cleanup_handler(instance->context, sig_abort_connect);
117 IFCALLRET(instance->PreConnect, status, instance);
118 instance->ConnectionCallbackState = CLIENT_STATE_PRECONNECT_PASSED;
120 freerdp_settings_print_warnings(settings);
122 status = freerdp_settings_enforce_monitor_exists(settings);
125 status = freerdp_settings_enforce_consistency(settings);
128 status = freerdp_settings_check_client_after_preconnect(settings);
131 status = rdp_set_backup_settings(rdp);
133 status = utils_reload_channels(instance->context);
136 int64_t KeyboardLayout = freerdp_get_keyboard_default_layout_for_locale(cp);
137 if (KeyboardLayout == 0)
140 switch (KeyboardLayout)
143 case KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002:
146 WINPR_KBD_TYPE_JAPANESE))
160 rdpContext* context = instance->context;
161 WINPR_ASSERT(context);
162 freerdp_set_last_error_if_not(context, FREERDP_ERROR_PRE_CONNECT_FAILED);
164 WLog_Print(context->log, WLOG_ERROR,
"freerdp_pre_connect failed: %s",
165 rdp_client_connection_state_string(instance->ConnectionCallbackState));
169 rc = rdp_client_connect(rdp);
174 rdpContext* context = rdp->context;
175 WINPR_ASSERT(context);
176 WLog_Print(context->log, WLOG_ERROR,
"Authentication only, exit status %" PRId32
"", rc);
183BOOL freerdp_connect(freerdp* instance)
186 ConnectionResultEventArgs e = { 0 };
187 const int rc = freerdp_connect_begin(instance);
189 UINT status2 = ERROR_INTERNAL_ERROR;
191 WINPR_ASSERT(instance);
192 WINPR_ASSERT(instance->context);
194 rdp = instance->context->rdp;
196 WINPR_ASSERT(rdp->settings);
205 up->pcap_rfx = pcap_open(
212 pointer_cache_register_callbacks(instance->context->update);
213 status = IFCALLRESULT(TRUE, instance->PostConnect, instance);
214 instance->ConnectionCallbackState = CLIENT_STATE_POSTCONNECT_PASSED;
217 status2 = freerdp_channels_post_connect(instance->context->channels, instance);
221 status2 = CHANNEL_RC_OK;
222 if (freerdp_get_last_error(instance->context) == FREERDP_ERROR_CONNECT_TRANSPORT_FAILED)
223 status = freerdp_reconnect(instance);
225 goto freerdp_connect_finally;
228 if (!status || (status2 != CHANNEL_RC_OK) || !update_post_connect(instance->context->update))
230 rdpContext* context = instance->context;
231 WINPR_ASSERT(context);
232 WLog_Print(context->log, WLOG_ERROR,
"freerdp_post_connect failed");
234 freerdp_set_last_error_if_not(context, FREERDP_ERROR_POST_CONNECT_FAILED);
237 goto freerdp_connect_finally;
240 if (rdp->settings->PlayRemoteFx)
244 pcap_record record = { 0 };
246 WINPR_ASSERT(update);
247 update->pcap_rfx = pcap_open(rdp->settings->PlayRemoteFxFile, FALSE);
250 if (!update->pcap_rfx)
251 goto freerdp_connect_finally;
253 update->play_rfx = TRUE;
257 while (pcap_has_next_record(update->pcap_rfx) && status)
259 pcap_get_next_record_header(update->pcap_rfx, &record);
261 s = transport_take_from_pool(rdp->transport, record.length);
265 record.data = Stream_Buffer(s);
266 pcap_get_next_record_content(update->pcap_rfx, &record);
267 Stream_SetLength(s, record.length);
268 Stream_SetPosition(s, 0);
270 if (!update_begin_paint(&update->common))
274 if (update_recv_surfcmds(&update->common, s) < 0)
277 if (!update_end_paint(&update->common))
284 pcap_close(update->pcap_rfx);
285 update->pcap_rfx = NULL;
286 goto freerdp_connect_finally;
289 if (rdp->errorInfo == ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES)
290 freerdp_set_last_error_log(instance->context, FREERDP_ERROR_INSUFFICIENT_PRIVILEGES);
292 transport_set_connected_event(rdp->transport);
294freerdp_connect_finally:
295 EventArgsInit(&e,
"freerdp");
296 e.result = status ? 0 : -1;
297 PubSub_OnConnectionResult(rdp->pubSub, instance->context, &e);
300 freerdp_disconnect(instance);
305#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
306BOOL freerdp_abort_connect(freerdp* instance)
311 return freerdp_abort_connect_context(instance->context);
315BOOL freerdp_abort_connect_context(rdpContext* context)
320 freerdp_set_last_error_if_not(context, FREERDP_ERROR_CONNECT_CANCELLED);
324 if (context->rdp && context->rdp->mcs)
326 if (!context->ServerMode)
328 (void)mcs_send_disconnect_provider_ultimatum(context->rdp->mcs,
329 Disconnect_Ultimatum_user_requested);
332 return utils_abort_connect(context->rdp);
335#if defined(WITH_FREERDP_DEPRECATED)
336BOOL freerdp_get_fds(freerdp* instance,
void** rfds,
int* rcount, WINPR_ATTR_UNUSED
void** wfds,
337 WINPR_ATTR_UNUSED
int* wcount)
341 WINPR_ASSERT(instance);
342 WINPR_ASSERT(instance->context);
344 rdp = instance->context->rdp;
347 transport_get_fds(rdp->transport, rfds, rcount);
352BOOL freerdp_check_fds(freerdp* instance)
360 if (!instance->context)
363 if (!instance->context->rdp)
366 rdp = instance->context->rdp;
367 status = rdp_check_fds(rdp);
371 TerminateEventArgs e;
372 rdpContext* context = instance->context;
373 WINPR_ASSERT(context);
375 WLog_Print(context->log, WLOG_DEBUG,
"rdp_check_fds() - %i", status);
376 EventArgsInit(&e,
"freerdp");
378 PubSub_OnTerminate(rdp->pubSub, context, &e);
385DWORD freerdp_get_event_handles(rdpContext* context, HANDLE* events, DWORD count)
389 WINPR_ASSERT(context);
390 WINPR_ASSERT(context->rdp);
391 WINPR_ASSERT(events || (count == 0));
393 nCount += transport_get_event_handles(context->rdp->transport, events, count);
398 if (events && (nCount < count + 2))
400 events[nCount++] = freerdp_channels_get_event_handle(context->instance);
401 events[nCount++] = getChannelErrorEventHandle(context);
402 events[nCount++] = utils_get_abort_event(context->rdp);
407 const SSIZE_T rc = freerdp_client_channel_get_registered_event_handles(
408 context->channels, &events[nCount], count - nCount);
411 return nCount + (DWORD)rc;
415static BOOL freerdp_prevent_session_lock(rdpContext* context)
417 WINPR_ASSERT(context);
418 WINPR_ASSERT(context->input);
422 UINT32 FakeMouseMotionInterval =
424 if (FakeMouseMotionInterval && in->lastInputTimestamp)
426 const time_t now = time(NULL);
427 if (WINPR_ASSERTING_INT_CAST(
size_t, now) - in->lastInputTimestamp >
428 FakeMouseMotionInterval)
430 WLog_Print(context->log, WLOG_DEBUG,
431 "fake mouse move: x=%d y=%d lastInputTimestamp=%" PRIu64
" "
432 "FakeMouseMotionInterval=%" PRIu32,
433 in->lastX, in->lastY, in->lastInputTimestamp, FakeMouseMotionInterval);
435 BOOL status = freerdp_input_send_mouse_event(context->input, PTR_FLAGS_MOVE, in->lastX,
439 if (freerdp_get_last_error(context) == FREERDP_ERROR_SUCCESS)
440 WLog_Print(context->log, WLOG_ERROR,
441 "freerdp_prevent_session_lock() failed - %" PRIi32
"", status);
453BOOL freerdp_check_event_handles(rdpContext* context)
455 WINPR_ASSERT(context);
457 BOOL status = freerdp_check_fds(context->instance);
461 if (freerdp_get_last_error(context) == FREERDP_ERROR_SUCCESS)
462 WLog_Print(context->log, WLOG_ERROR,
"freerdp_check_fds() failed - %" PRIi32
"",
468 status = freerdp_channels_check_fds(context->channels, context->instance);
472 if (freerdp_get_last_error(context) == FREERDP_ERROR_SUCCESS)
473 WLog_Print(context->log, WLOG_ERROR,
474 "freerdp_channels_check_fds() failed - %" PRIi32
"", status);
479 status = checkChannelErrorEvent(context);
483 if (freerdp_get_last_error(context) == FREERDP_ERROR_SUCCESS)
484 WLog_Print(context->log, WLOG_ERROR,
"checkChannelErrorEvent() failed - %" PRIi32
"",
490 status = freerdp_prevent_session_lock(context);
495wMessageQueue* freerdp_get_message_queue(freerdp* instance, DWORD
id)
497 wMessageQueue* queue = NULL;
499 WINPR_ASSERT(instance);
501 rdpContext* context = instance->context;
502 WINPR_ASSERT(context);
506 case FREERDP_UPDATE_MESSAGE_QUEUE:
509 queue = update->queue;
513 case FREERDP_INPUT_MESSAGE_QUEUE:
516 queue = input->queue;
526HANDLE freerdp_get_message_queue_event_handle(freerdp* instance, DWORD
id)
529 wMessageQueue* queue = freerdp_get_message_queue(instance,
id);
532 event = MessageQueue_Event(queue);
537int freerdp_message_queue_process_message(freerdp* instance, DWORD
id, wMessage* message)
540 rdpContext* context = NULL;
542 WINPR_ASSERT(instance);
544 context = instance->context;
545 WINPR_ASSERT(context);
549 case FREERDP_UPDATE_MESSAGE_QUEUE:
550 status = update_message_queue_process_message(context->update, message);
553 case FREERDP_INPUT_MESSAGE_QUEUE:
554 status = input_message_queue_process_message(context->input, message);
563int freerdp_message_queue_process_pending_messages(freerdp* instance, DWORD
id)
566 rdpContext* context = NULL;
568 WINPR_ASSERT(instance);
570 context = instance->context;
571 WINPR_ASSERT(context);
575 case FREERDP_UPDATE_MESSAGE_QUEUE:
576 status = update_message_queue_process_pending_messages(context->update);
579 case FREERDP_INPUT_MESSAGE_QUEUE:
580 status = input_message_queue_process_pending_messages(context->input);
589static BOOL freerdp_send_channel_data(freerdp* instance, UINT16 channelId,
const BYTE* data,
592 WINPR_ASSERT(instance);
593 WINPR_ASSERT(instance->context);
594 WINPR_ASSERT(instance->context->rdp);
595 return rdp_send_channel_data(instance->context->rdp, channelId, data, size);
598static BOOL freerdp_send_channel_packet(freerdp* instance, UINT16 channelId,
size_t totalSize,
599 UINT32 flags,
const BYTE* data,
size_t chunkSize)
601 WINPR_ASSERT(instance);
602 WINPR_ASSERT(instance->context);
603 WINPR_ASSERT(instance->context->rdp);
604 return rdp_channel_send_packet(instance->context->rdp, channelId, totalSize, flags, data,
608BOOL freerdp_disconnect(freerdp* instance)
614 if (!instance || !instance->context)
617 rdp = instance->context->rdp;
618 utils_abort_connect(rdp);
620 if (!rdp_client_disconnect(rdp))
623 up = update_cast(rdp->update);
625 update_post_disconnect(rdp->update);
627 IFCALL(instance->PostDisconnect, instance);
631 up->dump_rfx = FALSE;
632 pcap_close(up->pcap_rfx);
636 freerdp_channels_close(instance->context->channels, instance);
638 IFCALL(instance->PostFinalDisconnect, instance);
640 freerdp_del_signal_cleanup_handler(instance->context, sig_abort_connect);
644#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
645BOOL freerdp_disconnect_before_reconnect(freerdp* instance)
647 WINPR_ASSERT(instance);
648 return freerdp_disconnect_before_reconnect_context(instance->context);
652BOOL freerdp_disconnect_before_reconnect_context(rdpContext* context)
656 WINPR_ASSERT(context);
659 return rdp_client_disconnect_and_clear(rdp);
662BOOL freerdp_reconnect(freerdp* instance)
666 WINPR_ASSERT(instance);
667 WINPR_ASSERT(instance->context);
669 if (freerdp_get_last_error(instance->context) == FREERDP_ERROR_CONNECT_CANCELLED)
672 rdp = instance->context->rdp;
674 if (!utils_reset_abort(instance->context->rdp))
676 return rdp_client_reconnect(rdp);
679#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
680BOOL freerdp_shall_disconnect(freerdp* instance)
685 return freerdp_shall_disconnect_context(instance->context);
689BOOL freerdp_shall_disconnect_context(
const rdpContext* context)
694 return utils_abort_event_is_set(context->rdp);
697BOOL freerdp_focus_required(freerdp* instance)
700 BOOL bRetCode = FALSE;
702 WINPR_ASSERT(instance);
703 WINPR_ASSERT(instance->context);
705 rdp = instance->context->rdp;
708 if (rdp->resendFocus)
711 rdp->resendFocus = FALSE;
717void freerdp_set_focus(freerdp* instance)
721 WINPR_ASSERT(instance);
722 WINPR_ASSERT(instance->context);
724 rdp = instance->context->rdp;
727 rdp->resendFocus = TRUE;
730void freerdp_get_version(
int* major,
int* minor,
int* revision)
733 *major = FREERDP_VERSION_MAJOR;
736 *minor = FREERDP_VERSION_MINOR;
738 if (revision != NULL)
739 *revision = FREERDP_VERSION_REVISION;
742const char* freerdp_get_version_string(
void)
744 return FREERDP_VERSION_FULL;
747const char* freerdp_get_build_config(
void)
749 WINPR_PRAGMA_DIAG_PUSH
750 WINPR_PRAGMA_DIAG_IGNORED_OVERLENGTH_STRINGS
751 static const char build_config[] =
752 "Build configuration: " FREERDP_BUILD_CONFIG
"\n"
753 "Build type: " FREERDP_BUILD_TYPE
"\n"
754 "CFLAGS: " FREERDP_CFLAGS
"\n"
755 "Compiler: " FREERDP_COMPILER_ID
", " FREERDP_COMPILER_VERSION
"\n"
756 "Target architecture: " FREERDP_TARGET_ARCH
"\n";
757 WINPR_PRAGMA_DIAG_POP
761const char* freerdp_get_build_revision(
void)
763 return FREERDP_GIT_REVISION;
767 DEFINE_EVENT_ENTRY(WindowStateChange), DEFINE_EVENT_ENTRY(ResizeWindow),
768 DEFINE_EVENT_ENTRY(LocalResizeWindow), DEFINE_EVENT_ENTRY(EmbedWindow),
769 DEFINE_EVENT_ENTRY(PanningChange), DEFINE_EVENT_ENTRY(ZoomingChange),
770 DEFINE_EVENT_ENTRY(ErrorInfo), DEFINE_EVENT_ENTRY(Terminate),
771 DEFINE_EVENT_ENTRY(ConnectionResult), DEFINE_EVENT_ENTRY(ChannelConnected),
772 DEFINE_EVENT_ENTRY(ChannelDisconnected), DEFINE_EVENT_ENTRY(MouseEvent),
773 DEFINE_EVENT_ENTRY(Activated), DEFINE_EVENT_ENTRY(Timer),
774 DEFINE_EVENT_ENTRY(GraphicsReset)
787BOOL freerdp_context_new(freerdp* instance)
789 return freerdp_context_new_ex(instance, NULL);
792BOOL freerdp_context_new_ex(freerdp* instance, rdpSettings* settings)
795 rdpContext* context = NULL;
798 WINPR_ASSERT(instance);
800 instance->context = context = (rdpContext*)calloc(1, instance->ContextSize);
805 context->log = WLog_Get(TAG);
810 context->settings = settings;
811 context->instance = instance;
812 context->ServerMode = FALSE;
813 context->disconnectUltimatum = 0;
815 context->metrics = metrics_new(context);
817 if (!context->metrics)
820 rdp = rdp_new(context);
826 context->pubSub = rdp->pubSub;
828 if (!context->pubSub)
831 PubSub_AddEventTypes(rdp->pubSub, FreeRDP_Events, ARRAYSIZE(FreeRDP_Events));
833#if defined(WITH_FREERDP_DEPRECATED)
834 instance->input = rdp->input;
835 instance->update = rdp->update;
836 instance->settings = rdp->settings;
837 instance->autodetect = rdp->autodetect;
840 instance->heartbeat = rdp->heartbeat;
841 context->graphics = graphics_new(context);
843 if (!context->graphics)
846 context->input = rdp->input;
847 context->update = rdp->update;
848 context->settings = rdp->settings;
849 context->autodetect = rdp->autodetect;
851 if (!(context->errorDescription = calloc(1, 500)))
853 WLog_Print(context->log, WLOG_ERROR,
"calloc failed!");
857 if (!(context->channelErrorEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
859 WLog_Print(context->log, WLOG_ERROR,
"CreateEvent failed!");
863 update_register_client_callbacks(rdp->update);
865 if (!(context->channels = freerdp_channels_new(instance)))
868 context->dump = stream_dump_new();
872 IFCALLRET(instance->ContextNew, ret, instance, context);
878 freerdp_context_free(instance);
882BOOL freerdp_context_reset(freerdp* instance)
887 WINPR_ASSERT(instance->context);
888 rdpRdp* rdp = instance->context->rdp;
890 return rdp_reset_runtime_settings(rdp);
901void freerdp_context_free(freerdp* instance)
903 rdpContext* ctx = NULL;
908 if (!instance->context)
911 ctx = instance->context;
913 IFCALL(instance->ContextFree, instance, ctx);
916 ctx->settings = NULL;
918 graphics_free(ctx->graphics);
919 ctx->graphics = NULL;
921 metrics_free(ctx->metrics);
924 if (ctx->channelErrorEvent)
925 (void)CloseHandle(ctx->channelErrorEvent);
926 ctx->channelErrorEvent = NULL;
928 free(ctx->errorDescription);
929 ctx->errorDescription = NULL;
931 freerdp_channels_free(ctx->channels);
932 ctx->channels = NULL;
934 freerdp_client_codecs_free(ctx->codecs);
937 stream_dump_free(ctx->dump);
942 ctx->settings = NULL;
943 ctx->autodetect = NULL;
946 instance->context = NULL;
947#if defined(WITH_FREERDP_DEPRECATED)
948 instance->input = NULL;
949 instance->update = NULL;
950 instance->settings = NULL;
951 instance->autodetect = NULL;
953 instance->heartbeat = NULL;
956int freerdp_get_disconnect_ultimatum(rdpContext* context)
958 WINPR_ASSERT(context);
959 return context->disconnectUltimatum;
962UINT32 freerdp_error_info(freerdp* instance)
964 WINPR_ASSERT(instance);
965 WINPR_ASSERT(instance->context);
966 WINPR_ASSERT(instance->context->rdp);
967 return instance->context->rdp->errorInfo;
970void freerdp_set_error_info(rdpRdp* rdp, UINT32 error)
975 rdp_set_error_info(rdp, error);
978BOOL freerdp_send_error_info(rdpRdp* rdp)
983 return rdp_send_error_info(rdp);
986UINT32 freerdp_get_last_error(rdpContext* context)
988 WINPR_ASSERT(context);
989 return context->LastError;
992const char* freerdp_get_last_error_name(UINT32 code)
994 const char* name = NULL;
995 const UINT32 cls = GET_FREERDP_ERROR_CLASS(code);
996 const UINT32 type = GET_FREERDP_ERROR_TYPE(code);
1000 case FREERDP_ERROR_ERRBASE_CLASS:
1001 name = freerdp_get_error_base_name(type);
1004 case FREERDP_ERROR_ERRINFO_CLASS:
1005 name = freerdp_get_error_info_name(type);
1008 case FREERDP_ERROR_CONNECT_CLASS:
1009 name = freerdp_get_error_connect_name(type);
1013 name = rpc_error_to_string(code);
1020const char* freerdp_get_last_error_string(UINT32 code)
1022 const char*
string = NULL;
1023 const UINT32 cls = GET_FREERDP_ERROR_CLASS(code);
1024 const UINT32 type = GET_FREERDP_ERROR_TYPE(code);
1028 case FREERDP_ERROR_ERRBASE_CLASS:
1029 string = freerdp_get_error_base_string(type);
1032 case FREERDP_ERROR_ERRINFO_CLASS:
1033 string = freerdp_get_error_info_string(type);
1036 case FREERDP_ERROR_CONNECT_CLASS:
1037 string = freerdp_get_error_connect_string(type);
1041 string = rpc_error_to_string(code);
1048const char* freerdp_get_last_error_category(UINT32 code)
1050 const char*
string = NULL;
1051 const UINT32 cls = GET_FREERDP_ERROR_CLASS(code);
1052 const UINT32 type = GET_FREERDP_ERROR_TYPE(code);
1056 case FREERDP_ERROR_ERRBASE_CLASS:
1057 string = freerdp_get_error_base_category(type);
1060 case FREERDP_ERROR_ERRINFO_CLASS:
1061 string = freerdp_get_error_info_category(type);
1064 case FREERDP_ERROR_CONNECT_CLASS:
1065 string = freerdp_get_error_connect_category(type);
1069 string = rpc_error_to_category(code);
1076void freerdp_set_last_error_ex(rdpContext* context, UINT32 lastError,
const char* fkt,
1077 const char* file,
int line)
1079 WINPR_ASSERT(context);
1080 WINPR_ASSERT(line >= 0);
1084 if (WLog_IsLevelActive(context->log, WLOG_ERROR))
1086 WLog_PrintMessage(context->log, WLOG_MESSAGE_TEXT, WLOG_ERROR, (
size_t)line, file, fkt,
1087 "%s [0x%08" PRIX32
"]", freerdp_get_last_error_name(lastError),
1092 if (lastError == FREERDP_ERROR_SUCCESS)
1094 if (WLog_IsLevelActive(context->log, WLOG_DEBUG))
1095 WLog_PrintMessage(context->log, WLOG_MESSAGE_TEXT, WLOG_DEBUG, (
size_t)line, file, fkt,
1096 "resetting error state");
1098 else if (context->LastError != FREERDP_ERROR_SUCCESS)
1100 if (WLog_IsLevelActive(context->log, WLOG_ERROR))
1102 WLog_PrintMessage(context->log, WLOG_MESSAGE_TEXT, WLOG_ERROR, (
size_t)line, file, fkt,
1103 "TODO: Trying to set error code %s, but %s already set!",
1104 freerdp_get_last_error_name(lastError),
1105 freerdp_get_last_error_name(context->LastError));
1108 context->LastError = lastError;
1111const char* freerdp_get_logon_error_info_type_ex(UINT32 type,
char* buffer,
size_t size)
1113 const char* str = freerdp_get_logon_error_info_type(type);
1114 (void)_snprintf(buffer, size,
"%s(0x%04" PRIx32
")", str, type);
1118const char* freerdp_get_logon_error_info_type(UINT32 type)
1122 case LOGON_MSG_DISCONNECT_REFUSED:
1123 return "LOGON_MSG_DISCONNECT_REFUSED";
1125 case LOGON_MSG_NO_PERMISSION:
1126 return "LOGON_MSG_NO_PERMISSION";
1128 case LOGON_MSG_BUMP_OPTIONS:
1129 return "LOGON_MSG_BUMP_OPTIONS";
1131 case LOGON_MSG_RECONNECT_OPTIONS:
1132 return "LOGON_MSG_RECONNECT_OPTIONS";
1134 case LOGON_MSG_SESSION_TERMINATE:
1135 return "LOGON_MSG_SESSION_TERMINATE";
1137 case LOGON_MSG_SESSION_CONTINUE:
1138 return "LOGON_MSG_SESSION_CONTINUE";
1145const char* freerdp_get_logon_error_info_data(UINT32 data)
1149 case LOGON_FAILED_BAD_PASSWORD:
1150 return "LOGON_FAILED_BAD_PASSWORD";
1152 case LOGON_FAILED_UPDATE_PASSWORD:
1153 return "LOGON_FAILED_UPDATE_PASSWORD";
1155 case LOGON_FAILED_OTHER:
1156 return "LOGON_FAILED_OTHER";
1159 return "LOGON_WARNING";
1162 return "SESSION_ID";
1166const char* freerdp_get_logon_error_info_data_ex(UINT32 data,
char* buffer,
size_t size)
1168 const char* str = freerdp_get_logon_error_info_data(data);
1169 (void)_snprintf(buffer, size,
"%s(0x%04" PRIx32
")", str, data);
1176freerdp* freerdp_new(
void)
1178 freerdp* instance = NULL;
1179 instance = (freerdp*)calloc(1,
sizeof(freerdp));
1184 instance->ContextSize =
sizeof(rdpContext);
1185 instance->SendChannelData = freerdp_send_channel_data;
1186 instance->SendChannelPacket = freerdp_send_channel_packet;
1187 instance->ReceiveChannelData = freerdp_channels_data;
1195void freerdp_free(freerdp* instance)
1200ULONG freerdp_get_transport_sent(rdpContext* context, BOOL resetCount)
1202 WINPR_ASSERT(context);
1203 WINPR_ASSERT(context->rdp);
1204 UINT64 rc = transport_get_bytes_sent(context->rdp->transport, resetCount);
1205 return WINPR_CXX_COMPAT_CAST(ULONG, MIN(rc, UINT32_MAX));
1208BOOL freerdp_nla_impersonate(rdpContext* context)
1218 if (!context->rdp->transport)
1221 nla = transport_get_nla(context->rdp->transport);
1222 return nla_impersonate(nla);
1225BOOL freerdp_nla_revert_to_self(rdpContext* context)
1235 if (!context->rdp->transport)
1238 nla = transport_get_nla(context->rdp->transport);
1239 return nla_revert_to_self(nla);
1242UINT32 freerdp_get_nla_sspi_error(rdpContext* context)
1244 WINPR_ASSERT(context);
1245 WINPR_ASSERT(context->rdp);
1246 WINPR_ASSERT(context->rdp->transport);
1248 rdpNla* nla = transport_get_nla(context->rdp->transport);
1250 return (UINT32)nla_get_sspi_error(nla);
1253BOOL freerdp_nla_encrypt(rdpContext* context,
const SecBuffer* inBuffer,
SecBuffer* outBuffer)
1255 WINPR_ASSERT(context);
1256 WINPR_ASSERT(context->rdp);
1258 rdpNla* nla = context->rdp->nla;
1259 return nla_encrypt(nla, inBuffer, outBuffer);
1262BOOL freerdp_nla_decrypt(rdpContext* context,
const SecBuffer* inBuffer,
SecBuffer* outBuffer)
1264 WINPR_ASSERT(context);
1265 WINPR_ASSERT(context->rdp);
1267 rdpNla* nla = context->rdp->nla;
1268 return nla_decrypt(nla, inBuffer, outBuffer);
1271SECURITY_STATUS freerdp_nla_QueryContextAttributes(rdpContext* context, DWORD ulAttr, PVOID pBuffer)
1273 WINPR_ASSERT(context);
1274 WINPR_ASSERT(context->rdp);
1276 return nla_QueryContextAttributes(context->rdp->nla, ulAttr, pBuffer);
1279HANDLE getChannelErrorEventHandle(rdpContext* context)
1281 WINPR_ASSERT(context);
1282 return context->channelErrorEvent;
1285BOOL checkChannelErrorEvent(rdpContext* context)
1287 WINPR_ASSERT(context);
1289 if (WaitForSingleObject(context->channelErrorEvent, 0) == WAIT_OBJECT_0)
1291 WLog_Print(context->log, WLOG_ERROR,
"%s. Error was %" PRIu32
"", context->errorDescription,
1292 context->channelErrorNum);
1304UINT getChannelError(rdpContext* context)
1306 WINPR_ASSERT(context);
1307 return context->channelErrorNum;
1310const char* getChannelErrorDescription(rdpContext* context)
1312 WINPR_ASSERT(context);
1313 return context->errorDescription;
1316void clearChannelError(rdpContext* context)
1318 WINPR_ASSERT(context);
1319 context->channelErrorNum = 0;
1320 memset(context->errorDescription, 0, 500);
1321 (void)ResetEvent(context->channelErrorEvent);
1324WINPR_ATTR_FORMAT_ARG(3, 4)
1325void setChannelError(rdpContext* context, UINT errorNum, WINPR_FORMAT_ARG const
char* format, ...)
1328 va_start(ap, format);
1330 WINPR_ASSERT(context);
1332 context->channelErrorNum = errorNum;
1333 (void)vsnprintf(context->errorDescription, 499, format, ap);
1335 (void)SetEvent(context->channelErrorEvent);
1338const char* freerdp_nego_get_routing_token(rdpContext* context, DWORD* length)
1340 if (!context || !context->rdp)
1343 return (
const char*)nego_get_routing_token(context->rdp->nego, length);
1346BOOL freerdp_io_callback_set_event(rdpContext* context, BOOL set)
1348 WINPR_ASSERT(context);
1349 return rdp_io_callback_set_event(context->rdp, set);
1352const rdpTransportIo* freerdp_get_io_callbacks(rdpContext* context)
1354 WINPR_ASSERT(context);
1355 return rdp_get_io_callbacks(context->rdp);
1358BOOL freerdp_set_io_callbacks(rdpContext* context,
const rdpTransportIo* io_callbacks)
1360 WINPR_ASSERT(context);
1361 return rdp_set_io_callbacks(context->rdp, io_callbacks);
1364BOOL freerdp_set_io_callback_context(rdpContext* context,
void* usercontext)
1366 WINPR_ASSERT(context);
1367 return rdp_set_io_callback_context(context->rdp, usercontext);
1370void* freerdp_get_io_callback_context(rdpContext* context)
1372 WINPR_ASSERT(context);
1373 return rdp_get_io_callback_context(context->rdp);
1376CONNECTION_STATE freerdp_get_state(
const rdpContext* context)
1378 WINPR_ASSERT(context);
1379 return rdp_get_state(context->rdp);
1382const char* freerdp_state_string(CONNECTION_STATE state)
1384 return rdp_state_string(state);
1387BOOL freerdp_is_active_state(
const rdpContext* context)
1389 WINPR_ASSERT(context);
1390 return rdp_is_active_state(context->rdp);
1393BOOL freerdp_channels_from_mcs(rdpSettings* settings,
const rdpContext* context)
1395 WINPR_ASSERT(context);
1396 return rdp_channels_from_mcs(settings, context->rdp);
1399HANDLE freerdp_abort_event(rdpContext* context)
1401 WINPR_ASSERT(context);
1402 return utils_get_abort_event(context->rdp);
1405static void test_mcs_free(rdpMcs* mcs)
1410 rdpTransport* transport = mcs->transport;
1411 rdpContext* context = transport_get_context(transport);
1414 rdpSettings* settings = context->settings;
1418 transport_free(transport);
1423static rdpMcs* test_mcs_new(
void)
1425 rdpTransport* transport = NULL;
1427 rdpContext* context = calloc(1,
sizeof(rdpContext));
1436 context->settings = settings;
1437 transport = transport_new(context);
1440 return mcs_new(transport);
1443 transport_free(transport);
1450BOOL freerdp_is_valid_mcs_create_request(
const BYTE* data,
size_t size)
1454 wStream* s = Stream_StaticConstInit(&sbuffer, data, size);
1456 WINPR_ASSERT(data || (size == 0));
1459 rdpMcs* mcs = test_mcs_new();
1462 BOOL result = mcs_recv_connect_initial(mcs, s);
1467BOOL freerdp_is_valid_mcs_create_response(
const BYTE* data,
size_t size)
1471 wStream* s = Stream_StaticConstInit(&sbuffer, data, size);
1473 WINPR_ASSERT(data || (size == 0));
1476 rdpMcs* mcs = test_mcs_new();
1479 BOOL result = mcs_recv_connect_response(mcs, s);
1484BOOL freerdp_persist_credentials(rdpContext* context)
1488 WINPR_ASSERT(context->rdp);
1489 return utils_persist_credentials(context->rdp->originalSettings, context->rdp->settings);
1492const char* freerdp_disconnect_reason_string(
int reason)
1496 case Disconnect_Ultimatum_domain_disconnected:
1497 return "rn-domain-disconnected";
1498 case Disconnect_Ultimatum_provider_initiated:
1499 return "rn-provider-initiated";
1500 case Disconnect_Ultimatum_token_purged:
1501 return "rn-token-purged";
1502 case Disconnect_Ultimatum_user_requested:
1503 return "rn-user-requested";
1504 case Disconnect_Ultimatum_channel_purged:
1505 return "rn-channel-purged";
1507 return "rn-unknown";
FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.
FREERDP_API rdpSettings * freerdp_settings_new(DWORD flags)
creates a new setting struct
FREERDP_API void freerdp_settings_free(rdpSettings *settings)
Free a settings struct with all data in it.
FREERDP_API BOOL freerdp_settings_set_uint32(rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id, UINT32 param)
Sets a UINT32 settings value.
FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.
FREERDP_API BOOL freerdp_settings_set_bool(rdpSettings *settings, FreeRDP_Settings_Keys_Bool id, BOOL param)
Sets a BOOL settings value.