Exemple #1
0
BOOL rdp_recv_client_font_map_pdu(rdpRdp* rdp, STREAM* s)
{
	rdp->finalize_sc_pdus |= FINALIZE_SC_FONT_MAP_PDU;

	stream_seek_UINT16(s); /* numberEntries (2 bytes) */
	stream_seek_UINT16(s); /* totalNumEntries (2 bytes) */
	stream_seek_UINT16(s); /* mapFlags (2 bytes) */
	stream_seek_UINT16(s); /* entrySize (2 bytes) */

	return TRUE;
}
Exemple #2
0
static void cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, wStream* s, UINT16 length, UINT16 flags)
{
	int i;
	UINT16 lengthCapability;
	UINT16 cCapabilitiesSets;
	UINT16 capabilitySetType;

	stream_read_UINT16(s, cCapabilitiesSets); /* cCapabilitiesSets (2 bytes) */
	stream_seek_UINT16(s); /* pad1 (2 bytes) */

	DEBUG_CLIPRDR("cCapabilitiesSets %d", cCapabilitiesSets);

	for (i = 0; i < cCapabilitiesSets; i++)
	{
		stream_read_UINT16(s, capabilitySetType); /* capabilitySetType (2 bytes) */
		stream_read_UINT16(s, lengthCapability); /* lengthCapability (2 bytes) */

		switch (capabilitySetType)
		{
			case CB_CAPSTYPE_GENERAL:
				cliprdr_process_general_capability(cliprdr, s);
				break;

			default:
				DEBUG_WARN("unknown cliprdr capability set: %d", capabilitySetType);
				break;
		}
	}
}
Exemple #3
0
BOOL 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_BYTE(s); /* pad2Octets (1 byte) */
	return TRUE;
}
Exemple #4
0
static BOOL 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_BYTE(s); /* cLastBlockConfirmed */
	stream_seek_UINT16(s); /* wVersion */
	stream_seek_BYTE(s); /* bPad */

	if (rdpsnd->context.num_client_formats > 0)
	{
		rdpsnd->context.client_formats = (rdpsndFormat*) malloc(rdpsnd->context.num_client_formats * sizeof(rdpsndFormat));
		ZeroMemory(rdpsnd->context.client_formats, sizeof(rdpsndFormat));

		for (i = 0; i < rdpsnd->context.num_client_formats; i++)
		{
			if (stream_get_left(s) < 18)
			{
				free(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;
}
Exemple #5
0
BOOL update_recv_orders(rdpUpdate* update, STREAM* s)
{
	UINT16 numberOrders;

	stream_seek_UINT16(s); /* pad2OctetsA (2 bytes) */
	stream_read_UINT16(s, numberOrders); /* numberOrders (2 bytes) */
	stream_seek_UINT16(s); /* pad2OctetsB (2 bytes) */

	while (numberOrders > 0)
	{
		if (!update_recv_order(update, s))
			return FALSE;
		numberOrders--;
	}

	return TRUE;
}
Exemple #6
0
void rail_read_server_exec_result_order(STREAM* s, RAIL_EXEC_RESULT_ORDER* exec_result)
{
	stream_read_UINT16(s, exec_result->flags); /* flags (2 bytes) */
	stream_read_UINT16(s, exec_result->execResult); /* execResult (2 bytes) */
	stream_read_UINT32(s, exec_result->rawResult); /* rawResult (4 bytes) */
	stream_seek_UINT16(s); /* padding (2 bytes) */
	rail_read_unicode_string(s, &exec_result->exeOrFile); /* exeOrFile */
}
Exemple #7
0
void update_read_synchronize(rdpUpdate* update, STREAM* s)
{
	stream_seek_UINT16(s); /* pad2Octets (2 bytes) */

	/**
	 * The Synchronize Update is an artifact from the
	 * T.128 protocol and should be ignored.
	 */
}
Exemple #8
0
BOOL rdp_recv_control_pdu(STREAM* s, UINT16* action)
{
	if (stream_get_left(s) < 8)
		return FALSE;

	stream_read_UINT16(s, *action); /* action (2 bytes) */
	stream_seek_UINT16(s); /* grantId (2 bytes) */
	stream_seek_UINT32(s); /* controlId (4 bytes) */

	return TRUE;
}
Exemple #9
0
BOOL rdp_recv_client_synchronize_pdu(rdpRdp* rdp, STREAM* s)
{
	UINT16 messageType;

	rdp->finalize_sc_pdus |= FINALIZE_SC_SYNCHRONIZE_PDU;

	if (stream_get_left(s) < 4)
		return FALSE;

	stream_read_UINT16(s, messageType); /* messageType (2 bytes) */

	if (messageType != SYNCMSGTYPE_SYNC)
		return FALSE;

	/* targetUser (2 bytes) */
	stream_seek_UINT16(s);

	return TRUE;
}
Exemple #10
0
void update_read_palette(rdpUpdate* update, STREAM* s, PALETTE_UPDATE* palette_update)
{
	int i;
	PALETTE_ENTRY* entry;

	stream_seek_UINT16(s); /* pad2Octets (2 bytes) */
	stream_read_UINT32(s, palette_update->number); /* numberColors (4 bytes), must be set to 256 */

	if (palette_update->number > 256)
		palette_update->number = 256;

	/* paletteEntries */
	for (i = 0; i < (int) palette_update->number; i++)
	{
		entry = &palette_update->entries[i];

		stream_read_BYTE(s, entry->blue);
		stream_read_BYTE(s, entry->green);
		stream_read_BYTE(s, entry->red);
	}
}
Exemple #11
0
void update_recv_pointer(rdpUpdate* update, STREAM* s)
{
	UINT16 messageType;
	rdpContext* context = update->context;
	rdpPointerUpdate* pointer = update->pointer;

	stream_read_UINT16(s, messageType); /* messageType (2 bytes) */
	stream_seek_UINT16(s); /* pad2Octets (2 bytes) */

	switch (messageType)
	{
		case PTR_MSG_TYPE_POSITION:
			update_read_pointer_position(s, &pointer->pointer_position);
			IFCALL(pointer->PointerPosition, context, &pointer->pointer_position);
			break;

		case PTR_MSG_TYPE_SYSTEM:
			update_read_pointer_system(s, &pointer->pointer_system);
			IFCALL(pointer->PointerSystem, context, &pointer->pointer_system);
			break;

		case PTR_MSG_TYPE_COLOR:
			update_read_pointer_color(s, &pointer->pointer_color);
			IFCALL(pointer->PointerColor, context, &pointer->pointer_color);
			break;

		case PTR_MSG_TYPE_POINTER:
			update_read_pointer_new(s, &pointer->pointer_new);
			IFCALL(pointer->PointerNew, context, &pointer->pointer_new);
			break;

		case PTR_MSG_TYPE_CACHED:
			update_read_pointer_cached(s, &pointer->pointer_cached);
			IFCALL(pointer->PointerCached, context, &pointer->pointer_cached);
			break;

		default:
			break;
	}
}
Exemple #12
0
static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s)
{
	int i;
	int pos;
	BYTE quant;
	UINT32* quants;
	UINT16 subtype;
	UINT32 blockLen;
	UINT32 blockType;
	UINT32 tilesDataSize;
	PTP_WORK* work_objects = NULL;
	RFX_TILE_WORK_PARAM* params = NULL;

	if (stream_get_left(s) < 14)
	{
		DEBUG_WARN("RfxMessageTileSet packet too small");
		return FALSE;
	}

	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 FALSE;
	}

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

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

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

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

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

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

	if (context->quants != NULL)
		context->quants = (UINT32*) realloc((void*) context->quants, context->num_quants * 10 * sizeof(UINT32));
	else
		context->quants = (UINT32*) malloc(context->num_quants * 10 * sizeof(UINT32));
	quants = context->quants;

	/* quantVals */
	if (stream_get_left(s) < context->num_quants * 5)
	{
		DEBUG_WARN("RfxMessageTileSet packet too small for num_quants=%d", context->num_quants);
		return FALSE;
	}

	for (i = 0; i < context->num_quants; i++)
	{
		/* RFX_CODEC_QUANT */
		stream_read_BYTE(s, quant);
		*quants++ = (quant & 0x0F);
		*quants++ = (quant >> 4);
		stream_read_BYTE(s, quant);
		*quants++ = (quant & 0x0F);
		*quants++ = (quant >> 4);
		stream_read_BYTE(s, quant);
		*quants++ = (quant & 0x0F);
		*quants++ = (quant >> 4);
		stream_read_BYTE(s, quant);
		*quants++ = (quant & 0x0F);
		*quants++ = (quant >> 4);
		stream_read_BYTE(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_TILE**) malloc(sizeof(RFX_TILE*) * message->num_tiles);
	ZeroMemory(message->tiles, sizeof(RFX_TILE*) * message->num_tiles);

	if (context->priv->UseThreads)
	{
		work_objects = (PTP_WORK*) malloc(sizeof(PTP_WORK) * message->num_tiles);
		params = (RFX_TILE_WORK_PARAM*) malloc(sizeof(RFX_TILE_WORK_PARAM) * message->num_tiles);
	}

	/* tiles */
	for (i = 0; i < message->num_tiles; i++)
	{
		/* RFX_TILE */
		if (stream_get_left(s) < 6)
		{
			DEBUG_WARN("RfxMessageTileSet packet too small to read tile %d/%d", i, message->num_tiles);
			return FALSE;
		}

		stream_read_UINT16(s, blockType); /* blockType (2 bytes), must be set to CBT_TILE (0xCAC3) */
		stream_read_UINT32(s, blockLen); /* blockLen (4 bytes) */

		if (stream_get_left(s) < blockLen - 6)
		{
			DEBUG_WARN("RfxMessageTileSet not enough bytes to read tile %d/%d with blocklen=%d", i, message->num_tiles, blockLen);
			return FALSE;
		}

		pos = stream_get_pos(s) - 6 + blockLen;

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

		message->tiles[i] = rfx_tile_pool_take(context);

		if (context->priv->UseThreads)
		{
			params[i].context = context;
			params[i].tile = message->tiles[i];
			CopyMemory(&(params[i].s), s, sizeof(STREAM));

			work_objects[i] = CreateThreadpoolWork((PTP_WORK_CALLBACK) rfx_process_message_tile_work_callback,
					(void*) &params[i], &context->priv->ThreadPoolEnv);

			SubmitThreadpoolWork(work_objects[i]);
		}
		else
		{
			rfx_process_message_tile(context, message->tiles[i], s);
		}

		stream_set_pos(s, pos);
	}

	if (context->priv->UseThreads)
	{
		for (i = 0; i < message->num_tiles; i++)
			WaitForThreadpoolWorkCallbacks(work_objects[i], FALSE);

		free(work_objects);
		free(params);
	}
	return TRUE;
}
Exemple #13
0
BOOL gcc_read_client_core_data(STREAM* s, rdpSettings* settings, UINT16 blockLength)
{
	char* str;
	UINT32 version;
	UINT32 color_depth;
	UINT16 colorDepth = 0;
	UINT16 postBeta2ColorDepth = 0;
	UINT16 highColorDepth = 0;
	UINT16 supportedColorDepths = 0;
	UINT16 earlyCapabilityFlags = 0;
	UINT32 serverSelectedProtocol = 0;

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

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

	stream_read_UINT16(s, settings->DesktopWidth); /* DesktopWidth */
	stream_read_UINT16(s, settings->DesktopHeight); /* DesktopHeight */
	stream_read_UINT16(s, colorDepth); /* ColorDepth */
	stream_seek_UINT16(s); /* SASSequence (Secure Access Sequence) */
	stream_read_UINT32(s, settings->KeyboardLayout); /* KeyboardLayout */
	stream_read_UINT32(s, settings->ClientBuild); /* ClientBuild */

	/* clientName (32 bytes, null-terminated unicode, truncated to 15 characters) */
	ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(s), 32 / 2, &str, 0, NULL, NULL);
	stream_seek(s, 32);
	sprintf_s(settings->ClientHostname, 31, "%s", str);
	settings->ClientHostname[31] = 0;
	free(str);

	stream_read_UINT32(s, settings->KeyboardType); /* KeyboardType */
	stream_read_UINT32(s, settings->KeyboardSubType); /* KeyboardSubType */
	stream_read_UINT32(s, settings->KeyboardFunctionKey); /* 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;

		ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(s), 64 / 2, &str, 0, NULL, NULL);
		stream_seek(s, 64);
		sprintf_s(settings->ClientProductId, 32, "%s", str);
		free(str);
		blockLength -= 64;

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

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

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

		if (settings->SelectedProtocol != serverSelectedProtocol)
			return FALSE;
	} while (0);

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

	/*
	 * If we are in server mode, accept client's color depth only if
	 * it is smaller than ours. This is what Windows server does.
	 */
	if (color_depth < settings->ColorDepth || !settings->ServerMode)
		settings->ColorDepth = color_depth;

	return TRUE;
}
Exemple #14
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;
	BYTE 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_BYTE(s, context->num_quants); /* numQuant (1 byte) */
	stream_seek_BYTE(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*) realloc((void*) context->quants, context->num_quants * 10 * sizeof(UINT32));
	else
		context->quants = (UINT32*) malloc(context->num_quants * 10 * sizeof(UINT32));
	quants = context->quants;

	/* quantVals */
	for (i = 0; i < context->num_quants; i++)
	{
		/* RFX_CODEC_QUANT */
		stream_read_BYTE(s, quant);
		*quants++ = (quant & 0x0F);
		*quants++ = (quant >> 4);
		stream_read_BYTE(s, quant);
		*quants++ = (quant & 0x0F);
		*quants++ = (quant >> 4);
		stream_read_BYTE(s, quant);
		*quants++ = (quant & 0x0F);
		*quants++ = (quant >> 4);
		stream_read_BYTE(s, quant);
		*quants++ = (quant & 0x0F);
		*quants++ = (quant >> 4);
		stream_read_BYTE(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);
	}
}