rdpChanMan* freerdp_chanman_new(void) { rdpChanMan* chan_man; rdpChanManList* list; chan_man = xnew(rdpChanMan); chan_man->sync_data_mutex = freerdp_mutex_new(); chan_man->sync_data_list = list_new(); chan_man->event_sem = freerdp_sem_new(1); chan_man->signal = wait_obj_new(); /* Add it to the global list */ list = xnew(rdpChanManList); list->chan_man = chan_man; freerdp_mutex_lock(g_mutex_list); list->next = g_chan_man_list; g_chan_man_list = list; freerdp_mutex_unlock(g_mutex_list); return chan_man; }
/** * must be called by same thread that calls freerdp_chanman_load_plugin * according to MS docs * only called from main thread */ static uint32 FREERDP_CC MyVirtualChannelInit(void** ppInitHandle, PCHANNEL_DEF pChannel, int channelCount, uint32 versionRequested, PCHANNEL_INIT_EVENT_FN pChannelInitEventProc) { rdpChannels* chan_man; int index; struct lib_data* llib; struct channel_data* lchan; rdpChannel* lrdp_chan; PCHANNEL_DEF lchan_def; chan_man = g_init_chan_man; chan_man->init_handles[chan_man->num_init_handles].chan_man = chan_man; *ppInitHandle = &chan_man->init_handles[chan_man->num_init_handles]; chan_man->num_init_handles++; DEBUG_CHANNELS("enter"); if (!chan_man->can_call_init) { DEBUG_CHANNELS("error not in entry"); return CHANNEL_RC_NOT_IN_VIRTUALCHANNELENTRY; } if (ppInitHandle == 0) { DEBUG_CHANNELS("error bad pphan"); return CHANNEL_RC_BAD_INIT_HANDLE; } if (chan_man->num_chans + channelCount >= CHANNEL_MAX_COUNT) { DEBUG_CHANNELS("error too many channels"); return CHANNEL_RC_TOO_MANY_CHANNELS; } if (pChannel == 0) { DEBUG_CHANNELS("error bad pchan"); return CHANNEL_RC_BAD_CHANNEL; } if (chan_man->is_connected) { DEBUG_CHANNELS("error already connected"); return CHANNEL_RC_ALREADY_CONNECTED; } if (versionRequested != VIRTUAL_CHANNEL_VERSION_WIN2000) { DEBUG_CHANNELS("warning version"); } for (index = 0; index < channelCount; index++) { lchan_def = pChannel + index; if (freerdp_channels_find_channel_data_by_name(chan_man, lchan_def->name, 0) != 0) { DEBUG_CHANNELS("error channel already used"); return CHANNEL_RC_BAD_CHANNEL; } } llib = chan_man->libs + chan_man->num_libs; llib->init_event_proc = pChannelInitEventProc; llib->init_handle = *ppInitHandle; chan_man->num_libs++; for (index = 0; index < channelCount; index++) { lchan_def = pChannel + index; lchan = chan_man->chans + chan_man->num_chans; freerdp_mutex_lock(g_mutex_list); lchan->open_handle = g_open_handle_sequence++; freerdp_mutex_unlock(g_mutex_list); lchan->flags = 1; /* init */ strncpy(lchan->name, lchan_def->name, CHANNEL_NAME_LEN); lchan->options = lchan_def->options; if (chan_man->settings->num_channels < 16) { lrdp_chan = chan_man->settings->channels + chan_man->settings->num_channels; strncpy(lrdp_chan->name, lchan_def->name, 7); lrdp_chan->options = lchan_def->options; chan_man->settings->num_channels++; } else { DEBUG_CHANNELS("warning more than 16 channels"); } chan_man->num_chans++; } return CHANNEL_RC_OK; }
void* WTSVirtualChannelOpenEx( /* __in */ WTSVirtualChannelManager* vcm, /* __in */ const char* pVirtualName, /* __in */ uint32 flags) { int i; int len; rdpPeerChannel* channel; freerdp_peer* client = vcm->client; STREAM* s; if ((flags & WTS_CHANNEL_OPTION_DYNAMIC) != 0) { if (vcm->drdynvc_channel == NULL || vcm->drdynvc_state != DRDYNVC_STATE_READY) { DEBUG_DVC("Dynamic virtual channel not ready."); return NULL; } channel = xnew(rdpPeerChannel); channel->vcm = vcm; channel->client = client; channel->channel_type = RDP_PEER_CHANNEL_TYPE_DVC; channel->receive_data = stream_new(client->settings->vc_chunk_size); channel->receive_event = wait_obj_new(); channel->receive_queue = list_new(); channel->mutex = freerdp_mutex_new(); freerdp_mutex_lock(vcm->mutex); channel->channel_id = vcm->dvc_channel_id_seq++; list_enqueue(vcm->dvc_channel_list, channel); freerdp_mutex_unlock(vcm->mutex); s = stream_new(64); wts_write_drdynvc_create_request(s, channel->channel_id, pVirtualName); WTSVirtualChannelWrite(vcm->drdynvc_channel, stream_get_head(s), stream_get_length(s), NULL); stream_free(s); DEBUG_DVC("ChannelId %d.%s (total %d)", channel->channel_id, pVirtualName, list_size(vcm->dvc_channel_list)); } else { len = strlen(pVirtualName); if (len > 8) return NULL; for (i = 0; i < client->settings->num_channels; i++) { if (client->settings->channels[i].joined && strncmp(client->settings->channels[i].name, pVirtualName, len) == 0) { break; } } if (i >= client->settings->num_channels) return NULL; channel = (rdpPeerChannel*) client->settings->channels[i].handle; if (channel == NULL) { channel = xnew(rdpPeerChannel); channel->vcm = vcm; channel->client = client; channel->channel_id = client->settings->channels[i].channel_id; channel->index = i; channel->channel_type = RDP_PEER_CHANNEL_TYPE_SVC; channel->receive_data = stream_new(client->settings->vc_chunk_size); channel->receive_event = wait_obj_new(); channel->receive_queue = list_new(); channel->mutex = freerdp_mutex_new(); client->settings->channels[i].handle = channel; } } return channel; }