static void update_send_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker) { wStream* s; rdpRdp* rdp = context->rdp; s = fastpath_update_pdu_init(rdp->fastpath); update_write_surfcmd_frame_marker(s, surface_frame_marker->frameAction, surface_frame_marker->frameId); fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, s); Stream_Release(s); }
static void update_send_synchronize(rdpContext* context) { wStream* s; rdpRdp* rdp = context->rdp; s = fastpath_update_pdu_init(rdp->fastpath); Stream_Zero(s, 2); /* pad2Octets (2 bytes) */ fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SYNCHRONIZE, s); Stream_Release(s); }
int dvcman_receive_channel_data(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId, wStream* data) { int status = 0; DVCMAN_CHANNEL* channel; UINT32 dataSize = Stream_GetRemainingLength(data); channel = (DVCMAN_CHANNEL*) dvcman_find_channel_by_id(pChannelMgr, ChannelId); if (!channel) { DEBUG_WARN("ChannelId %d not found!", ChannelId); return 1; } if (channel->dvc_data) { /* Fragmented data */ if (Stream_GetPosition(channel->dvc_data) + dataSize > (UINT32) Stream_Capacity(channel->dvc_data)) { DEBUG_WARN("data exceeding declared length!"); Stream_Release(channel->dvc_data); channel->dvc_data = NULL; return 1; } Stream_Write(channel->dvc_data, Stream_Pointer(data), dataSize); if (((size_t) Stream_GetPosition(channel->dvc_data)) >= Stream_Capacity(channel->dvc_data)) { Stream_SealLength(channel->dvc_data); Stream_SetPosition(channel->dvc_data, 0); status = channel->channel_callback->OnDataReceived(channel->channel_callback, channel->dvc_data); Stream_Release(channel->dvc_data); channel->dvc_data = NULL; } } else { status = channel->channel_callback->OnDataReceived(channel->channel_callback, data); } return status; }
static void update_send_pointer_color(rdpContext* context, POINTER_COLOR_UPDATE* pointer_color) { wStream* s; rdpRdp* rdp = context->rdp; s = fastpath_update_pdu_init(rdp->fastpath); update_write_pointer_color(s, pointer_color); fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_COLOR, s); Stream_Release(s); }
static void update_send_pointer_cached(rdpContext* context, POINTER_CACHED_UPDATE* pointer_cached) { wStream* s; rdpRdp* rdp = context->rdp; s = fastpath_update_pdu_init(rdp->fastpath); Stream_Write_UINT16(s, pointer_cached->cacheIndex); /* cacheIndex (2 bytes) */ fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_CACHED, s); Stream_Release(s); }
int transport_check_fds(rdpTransport* transport) { int status; int recv_status; wStream* received; HANDLE event; if (!transport) return -1; while(!freerdp_shall_disconnect(transport->context->instance)) { /** * Note: transport_read_pdu tries to read one PDU from * the transport layer. * The ReceiveBuffer might have a position > 0 in case of a non blocking * transport. If transport_read_pdu returns 0 the pdu couldn't be read at * this point. * Note that transport->ReceiveBuffer is replaced after each iteration * of this loop with a fresh stream instance from a pool. */ if ((status = transport_read_pdu(transport, transport->ReceiveBuffer)) <= 0) { if (status < 0) WLog_DBG(TAG, "transport_check_fds: transport_read_pdu() - %i", status); return status; } received = transport->ReceiveBuffer; if (!(transport->ReceiveBuffer = StreamPool_Take(transport->ReceivePool, 0))) return -1; /** * status: * -1: error * 0: success * 1: redirection */ recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra); Stream_Release(received); /* session redirection or activation */ if (recv_status == 1 || recv_status == 2) { return recv_status; } if (recv_status < 0) { WLog_ERR(TAG, "transport_check_fds: transport->ReceiveCallback() - %i", recv_status); return -1; } } return 0; }
BOOL autodetect_send_bandwidth_measure_payload(rdpContext* context, UINT16 payloadLength, UINT16 sequenceNumber) { wStream* s; UCHAR* buffer = NULL; BOOL bResult = FALSE; s = rdp_message_channel_pdu_init(context->rdp); if (!s) return FALSE; WLog_VRB(AUTODETECT_TAG, "sending Bandwidth Measure Payload PDU -> payloadLength=%"PRIu16"", payloadLength); /* 4-bytes aligned */ payloadLength &= ~3; if (!Stream_EnsureRemainingCapacity(s, 8 + payloadLength)) { Stream_Release(s); return FALSE; } Stream_Write_UINT8(s, 0x08); /* headerLength (1 byte) */ Stream_Write_UINT8(s, TYPE_ID_AUTODETECT_REQUEST); /* headerTypeId (1 byte) */ Stream_Write_UINT16(s, sequenceNumber); /* sequenceNumber (2 bytes) */ Stream_Write_UINT16(s, RDP_BW_PAYLOAD_REQUEST_TYPE); /* requestType (2 bytes) */ Stream_Write_UINT16(s, payloadLength); /* payloadLength (2 bytes) */ /* Random data (better measurement in case the line is compressed) */ buffer = (UCHAR*)malloc(payloadLength); if (NULL == buffer) { Stream_Release(s); return FALSE; } winpr_RAND(buffer, payloadLength); Stream_Write(s, buffer, payloadLength); bResult = rdp_send_message_channel_pdu(context->rdp, s, SEC_AUTODETECT_REQ); free(buffer); return bResult; }
static void update_send_pointer_new(rdpContext* context, POINTER_NEW_UPDATE* pointer_new) { wStream* s; rdpRdp* rdp = context->rdp; s = fastpath_update_pdu_init(rdp->fastpath); Stream_Write_UINT16(s, pointer_new->xorBpp); /* xorBpp (2 bytes) */ update_write_pointer_color(s, &pointer_new->colorPtrAttr); fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_POINTER, s); Stream_Release(s); }
static void update_send_surface_command(rdpContext* context, wStream* s) { wStream* update; rdpRdp* rdp = context->rdp; update = fastpath_update_pdu_init(rdp->fastpath); Stream_EnsureRemainingCapacity(update, Stream_GetPosition(s)); Stream_Write(update, Stream_Buffer(s), Stream_GetPosition(s)); fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, update); Stream_Release(update); }
void transport_free(rdpTransport* transport) { if (transport) { if (transport->async) { if (transport->stopEvent) { SetEvent(transport->stopEvent); WaitForSingleObject(transport->thread, INFINITE); CloseHandle(transport->thread); CloseHandle(transport->stopEvent); transport->thread = NULL; transport->stopEvent = NULL; } } if (transport->ReceiveBuffer) Stream_Release(transport->ReceiveBuffer); StreamPool_Free(transport->ReceivePool); CloseHandle(transport->ReceiveEvent); CloseHandle(transport->connectedEvent); if (transport->TlsIn) tls_free(transport->TlsIn); if (transport->TlsOut != transport->TlsIn) tls_free(transport->TlsOut); transport->TlsIn = NULL; transport->TlsOut = NULL; if (transport->TcpIn) tcp_free(transport->TcpIn); if (transport->TcpOut != transport->TcpIn) tcp_free(transport->TcpOut); transport->TcpIn = NULL; transport->TcpOut = NULL; tsg_free(transport->tsg); transport->tsg = NULL; DeleteCriticalSection(&(transport->ReadLock)); DeleteCriticalSection(&(transport->WriteLock)); free(transport); } }
static void update_send_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_command) { wStream* s; rdpRdp* rdp = context->rdp; s = fastpath_update_pdu_init(rdp->fastpath); Stream_EnsureRemainingCapacity(s, SURFCMD_SURFACE_BITS_HEADER_LENGTH + (int) surface_bits_command->bitmapDataLength); update_write_surfcmd_surface_bits_header(s, surface_bits_command); Stream_Write(s, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, s); Stream_Release(s); }
wStream* transport_send_stream_init(rdpTransport* transport, int size) { wStream* s; if (!(s = StreamPool_Take(transport->ReceivePool, size))) return NULL; if (!Stream_EnsureCapacity(s, size)) { Stream_Release(s); return NULL; } Stream_SetPosition(s, 0); return s; }
static void update_send_frame_acknowledge(rdpContext* context, UINT32 frameId) { wStream* s; rdpRdp* rdp = context->rdp; if (rdp->settings->ReceivedCapabilities[CAPSET_TYPE_FRAME_ACKNOWLEDGE]) { s = rdp_data_pdu_init(rdp); Stream_Write_UINT32(s, frameId); rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FRAME_ACKNOWLEDGE, rdp->mcs->user_id); Stream_Release(s); } }
static void update_send_suppress_output(rdpContext* context, BYTE allow, RECTANGLE_16* area) { wStream* s; rdpRdp* rdp = context->rdp; if (rdp->settings->SuppressOutput) { s = rdp_data_pdu_init(rdp); update_write_suppress_output(s, allow, area); rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SUPPRESS_OUTPUT, rdp->mcs->user_id); Stream_Release(s); } }
static void update_send_refresh_rect(rdpContext* context, BYTE count, RECTANGLE_16* areas) { wStream* s; rdpRdp* rdp = context->rdp; if (rdp->settings->RefreshRect) { s = rdp_data_pdu_init(rdp); update_write_refresh_rect(s, count, areas); rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_REFRESH_RECT, rdp->mcs->user_id); Stream_Release(s); } }
BOOL rdp_send_deactivate_all(rdpRdp* rdp) { wStream* s = rdp_send_stream_pdu_init(rdp); BOOL status; if (!s) return FALSE; Stream_Write_UINT32(s, rdp->settings->ShareId); /* shareId (4 bytes) */ Stream_Write_UINT16(s, 1); /* lengthSourceDescriptor (2 bytes) */ Stream_Write_UINT8(s, 0); /* sourceDescriptor (should be 0x00) */ status = rdp_send_pdu(rdp, s, PDU_TYPE_DEACTIVATE_ALL, rdp->mcs->userId); Stream_Release(s); return status; }
static void update_send_pointer_system(rdpContext* context, POINTER_SYSTEM_UPDATE* pointer_system) { wStream* s; BYTE updateCode; rdpRdp* rdp = context->rdp; s = fastpath_update_pdu_init(rdp->fastpath); if (pointer_system->type == SYSPTR_NULL) updateCode = FASTPATH_UPDATETYPE_PTR_NULL; else updateCode = FASTPATH_UPDATETYPE_PTR_DEFAULT; fastpath_send_update_pdu(rdp->fastpath, updateCode, s); Stream_Release(s); }
static void update_send_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate) { wStream* s; rdpRdp* rdp = context->rdp; rdpUpdate* update = context->update; update_force_flush(context); s = fastpath_update_pdu_init(rdp->fastpath); update_write_bitmap_update(update, s, bitmapUpdate); fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_BITMAP, s); update_force_flush(context); Stream_Release(s); }
void transport_free(rdpTransport* transport) { if (!transport) return; transport_disconnect(transport); if (transport->ReceiveBuffer) Stream_Release(transport->ReceiveBuffer); StreamPool_Free(transport->ReceivePool); CloseHandle(transport->connectedEvent); DeleteCriticalSection(&(transport->ReadLock)); DeleteCriticalSection(&(transport->WriteLock)); free(transport); }
void transport_free(rdpTransport* transport) { if (transport) { if (transport->async) { assert(!transport->thread); assert(!transport->stopEvent); } if (transport->ReceiveBuffer) Stream_Release(transport->ReceiveBuffer); StreamPool_Free(transport->ReceivePool); CloseHandle(transport->ReceiveEvent); CloseHandle(transport->connectedEvent); if (transport->TlsIn) tls_free(transport->TlsIn); if (transport->TlsOut != transport->TlsIn) tls_free(transport->TlsOut); transport->TlsIn = NULL; transport->TlsOut = NULL; if (transport->TcpIn) tcp_free(transport->TcpIn); if (transport->TcpOut != transport->TcpIn) tcp_free(transport->TcpOut); transport->TcpIn = NULL; transport->TcpOut = NULL; tsg_free(transport->tsg); transport->tsg = NULL; CloseHandle(transport->ReadMutex); CloseHandle(transport->WriteMutex); free(transport); } }
static void dvcman_channel_free(void* arg) { DVCMAN_CHANNEL* channel = (DVCMAN_CHANNEL*) arg; UINT error = CHANNEL_RC_OK; if (channel) { if (channel->channel_callback) { IFCALL(channel->channel_callback->OnClose, channel->channel_callback); } if (channel->status == CHANNEL_RC_OK) { IWTSVirtualChannel* ichannel = (IWTSVirtualChannel*) channel; if (channel->dvcman && channel->dvcman->drdynvc) { DrdynvcClientContext* context = channel->dvcman->drdynvc->context; if (context) { IFCALLRET(context->OnChannelDisconnected, error, context, channel->channel_name, channel->pInterface); } } error = IFCALLRESULT(CHANNEL_RC_OK, ichannel->Close, ichannel); if (error != CHANNEL_RC_OK) WLog_ERR(TAG, "Close failed with error %"PRIu32"!", error); } if (channel->dvc_data) Stream_Release(channel->dvc_data); DeleteCriticalSection(&(channel->lock)); free(channel->channel_name); } free(channel); }
int dvcman_receive_channel_data_first(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId, UINT32 length) { DVCMAN_CHANNEL* channel; channel = (DVCMAN_CHANNEL*) dvcman_find_channel_by_id(pChannelMgr, ChannelId); if (!channel) { DEBUG_WARN("ChannelId %d not found!", ChannelId); return 1; } if (channel->dvc_data) Stream_Release(channel->dvc_data); channel->dvc_data = StreamPool_Take(channel->dvcman->pool, length); Stream_AddRef(channel->dvc_data); return 0; }
void transport_free(rdpTransport* transport) { if (!transport) return; transport_stop(transport); if (transport->ReceiveBuffer) Stream_Release(transport->ReceiveBuffer); StreamPool_Free(transport->ReceivePool); CloseHandle(transport->ReceiveEvent); CloseHandle(transport->connectedEvent); if (transport->TlsIn) tls_free(transport->TlsIn); if (transport->TlsOut != transport->TlsIn) tls_free(transport->TlsOut); transport->TlsIn = NULL; transport->TlsOut = NULL; if (transport->TcpIn) tcp_free(transport->TcpIn); if (transport->TcpOut != transport->TcpIn) tcp_free(transport->TcpOut); transport->TcpIn = NULL; transport->TcpOut = NULL; tsg_free(transport->tsg); transport->tsg = NULL; DeleteCriticalSection(&(transport->ReadLock)); DeleteCriticalSection(&(transport->WriteLock)); free(transport); }
static BOOL autodetect_send_bandwidth_measure_stop(rdpContext* context, UINT16 payloadLength, UINT16 sequenceNumber, UINT16 requestType) { UINT16 i; wStream* s; s = rdp_message_channel_pdu_init(context->rdp); if (!s) return FALSE; WLog_DBG(AUTODETECT_TAG, "sending Bandwidth Measure Stop PDU -> payloadLength=%u"); /* 4-bytes aligned */ payloadLength &= ~3; Stream_Write_UINT8(s, requestType == RDP_BW_STOP_REQUEST_TYPE_CONNECTTIME ? 0x08 : 0x06); /* headerLength (1 byte) */ Stream_Write_UINT8(s, TYPE_ID_AUTODETECT_REQUEST); /* headerTypeId (1 byte) */ Stream_Write_UINT16(s, sequenceNumber); /* sequenceNumber (2 bytes) */ Stream_Write_UINT16(s, requestType); /* requestType (2 bytes) */ if (requestType == RDP_BW_STOP_REQUEST_TYPE_CONNECTTIME) { Stream_Write_UINT16(s, payloadLength); /* payloadLength (2 bytes) */ if (payloadLength > 0) { if (!Stream_EnsureRemainingCapacity(s, payloadLength)) { Stream_Release(s); return FALSE; } /* Random data (better measurement in case the line is compressed) */ for (i = 0; i < payloadLength / 4; i++) { Stream_Write_UINT32(s, rand()); } } } return rdp_send_message_channel_pdu(context->rdp, s, SEC_AUTODETECT_REQ); }
BOOL rdp_server_accept_client_font_list_pdu(rdpRdp* rdp, wStream* s) { rdpSettings* settings = rdp->settings; freerdp_peer* peer = rdp->context->peer; if (!rdp_recv_client_font_list_pdu(s)) return FALSE; if (settings->SupportMonitorLayoutPdu && settings->MonitorCount && peer->AdjustMonitorsLayout && peer->AdjustMonitorsLayout(peer)) { /* client supports the monitorLayout PDU, let's send him the monitors if any */ wStream* st = rdp_data_pdu_init(rdp); BOOL r; if (!st) return FALSE; if (!rdp_write_monitor_layout_pdu(st, settings->MonitorCount, settings->MonitorDefArray)) { Stream_Release(st); return FALSE; } r = rdp_send_data_pdu(rdp, st, DATA_PDU_TYPE_MONITOR_LAYOUT, 0); if (!r) return FALSE; } if (!rdp_send_server_font_map_pdu(rdp)) return FALSE; if (rdp_server_transition_to_state(rdp, CONNECTION_STATE_ACTIVE) < 0) return FALSE; return TRUE; }
int dvcman_close_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId) { DVCMAN_CHANNEL* channel; IWTSVirtualChannel* ichannel; DrdynvcClientContext* context; DVCMAN* dvcman = (DVCMAN*) pChannelMgr; channel = (DVCMAN_CHANNEL*) dvcman_find_channel_by_id(pChannelMgr, ChannelId); if (!channel) { DEBUG_WARN("ChannelId %d not found!", ChannelId); return 1; } if (channel->dvc_data) { Stream_Release(channel->dvc_data); channel->dvc_data = NULL; } if (channel->status == 0) { context = dvcman->drdynvc->context; IFCALL(context->OnChannelDisconnected, context, channel->channel_name, channel->pInterface); free(channel->channel_name); DEBUG_DVC("dvcman_close_channel: channel %d closed", ChannelId); ichannel = (IWTSVirtualChannel*) channel; ichannel->Close(ichannel); } return 0; }
int transport_write(rdpTransport* transport, wStream* s) { int length; int status = -1; int writtenlength = 0; EnterCriticalSection(&(transport->WriteLock)); length = Stream_GetPosition(s); writtenlength = length; Stream_SetPosition(s, 0); if (length > 0) { WLog_Packet(WLog_Get(TAG), WLOG_TRACE, Stream_Buffer(s), length, WLOG_PACKET_OUTBOUND); } while (length > 0) { status = BIO_write(transport->frontBio, Stream_Pointer(s), length); if (status <= 0) { /* the buffered BIO that is at the end of the chain always says OK for writing, * so a retry means that for any reason we need to read. The most probable * is a SSL or TSG BIO in the chain. */ if (!BIO_should_retry(transport->frontBio)) goto out_cleanup; /* non-blocking can live with blocked IOs */ if (!transport->blocking) goto out_cleanup; if (BIO_wait_write(transport->frontBio, 100) < 0) { WLog_ERR(TAG, "error when selecting for write"); status = -1; goto out_cleanup; } continue; } if (transport->blocking || transport->settings->WaitForOutputBufferFlush) { while (BIO_write_blocked(transport->frontBio)) { if (BIO_wait_write(transport->frontBio, 100) < 0) { WLog_ERR(TAG, "error when selecting for write"); status = -1; goto out_cleanup; } if (BIO_flush(transport->frontBio) < 1) { WLog_ERR(TAG, "error when flushing outputBuffer"); status = -1; goto out_cleanup; } } } length -= status; Stream_Seek(s, status); } transport->written += writtenlength; out_cleanup: if (status < 0) { /* A write error indicates that the peer has dropped the connection */ transport->layer = TRANSPORT_LAYER_CLOSED; } if (s->pool) Stream_Release(s); LeaveCriticalSection(&(transport->WriteLock)); return status; }
static int freerdp_peer_virtual_channel_write(freerdp_peer* client, HANDLE hChannel, BYTE* buffer, UINT32 length) { wStream* s; UINT32 flags; UINT32 chunkSize; UINT32 maxChunkSize; UINT32 totalLength; rdpPeerChannel* peerChannel; rdpMcsChannel* mcsChannel; rdpRdp* rdp = client->context->rdp; if (!hChannel) return -1; peerChannel = (rdpPeerChannel*) hChannel; mcsChannel = peerChannel->mcsChannel; if (peerChannel->channelFlags & WTS_CHANNEL_OPTION_DYNAMIC) return -1; /* not yet supported */ maxChunkSize = rdp->settings->VirtualChannelChunkSize; totalLength = length; flags = CHANNEL_FLAG_FIRST; while (length > 0) { s = rdp_send_stream_init(rdp); if (!s) return -1; if (length > maxChunkSize) { chunkSize = rdp->settings->VirtualChannelChunkSize; } else { chunkSize = length; flags |= CHANNEL_FLAG_LAST; } if (mcsChannel->options & CHANNEL_OPTION_SHOW_PROTOCOL) flags |= CHANNEL_FLAG_SHOW_PROTOCOL; Stream_Write_UINT32(s, totalLength); Stream_Write_UINT32(s, flags); if (!Stream_EnsureRemainingCapacity(s, chunkSize)) { Stream_Release(s); return -1; } Stream_Write(s, buffer, chunkSize); if (!rdp_send(rdp, s, peerChannel->channelId)) { Stream_Release(s); return -1; } buffer += chunkSize; length -= chunkSize; flags = 0; } return 1; }
/** 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; }
BOOL freerdp_channel_send(rdpRdp* rdp, UINT16 channelId, BYTE* data, int size) { DWORD i; int left; wStream* s; UINT32 flags; int chunkSize; rdpMcs* mcs = rdp->mcs; rdpMcsChannel* channel = NULL; for (i = 0; i < mcs->channelCount; i++) { if (mcs->channels[i].ChannelId == channelId) { channel = &mcs->channels[i]; break; } } if (!channel) { WLog_ERR(TAG, "freerdp_channel_send: unknown channelId %"PRIu16"", channelId); return FALSE; } flags = CHANNEL_FLAG_FIRST; left = size; while (left > 0) { s = rdp_send_stream_init(rdp); if (!s) return FALSE; if (left > (int) rdp->settings->VirtualChannelChunkSize) { chunkSize = rdp->settings->VirtualChannelChunkSize; } else { chunkSize = left; flags |= CHANNEL_FLAG_LAST; } if ((channel->options & CHANNEL_OPTION_SHOW_PROTOCOL)) { flags |= CHANNEL_FLAG_SHOW_PROTOCOL; } Stream_Write_UINT32(s, size); Stream_Write_UINT32(s, flags); if (!Stream_EnsureCapacity(s, chunkSize)) { Stream_Release(s); return FALSE; } Stream_Write(s, data, chunkSize); /* WLog_DBG(TAG, "%s: sending data (flags=0x%x size=%d)", __FUNCTION__, flags, size); */ if (!rdp_send(rdp, s, channelId)) { Stream_Release(s); return FALSE; } data += chunkSize; left -= chunkSize; flags = 0; } return TRUE; }