예제 #1
0
static int drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, int cbChId, wStream* s)
{
	int pos;
	int status;
	UINT32 ChannelId;
	wStream* data_out;
	int channel_status;

	if (drdynvc->state == DRDYNVC_STATE_CAPABILITIES)
	{
		/**
		 * For some reason the server does not always send the
		 * capabilities pdu as it should. When this happens,
		 * send a capabilities response.
		 */

		drdynvc->version = 3;
		drdynvc_send_capability_response(drdynvc);
		drdynvc->state = DRDYNVC_STATE_READY;
	}

	ChannelId = drdynvc_read_variable_uint(s, cbChId);
	pos = Stream_GetPosition(s);
	DEBUG_DVC("ChannelId=%d ChannelName=%s", ChannelId, Stream_Pointer(s));

	channel_status = dvcman_create_channel(drdynvc->channel_mgr, ChannelId, (char*) Stream_Pointer(s));

	data_out = Stream_New(NULL, pos + 4);
	Stream_Write_UINT8(data_out, 0x10 | cbChId);
	Stream_SetPosition(s, 1);
	Stream_Copy(data_out, s, pos - 1);
	
	if (channel_status == 0)
	{
		DEBUG_DVC("channel created");
		Stream_Write_UINT32(data_out, 0);
	}
	else
	{
		DEBUG_DVC("no listener");
		Stream_Write_UINT32(data_out, (UINT32)(-1));
	}

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

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

	if (channel_status == 0)
	{
		dvcman_open_channel(drdynvc->channel_mgr, ChannelId);
	}

	return 0;
}
예제 #2
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT dvcman_receive_channel_data(drdynvcPlugin* drdynvc,
                                        IWTSVirtualChannelManager* pChannelMgr,
                                        UINT32 ChannelId, wStream* data)
{
	UINT status = CHANNEL_RC_OK;
	DVCMAN_CHANNEL* channel;
	size_t dataSize = Stream_GetRemainingLength(data);
	channel = (DVCMAN_CHANNEL*) dvcman_find_channel_by_id(pChannelMgr, ChannelId);

	if (!channel)
	{
		/* Windows 8.1 tries to open channels not created.
				 * Ignore cases like this. */
		WLog_Print(drdynvc->log, WLOG_ERROR, "ChannelId %"PRIu32" not found!", ChannelId);
		return CHANNEL_RC_OK;
	}

	if (channel->dvc_data)
	{
		/* Fragmented data */
		if (Stream_GetPosition(channel->dvc_data) + dataSize > Stream_Capacity(channel->dvc_data))
		{
			WLog_Print(drdynvc->log, WLOG_ERROR, "data exceeding declared length!");
			Stream_Release(channel->dvc_data);
			channel->dvc_data = NULL;
			return ERROR_INVALID_DATA;
		}

		Stream_Copy(data, channel->dvc_data, dataSize);

		if (Stream_GetPosition(channel->dvc_data) >= channel->dvc_data_length)
		{
			Stream_SealLength(channel->dvc_data);
			Stream_SetPosition(channel->dvc_data, 0);
			status = channel->channel_callback->OnDataReceived(channel->channel_callback,
			         channel->dvc_data);
			Stream_Release(channel->dvc_data);
			channel->dvc_data = NULL;
		}
	}
	else
	{
		status = channel->channel_callback->OnDataReceived(channel->channel_callback,
		         data);
	}

	return status;
}
예제 #3
0
int tsmf_ifman_exchange_capability_request(TSMF_IFMAN* ifman)
{
	UINT32 i;
	UINT32 v;
	UINT32 pos;
	UINT32 CapabilityType;
	UINT32 cbCapabilityLength;
	UINT32 numHostCapabilities;

	pos = Stream_GetPosition(ifman->output);
	Stream_EnsureRemainingCapacity(ifman->output, ifman->input_size + 4);
	Stream_Copy(ifman->output, ifman->input, ifman->input_size);

	Stream_SetPosition(ifman->output, pos);
	Stream_Read_UINT32(ifman->output, numHostCapabilities);

	for (i = 0; i < numHostCapabilities; i++)
	{
		Stream_Read_UINT32(ifman->output, CapabilityType);
		Stream_Read_UINT32(ifman->output, cbCapabilityLength);
		pos = Stream_GetPosition(ifman->output);

		switch (CapabilityType)
		{
			case 1: /* Protocol version request */
				Stream_Read_UINT32(ifman->output, v);
				DEBUG_DVC("server protocol version %d", v);
				break;
			case 2: /* Supported platform */
				Stream_Peek_UINT32(ifman->output, v);
				DEBUG_DVC("server supported platform %d", v);
				/* Claim that we support both MF and DShow platforms. */
				Stream_Write_UINT32(ifman->output,
					MMREDIR_CAPABILITY_PLATFORM_MF | MMREDIR_CAPABILITY_PLATFORM_DSHOW);
				break;
			default:
				DEBUG_WARN("unknown capability type %d", CapabilityType);
				break;
		}
		Stream_SetPosition(ifman->output, pos + cbCapabilityLength);
	}
	Stream_Write_UINT32(ifman->output, 0); /* Result */

	ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB;

	return 0;
}
예제 #4
0
파일: TestStream.c 프로젝트: jat255/FreeRDP
static BOOL TestStream_Copy(void)
{
	BOOL rc = FALSE;
	const BYTE data[] = "someteststreamdata";
	wStream* s = Stream_New(NULL, sizeof(data));
	wStream* d = Stream_New(NULL, sizeof(data));
	if (!s || !d)
		goto out;
	if (s->pointer != s->buffer)
		goto out;

	Stream_Write(s, data, sizeof(data));
	if (memcmp(Stream_Buffer(s), data, sizeof(data)) != 0)
		goto out;
	if (s->pointer != s->buffer + sizeof(data))
		goto out;
	Stream_SetPosition(s, 0);
	if (s->pointer != s->buffer)
		goto out;

	Stream_Copy(s, d, sizeof(data));
	if (s->pointer != s->buffer + sizeof(data))
		goto out;
	if (d->pointer != d->buffer + sizeof(data))
		goto out;
	if (Stream_GetPosition(s) != Stream_GetPosition(d))
		goto out;

	if (memcmp(Stream_Buffer(s), data, sizeof(data)) != 0)
		goto out;
	if (memcmp(Stream_Buffer(d), data, sizeof(data)) != 0)
		goto out;

	rc = TRUE;
out:
	Stream_Free(s, TRUE);
	Stream_Free(d, TRUE);
	return rc;
}
static int drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, int cbChId, wStream* s)
{
	int pos;
	int status;
	UINT32 ChannelId;
	wStream* data_out;

	ChannelId = drdynvc_read_variable_uint(s, cbChId);
	pos = Stream_GetPosition(s);
	DEBUG_DVC("ChannelId=%d ChannelName=%s", ChannelId, Stream_Pointer(s));

	status = dvcman_create_channel(drdynvc->channel_mgr, ChannelId, (char*) Stream_Pointer(s));

	data_out = Stream_New(NULL, pos + 4);
	Stream_Write_UINT8(data_out, 0x10 | cbChId);
	Stream_SetPosition(s, 1);
	Stream_Copy(data_out, s, pos - 1);
	
	if (status == 0)
	{
		DEBUG_DVC("channel created");
		Stream_Write_UINT32(data_out, 0);
	}
	else
	{
		DEBUG_DVC("no listener");
		Stream_Write_UINT32(data_out, (UINT32)(-1));
	}

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

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

	return 0;
}
예제 #6
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp,
        int cbChId, wStream* s)
{
	size_t pos;
	UINT status;
	UINT32 ChannelId;
	wStream* data_out;
	UINT channel_status;
	char* name;
	size_t length;

	if (!drdynvc)
		return CHANNEL_RC_BAD_CHANNEL_HANDLE;

	if (drdynvc->state == DRDYNVC_STATE_CAPABILITIES)
	{
		/**
		 * For some reason the server does not always send the
		 * capabilities pdu as it should. When this happens,
		 * send a capabilities response.
		 */
		drdynvc->version = 3;

		if ((status = drdynvc_send_capability_response(drdynvc)))
		{
			WLog_Print(drdynvc->log, WLOG_ERROR, "drdynvc_send_capability_response failed!");
			return status;
		}

		drdynvc->state = DRDYNVC_STATE_READY;
	}

	if (Stream_GetRemainingLength(s) < drdynvc_cblen_to_bytes(cbChId))
		return ERROR_INVALID_DATA;

	ChannelId = drdynvc_read_variable_uint(s, cbChId);
	pos = Stream_GetPosition(s);
	name = (char*)Stream_Pointer(s);
	length = Stream_GetRemainingLength(s);

	if (strnlen(name, length) >= length)
		return ERROR_INVALID_DATA;

	WLog_Print(drdynvc->log, WLOG_DEBUG, "process_create_request: ChannelId=%"PRIu32" ChannelName=%s",
	           ChannelId, name);
	channel_status = dvcman_create_channel(drdynvc, drdynvc->channel_mgr, ChannelId, name);
	data_out = Stream_New(NULL, pos + 4);

	if (!data_out)
	{
		WLog_Print(drdynvc->log, WLOG_ERROR, "Stream_New failed!");
		return CHANNEL_RC_NO_MEMORY;
	}

	Stream_Write_UINT8(data_out, 0x10 | cbChId);
	Stream_SetPosition(s, 1);
	Stream_Copy(s, data_out, pos - 1);

	if (channel_status == CHANNEL_RC_OK)
	{
		WLog_Print(drdynvc->log, WLOG_DEBUG, "channel created");
		Stream_Write_UINT32(data_out, 0);
	}
	else
	{
		WLog_Print(drdynvc->log, WLOG_DEBUG, "no listener");
		Stream_Write_UINT32(data_out, (UINT32)0xC0000001); /* same code used by mstsc */
	}

	status = drdynvc_send(drdynvc, data_out);

	if (status != CHANNEL_RC_OK)
	{
		WLog_Print(drdynvc->log, WLOG_ERROR, "VirtualChannelWriteEx failed with %s [%08"PRIX32"]",
		           WTSErrorToString(status), status);
		return status;
	}

	if (channel_status == CHANNEL_RC_OK)
	{
		if ((status = dvcman_open_channel(drdynvc, drdynvc->channel_mgr, ChannelId)))
		{
			WLog_Print(drdynvc->log, WLOG_ERROR, "dvcman_open_channel failed with error %"PRIu32"!", status);
			return status;
		}
	}
	else
	{
		if ((status = dvcman_close_channel(drdynvc->channel_mgr, ChannelId)))
			WLog_Print(drdynvc->log, WLOG_ERROR, "dvcman_close_channel failed with error %"PRIu32"!", status);
	}

	return status;
}
예제 #7
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp,
					   int cbChId, wStream* s)
{
	unsigned long pos;
	UINT status;
	UINT32 ChannelId;
	wStream* data_out;
	UINT channel_status;

	if (drdynvc->state == DRDYNVC_STATE_CAPABILITIES)
	{
		/**
		 * For some reason the server does not always send the
		 * capabilities pdu as it should. When this happens,
		 * send a capabilities response.
		 */

		drdynvc->version = 3;
		if ((status = drdynvc_send_capability_response(drdynvc)))
		{
			WLog_ERR(TAG, "drdynvc_send_capability_response failed!");
			return status;
		}
		drdynvc->state = DRDYNVC_STATE_READY;
	}

	ChannelId = drdynvc_read_variable_uint(s, cbChId);
	pos = Stream_GetPosition(s);
	WLog_DBG(TAG, "process_create_request: ChannelId=%d ChannelName=%s", ChannelId, Stream_Pointer(s));

	channel_status = dvcman_create_channel(drdynvc->channel_mgr, ChannelId, (char*) Stream_Pointer(s));

	data_out = Stream_New(NULL, pos + 4);

	if (!s)
	{
		WLog_ERR(TAG, "Stream_New failed!");
		return CHANNEL_RC_NO_MEMORY;
	}

	Stream_Write_UINT8(data_out, 0x10 | cbChId);
	Stream_SetPosition(s, 1);
	Stream_Copy(s, data_out, pos - 1);

	if (channel_status == CHANNEL_RC_OK)
	{
		WLog_DBG(TAG, "channel created");
		Stream_Write_UINT32(data_out, 0);
	}
	else
	{
		WLog_DBG(TAG, "no listener");
		Stream_Write_UINT32(data_out, (UINT32) 0xC0000001); /* same code used by mstsc */
	}

	status = drdynvc_send(drdynvc, data_out);

	if (status != CHANNEL_RC_OK)
	{
		WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]",
				 WTSErrorToString(status), status);
		return status;
	}

	if (channel_status == CHANNEL_RC_OK)
	{
		if ((status = dvcman_open_channel(drdynvc->channel_mgr, ChannelId)))
		{
			WLog_ERR(TAG, "dvcman_open_channel failed with error %lu!", status);
			return status;
		}
	}
	else
	{
		if ((status = dvcman_close_channel(drdynvc->channel_mgr, ChannelId)))
			WLog_ERR(TAG, "dvcman_close_channel failed with error %lu!", status);
	}

	return status;
}
예제 #8
0
파일: tsmf_ifman.c 프로젝트: artemh/FreeRDP
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
UINT tsmf_ifman_exchange_capability_request(TSMF_IFMAN* ifman)
{
	UINT32 i;
	UINT32 v;
	UINT32 pos;
	UINT32 CapabilityType;
	UINT32 cbCapabilityLength;
	UINT32 numHostCapabilities;

	if (!Stream_EnsureRemainingCapacity(ifman->output, ifman->input_size + 4))
		return ERROR_OUTOFMEMORY;
	pos = Stream_GetPosition(ifman->output);
	Stream_Copy(ifman->input, ifman->output, ifman->input_size);
	Stream_SetPosition(ifman->output, pos);

	if (Stream_GetRemainingLength(ifman->output) < 4)
		return ERROR_INVALID_DATA;
	Stream_Read_UINT32(ifman->output, numHostCapabilities);

	for (i = 0; i < numHostCapabilities; i++)
	{
		if (Stream_GetRemainingLength(ifman->output) < 8)
			return ERROR_INVALID_DATA;

		Stream_Read_UINT32(ifman->output, CapabilityType);
		Stream_Read_UINT32(ifman->output, cbCapabilityLength);

		if (Stream_GetRemainingLength(ifman->output) < cbCapabilityLength)
			return ERROR_INVALID_DATA;

		pos = Stream_GetPosition(ifman->output);

		switch (CapabilityType)
		{
			case 1: /* Protocol version request */
				if (Stream_GetRemainingLength(ifman->output) < 4)
					return ERROR_INVALID_DATA;

				Stream_Read_UINT32(ifman->output, v);
				DEBUG_TSMF("server protocol version %d", v);
				break;
			case 2: /* Supported platform */
				if (Stream_GetRemainingLength(ifman->output) < 4)
					return ERROR_INVALID_DATA;

				Stream_Peek_UINT32(ifman->output, v);
				DEBUG_TSMF("server supported platform %d", v);
				/* Claim that we support both MF and DShow platforms. */
				Stream_Write_UINT32(ifman->output, MMREDIR_CAPABILITY_PLATFORM_MF | MMREDIR_CAPABILITY_PLATFORM_DSHOW);
				break;
			default:
				WLog_ERR(TAG, "skipping unknown capability type %d", CapabilityType);
				break;
		}
		Stream_SetPosition(ifman->output, pos + cbCapabilityLength);
	}

	Stream_Write_UINT32(ifman->output, 0); /* Result */
	ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB;

	return CHANNEL_RC_OK;
}