Exemple #1
0
void WTSVirtualChannelManagerGetFileDescriptor(HANDLE hServer, void** fds, int* fds_count)
{
	void* fd;
	WTSVirtualChannelManager* vcm = (WTSVirtualChannelManager*) hServer;

	fd = GetEventWaitObject(MessageQueue_Event(vcm->queue));

	if (fd)
	{
		fds[*fds_count] = fd;
		(*fds_count)++;
	}

#if 0
	if (vcm->drdynvc_channel)
	{
		fd = GetEventWaitObject(vcm->drdynvc_channel->receiveEvent);

		if (fd)
		{
			fds[*fds_count] = fd;
			(*fds_count)++;
		}
	}
#endif
}
Exemple #2
0
HANDLE freerdp_channels_get_event_handle(freerdp* instance)
{
	HANDLE event = NULL;
	rdpChannels* channels;
	channels = instance->context->channels;
	event = MessageQueue_Event(channels->queue);
	return event;
}
Exemple #3
0
HANDLE freerdp_get_input_queue_event_handle(freerdp* instance)
{
	HANDLE event = NULL;

	if (instance->input->queue)
		event = MessageQueue_Event(instance->input->queue);

	return event;
}
Exemple #4
0
/**
 * called only from main thread
 */
BOOL freerdp_channels_check_fds(rdpChannels* channels, freerdp* instance)
{
	if (WaitForSingleObject(MessageQueue_Event(channels->queue), 0) == WAIT_OBJECT_0)
	{
		freerdp_channels_process_sync(channels, instance);
	}

	return TRUE;
}
Exemple #5
0
void* smartcard_context_thread(SMARTCARD_CONTEXT* pContext)
{
	DWORD nCount;
	DWORD status;
	HANDLE hEvents[2];
	wMessage message;
	SMARTCARD_DEVICE* smartcard;
	SMARTCARD_OPERATION* operation;

	smartcard = pContext->smartcard;

	nCount = 0;
	hEvents[nCount++] = MessageQueue_Event(pContext->IrpQueue);

	while (1)
	{
		status = WaitForMultipleObjects(nCount, hEvents, FALSE, INFINITE);

		if (WaitForSingleObject(MessageQueue_Event(pContext->IrpQueue), 0) == WAIT_OBJECT_0)
		{
			if (!MessageQueue_Peek(pContext->IrpQueue, &message, TRUE))
				break;

			if (message.id == WMQ_QUIT)
				break;

			operation = (SMARTCARD_OPERATION*) message.wParam;

			if (operation)
			{
				status = smartcard_irp_device_control_call(smartcard, operation);

				Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) operation->irp);

				free(operation);
			}
		}
	}

	ExitThread(0);
	return NULL;
}
Exemple #6
0
HANDLE freerdp_get_message_queue_event_handle(freerdp* instance, DWORD id)
{
	HANDLE event = NULL;
	wMessageQueue* queue = NULL;
	queue = freerdp_get_message_queue(instance, id);

	if (queue)
		event = MessageQueue_Event(queue);

	return event;
}
Exemple #7
0
int freerdp_channels_process_pending_messages(freerdp* instance)
{
	rdpChannels* channels;

	channels = instance->context->channels;

	if (WaitForSingleObject(MessageQueue_Event(channels->queue), 0) == WAIT_OBJECT_0)
	{
		 return freerdp_channels_process_sync(channels, instance);
	}

	return TRUE;
}
Exemple #8
0
/**
 * called only from main thread
 */
BOOL freerdp_channels_get_fds(rdpChannels* channels, freerdp* instance, void** read_fds,
	int* read_count, void** write_fds, int* write_count)
{
	void* pfd;

	pfd = GetEventWaitObject(MessageQueue_Event(channels->queue));

	if (pfd)
	{
		read_fds[*read_count] = pfd;
		(*read_count)++;
	}

	return TRUE;
}
Exemple #9
0
int freerds_client_get_event_handles(rdsBackend* backend, HANDLE* events, DWORD* nCount)
{
	rdsBackendConnector* connector = (rdsBackendConnector*) backend;

	if (connector)
	{
		if (connector->ServerQueue)
		{
			events[*nCount] = MessageQueue_Event(connector->ServerQueue);
			(*nCount)++;
		}
	}

	return 0;
}
Exemple #10
0
int freerds_client_check_event_handles(rdsBackend* backend)
{
	int status = 0;

	rdsBackendConnector* connector = (rdsBackendConnector*) backend;

	if (!connector)
		return 0;

	while (WaitForSingleObject(MessageQueue_Event(connector->ServerQueue), 0) == WAIT_OBJECT_0)
	{
		status = freerds_message_server_queue_process_pending_messages(connector);
	}

	return status;
}
Exemple #11
0
BOOL WINAPI FreeRDP_WTSVirtualChannelQuery(HANDLE hChannelHandle, WTS_VIRTUAL_CLASS WtsVirtualClass, PVOID* ppBuffer, DWORD* pBytesReturned)
{
	void* pfd;
	BOOL bval;
	void* fds[10];
	HANDLE hEvent;
	int fds_count = 0;
	BOOL status = FALSE;
	rdpPeerChannel* channel = (rdpPeerChannel*) hChannelHandle;
	ZeroMemory(fds, sizeof(fds));

	hEvent = MessageQueue_Event(channel->queue);

	switch ((UINT32) WtsVirtualClass)
	{
		case WTSVirtualFileHandle:

			pfd = GetEventWaitObject(hEvent);

			if (pfd)
			{
				fds[fds_count] = pfd;
				(fds_count)++;
			}

			*ppBuffer = malloc(sizeof(void*));
			CopyMemory(*ppBuffer, &fds[0], sizeof(void*));
			*pBytesReturned = sizeof(void*);
			status = TRUE;
			break;

		case WTSVirtualEventHandle:
			*ppBuffer = malloc(sizeof(HANDLE));
			CopyMemory(*ppBuffer, &(hEvent), sizeof(HANDLE));
			*pBytesReturned = sizeof(void*);
			status = TRUE;
			break;

		case WTSVirtualChannelReady:
			if (channel->channelType == RDP_PEER_CHANNEL_TYPE_SVC)
			{
				bval = TRUE;
				status = TRUE;
			}
			else
			{
				switch (channel->dvc_open_state)
				{
					case DVC_OPEN_STATE_NONE:
						bval = FALSE;
						status = TRUE;
						break;

					case DVC_OPEN_STATE_SUCCEEDED:
						bval = TRUE;
						status = TRUE;
						break;

					default:
						bval = FALSE;
						status = FALSE;
						break;
				}
			}

			*ppBuffer = malloc(sizeof(BOOL));
			CopyMemory(*ppBuffer, &bval, sizeof(BOOL));
			*pBytesReturned = sizeof(BOOL);
			break;

		default:
			break;
	}
	return status;
}
Exemple #12
0
void* shadow_client_thread(rdpShadowClient* client)
{
	DWORD status;
	DWORD nCount;
	wMessage message;
	wMessage pointerPositionMsg;
	wMessage pointerAlphaMsg;
	wMessage audioVolumeMsg;
	HANDLE events[32];
	HANDLE ClientEvent;
	HANDLE ChannelEvent;
	void* UpdateSubscriber;
	HANDLE UpdateEvent;
	freerdp_peer* peer;
	rdpContext* context;
	rdpSettings* settings;
	rdpShadowServer* server;
	rdpShadowScreen* screen;
	rdpShadowEncoder* encoder;
	rdpShadowSubsystem* subsystem;
	wMessageQueue* MsgQueue = client->MsgQueue;

	server = client->server;
	screen = server->screen;
	encoder = client->encoder;
	subsystem = server->subsystem;

	context = (rdpContext*) client;
	peer = context->peer;
	settings = peer->settings;

	peer->Capabilities = shadow_client_capabilities;
	peer->PostConnect = shadow_client_post_connect;
	peer->Activate = shadow_client_activate;

	shadow_input_register_callbacks(peer->input);

	peer->Initialize(peer);

	peer->update->RefreshRect = (pRefreshRect)shadow_client_refresh_rect;
	peer->update->SuppressOutput = (pSuppressOutput)shadow_client_suppress_output;
	peer->update->SurfaceFrameAcknowledge = (pSurfaceFrameAcknowledge)shadow_client_surface_frame_acknowledge;

	if ((!client->vcm) || (!subsystem->updateEvent))
		goto out;

	UpdateSubscriber = shadow_multiclient_get_subscriber(subsystem->updateEvent);
	if (!UpdateSubscriber)
		goto out;

	UpdateEvent = shadow_multiclient_getevent(UpdateSubscriber);
	ClientEvent = peer->GetEventHandle(peer);
	ChannelEvent = WTSVirtualChannelManagerGetEventHandle(client->vcm);

	while (1)
	{
		nCount = 0;
		events[nCount++] = UpdateEvent;
		events[nCount++] = ClientEvent;
		events[nCount++] = ChannelEvent;
		events[nCount++] = MessageQueue_Event(MsgQueue);

		status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);

		if (WaitForSingleObject(UpdateEvent, 0) == WAIT_OBJECT_0)
		{
			if (client->activated)
			{
				int index;
				int numRects = 0;
				const RECTANGLE_16* rects;
				int width, height;

				/* Check resize */
				shadow_client_calc_desktop_size(server, &width, &height);
				if (settings->DesktopWidth != (UINT32)width || settings->DesktopHeight != (UINT32)height)
				{
					/* Screen size changed, do resize */
					settings->DesktopWidth = width;
					settings->DesktopHeight = height;

					/**
					 * Unset client activated flag to avoid sending update message during
					 * resize. DesktopResize will reactive the client and 
					 * shadow_client_activate would be invoked later.
					 */
					client->activated = FALSE;

					/* Send Resize */
					peer->update->DesktopResize(peer->update->context); // update_send_desktop_resize

					/* Clear my invalidRegion. shadow_client_activate refreshes fullscreen */
					region16_clear(&(client->invalidRegion));

					WLog_ERR(TAG, "Client from %s is resized (%dx%d@%d)",
							peer->hostname, settings->DesktopWidth, settings->DesktopHeight, settings->ColorDepth);
				}
				else 
				{
					/* Send frame */
					rects = region16_rects(&(subsystem->invalidRegion), &numRects);

					for (index = 0; index < numRects; index++)
					{
						region16_union_rect(&(client->invalidRegion), &(client->invalidRegion), &rects[index]);
					}

					shadow_client_send_surface_update(client);
				}
			}

			/* 
			 * The return value of shadow_multiclient_consume is whether or not the subscriber really consumes the event.
			 * It's not cared currently.
			 */
			(void)shadow_multiclient_consume(UpdateSubscriber);
		}

		if (WaitForSingleObject(ClientEvent, 0) == WAIT_OBJECT_0)
		{
			if (!peer->CheckFileDescriptor(peer))
			{
				WLog_ERR(TAG, "Failed to check FreeRDP file descriptor");
				break;
			}
		}

		if (WaitForSingleObject(ChannelEvent, 0) == WAIT_OBJECT_0)
		{
			if (!WTSVirtualChannelManagerCheckFileDescriptor(client->vcm))
			{
				WLog_ERR(TAG, "WTSVirtualChannelManagerCheckFileDescriptor failure");
				break;
			}
		}

		if (WaitForSingleObject(MessageQueue_Event(MsgQueue), 0) == WAIT_OBJECT_0)
		{
			/* Drain messages. Pointer update could be accumulated. */
			pointerPositionMsg.id = 0;
			pointerPositionMsg.Free= NULL;
			pointerAlphaMsg.id = 0;
			pointerAlphaMsg.Free = NULL;
			audioVolumeMsg.id = 0;
			audioVolumeMsg.Free = NULL;
			while (MessageQueue_Peek(MsgQueue, &message, TRUE))
			{
				if (message.id == WMQ_QUIT)
				{
					break;
				}

				switch(message.id)
				{
					case SHADOW_MSG_OUT_POINTER_POSITION_UPDATE_ID:
						/* Abandon previous message */
						shadow_client_free_queued_message(&pointerPositionMsg);
						CopyMemory(&pointerPositionMsg, &message, sizeof(wMessage));
						break;

					case SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE_ID:
						/* Abandon previous message */
						shadow_client_free_queued_message(&pointerAlphaMsg);
						CopyMemory(&pointerAlphaMsg, &message, sizeof(wMessage));
						break;

					case SHADOW_MSG_OUT_AUDIO_OUT_VOLUME_ID:
						/* Abandon previous message */
						shadow_client_free_queued_message(&audioVolumeMsg);
						CopyMemory(&audioVolumeMsg, &message, sizeof(wMessage));
						break;

					default:
						shadow_client_subsystem_process_message(client, &message);
						break;
				}
			}

			if (message.id == WMQ_QUIT)
			{
				/* Release stored message */
				shadow_client_free_queued_message(&pointerPositionMsg);
				shadow_client_free_queued_message(&pointerAlphaMsg);
				shadow_client_free_queued_message(&audioVolumeMsg);
				break;
			}
			else
			{
				/* Process accumulated messages if needed */
				if (pointerPositionMsg.id)
				{
					shadow_client_subsystem_process_message(client, &pointerPositionMsg);
				}
				if (pointerAlphaMsg.id)
				{
					shadow_client_subsystem_process_message(client, &pointerAlphaMsg);
				}
				if (audioVolumeMsg.id)
				{
					shadow_client_subsystem_process_message(client, &audioVolumeMsg);
				}
			}
		}
	}

	/* Free channels early because we establish channels in post connect */
	shadow_client_channels_free(client);

	if (UpdateSubscriber)
	{
		shadow_multiclient_release_subscriber(UpdateSubscriber);
		UpdateSubscriber = NULL;
	}

	if (peer->connected && subsystem->ClientDisconnect)
	{
		subsystem->ClientDisconnect(subsystem, client);
	}

out:
	peer->Disconnect(peer);
	
	freerdp_peer_context_free(peer);
	freerdp_peer_free(peer);
	ExitThread(0);
	return NULL;
}
Exemple #13
0
static void* smartcard_thread_func(void* arg)
{
	IRP* irp;
	DWORD nCount;
	DWORD status;
	HANDLE hEvents[2];
	wMessage message;
	SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) arg;

	nCount = 0;
	hEvents[nCount++] = MessageQueue_Event(smartcard->IrpQueue);
	hEvents[nCount++] = Queue_Event(smartcard->CompletedIrpQueue);

	while (1)
	{
		status = WaitForMultipleObjects(nCount, hEvents, FALSE, INFINITE);

		if (WaitForSingleObject(MessageQueue_Event(smartcard->IrpQueue), 0) == WAIT_OBJECT_0)
		{
			if (!MessageQueue_Peek(smartcard->IrpQueue, &message, TRUE))
				break;

			if (message.id == WMQ_QUIT)
			{
				while (WaitForSingleObject(Queue_Event(smartcard->CompletedIrpQueue), 0) == WAIT_OBJECT_0)
				{
					irp = (IRP*) Queue_Dequeue(smartcard->CompletedIrpQueue);

					if (irp)
					{
						if (irp->thread)
						{
							WaitForSingleObject(irp->thread, INFINITE);
							CloseHandle(irp->thread);
							irp->thread = NULL;
						}

						smartcard_complete_irp(smartcard, irp);
					}
				}

				break;
			}

			irp = (IRP*) message.wParam;

			if (irp)
			{
				smartcard_process_irp(smartcard, irp);
			}
		}

		if (WaitForSingleObject(Queue_Event(smartcard->CompletedIrpQueue), 0) == WAIT_OBJECT_0)
		{
			irp = (IRP*) Queue_Dequeue(smartcard->CompletedIrpQueue);

			if (irp)
			{
				if (irp->thread)
				{
					WaitForSingleObject(irp->thread, INFINITE);
					CloseHandle(irp->thread);
					irp->thread = NULL;
				}

				smartcard_complete_irp(smartcard, irp);
			}
		}
	}

	ExitThread(0);
	return NULL;
}
Exemple #14
0
void* freerds_connection_main_thread(void* arg)
{
	DWORD status;
	DWORD nCount;
	HANDLE events[32];
	HANDLE ClientEvent;
	HANDLE ChannelEvent;
	HANDLE LocalTermEvent;
	HANDLE GlobalTermEvent;
	HANDLE NotificationEvent;
	rdsConnection* connection;
	rdpSettings* settings;
	rdsBackendConnector* connector = NULL;
	freerdp_peer* client = (freerdp_peer*) arg;
	BOOL disconnected = FALSE;
#ifndef WIN32
	sigset_t set;
	int ret;
#endif

	fprintf(stderr, "We've got a client %s\n", client->hostname);

	connection = (rdsConnection*) client->context;
	settings = client->settings;

	app_context_add_connection(connection);
	freerds_generate_certificate(settings);

	settings->RdpSecurity = FALSE;
	settings->TlsSecurity = TRUE;

	/**
	 * Disable NLA Security for now.
	 * TODO: make this a configurable option.
	 */
	settings->NlaSecurity = FALSE;

	client->Capabilities = freerds_peer_capabilities;
	client->PostConnect = freerds_peer_post_connect;
	client->Activate = freerds_peer_activate;

	client->Initialize(client);

	freerds_input_register_callbacks(client->input);

	client->update->SurfaceFrameAcknowledge = freerds_update_frame_acknowledge;
	client->update->SuppressOutput = freerds_suppress_output;

	ClientEvent = client->GetEventHandle(client);
	ChannelEvent = WTSVirtualChannelManagerGetEventHandle(connection->vcm);

	GlobalTermEvent = g_get_term_event();
	LocalTermEvent = connection->TermEvent;
	NotificationEvent = MessageQueue_Event(connection->notifications);
#ifndef WIN32
	sigemptyset(&set);
	sigaddset(&set, SIGPIPE);
	ret = pthread_sigmask(SIG_BLOCK, &set, NULL);
	if (0 != ret)
		fprintf(stderr, "couldn't block SIGPIPE\n");
#endif
	while (1)
	{
		nCount = 0;
		events[nCount++] = ClientEvent;
		events[nCount++] = ChannelEvent;
		events[nCount++] = GlobalTermEvent;
		events[nCount++] = LocalTermEvent;
		events[nCount++] = NotificationEvent;

		if (client->activated)
		{
			connector = (rdsBackendConnector*) connection->connector;

			if (connector && connector->GetEventHandles)
				connector->GetEventHandles((rdsBackend *)connector, events, &nCount);
		}

		status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);

		if (WaitForSingleObject(GlobalTermEvent, 0) == WAIT_OBJECT_0)
		{
			fprintf(stderr, "GlobalTermEvent\n");
			break;
		}

		if (WaitForSingleObject(LocalTermEvent, 0) == WAIT_OBJECT_0)
		{
			fprintf(stderr, "LocalTermEvent\n");
			break;
		}

		if (WaitForSingleObject(ClientEvent, 0) == WAIT_OBJECT_0)
		{
			if (client->CheckFileDescriptor(client) != TRUE)
			{
				fprintf(stderr, "Failed to check freerdp file descriptor\n");
				break;
			}
		}

		if (WaitForSingleObject(ChannelEvent, 0) == WAIT_OBJECT_0)
		{
			if (WTSVirtualChannelManagerCheckFileDescriptor(connection->vcm) != TRUE)
			{
				fprintf(stderr, "WTSVirtualChannelManagerCheckFileDescriptor failure\n");
				break;
			}
		}

		if (client->activated)
		{
			if (connector && connector->CheckEventHandles)
			{
				if (connector->CheckEventHandles((rdsBackend *)connector) < 0)
				{
					fprintf(stderr, "ModuleClient->CheckEventHandles failure\n");
					break;
				}
			}
		}
		if (WaitForSingleObject(NotificationEvent, 0) == WAIT_OBJECT_0)
		{
			wMessage message;

			MessageQueue_Peek(connection->notifications, (void *)(&message), TRUE);

			if (!freerds_client_process_notification(connection, &message))
				break;
		}
	}

	fprintf(stderr, "Client %s disconnected.\n", client->hostname);

	if (connection->connector)
	{
		freerds_connector_free(connection->connector);
		connection->connector = 0;

		freerds_icp_DisconnectUserSession(connection->id, &disconnected);
	}
	client->Disconnect(client);
	app_context_remove_connection(connection->id);

	freerdp_peer_context_free(client);
	freerdp_peer_free(client);

	return NULL;
}
Exemple #15
0
HANDLE WTSVirtualChannelManagerGetEventHandle(HANDLE hServer)
{
	WTSVirtualChannelManager* vcm = (WTSVirtualChannelManager*) hServer;
	return MessageQueue_Event(vcm->queue);
}
Exemple #16
0
void* smartcard_context_thread(SMARTCARD_CONTEXT* pContext)
{
	DWORD nCount;
	LONG status = 0;
	DWORD waitStatus;
	HANDLE hEvents[2];
	wMessage message;
	SMARTCARD_DEVICE* smartcard;
	SMARTCARD_OPERATION* operation;
	UINT error = CHANNEL_RC_OK;

	smartcard = pContext->smartcard;

	nCount = 0;
	hEvents[nCount++] = MessageQueue_Event(pContext->IrpQueue);

	while (1)
	{
		waitStatus = WaitForMultipleObjects(nCount, hEvents, FALSE, INFINITE);

		if (waitStatus == WAIT_FAILED)
		{
			error = GetLastError();
			WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error);
			break;
		}

		waitStatus = WaitForSingleObject(MessageQueue_Event(pContext->IrpQueue), 0);

		if (waitStatus == WAIT_FAILED)
		{
			error = GetLastError();
			WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
			break;
		}

		if (waitStatus == WAIT_OBJECT_0)
		{
			if (!MessageQueue_Peek(pContext->IrpQueue, &message, TRUE))
			{
				WLog_ERR(TAG, "MessageQueue_Peek failed!");
				status = ERROR_INTERNAL_ERROR;
				break;
			}


			if (message.id == WMQ_QUIT)
				break;

			operation = (SMARTCARD_OPERATION*) message.wParam;

			if (operation)
			{
				if ((status = smartcard_irp_device_control_call(smartcard, operation)))
				{
					WLog_ERR(TAG, "smartcard_irp_device_control_call failed with error %lu", status);
					break;
				}

				if (!Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) operation->irp))
				{
					WLog_ERR(TAG, "Queue_Enqueue failed!");
					status = ERROR_INTERNAL_ERROR;
					break;

				}

				free(operation);
			}
		}
	}

	if (status && smartcard->rdpcontext)
		setChannelError(smartcard->rdpcontext, error, "smartcard_context_thread reported an error");

	ExitThread((DWORD)status);
	return NULL;
}
Exemple #17
0
static void* smartcard_thread_func(void* arg)
{
	IRP* irp;
	DWORD nCount;
	DWORD status;
	HANDLE hEvents[2];
	wMessage message;
	SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) arg;
	UINT error = CHANNEL_RC_OK;

	nCount = 0;
	hEvents[nCount++] = MessageQueue_Event(smartcard->IrpQueue);
	hEvents[nCount++] = Queue_Event(smartcard->CompletedIrpQueue);

	while (1)
	{
		status = WaitForMultipleObjects(nCount, hEvents, FALSE, INFINITE);

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

		status = WaitForSingleObject(MessageQueue_Event(smartcard->IrpQueue), 0);

		if (status == WAIT_FAILED)
		{
			error = GetLastError();
			WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
			break;
		}

		if (status == WAIT_OBJECT_0)
		{
			if (!MessageQueue_Peek(smartcard->IrpQueue, &message, TRUE))
			{
				WLog_ERR(TAG, "MessageQueue_Peek failed!");
				error = ERROR_INTERNAL_ERROR;
				break;
			}


			if (message.id == WMQ_QUIT)
			{
				while (1)
				{
					status = WaitForSingleObject(Queue_Event(smartcard->CompletedIrpQueue), 0);

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

					if (status == WAIT_TIMEOUT)
						break;

					irp = (IRP*) Queue_Dequeue(smartcard->CompletedIrpQueue);

					if (irp)
					{
						if (irp->thread)
						{
							status = WaitForSingleObject(irp->thread, INFINITE);

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

							CloseHandle(irp->thread);
							irp->thread = NULL;
						}

						if ((error = smartcard_complete_irp(smartcard, irp)))
						{
							WLog_ERR(TAG, "smartcard_complete_irp failed with error %lu!", error);
							goto out;
						}
					}
				}

				break;
			}

			irp = (IRP*) message.wParam;

			if (irp)
			{
				if ((error = smartcard_process_irp(smartcard, irp)))
				{
					WLog_ERR(TAG, "smartcard_process_irp failed with error %lu!", error);
					goto out;
				}
			}
		}

		status = WaitForSingleObject(Queue_Event(smartcard->CompletedIrpQueue), 0);

		if (status == WAIT_FAILED)
		{
			error = GetLastError();
			WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
			break;
		}

		if (status == WAIT_OBJECT_0)
		{

			irp = (IRP*) Queue_Dequeue(smartcard->CompletedIrpQueue);

			if (irp)
			{
				if (irp->thread)
				{
					status = WaitForSingleObject(irp->thread, INFINITE);

					if (status == WAIT_FAILED)
					{
						error = GetLastError();
						WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
						break;
					}

					CloseHandle(irp->thread);
					irp->thread = NULL;
				}

				if ((error = smartcard_complete_irp(smartcard, irp)))
				{
					if (error == CHANNEL_RC_NOT_CONNECTED)
					{
						error = CHANNEL_RC_OK;
						goto out;
					}
					WLog_ERR(TAG, "smartcard_complete_irp failed with error %lu!", error);
					goto out;
				}
			}
		}
	}
out:
	if (error && smartcard->rdpcontext)
		setChannelError(smartcard->rdpcontext, error, "smartcard_thread_func reported an error");

	ExitThread((DWORD)error);
	return NULL;
}
Exemple #18
0
void* x11_shadow_subsystem_thread(x11ShadowSubsystem* subsystem)
{
	XEvent xevent;
	DWORD status;
	DWORD nCount;
	UINT64 cTime;
	DWORD dwTimeout;
	DWORD dwInterval;
	UINT64 frameTime;
	HANDLE events[32];
	wMessage message;
	wMessagePipe* MsgPipe;

	MsgPipe = subsystem->MsgPipe;

	nCount = 0;
	events[nCount++] = subsystem->event;
	events[nCount++] = MessageQueue_Event(MsgPipe->In);

	subsystem->captureFrameRate = 16;
	dwInterval = 1000 / subsystem->captureFrameRate;
	frameTime = GetTickCount64() + dwInterval;

	while (1)
	{
		cTime = GetTickCount64();
		dwTimeout = (cTime > frameTime) ? 0 : frameTime - cTime;

		status = WaitForMultipleObjects(nCount, events, FALSE, dwTimeout);

		if (WaitForSingleObject(MessageQueue_Event(MsgPipe->In), 0) == WAIT_OBJECT_0)
		{
			if (MessageQueue_Peek(MsgPipe->In, &message, TRUE))
			{
				if (message.id == WMQ_QUIT)
					break;

				x11_shadow_subsystem_process_message(subsystem, &message);
			}
		}

		if (WaitForSingleObject(subsystem->event, 0) == WAIT_OBJECT_0)
		{
			XLockDisplay(subsystem->display);

			if (XEventsQueued(subsystem->display, QueuedAlready))
			{
				XNextEvent(subsystem->display, &xevent);
				x11_shadow_handle_xevent(subsystem, &xevent);
			}

			XUnlockDisplay(subsystem->display);
		}

		if ((status == WAIT_TIMEOUT) || (GetTickCount64() > frameTime))
		{
			x11_shadow_check_resize(subsystem);
			x11_shadow_screen_grab(subsystem);
			x11_shadow_query_cursor(subsystem, FALSE);

			dwInterval = 1000 / subsystem->captureFrameRate;
			frameTime += dwInterval;
		}
	}

	ExitThread(0);
	return NULL;
}
Exemple #19
0
static void* shadow_client_thread(rdpShadowClient* client)
{
	DWORD status;
	DWORD nCount;
	wMessage message;
	wMessage pointerPositionMsg;
	wMessage pointerAlphaMsg;
	wMessage audioVolumeMsg;
	HANDLE events[32];
	HANDLE ClientEvent;
	HANDLE ChannelEvent;
	void* UpdateSubscriber;
	HANDLE UpdateEvent;
	freerdp_peer* peer;
	rdpContext* context;
	rdpSettings* settings;
	rdpShadowServer* server;
	rdpShadowScreen* screen;
	rdpShadowEncoder* encoder;
	rdpShadowSubsystem* subsystem;
	wMessageQueue* MsgQueue = client->MsgQueue;
	/* This should only be visited in client thread */
	SHADOW_GFX_STATUS gfxstatus;

	gfxstatus.gfxOpened = FALSE;
	gfxstatus.gfxSurfaceCreated = FALSE;

	server = client->server;
	screen = server->screen;
	encoder = client->encoder;
	subsystem = server->subsystem;

	context = (rdpContext*) client;
	peer = context->peer;
	settings = peer->settings;

	peer->Capabilities = shadow_client_capabilities;
	peer->PostConnect = shadow_client_post_connect;
	peer->Activate = shadow_client_activate;
	peer->Logon = shadow_client_logon;

	shadow_input_register_callbacks(peer->input);

	peer->Initialize(peer);

	peer->update->RefreshRect = (pRefreshRect)shadow_client_refresh_rect;
	peer->update->SuppressOutput = (pSuppressOutput)shadow_client_suppress_output;
	peer->update->SurfaceFrameAcknowledge = (pSurfaceFrameAcknowledge)shadow_client_surface_frame_acknowledge;

	if ((!client->vcm) || (!subsystem->updateEvent))
		goto out;

	UpdateSubscriber = shadow_multiclient_get_subscriber(subsystem->updateEvent);
	if (!UpdateSubscriber)
		goto out;

	UpdateEvent = shadow_multiclient_getevent(UpdateSubscriber);
	ClientEvent = peer->GetEventHandle(peer);
	ChannelEvent = WTSVirtualChannelManagerGetEventHandle(client->vcm);

	while (1)
	{
		nCount = 0;
		events[nCount++] = UpdateEvent;
		events[nCount++] = ClientEvent;
		events[nCount++] = ChannelEvent;
		events[nCount++] = MessageQueue_Event(MsgQueue);

		status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);

		if (WaitForSingleObject(UpdateEvent, 0) == WAIT_OBJECT_0)
		{
			/* The UpdateEvent means to start sending current frame. It is
			 * triggered from subsystem implementation and it should ensure
			 * that the screen and primary surface meta data (width, height,
			 * scanline, invalid region, etc) is not changed until it is reset
			 * (at shadow_multiclient_consume). As best practice, subsystem
			 * implementation should invoke shadow_subsystem_frame_update which
			 * triggers the event and then wait for completion */

			if (client->activated && !client->suppressOutput)
			{
				/* Send screen update or resize to this client */

				/* Check resize */
				if (shadow_client_recalc_desktop_size(client))
				{
					/* Screen size changed, do resize */
					if (!shadow_client_send_resize(client, &gfxstatus))
					{
						WLog_ERR(TAG, "Failed to send resize message");
						break;
					}
				}
				else
				{
					/* Send frame */
					if (!shadow_client_send_surface_update(client, &gfxstatus))
					{
						WLog_ERR(TAG, "Failed to send surface update");
						break;
					}
				}
			}
			else
			{
				/* Our client don't receive graphic updates. Just save the invalid region */
				if (!shadow_client_no_surface_update(client, &gfxstatus))
				{
					WLog_ERR(TAG, "Failed to handle surface update");
					break;
				}
			}

			/*
			 * The return value of shadow_multiclient_consume is whether or not 
			 * the subscriber really consumes the event. It's not cared currently.
			 */
			(void)shadow_multiclient_consume(UpdateSubscriber);
		}

		if (WaitForSingleObject(ClientEvent, 0) == WAIT_OBJECT_0)
		{
			if (!peer->CheckFileDescriptor(peer))
			{
				WLog_ERR(TAG, "Failed to check FreeRDP file descriptor");
				break;
			}

			if (WTSVirtualChannelManagerIsChannelJoined(client->vcm, "drdynvc"))
			{
				/* Dynamic channel status may have been changed after processing */
				if (WTSVirtualChannelManagerGetDrdynvcState(client->vcm) == DRDYNVC_STATE_NONE)
				{
					/* Call this routine to Initialize drdynvc channel */
					if (!WTSVirtualChannelManagerCheckFileDescriptor(client->vcm))
					{
						WLog_ERR(TAG, "Failed to initialize drdynvc channel");
						break;
					}
				}
				else if (WTSVirtualChannelManagerGetDrdynvcState(client->vcm) == DRDYNVC_STATE_READY)
				{
					/* Init RDPGFX dynamic channel */
					if (settings->SupportGraphicsPipeline && client->rdpgfx &&
					    !gfxstatus.gfxOpened)
					{
						if (!client->rdpgfx->Open(client->rdpgfx))
						{
							WLog_WARN(TAG, "Failed to open GraphicsPipeline");
							settings->SupportGraphicsPipeline = FALSE;
						}

						client->rdpgfx->FrameAcknowledge = shadow_client_rdpgfx_frame_acknowledge;
						client->rdpgfx->QoeFrameAcknowledge = shadow_client_rdpgfx_qoe_frame_acknowledge;

						gfxstatus.gfxOpened = TRUE;
						WLog_INFO(TAG, "Gfx Pipeline Opened");
					}
				}
			}
		}

		if (WaitForSingleObject(ChannelEvent, 0) == WAIT_OBJECT_0)
		{
			if (!WTSVirtualChannelManagerCheckFileDescriptor(client->vcm))
			{
				WLog_ERR(TAG, "WTSVirtualChannelManagerCheckFileDescriptor failure");
				break;
			}
		}

		if (WaitForSingleObject(MessageQueue_Event(MsgQueue), 0) == WAIT_OBJECT_0)
		{
			/* Drain messages. Pointer update could be accumulated. */
			pointerPositionMsg.id = 0;
			pointerPositionMsg.Free= NULL;
			pointerAlphaMsg.id = 0;
			pointerAlphaMsg.Free = NULL;
			audioVolumeMsg.id = 0;
			audioVolumeMsg.Free = NULL;
			while (MessageQueue_Peek(MsgQueue, &message, TRUE))
			{
				if (message.id == WMQ_QUIT)
				{
					break;
				}

				switch(message.id)
				{
					case SHADOW_MSG_OUT_POINTER_POSITION_UPDATE_ID:
						/* Abandon previous message */
						shadow_client_free_queued_message(&pointerPositionMsg);
						CopyMemory(&pointerPositionMsg, &message, sizeof(wMessage));
						break;

					case SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE_ID:
						/* Abandon previous message */
						shadow_client_free_queued_message(&pointerAlphaMsg);
						CopyMemory(&pointerAlphaMsg, &message, sizeof(wMessage));
						break;

					case SHADOW_MSG_OUT_AUDIO_OUT_VOLUME_ID:
						/* Abandon previous message */
						shadow_client_free_queued_message(&audioVolumeMsg);
						CopyMemory(&audioVolumeMsg, &message, sizeof(wMessage));
						break;

					default:
						shadow_client_subsystem_process_message(client, &message);
						break;
				}
			}

			if (message.id == WMQ_QUIT)
			{
				/* Release stored message */
				shadow_client_free_queued_message(&pointerPositionMsg);
				shadow_client_free_queued_message(&pointerAlphaMsg);
				shadow_client_free_queued_message(&audioVolumeMsg);
				break;
			}
			else
			{
				/* Process accumulated messages if needed */
				if (pointerPositionMsg.id)
				{
					shadow_client_subsystem_process_message(client, &pointerPositionMsg);
				}
				if (pointerAlphaMsg.id)
				{
					shadow_client_subsystem_process_message(client, &pointerAlphaMsg);
				}
				if (audioVolumeMsg.id)
				{
					shadow_client_subsystem_process_message(client, &audioVolumeMsg);
				}
			}
		}
	}

	/* Free channels early because we establish channels in post connect */
	if (gfxstatus.gfxOpened)
	{
		if (gfxstatus.gfxSurfaceCreated)
		{
			if (!shadow_client_rdpgfx_release_surface(client))
				WLog_WARN(TAG, "GFX release surface failure!");
		}
		(void)client->rdpgfx->Close(client->rdpgfx);
	}
	shadow_client_channels_free(client);

	if (UpdateSubscriber)
	{
		shadow_multiclient_release_subscriber(UpdateSubscriber);
		UpdateSubscriber = NULL;
	}

	if (peer->connected && subsystem->ClientDisconnect)
	{
		subsystem->ClientDisconnect(subsystem, client);
	}

out:
	peer->Disconnect(peer);

	freerdp_peer_context_free(peer);
	freerdp_peer_free(peer);
	ExitThread(0);
	return NULL;
}