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; }
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; }
//------------------------------------------------------------------------------ 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; }
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; }
/** * 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; }
/** * 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; }
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; }
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; }
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); }
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; }
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; }
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; }