Exemple #1
0
/* called by main thread
   add item to linked list and inform worker thread that there is data */
static void
queue_data_and_signal_data_received(railCorePlugin * plugin)
{
	struct data_in_item * item;

	item = (struct data_in_item *) malloc(sizeof(struct data_in_item));

	item->data = plugin->data_in;
	item->data_size = plugin->data_in_size;
	item->next = NULL;

	plugin->data_in = NULL;
	plugin->data_in_size = 0;

	pthread_mutex_lock(plugin->in_mutex);
	if (plugin->in_list_tail == NULL)
	{
		plugin->in_list_head = item;
		plugin->in_list_tail = item;
	}
	else
	{
		plugin->in_list_tail->next = item;
		plugin->in_list_tail = item;
	}
	pthread_mutex_unlock(plugin->in_mutex);
	wait_obj_set(plugin->data_in_event);
}
Exemple #2
0
/* called by main thread
   add item to linked list and inform worker thread that there is data */
static void
signal_data_in(rdpsndPlugin * plugin)
{
	struct data_in_item * item;

	item = (struct data_in_item *) malloc(sizeof(struct data_in_item));
	item->next = 0;
	item->data = plugin->data_in;
	plugin->data_in = 0;
	item->data_size = plugin->data_in_size;
	plugin->data_in_size = 0;
	pthread_mutex_lock(plugin->in_mutex);
	if (plugin->in_list_tail == 0)
	{
		plugin->in_list_head = item;
		plugin->in_list_tail = item;
	}
	else
	{
		plugin->in_list_tail->next = item;
		plugin->in_list_tail = item;
	}
	pthread_mutex_unlock(plugin->in_mutex);
	wait_obj_set(plugin->data_in_event);
}
Exemple #3
0
static void __serial_check_fds(SERIAL_DEVICE* serial)
{
    IRP* irp;
    IRP* prev;
    SERIAL_TTY* tty;
    uint32 result = 0;

    memset(&serial->tv, 0, sizeof(struct timeval));
    tty = serial->tty;

    /* scan every pending */
    irp = list_peek(serial->pending_irps);
    while (irp)
    {
        DEBUG_SVC("MajorFunction %u", irp->MajorFunction);

        switch (irp->MajorFunction)
        {
        case IRP_MJ_READ:
            if (FD_ISSET(tty->fd, &serial->read_fds))
            {
                irp->IoStatus = STATUS_SUCCESS;
                serial_process_irp_read(serial, irp);
            }
            break;

        case IRP_MJ_WRITE:
            if (FD_ISSET(tty->fd, &serial->write_fds))
            {
                irp->IoStatus = STATUS_SUCCESS;
                serial_process_irp_write(serial, irp);
            }
            break;

        case IRP_MJ_DEVICE_CONTROL:
            if (serial_tty_get_event(tty, &result))
            {
                DEBUG_SVC("got event result %u", result);

                irp->IoStatus = STATUS_SUCCESS;
                stream_write_uint32(irp->output, result);
                irp->Complete(irp);
            }
            break;

        default:
            DEBUG_SVC("no request found");
            break;
        }

        prev = irp;
        irp = (IRP*)list_next(serial->pending_irps, irp);
        if (prev->IoStatus == STATUS_SUCCESS)
        {
            list_remove(serial->pending_irps, prev);
            wait_obj_set(serial->in_event);
        }
    }
}
Exemple #4
0
/* can be called from any thread */
static uint32 FREERDP_CC MyVirtualChannelWrite(uint32 openHandle, void* pData, uint32 dataLength,
	void* pUserData)
{
	rdpChannels* chan_man;
	struct channel_data* lchan;
	struct sync_data* item;
	int index;

	chan_man = freerdp_channels_find_by_open_handle(openHandle, &index);
	if ((chan_man == NULL) || (index < 0) || (index >= CHANNEL_MAX_COUNT))
	{
		DEBUG_CHANNELS("error bad chanhan");
		return CHANNEL_RC_BAD_CHANNEL_HANDLE;
	}
	if (!chan_man->is_connected)
	{
		DEBUG_CHANNELS("error not connected");
		return CHANNEL_RC_NOT_CONNECTED;
	}
	if (pData == 0)
	{
		DEBUG_CHANNELS("error bad pData");
		return CHANNEL_RC_NULL_DATA;
	}
	if (dataLength == 0)
	{
		DEBUG_CHANNELS("error bad dataLength");
		return CHANNEL_RC_ZERO_LENGTH;
	}
	lchan = chan_man->chans + index;
	if (lchan->flags != 2)
	{
		DEBUG_CHANNELS("error not open");
		return CHANNEL_RC_NOT_OPEN;
	}
	freerdp_mutex_lock(chan_man->sync_data_mutex); /* lock channels->sync* vars */
	if (!chan_man->is_connected)
	{
		freerdp_mutex_unlock(chan_man->sync_data_mutex);
		DEBUG_CHANNELS("error not connected");
		return CHANNEL_RC_NOT_CONNECTED;
	}
	item = xnew(struct sync_data);
	item->data = pData;
	item->data_length = dataLength;
	item->user_data = pUserData;
	item->index = index;
	list_enqueue(chan_man->sync_data_list, item);
	freerdp_mutex_unlock(chan_man->sync_data_mutex);

	/* set the event */
	wait_obj_set(chan_man->signal);

	return CHANNEL_RC_OK;
}
Exemple #5
0
int transport_write(rdpTransport* transport, STREAM* s)
{
	int status = -1;
	int length;

	length = stream_get_length(s);
	stream_set_pos(s, 0);

#ifdef WITH_DEBUG_TRANSPORT
	if (length > 0)
	{
		printf("Local > Remote\n");
		freerdp_hexdump(s->data, length);
	}
#endif

	while (length > 0)
	{
		if (transport->layer == TRANSPORT_LAYER_TLS)
			status = tls_write(transport->tls, stream_get_tail(s), length);
		else if (transport->layer == TRANSPORT_LAYER_TCP)
			status = tcp_write(transport->tcp, stream_get_tail(s), length);
		else if (transport->layer == TRANSPORT_LAYER_TSG)
			status = tsg_write(transport->tsg, stream_get_tail(s), length);

		if (status < 0)
			break; /* error occurred */

		if (status == 0)
		{
			/* blocking while sending */
			freerdp_usleep(transport->usleep_interval);

			/* when sending is blocked in nonblocking mode, the receiving buffer should be checked */
			if (!transport->blocking)
			{
				/* and in case we do have buffered some data, we set the event so next loop will get it */
				if (transport_read_nonblocking(transport) > 0)
					wait_obj_set(transport->recv_event);
			}
		}

		length -= status;
		stream_seek(s, status);
	}

	if (status < 0)
	{
		/* A write error indicates that the peer has dropped the connection */
		transport->layer = TRANSPORT_LAYER_CLOSED;
	}

	return status;
}
Exemple #6
0
static void
InitEventProcessTerminated(void * pInitHandle)
{
	rdpsndPlugin * plugin;
	int index;
	struct data_in_item * in_item;
	struct data_out_item * out_item;

	plugin = (rdpsndPlugin *) chan_plugin_find_by_init_handle(pInitHandle);
	if (plugin == NULL)
	{
		LLOGLN(0, ("InitEventProcessConnected: error no match"));
		return;
	}

	wait_obj_set(plugin->term_event);
	index = 0;
	while ((plugin->thread_status > 0) && (index < 100))
	{
		index++;
		usleep(250 * 1000);
	}
	wait_obj_free(plugin->term_event);
	wait_obj_free(plugin->data_in_event);

	pthread_mutex_destroy(plugin->in_mutex);
	free(plugin->in_mutex);

	/* free the un-processed in/out queue */
	while (plugin->in_list_head != 0)
	{
		in_item = plugin->in_list_head;
		plugin->in_list_head = in_item->next;
		free(in_item->data);
		free(in_item);
	}
	while (plugin->out_list_head != 0)
	{
		out_item = plugin->out_list_head;
		plugin->out_list_head = out_item->next;
		free(out_item->data);
		free(out_item);
	}

	if (plugin->device_plugin)
	{
		plugin->device_plugin->free(plugin->device_plugin);
		free(plugin->device_plugin);
		plugin->device_plugin = NULL;
	}
	chan_plugin_uninit((rdpChanPlugin *) plugin);
	free(plugin);
}
Exemple #7
0
void freerdp_thread_stop(freerdp_thread* thread)
{
	int i = 0;

	wait_obj_set(thread->signals[0]);

	while (thread->status > 0 && i < 1000)
	{
		i++;
		freerdp_usleep(100000);
	}
}
Exemple #8
0
static void wts_queue_send_item(rdpPeerChannel* channel, wts_data_item* item)
{
	WTSVirtualChannelManager* vcm;

	vcm = channel->vcm;

	item->channel_id = channel->channel_id;

	WaitForSingleObject(vcm->mutex, INFINITE);
	list_enqueue(vcm->send_queue, item);
	ReleaseMutex(vcm->mutex);

	wait_obj_set(vcm->send_event);
}
Exemple #9
0
static void serial_abort_single_io(SERIAL_DEVICE* serial, uint32 file_id, uint32 abort_io, uint32 io_status)
{
    IRP* irp = NULL;
    uint32 major;
    SERIAL_TTY* tty;

    DEBUG_SVC("[in] pending size %d", list_size(serial->pending_irps));

    tty = serial->tty;

    switch (abort_io)
    {
    case SERIAL_ABORT_IO_NONE:
        major = 0;
        break;

    case SERIAL_ABORT_IO_READ:
        major = IRP_MJ_READ;
        break;

    case SERIAL_ABORT_IO_WRITE:
        major = IRP_MJ_WRITE;
        break;

    default:
        DEBUG_SVC("unexpected abort_io code %d", abort_io);
        return;
    }

    irp = (IRP*)list_peek(serial->pending_irps);
    while (irp)
    {
        if (irp->FileId != file_id || irp->MajorFunction != major)
        {
            irp = (IRP*)list_next(serial->pending_irps, irp);
            continue;
        }

        /* Process a SINGLE FileId and MajorFunction */
        list_remove(serial->pending_irps, irp);
        irp->IoStatus = io_status;
        stream_write_uint32(irp->output, 0);
        irp->Complete(irp);

        wait_obj_set(serial->in_event);
        break;
    }

    DEBUG_SVC("[out] pending size %d", list_size(serial->pending_irps));
}
Exemple #10
0
static void wts_queue_send_item(rdpPeerChannel* channel, wts_data_item* item)
{
	WTSVirtualChannelManager* vcm;

	vcm = channel->vcm;

	item->channel_id = channel->channel_id;

	freerdp_mutex_lock(vcm->mutex);
	list_enqueue(vcm->send_queue, item);
	freerdp_mutex_unlock(vcm->mutex);

	wait_obj_set(vcm->send_event);
}
Exemple #11
0
//------------------------------------------------------------------------------
static void
InitEventProcessTerminated(void * pInitHandle)
{
	railCorePlugin * plugin;
	int index;
	struct data_in_item * in_item;

	LLOGLN(10, ("rail_core_plugin:InitEventProcessTerminated: pInitHandle=0x%p",
			pInitHandle));

	plugin = (railCorePlugin *) chan_plugin_find_by_init_handle(pInitHandle);
	if (plugin == NULL)
	{
		LLOGLN(0, ("rail_core_plugin:InitEventProcessTerminated: error no match"));
		return;
	}


	wait_obj_set(plugin->term_event);
	index = 0;
	while ((plugin->thread_status > 0) && (index < 100))
	{
		index++;
		usleep(250 * 1000);
	}
	wait_obj_free(plugin->term_event);
	wait_obj_free(plugin->data_in_event);

	pthread_mutex_destroy(plugin->in_mutex);
	free(plugin->in_mutex);

	/* free the un-processed in/out queue */
	while (plugin->in_list_head != NULL)
	{
		in_item = plugin->in_list_head;
		plugin->in_list_head = in_item->next;
		free(in_item->data);
		free(in_item);
	}
	if (plugin->data_in != NULL)
	{
		free(plugin->data_in);
	}

	chan_plugin_uninit((rdpChanPlugin *) plugin);

	rail_on_channel_terminated(plugin->session);
	free(plugin);
}
Exemple #12
0
static void wts_queue_receive_data(rdpPeerChannel* channel, const uint8* buffer, uint32 length)
{
	wts_data_item* item;

	item = xnew(wts_data_item);
	item->length = length;
	item->buffer = xmalloc(length);
	memcpy(item->buffer, buffer, length);

	freerdp_mutex_lock(channel->mutex);
	list_enqueue(channel->receive_queue, item);
	freerdp_mutex_unlock(channel->mutex);

	wait_obj_set(channel->receive_event);
}
Exemple #13
0
static void wts_queue_receive_data(rdpPeerChannel* channel, const uint8* buffer, uint32 length)
{
	wts_data_item* item;

	item = xnew(wts_data_item);
	item->length = length;
	item->buffer = xmalloc(length);
	memcpy(item->buffer, buffer, length);

	WaitForSingleObject(channel->mutex, INFINITE);
	list_enqueue(channel->receive_queue, item);
	ReleaseMutex(channel->mutex);

	wait_obj_set(channel->receive_event);
}
Exemple #14
0
static void serial_handle_async_irp(SERIAL_DEVICE* serial, IRP* irp)
{
    uint32 timeout = 0;
    uint32 itv_timeout = 0;
    SERIAL_TTY* tty;

    tty = serial->tty;

    switch (irp->MajorFunction)
    {
    case IRP_MJ_WRITE:
        DEBUG_SVC("handling IRP_MJ_WRITE");
        break;

    case IRP_MJ_READ:
        DEBUG_SVC("handling IRP_MJ_READ");

        serial_get_timeouts(serial, irp, &timeout, &itv_timeout);

        /* Check if io request timeout is smaller than current (but not 0). */
        if (timeout && (serial->select_timeout == 0 || timeout < serial->select_timeout))
        {
            serial->select_timeout = timeout;
            serial->tv.tv_sec = serial->select_timeout / 1000;
            serial->tv.tv_usec = (serial->select_timeout % 1000) * 1000;
            serial->timeout_id = tty->id;
        }
        if (itv_timeout && (serial->select_timeout == 0 || itv_timeout < serial->select_timeout))
        {
            serial->select_timeout = itv_timeout;
            serial->tv.tv_sec = serial->select_timeout / 1000;
            serial->tv.tv_usec = (serial->select_timeout % 1000) * 1000;
            serial->timeout_id = tty->id;
        }
        DEBUG_SVC("select_timeout %u, tv_sec %lu tv_usec %lu, timeout_id %u",
                  serial->select_timeout, serial->tv.tv_sec, serial->tv.tv_usec, serial->timeout_id);
        break;

    default:
        DEBUG_SVC("no need to handle %d", irp->MajorFunction);
        return;
    }

    irp->IoStatus = STATUS_PENDING;
    list_enqueue(serial->pending_irps, irp);
    wait_obj_set(serial->in_event);
}
Exemple #15
0
static void wts_read_drdynvc_create_response(rdpPeerChannel* channel, STREAM* s, uint32 length)
{
	uint32 CreationStatus;

	if (length < 4)
		return;
	stream_read_uint32(s, CreationStatus);
	if ((sint32)CreationStatus < 0)
	{
		DEBUG_DVC("ChannelId %d creation failed (%d)", channel->channel_id, (sint32)CreationStatus);
		channel->dvc_open_state = DVC_OPEN_STATE_FAILED;
	}
	else
	{
		DEBUG_DVC("ChannelId %d creation succeeded", channel->channel_id);
		channel->dvc_open_state = DVC_OPEN_STATE_SUCCEEDED;
	}
	wait_obj_set(channel->receive_event);
}
Exemple #16
0
boolean WTSVirtualChannelWrite(
    /* __in */  void* hChannelHandle,
    /* __in */  uint8* Buffer,
    /* __in */  uint32 Length,
    /* __out */ uint32* pBytesWritten)
{
    uint32 written = 0;
    wts_data_item* item;
    boolean result = false;
    rdpPeerChannel* channel = (rdpPeerChannel*) hChannelHandle;
    WTSVirtualChannelManager* vcm ;

    if (channel == NULL)
        return false;

    vcm = channel->vcm ;

    if (channel->channel_type == RDP_PEER_CHANNEL_TYPE_SVC)
    {
        item = xnew(wts_data_item);
        item->channel_id = channel->channel_id;
        item->buffer = xmalloc(Length);
        item->length = Length;
        memcpy(item->buffer, Buffer, Length);

        freerdp_mutex_lock(vcm->mutex);
        list_enqueue(vcm->send_queue, item);
        freerdp_mutex_unlock(vcm->mutex);

        wait_obj_set(vcm->send_event);

        written = Length;
        result = true;
    }
    else
    {
        /* TODO: Send to DVC channel */
    }

    if (pBytesWritten != NULL)
        *pBytesWritten = written;
    return result;
}
Exemple #17
0
static void serial_check_for_events(SERIAL_DEVICE* serial)
{
    IRP* irp = NULL;
    IRP* prev;
    uint32 result = 0;
    SERIAL_TTY* tty;

    tty = serial->tty;

    DEBUG_SVC("[in] pending size %d", list_size(serial->pending_irps));

    irp = (IRP*)list_peek(serial->pending_irps);
    while (irp)
    {
        prev = NULL;

        if (irp->MajorFunction == IRP_MJ_DEVICE_CONTROL)
        {
            if (serial_tty_get_event(tty, &result))
            {
                DEBUG_SVC("got event result %u", result);

                irp->IoStatus = STATUS_SUCCESS;
                stream_write_uint32(irp->output, result);
                irp->Complete(irp);

                prev = irp;
                irp = (IRP*)list_next(serial->pending_irps, irp);
                list_remove(serial->pending_irps, prev);

                wait_obj_set(serial->in_event);
            }
        }

        if (!prev)
            irp = (IRP*)list_next(serial->pending_irps, irp);
    }

    DEBUG_SVC("[out] pending size %d", list_size(serial->pending_irps));
}
Exemple #18
0
static uint32 FREERDP_CC MyVirtualChannelEventPush(uint32 openHandle, RDP_EVENT* event)
{
	rdpChannels* chan_man;
	struct channel_data* lchan;
	int index;

	chan_man = freerdp_channels_find_by_open_handle(openHandle, &index);
	if ((chan_man == NULL) || (index < 0) || (index >= CHANNEL_MAX_COUNT))
	{
		DEBUG_CHANNELS("error bad chanhan");
		return CHANNEL_RC_BAD_CHANNEL_HANDLE;
	}
	if (!chan_man->is_connected)
	{
		DEBUG_CHANNELS("error not connected");
		return CHANNEL_RC_NOT_CONNECTED;
	}
	if (event == NULL)
	{
		DEBUG_CHANNELS("error bad event");
		return CHANNEL_RC_NULL_DATA;
	}
	lchan = chan_man->chans + index;
	if (lchan->flags != 2)
	{
		DEBUG_CHANNELS("error not open");
		return CHANNEL_RC_NOT_OPEN;
	}
	freerdp_sem_wait(chan_man->event_sem); /* lock channels->event */
	if (!chan_man->is_connected)
	{
		freerdp_sem_signal(chan_man->event_sem);
		DEBUG_CHANNELS("error not connected");
		return CHANNEL_RC_NOT_CONNECTED;
	}
	chan_man->event = event;
	/* set the event */
	wait_obj_set(chan_man->signal);
	return CHANNEL_RC_OK;
}
Exemple #19
0
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);
}
Exemple #20
0
static void WTSProcessChannelData(rdpPeerChannel* channel, int channelId, uint8* data, int size, int flags, int total_size)
{
    wts_data_item* item;

    if (flags & CHANNEL_FLAG_FIRST)
    {
        stream_set_pos(channel->receive_data, 0);
    }

    stream_check_size(channel->receive_data, size);
    stream_write(channel->receive_data, data, size);

    if (flags & CHANNEL_FLAG_LAST)
    {
        if (stream_get_length(channel->receive_data) != total_size)
        {
            printf("WTSProcessChannelData: read error\n");
        }
        if (channel->channel_type == RDP_PEER_CHANNEL_TYPE_DVC)
        {
            /* TODO: Receive DVC channel data */
        }
        else
        {
            item = xnew(wts_data_item);
            item->length = stream_get_length(channel->receive_data);
            item->buffer = xmalloc(item->length);
            memcpy(item->buffer, stream_get_head(channel->receive_data), item->length);

            freerdp_mutex_lock(channel->mutex);
            list_enqueue(channel->receive_queue, item);
            freerdp_mutex_unlock(channel->mutex);

            wait_obj_set(channel->receive_event);
        }
        stream_set_pos(channel->receive_data, 0);
    }
}
Exemple #21
0
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;
}