Пример #1
0
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);
}
Пример #2
0
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);
}
Пример #3
0
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;
}
Пример #4
0
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);
}
Пример #5
0
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);
}
Пример #6
0
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;
}
Пример #7
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;
}
Пример #8
0
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);
}
Пример #9
0
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);
}
Пример #10
0
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);
	}
}
Пример #11
0
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);
}
Пример #12
0
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;
}
Пример #13
0
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);
	}
}
Пример #14
0
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);
	}
}
Пример #15
0
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);
	}
}
Пример #16
0
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;
}
Пример #17
0
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);
}
Пример #18
0
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);
}
Пример #19
0
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);
}
Пример #20
0
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);
	}
}
Пример #21
0
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);
}
Пример #22
0
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;
}
Пример #23
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);
}
Пример #24
0
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);
}
Пример #25
0
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;
}
Пример #26
0
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;
}
Пример #27
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;
}
Пример #28
0
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;
}
Пример #29
0
/** 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;
}
Пример #30
0
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;
}