/** 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; ConnectionResultEventArgs e; /* 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) { if (!connectErrorCode) { connectErrorCode = PREECONNECTERROR; } fprintf(stderr, "%s:%d: freerdp_pre_connect failed\n", __FILE__, __LINE__); goto freerdp_connect_finally; } 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); goto freerdp_connect_finally; } 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) { fprintf(stderr, "freerdp_post_connect failed\n"); if (!connectErrorCode) { connectErrorCode = POSTCONNECTERROR; } 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); if (!update->pcap_rfx) { status = FALSE; goto freerdp_connect_finally; } else { update->play_rfx = TRUE; } while (pcap_has_next_record(update->pcap_rfx)) { pcap_get_next_record_header(update->pcap_rfx, &record); s = StreamPool_Take(rdp->transport->ReceivePool, record.length); record.data = Stream_Buffer(s); pcap_get_next_record_content(update->pcap_rfx, &record); Stream_SetLength(s,record.length); Stream_SetPosition(s, 0); update->BeginPaint(update->context); update_recv_surfcmds(update, Stream_Length(s) , s); update->EndPaint(update->context); Stream_Release(s); StreamPool_Return(rdp->transport->ReceivePool, s); } pcap_close(update->pcap_rfx); update->pcap_rfx = NULL; status = TRUE; goto freerdp_connect_finally; } } if (rdp->errorInfo == ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES) { connectErrorCode = INSUFFICIENTPRIVILEGESERROR; } if (!connectErrorCode) { connectErrorCode = UNDEFINEDCONNECTERROR; } SetEvent(rdp->transport->connectedEvent); freerdp_connect_finally: EventArgsInit(&e, "freerdp"); e.result = status ? 0 : -1; PubSub_OnConnectionResult(instance->context->pubSub, instance->context, &e); return status; }
/** 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; BOOL status = TRUE; rdpSettings* settings; ConnectionResultEventArgs e; /* We always set the return code to 0 before we start the connect sequence*/ connectErrorCode = 0; freerdp_set_last_error(instance->context, FREERDP_ERROR_SUCCESS); rdp = instance->context->rdp; settings = instance->settings; instance->context->codecs = codecs_new(instance->context); IFCALLRET(instance->PreConnect, status, instance); if (settings->KeyboardLayout == KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002) { settings->KeyboardType = 7; settings->KeyboardSubType = 2; settings->KeyboardFunctionKey = 12; } if (!status) { 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 %d", !status); goto freerdp_connect_finally; } 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; } IFCALLRET(instance->PostConnect, status, instance); if (!status || !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); 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); if (!update->pcap_rfx) { status = FALSE; goto freerdp_connect_finally; } else { update->play_rfx = TRUE; } while (pcap_has_next_record(update->pcap_rfx)) { 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); update->BeginPaint(update->context); update_recv_surfcmds(update, Stream_Length(s) , s); update->EndPaint(update->context); Stream_Release(s); } pcap_close(update->pcap_rfx); update->pcap_rfx = NULL; status = TRUE; 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); return status; }