22 #include <freerdp/config.h>
34 #include "transport.h"
35 #include "connection.h"
37 #include <freerdp/buildflags.h>
38 #include "gateway/rpc_fault.h"
40 #include <winpr/assert.h>
42 #include <winpr/crt.h>
43 #include <winpr/string.h>
44 #include <winpr/stream.h>
45 #include <winpr/wtsapi.h>
46 #include <winpr/ssl.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")
65 static 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);
85 static int freerdp_connect_begin(freerdp* instance)
90 rdpSettings* settings = NULL;
91 UINT32 KeyboardLayout = 0;
96 WINPR_ASSERT(instance->context);
99 instance->ConnectionCallbackState = CLIENT_STATE_INITIAL;
100 freerdp_set_last_error_log(instance->context, FREERDP_ERROR_SUCCESS);
101 clearChannelError(instance->context);
102 if (!utils_reset_abort(instance->context->rdp))
105 rdp = instance->context->rdp;
108 settings = instance->context->settings;
109 WINPR_ASSERT(settings);
111 freerdp_channels_register_instance(instance->context->channels, instance);
113 if (!freerdp_settings_set_default_order_support(settings))
116 freerdp_add_signal_cleanup_handler(instance->context, sig_abort_connect);
118 IFCALLRET(instance->PreConnect, status, instance);
119 instance->ConnectionCallbackState = CLIENT_STATE_PRECONNECT_PASSED;
121 freerdp_settings_print_warnings(settings);
123 status = freerdp_settings_enforce_monitor_exists(settings);
126 status = freerdp_settings_check_client_after_preconnect(settings);
129 status = rdp_set_backup_settings(rdp);
131 status = utils_reload_channels(instance->context);
134 KeyboardLayout = freerdp_get_keyboard_default_layout_for_locale(cp);
135 if (KeyboardLayout == 0)
138 switch (KeyboardLayout)
141 case KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002:
144 WINPR_KBD_TYPE_JAPANESE))
158 rdpContext* context = instance->context;
159 WINPR_ASSERT(context);
160 freerdp_set_last_error_if_not(context, FREERDP_ERROR_PRE_CONNECT_FAILED);
162 WLog_Print(context->log, WLOG_ERROR,
"freerdp_pre_connect failed: %s",
163 rdp_client_connection_state_string(instance->ConnectionCallbackState));
167 rc = rdp_client_connect(rdp);
172 rdpContext* context = rdp->context;
173 WINPR_ASSERT(context);
174 WLog_Print(context->log, WLOG_ERROR,
"Authentication only, exit status %" PRId32
"", rc);
181 BOOL freerdp_connect(freerdp* instance)
184 ConnectionResultEventArgs e = { 0 };
185 const int rc = freerdp_connect_begin(instance);
187 UINT status2 = ERROR_INTERNAL_ERROR;
189 WINPR_ASSERT(instance);
190 WINPR_ASSERT(instance->context);
192 rdp = instance->context->rdp;
194 WINPR_ASSERT(rdp->settings);
203 up->pcap_rfx = pcap_open(
210 pointer_cache_register_callbacks(instance->context->update);
211 status = IFCALLRESULT(TRUE, instance->PostConnect, instance);
212 instance->ConnectionCallbackState = CLIENT_STATE_POSTCONNECT_PASSED;
215 status2 = freerdp_channels_post_connect(instance->context->channels, instance);
219 status2 = CHANNEL_RC_OK;
220 if (freerdp_get_last_error(instance->context) == FREERDP_ERROR_CONNECT_TRANSPORT_FAILED)
221 status = freerdp_reconnect(instance);
223 goto freerdp_connect_finally;
226 if (!status || (status2 != CHANNEL_RC_OK) || !update_post_connect(instance->context->update))
228 rdpContext* context = instance->context;
229 WINPR_ASSERT(context);
230 WLog_Print(context->log, WLOG_ERROR,
"freerdp_post_connect failed");
232 freerdp_set_last_error_if_not(context, FREERDP_ERROR_POST_CONNECT_FAILED);
235 goto freerdp_connect_finally;
238 if (rdp->settings->PlayRemoteFx)
242 pcap_record record = { 0 };
244 WINPR_ASSERT(update);
245 update->pcap_rfx = pcap_open(rdp->settings->PlayRemoteFxFile, FALSE);
248 if (!update->pcap_rfx)
249 goto freerdp_connect_finally;
251 update->play_rfx = TRUE;
255 while (pcap_has_next_record(update->pcap_rfx) && status)
257 pcap_get_next_record_header(update->pcap_rfx, &record);
259 s = transport_take_from_pool(rdp->transport, record.length);
263 record.data = Stream_Buffer(s);
264 pcap_get_next_record_content(update->pcap_rfx, &record);
265 Stream_SetLength(s, record.length);
266 Stream_SetPosition(s, 0);
268 if (!update_begin_paint(&update->common))
272 if (update_recv_surfcmds(&update->common, s) < 0)
275 if (!update_end_paint(&update->common))
282 pcap_close(update->pcap_rfx);
283 update->pcap_rfx = NULL;
284 goto freerdp_connect_finally;
287 if (rdp->errorInfo == ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES)
288 freerdp_set_last_error_log(instance->context, FREERDP_ERROR_INSUFFICIENT_PRIVILEGES);
290 transport_set_connected_event(rdp->transport);
292 freerdp_connect_finally:
293 EventArgsInit(&e,
"freerdp");
294 e.result = status ? 0 : -1;
295 PubSub_OnConnectionResult(rdp->pubSub, instance->context, &e);
298 freerdp_disconnect(instance);
303 BOOL freerdp_abort_connect(freerdp* instance)
308 return freerdp_abort_connect_context(instance->context);
311 BOOL freerdp_abort_connect_context(rdpContext* context)
316 freerdp_set_last_error_if_not(context, FREERDP_ERROR_CONNECT_CANCELLED);
318 return utils_abort_connect(context->rdp);
321 #if defined(WITH_FREERDP_DEPRECATED)
322 BOOL freerdp_get_fds(freerdp* instance,
void** rfds,
int* rcount,
void** wfds,
int* wcount)
326 WINPR_ASSERT(instance);
327 WINPR_ASSERT(instance->context);
329 rdp = instance->context->rdp;
332 transport_get_fds(rdp->transport, rfds, rcount);
337 BOOL freerdp_check_fds(freerdp* instance)
345 if (!instance->context)
348 if (!instance->context->rdp)
351 rdp = instance->context->rdp;
352 status = rdp_check_fds(rdp);
356 TerminateEventArgs e;
357 rdpContext* context = instance->context;
358 WINPR_ASSERT(context);
360 WLog_Print(context->log, WLOG_DEBUG,
"rdp_check_fds() - %i", status);
361 EventArgsInit(&e,
"freerdp");
363 PubSub_OnTerminate(rdp->pubSub, context, &e);
370 DWORD freerdp_get_event_handles(rdpContext* context, HANDLE* events, DWORD count)
374 WINPR_ASSERT(context);
375 WINPR_ASSERT(context->rdp);
376 WINPR_ASSERT(events || (count == 0));
378 nCount += transport_get_event_handles(context->rdp->transport, events, count);
383 if (events && (nCount < count + 2))
385 events[nCount++] = freerdp_channels_get_event_handle(context->instance);
386 events[nCount++] = getChannelErrorEventHandle(context);
387 events[nCount++] = utils_get_abort_event(context->rdp);
392 const SSIZE_T rc = freerdp_client_channel_get_registered_event_handles(
393 context->channels, &events[nCount], count - nCount);
396 return nCount + (DWORD)rc;
400 static BOOL freerdp_prevent_session_lock(rdpContext* context)
402 WINPR_ASSERT(context);
403 WINPR_ASSERT(context->input);
407 UINT32 FakeMouseMotionInterval =
409 if (FakeMouseMotionInterval && in->lastInputTimestamp)
411 const time_t now = time(NULL);
412 if (WINPR_ASSERTING_INT_CAST(
size_t, now) - in->lastInputTimestamp >
413 FakeMouseMotionInterval)
415 WLog_Print(context->log, WLOG_DEBUG,
416 "fake mouse move: x=%d y=%d lastInputTimestamp=%" PRIu64
" "
417 "FakeMouseMotionInterval=%" PRIu32,
418 in->lastX, in->lastY, in->lastInputTimestamp, FakeMouseMotionInterval);
420 BOOL status = freerdp_input_send_mouse_event(context->input, PTR_FLAGS_MOVE, in->lastX,
424 if (freerdp_get_last_error(context) == FREERDP_ERROR_SUCCESS)
425 WLog_Print(context->log, WLOG_ERROR,
426 "freerdp_prevent_session_lock() failed - %" PRIi32
"", status);
438 BOOL freerdp_check_event_handles(rdpContext* context)
440 WINPR_ASSERT(context);
442 BOOL status = freerdp_check_fds(context->instance);
446 if (freerdp_get_last_error(context) == FREERDP_ERROR_SUCCESS)
447 WLog_Print(context->log, WLOG_ERROR,
"freerdp_check_fds() failed - %" PRIi32
"",
453 status = freerdp_channels_check_fds(context->channels, context->instance);
457 if (freerdp_get_last_error(context) == FREERDP_ERROR_SUCCESS)
458 WLog_Print(context->log, WLOG_ERROR,
459 "freerdp_channels_check_fds() failed - %" PRIi32
"", status);
464 status = checkChannelErrorEvent(context);
468 if (freerdp_get_last_error(context) == FREERDP_ERROR_SUCCESS)
469 WLog_Print(context->log, WLOG_ERROR,
"checkChannelErrorEvent() failed - %" PRIi32
"",
475 status = freerdp_prevent_session_lock(context);
480 wMessageQueue* freerdp_get_message_queue(freerdp* instance, DWORD
id)
482 wMessageQueue* queue = NULL;
484 WINPR_ASSERT(instance);
486 rdpContext* context = instance->context;
487 WINPR_ASSERT(context);
491 case FREERDP_UPDATE_MESSAGE_QUEUE:
494 queue = update->queue;
498 case FREERDP_INPUT_MESSAGE_QUEUE:
501 queue = input->queue;
511 HANDLE freerdp_get_message_queue_event_handle(freerdp* instance, DWORD
id)
514 wMessageQueue* queue = freerdp_get_message_queue(instance,
id);
517 event = MessageQueue_Event(queue);
522 int freerdp_message_queue_process_message(freerdp* instance, DWORD
id, wMessage* message)
525 rdpContext* context = NULL;
527 WINPR_ASSERT(instance);
529 context = instance->context;
530 WINPR_ASSERT(context);
534 case FREERDP_UPDATE_MESSAGE_QUEUE:
535 status = update_message_queue_process_message(context->update, message);
538 case FREERDP_INPUT_MESSAGE_QUEUE:
539 status = input_message_queue_process_message(context->input, message);
548 int freerdp_message_queue_process_pending_messages(freerdp* instance, DWORD
id)
551 rdpContext* context = NULL;
553 WINPR_ASSERT(instance);
555 context = instance->context;
556 WINPR_ASSERT(context);
560 case FREERDP_UPDATE_MESSAGE_QUEUE:
561 status = update_message_queue_process_pending_messages(context->update);
564 case FREERDP_INPUT_MESSAGE_QUEUE:
565 status = input_message_queue_process_pending_messages(context->input);
574 static BOOL freerdp_send_channel_data(freerdp* instance, UINT16 channelId,
const BYTE* data,
577 WINPR_ASSERT(instance);
578 WINPR_ASSERT(instance->context);
579 WINPR_ASSERT(instance->context->rdp);
580 return rdp_send_channel_data(instance->context->rdp, channelId, data, size);
583 static BOOL freerdp_send_channel_packet(freerdp* instance, UINT16 channelId,
size_t totalSize,
584 UINT32 flags,
const BYTE* data,
size_t chunkSize)
586 WINPR_ASSERT(instance);
587 WINPR_ASSERT(instance->context);
588 WINPR_ASSERT(instance->context->rdp);
589 return rdp_channel_send_packet(instance->context->rdp, channelId, totalSize, flags, data,
593 BOOL freerdp_disconnect(freerdp* instance)
599 if (!instance || !instance->context)
602 rdp = instance->context->rdp;
603 utils_abort_connect(rdp);
605 if (!rdp_client_disconnect(rdp))
608 up = update_cast(rdp->update);
610 update_post_disconnect(rdp->update);
612 IFCALL(instance->PostDisconnect, instance);
616 up->dump_rfx = FALSE;
617 pcap_close(up->pcap_rfx);
621 freerdp_channels_close(instance->context->channels, instance);
623 IFCALL(instance->PostFinalDisconnect, instance);
625 freerdp_del_signal_cleanup_handler(instance->context, sig_abort_connect);
629 BOOL freerdp_disconnect_before_reconnect(freerdp* instance)
631 WINPR_ASSERT(instance);
632 return freerdp_disconnect_before_reconnect_context(instance->context);
635 BOOL freerdp_disconnect_before_reconnect_context(rdpContext* context)
639 WINPR_ASSERT(context);
642 return rdp_client_disconnect_and_clear(rdp);
645 BOOL freerdp_reconnect(freerdp* instance)
649 WINPR_ASSERT(instance);
650 WINPR_ASSERT(instance->context);
652 if (freerdp_get_last_error(instance->context) == FREERDP_ERROR_CONNECT_CANCELLED)
655 rdp = instance->context->rdp;
657 if (!utils_reset_abort(instance->context->rdp))
659 return rdp_client_reconnect(rdp);
662 BOOL freerdp_shall_disconnect(freerdp* instance)
667 return freerdp_shall_disconnect_context(instance->context);
670 BOOL freerdp_shall_disconnect_context(
const rdpContext* context)
675 return utils_abort_event_is_set(context->rdp);
678 BOOL freerdp_focus_required(freerdp* instance)
681 BOOL bRetCode = FALSE;
683 WINPR_ASSERT(instance);
684 WINPR_ASSERT(instance->context);
686 rdp = instance->context->rdp;
689 if (rdp->resendFocus)
692 rdp->resendFocus = FALSE;
698 void freerdp_set_focus(freerdp* instance)
702 WINPR_ASSERT(instance);
703 WINPR_ASSERT(instance->context);
705 rdp = instance->context->rdp;
708 rdp->resendFocus = TRUE;
711 void freerdp_get_version(
int* major,
int* minor,
int* revision)
714 *major = FREERDP_VERSION_MAJOR;
717 *minor = FREERDP_VERSION_MINOR;
719 if (revision != NULL)
720 *revision = FREERDP_VERSION_REVISION;
723 const char* freerdp_get_version_string(
void)
725 return FREERDP_VERSION_FULL;
728 const char* freerdp_get_build_config(
void)
730 WINPR_PRAGMA_DIAG_PUSH
731 WINPR_PRAGMA_DIAG_IGNORED_OVERLENGTH_STRINGS
732 static const char build_config[] =
733 "Build configuration: " FREERDP_BUILD_CONFIG
"\n"
734 "Build type: " FREERDP_BUILD_TYPE
"\n"
735 "CFLAGS: " FREERDP_CFLAGS
"\n"
736 "Compiler: " FREERDP_COMPILER_ID
", " FREERDP_COMPILER_VERSION
"\n"
737 "Target architecture: " FREERDP_TARGET_ARCH
"\n";
738 WINPR_PRAGMA_DIAG_POP
742 const char* freerdp_get_build_revision(
void)
744 return FREERDP_GIT_REVISION;
748 DEFINE_EVENT_ENTRY(WindowStateChange), DEFINE_EVENT_ENTRY(ResizeWindow),
749 DEFINE_EVENT_ENTRY(LocalResizeWindow), DEFINE_EVENT_ENTRY(EmbedWindow),
750 DEFINE_EVENT_ENTRY(PanningChange), DEFINE_EVENT_ENTRY(ZoomingChange),
751 DEFINE_EVENT_ENTRY(ErrorInfo), DEFINE_EVENT_ENTRY(Terminate),
752 DEFINE_EVENT_ENTRY(ConnectionResult), DEFINE_EVENT_ENTRY(ChannelConnected),
753 DEFINE_EVENT_ENTRY(ChannelDisconnected), DEFINE_EVENT_ENTRY(MouseEvent),
754 DEFINE_EVENT_ENTRY(Activated), DEFINE_EVENT_ENTRY(Timer),
755 DEFINE_EVENT_ENTRY(GraphicsReset)
768 BOOL freerdp_context_new(freerdp* instance)
770 return freerdp_context_new_ex(instance, NULL);
773 BOOL freerdp_context_new_ex(freerdp* instance, rdpSettings* settings)
776 rdpContext* context = NULL;
779 WINPR_ASSERT(instance);
781 instance->context = context = (rdpContext*)calloc(1, instance->ContextSize);
786 context->log = WLog_Get(TAG);
791 context->settings = settings;
792 context->instance = instance;
793 context->ServerMode = FALSE;
794 context->disconnectUltimatum = 0;
796 context->metrics = metrics_new(context);
798 if (!context->metrics)
801 rdp = rdp_new(context);
807 context->pubSub = rdp->pubSub;
809 if (!context->pubSub)
812 PubSub_AddEventTypes(rdp->pubSub, FreeRDP_Events, ARRAYSIZE(FreeRDP_Events));
814 #if defined(WITH_FREERDP_DEPRECATED)
815 instance->input = rdp->input;
816 instance->update = rdp->update;
817 instance->settings = rdp->settings;
818 instance->autodetect = rdp->autodetect;
821 instance->heartbeat = rdp->heartbeat;
822 context->graphics = graphics_new(context);
824 if (!context->graphics)
827 context->input = rdp->input;
828 context->update = rdp->update;
829 context->settings = rdp->settings;
830 context->autodetect = rdp->autodetect;
832 if (!(context->errorDescription = calloc(1, 500)))
834 WLog_Print(context->log, WLOG_ERROR,
"calloc failed!");
838 if (!(context->channelErrorEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
840 WLog_Print(context->log, WLOG_ERROR,
"CreateEvent failed!");
844 update_register_client_callbacks(rdp->update);
846 if (!(context->channels = freerdp_channels_new(instance)))
849 context->dump = stream_dump_new();
853 IFCALLRET(instance->ContextNew, ret, instance, context);
859 freerdp_context_free(instance);
863 BOOL freerdp_context_reset(freerdp* instance)
868 WINPR_ASSERT(instance->context);
869 rdpRdp* rdp = instance->context->rdp;
871 return rdp_reset_runtime_settings(rdp);
882 void freerdp_context_free(freerdp* instance)
884 rdpContext* ctx = NULL;
889 if (!instance->context)
892 ctx = instance->context;
894 IFCALL(instance->ContextFree, instance, ctx);
897 ctx->settings = NULL;
899 graphics_free(ctx->graphics);
900 ctx->graphics = NULL;
902 metrics_free(ctx->metrics);
905 if (ctx->channelErrorEvent)
906 (void)CloseHandle(ctx->channelErrorEvent);
907 ctx->channelErrorEvent = NULL;
909 free(ctx->errorDescription);
910 ctx->errorDescription = NULL;
912 freerdp_channels_free(ctx->channels);
913 ctx->channels = NULL;
915 freerdp_client_codecs_free(ctx->codecs);
918 stream_dump_free(ctx->dump);
923 ctx->settings = NULL;
924 ctx->autodetect = NULL;
927 instance->context = NULL;
928 #if defined(WITH_FREERDP_DEPRECATED)
929 instance->input = NULL;
930 instance->update = NULL;
931 instance->settings = NULL;
932 instance->autodetect = NULL;
934 instance->heartbeat = NULL;
937 int freerdp_get_disconnect_ultimatum(rdpContext* context)
939 WINPR_ASSERT(context);
940 return context->disconnectUltimatum;
943 UINT32 freerdp_error_info(freerdp* instance)
945 WINPR_ASSERT(instance);
946 WINPR_ASSERT(instance->context);
947 WINPR_ASSERT(instance->context->rdp);
948 return instance->context->rdp->errorInfo;
951 void freerdp_set_error_info(rdpRdp* rdp, UINT32 error)
956 rdp_set_error_info(rdp, error);
959 BOOL freerdp_send_error_info(rdpRdp* rdp)
964 return rdp_send_error_info(rdp);
967 UINT32 freerdp_get_last_error(rdpContext* context)
969 WINPR_ASSERT(context);
970 return context->LastError;
973 const char* freerdp_get_last_error_name(UINT32 code)
975 const char* name = NULL;
976 const UINT32 cls = GET_FREERDP_ERROR_CLASS(code);
977 const UINT32 type = GET_FREERDP_ERROR_TYPE(code);
981 case FREERDP_ERROR_ERRBASE_CLASS:
982 name = freerdp_get_error_base_name(type);
985 case FREERDP_ERROR_ERRINFO_CLASS:
986 name = freerdp_get_error_info_name(type);
989 case FREERDP_ERROR_CONNECT_CLASS:
990 name = freerdp_get_error_connect_name(type);
994 name = rpc_error_to_string(code);
1001 const char* freerdp_get_last_error_string(UINT32 code)
1003 const char*
string = NULL;
1004 const UINT32 cls = GET_FREERDP_ERROR_CLASS(code);
1005 const UINT32 type = GET_FREERDP_ERROR_TYPE(code);
1009 case FREERDP_ERROR_ERRBASE_CLASS:
1010 string = freerdp_get_error_base_string(type);
1013 case FREERDP_ERROR_ERRINFO_CLASS:
1014 string = freerdp_get_error_info_string(type);
1017 case FREERDP_ERROR_CONNECT_CLASS:
1018 string = freerdp_get_error_connect_string(type);
1022 string = rpc_error_to_string(code);
1029 const char* freerdp_get_last_error_category(UINT32 code)
1031 const char*
string = NULL;
1032 const UINT32 cls = GET_FREERDP_ERROR_CLASS(code);
1033 const UINT32 type = GET_FREERDP_ERROR_TYPE(code);
1037 case FREERDP_ERROR_ERRBASE_CLASS:
1038 string = freerdp_get_error_base_category(type);
1041 case FREERDP_ERROR_ERRINFO_CLASS:
1042 string = freerdp_get_error_info_category(type);
1045 case FREERDP_ERROR_CONNECT_CLASS:
1046 string = freerdp_get_error_connect_category(type);
1050 string = rpc_error_to_category(code);
1057 void freerdp_set_last_error_ex(rdpContext* context, UINT32 lastError,
const char* fkt,
1058 const char* file,
int line)
1060 WINPR_ASSERT(context);
1061 WINPR_ASSERT(line >= 0);
1065 if (WLog_IsLevelActive(context->log, WLOG_ERROR))
1067 WLog_PrintMessage(context->log, WLOG_MESSAGE_TEXT, WLOG_ERROR, (
size_t)line, file, fkt,
1068 "%s [0x%08" PRIX32
"]", freerdp_get_last_error_name(lastError),
1073 if (lastError == FREERDP_ERROR_SUCCESS)
1075 if (WLog_IsLevelActive(context->log, WLOG_DEBUG))
1076 WLog_PrintMessage(context->log, WLOG_MESSAGE_TEXT, WLOG_DEBUG, (
size_t)line, file, fkt,
1077 "resetting error state");
1079 else if (context->LastError != FREERDP_ERROR_SUCCESS)
1081 if (WLog_IsLevelActive(context->log, WLOG_ERROR))
1083 WLog_PrintMessage(context->log, WLOG_MESSAGE_TEXT, WLOG_ERROR, (
size_t)line, file, fkt,
1084 "TODO: Trying to set error code %s, but %s already set!",
1085 freerdp_get_last_error_name(lastError),
1086 freerdp_get_last_error_name(context->LastError));
1089 context->LastError = lastError;
1092 const char* freerdp_get_logon_error_info_type_ex(UINT32 type,
char* buffer,
size_t size)
1094 const char* str = freerdp_get_logon_error_info_type(type);
1095 (void)_snprintf(buffer, size,
"%s(0x%04" PRIx32
")", str, type);
1099 const char* freerdp_get_logon_error_info_type(UINT32 type)
1103 case LOGON_MSG_DISCONNECT_REFUSED:
1104 return "LOGON_MSG_DISCONNECT_REFUSED";
1106 case LOGON_MSG_NO_PERMISSION:
1107 return "LOGON_MSG_NO_PERMISSION";
1109 case LOGON_MSG_BUMP_OPTIONS:
1110 return "LOGON_MSG_BUMP_OPTIONS";
1112 case LOGON_MSG_RECONNECT_OPTIONS:
1113 return "LOGON_MSG_RECONNECT_OPTIONS";
1115 case LOGON_MSG_SESSION_TERMINATE:
1116 return "LOGON_MSG_SESSION_TERMINATE";
1118 case LOGON_MSG_SESSION_CONTINUE:
1119 return "LOGON_MSG_SESSION_CONTINUE";
1126 const char* freerdp_get_logon_error_info_data(UINT32 data)
1130 case LOGON_FAILED_BAD_PASSWORD:
1131 return "LOGON_FAILED_BAD_PASSWORD";
1133 case LOGON_FAILED_UPDATE_PASSWORD:
1134 return "LOGON_FAILED_UPDATE_PASSWORD";
1136 case LOGON_FAILED_OTHER:
1137 return "LOGON_FAILED_OTHER";
1140 return "LOGON_WARNING";
1143 return "SESSION_ID";
1147 const char* freerdp_get_logon_error_info_data_ex(UINT32 data,
char* buffer,
size_t size)
1149 const char* str = freerdp_get_logon_error_info_data(data);
1150 (void)_snprintf(buffer, size,
"%s(0x%04" PRIx32
")", str, data);
1157 freerdp* freerdp_new(
void)
1159 freerdp* instance = NULL;
1160 instance = (freerdp*)calloc(1,
sizeof(freerdp));
1165 instance->ContextSize =
sizeof(rdpContext);
1166 instance->SendChannelData = freerdp_send_channel_data;
1167 instance->SendChannelPacket = freerdp_send_channel_packet;
1168 instance->ReceiveChannelData = freerdp_channels_data;
1176 void freerdp_free(freerdp* instance)
1181 ULONG freerdp_get_transport_sent(rdpContext* context, BOOL resetCount)
1183 WINPR_ASSERT(context);
1184 WINPR_ASSERT(context->rdp);
1185 return transport_get_bytes_sent(context->rdp->transport, resetCount);
1188 BOOL freerdp_nla_impersonate(rdpContext* context)
1198 if (!context->rdp->transport)
1201 nla = transport_get_nla(context->rdp->transport);
1202 return nla_impersonate(nla);
1205 BOOL freerdp_nla_revert_to_self(rdpContext* context)
1215 if (!context->rdp->transport)
1218 nla = transport_get_nla(context->rdp->transport);
1219 return nla_revert_to_self(nla);
1222 UINT32 freerdp_get_nla_sspi_error(rdpContext* context)
1224 WINPR_ASSERT(context);
1225 WINPR_ASSERT(context->rdp);
1226 WINPR_ASSERT(context->rdp->transport);
1228 rdpNla* nla = transport_get_nla(context->rdp->transport);
1230 return (UINT32)nla_get_sspi_error(nla);
1233 BOOL freerdp_nla_encrypt(rdpContext* context,
const SecBuffer* inBuffer,
SecBuffer* outBuffer)
1235 WINPR_ASSERT(context);
1236 WINPR_ASSERT(context->rdp);
1238 rdpNla* nla = context->rdp->nla;
1239 return nla_encrypt(nla, inBuffer, outBuffer);
1242 BOOL freerdp_nla_decrypt(rdpContext* context,
const SecBuffer* inBuffer,
SecBuffer* outBuffer)
1244 WINPR_ASSERT(context);
1245 WINPR_ASSERT(context->rdp);
1247 rdpNla* nla = context->rdp->nla;
1248 return nla_decrypt(nla, inBuffer, outBuffer);
1251 SECURITY_STATUS freerdp_nla_QueryContextAttributes(rdpContext* context, DWORD ulAttr, PVOID pBuffer)
1253 WINPR_ASSERT(context);
1254 WINPR_ASSERT(context->rdp);
1256 return nla_QueryContextAttributes(context->rdp->nla, ulAttr, pBuffer);
1259 HANDLE getChannelErrorEventHandle(rdpContext* context)
1261 WINPR_ASSERT(context);
1262 return context->channelErrorEvent;
1265 BOOL checkChannelErrorEvent(rdpContext* context)
1267 WINPR_ASSERT(context);
1269 if (WaitForSingleObject(context->channelErrorEvent, 0) == WAIT_OBJECT_0)
1271 WLog_Print(context->log, WLOG_ERROR,
"%s. Error was %" PRIu32
"", context->errorDescription,
1272 context->channelErrorNum);
1284 UINT getChannelError(rdpContext* context)
1286 WINPR_ASSERT(context);
1287 return context->channelErrorNum;
1290 const char* getChannelErrorDescription(rdpContext* context)
1292 WINPR_ASSERT(context);
1293 return context->errorDescription;
1296 void clearChannelError(rdpContext* context)
1298 WINPR_ASSERT(context);
1299 context->channelErrorNum = 0;
1300 memset(context->errorDescription, 0, 500);
1301 (void)ResetEvent(context->channelErrorEvent);
1304 WINPR_ATTR_FORMAT_ARG(3, 4)
1305 void setChannelError(rdpContext* context, UINT errorNum, WINPR_FORMAT_ARG const
char* format, ...)
1308 va_start(ap, format);
1310 WINPR_ASSERT(context);
1312 context->channelErrorNum = errorNum;
1313 (void)vsnprintf(context->errorDescription, 499, format, ap);
1315 (void)SetEvent(context->channelErrorEvent);
1318 const char* freerdp_nego_get_routing_token(rdpContext* context, DWORD* length)
1320 if (!context || !context->rdp)
1323 return (
const char*)nego_get_routing_token(context->rdp->nego, length);
1326 BOOL freerdp_io_callback_set_event(rdpContext* context, BOOL set)
1328 WINPR_ASSERT(context);
1329 return rdp_io_callback_set_event(context->rdp, set);
1332 const rdpTransportIo* freerdp_get_io_callbacks(rdpContext* context)
1334 WINPR_ASSERT(context);
1335 return rdp_get_io_callbacks(context->rdp);
1338 BOOL freerdp_set_io_callbacks(rdpContext* context,
const rdpTransportIo* io_callbacks)
1340 WINPR_ASSERT(context);
1341 return rdp_set_io_callbacks(context->rdp, io_callbacks);
1344 BOOL freerdp_set_io_callback_context(rdpContext* context,
void* usercontext)
1346 WINPR_ASSERT(context);
1347 return rdp_set_io_callback_context(context->rdp, usercontext);
1350 void* freerdp_get_io_callback_context(rdpContext* context)
1352 WINPR_ASSERT(context);
1353 return rdp_get_io_callback_context(context->rdp);
1356 CONNECTION_STATE freerdp_get_state(
const rdpContext* context)
1358 WINPR_ASSERT(context);
1359 return rdp_get_state(context->rdp);
1362 const char* freerdp_state_string(CONNECTION_STATE state)
1364 return rdp_state_string(state);
1367 BOOL freerdp_is_active_state(
const rdpContext* context)
1369 WINPR_ASSERT(context);
1370 return rdp_is_active_state(context->rdp);
1373 BOOL freerdp_channels_from_mcs(rdpSettings* settings,
const rdpContext* context)
1375 WINPR_ASSERT(context);
1376 return rdp_channels_from_mcs(settings, context->rdp);
1379 HANDLE freerdp_abort_event(rdpContext* context)
1381 WINPR_ASSERT(context);
1382 return utils_get_abort_event(context->rdp);
1385 static void test_mcs_free(rdpMcs* mcs)
1390 rdpTransport* transport = mcs->transport;
1391 rdpContext* context = transport_get_context(transport);
1394 rdpSettings* settings = context->settings;
1398 transport_free(transport);
1403 static rdpMcs* test_mcs_new(
void)
1405 rdpTransport* transport = NULL;
1407 rdpContext* context = calloc(1,
sizeof(rdpContext));
1416 context->settings = settings;
1417 transport = transport_new(context);
1420 return mcs_new(transport);
1423 transport_free(transport);
1430 BOOL freerdp_is_valid_mcs_create_request(
const BYTE* data,
size_t size)
1434 wStream* s = Stream_StaticConstInit(&sbuffer, data, size);
1436 WINPR_ASSERT(data || (size == 0));
1439 rdpMcs* mcs = test_mcs_new();
1442 BOOL result = mcs_recv_connect_initial(mcs, s);
1447 BOOL freerdp_is_valid_mcs_create_response(
const BYTE* data,
size_t size)
1451 wStream* s = Stream_StaticConstInit(&sbuffer, data, size);
1453 WINPR_ASSERT(data || (size == 0));
1456 rdpMcs* mcs = test_mcs_new();
1459 BOOL result = mcs_recv_connect_response(mcs, s);
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 const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.
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 BOOL freerdp_settings_set_bool(rdpSettings *settings, FreeRDP_Settings_Keys_Bool id, BOOL param)
Sets a BOOL settings value.