Пример #1
0
boolean rdp_read_share_data_header(STREAM* s, uint16* length, uint8* type, uint32* share_id,
					uint8 *compressed_type, uint16 *compressed_len)
{
	if (stream_get_left(s) < 12)
		return false;

	/* Share Data Header */
	stream_read_uint32(s, *share_id); /* shareId (4 bytes) */
	stream_seek_uint8(s); /* pad1 (1 byte) */
	stream_seek_uint8(s); /* streamId (1 byte) */
	stream_read_uint16(s, *length); /* uncompressedLength (2 bytes) */
	stream_read_uint8(s, *type); /* pduType2, Data PDU Type (1 byte) */

	if (*type & 0x80)
	{
		stream_read_uint8(s, *compressed_type); /* compressedType (1 byte) */
		stream_read_uint16(s, *compressed_len); /* compressedLength (2 bytes) */
	}
	else
	{
		stream_seek(s, 3);
		*compressed_type = 0;
		*compressed_len = 0;
	}

	return true;
}
Пример #2
0
void rdp_read_share_data_header(STREAM* s, uint16* length, uint8* type, uint32* share_id)
{
	/* Share Data Header */
	stream_read_uint32(s, *share_id); /* shareId (4 bytes) */
	stream_seek_uint8(s); /* pad1 (1 byte) */
	stream_seek_uint8(s); /* streamId (1 byte) */
	stream_read_uint16(s, *length); /* uncompressedLength (2 bytes) */
	stream_read_uint8(s, *type); /* pduType2, Data PDU Type (1 byte) */
	stream_seek_uint8(s); /* compressedType (1 byte) */
	stream_seek_uint16(s); /* compressedLength (2 bytes) */
}
Пример #3
0
void rdp_read_bitmap_cache_v2_capability_set(STREAM* s, rdpSettings* settings)
{
	stream_seek_uint16(s); /* cacheFlags (2 bytes) */
	stream_seek_uint8(s); /* pad2 (1 byte) */
	stream_seek_uint8(s); /* numCellCaches (1 byte) */
	stream_seek(s, 4); /* bitmapCache0CellInfo (4 bytes) */
	stream_seek(s, 4); /* bitmapCache1CellInfo (4 bytes) */
	stream_seek(s, 4); /* bitmapCache2CellInfo (4 bytes) */
	stream_seek(s, 4); /* bitmapCache3CellInfo (4 bytes) */
	stream_seek(s, 4); /* bitmapCache4CellInfo (4 bytes) */
	stream_seek(s, 12); /* pad3 (12 bytes) */
}
Пример #4
0
boolean rdp_recv_enhanced_security_redirection_packet(rdpRdp* rdp, STREAM* s)
{
	stream_seek_uint16(s); /* pad2Octets (2 bytes) */
	rdp_recv_server_redirection_pdu(rdp, s);
	stream_seek_uint8(s); /* pad2Octets (1 byte) */
	return true;
}
Пример #5
0
void rdp_read_bitmap_capability_set(STREAM* s, rdpSettings* settings)
{
	uint8 drawingFlags;
	uint16 desktopWidth;
	uint16 desktopHeight;
	uint16 desktopResizeFlag;
	uint16 preferredBitsPerPixel;

	stream_read_uint16(s, preferredBitsPerPixel); /* preferredBitsPerPixel (2 bytes) */
	stream_seek_uint16(s); /* receive1BitPerPixel (2 bytes) */
	stream_seek_uint16(s); /* receive4BitsPerPixel (2 bytes) */
	stream_seek_uint16(s); /* receive8BitsPerPixel (2 bytes) */
	stream_read_uint16(s, desktopWidth); /* desktopWidth (2 bytes) */
	stream_read_uint16(s, desktopHeight); /* desktopHeight (2 bytes) */
	stream_seek_uint16(s); /* pad2Octets (2 bytes) */
	stream_read_uint16(s, desktopResizeFlag); /* desktopResizeFlag (2 bytes) */
	stream_seek_uint16(s); /* bitmapCompressionFlag (2 bytes) */
	stream_seek_uint8(s); /* highColorFlags (1 byte) */
	stream_read_uint8(s, drawingFlags); /* drawingFlags (1 byte) */
	stream_seek_uint16(s); /* multipleRectangleSupport (2 bytes) */
	stream_seek_uint16(s); /* pad2OctetsB (2 bytes) */

	if (desktopResizeFlag == False)
		settings->desktop_resize = False;
}
Пример #6
0
static void rfx_process_message_region(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s)
{
	int i;

	stream_seek_uint8(s); /* regionFlags (1 byte) */
	stream_read_uint16(s, message->num_rects); /* numRects (2 bytes) */

	if (message->num_rects < 1)
	{
		DEBUG_WARN("no rects.");
		return;
	}

	if (message->rects != NULL)
		message->rects = (RFX_RECT*) xrealloc(message->rects, message->num_rects * sizeof(RFX_RECT));
	else
		message->rects = (RFX_RECT*) xmalloc(message->num_rects * sizeof(RFX_RECT));

	/* rects */
	for (i = 0; i < message->num_rects; i++)
	{
		/* RFX_RECT */
		stream_read_uint16(s, message->rects[i].x); /* x (2 bytes) */
		stream_read_uint16(s, message->rects[i].y); /* y (2 bytes) */
		stream_read_uint16(s, message->rects[i].width); /* width (2 bytes) */
		stream_read_uint16(s, message->rects[i].height); /* height (2 bytes) */

		DEBUG_RFX("rect %d (%d %d %d %d).",
			i, message->rects[i].x, message->rects[i].y, message->rects[i].width, message->rects[i].height);
	}
}
Пример #7
0
static boolean rdpsnd_server_recv_formats(rdpsnd_server* rdpsnd, STREAM* s)
{
	int i;

	if (stream_get_left(s) < 20)
		return false;

	stream_seek_uint32(s); /* dwFlags */
	stream_seek_uint32(s); /* dwVolume */
	stream_seek_uint32(s); /* dwPitch */
	stream_seek_uint16(s); /* wDGramPort */
	stream_read_uint16(s, rdpsnd->context.num_client_formats); /* wNumberOfFormats */
	stream_seek_uint8(s); /* cLastBlockConfirmed */
	stream_seek_uint16(s); /* wVersion */
	stream_seek_uint8(s); /* bPad */

	if (rdpsnd->context.num_client_formats > 0)
	{
		rdpsnd->context.client_formats = xzalloc(rdpsnd->context.num_client_formats * sizeof(rdpsndFormat));
		for (i = 0; i < rdpsnd->context.num_client_formats; i++)
		{
			if (stream_get_left(s) < 18)
			{
				xfree(rdpsnd->context.client_formats);
				rdpsnd->context.client_formats = NULL;
				return false;
			}

			stream_read_uint16(s, rdpsnd->context.client_formats[i].wFormatTag);
			stream_read_uint16(s, rdpsnd->context.client_formats[i].nChannels);
			stream_read_uint32(s, rdpsnd->context.client_formats[i].nSamplesPerSec);
			stream_seek_uint32(s); /* nAvgBytesPerSec */
			stream_read_uint16(s, rdpsnd->context.client_formats[i].nBlockAlign);
			stream_read_uint16(s, rdpsnd->context.client_formats[i].wBitsPerSample);
			stream_read_uint16(s, rdpsnd->context.client_formats[i].cbSize);
			if (rdpsnd->context.client_formats[i].cbSize > 0)
			{
				stream_seek(s, rdpsnd->context.client_formats[i].cbSize);
			}
		}
	}

	return true;
}
Пример #8
0
/*
 * The fastpath header may be two or three bytes long.
 * This function assumes that at least two bytes are available in the stream
 * and doesn't touch third byte.
 */
uint16 fastpath_header_length(STREAM* s)
{
	uint8 length1;

	stream_seek_uint8(s);
	stream_read_uint8(s, length1);
	stream_rewind(s, 2);

	return ((length1 & 0x80) != 0 ? 3 : 2);
}
Пример #9
0
static void wts_write_drdynvc_header(STREAM *s, uint8 Cmd, uint32 ChannelId)
{
	uint8* bm;
	int cbChId;

	stream_get_mark(s, bm);
	stream_seek_uint8(s);
	cbChId = wts_write_variable_uint(s, ChannelId);
	*bm = ((Cmd & 0x0F) << 4) | cbChId;
}
Пример #10
0
void rdp_read_bitmap_cache_host_support_capability_set(STREAM* s, rdpSettings* settings)
{
	uint8 cacheVersion;

	stream_read_uint8(s, cacheVersion); /* cacheVersion (1 byte) */
	stream_seek_uint8(s); /* pad1 (1 byte) */
	stream_seek_uint16(s); /* pad2 (2 bytes) */

	if (cacheVersion & BITMAP_CACHE_V2)
		settings->persistent_bitmap_cache = True;
}
Пример #11
0
boolean nego_read_request(rdpNego* nego, STREAM* s)
{
	uint8 li;
	uint8 c;
	uint8 type;

	tpkt_read_header(s);
	li = tpdu_read_connection_request(s);

	if (li != stream_get_left(s) + 6)
	{
		printf("Incorrect TPDU length indicator.\n");
		return false;
	}

	if (stream_get_left(s) > 8)
	{
		/* Optional routingToken or cookie, ending with CR+LF */
		while (stream_get_left(s) > 0)
		{
			stream_read_uint8(s, c);

			if (c != '\x0D')
				continue;

			stream_peek_uint8(s, c);

			if (c != '\x0A')
				continue;

			stream_seek_uint8(s);
			break;
		}
	}

	if (stream_get_left(s) >= 8)
	{
		/* rdpNegData (optional) */

		stream_read_uint8(s, type); /* Type */

		if (type != TYPE_RDP_NEG_REQ)
		{
			printf("Incorrect negotiation request type %d\n", type);
			return false;
		}

		nego_process_negotiation_request(nego, s);
	}

	return true;
}
Пример #12
0
static void wts_read_drdynvc_capabilities_response(rdpPeerChannel* channel, uint32 length)
{
	uint16 Version;

	if (length < 3)
		return;
	stream_seek_uint8(channel->receive_data); /* Pad (1 byte) */
	stream_read_uint16(channel->receive_data, Version);

	DEBUG_DVC("Version: %d", Version);

	channel->vcm->drdynvc_state = DRDYNVC_STATE_READY;
}
Пример #13
0
void rdp_read_bitmap_codecs_capability_set(STREAM* s, rdpSettings* settings)
{
	uint8 bitmapCodecCount;
	uint16 codecPropertiesLength;

	stream_read_uint8(s, bitmapCodecCount); /* bitmapCodecCount (1 byte) */

	while (bitmapCodecCount > 0)
	{
		stream_seek(s, 16); /* codecGUID (16 bytes) */
		stream_seek_uint8(s); /* codecID (1 byte) */

		stream_read_uint16(s, codecPropertiesLength); /* codecPropertiesLength (2 bytes) */
		stream_seek(s, codecPropertiesLength); /* codecProperties */

		bitmapCodecCount--;
	}
}
Пример #14
0
static void rdpsnd_process_receive(rdpSvcPlugin* plugin, STREAM* data_in)
{
	rdpsndPlugin* rdpsnd = (rdpsndPlugin*)plugin;
	uint8 msgType;
	uint16 BodySize;

	if (rdpsnd->expectingWave)
	{
		rdpsnd_process_message_wave(rdpsnd, data_in);
		stream_free(data_in);
		return;
	}

	stream_read_uint8(data_in, msgType); /* msgType */
	stream_seek_uint8(data_in); /* bPad */
	stream_read_uint16(data_in, BodySize);

	DEBUG_SVC("msgType %d BodySize %d", msgType, BodySize);

	switch (msgType)
	{
		case SNDC_FORMATS:
			rdpsnd_process_message_formats(rdpsnd, data_in);
			break;
		case SNDC_TRAINING:
			rdpsnd_process_message_training(rdpsnd, data_in);
			break;
		case SNDC_WAVE:
			rdpsnd_process_message_wave_info(rdpsnd, data_in, BodySize);
			break;
		case SNDC_CLOSE:
			rdpsnd_process_message_close(rdpsnd);
			break;
		case SNDC_SETVOLUME:
			rdpsnd_process_message_setvolume(rdpsnd, data_in);
			break;
		default:
			DEBUG_WARN("unknown msgType %d", msgType);
			break;
	}

	stream_free(data_in);
}
Пример #15
0
void update_read_pointer_color(STREAM* s, POINTER_COLOR_UPDATE* pointer_color)
{
	stream_read_uint16(s, pointer_color->cacheIndex); /* cacheIndex (2 bytes) */
	stream_read_uint32(s, pointer_color->hotSpot); /* hotSpot (4 bytes) */
	stream_read_uint16(s, pointer_color->width); /* width (2 bytes) */
	stream_read_uint16(s, pointer_color->height); /* height (2 bytes) */
	stream_read_uint16(s, pointer_color->lengthAndMask); /* lengthAndMask (2 bytes) */
	stream_read_uint16(s, pointer_color->lengthXorMask); /* lengthXorMask (2 bytes) */

	if (pointer_color->lengthXorMask > 0)
	{
		pointer_color->xorMaskData = (uint8*) xmalloc(pointer_color->lengthXorMask);
		stream_read(s, pointer_color->xorMaskData, pointer_color->lengthXorMask);
	}

	if (pointer_color->lengthAndMask > 0)
	{
		pointer_color->andMaskData = (uint8*) xmalloc(pointer_color->lengthAndMask);
		stream_read(s, pointer_color->andMaskData, pointer_color->lengthAndMask);
	}

	stream_seek_uint8(s); /* pad (1 byte) */
}
Пример #16
0
static void* rdpsnd_server_thread_func(void* arg)
{
	void* fd;
	STREAM* s;
	void* buffer;
	uint8 msgType;
	uint16 BodySize;
	uint32 bytes_returned = 0;
	rdpsnd_server* rdpsnd = (rdpsnd_server*) arg;
	freerdp_thread* thread = rdpsnd->rdpsnd_channel_thread;

	if (WTSVirtualChannelQuery(rdpsnd->rdpsnd_channel, WTSVirtualFileHandle, &buffer, &bytes_returned) == true)
	{
		fd = *((void**)buffer);
		WTSFreeMemory(buffer);
		thread->signals[thread->num_signals++] = wait_obj_new_with_fd(fd);
	}

	s = stream_new(4096);

	rdpsnd_server_send_formats(rdpsnd, s);

	while (1)
	{
		freerdp_thread_wait(thread);
		if (freerdp_thread_is_stopped(thread))
			break;

		stream_set_pos(s, 0);
		if (WTSVirtualChannelRead(rdpsnd->rdpsnd_channel, 0, stream_get_head(s),
			stream_get_size(s), &bytes_returned) == false)
		{
			if (bytes_returned == 0)
				break;
			stream_check_size(s, bytes_returned);
			if (WTSVirtualChannelRead(rdpsnd->rdpsnd_channel, 0, stream_get_head(s),
				stream_get_size(s), &bytes_returned) == false)
				break;
		}

		stream_read_uint8(s, msgType);
		stream_seek_uint8(s); /* bPad */
		stream_read_uint16(s, BodySize);
		if (BodySize + 4 > bytes_returned)
			continue;

		switch (msgType) {
			case SNDC_FORMATS:
				if (rdpsnd_server_recv_formats(rdpsnd, s))
				{
					IFCALL(rdpsnd->context.Activated, &rdpsnd->context);
				}
				break;
			default:
				break;
		}
	}

	stream_free(s);
	freerdp_thread_quit(thread);

	return 0;
}
Пример #17
0
/* receives a list of server supported formats and returns a list
   of client supported formats */
static void rdpsnd_process_message_formats(rdpsndPlugin* rdpsnd, STREAM* data_in)
{
	uint16 wNumberOfFormats;
	uint16 nFormat;
	uint16 wVersion;
	STREAM* data_out;
	rdpsndFormat* out_formats;
	uint16 n_out_formats;
	rdpsndFormat* format;
	uint8* format_mark;
	uint8* data_mark;
	int pos;

	rdpsnd_free_supported_formats(rdpsnd);

	stream_seek_uint32(data_in); /* dwFlags */
	stream_seek_uint32(data_in); /* dwVolume */
	stream_seek_uint32(data_in); /* dwPitch */
	stream_seek_uint16(data_in); /* wDGramPort */
	stream_read_uint16(data_in, wNumberOfFormats);
	stream_read_uint8(data_in, rdpsnd->cBlockNo); /* cLastBlockConfirmed */
	stream_read_uint16(data_in, wVersion);
	stream_seek_uint8(data_in); /* bPad */

	DEBUG_SVC("wNumberOfFormats %d wVersion %d", wNumberOfFormats, wVersion);
	if (wNumberOfFormats < 1)
	{
		DEBUG_WARN("wNumberOfFormats is 0");
		return;
	}

	out_formats = (rdpsndFormat*)xzalloc(wNumberOfFormats * sizeof(rdpsndFormat));
	n_out_formats = 0;

	data_out = stream_new(24);
	stream_write_uint8(data_out, SNDC_FORMATS); /* msgType */
	stream_write_uint8(data_out, 0); /* bPad */
	stream_seek_uint16(data_out); /* BodySize */
	stream_write_uint32(data_out, TSSNDCAPS_ALIVE | TSSNDCAPS_VOLUME); /* dwFlags */
	stream_write_uint32(data_out, 0xFFFFFFFF); /* dwVolume */
	stream_write_uint32(data_out, 0); /* dwPitch */
	stream_write_uint16_be(data_out, 0); /* wDGramPort */
	stream_seek_uint16(data_out); /* wNumberOfFormats */
	stream_write_uint8(data_out, 0); /* cLastBlockConfirmed */
	stream_write_uint16(data_out, 6); /* wVersion */
	stream_write_uint8(data_out, 0); /* bPad */

	for (nFormat = 0; nFormat < wNumberOfFormats; nFormat++)
	{
		stream_get_mark(data_in, format_mark);
		format = &out_formats[n_out_formats];
		stream_read_uint16(data_in, format->wFormatTag);
		stream_read_uint16(data_in, format->nChannels);
		stream_read_uint32(data_in, format->nSamplesPerSec);
		stream_seek_uint32(data_in); /* nAvgBytesPerSec */
		stream_read_uint16(data_in, format->nBlockAlign);
		stream_read_uint16(data_in, format->wBitsPerSample);
		stream_read_uint16(data_in, format->cbSize);
		stream_get_mark(data_in, data_mark);
		stream_seek(data_in, format->cbSize);
		format->data = NULL;

		DEBUG_SVC("wFormatTag=%d nChannels=%d nSamplesPerSec=%d nBlockAlign=%d wBitsPerSample=%d",
			format->wFormatTag, format->nChannels, format->nSamplesPerSec,
			format->nBlockAlign, format->wBitsPerSample);

		if (rdpsnd->fixed_format > 0 && rdpsnd->fixed_format != format->wFormatTag)
			continue;
		if (rdpsnd->fixed_channel > 0 && rdpsnd->fixed_channel != format->nChannels)
			continue;
		if (rdpsnd->fixed_rate > 0 && rdpsnd->fixed_rate != format->nSamplesPerSec)
			continue;
		if (rdpsnd->device && rdpsnd->device->FormatSupported(rdpsnd->device, format))
		{
			DEBUG_SVC("format supported.");

			stream_check_size(data_out, 18 + format->cbSize);
			stream_write(data_out, format_mark, 18 + format->cbSize);
			if (format->cbSize > 0)
			{
				format->data = xmalloc(format->cbSize);
				memcpy(format->data, data_mark, format->cbSize);
			}
			n_out_formats++;
		}
	}

	rdpsnd->n_supported_formats = n_out_formats;
	if (n_out_formats > 0)
	{
		rdpsnd->supported_formats = out_formats;
	}
	else
	{
		xfree(out_formats);
		DEBUG_WARN("no formats supported");
	}

	pos = stream_get_pos(data_out);
	stream_set_pos(data_out, 2);
	stream_write_uint16(data_out, pos - 4);
	stream_set_pos(data_out, 18);
	stream_write_uint16(data_out, n_out_formats);
	stream_set_pos(data_out, pos);

	svc_plugin_send((rdpSvcPlugin*)rdpsnd, data_out);

	if (wVersion >= 6)
	{
		data_out = stream_new(8);
		stream_write_uint8(data_out, SNDC_QUALITYMODE); /* msgType */
		stream_write_uint8(data_out, 0); /* bPad */
		stream_write_uint16(data_out, 4); /* BodySize */
		stream_write_uint16(data_out, HIGH_QUALITY); /* wQualityMode */
		stream_write_uint16(data_out, 0); /* Reserved */

		svc_plugin_send((rdpSvcPlugin*)rdpsnd, data_out);
	}
}
Пример #18
0
boolean disk_file_set_information(DISK_FILE* file, uint32 FsInformationClass, uint32 Length, STREAM* input)
{
	char* s;
	mode_t m;
	uint64 size;
	char* fullpath;
	struct stat st;
	UNICONV* uniconv;
	struct timeval tv[2];
	uint64 LastWriteTime;
	uint32 FileAttributes;
	uint32 FileNameLength;

	switch (FsInformationClass)
	{
		case FileBasicInformation:
			/* http://msdn.microsoft.com/en-us/library/cc232094.aspx */
			stream_seek_uint64(input); /* CreationTime */
			stream_seek_uint64(input); /* LastAccessTime */
			stream_read_uint64(input, LastWriteTime);
			stream_seek_uint64(input); /* ChangeTime */
			stream_read_uint32(input, FileAttributes);

			if (fstat(file->fd, &st) != 0)
				return false;

			tv[0].tv_sec = st.st_atime;
			tv[0].tv_usec = 0;
			tv[1].tv_sec = (LastWriteTime > 0 ? FILE_TIME_RDP_TO_SYSTEM(LastWriteTime) : st.st_mtime);
			tv[1].tv_usec = 0;
			futimes(file->fd, tv);

			if (FileAttributes > 0)
			{
				m = st.st_mode;
				if ((FileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
					m |= S_IWUSR;
				else
					m &= ~S_IWUSR;
				if (m != st.st_mode)
					fchmod(file->fd, st.st_mode);
			}
			break;

		case FileEndOfFileInformation:
			/* http://msdn.microsoft.com/en-us/library/cc232067.aspx */
		case FileAllocationInformation:
			/* http://msdn.microsoft.com/en-us/library/cc232076.aspx */
			stream_read_uint64(input, size);
			if (ftruncate(file->fd, size) != 0)
				return false;
			break;

		case FileDispositionInformation:
			/* http://msdn.microsoft.com/en-us/library/cc232098.aspx */
			stream_read_uint8(input, file->delete_pending);
			break;

		case FileRenameInformation:
			/* http://msdn.microsoft.com/en-us/library/cc232085.aspx */
			stream_seek_uint8(input); /* ReplaceIfExists */
			stream_seek_uint8(input); /* RootDirectory */
			stream_read_uint32(input, FileNameLength);
			uniconv = freerdp_uniconv_new();
			s = freerdp_uniconv_in(uniconv, stream_get_tail(input), FileNameLength);
			freerdp_uniconv_free(uniconv);

			fullpath = disk_file_combine_fullpath(file->basepath, s);
			xfree(s);

			if (rename(file->fullpath, fullpath) == 0)
			{
				DEBUG_SVC("renamed %s to %s", file->fullpath, fullpath);
				disk_file_set_fullpath(file, fullpath);
			}
			else
			{
				DEBUG_WARN("rename %s to %s failed", file->fullpath, fullpath);
				free(fullpath);
				return false;
			}

			break;

		default:
			DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass);
			return false;
	}

	return true;
}
Пример #19
0
boolean WTSVirtualChannelWrite(
	/* __in */  void* hChannelHandle,
	/* __in */  uint8* Buffer,
	/* __in */  uint32 Length,
	/* __out */ uint32* pBytesWritten)
{
	rdpPeerChannel* channel = (rdpPeerChannel*) hChannelHandle;
	wts_data_item* item;
	STREAM* s;
	int cbLen;
	int cbChId;
	int first;
	uint32 written;

	if (channel == NULL)
		return false;

	if (channel->channel_type == RDP_PEER_CHANNEL_TYPE_SVC)
	{
		item = xnew(wts_data_item);
		item->buffer = xmalloc(Length);
		item->length = Length;
		memcpy(item->buffer, Buffer, Length);

		wts_queue_send_item(channel, item);
	}
	else if (channel->vcm->drdynvc_channel == NULL || channel->vcm->drdynvc_state != DRDYNVC_STATE_READY)
	{
		DEBUG_DVC("drdynvc not ready");
		return false;
	}
	else
	{
		s = stream_new(0);
		first = true;

		while (Length > 0)
		{
			item = xnew(wts_data_item);
			item->buffer = xmalloc(channel->client->settings->vc_chunk_size);
			stream_attach(s, item->buffer, channel->client->settings->vc_chunk_size);

			stream_seek_uint8(s);
			cbChId = wts_write_variable_uint(s, channel->channel_id);
			if (first && (Length > (uint32) stream_get_left(s)))
			{
				cbLen = wts_write_variable_uint(s, Length);
				item->buffer[0] = (DATA_FIRST_PDU << 4) | (cbLen << 2) | cbChId;
			}
			else
			{
				item->buffer[0] = (DATA_PDU << 4) | cbChId;
			}
			first = false;
			written = stream_get_left(s);
			if (written > Length)
				written = Length;
			stream_write(s, Buffer, written);
			item->length = stream_get_length(s);
			stream_detach(s);
			Length -= written;
			Buffer += written;

			wts_queue_send_item(channel->vcm->drdynvc_channel, item);
		}

		stream_free(s);
	}

	if (pBytesWritten != NULL)
		*pBytesWritten = Length;
	return true;
}
Пример #20
0
static void rfx_cvt_rdvh_opt_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s)
{
	int i,j;
	RFX_CONTEXT_CVT_PRIV* priv;
	uint16 destLeft, destTop;
	uint16 subtype;
	uint32 blockLen;
	uint32 blockType;
	uint32 tilesDataSize;
	uint32* quants;
	uint8 quant;
	int pos;
	int YQidx,UQidx,VQidx;
	decode_st dec_st;
	rect_st *p_rects;
	uint32 *p_size;
	int io_err;
	uint16 x,y;
	uint32 num_tile_rects;
	uint32 num_tile_rects_save;
	uint32 num_match;
	uint32 num_copy_rects;
	rfx_cvt_rect *p_rects_dst;
	rfx_cvt_rect *p_rects_ext;
	rfx_cvt_rect *p1,*p2;
	int match;
	uint8 disp_idx;
	uint8 idx;
	RFX_RECT *p_tile_rects;
	uint32 num_rects_max;

	destLeft = message->dst_rect.left;
	destTop = message->dst_rect.top;
	priv = (RFX_CONTEXT_CVT_PRIV*) context->priv;

	stream_read_uint16(s, subtype); /* subtype (2 bytes) must be set to CBT_TILESET (0xCAC2) */

	if (subtype != CBT_TILESET)
	{
		DEBUG_WARN("invalid subtype, expected CBT_TILESET.");
		return;
	}

	stream_seek_uint16(s); /* idx (2 bytes), must be set to 0x0000 */
	stream_seek_uint16(s); /* properties (2 bytes) */

	stream_read_uint8(s, context->num_quants); /* numQuant (1 byte) */
	stream_seek_uint8(s); /* tileSize (1 byte), must be set to 0x40 */

	if (context->num_quants < 1)
	{
		DEBUG_WARN("no quantization value.");
		return;
	}

	stream_read_uint16(s, message->num_tiles); /* numTiles (2 bytes) */

	if (message->num_tiles < 1)
	{
		DEBUG_WARN("no tiles.");
		return;
	}

	stream_read_uint32(s, tilesDataSize); /* tilesDataSize (4 bytes) */

	if (context->quants != NULL)
		context->quants = (uint32*) xrealloc((void*) context->quants, context->num_quants * 5 * sizeof(uint32));
	else
		context->quants = (uint32*) xmalloc(context->num_quants * 5 * sizeof(uint32));

	quants = context->quants;

	/* quantVals */
	for (i = 0; i < context->num_quants; i++)
	{
		/* RFX_CODEC_QUANT */
		/* Hardware takes packed Q values. */
		stream_read_uint8(s, *quants++);
		stream_read_uint8(s, *quants++);
		stream_read_uint8(s, *quants++);
		stream_read_uint8(s, *quants++);
		stream_read_uint8(s, *quants++);
	}

	memset(&dec_st,0,sizeof(dec_st));

	rfx_cvt_setup_decode_st(&dec_st, destLeft, destTop, context, priv->rfx_mon_layout);

	dec_st.dest_off_x = destLeft;
	dec_st.dest_off_y = destTop;

	disp_idx = dec_st.display_num;
	idx = g_idx[disp_idx];

	dec_st.p_frame_data = stream_get_tail(s);
	dec_st.num_tiles = message->num_tiles;
	dec_st.p_size = (uint32*) xmalloc(dec_st.num_tiles * sizeof(uint32));

	p_size = dec_st.p_size;

	dec_st.data_size = 0;

	num_tile_rects_save = 0;
	num_tile_rects = 0;
	p_rects_dst = &g_rects_tile[disp_idx][idx][0];
	p_rects_ext = p_rects_dst + dec_st.num_tiles; // for extra rects when 1 tile belongs to more than 1 rects.
	p_tile_rects = (RFX_RECT*) xmalloc(dec_st.num_tiles * sizeof(RFX_RECT));
	/* tiles */
	for (i = 0; i < dec_st.num_tiles; i++)
	{
		/* RFX_TILE */
		stream_read_uint16(s, blockType); /* blockType (2 bytes), must be set to CBT_TILE (0xCAC3) */
		stream_read_uint32(s, blockLen); /* blockLen (4 bytes) */

		pos = stream_get_pos(s) - 6 + blockLen;

		if (blockType != CBT_TILE)
		{
			printf("unknown block type 0x%X, expected CBT_TILE (0xCAC3).", blockType);
			break;
		}

		/* hardware only takes 1 set of Qvalues per frame, check the first tile */
		stream_read_uint8(s, YQidx);
		stream_read_uint8(s, UQidx);
		stream_read_uint8(s, VQidx);
		if (i == 0)
		{
			if ((YQidx > context->num_quants) ||
				(UQidx > context->num_quants) ||
				(VQidx > context->num_quants))
			{
				printf("invalid Qval index.\n");
				printf("YQidx=%d;UQidx=%d;VQidx=%d\n",YQidx,UQidx,VQidx);
				return;
			}
			for(j=0;j<5;j++)
			{
				quant = *(uint8*) (context->quants + 5 * YQidx + j);
				dec_st.quants[4-j]  = (quant >> 4) | (quant << 4);
				quant = *(uint8*) (context->quants + 5 * UQidx + j);
				dec_st.quants[9-j]  = (quant >> 4) | (quant << 4);
				quant = *(uint8*) (context->quants + 5 * VQidx + j);
				dec_st.quants[14-j] = (quant >> 4) | (quant << 4);
			}
		}
		stream_read_uint16(s, x);
		stream_read_uint16(s, y);

		/* save tile rectangles for comparison */
		p_rects = &(g_rects_tile[disp_idx][idx][i].rect) ;
		p_rects->x      = x*64;
		p_rects->y      = y*64;
		p_rects->width  = 64;
		p_rects->height = 64;

		/* get clip window ( get clips tile by tile ) */
		num_match = rfx_cvt_get_clip(message, (RFX_RECT*)p_rects, p_rects_dst, p_rects_ext);
		if (!num_match)
		{
			printf("interesting ???\n");
			p_rects_dst->clip.x      = p_rects->x ;
			p_rects_dst->clip.y      = p_rects->y ;
			p_rects_dst->clip.width  = p_rects->width ;
			p_rects_dst->clip.height = p_rects->height ;
			p_rects_dst++;
			num_tile_rects_save++;
		}
		else
		{
			p_rects_dst++;
			p_rects_ext+=(num_match-1);
		}
		num_tile_rects_save += num_match;

		/* tile_rects for blit */
		p_tile_rects->x      = x*64;
		p_tile_rects->y      = y*64;
		p_tile_rects->width  = 64;
		p_tile_rects->height = 64;

		//horizontal merge tiles
		if (i)
		{
			if (
				(p_tile_rects->y == (p_tile_rects-1)->y) &&
				(p_tile_rects->x == (p_tile_rects-1)->x + (p_tile_rects-1)->width)
			)
			{
				p_tile_rects--;
				p_tile_rects->width += 64;
				num_tile_rects--;
			}
		}
		p_tile_rects++;
		num_tile_rects++;

		dec_st.data_size+=blockLen;
		*(p_size++)=blockLen;

		stream_set_pos(s, pos);
	}

	dec_st.num_tile_rects = num_tile_rects;
	p_tile_rects -= num_tile_rects;
	/* check tiles need to be copied from previous frame */
	num_copy_rects = 0;
	for(i=0;i<g_num_rects_tile[disp_idx];i++)
	{
		match = 0;
		for(j=0;j<num_tile_rects_save;j++)
		{
			if (rfx_cvt_rects_compare(&(g_rects_tile[disp_idx][1-idx][i]),&(g_rects_tile[disp_idx][idx][j])))
			{
				match = 1;
				break;
			}
		}
		if (!match)
		{
			memcpy((uint8*)&(g_rects_copy[disp_idx][num_copy_rects]),(uint8*)&(g_rects_tile[disp_idx][1-idx][i]),sizeof(rfx_cvt_rect));
			num_copy_rects++;
		}
	}
	/* update tile rects number (for next frame) */
	g_num_rects_tile[disp_idx] = num_tile_rects_save;

	/* horizontal merge copy rects */
	p1 = (rfx_cvt_rect*)&g_rects_copy[disp_idx][0];
	p2 = (rfx_cvt_rect*)&g_rects_copy[disp_idx][0];
	if (num_copy_rects)
	{
		dec_st.num_copy_rects = rfx_cvt_rdvh_opt_tile_merge(p1,p2,num_copy_rects);
		dec_st.num_copy_rects = rfx_cvt_rdvh_opt_copy_rects_optimize(p1,dec_st.num_copy_rects);
	}
	else
	{
		dec_st.num_copy_rects = 0;
	}
	dec_st.p_copy_rects = &(g_rects_copy[disp_idx][0]);

	/* exceed 2D command fifo depth limitation */
	if (dec_st.num_copy_rects > 160)
	{
		dec_st.num_copy_rects = 1;
		dec_st.p_copy_rects->rect.x = 0;
		dec_st.p_copy_rects->rect.y = 0;
		dec_st.p_copy_rects->rect.width  = context->width;
		dec_st.p_copy_rects->rect.height = context->height;
		dec_st.p_copy_rects->clip.x = 0;
		dec_st.p_copy_rects->clip.y = 0;
		dec_st.p_copy_rects->clip.width  = context->width;
		dec_st.p_copy_rects->clip.height = context->height;
	}

	/* verical merge tile rects */
	for(j=0;j<dec_st.num_tile_rects;j++)
	{
		for(i=j+1;i<dec_st.num_tile_rects;i++)
		{
			if (
				(p_tile_rects[j].x == p_tile_rects[i].x) &&
				((p_tile_rects[j].y+p_tile_rects[j].height) == p_tile_rects[i].y) &&
				(p_tile_rects[j].width == p_tile_rects[i].width) && (p_tile_rects[i].width!=0)
			)
			{
				p_tile_rects[j].height +=64;
				p_tile_rects[i].width = 0;
			}
		}
	}
	num_tile_rects=0;
	for(i=0;i<dec_st.num_tile_rects;i++)
	{
		if (p_tile_rects[i].width)
		{
			if (i!=num_tile_rects)
				memcpy((uint8*)(p_tile_rects+num_tile_rects),(uint8*)(p_tile_rects+i),sizeof(rect_st));
			num_tile_rects++;
		}
	}
	dec_st.num_tile_rects = num_tile_rects;

	/* create clip window list for tile rects */
	num_rects_max = message->num_rects*dec_st.num_tile_rects;
	dec_st.p_tile_rects = (rfx_cvt_rect*) xmalloc(num_rects_max * sizeof(rfx_cvt_rect));
	p_rects_dst = dec_st.p_tile_rects;
	p_rects_ext = dec_st.p_tile_rects + dec_st.num_tile_rects;	/* for extra rects when 1 tile belongs to more than 1 rects. */
	num_tile_rects = 0;
	for (i = 0; i < dec_st.num_tile_rects; i++)
	{
		num_match = rfx_cvt_get_clip(message, p_tile_rects, p_rects_dst, p_rects_ext);
		if (!num_match)
		{
			printf("interesting ???\n");
			p_rects_dst->clip.x      = p_tile_rects->x ;
			p_rects_dst->clip.y      = p_tile_rects->y ;
			p_rects_dst->clip.width  = p_tile_rects->width ;
			p_rects_dst->clip.height = p_tile_rects->height ;
			p_rects_dst++;
			num_tile_rects++;
		}
		else
		{
			p_rects_dst++;
			p_rects_ext+=(num_match-1);
		}
		p_tile_rects++;
		num_tile_rects += num_match;
	}
	p_tile_rects-=dec_st.num_tile_rects;
	xfree(p_tile_rects);
	dec_st.num_tile_rects = num_tile_rects;

	if (dec_st.num_tile_rects > 160)
		printf("******Error : too many rectangles ( %d )******\n",dec_st.num_tile_rects);

	g_idx[disp_idx] = 1 - idx;

	//Call driver
	io_err = ioctl(priv->fd, DEV_IOCTL_DECODING, &dec_st);
	if (io_err)
		printf("Hardware decoding failed.\n");

	xfree(dec_st.p_size);
	xfree(dec_st.p_tile_rects);

}
Пример #21
0
static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, boolean user_loggedon)
{
	STREAM* data_out;
	DEVICE* device;
	LIST_ITEM* item;
	uint32 count;
	uint8 c;
	int data_len;
	int i;
	int count_pos;
	int pos;

	data_out = stream_new(256);

	stream_write_uint16(data_out, RDPDR_CTYP_CORE);
	stream_write_uint16(data_out, PAKID_CORE_DEVICELIST_ANNOUNCE);

	count_pos = stream_get_pos(data_out);
	count = 0;
	stream_seek_uint32(data_out); /* deviceCount */

	for (item = rdpdr->devman->devices->head; item; item = item->next)
	{
		device = (DEVICE*)item->data;

		/**
		 * 1. versionMinor 0x0005 doesn't send PAKID_CORE_USER_LOGGEDON
		 *    so all devices should be sent regardless of user_loggedon
		 * 2. smartcard devices should be always sent
		 * 3. other devices are sent only after user_loggedon
		 */
		if (rdpdr->versionMinor == 0x0005 ||
			device->type == RDPDR_DTYP_SMARTCARD ||
			user_loggedon)
		{
			data_len = (device->data == NULL ? 0 : stream_get_length(device->data));
			stream_check_size(data_out, 20 + data_len);

			stream_write_uint32(data_out, device->type); /* deviceType */
			stream_write_uint32(data_out, device->id); /* deviceID */
			strncpy((char*)stream_get_tail(data_out), device->name, 8);

			for (i = 0; i < 8; i++)
			{
				stream_peek_uint8(data_out, c);
				if (c > 0x7F)
					stream_write_uint8(data_out, '_');
				else
					stream_seek_uint8(data_out);
			}

			stream_write_uint32(data_out, data_len);
			if (data_len > 0)
				stream_write(data_out, stream_get_data(device->data), data_len);

			count++;
			printf("registered device #%d: %s (type=%d id=%d)\n",
				count, device->name, device->type, device->id);
		}
	}

	pos = stream_get_pos(data_out);
	stream_set_pos(data_out, count_pos);
	stream_write_uint32(data_out, count);
	stream_set_pos(data_out, pos);
	stream_seal(data_out);

	svc_plugin_send((rdpSvcPlugin*)rdpdr, data_out);
}
Пример #22
0
static void rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s)
{
	int i;
	uint16 subtype;
	uint32 blockLen;
	uint32 blockType;
	uint32 tilesDataSize;
	uint32* quants;
	uint8 quant;
	int pos;

	stream_read_uint16(s, subtype); /* subtype (2 bytes) must be set to CBT_TILESET (0xCAC2) */

	if (subtype != CBT_TILESET)
	{
		DEBUG_WARN("invalid subtype, expected CBT_TILESET.");
		return;
	}

	stream_seek_uint16(s); /* idx (2 bytes), must be set to 0x0000 */
	stream_seek_uint16(s); /* properties (2 bytes) */

	stream_read_uint8(s, context->num_quants); /* numQuant (1 byte) */
	stream_seek_uint8(s); /* tileSize (1 byte), must be set to 0x40 */

	if (context->num_quants < 1)
	{
		DEBUG_WARN("no quantization value.");
		return;
	}

	stream_read_uint16(s, message->num_tiles); /* numTiles (2 bytes) */

	if (message->num_tiles < 1)
	{
		DEBUG_WARN("no tiles.");
		return;
	}

	stream_read_uint32(s, tilesDataSize); /* tilesDataSize (4 bytes) */

	if (context->quants != NULL)
		context->quants = (uint32*) xrealloc((void*) context->quants, context->num_quants * 10 * sizeof(uint32));
	else
		context->quants = (uint32*) xmalloc(context->num_quants * 10 * sizeof(uint32));
	quants = context->quants;

	/* quantVals */
	for (i = 0; i < context->num_quants; i++)
	{
		/* RFX_CODEC_QUANT */
		stream_read_uint8(s, quant);
		*quants++ = (quant & 0x0F);
		*quants++ = (quant >> 4);
		stream_read_uint8(s, quant);
		*quants++ = (quant & 0x0F);
		*quants++ = (quant >> 4);
		stream_read_uint8(s, quant);
		*quants++ = (quant & 0x0F);
		*quants++ = (quant >> 4);
		stream_read_uint8(s, quant);
		*quants++ = (quant & 0x0F);
		*quants++ = (quant >> 4);
		stream_read_uint8(s, quant);
		*quants++ = (quant & 0x0F);
		*quants++ = (quant >> 4);

		DEBUG_RFX("quant %d (%d %d %d %d %d %d %d %d %d %d).",
			i, context->quants[i * 10], context->quants[i * 10 + 1],
			context->quants[i * 10 + 2], context->quants[i * 10 + 3],
			context->quants[i * 10 + 4], context->quants[i * 10 + 5],
			context->quants[i * 10 + 6], context->quants[i * 10 + 7],
			context->quants[i * 10 + 8], context->quants[i * 10 + 9]);
	}

	message->tiles = rfx_pool_get_tiles(context->priv->pool, message->num_tiles);

	/* tiles */
	for (i = 0; i < message->num_tiles; i++)
	{
		/* RFX_TILE */
		stream_read_uint16(s, blockType); /* blockType (2 bytes), must be set to CBT_TILE (0xCAC3) */
		stream_read_uint32(s, blockLen); /* blockLen (4 bytes) */

		pos = stream_get_pos(s) - 6 + blockLen;

		if (blockType != CBT_TILE)
		{
			DEBUG_WARN("unknown block type 0x%X, expected CBT_TILE (0xCAC3).", blockType);
			break;
		}

		rfx_process_message_tile(context, message->tiles[i], s);

		stream_set_pos(s, pos);
	}
}
Пример #23
0
boolean gcc_read_client_core_data(STREAM* s, rdpSettings *settings, uint16 blockLength)
{
	uint32 version;
	uint16 colorDepth = 0;
	uint16 postBeta2ColorDepth = 0;
	uint16 highColorDepth = 0;
	uint16 supportedColorDepths = 0;
	uint16 earlyCapabilityFlags = 0;
	uint32 serverSelectedProtocol = 0;
	char* str;

	/* Length of all required fields, until imeFileName */
	if (blockLength < 128)
		return false;

	stream_read_uint32(s, version); /* version */
	settings->rdp_version = (version == RDP_VERSION_4 ? 4 : 7);

	stream_read_uint16(s, settings->width); /* desktopWidth */
	stream_read_uint16(s, settings->height); /* desktopHeight */
	stream_read_uint16(s, colorDepth); /* colorDepth */
	stream_seek_uint16(s); /* SASSequence (Secure Access Sequence) */
	stream_read_uint32(s, settings->kbd_layout); /* keyboardLayout */
	stream_read_uint32(s, settings->client_build); /* clientBuild */
	
	/* clientName (32 bytes, null-terminated unicode, truncated to 15 characters) */
	str = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), 32);
	stream_seek(s, 32);
	snprintf(settings->client_hostname, sizeof(settings->client_hostname), "%s", str);
	xfree(str);

	stream_read_uint32(s, settings->kbd_type); /* keyboardType */
	stream_read_uint32(s, settings->kbd_subtype); /* keyboardSubType */
	stream_read_uint32(s, settings->kbd_fn_keys); /* keyboardFunctionKey */

	stream_seek(s, 64); /* imeFileName */

	blockLength -= 128;

	/**
	 * The following fields are all optional. If one field is present, all of the preceding
	 * fields MUST also be present. If one field is not present, all of the subsequent fields
	 * MUST NOT be present.
	 * We must check the bytes left before reading each field.
	 */

	do
	{
		if (blockLength < 2)
			break;
		stream_read_uint16(s, postBeta2ColorDepth); /* postBeta2ColorDepth */
		blockLength -= 2;

		if (blockLength < 2)
			break;
		stream_seek_uint16(s); /* clientProductID */
		blockLength -= 2;

		if (blockLength < 4)
			break;
		stream_seek_uint32(s); /* serialNumber */
		blockLength -= 4;

		if (blockLength < 2)
			break;
		stream_read_uint16(s, highColorDepth); /* highColorDepth */
		blockLength -= 2;

		if (blockLength < 2)
			break;
		stream_read_uint16(s, supportedColorDepths); /* supportedColorDepths */
		blockLength -= 2;

		if (blockLength < 2)
			break;
		stream_read_uint16(s, earlyCapabilityFlags); /* earlyCapabilityFlags */
		blockLength -= 2;

		if (blockLength < 64)
			break;
		str = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), 64);
		stream_seek(s, 64);
		snprintf(settings->client_product_id, sizeof(settings->client_product_id), "%s", str);
		xfree(str);
		blockLength -= 64;

		if (blockLength < 1)
			break;
		stream_read_uint8(s, settings->performance_flags); /* connectionType */
		blockLength -= 1;

		if (blockLength < 1)
			break;
		stream_seek_uint8(s); /* pad1octet */
		blockLength -= 1;

		if (blockLength < 4)
			break;
		stream_read_uint32(s, serverSelectedProtocol); /* serverSelectedProtocol */
		blockLength -= 4;

		if (settings->selected_protocol != serverSelectedProtocol)
			return false;
	} while (0);

	if (highColorDepth > 0)
		settings->color_depth = highColorDepth;
	else if (postBeta2ColorDepth > 0)
	{
		switch (postBeta2ColorDepth)
		{
			case RNS_UD_COLOR_4BPP:
				settings->color_depth = 4;
				break;
			case RNS_UD_COLOR_8BPP:
				settings->color_depth = 8;
				break;
			case RNS_UD_COLOR_16BPP_555:
				settings->color_depth = 15;
				break;
			case RNS_UD_COLOR_16BPP_565:
				settings->color_depth = 16;
				break;
			case RNS_UD_COLOR_24BPP:
				settings->color_depth = 24;
				break;
			default:
				return false;
		}
	}
	else
	{
		switch (colorDepth)
		{
			case RNS_UD_COLOR_4BPP:
				settings->color_depth = 4;
				break;
			case RNS_UD_COLOR_8BPP:
				settings->color_depth = 8;
				break;
			default:
				return false;
		}
	}

	return true;
}