コード例 #1
0
ファイル: test_stream.c プロジェクト: felfert/FreeRDP
void test_stream(void)
{
	STREAM * stream;
	int pos;
	uint32 n;
	uint64 n64;

	stream = stream_new(1);
	pos = stream_get_pos(stream);

	stream_write_uint8(stream, 0xFE);

	stream_check_size(stream, 14);
	stream_write_uint16(stream, 0x0102);
	stream_write_uint32(stream, 0x03040506);
	stream_write_uint64(stream, 0x0708091011121314LL);

	/* freerdp_hexdump(stream->buffer, 15); */

	stream_set_pos(stream, pos);
	stream_seek(stream, 3);
	stream_read_uint32(stream, n);
	stream_read_uint64(stream, n64);

	CU_ASSERT(n == 0x03040506);
	CU_ASSERT(n64 == 0x0708091011121314LL);

	stream_free(stream);
}
コード例 #2
0
ファイル: surface.c プロジェクト: sgillani/FreeRDP
static BOOL update_recv_surfcmd_surface_bits(rdpUpdate* update, STREAM* s, UINT32 *length)
{
	int pos;
	SURFACE_BITS_COMMAND* cmd = &update->surface_bits_command;

	if(stream_get_left(s) < 20)
		return FALSE;
	stream_read_UINT16(s, cmd->destLeft);
	stream_read_UINT16(s, cmd->destTop);
	stream_read_UINT16(s, cmd->destRight);
	stream_read_UINT16(s, cmd->destBottom);
	stream_read_BYTE(s, cmd->bpp);
	stream_seek(s, 2); /* reserved1, reserved2 */
	stream_read_BYTE(s, cmd->codecID);
	stream_read_UINT16(s, cmd->width);
	stream_read_UINT16(s, cmd->height);
	stream_read_UINT32(s, cmd->bitmapDataLength);
	if(stream_get_left(s) < cmd->bitmapDataLength)
		return FALSE;
	pos = stream_get_pos(s) + cmd->bitmapDataLength;
	cmd->bitmapData = stream_get_tail(s);

	IFCALL(update->SurfaceBits, update->context, cmd);

	stream_set_pos(s, pos);

	*length = 20 + cmd->bitmapDataLength;
	return TRUE;
}
コード例 #3
0
ファイル: rfx.c プロジェクト: nour8394/FreeRDP
static void rfx_compose_message_tile(RFX_CONTEXT* context, STREAM* s,
	BYTE* tile_data, int tile_width, int tile_height, int rowstride,
	const UINT32* quantVals, int quantIdxY, int quantIdxCb, int quantIdxCr,
	int xIdx, int yIdx)
{
	int YLen = 0;
	int CbLen = 0;
	int CrLen = 0;
	int start_pos, end_pos;

	stream_check_size(s, 19);
	start_pos = stream_get_pos(s);

	stream_write_UINT16(s, CBT_TILE); /* BlockT.blockType */
	stream_seek_UINT32(s); /* set BlockT.blockLen later */
	stream_write_BYTE(s, quantIdxY);
	stream_write_BYTE(s, quantIdxCb);
	stream_write_BYTE(s, quantIdxCr);
	stream_write_UINT16(s, xIdx);
	stream_write_UINT16(s, yIdx);

	stream_seek(s, 6); /* YLen, CbLen, CrLen */

	rfx_encode_rgb(context, tile_data, tile_width, tile_height, rowstride,
		quantVals + quantIdxY * 10, quantVals + quantIdxCb * 10, quantVals + quantIdxCr * 10,
		s, &YLen, &CbLen, &CrLen);

	DEBUG_RFX("xIdx=%d yIdx=%d width=%d height=%d YLen=%d CbLen=%d CrLen=%d",
		xIdx, yIdx, tile_width, tile_height, YLen, CbLen, CrLen);

	end_pos = stream_get_pos(s);

	stream_set_pos(s, start_pos + 2);
	stream_write_UINT32(s, 19 + YLen + CbLen + CrLen); /* BlockT.blockLen */
	stream_set_pos(s, start_pos + 13);
	stream_write_UINT16(s, YLen);
	stream_write_UINT16(s, CbLen);
	stream_write_UINT16(s, CrLen);

	stream_set_pos(s, end_pos);
}
コード例 #4
0
ファイル: drdynvc_main.c プロジェクト: bradh/FreeRDP-1.0
static int drdynvc_process_data(drdynvcPlugin* drdynvc, int Sp, int cbChId, STREAM* data_in, int in_length)
{
	int pos;
	uint32 ChannelId;

	ChannelId = drdynvc_read_variable_uint(data_in, cbChId);
	pos = stream_get_pos(data_in);
	DEBUG_DVC("ChannelId=%d", ChannelId);

	return dvcman_receive_channel_data(drdynvc->channel_mgr, ChannelId,
		stream_get_tail(data_in), in_length - pos);
}
コード例 #5
0
ファイル: cliprdr_main.c プロジェクト: adambprotiviti/FreeRDP
void cliprdr_packet_send(cliprdrPlugin* cliprdr, STREAM* s)
{
	int pos;
	uint32 dataLen;

	pos = stream_get_pos(s);
	dataLen = pos - 8;
	stream_set_pos(s, 4);
	stream_write_uint32(s, dataLen);
	stream_set_pos(s, pos);

	svc_plugin_send((rdpSvcPlugin*) cliprdr, s);
}
コード例 #6
0
ファイル: stream.c プロジェクト: roman-b/FreeRDP-1.0
void stream_extend(STREAM* stream, int request_size)
{
	int original_size;
	int increased_size;
	int pos;

	pos = stream_get_pos(stream);
	original_size = stream->size;
	increased_size = (request_size > original_size ? request_size : original_size);
	stream->size += increased_size;
	stream->data = (uint8*)xrealloc(stream->data, stream->size);
	memset(stream->data + original_size, 0, increased_size);
	stream_set_pos(stream, pos);
}
コード例 #7
0
ファイル: gcc.c プロジェクト: Arkantos7/FreeRDP
BOOL gcc_read_client_data_blocks(STREAM* s, rdpSettings* settings, int length)
{
	UINT16 type;
	UINT16 blockLength;
	int pos;

	while (length > 0)
	{
		pos = stream_get_pos(s);
		gcc_read_user_data_header(s, &type, &blockLength);

		switch (type)
		{
			case CS_CORE:
				if (!gcc_read_client_core_data(s, settings, blockLength - 4))
					return FALSE;
				break;

			case CS_SECURITY:
				if (!gcc_read_client_security_data(s, settings, blockLength - 4))
					return FALSE;
				break;

			case CS_NET:
				if (!gcc_read_client_network_data(s, settings, blockLength - 4))
					return FALSE;
				break;

			case CS_CLUSTER:
				if (!gcc_read_client_cluster_data(s, settings, blockLength - 4))
					return FALSE;
				break;

			case CS_MONITOR:
				if (!gcc_read_client_monitor_data(s, settings, blockLength - 4))
					return FALSE;
				break;

			default:
				break;
		}

		length -= blockLength;
		stream_set_pos(s, pos + blockLength);
	}

	return TRUE;
}
コード例 #8
0
ファイル: irp.c プロジェクト: felfert/FreeRDP
static void irp_complete(IRP* irp)
{
	int pos;

	DEBUG_SVC("DeviceId %d FileId %d CompletionId %d", irp->device->id, irp->FileId, irp->CompletionId);

	pos = stream_get_pos(irp->output);
	stream_set_pos(irp->output, 12);
	stream_write_uint32(irp->output, irp->IoStatus);
	stream_set_pos(irp->output, pos);

	svc_plugin_send(irp->devman->plugin, irp->output);
	irp->output = NULL;

	irp_free(irp);
}
コード例 #9
0
ファイル: scard_main.c プロジェクト: rafcabezas/FreeRDP
static void 
scard_irp_complete(IRP* irp)
{
/* This function is (mostly) a copy of the statically-declared "irp_complete()" 
 * function except that this function adds extra operations for the 
 * smart card's handling of duplicate "CompletionID"s.  This function needs 
 * to be in this file so that "scard_irp_request()" can reference it.
 */
	int pos;
	boolean duplicate;
	SCARD_DEVICE* scard = (SCARD_DEVICE*)irp->device;

	DEBUG_SVC("DeviceId %d FileId %d CompletionId %d", irp->device->id, irp->FileId, irp->CompletionId);

	pos = stream_get_pos(irp->output);
	stream_set_pos(irp->output, 12);
	stream_write_uint32(irp->output, irp->IoStatus);
	stream_set_pos(irp->output, pos);

	/* Begin TS Client defect workaround. */
	freerdp_mutex_lock(scard->CompletionIdsMutex);
	/* Remove from the list the item identified by the CompletionID.
	 * The function returns whether or not it was a duplicate CompletionID.
	 */
	duplicate = scard_check_for_duplicate_id(scard, irp->CompletionId);
	freerdp_mutex_unlock(scard->CompletionIdsMutex);

	if (false == duplicate)
	{
	        svc_plugin_send(irp->devman->plugin, irp->output);
		irp->output = NULL;
	}
	/* End TS Client defect workaround. */

	/* irp_free(irp); 	The "irp_free()" function is statically-declared
	 * 			and so is not available to be called
	 * 			here.  Instead, call it indirectly by calling
	 * 			the IRP's "Discard()" function,
	 * 			which has already been assigned 
	 * 			to point to "irp_free()" in "irp_new()".
	 */
	irp->Discard(irp);
}
コード例 #10
0
ファイル: serial_main.c プロジェクト: rafcabezas/FreeRDP
void serial_get_timeouts(SERIAL_DEVICE* serial, IRP* irp, uint32* timeout, uint32* interval_timeout)
{
    SERIAL_TTY* tty;
    uint32 Length;
    uint32 pos;

    pos = stream_get_pos(irp->input);
    stream_read_uint32(irp->input, Length);
    stream_set_pos(irp->input, pos);

    DEBUG_SVC("length read %u", Length);

    tty = serial->tty;
    *timeout = (tty->read_total_timeout_multiplier * Length) +
               tty->read_total_timeout_constant;
    *interval_timeout = tty->read_interval_timeout;

    DEBUG_SVC("timeouts %u %u", *timeout, *interval_timeout);
}
コード例 #11
0
ファイル: drdynvc_main.c プロジェクト: mgariepy/FreeRDP
static int drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, int cbChId, STREAM* s)
{
	int pos;
	int error;
	UINT32 ChannelId;
	STREAM* data_out;

	ChannelId = drdynvc_read_variable_uint(s, cbChId);
	pos = stream_get_pos(s);
	DEBUG_DVC("ChannelId=%d ChannelName=%s", ChannelId, stream_get_tail(s));

	error = dvcman_create_channel(drdynvc->channel_mgr, ChannelId, (char*) stream_get_tail(s));

	data_out = stream_new(pos + 4);
	stream_write_BYTE(data_out, 0x10 | cbChId);
	stream_set_pos(s, 1);
	stream_copy(data_out, s, pos - 1);
	
	if (error == 0)
	{
		DEBUG_DVC("channel created");
		stream_write_UINT32(data_out, 0);
	}
	else
	{
		DEBUG_DVC("no listener");
		stream_write_UINT32(data_out, (UINT32)(-1));
	}

	error = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out);

	if (error != CHANNEL_RC_OK)
	{
		DEBUG_WARN("VirtualChannelWrite failed %d", error);
		return 1;
	}

	return 0;
}
コード例 #12
0
ファイル: surface.c プロジェクト: johnsonyes/FreeRDP
static int update_recv_surfcmd_surface_bits(rdpUpdate* update, STREAM* s)
{
	int pos;
	SURFACE_BITS_COMMAND* cmd = &update->surface_bits_command;

	stream_read_uint16(s, cmd->destLeft);
	stream_read_uint16(s, cmd->destTop);
	stream_read_uint16(s, cmd->destRight);
	stream_read_uint16(s, cmd->destBottom);
	stream_read_uint8(s, cmd->bpp);
	stream_seek(s, 2); /* reserved1, reserved2 */
	stream_read_uint8(s, cmd->codecID);
	stream_read_uint16(s, cmd->width);
	stream_read_uint16(s, cmd->height);
	stream_read_uint32(s, cmd->bitmapDataLength);
	pos = stream_get_pos(s) + cmd->bitmapDataLength;
	cmd->bitmapData = stream_get_tail(s);

	IFCALL(update->SurfaceBits, update->context, cmd);

	stream_set_pos(s, pos);

	return 20 + cmd->bitmapDataLength;
}
コード例 #13
0
ファイル: rfx.c プロジェクト: nour8394/FreeRDP
RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, BYTE* data, UINT32 length)
{
	int pos;
	STREAM* s;
	UINT32 blockLen;
	UINT32 blockType;
	RFX_MESSAGE* message;

	message = (RFX_MESSAGE*) malloc(sizeof(RFX_MESSAGE));
	ZeroMemory(message, sizeof(RFX_MESSAGE));

	s = stream_new(0);
	stream_attach(s, data, length);

	while (stream_get_left(s) > 6)
	{
		/* RFX_BLOCKT */
		stream_read_UINT16(s, blockType); /* blockType (2 bytes) */
		stream_read_UINT32(s, blockLen); /* blockLen (4 bytes) */

		DEBUG_RFX("blockType 0x%X blockLen %d", blockType, blockLen);

		if (blockLen == 0)
		{
			DEBUG_WARN("zero blockLen");
			break;
		}

		if (stream_get_left(s) < blockLen - 6)
		{
			DEBUG_WARN("rfx_process_message: packet too small for blocklen=%d", blockLen);
			break;
		}


		pos = stream_get_pos(s) - 6 + blockLen;

		if (blockType >= WBT_CONTEXT && blockType <= WBT_EXTENSION)
		{
			/* RFX_CODEC_CHANNELT */
			/* codecId (1 byte) must be set to 0x01 */
			/* channelId (1 byte) must be set to 0x00 */
			if (!stream_skip(s, 2))
			{
				DEBUG_WARN("rfx_process_message: unable to skip RFX_CODEC_CHANNELT");
				break;
			}
		}

		switch (blockType)
		{
			case WBT_SYNC:
				rfx_process_message_sync(context, s);
				break;

			case WBT_CODEC_VERSIONS:
				rfx_process_message_codec_versions(context, s);
				break;

			case WBT_CHANNELS:
				rfx_process_message_channels(context, s);
				break;

			case WBT_CONTEXT:
				rfx_process_message_context(context, s);
				break;

			case WBT_FRAME_BEGIN:
				rfx_process_message_frame_begin(context, message, s);
				break;

			case WBT_FRAME_END:
				rfx_process_message_frame_end(context, message, s);
				break;

			case WBT_REGION:
				rfx_process_message_region(context, message, s);
				break;

			case WBT_EXTENSION:
				rfx_process_message_tileset(context, message, s);
				break;

			default:
				DEBUG_WARN("unknown blockType 0x%X", blockType);
				break;
		}

		stream_set_pos(s, pos);
	}

	stream_detach(s);
	stream_free(s);

	return message;
}
コード例 #14
0
ファイル: rfx.c プロジェクト: nour8394/FreeRDP
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;
}
コード例 #15
0
ファイル: rfx.c プロジェクト: nour8394/FreeRDP
static void rfx_compose_message_tileset(RFX_CONTEXT* context, STREAM* s,
	BYTE* image_data, int width, int height, int rowstride)
{
	int i;
	int size;
	int start_pos, end_pos;
	int numQuants;
	const UINT32* quantVals;
	const UINT32* quantValsPtr;
	int quantIdxY;
	int quantIdxCb;
	int quantIdxCr;
	int numTiles;
	int numTilesX;
	int numTilesY;
	int xIdx;
	int yIdx;
	int tilesDataSize;

	if (context->num_quants == 0)
	{
		numQuants = 1;
		quantVals = rfx_default_quantization_values;
		quantIdxY = 0;
		quantIdxCb = 0;
		quantIdxCr = 0;
	}
	else
	{
		numQuants = context->num_quants;
		quantVals = context->quants;
		quantIdxY = context->quant_idx_y;
		quantIdxCb = context->quant_idx_cb;
		quantIdxCr = context->quant_idx_cr;
	}

	numTilesX = (width + 63) / 64;
	numTilesY = (height + 63) / 64;
	numTiles = numTilesX * numTilesY;

	size = 22 + numQuants * 5;
	stream_check_size(s, size);
	start_pos = stream_get_pos(s);

	stream_write_UINT16(s, WBT_EXTENSION); /* CodecChannelT.blockType */
	stream_seek_UINT32(s); /* set CodecChannelT.blockLen later */
	stream_write_BYTE(s, 1); /* CodecChannelT.codecId */
	stream_write_BYTE(s, 0); /* CodecChannelT.channelId */
	stream_write_UINT16(s, CBT_TILESET); /* subtype */
	stream_write_UINT16(s, 0); /* idx */
	stream_write_UINT16(s, context->properties); /* properties */
	stream_write_BYTE(s, numQuants); /* numQuants */
	stream_write_BYTE(s, 0x40); /* tileSize */
	stream_write_UINT16(s, numTiles); /* numTiles */
	stream_seek_UINT32(s); /* set tilesDataSize later */

	quantValsPtr = quantVals;
	for (i = 0; i < numQuants * 5; i++)
	{
		stream_write_BYTE(s, quantValsPtr[0] + (quantValsPtr[1] << 4));
		quantValsPtr += 2;
	}

	DEBUG_RFX("width:%d height:%d rowstride:%d", width, height, rowstride);

	end_pos = stream_get_pos(s);
	for (yIdx = 0; yIdx < numTilesY; yIdx++)
	{
		for (xIdx = 0; xIdx < numTilesX; xIdx++)
		{
			rfx_compose_message_tile(context, s,
				image_data + yIdx * 64 * rowstride + xIdx * 8 * context->bits_per_pixel,
				(xIdx < numTilesX - 1) ? 64 : width - xIdx * 64,
				(yIdx < numTilesY - 1) ? 64 : height - yIdx * 64,
				rowstride, quantVals, quantIdxY, quantIdxCb, quantIdxCr, xIdx, yIdx);
		}
	}
	tilesDataSize = stream_get_pos(s) - end_pos;
	size += tilesDataSize;
	end_pos = stream_get_pos(s);

	stream_set_pos(s, start_pos + 2);
	stream_write_UINT32(s, size); /* CodecChannelT.blockLen */
	stream_set_pos(s, start_pos + 18);
	stream_write_UINT32(s, tilesDataSize);

	stream_set_pos(s, end_pos);
}
コード例 #16
0
ファイル: rdpsnd_main.c プロジェクト: rafcabezas/FreeRDP
/* 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);
	}
}
コード例 #17
0
ファイル: drdynvc_main.c プロジェクト: bradh/FreeRDP-1.0
int drdynvc_write_data(drdynvcPlugin* drdynvc, uint32 ChannelId, char* data, uint32 data_size)
{
	STREAM* data_out;
	uint32 pos = 0;
	uint32 cbChId;
	uint32 cbLen;
	uint32 chunk_len;
	int error;

	DEBUG_DVC("ChannelId=%d size=%d", ChannelId, data_size);

	data_out = stream_new(CHANNEL_CHUNK_LENGTH);
	stream_set_pos(data_out, 1);
	cbChId = drdynvc_write_variable_uint(data_out, ChannelId);

	if (data_size <= CHANNEL_CHUNK_LENGTH - pos)
	{
		pos = stream_get_pos(data_out);
		stream_set_pos(data_out, 0);
		stream_write_uint8(data_out, 0x30 | cbChId);
		stream_set_pos(data_out, pos);
		stream_write(data_out, data, data_size);
		error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out);
	}
	else
	{
		/* Fragment the data */
		cbLen = drdynvc_write_variable_uint(data_out, data_size);
		pos = stream_get_pos(data_out);
		stream_set_pos(data_out, 0);
		stream_write_uint8(data_out, 0x20 | cbChId | (cbLen << 2));
		stream_set_pos(data_out, pos);
		chunk_len = CHANNEL_CHUNK_LENGTH - pos;
		stream_write(data_out, data, chunk_len);
		data += chunk_len;
		data_size -= chunk_len;
		error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out);

		while (error == CHANNEL_RC_OK && data_size > 0)
		{
			data_out = stream_new(CHANNEL_CHUNK_LENGTH);
			stream_set_pos(data_out, 1);
			cbChId = drdynvc_write_variable_uint(data_out, ChannelId);

			pos = stream_get_pos(data_out);
			stream_set_pos(data_out, 0);
			stream_write_uint8(data_out, 0x30 | cbChId);
			stream_set_pos(data_out, pos);

			chunk_len = data_size;
			if (chunk_len > CHANNEL_CHUNK_LENGTH - pos)
				chunk_len = CHANNEL_CHUNK_LENGTH - pos;
			stream_write(data_out, data, chunk_len);
			data += chunk_len;
			data_size -= chunk_len;
			error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out);
		}
	}
	if (error != CHANNEL_RC_OK)
	{
		DEBUG_WARN("VirtualChannelWrite failed %d", error);
		return 1;
	}
	return 0;
}
コード例 #18
0
ファイル: rfx.c プロジェクト: Arkantos7/FreeRDP
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);
	}
}
コード例 #19
0
static uint32 handle_ListReaders(IRP* irp, tbool wide)
{
	uint32 len, rv;
	SCARDCONTEXT hContext;
	DWORD dwReaders;
	char *readerList = NULL, *walker;
	int elemLength, dataLength;
	int pos, poslen1, poslen2;

	stream_seek(irp->input, 8);
	stream_read_uint32(irp->input, len);

	stream_seek(irp->input, 0x1c);
	stream_read_uint32(irp->input, len);

	if (len != 4)
		return SCARD_F_INTERNAL_ERROR;

	stream_read_uint32(irp->input, hContext);

	/* ignore rest of [MS-RDPESC] 2.2.2.4 ListReaders_Call */

	rv = SCARD_S_SUCCESS;
#ifdef SCARD_AUTOALLOCATE
	dwReaders = SCARD_AUTOALLOCATE;
	rv = SCardListReaders(hContext, NULL, (LPSTR) &readerList, &dwReaders);
#else
	rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);

	readerList = xmalloc(dwReaders);
	rv = SCardListReaders(hContext, NULL, readerList, &dwReaders);
#endif
	if (rv != SCARD_S_SUCCESS)
	{
		DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv);
		return rv;
	}

/*	DEBUG_SCARD("Success 0x%08x %d %d", (unsigned) hContext, (unsigned) cchReaders, (int) strlen(readerList));*/

	poslen1 = stream_get_pos(irp->output);
	stream_seek_uint32(irp->output);

	stream_write_uint32(irp->output, 0x01760650);

	poslen2 = stream_get_pos(irp->output);
	stream_seek_uint32(irp->output);

	walker = readerList;
	dataLength = 0;

	while (1)
	{
		elemLength = strlen(walker);
		if (elemLength == 0)
			break;

		dataLength += sc_output_string(irp, walker, wide);
		walker += elemLength + 1;
		elemLength = strlen(walker);
	}

	dataLength += sc_output_string(irp, "\0", wide);

	pos = stream_get_pos(irp->output);

	stream_set_pos(irp->output, poslen1);
	stream_write_uint32(irp->output, dataLength);
	stream_set_pos(irp->output, poslen2);
	stream_write_uint32(irp->output, dataLength);

	stream_set_pos(irp->output, pos);

	sc_output_repos(irp, dataLength);
	sc_output_alignment(irp, 8);

#ifdef SCARD_AUTOALLOCATE
	SCardFreeMemory(hContext, readerList);
#else
	xfree(readerList);
#endif

	return rv;
}
コード例 #20
0
ファイル: transport.c プロジェクト: racoon00/FreeRDP
int transport_check_fds(rdpTransport* transport)
{
	int pos;
	int status;
	uint16 length;
	STREAM* received;

	wait_obj_clear(transport->recv_event);

	status = transport_read_nonblocking(transport);

	if (status < 0)
		return status;

	while ((pos = stream_get_pos(transport->recv_buffer)) > 0)
	{
		stream_set_pos(transport->recv_buffer, 0);
		if (tpkt_verify_header(transport->recv_buffer)) /* TPKT */
		{
			/* Ensure the TPKT header is available. */
			if (pos <= 4)
			{
				stream_set_pos(transport->recv_buffer, pos);
				return 0;
			}
			length = tpkt_read_header(transport->recv_buffer);
		}
		else /* Fast Path */
		{
			/* Ensure the Fast Path header is available. */
			if (pos <= 2)
			{
				stream_set_pos(transport->recv_buffer, pos);
				return 0;
			}
			length = fastpath_read_header(NULL, transport->recv_buffer);
		}

		if (length == 0)
		{
			printf("transport_check_fds: protocol error, not a TPKT or Fast Path header.\n");
			freerdp_hexdump(stream_get_head(transport->recv_buffer), pos);
			return -1;
		}

		if (pos < length)
		{
			stream_set_pos(transport->recv_buffer, pos);
			return 0; /* Packet is not yet completely received. */
		}

		/*
		 * A complete packet has been received. In case there are trailing data
		 * for the next packet, we copy it to the new receive buffer.
		 */
		received = transport->recv_buffer;
		transport->recv_buffer = stream_new(BUFFER_SIZE);

		if (pos > length)
		{
			stream_set_pos(received, length);
			stream_check_size(transport->recv_buffer, pos - length);
			stream_copy(transport->recv_buffer, received, pos - length);
		}

		stream_set_pos(received, length);
		stream_seal(received);
		stream_set_pos(received, 0);
		
		if (transport->recv_callback(transport, received, transport->recv_extra) == False)
			status = -1;
	
		stream_free(received);

		if (status < 0)
			return status;
	}

	return 0;
}
コード例 #21
0
RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, uint8* data, uint32 length)
{
	int pos;
	STREAM* s;
	uint32 blockLen;
	uint32 blockType;
	RFX_MESSAGE* message;

	s = stream_new(0);
	message = xnew(RFX_MESSAGE);
	stream_attach(s, data, length);

	while (stream_get_left(s) > 6)
	{
		/* RFX_BLOCKT */
		stream_read_uint16(s, blockType); /* blockType (2 bytes) */
		stream_read_uint32(s, blockLen); /* blockLen (4 bytes) */

		DEBUG_RFX("blockType 0x%X blockLen %d", blockType, blockLen);

		if (blockLen == 0)
		{
			DEBUG_WARN("zero blockLen");
			break;
		}

		pos = stream_get_pos(s) - 6 + blockLen;

		if (blockType >= WBT_CONTEXT && blockType <= WBT_EXTENSION)
		{
			/* RFX_CODEC_CHANNELT */
			/* codecId (1 byte) must be set to 0x01 */
			/* channelId (1 byte) must be set to 0x00 */
			stream_seek(s, 2);
		}

		switch (blockType)
		{
			case WBT_SYNC:
				rfx_process_message_sync(context, s);
				break;

			case WBT_CODEC_VERSIONS:
				rfx_process_message_codec_versions(context, s);
				break;

			case WBT_CHANNELS:
				rfx_process_message_channels(context, s);
				break;

			case WBT_CONTEXT:
				rfx_process_message_context(context, s);
				break;

			case WBT_FRAME_BEGIN:
				rfx_process_message_frame_begin(context, message, s);
				break;

			case WBT_FRAME_END:
				rfx_process_message_frame_end(context, message, s);
				break;

			case WBT_REGION:
				rfx_process_message_region(context, message, s);
				break;

			case WBT_EXTENSION:
				rfx_process_message_tileset(context, message, s);
				break;

			default:
				DEBUG_WARN("unknown blockType 0x%X", blockType);
				break;
		}

		stream_set_pos(s, pos);
	}

	stream_detach(s);
	stream_free(s);

	return message;
}
コード例 #22
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);

}
コード例 #23
0
RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, uint8* data, uint32 length, RECTANGLE_16* dst_rect)
{
	int pos;
	STREAM* s;
	uint32 blockLen;
	uint32 blockType;
	RFX_CONTEXT_CVT_PRIV* priv;
	RFX_MESSAGE* message;

	s = stream_new(0);

	message = rfx_message_new();
	if (dst_rect)
		memcpy(&message->dst_rect, dst_rect, sizeof(RECTANGLE_16));

	stream_attach(s, data, length);

	while (stream_get_left(s) > 6)
	{
		/* RFX_BLOCKT */
		stream_read_uint16(s, blockType); /* blockType (2 bytes) */
		stream_read_uint32(s, blockLen); /* blockLen (4 bytes) */

		DEBUG_RFX("blockType 0x%X blockLen %d", blockType, blockLen);

		if (blockLen == 0)
		{
			DEBUG_WARN("zero blockLen");
			break;
		}

		pos = stream_get_pos(s) - 6 + blockLen;

		if (blockType >= WBT_CONTEXT && blockType <= WBT_EXTENSION)
		{
			/* RFX_CODEC_CHANNELT */
			/* codecId (1 byte) must be set to 0x01 */
			/* channelId (1 byte) must be set to 0x00 */
			stream_seek(s, 2);
		}

		switch (blockType)
		{
			case WBT_SYNC:
				rfx_process_message_sync(context, s);
				break;

			case WBT_CODEC_VERSIONS:
				rfx_process_message_codec_versions(context, s);
				break;

			case WBT_CHANNELS:
				rfx_process_message_channels(context, s);
				break;

			case WBT_CONTEXT:
				rfx_process_message_context(context, s);
				break;

			case WBT_FRAME_BEGIN:
				rfx_process_message_frame_begin(context, message, s);
				break;

			case WBT_FRAME_END:
				rfx_process_message_frame_end(context, message, s);
				break;

			case WBT_REGION:
				rfx_process_message_region(context, message, s);
				break;

			case WBT_EXTENSION:
				priv = (RFX_CONTEXT_CVT_PRIV*) context->priv;
				if (priv->rfx_op_mode == RDVH_OPT)
					rfx_cvt_rdvh_opt_process_message_tileset(context, message, s);
				else
					rfx_cvt_process_message_tileset(context, message, s);
				break;

			default:
				DEBUG_WARN("unknown blockType 0x%X", blockType);
				break;
		}

		stream_set_pos(s, pos);
	}

	stream_detach(s);
	stream_free(s);

	return message;
}
コード例 #24
0
ファイル: rdpdr_main.c プロジェクト: 4hosi/FreeRDP
static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL user_loggedon)
{
	int i;
	int pos;
	BYTE c;
	UINT32 count;
	int data_len;
	int count_pos;
	STREAM* data_out;
	DEVICE* device;
	LIST_ITEM* item;

	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_BYTE(data_out, c);

				if (c > 0x7F)
					stream_write_BYTE(data_out, '_');
				else
					stream_seek_BYTE(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);
}
コード例 #25
0
ファイル: transport.c プロジェクト: Cyclic/FreeRDP
int transport_check_fds(rdpTransport** ptransport)
{
	int pos;
	int status;
	uint16 length;
	STREAM* received;
	rdpTransport* transport = *ptransport;

	wait_obj_clear(transport->recv_event);

	status = transport_read_nonblocking(transport);

	if (status < 0)
		return status;

	while ((pos = stream_get_pos(transport->recv_buffer)) > 0)
	{
		stream_set_pos(transport->recv_buffer, 0);
		if (tpkt_verify_header(transport->recv_buffer)) /* TPKT */
		{
			/* Ensure the TPKT header is available. */
			if (pos <= 4)
			{
				stream_set_pos(transport->recv_buffer, pos);
				return 0;
			}
			length = tpkt_read_header(transport->recv_buffer);
		}
		else /* Fast Path */
		{
			/* Ensure the Fast Path header is available. */
			if (pos <= 2)
			{
				stream_set_pos(transport->recv_buffer, pos);
				return 0;
			}
			/* Fastpath header can be two or three bytes long. */
			length = fastpath_header_length(transport->recv_buffer);
			if (pos < length)
			{
				stream_set_pos(transport->recv_buffer, pos);
				return 0;
			}
			length = fastpath_read_header(NULL, transport->recv_buffer);
		}

		if (length == 0)
		{
			printf("transport_check_fds: protocol error, not a TPKT or Fast Path header.\n");
			freerdp_hexdump(stream_get_head(transport->recv_buffer), pos);
			return -1;
		}

		if (pos < length)
		{
			stream_set_pos(transport->recv_buffer, pos);
			return 0; /* Packet is not yet completely received. */
		}

		/*
		 * A complete packet has been received. In case there are trailing data
		 * for the next packet, we copy it to the new receive buffer.
		 */
		received = transport->recv_buffer;
		transport->recv_buffer = stream_new(BUFFER_SIZE);

		if (pos > length)
		{
			stream_set_pos(received, length);
			stream_check_size(transport->recv_buffer, pos - length);
			stream_copy(transport->recv_buffer, received, pos - length);
		}

		stream_set_pos(received, length);
		stream_seal(received);
		stream_set_pos(received, 0);

		if (transport->recv_callback(transport, received, transport->recv_extra) == false)
			status = -1;

		stream_free(received);

		if (status < 0)
			return status;

		/* transport might now have been freed by rdp_client_redirect and a new rdp->transport created */
		transport = *ptransport;

		if (transport->process_single_pdu)
		{
			/* one at a time but set event if data buffered
			 * so the main loop will call freerdp_check_fds asap */
			if (stream_get_pos(transport->recv_buffer) > 0)
				wait_obj_set(transport->recv_event);
			break;
		}

	}

	return 0;
}
コード例 #26
0
ファイル: serial_tty.c プロジェクト: blu3bird/FreeRDP
uint32 serial_tty_control(SERIAL_TTY* tty, uint32 IoControlCode, STREAM* input, STREAM* output, uint32* abort_io)
{
	int purge_mask;
	uint32 result;
	uint32 modemstate;
	uint8 immediate;
	uint32 ret = STATUS_SUCCESS;
	uint32 length = 0;
	uint32 pos;

	DEBUG_SVC("in");

	stream_seek(output, sizeof(uint32));

	switch (IoControlCode)
	{
		case IOCTL_SERIAL_SET_BAUD_RATE:
			stream_read_uint32(input, tty->baud_rate);
			tty_set_termios(tty);
			DEBUG_SVC("SERIAL_SET_BAUD_RATE %d", tty->baud_rate);
			break;

		case IOCTL_SERIAL_GET_BAUD_RATE:
			length = 4;
			stream_write_uint32(output, tty->baud_rate);
			DEBUG_SVC("SERIAL_GET_BAUD_RATE %d", tty->baud_rate);
			break;

		case IOCTL_SERIAL_SET_QUEUE_SIZE:
			stream_read_uint32(input, tty->queue_in_size);
			stream_read_uint32(input, tty->queue_out_size);
			DEBUG_SVC("SERIAL_SET_QUEUE_SIZE in %d out %d", tty->queue_in_size, tty->queue_out_size);
			break;

		case IOCTL_SERIAL_SET_LINE_CONTROL:
			stream_read_uint8(input, tty->stop_bits);
			stream_read_uint8(input, tty->parity);
			stream_read_uint8(input, tty->word_length);
			tty_set_termios(tty);
			DEBUG_SVC("SERIAL_SET_LINE_CONTROL stop %d parity %d word %d",
				tty->stop_bits, tty->parity, tty->word_length);
			break;

		case IOCTL_SERIAL_GET_LINE_CONTROL:
			DEBUG_SVC("SERIAL_GET_LINE_CONTROL");
			length = 3;
			stream_write_uint8(output, tty->stop_bits);
			stream_write_uint8(output, tty->parity);
			stream_write_uint8(output, tty->word_length);
			break;

		case IOCTL_SERIAL_IMMEDIATE_CHAR:
			DEBUG_SVC("SERIAL_IMMEDIATE_CHAR");
			stream_read_uint8(input, immediate);
			tty_write_data(tty, &immediate, 1);
			break;

		case IOCTL_SERIAL_CONFIG_SIZE:
			DEBUG_SVC("SERIAL_CONFIG_SIZE");
			length = 4;
			stream_write_uint32(output, 0);
			break;

		case IOCTL_SERIAL_GET_CHARS:
			DEBUG_SVC("SERIAL_GET_CHARS");
			length = 6;
			stream_write(output, tty->chars, 6);
			break;

		case IOCTL_SERIAL_SET_CHARS:
			DEBUG_SVC("SERIAL_SET_CHARS");
			stream_read(input, tty->chars, 6);
			tty_set_termios(tty);
			break;

		case IOCTL_SERIAL_GET_HANDFLOW:
			length = 16;
			tty_get_termios(tty);
			stream_write_uint32(output, tty->control);
			stream_write_uint32(output, tty->xonoff);
			stream_write_uint32(output, tty->onlimit);
			stream_write_uint32(output, tty->offlimit);
			DEBUG_SVC("IOCTL_SERIAL_GET_HANDFLOW %X %X %X %X",
				tty->control, tty->xonoff, tty->onlimit, tty->offlimit);
			break;

		case IOCTL_SERIAL_SET_HANDFLOW:
			stream_read_uint32(input, tty->control);
			stream_read_uint32(input, tty->xonoff);
			stream_read_uint32(input, tty->onlimit);
			stream_read_uint32(input, tty->offlimit);
			DEBUG_SVC("IOCTL_SERIAL_SET_HANDFLOW %X %X %X %X",
				tty->control, tty->xonoff, tty->onlimit, tty->offlimit);
			tty_set_termios(tty);
			break;

		case IOCTL_SERIAL_SET_TIMEOUTS:
			stream_read_uint32(input, tty->read_interval_timeout);
			stream_read_uint32(input, tty->read_total_timeout_multiplier);
			stream_read_uint32(input, tty->read_total_timeout_constant);
			stream_read_uint32(input, tty->write_total_timeout_multiplier);
			stream_read_uint32(input, tty->write_total_timeout_constant);

			/* http://www.codeproject.com/KB/system/chaiyasit_t.aspx, see 'ReadIntervalTimeout' section
				http://msdn.microsoft.com/en-us/library/ms885171.aspx */
			if (tty->read_interval_timeout == SERIAL_TIMEOUT_MAX)
			{
				tty->read_interval_timeout = 0;
				tty->read_total_timeout_multiplier = 0;
			}

			DEBUG_SVC("SERIAL_SET_TIMEOUTS read timeout %d %d %d",
				tty->read_interval_timeout,
				tty->read_total_timeout_multiplier,
				tty->read_total_timeout_constant);
			break;

		case IOCTL_SERIAL_GET_TIMEOUTS:
			DEBUG_SVC("SERIAL_GET_TIMEOUTS read timeout %d %d %d",
				tty->read_interval_timeout,
				tty->read_total_timeout_multiplier,
				tty->read_total_timeout_constant);
			length = 20;
			stream_write_uint32(output, tty->read_interval_timeout);
			stream_write_uint32(output, tty->read_total_timeout_multiplier);
			stream_write_uint32(output, tty->read_total_timeout_constant);
			stream_write_uint32(output, tty->write_total_timeout_multiplier);
			stream_write_uint32(output, tty->write_total_timeout_constant);
			break;

		case IOCTL_SERIAL_GET_WAIT_MASK:
			DEBUG_SVC("SERIAL_GET_WAIT_MASK %X", tty->wait_mask);
			length = 4;
			stream_write_uint32(output, tty->wait_mask);
			break;

		case IOCTL_SERIAL_SET_WAIT_MASK:
			stream_read_uint32(input, tty->wait_mask);
			DEBUG_SVC("SERIAL_SET_WAIT_MASK %X", tty->wait_mask);
			break;

		case IOCTL_SERIAL_SET_DTR:
			DEBUG_SVC("SERIAL_SET_DTR");
			ioctl(tty->fd, TIOCMGET, &result);
			result |= TIOCM_DTR;
			ioctl(tty->fd, TIOCMSET, &result);
			tty->dtr = 1;
			break;

		case IOCTL_SERIAL_CLR_DTR:
			DEBUG_SVC("SERIAL_CLR_DTR");
			ioctl(tty->fd, TIOCMGET, &result);
			result &= ~TIOCM_DTR;
			ioctl(tty->fd, TIOCMSET, &result);
			tty->dtr = 0;
			break;

		case IOCTL_SERIAL_SET_RTS:
			DEBUG_SVC("SERIAL_SET_RTS");
			ioctl(tty->fd, TIOCMGET, &result);
			result |= TIOCM_RTS;
			ioctl(tty->fd, TIOCMSET, &result);
			tty->rts = 1;
			break;

		case IOCTL_SERIAL_CLR_RTS:
			DEBUG_SVC("SERIAL_CLR_RTS");
			ioctl(tty->fd, TIOCMGET, &result);
			result &= ~TIOCM_RTS;
			ioctl(tty->fd, TIOCMSET, &result);
			tty->rts = 0;
			break;

		case IOCTL_SERIAL_GET_MODEMSTATUS:
			modemstate = 0;
#ifdef TIOCMGET
			ioctl(tty->fd, TIOCMGET, &result);
			if (result & TIOCM_CTS)
				modemstate |= SERIAL_MS_CTS;
			if (result & TIOCM_DSR)
				modemstate |= SERIAL_MS_DSR;
			if (result & TIOCM_RNG)
				modemstate |= SERIAL_MS_RNG;
			if (result & TIOCM_CAR)
				modemstate |= SERIAL_MS_CAR;
			if (result & TIOCM_DTR)
				modemstate |= SERIAL_MS_DTR;
			if (result & TIOCM_RTS)
				modemstate |= SERIAL_MS_RTS;
#endif
			DEBUG_SVC("SERIAL_GET_MODEMSTATUS %X", modemstate);
			length = 4;
			stream_write_uint32(output, modemstate);
			break;

		case IOCTL_SERIAL_GET_COMMSTATUS:
			length = 18;
			stream_write_uint32(output, 0);	/* Errors */
			stream_write_uint32(output, 0);	/* Hold reasons */

			result = 0;
#ifdef TIOCINQ
			ioctl(tty->fd, TIOCINQ, &result);
#endif
			stream_write_uint32(output, result); /* Amount in in queue */
			if (result)
				DEBUG_SVC("SERIAL_GET_COMMSTATUS in queue %d", result);

			result = 0;
#ifdef TIOCOUTQ
			ioctl(tty->fd, TIOCOUTQ, &result);
#endif
			stream_write_uint32(output, result);	/* Amount in out queue */
			DEBUG_SVC("SERIAL_GET_COMMSTATUS out queue %d", result);

			stream_write_uint8(output, 0); /* EofReceived */
			stream_write_uint8(output, 0); /* WaitForImmediate */
			break;

		case IOCTL_SERIAL_PURGE:
			stream_read_uint32(input, purge_mask);
			DEBUG_SVC("SERIAL_PURGE purge_mask %X", purge_mask);

		/*	See http://msdn.microsoft.com/en-us/library/ms901431.aspx
			PURGE_TXCLEAR 	Clears the output buffer, if the driver has one.
			PURGE_RXCLEAR 	Clears the input buffer, if the driver has one.

			It clearly states to clear the *driver* buffer, not the port buffer
		*/

#ifdef DEBUG_SVC
			if (purge_mask & SERIAL_PURGE_TXCLEAR)
				DEBUG_SVC("Ignoring SERIAL_PURGE_TXCLEAR");
			if (purge_mask & SERIAL_PURGE_RXCLEAR)
				DEBUG_SVC("Ignoring SERIAL_PURGE_RXCLEAR");
#endif

			if (purge_mask & SERIAL_PURGE_TXABORT)
				*abort_io |= SERIAL_ABORT_IO_WRITE;
			if (purge_mask & SERIAL_PURGE_RXABORT)
				*abort_io |= SERIAL_ABORT_IO_READ;
			break;
		case IOCTL_SERIAL_WAIT_ON_MASK:
			DEBUG_SVC("SERIAL_WAIT_ON_MASK %X", tty->wait_mask);
			tty->event_pending = 1;
			length = 4;
			if (serial_tty_get_event(tty, &result))
			{
				DEBUG_SVC("WAIT end  event = %X", result);
				stream_write_uint32(output, result);
				break;
			}
			ret = STATUS_PENDING;
			break;

		case IOCTL_SERIAL_SET_BREAK_ON:
			DEBUG_SVC("SERIAL_SET_BREAK_ON");
			tcsendbreak(tty->fd, 0);
			break;

		case IOCTL_SERIAL_RESET_DEVICE:
			DEBUG_SVC("SERIAL_RESET_DEVICE");
			break;

		case IOCTL_SERIAL_SET_BREAK_OFF:
			DEBUG_SVC("SERIAL_SET_BREAK_OFF");
			break;

		case IOCTL_SERIAL_SET_XOFF:
			DEBUG_SVC("SERIAL_SET_XOFF");
			break;

		case IOCTL_SERIAL_SET_XON:
			DEBUG_SVC("SERIAL_SET_XON");
			tcflow(tty->fd, TCION);
			break;

		default:
			DEBUG_SVC("NOT FOUND IoControlCode SERIAL IOCTL %d", IoControlCode);
			return STATUS_INVALID_PARAMETER;
	}

	/* Write OutputBufferLength */
	pos = stream_get_pos(output);
	stream_set_pos(output, 16);
	stream_write_uint32(output, length);
	stream_set_pos(output, pos);

	return ret;
}
コード例 #27
0
void scard_device_control(SCARD_DEVICE* scard, IRP* irp)
{
	uint32 output_len, input_len, ioctl_code;
	uint32 stream_len, result;
	uint32 pos, pad_len;
	uint32 irp_len;
	uint32 irp_result_pos, output_len_pos, result_pos;

	stream_read_uint32(irp->input, output_len);
	stream_read_uint32(irp->input, input_len);
	stream_read_uint32(irp->input, ioctl_code);

	stream_seek(irp->input, 20);	/* padding */

	// stream_seek(irp->input, 4);	/* TODO: parse len, le, v1 */
	// stream_seek(irp->input, 4);	/* 0xcccccccc */
	// stream_seek(irp->input, 4);	/* rpce len */

	/* [MS-RDPESC] 3.2.5.1 Sending Outgoing Messages */
	stream_extend(irp->output, 2048);

	irp_result_pos = stream_get_pos(irp->output);

	stream_write_uint32(irp->output, 0x00081001); /* len 8, LE, v1 */

	/* [MS-RPCE] 2.2.6.1 */
	stream_write_uint32(irp->output, 0x00081001); /* len 8, LE, v1 */
	stream_write_uint32(irp->output, 0xcccccccc); /* filler */

	output_len_pos = stream_get_pos(irp->output);
	stream_seek(irp->output, 4);		/* size */

	stream_write_uint32(irp->output, 0x0);	/* filler */

	result_pos = stream_get_pos(irp->output);
	stream_seek(irp->output, 4);		/* result */

	/* body */
	switch (ioctl_code)
	{
		case SCARD_IOCTL_ESTABLISH_CONTEXT:
			result = handle_EstablishContext(irp);
			break;

		case SCARD_IOCTL_IS_VALID_CONTEXT:
			result = handle_IsValidContext(irp);
			break;

		case SCARD_IOCTL_RELEASE_CONTEXT:
			result = handle_ReleaseContext(irp);
			break;

		case SCARD_IOCTL_LIST_READERS:
			result = handle_ListReaders(irp, 0);
			break;
		case SCARD_IOCTL_LIST_READERS + 4:
			result = handle_ListReaders(irp, 1);
			break;

		case SCARD_IOCTL_LIST_READER_GROUPS:
		case SCARD_IOCTL_LIST_READER_GROUPS + 4:
			/* typically not used unless list_readers fail */
			result = SCARD_F_INTERNAL_ERROR;
			break;

		case SCARD_IOCTL_GET_STATUS_CHANGE:
			result = handle_GetStatusChange(irp, 0);
			break;
		case SCARD_IOCTL_GET_STATUS_CHANGE + 4:
			result = handle_GetStatusChange(irp, 1);
			break;

		case SCARD_IOCTL_CANCEL:
			result = handle_Cancel(irp);
			break;

		case SCARD_IOCTL_CONNECT:
			result = handle_Connect(irp, 0);
			break;
		case SCARD_IOCTL_CONNECT + 4:
			result = handle_Connect(irp, 1);
			break;

		case SCARD_IOCTL_RECONNECT:
			result = handle_Reconnect(irp);
			break;

		case SCARD_IOCTL_DISCONNECT:
			result = handle_Disconnect(irp);
			break;

		case SCARD_IOCTL_BEGIN_TRANSACTION:
			result = handle_BeginTransaction(irp);
			break;

		case SCARD_IOCTL_END_TRANSACTION:
			result = handle_EndTransaction(irp);
			break;

		case SCARD_IOCTL_STATE:
			result = handle_State(irp);
			break;

		case SCARD_IOCTL_STATUS:
			result = handle_Status(irp, 0);
			break;
		case SCARD_IOCTL_STATUS + 4:
			result = handle_Status(irp, 1);
			break;

		case SCARD_IOCTL_TRANSMIT:
			result = handle_Transmit(irp);
			break;

		case SCARD_IOCTL_CONTROL:
			result = handle_Control(irp);
			break;

		case SCARD_IOCTL_GETATTRIB:
			result = handle_GetAttrib(irp);
			break;

		case SCARD_IOCTL_ACCESS_STARTED_EVENT:
			result = handle_AccessStartedEvent(irp);
			break;

		case SCARD_IOCTL_LOCATE_CARDS_BY_ATR:
			result = handle_LocateCardsByATR(irp, 0);
			break;
		case SCARD_IOCTL_LOCATE_CARDS_BY_ATR + 4:
			result = handle_LocateCardsByATR(irp, 1);
			break;

		default:
			result = 0xc0000001;
			printf("scard unknown ioctl 0x%x\n", ioctl_code);
			break;
	}

	/* look for NTSTATUS errors */
	if ((result & 0xc0000000) == 0xc0000000)
		return scard_error(scard, irp, result);

	/* per Ludovic Rousseau, map different usage of this particular
  	 * error code between pcsc-lite & windows */
	if (result == 0x8010001F)
		result = 0x80100022;

	/* handle response packet */
	pos = stream_get_pos(irp->output);
	stream_len = pos - irp_result_pos - 4;

	stream_set_pos(irp->output, output_len_pos);
	stream_write_uint32(irp->output, stream_len - 24);

	stream_set_pos(irp->output, result_pos);
	stream_write_uint32(irp->output, result);

	stream_set_pos(irp->output, pos);

	/* pad stream to 16 byte align */
	pad_len = stream_len % 16;
	stream_write_zero(irp->output, pad_len);
	pos = stream_get_pos(irp->output);
	irp_len = stream_len + pad_len;

	stream_set_pos(irp->output, irp_result_pos);
	stream_write_uint32(irp->output, irp_len);
	stream_set_pos(irp->output, pos);

#ifdef WITH_DEBUG_SCARD
	freerdp_hexdump(stream_get_data(irp->output), stream_get_length(irp->output));
#endif
	irp->IoStatus = 0;

	irp->Complete(irp);

}
コード例 #28
0
ファイル: channels.c プロジェクト: KimDongChun/FreeRDP
static void wts_read_drdynvc_pdu(rdpPeerChannel* channel)
{
	UINT32 length;
	int value;
	int Cmd;
	int Sp;
	int cbChId;
	UINT32 ChannelId;
	rdpPeerChannel* dvc;

	length = stream_get_pos(channel->receive_data);

	if (length < 1)
		return;

	stream_set_pos(channel->receive_data, 0);
	stream_read_BYTE(channel->receive_data, value);

	length--;
	Cmd = (value & 0xf0) >> 4;
	Sp = (value & 0x0c) >> 2;
	cbChId = (value & 0x03) >> 0;

	if (Cmd == CAPABILITY_REQUEST_PDU)
	{
		wts_read_drdynvc_capabilities_response(channel, length);
	}
	else if (channel->vcm->drdynvc_state == DRDYNVC_STATE_READY)
	{
		value = wts_read_variable_uint(channel->receive_data, cbChId, &ChannelId);

		if (value == 0)
			return;

		length -= value;

		DEBUG_DVC("Cmd %d ChannelId %d length %d", Cmd, ChannelId, length);
		dvc = wts_get_dvc_channel_by_id(channel->vcm, ChannelId);

		if (dvc)
		{
			switch (Cmd)
			{
				case CREATE_REQUEST_PDU:
					wts_read_drdynvc_create_response(dvc, channel->receive_data, length);
					break;

				case DATA_FIRST_PDU:
					wts_read_drdynvc_data_first(dvc, channel->receive_data, Sp, length);
					break;

				case DATA_PDU:
					wts_read_drdynvc_data(dvc, channel->receive_data, length);
					break;

				case CLOSE_REQUEST_PDU:
					wts_read_drdynvc_close_response(dvc);
					break;

				default:
					fprintf(stderr, "wts_read_drdynvc_pdu: Cmd %d not recognized.\n", Cmd);
					break;
			}
		}
		else
		{
			DEBUG_DVC("ChannelId %d not exists.", ChannelId);
		}
	}
	else
	{
		fprintf(stderr, "wts_read_drdynvc_pdu: received Cmd %d but channel is not ready.\n", Cmd);
	}
}
コード例 #29
0
static DWORD handle_Status(IRP *irp, tbool wide)
{
	LONG rv;
	SCARDHANDLE hCard;
	DWORD state, protocol;
	DWORD readerLen = 0;
	DWORD atrLen = 0;
	char * readerName;
	BYTE pbAtr[MAX_ATR_SIZE];
	uint32 dataLength;
	int pos, poslen1, poslen2;

#ifdef WITH_DEBUG_SCARD
	int i;
#endif

	stream_seek(irp->input, 0x24);
	stream_read_uint32(irp->input, readerLen);
	stream_read_uint32(irp->input, atrLen);
	stream_seek(irp->input, 0x0c);
	stream_read_uint32(irp->input, hCard);
	stream_seek(irp->input, 0x4);

	atrLen = MAX_ATR_SIZE;

#ifdef SCARD_AUTOALLOCATE
	readerLen = SCARD_AUTOALLOCATE;

	rv = SCardStatus(hCard, (LPSTR) &readerName, &readerLen, &state, &protocol, pbAtr, &atrLen);
#else
	readerLen = 256;
	readerName = xmalloc(readerLen);

	rv = SCardStatus(hCard, (LPSTR) readerName, &readerLen, &state, &protocol, pbAtr, &atrLen);
#endif

	if (rv != SCARD_S_SUCCESS)
	{
		DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv);
		return sc_output_return(irp, rv);
	}

	DEBUG_SCARD("Success (state: 0x%08x, proto: 0x%08x)", (unsigned) state, (unsigned) protocol);
	DEBUG_SCARD("       Reader: \"%s\"", readerName ? readerName : "NULL");

#ifdef WITH_DEBUG_SCARD
	printf("       ATR: ");
	for (i = 0; i < atrLen; i++)
		printf("%02x%c", pbAtr[i], (i == atrLen - 1) ? ' ' : ':');
	printf("\n");
#endif

	state = sc_map_state(state);

	poslen1 = stream_get_pos(irp->output);
	stream_write_uint32(irp->output, readerLen);
	stream_write_uint32(irp->output, 0x00020000);
	stream_write_uint32(irp->output, state);
	stream_write_uint32(irp->output, protocol);
	stream_write(irp->output, pbAtr, atrLen);

	if (atrLen < 32)
		stream_write_zero(irp->output, 32 - atrLen);
	stream_write_uint32(irp->output, atrLen);

	poslen2 = stream_get_pos(irp->output);
	stream_write_uint32(irp->output, readerLen);

	dataLength = sc_output_string(irp, readerName, wide);
	dataLength += sc_output_string(irp, "\0", wide);
	sc_output_repos(irp, dataLength);

	pos = stream_get_pos(irp->output);
	stream_set_pos(irp->output, poslen1);
	stream_write_uint32(irp->output,dataLength);
	stream_set_pos(irp->output, poslen2);
	stream_write_uint32(irp->output,dataLength);
	stream_set_pos(irp->output, pos);

	sc_output_alignment(irp, 8);

#ifdef SCARD_AUTOALLOCATE
	/* SCardFreeMemory(NULL, readerName); */
	free(readerName);
#else
	xfree(readerName);
#endif

	return rv;
}
コード例 #30
0
ファイル: transport.c プロジェクト: 4hosi/FreeRDP
int transport_check_fds(rdpTransport** ptransport)
{
	int pos;
	int status;
	UINT16 length;
	int recv_status;
	STREAM* received;
	rdpTransport* transport = *ptransport;

#ifdef _WIN32
	WSAResetEvent(transport->TcpIn->wsa_event);
#endif
	ResetEvent(transport->ReceiveEvent);

	status = transport_read_nonblocking(transport);

	if (status < 0)
		return status;

	while ((pos = stream_get_pos(transport->ReceiveBuffer)) > 0)
	{
		stream_set_pos(transport->ReceiveBuffer, 0);

		if (tpkt_verify_header(transport->ReceiveBuffer)) /* TPKT */
		{
			/* Ensure the TPKT header is available. */
			if (pos <= 4)
			{
				stream_set_pos(transport->ReceiveBuffer, pos);
				return 0;
			}

			length = tpkt_read_header(transport->ReceiveBuffer);
		}
		else if (nla_verify_header(transport->ReceiveBuffer))
		{
			/* TSRequest */

			/* Ensure the TSRequest header is available. */
			if (pos <= 4)
			{
				stream_set_pos(transport->ReceiveBuffer, pos);
				return 0;
			}

			/* TSRequest header can be 2, 3 or 4 bytes long */
			length = nla_header_length(transport->ReceiveBuffer);

			if (pos < length)
			{
				stream_set_pos(transport->ReceiveBuffer, pos);
				return 0;
			}

			length = nla_read_header(transport->ReceiveBuffer);
		}
		else /* Fast Path */
		{
			/* Ensure the Fast Path header is available. */
			if (pos <= 2)
			{
				stream_set_pos(transport->ReceiveBuffer, pos);
				return 0;
			}

			/* Fastpath header can be two or three bytes long. */
			length = fastpath_header_length(transport->ReceiveBuffer);

			if (pos < length)
			{
				stream_set_pos(transport->ReceiveBuffer, pos);
				return 0;
			}

			length = fastpath_read_header(NULL, transport->ReceiveBuffer);
		}

		if (length == 0)
		{
			printf("transport_check_fds: protocol error, not a TPKT or Fast Path header.\n");
			winpr_HexDump(stream_get_head(transport->ReceiveBuffer), pos);
			return -1;
		}

		if (pos < length)
		{
			stream_set_pos(transport->ReceiveBuffer, pos);
			return 0; /* Packet is not yet completely received. */
		}

		received = transport->ReceiveBuffer;
		transport->ReceiveBuffer = transport_receive_pool_take(transport);

		stream_set_pos(received, length);
		stream_seal(received);
		stream_set_pos(received, 0);

		/**
		 * ReceiveCallback return values:
		 *
		 * -1: synchronous failure
		 *  0: synchronous success
		 *  1: asynchronous return
		 */

		recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra);

		transport_receive_pool_return(transport, received);

		if (recv_status < 0)
			status = -1;

		if (status < 0)
			return status;

		/* transport might now have been freed by rdp_client_redirect and a new rdp->transport created */
		transport = *ptransport;
	}

	return 0;
}