Пример #1
0
void
channel_send(STREAM s, VCHANNEL * channel)
{
	uint32 length, flags;
	uint32 thislength, remaining;
	uint8 *data;

#ifdef WITH_SCARD
	scard_lock(SCARD_LOCK_CHANNEL);
#endif

	/* first fragment sent in-place */
	s_pop_layer(s, channel_hdr);
	length = s->end - s->p - 8;

	DEBUG_CHANNEL(("channel_send, length = %d\n", length));

	thislength = MIN(length, CHANNEL_CHUNK_LENGTH);
/* Note: In the original clipboard implementation, this number was
   1592, not 1600. However, I don't remember the reason and 1600 seems
   to work so.. This applies only to *this* length, not the length of
   continuation or ending packets. */
	remaining = length - thislength;
	flags = (remaining == 0) ? CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST : CHANNEL_FLAG_FIRST;
	if (channel->flags & CHANNEL_OPTION_SHOW_PROTOCOL)
		flags |= CHANNEL_FLAG_SHOW_PROTOCOL;

	out_uint32_le(s, length);
	out_uint32_le(s, flags);
	data = s->end = s->p + thislength;
	DEBUG_CHANNEL(("Sending %d bytes with FLAG_FIRST\n", thislength));
	sec_send_to_channel(s, g_encryption ? SEC_ENCRYPT : 0, channel->mcs_id);

	/* subsequent segments copied (otherwise would have to generate headers backwards) */
	while (remaining > 0)
	{
		thislength = MIN(remaining, CHANNEL_CHUNK_LENGTH);
		remaining -= thislength;
		flags = (remaining == 0) ? CHANNEL_FLAG_LAST : 0;
		if (channel->flags & CHANNEL_OPTION_SHOW_PROTOCOL)
			flags |= CHANNEL_FLAG_SHOW_PROTOCOL;

		DEBUG_CHANNEL(("Sending %d bytes with flags %d\n", thislength, flags));

		s = sec_init(g_encryption ? SEC_ENCRYPT : 0, thislength + 8);
		out_uint32_le(s, length);
		out_uint32_le(s, flags);
		out_uint8p(s, data, thislength);
		s_mark_end(s);
		sec_send_to_channel(s, g_encryption ? SEC_ENCRYPT : 0, channel->mcs_id);

		data += thislength;
	}

#ifdef WITH_SCARD
	scard_unlock(SCARD_LOCK_CHANNEL);
#endif
}
Пример #2
0
int
vchan_send(rdpChannels * chan, int mcs_id, char * data, int total_length)
{
	STREAM s;
	int sec_flags;
	int length;
	int sent;
	int chan_flags;
	int chan_index;
	rdpSet * settings;
	struct rdp_chan * channel;

	settings = chan->mcs->sec->rdp->settings;
	chan_index = (mcs_id - MCS_GLOBAL_CHANNEL) - 1;
	if ((chan_index < 0) || (chan_index >= settings->num_channels))
	{
		ui_error(chan->mcs->sec->rdp->inst, "error\n");
		return 0;
	}
	channel = &(settings->channels[chan_index]);
	chan_flags = CHANNEL_FLAG_FIRST;
	sent = 0;
	sec_flags = settings->encryption ? SEC_ENCRYPT : 0;
	while (sent < total_length)
	{
		length = MIN(CHANNEL_CHUNK_LENGTH, total_length);
		length = MIN(total_length - sent, length);
		if ((sent + length) >= total_length)
		{
			chan_flags |= CHANNEL_FLAG_LAST;
		}
		if (channel->flags & CHANNEL_OPTION_SHOW_PROTOCOL)
		{
			chan_flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
		}
		s = sec_init(chan->mcs->sec, sec_flags, length + 8);
		out_uint32_le(s, total_length);
		out_uint32_le(s, chan_flags);
		out_uint8p(s, data + sent, length);
		s_mark_end(s);
		sec_send_to_channel(chan->mcs->sec, s, sec_flags, mcs_id);
		sent += length;
		chan_flags = 0;
	}
	return sent;
}