示例#1
0
/**
 * Send a plugin-defined event to the plugin.
 * called only from main thread
 * @param channels the channel manager instance
 * @param event an event object created by freerdp_event_new()
 */
FREERDP_API int freerdp_channels_send_event(rdpChannels* chan_man, RDP_EVENT* event)
{
	struct channel_data* lchan_data;
	int index;
	const char* name;

	name = event_class_to_name_table[event->event_class];
	if (name == NULL)
	{
		DEBUG_CHANNELS("unknown event_class %d", event->event_class);
		freerdp_event_free(event);
		return 1;
	}

	lchan_data = freerdp_channels_find_channel_data_by_name(chan_man, name, &index);
	if (lchan_data == NULL)
	{
		DEBUG_CHANNELS("could not find channel name %s", name);
		freerdp_event_free(event);
		return 1;
	}
	if (lchan_data->open_event_proc != NULL)
	{
		lchan_data->open_event_proc(lchan_data->open_handle,
			CHANNEL_EVENT_USER,
			event, sizeof(RDP_EVENT), sizeof(RDP_EVENT), 0);
	}
	return 0;
}
示例#2
0
/**
 * Send a plugin-defined event to the plugin.
 * called only from main thread
 * @param channels the channel manager instance
 * @param event an event object created by freerdp_event_new()
 */
FREERDP_API int freerdp_channels_send_event(rdpChannels* channels, wMessage* event)
{
	int index;
	const char* name = NULL;
	rdpChannelData* lchannel_data;

	switch (GetMessageClass(event->id))
	{
		case DebugChannel_Class:
			name = "rdpdbg";
			break;

		case CliprdrChannel_Class:
			name = "cliprdr";
			break;

		case TsmfChannel_Class:
			name = "tsmf";
			break;

		case RailChannel_Class:
			name = "rail";
			break;
	}

	if (!name)
	{
		DEBUG_CHANNELS("unknown event_class %d", event->event_class);
		freerdp_event_free(event);
		return 1;
	}

	lchannel_data = freerdp_channels_find_channel_data_by_name(channels, name, &index);

	if (!lchannel_data)
	{
		DEBUG_CHANNELS("could not find channel name %s", name);
		freerdp_event_free(event);
		return 1;
	}

	if (lchannel_data->open_event_proc)
	{
		lchannel_data->open_event_proc(lchannel_data->open_handle, CHANNEL_EVENT_USER,
			event, sizeof(wMessage), sizeof(wMessage), 0);
	}

	return 0;
}
示例#3
0
/**
 * Send a plugin-defined event to the plugin.
 * called only from main thread
 * @param channels the channel manager instance
 * @param event an event object created by freerdp_event_new()
 */
FREERDP_API int freerdp_channels_send_event(rdpChannels* channels, wMessage* event)
{
	const char* name = NULL;
	CHANNEL_OPEN_DATA* pChannelOpenData;

	switch (GetMessageClass(event->id))
	{
		case DebugChannel_Class:
			name = "rdpdbg";
			break;

		case CliprdrChannel_Class:
			name = "cliprdr";
			break;

		case TsmfChannel_Class:
			name = "tsmf";
			break;

		case RailChannel_Class:
			name = "rail";
			break;
	}

	if (!name)
	{
		DEBUG_CHANNELS("unknown event_class %d", GetMessageClass(event->id));
		freerdp_event_free(event);
		return 1;
	}

	pChannelOpenData = freerdp_channels_find_channel_open_data_by_name(channels, name);

	if (!pChannelOpenData)
	{
		DEBUG_CHANNELS("could not find channel name %s", name);
		freerdp_event_free(event);
		return 1;
	}

	if (pChannelOpenData->pChannelOpenEventProc)
	{
		pChannelOpenData->pChannelOpenEventProc(pChannelOpenData->OpenHandle, CHANNEL_EVENT_USER,
			event, sizeof(wMessage), sizeof(wMessage), 0);
	}

	return 0;
}
示例#4
0
//-----------------------------------------------------------------------------
static void process_events_and_channel_data_from_plugin(thread_param* param)
{
	RDP_EVENT* event;

	param->th_count++;
	while (param->th_to_finish == 0)
	{
		freerdp_channels_check_fds(param->chan_man, param->instance);

		while (1)
		{
			event = freerdp_channels_pop_event(param->chan_man);
			if (event == NULL) break;

			static int counter = 0;
			counter++;

			printf("UI receive event. (type=%d counter=%d).\n",
					event->event_type,
					counter);

			// add to global event list
			if (param->in_events_number < RAIL_ARRAY_SIZE(param->in_events))
			{
				save_event(event, &param->in_events[param->in_events_number]);
				param->in_events_number++;
			}
			freerdp_event_free(event);
		}

		usleep(1000);
	}
	param->th_count--;
}
示例#5
0
void rds_process_channel_event(rdpChannels* channels, freerdp* instance)
{
	rdsContext* rds;
	wMessage* event;

	rds = (rdsContext*) instance->context;

	event = freerdp_channels_pop_event(channels);

	if (event)
	{
		switch (GetMessageClass(event->id))
		{
			case RailChannel_Class:
				break;

			case TsmfChannel_Class:
				break;

			case CliprdrChannel_Class:
				break;

			case RdpeiChannel_Class:
				break;

			default:
				break;
		}

		freerdp_event_free(event);
	}
}
示例#6
0
void test_channels(void)
{
	rdpChannels* chan_man;
	rdpSettings settings = { 0 };
	freerdp instance = { 0 };
	RDP_EVENT* event;

	settings.hostname = "testhost";
	instance.settings = &settings;
	instance.SendChannelData = test_rdp_channel_data;

	chan_man = freerdp_channels_new();

	freerdp_channels_load_plugin(chan_man, &settings, "../channels/rdpdbg/rdpdbg.so", NULL);
	freerdp_channels_pre_connect(chan_man, &instance);
	freerdp_channels_post_connect(chan_man, &instance);

	freerdp_channels_data(&instance, 0, "testdata", 8, CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, 8);
	freerdp_channels_data(&instance, 0, "testdata1", 9, CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, 9);
	freerdp_channels_data(&instance, 0, "testdata11", 10, CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, 10);
	freerdp_channels_data(&instance, 0, "testdata111", 11, CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, 11);

	event = freerdp_event_new(RDP_EVENT_CLASS_DEBUG, 0, NULL, NULL);
	freerdp_channels_send_event(chan_man, event);

	while ((event = freerdp_channels_pop_event(chan_man)) == NULL)
	{
		freerdp_channels_check_fds(chan_man, &instance);
	}
	printf("responded event_type %d\n", event->event_type);
	freerdp_event_free(event);

	freerdp_channels_close(chan_man, &instance);
	freerdp_channels_free(chan_man);
}
示例#7
0
static void cliprdr_process_event(rdpSvcPlugin* plugin, wMessage* event)
{
	switch (GetMessageType(event->id))
	{
		case CliprdrChannel_FormatList:
			cliprdr_process_format_list_event((cliprdrPlugin*) plugin, (RDP_CB_FORMAT_LIST_EVENT*) event);
			break;
		case CliprdrChannel_DataRequest:
			cliprdr_process_format_data_request_event((cliprdrPlugin*) plugin, (RDP_CB_DATA_REQUEST_EVENT*) event);
			break;
		case CliprdrChannel_DataResponse:
			cliprdr_process_format_data_response_event((cliprdrPlugin*) plugin, (RDP_CB_DATA_RESPONSE_EVENT*) event);
			break;
		case CliprdrChannel_FilecontentsRequest:
			cliprdr_process_filecontents_request_event((cliprdrPlugin*) plugin, (RDP_CB_FILECONTENTS_REQUEST_EVENT*) event);
			break;
		case CliprdrChannel_FilecontentsResponse:
			cliprdr_process_filecontents_response_event((cliprdrPlugin*) plugin, (RDP_CB_FILECONTENTS_RESPONSE_EVENT*) event);
			break;
		case CliprdrChannel_LockClipdata:
			cliprdr_process_lock_clipdata_event((cliprdrPlugin*) plugin, (RDP_CB_LOCK_CLIPDATA_EVENT*) event);
			break;
		case CliprdrChannel_UnLockClipdata:
			cliprdr_process_unlock_clipdata_event((cliprdrPlugin*) plugin, (RDP_CB_UNLOCK_CLIPDATA_EVENT*) event);
			break;
		case CliprdrChannel_TemporaryDirectory:
			cliprdr_process_tempdir_event((cliprdrPlugin*) plugin, (RDP_CB_TEMPDIR_EVENT*) event);
			break;
		default:
			WLog_ERR(TAG, "unknown event type %d", GetMessageType(event->id));
			break;
	}

	freerdp_event_free(event);
}
示例#8
0
static void tsmf_presentation_restore_last_video_frame(TSMF_PRESENTATION* presentation)
{
	RDP_REDRAW_EVENT* revent;

	if (presentation->last_width && presentation->last_height)
	{
		revent = (RDP_REDRAW_EVENT*) freerdp_event_new(TsmfChannel_Class, TsmfChannel_Redraw,
			NULL, NULL);

		revent->x = presentation->last_x;
		revent->y = presentation->last_y;
		revent->width = presentation->last_width;
		revent->height = presentation->last_height;

		if (!tsmf_push_event(presentation->channel_callback, (wMessage*) revent))
		{
			freerdp_event_free((wMessage*) revent);
		}

		presentation->last_x = 0;
		presentation->last_y = 0;
		presentation->last_width = 0;
		presentation->last_height = 0;
	}
}
示例#9
0
static void rdpdbg_process_event(rdpSvcPlugin* plugin, FRDP_EVENT* event)
{
	DEBUG_WARN("event_type %d", event->event_type);
	freerdp_event_free(event);

	event = freerdp_event_new(FRDP_EVENT_CLASS_DEBUG, 0, NULL, NULL);
	svc_plugin_send_event(plugin, event);
}
示例#10
0
static void sample_process_event(rdpSvcPlugin* plugin, RDP_EVENT* event)
{
	printf("sample_process_event:\n");

	/* events coming from main freerdp window to plugin */
	/* send them back with svc_plugin_send_event */

	freerdp_event_free(event);
}
示例#11
0
static void sample_process_event(rdpSvcPlugin* plugin, wMessage* event)
{
	fprintf(stderr, "sample_process_event:\n");

	/* events coming from main freerdp window to plugin */
	/* send them back with svc_plugin_send_event */

	freerdp_event_free(event);
}
示例#12
0
void wf_process_channel_event(rdpChannels* channels, freerdp* instance)
{
	RDP_EVENT* event;

	event = freerdp_channels_pop_event(channels);

	if (event)
		freerdp_event_free(event);
}
示例#13
0
static void svc_data_in_item_free(svc_data_in_item* item)
{
	if (item->data_in)
	{
		stream_free(item->data_in);
		item->data_in = NULL;
	}
	if (item->event_in)
	{
		freerdp_event_free(item->event_in);
		item->event_in = NULL;
	}
	xfree(item);
}
示例#14
0
static void rail_process_event(rdpSvcPlugin* plugin, RDP_EVENT* event)
{
	railPlugin* rail = NULL;
	rail = (railPlugin*) plugin;

	switch (event->event_type)
	{
		case RDP_EVENT_TYPE_RAIL_CLIENT_SET_SYSPARAMS:
			rail_recv_set_sysparams_event(rail->rail_order, event);
			break;

		case RDP_EVENT_TYPE_RAIL_CLIENT_EXEC_REMOTE_APP:
			rail_recv_exec_remote_app_event(rail->rail_order, event);
			break;

		case RDP_EVENT_TYPE_RAIL_CLIENT_ACTIVATE:
			rail_recv_activate_event(rail->rail_order, event);
			break;

		case RDP_EVENT_TYPE_RAIL_CLIENT_SYSMENU:
			rail_recv_sysmenu_event(rail->rail_order, event);
			break;

		case RDP_EVENT_TYPE_RAIL_CLIENT_SYSCOMMAND:
			rail_recv_syscommand_event(rail->rail_order, event);
			break;

		case RDP_EVENT_TYPE_RAIL_CLIENT_NOTIFY_EVENT:
			rail_recv_notify_event(rail->rail_order, event);
			break;

		case RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE:
			rail_recv_window_move_event(rail->rail_order, event);
			break;

		case RDP_EVENT_TYPE_RAIL_CLIENT_APPID_REQ:
			rail_recv_app_req_event(rail->rail_order, event);
			break;

		case RDP_EVENT_TYPE_RAIL_CLIENT_LANGBARINFO:
			rail_recv_langbarinfo_event(rail->rail_order, event);
			break;

		default:
			break;
	}

	freerdp_event_free(event);
}
示例#15
0
static void rail_process_event(rdpSvcPlugin* plugin, wMessage* event)
{
	railPlugin* rail = NULL;
	rail = (railPlugin*) plugin;

	switch (GetMessageType(event->id))
	{
		case RailChannel_ClientSystemParam:
			rail_recv_set_sysparams_event(rail->rail_order, event);
			break;

		case RailChannel_ClientExecute:
			rail_recv_exec_remote_app_event(rail->rail_order, event);
			break;

		case RailChannel_ClientActivate:
			rail_recv_activate_event(rail->rail_order, event);
			break;

		case RailChannel_ClientSystemMenu:
			rail_recv_sysmenu_event(rail->rail_order, event);
			break;

		case RailChannel_ClientSystemCommand:
			rail_recv_syscommand_event(rail->rail_order, event);
			break;

		case RailChannel_ClientNotifyEvent:
			rail_recv_notify_event(rail->rail_order, event);
			break;

		case RailChannel_ClientWindowMove:
			rail_recv_window_move_event(rail->rail_order, event);
			break;

		case RailChannel_ClientGetAppIdRequest:
			rail_recv_app_req_event(rail->rail_order, event);
			break;

		case RailChannel_ClientLanguageBarInfo:
			rail_recv_langbarinfo_event(rail->rail_order, event);
			break;

		default:
			break;
	}

	freerdp_event_free(event);
}
示例#16
0
void tf_process_channel_event(rdpChanMan* chanman, freerdp* instance)
{
	RDP_EVENT* event;

	event = freerdp_chanman_pop_event(chanman);
	if (event)
	{
		switch (event->event_type)
		{
			case RDP_EVENT_TYPE_CB_SYNC:
				tf_process_cb_sync_event(chanman, instance);
				break;
			default:
				printf("tf_process_channel_event: unknown event type %d\n", event->event_type);
				break;
		}
		freerdp_event_free(event);
	}
}
示例#17
0
void android_process_channel_event(rdpChannels* channels, freerdp* instance)
{
	wMessage* event;

	event = freerdp_channels_pop_event(channels);

	if (event)
	{
		switch(GetMessageClass(event->id))
		{
			case CliprdrChannel_Class:
				android_process_cliprdr_event(instance, event);
				break;

			default:
				break;
		}

		freerdp_event_free(event);
	}
}
示例#18
0
文件: freerdp.c 项目: felfert/FreeRDP
void tf_process_channel_event(rdpChannels* channels, freerdp* instance)
{
	RDP_EVENT* event;

	event = freerdp_channels_pop_event(channels);

	if (event)
	{
		switch (event->event_type)
		{
			case RDP_EVENT_TYPE_CB_MONITOR_READY:
				tf_process_cb_monitor_ready_event(channels, instance);
				break;
			default:
				printf("tf_process_channel_event: unknown event type %d\n", event->event_type);
				break;
		}

		freerdp_event_free(event);
	}
}
示例#19
0
static void cliprdr_process_event(rdpSvcPlugin* plugin, FRDP_EVENT* event)
{
	switch (event->event_type)
	{
		case FRDP_EVENT_TYPE_CB_FORMAT_LIST:
			cliprdr_process_format_list_event((cliprdrPlugin*)plugin, (FRDP_CB_FORMAT_LIST_EVENT*)event);
			break;

		case FRDP_EVENT_TYPE_CB_DATA_REQUEST:
			cliprdr_process_format_data_request_event((cliprdrPlugin*)plugin, (FRDP_CB_DATA_REQUEST_EVENT*)event);
			break;

		case FRDP_EVENT_TYPE_CB_DATA_RESPONSE:
			cliprdr_process_format_data_response_event((cliprdrPlugin*)plugin, (FRDP_CB_DATA_RESPONSE_EVENT*)event);
			break;

		default:
			DEBUG_WARN("unknown event type %d", event->event_type);
			break;
	}
	freerdp_event_free(event);
}
示例#20
0
void tf_process_channel_event(rdpChannels* channels, freerdp* instance)
{
	wMessage* event;

	event = freerdp_channels_pop_event(channels);

	if (event)
	{
		switch (GetMessageType(event->id))
		{
			case CliprdrChannel_MonitorReady:
				tf_process_cb_monitor_ready_event(channels, instance);
				break;

			default:
				printf("tf_process_channel_event: unknown event type %d\n", GetMessageType(event->id));
				break;
		}

		freerdp_event_free(event);
	}
}
示例#21
0
//-----------------------------------------------------------------------------
static void process_events_and_channel_data_from_plugin(thread_param* param)
{
	FRDP_EVENT* event;

	param->th_count++;
	while (param->th_to_finish == 0)
	{
		freerdp_chanman_check_fds(param->chan_man, param->instance);
		event = freerdp_chanman_pop_event(param->chan_man);
		if (event)
		{
			DEBUG_RAIL("UI receive %d event.", event->event_type);
			debug_event(event);

			// add to global event list
			freerdp_event_free(event);
		}

		usleep(1000);
	}
	param->th_count--;
}
示例#22
0
static void tsmf_presentation_restore_last_video_frame(TSMF_PRESENTATION* presentation)
{
	RDP_REDRAW_EVENT* revent;

	if (presentation->last_width && presentation->last_height)
	{
		revent = (RDP_REDRAW_EVENT*) freerdp_event_new(RDP_EVENT_CLASS_TSMF, RDP_EVENT_TYPE_TSMF_REDRAW,
			NULL, NULL);
		revent->x = presentation->last_x;
		revent->y = presentation->last_y;
		revent->width = presentation->last_width;
		revent->height = presentation->last_height;
		if (!tsmf_push_event(presentation->channel_callback, (RDP_EVENT*) revent))
		{
			freerdp_event_free((RDP_EVENT*) revent);
		}
		presentation->last_x = 0;
		presentation->last_y = 0;
		presentation->last_width = 0;
		presentation->last_height = 0;
	}
}
示例#23
0
void wf_process_channel_event(rdpChannels* channels, freerdp* instance)
{
	wfContext* wfc;
	wMessage* event;

	wfc = (wfContext*) instance->context;
	event = freerdp_channels_pop_event(channels);

	if (event)
	{
		switch (GetMessageClass(event->id))
		{
			case CliprdrChannel_Class:
				wf_process_cliprdr_event(wfc, event);
				break;

			default:
				break;
		}

		freerdp_event_free(event);
	}
}
示例#24
0
static void android_process_channel_event(rdpChannels* channels, freerdp* instance)
{
	wMessage* event;

	event = freerdp_channels_pop_event(channels);

	if (event)
	{
		int ev = GetMessageClass(event->id);
		switch(ev)
		{
			case CliprdrChannel_Class:
				android_process_cliprdr_event(instance, event);
				break;

			default:
				DEBUG_ANDROID("Unsupported channel event %08X", ev);
				break;
		}

		freerdp_event_free(event);
	}
}
示例#25
0
static void cliprdr_process_event(rdpSvcPlugin* plugin, wMessage* event)
{
	switch (GetMessageType(event->id))
	{
		case CliprdrChannel_FormatList:
			cliprdr_process_format_list_event((cliprdrPlugin*) plugin, (RDP_CB_FORMAT_LIST_EVENT*) event);
			break;

		case CliprdrChannel_DataRequest:
			cliprdr_process_format_data_request_event((cliprdrPlugin*) plugin, (RDP_CB_DATA_REQUEST_EVENT*) event);
			break;

		case CliprdrChannel_DataResponse:
			cliprdr_process_format_data_response_event((cliprdrPlugin*) plugin, (RDP_CB_DATA_RESPONSE_EVENT*) event);
			break;

		default:
			DEBUG_WARN("unknown event type %d", GetMessageType(event->id));
			break;
	}

	freerdp_event_free(event);
}
示例#26
0
void guac_rdpsnd_process_event(rdpSvcPlugin* plugin, wMessage* event) {
    freerdp_event_free(event);
}
示例#27
0
static void rdpsnd_process_event(rdpSvcPlugin* plugin, RDP_EVENT* event)
{
	freerdp_event_free(event);
}
示例#28
0
static void drdynvc_process_event(rdpSvcPlugin* plugin, FRDP_EVENT* event)
{
	freerdp_event_free(event);
}
示例#29
0
void test_cliprdr(void)
{
	int i;
	rdpChannels* channels;
	rdpSettings settings = { 0 };
	freerdp instance = { 0 };
	RDP_EVENT* event;
	RDP_CB_FORMAT_LIST_EVENT* format_list_event;
	RDP_CB_DATA_REQUEST_EVENT* data_request_event;
	RDP_CB_DATA_RESPONSE_EVENT* data_response_event;

	settings.hostname = "testhost";
	instance.settings = &settings;
	instance.SendChannelData = test_rdp_channel_data;

	channels = freerdp_channels_new();

	freerdp_channels_load_plugin(channels, &settings, "../channels/cliprdr/cliprdr.so", NULL);
	freerdp_channels_pre_connect(channels, &instance);
	freerdp_channels_post_connect(channels, &instance);

	/* server sends cliprdr capabilities and monitor ready PDU */
	freerdp_channels_data(&instance, 0, (char*)test_clip_caps_data, sizeof(test_clip_caps_data) - 1,
		CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, sizeof(test_clip_caps_data) - 1);

	freerdp_channels_data(&instance, 0, (char*)test_monitor_ready_data, sizeof(test_monitor_ready_data) - 1,
		CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, sizeof(test_monitor_ready_data) - 1);

	/* cliprdr sends clipboard_sync event to UI */
	while ((event = freerdp_channels_pop_event(channels)) == NULL)
	{
		freerdp_channels_check_fds(channels, &instance);
	}
	printf("Got event %d\n", event->event_type);
	CU_ASSERT(event->event_type == RDP_EVENT_TYPE_CB_MONITOR_READY);
	freerdp_event_free(event);

	/* UI sends format_list event to cliprdr */
	event = freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, RDP_EVENT_TYPE_CB_FORMAT_LIST, event_process_callback, NULL);
	format_list_event = (RDP_CB_FORMAT_LIST_EVENT*) event;
	format_list_event->num_formats = 2;
	format_list_event->formats = (uint32*) xmalloc(sizeof(uint32) * 2);
	format_list_event->formats[0] = CB_FORMAT_TEXT;
	format_list_event->formats[1] = CB_FORMAT_HTML;
	event_processed = 0;
	freerdp_channels_send_event(channels, event);

	/* cliprdr sends format list PDU to server */
	while (!event_processed)
	{
		freerdp_channels_check_fds(channels, &instance);
	}

	/* server sends format list response PDU to cliprdr */
	freerdp_channels_data(&instance, 0, (char*)test_format_list_response_data, sizeof(test_format_list_response_data) - 1,
		CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, sizeof(test_format_list_response_data) - 1);

	/* server sends format list PDU to cliprdr */
	freerdp_channels_data(&instance, 0, (char*)test_format_list_data, sizeof(test_format_list_data) - 1,
		CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, sizeof(test_format_list_data) - 1);

	/* cliprdr sends format_list event to UI */
	while ((event = freerdp_channels_pop_event(channels)) == NULL)
	{
		freerdp_channels_check_fds(channels, &instance);
	}
	printf("Got event %d\n", event->event_type);
	CU_ASSERT(event->event_type == RDP_EVENT_TYPE_CB_FORMAT_LIST);
	if (event->event_type == RDP_EVENT_TYPE_CB_FORMAT_LIST)
	{
		format_list_event = (RDP_CB_FORMAT_LIST_EVENT*)event;
		for (i = 0; i < format_list_event->num_formats; i++)
			printf("Format: 0x%X\n", format_list_event->formats[i]);
	}
	freerdp_event_free(event);

	/* server sends data request PDU to cliprdr */
	freerdp_channels_data(&instance, 0, (char*)test_data_request_data, sizeof(test_data_request_data) - 1,
		CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, sizeof(test_data_request_data) - 1);

	/* cliprdr sends data request event to UI */
	while ((event = freerdp_channels_pop_event(channels)) == NULL)
	{
		freerdp_channels_check_fds(channels, &instance);
	}
	printf("Got event %d\n", event->event_type);
	CU_ASSERT(event->event_type == RDP_EVENT_TYPE_CB_DATA_REQUEST);
	if (event->event_type == RDP_EVENT_TYPE_CB_DATA_REQUEST)
	{
		data_request_event = (RDP_CB_DATA_REQUEST_EVENT*)event;
		printf("Requested format: 0x%X\n", data_request_event->format);
	}
	freerdp_event_free(event);

	/* UI sends data response event to cliprdr */
	event = freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, RDP_EVENT_TYPE_CB_DATA_RESPONSE, event_process_callback, NULL);
	data_response_event = (RDP_CB_DATA_RESPONSE_EVENT*)event;
	data_response_event->data = (uint8*)xmalloc(6);
	strcpy((char*)data_response_event->data, "hello");
	data_response_event->size = 6;
	event_processed = 0;
	freerdp_channels_send_event(channels, event);

	/* cliprdr sends data response PDU to server */
	while (!event_processed)
	{
		freerdp_channels_check_fds(channels, &instance);
	}

	/* UI sends data request event to cliprdr */
	event = freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, RDP_EVENT_TYPE_CB_DATA_REQUEST, event_process_callback, NULL);
	data_request_event = (RDP_CB_DATA_REQUEST_EVENT*)event;
	data_request_event->format = CB_FORMAT_UNICODETEXT;
	event_processed = 0;
	freerdp_channels_send_event(channels, event);

	/* cliprdr sends data request PDU to server */
	while (!event_processed)
	{
		freerdp_channels_check_fds(channels, &instance);
	}

	/* server sends data response PDU to cliprdr */
	freerdp_channels_data(&instance, 0, (char*)test_data_response_data, sizeof(test_data_response_data) - 1,
		CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, sizeof(test_data_response_data) - 1);

	/* cliprdr sends data response event to UI */
	while ((event = freerdp_channels_pop_event(channels)) == NULL)
	{
		freerdp_channels_check_fds(channels, &instance);
	}
	printf("Got event %d\n", event->event_type);
	CU_ASSERT(event->event_type == RDP_EVENT_TYPE_CB_DATA_RESPONSE);
	if (event->event_type == RDP_EVENT_TYPE_CB_DATA_RESPONSE)
	{
		data_response_event = (RDP_CB_DATA_RESPONSE_EVENT*)event;
		printf("Data response size: %d\n", data_response_event->size);
		freerdp_hexdump(data_response_event->data, data_response_event->size);
	}
	freerdp_event_free(event);

	freerdp_channels_close(channels, &instance);
	freerdp_channels_free(channels);
}
示例#30
0
/**
 * Connects to an RDP server as described by the guac_rdp_settings structure
 * associated with the given client, allocating and freeing all objects
 * directly related to the RDP connection. It is expected that all objects
 * which are independent of FreeRDP's state (the clipboard, display update
 * management, etc.) will already be allocated and associated with the
 * guac_rdp_client associated with the given guac_client. This function blocks
 * for the duration of the RDP session, returning only after the session has
 * completely disconnected.
 *
 * @param client
 *     The guac_client associated with the RDP settings describing the
 *     connection that should be established.
 *
 * @return
 *     Zero if the connection successfully terminated and a reconnect is
 *     desired, non-zero if an error occurs or the connection was disconnected
 *     and a reconnect is NOT desired.
 */
static int guac_rdp_handle_connection(guac_client* client) {

    guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
    guac_rdp_settings* settings = rdp_client->settings;

    /* Init random number generator */
    srandom(time(NULL));

    /* Set up screen recording, if requested */
    if (settings->recording_path != NULL) {
        guac_common_recording_create(client,
                settings->recording_path,
                settings->recording_name,
                settings->create_recording_path);
    }

    /* Create display */
    rdp_client->display = guac_common_display_alloc(client,
            rdp_client->settings->width,
            rdp_client->settings->height);

    rdp_client->current_surface = rdp_client->display->default_surface;

    rdp_client->requested_clipboard_format = CB_FORMAT_TEXT;
    rdp_client->available_svc = guac_common_list_alloc();

#ifdef HAVE_FREERDP_CHANNELS_GLOBAL_INIT
    freerdp_channels_global_init();
#endif

    /* Init client */
    freerdp* rdp_inst = freerdp_new();
    rdp_inst->PreConnect = rdp_freerdp_pre_connect;
    rdp_inst->PostConnect = rdp_freerdp_post_connect;
    rdp_inst->Authenticate = rdp_freerdp_authenticate;
    rdp_inst->VerifyCertificate = rdp_freerdp_verify_certificate;
    rdp_inst->ReceiveChannelData = __guac_receive_channel_data;

    /* Allocate FreeRDP context */
#ifdef LEGACY_FREERDP
    rdp_inst->context_size = sizeof(rdp_freerdp_context);
#else
    rdp_inst->ContextSize = sizeof(rdp_freerdp_context);
#endif
    rdp_inst->ContextNew  = (pContextNew) rdp_freerdp_context_new;
    rdp_inst->ContextFree = (pContextFree) rdp_freerdp_context_free;

    freerdp_context_new(rdp_inst);
    ((rdp_freerdp_context*) rdp_inst->context)->client = client;

    /* Load keymap into client */
    rdp_client->keyboard = guac_rdp_keyboard_alloc(client,
            settings->server_layout);

    /* Send connection name */
    guac_protocol_send_name(client->socket, settings->hostname);

    /* Set default pointer */
    guac_common_cursor_set_pointer(rdp_client->display->cursor);

    /* Push desired settings to FreeRDP */
    guac_rdp_push_settings(settings, rdp_inst);

    /* Connect to RDP server */
    if (!freerdp_connect(rdp_inst)) {
        guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR,
                "Error connecting to RDP server");
        return 1;
    }

    /* Connection complete */
    rdp_client->rdp_inst = rdp_inst;
    rdpChannels* channels = rdp_inst->context->channels;

    guac_timestamp last_frame_end = guac_timestamp_current();

    /* Signal that reconnect has been completed */
    guac_rdp_disp_reconnect_complete(rdp_client->disp);

    /* Handle messages from RDP server while client is running */
    while (client->state == GUAC_CLIENT_RUNNING
            && !guac_rdp_disp_reconnect_needed(rdp_client->disp)) {

        /* Update remote display size */
        pthread_mutex_lock(&(rdp_client->rdp_lock));
        guac_rdp_disp_update_size(rdp_client->disp, settings, rdp_inst);
        pthread_mutex_unlock(&(rdp_client->rdp_lock));

        /* Wait for data and construct a reasonable frame */
        int wait_result = rdp_guac_client_wait_for_messages(client,
                GUAC_RDP_FRAME_START_TIMEOUT);
        if (wait_result > 0) {

            int processing_lag = guac_client_get_processing_lag(client);
            guac_timestamp frame_start = guac_timestamp_current();

            /* Read server messages until frame is built */
            do {

                guac_timestamp frame_end;
                int frame_remaining;

                pthread_mutex_lock(&(rdp_client->rdp_lock));

                /* Check the libfreerdp fds */
                if (!freerdp_check_fds(rdp_inst)) {
                    guac_client_abort(client,
                            GUAC_PROTOCOL_STATUS_SERVER_ERROR,
                            "Error handling RDP file descriptors");
                    pthread_mutex_unlock(&(rdp_client->rdp_lock));
                    return 1;
                }

                /* Check channel fds */
                if (!freerdp_channels_check_fds(channels, rdp_inst)) {
                    guac_client_abort(client,
                            GUAC_PROTOCOL_STATUS_SERVER_ERROR,
                            "Error handling RDP channel file descriptors");
                    pthread_mutex_unlock(&(rdp_client->rdp_lock));
                    return 1;
                }

                /* Check for channel events */
                wMessage* event = freerdp_channels_pop_event(channels);
                if (event) {

                    /* Handle channel events (clipboard and RAIL) */
#ifdef LEGACY_EVENT
                    if (event->event_class == CliprdrChannel_Class)
                        guac_rdp_process_cliprdr_event(client, event);
                    else if (event->event_class == RailChannel_Class)
                        guac_rdp_process_rail_event(client, event);
#else
                    if (GetMessageClass(event->id) == CliprdrChannel_Class)
                        guac_rdp_process_cliprdr_event(client, event);
                    else if (GetMessageClass(event->id) == RailChannel_Class)
                        guac_rdp_process_rail_event(client, event);
#endif

                    freerdp_event_free(event);

                }

                /* Handle RDP disconnect */
                if (freerdp_shall_disconnect(rdp_inst)) {
                    guac_client_stop(client);
                    guac_client_log(client, GUAC_LOG_INFO,
                            "RDP server closed connection");
                    pthread_mutex_unlock(&(rdp_client->rdp_lock));
                    return 1;
                }

                pthread_mutex_unlock(&(rdp_client->rdp_lock));

                /* Calculate time remaining in frame */
                frame_end = guac_timestamp_current();
                frame_remaining = frame_start + GUAC_RDP_FRAME_DURATION
                                - frame_end;

                /* Calculate time that client needs to catch up */
                int time_elapsed = frame_end - last_frame_end;
                int required_wait = processing_lag - time_elapsed;

                /* Increase the duration of this frame if client is lagging */
                if (required_wait > GUAC_RDP_FRAME_TIMEOUT)
                    wait_result = rdp_guac_client_wait_for_messages(client,
                            required_wait);

                /* Wait again if frame remaining */
                else if (frame_remaining > 0)
                    wait_result = rdp_guac_client_wait_for_messages(client,
                            GUAC_RDP_FRAME_TIMEOUT);
                else
                    break;

            } while (wait_result > 0);

            /* Record end of frame, excluding server-side rendering time (we
             * assume server-side rendering time will be consistent between any
             * two subsequent frames, and that this time should thus be
             * excluded from the required wait period of the next frame). */
            last_frame_end = frame_start;

        }

        /* If an error occurred, fail */
        if (wait_result < 0)
            guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR,
                    "Connection closed.");

        /* Flush frame */
        guac_common_display_flush(rdp_client->display);
        guac_client_end_frame(client);
        guac_socket_flush(client->socket);

    }

    pthread_mutex_lock(&(rdp_client->rdp_lock));

    /* Disconnect client and channels */
    freerdp_channels_close(channels, rdp_inst);
    freerdp_channels_free(channels);
    freerdp_disconnect(rdp_inst);

    /* Clean up RDP client context */
    freerdp_clrconv_free(((rdp_freerdp_context*) rdp_inst->context)->clrconv);
    cache_free(rdp_inst->context->cache);
    freerdp_context_free(rdp_inst);

    /* Clean up RDP client */
    freerdp_free(rdp_inst);
    rdp_client->rdp_inst = NULL;

    /* Free SVC list */
    guac_common_list_free(rdp_client->available_svc);

    /* Free RDP keyboard state */
    guac_rdp_keyboard_free(rdp_client->keyboard);

    /* Free display */
    guac_common_display_free(rdp_client->display);

    pthread_mutex_unlock(&(rdp_client->rdp_lock));

    /* Client is now disconnected */
    guac_client_log(client, GUAC_LOG_INFO, "Internal RDP client disconnected");

    return 0;

}