Beispiel #1
0
static void* audin_server_thread_func(void* arg)
{
	void* fd;
	STREAM* s;
	void* buffer;
	BYTE MessageId;
	BOOL ready = FALSE;
	UINT32 bytes_returned = 0;
	audin_server* audin = (audin_server*) arg;
	freerdp_thread* thread = audin->audin_channel_thread;

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

	/* Wait for the client to confirm that the Audio Input dynamic channel is ready */
	while (1)
	{
		freerdp_thread_wait(thread);
		if (freerdp_thread_is_stopped(thread))
			break;

		if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualChannelReady, &buffer, &bytes_returned) == FALSE)
			break;
		ready = *((BOOL*)buffer);
		WTSFreeMemory(buffer);
		if (ready)
			break;
	}

	s = stream_new(4096);

	if (ready)
	{
		audin_server_send_version(audin, s);
	}

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

		stream_set_pos(s, 0);

		if (WTSVirtualChannelRead(audin->audin_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(audin->audin_channel, 0, stream_get_head(s),
				stream_get_size(s), &bytes_returned) == FALSE)
				break;
		}
		if (bytes_returned < 1)
			continue;

		stream_read_BYTE(s, MessageId);
		bytes_returned--;
		switch (MessageId)
		{
			case MSG_SNDIN_VERSION:
				if (audin_server_recv_version(audin, s, bytes_returned))
					audin_server_send_formats(audin, s);
				break;

			case MSG_SNDIN_FORMATS:
				if (audin_server_recv_formats(audin, s, bytes_returned))
					audin_server_send_open(audin, s);
				break;

			case MSG_SNDIN_OPEN_REPLY:
				audin_server_recv_open_reply(audin, s, bytes_returned);
				break;

			case MSG_SNDIN_DATA_INCOMING:
				break;

			case MSG_SNDIN_DATA:
				audin_server_recv_data(audin, s, bytes_returned);
				break;

			case MSG_SNDIN_FORMATCHANGE:
				break;

			default:
				printf("audin_server_thread_func: unknown MessageId %d\n", MessageId);
				break;
		}
	}

	stream_free(s);
	WTSVirtualChannelClose(audin->audin_channel);
	audin->audin_channel = NULL;
	freerdp_thread_quit(thread);

	return NULL;
}
Beispiel #2
0
static void* audin_server_thread_func(void* arg)
{
	wStream* s;
	void* buffer;
	DWORD nCount;
	BYTE MessageId;
	HANDLE events[8];
	BOOL ready = FALSE;
	HANDLE ChannelEvent;
	DWORD BytesReturned = 0;
	audin_server* audin = (audin_server*) arg;
	UINT error = CHANNEL_RC_OK;
	DWORD status;

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

	if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE)
	{
		if (BytesReturned == sizeof(HANDLE))
			CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE));

		WTSFreeMemory(buffer);
	}
	else
	{
		WLog_ERR(TAG, "WTSVirtualChannelQuery failed");
		error = ERROR_INTERNAL_ERROR;
		goto out;
	}

	nCount = 0;
	events[nCount++] = audin->stopEvent;
	events[nCount++] = ChannelEvent;

	/* Wait for the client to confirm that the Audio Input dynamic channel is ready */

	while (1)
	{
		if ((status = WaitForMultipleObjects(nCount, events, FALSE, 100)) == WAIT_OBJECT_0)
			goto out;

		if (status == WAIT_FAILED)
		{
            error = GetLastError();
			WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error);
			goto out;
		}

		if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualChannelReady, &buffer, &BytesReturned) == FALSE)
		{
			WLog_ERR(TAG, "WTSVirtualChannelQuery failed");
			error = ERROR_INTERNAL_ERROR;
			goto out;
		}

		ready = *((BOOL*) buffer);

		WTSFreeMemory(buffer);

		if (ready)
			break;
	}

	s = Stream_New(NULL, 4096);
	if (!s)
	{
		WLog_ERR(TAG, "Stream_New failed!");
		error = CHANNEL_RC_NO_MEMORY;
		goto out;
	}


	if (ready)
	{
		if ((error = audin_server_send_version(audin, s)))
		{
			WLog_ERR(TAG, "audin_server_send_version failed with error %lu!", error);
			goto out_capacity;
		}
	}

	while (ready)
	{
		if ((status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE)) == WAIT_OBJECT_0)
			break;

		if (status == WAIT_FAILED)
		{
            error = GetLastError();
            WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error);
            goto out;
		}

		Stream_SetPosition(s, 0);

		if (!WTSVirtualChannelRead(audin->audin_channel, 0, NULL, 0, &BytesReturned))
		{
			WLog_ERR(TAG, "WTSVirtualChannelRead failed!");
			error = ERROR_INTERNAL_ERROR;
			break;
		}
		if (BytesReturned < 1)
			continue;
		if (!Stream_EnsureRemainingCapacity(s, BytesReturned))
			break;
		if (WTSVirtualChannelRead(audin->audin_channel, 0, (PCHAR) Stream_Buffer(s),
			Stream_Capacity(s), &BytesReturned) == FALSE)
		{
			WLog_ERR(TAG, "WTSVirtualChannelRead failed!");
			error = ERROR_INTERNAL_ERROR;
			break;
		}

		Stream_Read_UINT8(s, MessageId);
		BytesReturned--;

		switch (MessageId)
		{
			case MSG_SNDIN_VERSION:
				if ((error = audin_server_recv_version(audin, s, BytesReturned)))
				{
                    WLog_ERR(TAG, "audin_server_recv_version failed with error %lu!", error);
                    goto out_capacity;
                }
				if ((error = audin_server_send_formats(audin, s)))
				{
					WLog_ERR(TAG, "audin_server_send_formats failed with error %lu!", error);
					goto out_capacity;
				}
				break;

			case MSG_SNDIN_FORMATS:
				if ((error = audin_server_recv_formats(audin, s, BytesReturned)))
				{
					WLog_ERR(TAG, "audin_server_recv_formats failed with error %lu!", error);
					goto out_capacity;
				}
				if ((error = audin_server_send_open(audin, s)))
				{
					WLog_ERR(TAG, "audin_server_send_open failed with error %lu!", error);
					goto out_capacity;
				}
				break;

			case MSG_SNDIN_OPEN_REPLY:
				if ((error = audin_server_recv_open_reply(audin, s, BytesReturned)))
				{
					WLog_ERR(TAG, "audin_server_recv_open_reply failed with error %lu!", error);
					goto out_capacity;
				}
				break;

			case MSG_SNDIN_DATA_INCOMING:
				break;

			case MSG_SNDIN_DATA:
				if ((error = audin_server_recv_data(audin, s, BytesReturned)))
				{
					WLog_ERR(TAG, "audin_server_recv_data failed with error %lu!", error);
					goto out_capacity;
				};
				break;

			case MSG_SNDIN_FORMATCHANGE:
				break;

			default:
				WLog_ERR(TAG, "audin_server_thread_func: unknown MessageId %d", MessageId);
				break;
		}
	}

out_capacity:
	Stream_Free(s, TRUE);
out:
	WTSVirtualChannelClose(audin->audin_channel);
	audin->audin_channel = NULL;
	if (error && audin->context.rdpcontext)
		setChannelError(audin->context.rdpcontext, error, "audin_server_thread_func reported an error");

	ExitThread((DWORD)error);
	return NULL;
}
Beispiel #3
0
static void* audin_server_thread_func(void* arg)
{
	wStream* s;
	void* buffer;
	DWORD nCount;
	BYTE MessageId;
	HANDLE events[8];
	BOOL ready = FALSE;
	HANDLE ChannelEvent;
	DWORD BytesReturned = 0;
	audin_server* audin = (audin_server*) arg;

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

	if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE)
	{
		if (BytesReturned == sizeof(HANDLE))
			CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE));

		WTSFreeMemory(buffer);
	}

	nCount = 0;
	events[nCount++] = audin->stopEvent;
	events[nCount++] = ChannelEvent;

	/* Wait for the client to confirm that the Audio Input dynamic channel is ready */

	while (1)
	{
		if (WaitForMultipleObjects(nCount, events, FALSE, 100) == WAIT_OBJECT_0)
			break;

		if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualChannelReady, &buffer, &BytesReturned) == FALSE)
			break;

		ready = *((BOOL*) buffer);

		WTSFreeMemory(buffer);

		if (ready)
			break;
	}

	s = Stream_New(NULL, 4096);
	if (!s)
		goto out;

	if (ready)
	{
		audin_server_send_version(audin, s);
	}

	while (ready)
	{
		if (WaitForMultipleObjects(nCount, events, FALSE, INFINITE) == WAIT_OBJECT_0)
			break;

		Stream_SetPosition(s, 0);

		if (WTSVirtualChannelRead(audin->audin_channel, 0, (PCHAR) Stream_Buffer(s),
			Stream_Capacity(s), &BytesReturned) == FALSE)
		{
			if (BytesReturned == 0)
				break;
			
			Stream_EnsureRemainingCapacity(s, BytesReturned);

			if (WTSVirtualChannelRead(audin->audin_channel, 0, (PCHAR) Stream_Buffer(s),
				Stream_Capacity(s), &BytesReturned) == FALSE)
			{
				break;
			}
		}

		if (BytesReturned < 1)
			continue;

		Stream_Read_UINT8(s, MessageId);
		BytesReturned--;

		switch (MessageId)
		{
			case MSG_SNDIN_VERSION:
				if (audin_server_recv_version(audin, s, BytesReturned))
					audin_server_send_formats(audin, s);
				break;

			case MSG_SNDIN_FORMATS:
				if (audin_server_recv_formats(audin, s, BytesReturned))
					audin_server_send_open(audin, s);
				break;

			case MSG_SNDIN_OPEN_REPLY:
				audin_server_recv_open_reply(audin, s, BytesReturned);
				break;

			case MSG_SNDIN_DATA_INCOMING:
				break;

			case MSG_SNDIN_DATA:
				audin_server_recv_data(audin, s, BytesReturned);
				break;

			case MSG_SNDIN_FORMATCHANGE:
				break;

			default:
				fprintf(stderr, "audin_server_thread_func: unknown MessageId %d\n", MessageId);
				break;
		}
	}

	Stream_Free(s, TRUE);

out:
	WTSVirtualChannelClose(audin->audin_channel);
	audin->audin_channel = NULL;

	return NULL;
}