/** * can be called from any thread * thread safe because no 2 threads can have the same openHandle */ static UINT32 FREERDP_CC MyVirtualChannelClose(UINT32 openHandle) { int index; rdpChannels* channels; struct channel_data* lchannel_data; DEBUG_CHANNELS("enter"); channels = freerdp_channels_find_by_open_handle(openHandle, &index); if ((channels == NULL) || (index < 0) || (index >= CHANNEL_MAX_COUNT)) { DEBUG_CHANNELS("error bad channels"); return CHANNEL_RC_BAD_CHANNEL_HANDLE; } lchannel_data = channels->channels_data + index; if (lchannel_data->flags != 2) { DEBUG_CHANNELS("error not open"); return CHANNEL_RC_NOT_OPEN; } lchannel_data->flags = 0; return CHANNEL_RC_OK; }
/** * Send a plugin-defined event to the plugin. * called only from main thread * @param channels the channel manager instance * @param event an event object created by freerdp_event_new() */ FREERDP_API int freerdp_channels_send_event(rdpChannels* chan_man, RDP_EVENT* event) { struct channel_data* lchan_data; int index; const char* name; name = event_class_to_name_table[event->event_class]; if (name == NULL) { DEBUG_CHANNELS("unknown event_class %d", event->event_class); freerdp_event_free(event); return 1; } lchan_data = freerdp_channels_find_channel_data_by_name(chan_man, name, &index); if (lchan_data == NULL) { DEBUG_CHANNELS("could not find channel name %s", name); freerdp_event_free(event); return 1; } if (lchan_data->open_event_proc != NULL) { lchan_data->open_event_proc(lchan_data->open_handle, CHANNEL_EVENT_USER, event, sizeof(RDP_EVENT), sizeof(RDP_EVENT), 0); } return 0; }
static UINT32 FREERDP_CC MyVirtualChannelEventPush(UINT32 openHandle, wMessage* event) { int index; rdpChannels* channels; rdpChannelData* lchannel_data; channels = freerdp_channels_find_by_open_handle(openHandle, &index); if ((!channels) || (index < 0) || (index >= CHANNEL_MAX_COUNT)) { DEBUG_CHANNELS("error bad channels handle"); return CHANNEL_RC_BAD_CHANNEL_HANDLE; } if (!channels->is_connected) { DEBUG_CHANNELS("error not connected"); return CHANNEL_RC_NOT_CONNECTED; } if (!event) { DEBUG_CHANNELS("error bad event"); return CHANNEL_RC_NULL_DATA; } lchannel_data = &channels->channelDataList[index]; if (lchannel_data->flags != 2) { DEBUG_CHANNELS("error not open"); return CHANNEL_RC_NOT_OPEN; } if (!channels->is_connected) { DEBUG_CHANNELS("error not connected"); return CHANNEL_RC_NOT_CONNECTED; } /** * We really intend to use the In queue for events, but we're pushing on both * to wake up threads waiting on the out queue. Doing this cleanly would require * breaking freerdp_pop_event() a bit too early in this refactoring. */ MessageQueue_Post(channels->MsgPipe->In, (void*) channels, 1, (void*) event, NULL); MessageQueue_Post(channels->MsgPipe->Out, (void*) channels, 1, (void*) event, NULL); return CHANNEL_RC_OK; }
static UINT32 FREERDP_CC MyVirtualChannelEventPush(UINT32 openHandle, RDP_EVENT* event) { int index; rdpChannels* channels; struct channel_data* lchannel_data; channels = freerdp_channels_find_by_open_handle(openHandle, &index); if ((channels == NULL) || (index < 0) || (index >= CHANNEL_MAX_COUNT)) { DEBUG_CHANNELS("error bad channels handle"); return CHANNEL_RC_BAD_CHANNEL_HANDLE; } if (!channels->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; } lchannel_data = channels->channels_data + index; if (lchannel_data->flags != 2) { DEBUG_CHANNELS("error not open"); return CHANNEL_RC_NOT_OPEN; } /* lock channels->event */ WaitForSingleObject(channels->event_sem, INFINITE); if (!channels->is_connected) { ReleaseSemaphore(channels->event_sem, 1, NULL); DEBUG_CHANNELS("error not connected"); return CHANNEL_RC_NOT_CONNECTED; } channels->event = event; /* set the event */ SetEvent(channels->signal); return CHANNEL_RC_OK; }
/** * Send a plugin-defined event to the plugin. * called only from main thread * @param channels the channel manager instance * @param event an event object created by freerdp_event_new() */ FREERDP_API int freerdp_channels_send_event(rdpChannels* channels, wMessage* event) { int index; const char* name = NULL; rdpChannelData* lchannel_data; switch (GetMessageClass(event->id)) { case DebugChannel_Class: name = "rdpdbg"; break; case CliprdrChannel_Class: name = "cliprdr"; break; case TsmfChannel_Class: name = "tsmf"; break; case RailChannel_Class: name = "rail"; break; } if (!name) { DEBUG_CHANNELS("unknown event_class %d", event->event_class); freerdp_event_free(event); return 1; } lchannel_data = freerdp_channels_find_channel_data_by_name(channels, name, &index); if (!lchannel_data) { DEBUG_CHANNELS("could not find channel name %s", name); freerdp_event_free(event); return 1; } if (lchannel_data->open_event_proc) { lchannel_data->open_event_proc(lchannel_data->open_handle, CHANNEL_EVENT_USER, event, sizeof(wMessage), sizeof(wMessage), 0); } return 0; }
/** * this is called when processing the command line parameters * called only from main thread */ int freerdp_channels_load_plugin(rdpChannels* chan_man, rdpSettings* settings, const char* name, void* data) { struct lib_data* lib; CHANNEL_ENTRY_POINTS_EX ep; int ok; DEBUG_CHANNELS("%s", name); if (chan_man->num_libs + 1 >= CHANNEL_MAX_COUNT) { DEBUG_CHANNELS("too many channels"); return 1; } lib = chan_man->libs + chan_man->num_libs; lib->entry = (PVIRTUALCHANNELENTRY)freerdp_load_plugin(name, CHANNEL_EXPORT_FUNC_NAME); if (lib->entry == NULL) { DEBUG_CHANNELS("failed to find export function"); return 1; } ep.cbSize = sizeof(ep); ep.protocolVersion = VIRTUAL_CHANNEL_VERSION_WIN2000; ep.pVirtualChannelInit = MyVirtualChannelInit; ep.pVirtualChannelOpen = MyVirtualChannelOpen; ep.pVirtualChannelClose = MyVirtualChannelClose; ep.pVirtualChannelWrite = MyVirtualChannelWrite; ep.pExtendedData = data; ep.pVirtualChannelEventPush = MyVirtualChannelEventPush; /* enable MyVirtualChannelInit */ chan_man->can_call_init = 1; chan_man->settings = settings; freerdp_mutex_lock(g_mutex_init); g_init_chan_man = chan_man; ok = lib->entry((PCHANNEL_ENTRY_POINTS)&ep); g_init_chan_man = NULL; freerdp_mutex_unlock(g_mutex_init); /* disable MyVirtualChannelInit */ chan_man->settings = 0; chan_man->can_call_init = 0; if (!ok) { DEBUG_CHANNELS("export function call failed"); return 1; } return 0; }
/** * Send a plugin-defined event to the plugin. * called only from main thread * @param channels the channel manager instance * @param event an event object created by freerdp_event_new() */ FREERDP_API int freerdp_channels_send_event(rdpChannels* channels, wMessage* event) { const char* name = NULL; CHANNEL_OPEN_DATA* pChannelOpenData; switch (GetMessageClass(event->id)) { case DebugChannel_Class: name = "rdpdbg"; break; case CliprdrChannel_Class: name = "cliprdr"; break; case TsmfChannel_Class: name = "tsmf"; break; case RailChannel_Class: name = "rail"; break; } if (!name) { DEBUG_CHANNELS("unknown event_class %d", GetMessageClass(event->id)); freerdp_event_free(event); return 1; } pChannelOpenData = freerdp_channels_find_channel_open_data_by_name(channels, name); if (!pChannelOpenData) { DEBUG_CHANNELS("could not find channel name %s", name); freerdp_event_free(event); return 1; } if (pChannelOpenData->pChannelOpenEventProc) { pChannelOpenData->pChannelOpenEventProc(pChannelOpenData->OpenHandle, CHANNEL_EVENT_USER, event, sizeof(wMessage), sizeof(wMessage), 0); } return 0; }
/** * this is called when processing the command line parameters * called only from main thread */ int freerdp_channels_load_plugin(rdpChannels* channels, rdpSettings* settings, const char* name, void* data) { void* entry; DEBUG_CHANNELS("%s", name); entry = (PVIRTUALCHANNELENTRY) freerdp_load_channel_addin_entry(name, NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC); if (entry == NULL) { DEBUG_CHANNELS("failed to find export function"); return 1; } return freerdp_channels_client_load(channels, settings, entry, data); }
/** * go through and inform all the libraries that we are connected * this will tell the libraries that its ok to call MyVirtualChannelOpen * called only from main thread */ int freerdp_channels_post_connect(rdpChannels* channels, freerdp* instance) { int index; char* hostname; int hostnameLength; CHANNEL_CLIENT_DATA* pChannelClientData; channels->is_connected = 1; hostname = instance->settings->ServerHostname; hostnameLength = strlen(hostname); DEBUG_CHANNELS("hostname [%s] channels->num_libs [%d]", hostname, channels->clientDataCount); for (index = 0; index < channels->clientDataCount; index++) { pChannelClientData = &channels->clientDataList[index]; if (pChannelClientData->pChannelInitEventProc) pChannelClientData->pChannelInitEventProc(pChannelClientData->pInitHandle, CHANNEL_EVENT_CONNECTED, hostname, hostnameLength); } channels->drdynvc = (DrdynvcClientContext*) freerdp_channels_get_static_channel_interface(channels, "drdynvc"); if (channels->drdynvc) { channels->drdynvc->custom = (void*) channels; channels->drdynvc->OnChannelConnected = freerdp_drdynvc_on_channel_connected; channels->drdynvc->OnChannelDisconnected = freerdp_drdynvc_on_channel_disconnected; } return 0; }
/** * go through and inform all the libraries that we are initialized * called only from main thread */ int freerdp_channels_pre_connect(rdpChannels* chan_man, freerdp* instance) { int index; struct lib_data* llib; CHANNEL_DEF lchannel_def; void* dummy; DEBUG_CHANNELS("enter"); chan_man->instance = instance; /** * If rdpsnd is registered but not rdpdr, it's necessary to register a fake * rdpdr channel to make sound work. This is a workaround for Window 7 and * Windows 2008 */ if (freerdp_channels_find_channel_data_by_name(chan_man, "rdpsnd", 0) != 0 && freerdp_channels_find_channel_data_by_name(chan_man, "rdpdr", 0) == 0) { lchannel_def.options = CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP; strcpy(lchannel_def.name, "rdpdr"); chan_man->can_call_init = 1; chan_man->settings = instance->settings; freerdp_mutex_lock(g_mutex_init); g_init_chan_man = chan_man; MyVirtualChannelInit(&dummy, &lchannel_def, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, 0); g_init_chan_man = NULL; freerdp_mutex_unlock(g_mutex_init); chan_man->can_call_init = 0; chan_man->settings = 0; DEBUG_CHANNELS("registered fake rdpdr for rdpsnd."); } for (index = 0; index < chan_man->num_libs; index++) { llib = chan_man->libs + index; if (llib->init_event_proc != 0) { llib->init_event_proc(llib->init_handle, CHANNEL_EVENT_INITIALIZED, 0, 0); } } return 0; }
/* can be called from any thread */ static UINT32 FREERDP_CC MyVirtualChannelWrite(UINT32 openHandle, void* pData, UINT32 dataLength, void* pUserData) { int index; SYNC_DATA* item; rdpChannels* channels; struct channel_data* lchannel_data; channels = freerdp_channels_find_by_open_handle(openHandle, &index); if ((channels == NULL) || (index < 0) || (index >= CHANNEL_MAX_COUNT)) { DEBUG_CHANNELS("error bad channel handle"); return CHANNEL_RC_BAD_CHANNEL_HANDLE; } if (!channels->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; } lchannel_data = channels->channels_data + index; if (lchannel_data->flags != 2) { DEBUG_CHANNELS("error not open"); return CHANNEL_RC_NOT_OPEN; } if (!channels->is_connected) { DEBUG_CHANNELS("error not connected"); return CHANNEL_RC_NOT_CONNECTED; } item = (SYNC_DATA*) _aligned_malloc(sizeof(SYNC_DATA), MEMORY_ALLOCATION_ALIGNMENT); item->Data = pData; item->DataLength = dataLength; item->UserData = pUserData; item->Index = index; InterlockedPushEntrySList(channels->pSyncDataList, &(item->ItemEntry)); /* set the event */ SetEvent(channels->signal); return CHANNEL_RC_OK; }
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; }
/** * data coming from the server to the client * called only from main thread */ int freerdp_channels_data(freerdp* instance, int channel_id, void* data, int data_size, int flags, int total_size) { int index; rdpChannel* channel; rdpChannels* channels; CHANNEL_OPEN_DATA* pChannelOpenData; channels = freerdp_channels_find_by_instance(instance); if (!channels) { DEBUG_CHANNELS("could not find channel manager"); return 1; } channel = freerdp_channels_find_channel_by_id(channels, instance->settings, channel_id, &index); if (!channel) { DEBUG_CHANNELS("could not find channel id"); return 1; } pChannelOpenData = freerdp_channels_find_channel_open_data_by_name(channels, channel->Name); if (!pChannelOpenData) { DEBUG_CHANNELS("could not find channel name"); return 1; } if (pChannelOpenData->pChannelOpenEventProc) { pChannelOpenData->pChannelOpenEventProc(pChannelOpenData->OpenHandle, CHANNEL_EVENT_DATA_RECEIVED, data, data_size, total_size, flags); } return 0; }
/** * data comming from the server to the client * called only from main thread */ int freerdp_channels_data(freerdp* instance, int channel_id, void* data, int data_size, int flags, int total_size) { int index; rdpChannels* channels; rdpChannel* lrdp_channel; struct channel_data* lchannel_data; channels = freerdp_channels_find_by_instance(instance); if (channels == 0) { DEBUG_CHANNELS("could not find channel manager"); return 1; } lrdp_channel = freerdp_channels_find_channel_by_id(channels, instance->settings, channel_id, &index); if (lrdp_channel == 0) { DEBUG_CHANNELS("could not find channel id"); return 1; } lchannel_data = freerdp_channels_find_channel_data_by_name(channels, lrdp_channel->Name, &index); if (lchannel_data == 0) { DEBUG_CHANNELS("could not find channel name"); return 1; } if (lchannel_data->open_event_proc != 0) { lchannel_data->open_event_proc(lchannel_data->open_handle, CHANNEL_EVENT_DATA_RECEIVED, data, data_size, total_size, flags); } return 0; }
/* can be called from any thread */ static UINT32 FREERDP_CC MyVirtualChannelWrite(UINT32 openHandle, void* pData, UINT32 dataLength, void* pUserData) { int index; CHANNEL_OPEN_EVENT* item; rdpChannels* channels; rdpChannelData* lchannel_data; channels = freerdp_channels_find_by_open_handle(openHandle, &index); if ((!channels) || (index < 0) || (index >= CHANNEL_MAX_COUNT)) { DEBUG_CHANNELS("error bad channel handle"); return CHANNEL_RC_BAD_CHANNEL_HANDLE; } if (!channels->is_connected) { DEBUG_CHANNELS("error not connected"); return CHANNEL_RC_NOT_CONNECTED; } if (!pData) { DEBUG_CHANNELS("error bad pData"); return CHANNEL_RC_NULL_DATA; } if (!dataLength) { DEBUG_CHANNELS("error bad dataLength"); return CHANNEL_RC_ZERO_LENGTH; } lchannel_data = &channels->channelDataList[index]; if (lchannel_data->flags != 2) { DEBUG_CHANNELS("error not open"); return CHANNEL_RC_NOT_OPEN; } if (!channels->is_connected) { DEBUG_CHANNELS("error not connected"); return CHANNEL_RC_NOT_CONNECTED; } item = (CHANNEL_OPEN_EVENT*) malloc(sizeof(CHANNEL_OPEN_EVENT)); item->Data = pData; item->DataLength = dataLength; item->UserData = pUserData; item->Index = index; MessageQueue_Post(channels->MsgPipe->Out, (void*) channels, 0, (void*) item, NULL); return CHANNEL_RC_OK; }
/* 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; }
void freerdp_channels_close(rdpChannels* channels, freerdp* instance) { int index; CHANNEL_CLIENT_DATA* pChannelClientData; DEBUG_CHANNELS("closing"); channels->is_connected = 0; freerdp_channels_check_fds(channels, instance); /* tell all libraries we are shutting down */ for (index = 0; index < channels->clientDataCount; index++) { pChannelClientData = &channels->clientDataList[index]; if (pChannelClientData->pChannelInitEventProc) pChannelClientData->pChannelInitEventProc(pChannelClientData->pInitHandle, CHANNEL_EVENT_TERMINATED, 0, 0); } }
/** * go through and inform all the libraries that we are initialized * called only from main thread */ int freerdp_channels_pre_connect(rdpChannels* channels, freerdp* instance) { int index; rdpLibraryData* llib; DEBUG_CHANNELS("enter"); channels->instance = instance; for (index = 0; index < channels->libraryDataCount; index++) { llib = &channels->libraryDataList[index]; if (llib->init_event_proc != 0) llib->init_event_proc(llib->init_handle, CHANNEL_EVENT_INITIALIZED, 0, 0); } return 0; }
/** * go through and inform all the libraries that we are initialized * called only from main thread */ int freerdp_channels_pre_connect(rdpChannels* channels, freerdp* instance) { int index; CHANNEL_CLIENT_DATA* pChannelClientData; DEBUG_CHANNELS("enter"); channels->instance = instance; for (index = 0; index < channels->clientDataCount; index++) { pChannelClientData = &channels->clientDataList[index]; if (pChannelClientData->pChannelInitEventProc) pChannelClientData->pChannelInitEventProc(pChannelClientData->pInitHandle, CHANNEL_EVENT_INITIALIZED, 0, 0); } return 0; }
void freerdp_channels_close(rdpChannels* channels, freerdp* instance) { int index; struct lib_data* llib; DEBUG_CHANNELS("closing"); channels->is_connected = 0; freerdp_channels_check_fds(channels, instance); /* tell all libraries we are shutting down */ for (index = 0; index < channels->num_libs_data; index++) { llib = channels->libs_data + index; if (llib->init_event_proc != 0) llib->init_event_proc(llib->init_handle, CHANNEL_EVENT_TERMINATED, 0, 0); } }
/** * can be called from any thread * thread safe because no 2 threads can have the same channel name registered */ static UINT32 FREERDP_CC MyVirtualChannelOpen(void* pInitHandle, UINT32* pOpenHandle, char* pChannelName, PCHANNEL_OPEN_EVENT_FN pChannelOpenEventProc) { int index; rdpChannels* channels; struct channel_data* lchannel_data; DEBUG_CHANNELS("enter"); channels = ((rdpInitHandle*) pInitHandle)->channels; if (pOpenHandle == 0) { DEBUG_CHANNELS("error bad channel handle"); return CHANNEL_RC_BAD_CHANNEL_HANDLE; } if (pChannelOpenEventProc == 0) { DEBUG_CHANNELS("error bad proc"); return CHANNEL_RC_BAD_PROC; } if (!channels->is_connected) { DEBUG_CHANNELS("error not connected"); return CHANNEL_RC_NOT_CONNECTED; } lchannel_data = freerdp_channels_find_channel_data_by_name(channels, pChannelName, &index); if (lchannel_data == 0) { DEBUG_CHANNELS("error channel name"); return CHANNEL_RC_UNKNOWN_CHANNEL_NAME; } if (lchannel_data->flags == 2) { DEBUG_CHANNELS("error channel already open"); return CHANNEL_RC_ALREADY_OPEN; } lchannel_data->flags = 2; /* open */ lchannel_data->open_event_proc = pChannelOpenEventProc; *pOpenHandle = lchannel_data->open_handle; return CHANNEL_RC_OK; }
void freerdp_channels_close(rdpChannels* channels, freerdp* instance) { int index; char* name; CHANNEL_OPEN_DATA* pChannelOpenData; CHANNEL_CLIENT_DATA* pChannelClientData; DEBUG_CHANNELS("closing"); channels->is_connected = 0; freerdp_channels_check_fds(channels, instance); /* tell all libraries we are shutting down */ for (index = 0; index < channels->clientDataCount; index++) { ChannelDisconnectedEventArgs e; pChannelClientData = &channels->clientDataList[index]; if (pChannelClientData->pChannelInitEventProc) pChannelClientData->pChannelInitEventProc(pChannelClientData->pInitHandle, CHANNEL_EVENT_TERMINATED, 0, 0); pChannelOpenData = &channels->openDataList[index]; name = (char*) malloc(9); CopyMemory(name, pChannelOpenData->name, 8); name[8] = '\0'; EventArgsInit(&e, "freerdp"); e.name = name; e.pInterface = pChannelOpenData->pInterface; PubSub_OnChannelDisconnected(instance->context->pubSub, instance->context, &e); free(name); } /* Emit a quit signal to the internal message pipe. */ MessagePipe_PostQuit(channels->MsgPipe, 0); }
/** * go through and inform all the libraries that we are connected * this will tell the libraries that its ok to call MyVirtualChannelOpen * called only from main thread */ int freerdp_channels_post_connect(rdpChannels* chan_man, freerdp* instance) { int index; struct lib_data* llib; char* hostname; int hostname_len; chan_man->is_connected = 1; hostname = instance->settings->hostname; hostname_len = strlen(hostname); DEBUG_CHANNELS("hostname [%s] channels->num_libs [%d]", hostname, channels->num_libs); for (index = 0; index < chan_man->num_libs; index++) { llib = chan_man->libs + index; if (llib->init_event_proc != 0) { llib->init_event_proc(llib->init_handle, CHANNEL_EVENT_CONNECTED, hostname, hostname_len); } } return 0; }
/** * go through and inform all the libraries that we are connected * this will tell the libraries that its ok to call MyVirtualChannelOpen * called only from main thread */ int freerdp_channels_post_connect(rdpChannels* channels, freerdp* instance) { int index; char* hostname; int hostname_len; rdpLibraryData* llib; channels->is_connected = 1; hostname = instance->settings->ServerHostname; hostname_len = strlen(hostname); DEBUG_CHANNELS("hostname [%s] channels->num_libs [%d]", hostname, channels->libraryDataCount); for (index = 0; index < channels->libraryDataCount; index++) { llib = &channels->libraryDataList[index]; if (llib->init_event_proc != 0) llib->init_event_proc(llib->init_handle, CHANNEL_EVENT_CONNECTED, hostname, hostname_len); } return 0; }
/** * 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) { int index; rdpChannel* channel; rdpChannels* channels; rdpLibraryData* llib; PCHANNEL_DEF lchannel_def; rdpChannelData* lchannel_data; if (!ppInitHandle) { DEBUG_CHANNELS("error bad init handle"); return CHANNEL_RC_BAD_INIT_HANDLE; } channels = g_init_channels; channels->initHandleList[channels->initHandleCount].channels = channels; *ppInitHandle = &channels->initHandleList[channels->initHandleCount]; channels->initHandleCount++; DEBUG_CHANNELS("enter"); if (!channels->can_call_init) { DEBUG_CHANNELS("error not in entry"); return CHANNEL_RC_NOT_IN_VIRTUALCHANNELENTRY; } if (channels->channelDataCount + channelCount >= CHANNEL_MAX_COUNT) { DEBUG_CHANNELS("error too many channels"); return CHANNEL_RC_TOO_MANY_CHANNELS; } if (!pChannel) { DEBUG_CHANNELS("error bad channel"); return CHANNEL_RC_BAD_CHANNEL; } if (channels->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++) { lchannel_def = &pChannel[index]; if (freerdp_channels_find_channel_data_by_name(channels, lchannel_def->name, 0) != 0) { DEBUG_CHANNELS("error channel already used"); return CHANNEL_RC_BAD_CHANNEL; } } llib = &channels->libraryDataList[channels->libraryDataCount]; llib->init_event_proc = pChannelInitEventProc; llib->init_handle = *ppInitHandle; channels->libraryDataCount++; for (index = 0; index < channelCount; index++) { lchannel_def = &pChannel[index]; lchannel_data = &channels->channelDataList[channels->channelDataCount]; lchannel_data->open_handle = g_open_handle_sequence++; lchannel_data->flags = 1; /* init */ strncpy(lchannel_data->name, lchannel_def->name, CHANNEL_NAME_LEN); lchannel_data->options = lchannel_def->options; if (channels->settings->ChannelCount < 16) { channel = channels->settings->ChannelDefArray + channels->settings->ChannelCount; strncpy(channel->Name, lchannel_def->name, 7); channel->options = lchannel_def->options; channels->settings->ChannelCount++; } else { DEBUG_CHANNELS("warning more than 16 channels"); } channels->channelDataCount++; } return CHANNEL_RC_OK; }
/** * 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; }
/** * 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) { int index; rdpChannels* channels; struct lib_data* llib; rdpChannel* lrdp_channel; PCHANNEL_DEF lchannel_def; struct channel_data* lchannel_data; if (ppInitHandle == NULL) { DEBUG_CHANNELS("error bad init handle"); return CHANNEL_RC_BAD_INIT_HANDLE; } channels = g_init_channels; channels->init_handles[channels->num_init_handles].channels = channels; *ppInitHandle = &channels->init_handles[channels->num_init_handles]; channels->num_init_handles++; DEBUG_CHANNELS("enter"); if (!channels->can_call_init) { DEBUG_CHANNELS("error not in entry"); return CHANNEL_RC_NOT_IN_VIRTUALCHANNELENTRY; } if (channels->num_channels_data + channelCount >= CHANNEL_MAX_COUNT) { DEBUG_CHANNELS("error too many channels"); return CHANNEL_RC_TOO_MANY_CHANNELS; } if (pChannel == 0) { DEBUG_CHANNELS("error bad channel"); return CHANNEL_RC_BAD_CHANNEL; } if (channels->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++) { lchannel_def = pChannel + index; if (freerdp_channels_find_channel_data_by_name(channels, lchannel_def->name, 0) != 0) { DEBUG_CHANNELS("error channel already used"); return CHANNEL_RC_BAD_CHANNEL; } } llib = channels->libs_data + channels->num_libs_data; llib->init_event_proc = pChannelInitEventProc; llib->init_handle = *ppInitHandle; channels->num_libs_data++; for (index = 0; index < channelCount; index++) { lchannel_def = pChannel + index; lchannel_data = channels->channels_data + channels->num_channels_data; WaitForSingleObject(g_mutex_list, INFINITE); lchannel_data->open_handle = g_open_handle_sequence++; ReleaseMutex(g_mutex_list); lchannel_data->flags = 1; /* init */ strncpy(lchannel_data->name, lchannel_def->name, CHANNEL_NAME_LEN); lchannel_data->options = lchannel_def->options; if (channels->settings->ChannelCount < 16) { lrdp_channel = channels->settings->ChannelDefArray + channels->settings->ChannelCount; strncpy(lrdp_channel->Name, lchannel_def->name, 7); lrdp_channel->options = lchannel_def->options; channels->settings->ChannelCount++; } else { DEBUG_CHANNELS("warning more than 16 channels"); } channels->num_channels_data++; } return CHANNEL_RC_OK; }