Esempio n. 1
0
static void* rdpsnd_server_thread(void* arg)
{
	wStream* s;
	DWORD status;
	DWORD nCount;
	void* buffer;
	BYTE msgType;
	UINT16 BodySize;
	HANDLE events[8];
	HANDLE ChannelEvent;
	DWORD BytesReturned;
	RdpsndServerContext* context;
	BOOL doRun;

	context = (RdpsndServerContext *)arg;

	buffer = NULL;
	BytesReturned = 0;
	ChannelEvent = NULL;

	s = Stream_New(NULL, 4096);
	if (!s)
		return NULL;

	if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &BytesReturned))
	{
		if (BytesReturned == sizeof(HANDLE))
			CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE));

		WTSFreeMemory(buffer);
	}

	nCount = 0;
	if (ChannelEvent)
		events[nCount++] = ChannelEvent;
	events[nCount++] = context->priv->StopEvent;

	if (!rdpsnd_server_send_formats(context, s))
		goto out;

	doRun = TRUE;
	while (doRun)
	{
		status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);

		if (WaitForSingleObject(context->priv->StopEvent, 0) == WAIT_OBJECT_0)
			break;

		Stream_SetPosition(s, 0);

		if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0, (PCHAR)Stream_Buffer(s),
									Stream_Capacity(s), &BytesReturned))
		{
			if (!BytesReturned)
				break;

			Stream_EnsureRemainingCapacity(s, BytesReturned);

			if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0, (PCHAR)Stream_Buffer(s),
										Stream_Capacity(s), &BytesReturned))
				break;
		}

		if (Stream_GetRemainingLength(s) < 4)
			break;

		Stream_Read_UINT8(s, msgType);
		Stream_Seek_UINT8(s); /* bPad */
		Stream_Read_UINT16(s, BodySize);

		if (Stream_GetRemainingLength(s) < BodySize)
			break;

		switch (msgType)
		{
			case SNDC_WAVECONFIRM:
				doRun = rdpsnd_server_recv_waveconfirm(context, s);
				break;

			case SNDC_QUALITYMODE:
				doRun = rdpsnd_server_recv_quality_mode(context, s);
				break;

			case SNDC_FORMATS:
				doRun = rdpsnd_server_recv_formats(context, s);
				if (doRun)
				{
					IFCALL(context->Activated, context);
				}
				break;

			default:
				fprintf(stderr, "%s: UNKOWN MESSAGE TYPE!! (%#0X)\n\n", __FUNCTION__, msgType);
				break;
		}
	}

out:
	Stream_Free(s, TRUE);
	return NULL;
}
Esempio n. 2
0
static void* rdpsnd_server_thread_func(void* arg)
{
	void* fd;
	STREAM* s;
	void* buffer;
	BYTE msgType;
	UINT16 BodySize;
	UINT32 bytes_returned = 0;
	rdpsnd_server* rdpsnd = (rdpsnd_server*) arg;
	freerdp_thread* thread = rdpsnd->rdpsnd_channel_thread;

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

	s = stream_new(4096);

	rdpsnd_server_send_formats(rdpsnd, s);

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

		stream_set_pos(s, 0);

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

			if (WTSVirtualChannelRead(rdpsnd->rdpsnd_channel, 0, stream_get_head(s),
				stream_get_size(s), &bytes_returned) == FALSE)
				break;
		}

		stream_read_BYTE(s, msgType);
		stream_seek_BYTE(s); /* bPad */
		stream_read_UINT16(s, BodySize);

		if (BodySize + 4 > (int) bytes_returned)
			continue;

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

	stream_free(s);
	freerdp_thread_quit(thread);

	return 0;
}
Esempio n. 3
0
BOOL rdpsnd_server_handle_messages(RdpsndServerContext *context)
{
	DWORD bytesReturned;
	BOOL ret;

	RdpsndServerPrivate *priv = context->priv;
	wStream *s = priv->input_stream;

	if (!WTSVirtualChannelRead(priv->ChannelHandle, 0, (PCHAR)Stream_Pointer(s), priv->expectedBytes, &bytesReturned))
	{
		if (GetLastError() == ERROR_NO_DATA)
			return TRUE;

		CLOG_ERR( "%s: channel connection closed\n", __FUNCTION__);
		return FALSE;
	}
	priv->expectedBytes -= bytesReturned;
	Stream_Seek(s, bytesReturned);

	if (priv->expectedBytes)
		return TRUE;

	Stream_SetPosition(s, 0);
	if (priv->waitingHeader)
	{
		/* header case */
		Stream_Read_UINT8(s, priv->msgType);
		Stream_Seek_UINT8(s); /* bPad */
		Stream_Read_UINT16(s, priv->expectedBytes);

		priv->waitingHeader = FALSE;
		Stream_SetPosition(s, 0);
		if (priv->expectedBytes)
		{
			Stream_EnsureCapacity(s, priv->expectedBytes);
			return TRUE;
		}
	}

	/* when here we have the header + the body */
#ifdef WITH_DEBUG_SND
	CLOG_ERR( "%s: message type %d\n", __FUNCTION__, priv->msgType);
#endif
	priv->expectedBytes = 4;
	priv->waitingHeader = TRUE;

	switch (priv->msgType)
	{
		case SNDC_WAVECONFIRM:
			ret = rdpsnd_server_recv_waveconfirm(context, s);
			break;

		case SNDC_FORMATS:
			ret = rdpsnd_server_recv_formats(context, s);
			break;

		case SNDC_QUALITYMODE:
			ret = rdpsnd_server_recv_quality_mode(context, s);
			Stream_SetPosition(s, 0); /* in case the Activated callback tries to treat some messages */

			if (ret)
			{
				IFCALL(context->Activated, context);
			}
			break;

		default:
			CLOG_ERR( "%s: UNKOWN MESSAGE TYPE!! (%#0X)\n\n", __FUNCTION__, priv->msgType);
			ret = FALSE;
			break;
	}
	Stream_SetPosition(s, 0);

	return ret;
}
Esempio n. 4
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
UINT rdpsnd_server_handle_messages(RdpsndServerContext *context)
{
	DWORD bytesReturned;
	UINT ret = CHANNEL_RC_OK;

	RdpsndServerPrivate *priv = context->priv;
	wStream *s = priv->input_stream;

	if (!WTSVirtualChannelRead(priv->ChannelHandle, 0, (PCHAR)Stream_Pointer(s), priv->expectedBytes, &bytesReturned))
	{
		if (GetLastError() == ERROR_NO_DATA)
			return ERROR_NO_DATA;

		WLog_ERR(TAG,  "channel connection closed");
		return ERROR_INTERNAL_ERROR;
	}
	priv->expectedBytes -= bytesReturned;
	Stream_Seek(s, bytesReturned);

	if (priv->expectedBytes)
		return CHANNEL_RC_OK;

	Stream_SealLength(s);
	Stream_SetPosition(s, 0);
	if (priv->waitingHeader)
	{
		/* header case */
		Stream_Read_UINT8(s, priv->msgType);
		Stream_Seek_UINT8(s); /* bPad */
		Stream_Read_UINT16(s, priv->expectedBytes);

		priv->waitingHeader = FALSE;
		Stream_SetPosition(s, 0);
		if (priv->expectedBytes)
		{
			if (!Stream_EnsureCapacity(s, priv->expectedBytes))
			{
				WLog_ERR(TAG, "Stream_EnsureCapacity failed!");
				return CHANNEL_RC_NO_MEMORY;
			}
			return CHANNEL_RC_OK;
		}
	}

	/* when here we have the header + the body */
#ifdef WITH_DEBUG_SND
	WLog_DBG(TAG,  "message type %d", priv->msgType);
#endif
	priv->expectedBytes = 4;
	priv->waitingHeader = TRUE;

	switch (priv->msgType)
	{
		case SNDC_WAVECONFIRM:
			ret = rdpsnd_server_recv_waveconfirm(context, s);
			break;

		case SNDC_FORMATS:
			ret = rdpsnd_server_recv_formats(context, s);

			if ((ret == CHANNEL_RC_OK) && (context->clientVersion < 6))
				IFCALL(context->Activated, context);

			break;

		case SNDC_QUALITYMODE:
			ret = rdpsnd_server_recv_quality_mode(context, s);
			Stream_SetPosition(s, 0); /* in case the Activated callback tries to treat some messages */

			if ((ret == CHANNEL_RC_OK) && (context->clientVersion >= 6))
				IFCALL(context->Activated, context);
			break;

		default:
			WLog_ERR(TAG,  "UNKOWN MESSAGE TYPE!! (%#0X)", priv->msgType);
			ret = ERROR_INVALID_DATA;
			break;
	}
	Stream_SetPosition(s, 0);

	return ret;
}