예제 #1
0
파일: wtsvc.c 프로젝트: railmeat/FreeRDP
boolean WTSVirtualChannelRead(
    /* __in */  void* hChannelHandle,
    /* __in */  uint32 TimeOut,
    /* __out */ uint8* Buffer,
    /* __in */  uint32 BufferSize,
    /* __out */ uint32* pBytesRead)
{
    wts_data_item* item;
    rdpPeerChannel* channel = (rdpPeerChannel*) hChannelHandle;

    item = (wts_data_item*) list_peek(channel->receive_queue);
    if (item == NULL)
    {
        wait_obj_clear(channel->receive_event);
        *pBytesRead = 0;
        return true;
    }
    *pBytesRead = item->length;
    if (item->length > BufferSize)
        return false;

    /* remove the first element (same as what we just peek) */
    freerdp_mutex_lock(channel->mutex);
    list_dequeue(channel->receive_queue);
    if (list_size(channel->receive_queue) == 0)
        wait_obj_clear(channel->receive_event);
    freerdp_mutex_unlock(channel->mutex);

    memcpy(Buffer, item->buffer, item->length);
    wts_data_item_free(item) ;

    return true;
}
예제 #2
0
static void *
thread_func(void * arg)
{
	cliprdrPlugin * plugin;
	struct wait_obj * listobj[2];
	int numobj;

	plugin = (cliprdrPlugin *) arg;

	plugin->thread_status = 1;
	LLOGLN(10, ("cliprdr_main thread_func: in"));
	while (1)
	{
		listobj[0] = plugin->term_event;
		listobj[1] = plugin->data_in_event;
		numobj = 2;
		wait_obj_select(listobj, numobj, NULL, 0, 500);

		if (wait_obj_is_set(plugin->term_event))
		{
			break;
		}
		if (wait_obj_is_set(plugin->data_in_event))
		{
			wait_obj_clear(plugin->data_in_event);
			/* process data in */
			thread_process_data_in(plugin);
		}
	}
	LLOGLN(10, ("cliprdr_main thread_func: out"));
	plugin->thread_status = -1;
	return 0;
}
예제 #3
0
//------------------------------------------------------------------------------
static void *
received_data_processing_thread_func(void * arg)
{
	railCorePlugin * plugin;
	struct wait_obj * listobj[2];
	int numobj;

	plugin = (railCorePlugin *) arg;

	plugin->thread_status = 1;
	LLOGLN(10, ("rail_core_plugin:received_data_processing_thread_func: in"));
	while (1)
	{
		listobj[0] = plugin->term_event;
		listobj[1] = plugin->data_in_event;
		numobj = 2;
		wait_obj_select(listobj, numobj, NULL, 0, 500);

		if (wait_obj_is_set(plugin->term_event))
		{
			break;
		}
		if (wait_obj_is_set(plugin->data_in_event))
		{
			wait_obj_clear(plugin->data_in_event);

			/* process data in */
			process_received_data(plugin);
		}
	}
	LLOGLN(10, ("rail_core_plugin:received_data_processing_thread_func: out"));
	plugin->thread_status = -1;
	return 0;
}
예제 #4
0
static void* serial_thread_func(void* arg)
{
    SERIAL_DEVICE* serial = (SERIAL_DEVICE*)arg;

    while (1)
    {
        freerdp_thread_wait(serial->thread);

        serial->nfds = 1;
        FD_ZERO(&serial->read_fds);
        FD_ZERO(&serial->write_fds);

        serial->tv.tv_sec = 20;
        serial->tv.tv_usec = 0;
        serial->select_timeout = 0;

        if (freerdp_thread_is_stopped(serial->thread))
            break;

        freerdp_thread_reset(serial->thread);
        serial_process_irp_list(serial);

        if (wait_obj_is_set(serial->in_event))
        {
            if (serial_check_fds(serial))
                wait_obj_clear(serial->in_event);
        }
    }

    freerdp_thread_quit(serial->thread);

    return NULL;
}
예제 #5
0
/**
 * called only from main thread
 */
boolean freerdp_chanman_check_fds(rdpChanMan * chan_man, freerdp* instance)
{
	if (wait_obj_is_set(chan_man->signal))
	{
		wait_obj_clear(chan_man->signal);
		freerdp_chanman_process_sync(chan_man, instance);
	}
	return True;
}
예제 #6
0
/**
 * called only from main thread
 */
int freerdp_chanman_check_fds(rdpChanMan * chan_man, rdpInst * inst)
{
	if (wait_obj_is_set(chan_man->signal))
	{
		wait_obj_clear(chan_man->signal);
		freerdp_chanman_process_sync(chan_man, inst);
	}
	return 0;
}
예제 #7
0
파일: wtsvc.c 프로젝트: ArthurGodoy/FreeRDP
boolean WTSVirtualChannelManagerCheckFileDescriptor(WTSVirtualChannelManager* vcm)
{
	boolean result = true;
	wts_data_item* item;
	rdpPeerChannel* channel;
	uint32 dynvc_caps;

	if (vcm->drdynvc_state == DRDYNVC_STATE_NONE && vcm->client->activated)
	{
		/* Initialize drdynvc channel once and only once. */
		vcm->drdynvc_state = DRDYNVC_STATE_INITIALIZED;

		channel = WTSVirtualChannelOpenEx(vcm, "drdynvc", 0);
		if (channel)
		{
			vcm->drdynvc_channel = channel;
			dynvc_caps = 0x00010050; /* DYNVC_CAPS_VERSION1 (4 bytes) */
			WTSVirtualChannelWrite(channel, (uint8*) &dynvc_caps, sizeof(dynvc_caps), NULL);
		}
	}

	wait_obj_clear(vcm->send_event);

	WaitForSingleObject(vcm->mutex, INFINITE);

	while ((item = (wts_data_item*) list_dequeue(vcm->send_queue)) != NULL)
	{
		if (vcm->client->SendChannelData(vcm->client, item->channel_id, item->buffer, item->length) == false)
		{
			result = false;
		}

		wts_data_item_free(item);

		if (result == false)
			break;
	}

	ReleaseMutex(vcm->mutex);

	return result;
}
예제 #8
0
파일: wtsvc.c 프로젝트: railmeat/FreeRDP
boolean WTSVirtualChannelManagerCheckFileDescriptor(WTSVirtualChannelManager* vcm)
{
    boolean result = true;
    wts_data_item* item;

    wait_obj_clear(vcm->send_event);

    freerdp_mutex_lock(vcm->mutex);
    while ((item = (wts_data_item*) list_dequeue(vcm->send_queue)) != NULL)
    {
        if (vcm->client->SendChannelData(vcm->client, item->channel_id, item->buffer, item->length) == false)
        {
            result = false;
        }
        wts_data_item_free(item);
        if (result == false)
            break;
    }
    freerdp_mutex_unlock(vcm->mutex);

    return result;
}
예제 #9
0
파일: test_utils.c 프로젝트: Cyclic/FreeRDP
void test_wait_obj(void)
{
	struct wait_obj* wo;
	int set;

	wo = wait_obj_new();

	set = wait_obj_is_set(wo);
	CU_ASSERT(set == 0);

	wait_obj_set(wo);
	set = wait_obj_is_set(wo);
	CU_ASSERT(set == 1);

	wait_obj_clear(wo);
	set = wait_obj_is_set(wo);
	CU_ASSERT(set == 0);

	wait_obj_select(&wo, 1, 1000);

	wait_obj_free(wo);
}
예제 #10
0
파일: rdpsnd_main.c 프로젝트: alama/freerdp
static void *
thread_func(void * arg)
{
	rdpsndPlugin * plugin;
	struct wait_obj * listobj[2];
	int numobj;
	int timeout;

	plugin = (rdpsndPlugin *) arg;

	plugin->thread_status = 1;
	LLOGLN(10, ("thread_func: in"));
	while (1)
	{
		listobj[0] = plugin->term_event;
		listobj[1] = plugin->data_in_event;
		numobj = 2;
		timeout = plugin->out_list_head == 0 ? -1 : 500;
		wait_obj_select(listobj, numobj, NULL, 0, timeout);
		if (wait_obj_is_set(plugin->term_event))
		{
			break;
		}
		if (wait_obj_is_set(plugin->data_in_event))
		{
			wait_obj_clear(plugin->data_in_event);
			/* process data in */
			thread_process_data_in(plugin);
		}
		if (plugin->out_list_head != 0)
		{
			thread_process_data_out(plugin);
		}
	}
	LLOGLN(10, ("thread_func: out"));
	plugin->thread_status = -1;
	return 0;
}
예제 #11
0
int transport_check_fds(rdpTransport* transport)
{
	int pos;
	int status;
	uint16 length;
	STREAM* received;

	wait_obj_clear(transport->recv_event);

	status = transport_read_nonblocking(transport);

	if (status < 0)
		return status;

	while ((pos = stream_get_pos(transport->recv_buffer)) > 0)
	{
		stream_set_pos(transport->recv_buffer, 0);
		if (tpkt_verify_header(transport->recv_buffer)) /* TPKT */
		{
			/* Ensure the TPKT header is available. */
			if (pos <= 4)
			{
				stream_set_pos(transport->recv_buffer, pos);
				return 0;
			}
			length = tpkt_read_header(transport->recv_buffer);
		}
		else /* Fast Path */
		{
			/* Ensure the Fast Path header is available. */
			if (pos <= 2)
			{
				stream_set_pos(transport->recv_buffer, pos);
				return 0;
			}
			length = fastpath_read_header(NULL, transport->recv_buffer);
		}

		if (length == 0)
		{
			printf("transport_check_fds: protocol error, not a TPKT or Fast Path header.\n");
			freerdp_hexdump(stream_get_head(transport->recv_buffer), pos);
			return -1;
		}

		if (pos < length)
		{
			stream_set_pos(transport->recv_buffer, pos);
			return 0; /* Packet is not yet completely received. */
		}

		/*
		 * A complete packet has been received. In case there are trailing data
		 * for the next packet, we copy it to the new receive buffer.
		 */
		received = transport->recv_buffer;
		transport->recv_buffer = stream_new(BUFFER_SIZE);

		if (pos > length)
		{
			stream_set_pos(received, length);
			stream_check_size(transport->recv_buffer, pos - length);
			stream_copy(transport->recv_buffer, received, pos - length);
		}

		stream_set_pos(received, length);
		stream_seal(received);
		stream_set_pos(received, 0);
		
		if (transport->recv_callback(transport, received, transport->recv_extra) == False)
			status = -1;
	
		stream_free(received);

		if (status < 0)
			return status;
	}

	return 0;
}
예제 #12
0
파일: transport.c 프로젝트: Cyclic/FreeRDP
int transport_check_fds(rdpTransport** ptransport)
{
	int pos;
	int status;
	uint16 length;
	STREAM* received;
	rdpTransport* transport = *ptransport;

	wait_obj_clear(transport->recv_event);

	status = transport_read_nonblocking(transport);

	if (status < 0)
		return status;

	while ((pos = stream_get_pos(transport->recv_buffer)) > 0)
	{
		stream_set_pos(transport->recv_buffer, 0);
		if (tpkt_verify_header(transport->recv_buffer)) /* TPKT */
		{
			/* Ensure the TPKT header is available. */
			if (pos <= 4)
			{
				stream_set_pos(transport->recv_buffer, pos);
				return 0;
			}
			length = tpkt_read_header(transport->recv_buffer);
		}
		else /* Fast Path */
		{
			/* Ensure the Fast Path header is available. */
			if (pos <= 2)
			{
				stream_set_pos(transport->recv_buffer, pos);
				return 0;
			}
			/* Fastpath header can be two or three bytes long. */
			length = fastpath_header_length(transport->recv_buffer);
			if (pos < length)
			{
				stream_set_pos(transport->recv_buffer, pos);
				return 0;
			}
			length = fastpath_read_header(NULL, transport->recv_buffer);
		}

		if (length == 0)
		{
			printf("transport_check_fds: protocol error, not a TPKT or Fast Path header.\n");
			freerdp_hexdump(stream_get_head(transport->recv_buffer), pos);
			return -1;
		}

		if (pos < length)
		{
			stream_set_pos(transport->recv_buffer, pos);
			return 0; /* Packet is not yet completely received. */
		}

		/*
		 * A complete packet has been received. In case there are trailing data
		 * for the next packet, we copy it to the new receive buffer.
		 */
		received = transport->recv_buffer;
		transport->recv_buffer = stream_new(BUFFER_SIZE);

		if (pos > length)
		{
			stream_set_pos(received, length);
			stream_check_size(transport->recv_buffer, pos - length);
			stream_copy(transport->recv_buffer, received, pos - length);
		}

		stream_set_pos(received, length);
		stream_seal(received);
		stream_set_pos(received, 0);

		if (transport->recv_callback(transport, received, transport->recv_extra) == false)
			status = -1;

		stream_free(received);

		if (status < 0)
			return status;

		/* transport might now have been freed by rdp_client_redirect and a new rdp->transport created */
		transport = *ptransport;

		if (transport->process_single_pdu)
		{
			/* one at a time but set event if data buffered
			 * so the main loop will call freerdp_check_fds asap */
			if (stream_get_pos(transport->recv_buffer) > 0)
				wait_obj_set(transport->recv_event);
			break;
		}

	}

	return 0;
}