/** Creates a new connection based on the settings found in the "instance" parameter * It will use the callbacks registered on the structure to process the pre/post connect operations * that the caller requires. * @see struct rdp_freerdp in freerdp.h * * @param instance - pointer to a rdp_freerdp structure that contains base information to establish the connection. * On return, this function will be initialized with the new connection's settings. * * @return TRUE if successful. FALSE otherwise. * */ BOOL freerdp_connect(freerdp* instance) { UINT status2 = CHANNEL_RC_OK; rdpRdp* rdp; BOOL status = TRUE; rdpSettings* settings; ConnectionResultEventArgs e; if (!instance) return FALSE; /* We always set the return code to 0 before we start the connect sequence*/ connectErrorCode = 0; instance->context->LastError = FREERDP_ERROR_SUCCESS; clearChannelError(instance->context); ResetEvent(instance->context->abortEvent); rdp = instance->context->rdp; settings = instance->settings; instance->context->codecs = codecs_new(instance->context); IFCALLRET(instance->PreConnect, status, instance); if (status) status2 = freerdp_channels_pre_connect(instance->context->channels, instance); if (settings->KeyboardLayout == KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002) { settings->KeyboardType = 7; settings->KeyboardSubType = 2; settings->KeyboardFunctionKey = 12; } if (!status || (status2 != CHANNEL_RC_OK)) { if (!freerdp_get_last_error(rdp->context)) freerdp_set_last_error(instance->context, FREERDP_ERROR_PRE_CONNECT_FAILED); WLog_ERR(TAG, "freerdp_pre_connect failed"); goto freerdp_connect_finally; } status = rdp_client_connect(rdp); /* --authonly tests the connection without a UI */ if (instance->settings->AuthenticationOnly) { WLog_ERR(TAG, "Authentication only, exit status %"PRId32"", !status); goto freerdp_connect_finally; } if (!status) goto freerdp_connect_finally; if (status) { UINT status2; if (instance->settings->DumpRemoteFx) { instance->update->pcap_rfx = pcap_open(instance->settings->DumpRemoteFxFile, TRUE); if (instance->update->pcap_rfx) instance->update->dump_rfx = TRUE; } IFCALLRET(instance->PostConnect, status, instance); if (status) status2 = freerdp_channels_post_connect(instance->context->channels, instance); if (!status || (status2 != CHANNEL_RC_OK) || !update_post_connect(instance->update)) { WLog_ERR(TAG, "freerdp_post_connect failed"); if (!freerdp_get_last_error(rdp->context)) freerdp_set_last_error(instance->context, FREERDP_ERROR_POST_CONNECT_FAILED); status = FALSE; goto freerdp_connect_finally; } if (instance->settings->PlayRemoteFx) { wStream* s; rdpUpdate* update; pcap_record record; update = instance->update; update->pcap_rfx = pcap_open(settings->PlayRemoteFxFile, FALSE); status = FALSE; if (!update->pcap_rfx) goto freerdp_connect_finally; else update->play_rfx = TRUE; status = TRUE; while (pcap_has_next_record(update->pcap_rfx) && status) { pcap_get_next_record_header(update->pcap_rfx, &record); if (!(s = StreamPool_Take(rdp->transport->ReceivePool, record.length))) break; record.data = Stream_Buffer(s); pcap_get_next_record_content(update->pcap_rfx, &record); Stream_SetLength(s, record.length); Stream_SetPosition(s, 0); if (!update->BeginPaint(update->context)) status = FALSE; else if (update_recv_surfcmds(update, s) < 0) status = FALSE; else if (!update->EndPaint(update->context)) status = FALSE; Stream_Release(s); } pcap_close(update->pcap_rfx); update->pcap_rfx = NULL; goto freerdp_connect_finally; } } if (rdp->errorInfo == ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES) freerdp_set_last_error(instance->context, FREERDP_ERROR_INSUFFICIENT_PRIVILEGES); SetEvent(rdp->transport->connectedEvent); freerdp_connect_finally: EventArgsInit(&e, "freerdp"); e.result = status ? 0 : -1; PubSub_OnConnectionResult(instance->context->pubSub, instance->context, &e); if (!status) freerdp_disconnect(instance); return status; }
BOOL pcap_get_next_record(rdpPcap* pcap, pcap_record* record) { return pcap_has_next_record(pcap) && pcap_read_record(pcap, record); }
/** Creates a new connection based on the settings found in the "instance" parameter * It will use the callbacks registered on the structure to process the pre/post connect operations * that the caller requires. * @see struct rdp_freerdp in freerdp.h * * @param instance - pointer to a rdp_freerdp structure that contains base information to establish the connection. * On return, this function will be initialized with the new connection's settings. * * @return TRUE if successful. FALSE otherwise. * */ BOOL freerdp_connect(freerdp* instance) { rdpRdp* rdp; rdpSettings* settings; BOOL status = FALSE; /* We always set the return code to 0 before we start the connect sequence*/ connectErrorCode = 0; rdp = instance->context->rdp; settings = instance->settings; IFCALLRET(instance->PreConnect, status, instance); if (settings->KeyboardLayout == KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002) { settings->KeyboardType = 7; settings->KeyboardSubType = 2; settings->KeyboardFunctionKey = 12; } extension_load_and_init_plugins(rdp->extension); extension_pre_connect(rdp->extension); if (status != TRUE) { if (!connectErrorCode) { connectErrorCode = PREECONNECTERROR; } fprintf(stderr, "%s:%d: freerdp_pre_connect failed\n", __FILE__, __LINE__); return FALSE; } status = rdp_client_connect(rdp); /* --authonly tests the connection without a UI */ if (instance->settings->AuthenticationOnly) { fprintf(stderr, "%s:%d: Authentication only, exit status %d\n", __FILE__, __LINE__, !status); return status; } if (status) { if (instance->settings->DumpRemoteFx) { instance->update->pcap_rfx = pcap_open(instance->settings->DumpRemoteFxFile, TRUE); if (instance->update->pcap_rfx) instance->update->dump_rfx = TRUE; } extension_post_connect(rdp->extension); IFCALLRET(instance->PostConnect, status, instance); update_post_connect(instance->update); if (status != TRUE) { fprintf(stderr, "freerdp_post_connect failed\n"); if (!connectErrorCode) { connectErrorCode = POSTCONNECTERROR; } return FALSE; } if (instance->settings->PlayRemoteFx) { wStream* s; rdpUpdate* update; pcap_record record; s = stream_new(1024); instance->update->pcap_rfx = pcap_open(instance->settings->PlayRemoteFxFile, FALSE); if (instance->update->pcap_rfx) instance->update->play_rfx = TRUE; update = instance->update; while (instance->update->play_rfx && pcap_has_next_record(update->pcap_rfx)) { pcap_get_next_record_header(update->pcap_rfx, &record); s->buffer = (BYTE*) realloc(s->buffer, record.length); record.data = s->buffer; s->capacity = record.length; pcap_get_next_record_content(update->pcap_rfx, &record); stream_set_pos(s, 0); update->BeginPaint(update->context); update_recv_surfcmds(update, s->capacity, s); update->EndPaint(update->context); } free(s->buffer); return TRUE; } } if (!connectErrorCode) { connectErrorCode = UNDEFINEDCONNECTERROR; } return status; }
boolean freerdp_connect(freerdp* instance) { rdpRdp* rdp; boolean status = false; rdp = instance->context->rdp; IFCALLRET(instance->PreConnect, status, instance); if (status != true) { printf("freerdp_pre_connect failed\n"); return false; } rdp->extension = extension_new(instance); extension_pre_connect(rdp->extension); status = rdp_client_connect(rdp); if (status) { if (instance->settings->dump_rfx) { instance->update->pcap_rfx = pcap_open(instance->settings->dump_rfx_file, true); if (instance->update->pcap_rfx) instance->update->dump_rfx = true; } extension_post_connect(rdp->extension); IFCALLRET(instance->PostConnect, status, instance); if (status != true) { printf("freerdp_post_connect failed\n"); return false; } if (instance->settings->play_rfx) { STREAM* s; rdpUpdate* update; pcap_record record; s = stream_new(1024); instance->update->pcap_rfx = pcap_open(instance->settings->play_rfx_file, false); if (instance->update->pcap_rfx) instance->update->play_rfx = true; update = instance->update; while (instance->update->play_rfx && pcap_has_next_record(update->pcap_rfx)) { pcap_get_next_record_header(update->pcap_rfx, &record); s->data = xrealloc(s->data, record.length); record.data = s->data; s->size = record.length; pcap_get_next_record_content(update->pcap_rfx, &record); stream_set_pos(s, 0); update->BeginPaint(update->context); update_recv_surfcmds(update, s->size, s); update->EndPaint(update->context); } xfree(s->data); return true; } } return status; }