diff --git a/channels/drdynvc/client/dvcman.c b/channels/drdynvc/client/dvcman.c index da170160d..1c25a887b 100644 --- a/channels/drdynvc/client/dvcman.c +++ b/channels/drdynvc/client/dvcman.c @@ -21,6 +21,8 @@ #include "config.h" #endif +#include + #include #include #include @@ -28,45 +30,45 @@ #include #include #include +#include #include #include "drdynvc_types.h" #include "dvcman.h" +static wListDictionary *cb_dict = NULL; +struct cb_value +{ + void *fkt; + void *context; +}; -static int dvcman_get_configuration(IWTSListener* pListener, void** ppPropertyBag) +static int dvcman_get_configuration(IWTSListener *pListener, void **ppPropertyBag) { *ppPropertyBag = NULL; return 1; } -static int dvcman_create_listener(IWTSVirtualChannelManager* pChannelMgr, - const char* pszChannelName, UINT32 ulFlags, - IWTSListenerCallback* pListenerCallback, IWTSListener** ppListener) +static int dvcman_create_listener(IWTSVirtualChannelManager *pChannelMgr, + const char *pszChannelName, UINT32 ulFlags, + IWTSListenerCallback *pListenerCallback, IWTSListener **ppListener) { - DVCMAN* dvcman = (DVCMAN*) pChannelMgr; - DVCMAN_LISTENER* listener; - - if (dvcman->num_listeners < MAX_PLUGINS) + DVCMAN *dvcman = (DVCMAN *) pChannelMgr; + DVCMAN_LISTENER *listener; + if(dvcman->num_listeners < MAX_PLUGINS) { DEBUG_DVC("%d.%s.", dvcman->num_listeners, pszChannelName); - - listener = (DVCMAN_LISTENER*) malloc(sizeof(DVCMAN_LISTENER)); + listener = (DVCMAN_LISTENER *) malloc(sizeof(DVCMAN_LISTENER)); ZeroMemory(listener, sizeof(DVCMAN_LISTENER)); - listener->iface.GetConfiguration = dvcman_get_configuration; listener->iface.pInterface = NULL; - listener->dvcman = dvcman; listener->channel_name = _strdup(pszChannelName); listener->flags = ulFlags; listener->listener_callback = pListenerCallback; - - if (ppListener) - *ppListener = (IWTSListener*) listener; - - dvcman->listeners[dvcman->num_listeners++] = (IWTSListener*) listener; - + if(ppListener) + *ppListener = (IWTSListener *) listener; + dvcman->listeners[dvcman->num_listeners++] = (IWTSListener *) listener; return 0; } else @@ -76,14 +78,12 @@ static int dvcman_create_listener(IWTSVirtualChannelManager* pChannelMgr, } } -static int dvcman_push_event(IWTSVirtualChannelManager* pChannelMgr, wMessage* pEvent) +static int dvcman_push_event(IWTSVirtualChannelManager *pChannelMgr, wMessage *pEvent) { int status; - DVCMAN* dvcman = (DVCMAN*) pChannelMgr; - + DVCMAN *dvcman = (DVCMAN *) pChannelMgr; status = drdynvc_push_event(dvcman->drdynvc, pEvent); - - if (status == 0) + if(status == 0) { DEBUG_DVC("event_type %d pushed.", GetMessageType(pEvent->id)); } @@ -91,15 +91,13 @@ static int dvcman_push_event(IWTSVirtualChannelManager* pChannelMgr, wMessage* p { DEBUG_WARN("event_type %d push failed.", GetMessageType(pEvent->id)); } - return status; } -static int dvcman_register_plugin(IDRDYNVC_ENTRY_POINTS* pEntryPoints, const char* name, IWTSPlugin* pPlugin) +static int dvcman_register_plugin(IDRDYNVC_ENTRY_POINTS *pEntryPoints, const char *name, IWTSPlugin *pPlugin) { - DVCMAN* dvcman = ((DVCMAN_ENTRY_POINTS*) pEntryPoints)->dvcman; - - if (dvcman->num_plugins < MAX_PLUGINS) + DVCMAN *dvcman = ((DVCMAN_ENTRY_POINTS *) pEntryPoints)->dvcman; + if(dvcman->num_plugins < MAX_PLUGINS) { DEBUG_DVC("num_plugins %d", dvcman->num_plugins); dvcman->plugin_names[dvcman->num_plugins] = name; @@ -113,365 +111,299 @@ static int dvcman_register_plugin(IDRDYNVC_ENTRY_POINTS* pEntryPoints, const cha } } -IWTSPlugin* dvcman_get_plugin(IDRDYNVC_ENTRY_POINTS* pEntryPoints, const char* name) +IWTSPlugin *dvcman_get_plugin(IDRDYNVC_ENTRY_POINTS *pEntryPoints, const char *name) { int i; - DVCMAN* dvcman = ((DVCMAN_ENTRY_POINTS*) pEntryPoints)->dvcman; - - for (i = 0; i < dvcman->num_plugins; i++) + DVCMAN *dvcman = ((DVCMAN_ENTRY_POINTS *) pEntryPoints)->dvcman; + for(i = 0; i < dvcman->num_plugins; i++) { - if (dvcman->plugin_names[i] == name || - strcmp(dvcman->plugin_names[i], name) == 0) + if(dvcman->plugin_names[i] == name || + strcmp(dvcman->plugin_names[i], name) == 0) { return dvcman->plugins[i]; } } - return NULL; } -ADDIN_ARGV* dvcman_get_plugin_data(IDRDYNVC_ENTRY_POINTS* pEntryPoints) +ADDIN_ARGV *dvcman_get_plugin_data(IDRDYNVC_ENTRY_POINTS *pEntryPoints) { - return ((DVCMAN_ENTRY_POINTS*) pEntryPoints)->args; + return ((DVCMAN_ENTRY_POINTS *) pEntryPoints)->args; } -UINT32 dvcman_get_channel_id(IWTSVirtualChannel * channel) +UINT32 dvcman_get_channel_id(IWTSVirtualChannel *channel) { - return ((DVCMAN_CHANNEL*) channel)->channel_id; + return ((DVCMAN_CHANNEL *) channel)->channel_id; } -IWTSVirtualChannel* dvcman_find_channel_by_id(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId) +IWTSVirtualChannel *dvcman_find_channel_by_id(IWTSVirtualChannelManager *pChannelMgr, UINT32 ChannelId) { int index; BOOL found = FALSE; - DVCMAN_CHANNEL* channel; - DVCMAN* dvcman = (DVCMAN*) pChannelMgr; - + DVCMAN_CHANNEL *channel; + DVCMAN *dvcman = (DVCMAN *) pChannelMgr; ArrayList_Lock(dvcman->channels); - index = 0; - channel = (DVCMAN_CHANNEL*) ArrayList_GetItem(dvcman->channels, index++); - - while (channel) + channel = (DVCMAN_CHANNEL *) ArrayList_GetItem(dvcman->channels, index++); + while(channel) { - if (channel->channel_id == ChannelId) + if(channel->channel_id == ChannelId) { found = TRUE; break; } - - channel = (DVCMAN_CHANNEL*) ArrayList_GetItem(dvcman->channels, index++); + channel = (DVCMAN_CHANNEL *) ArrayList_GetItem(dvcman->channels, index++); } - ArrayList_Unlock(dvcman->channels); - - return (found) ? ((IWTSVirtualChannel*) channel) : NULL; + return (found) ? ((IWTSVirtualChannel *) channel) : NULL; } -void* dvcman_get_channel_interface_by_name(IWTSVirtualChannelManager* pChannelMgr, const char* ChannelName) +void *dvcman_get_channel_interface_by_name(IWTSVirtualChannelManager *pChannelMgr, const char *ChannelName) { int i; BOOL found = FALSE; - void* pInterface = NULL; - DVCMAN_LISTENER* listener; - DVCMAN* dvcman = (DVCMAN*) pChannelMgr; - - for (i = 0; i < dvcman->num_listeners; i++) + void *pInterface = NULL; + DVCMAN_LISTENER *listener; + DVCMAN *dvcman = (DVCMAN *) pChannelMgr; + for(i = 0; i < dvcman->num_listeners; i++) { - listener = (DVCMAN_LISTENER*) dvcman->listeners[i]; - - if (strcmp(listener->channel_name, ChannelName) == 0) + listener = (DVCMAN_LISTENER *) dvcman->listeners[i]; + if(strcmp(listener->channel_name, ChannelName) == 0) { pInterface = listener->iface.pInterface; found = TRUE; break; } } - return (found) ? pInterface : NULL; } -IWTSVirtualChannelManager* dvcman_new(drdynvcPlugin* plugin) +IWTSVirtualChannelManager *dvcman_new(drdynvcPlugin *plugin) { - DVCMAN* dvcman; - - dvcman = (DVCMAN*) malloc(sizeof(DVCMAN)); + DVCMAN *dvcman; + dvcman = (DVCMAN *) malloc(sizeof(DVCMAN)); ZeroMemory(dvcman, sizeof(DVCMAN)); - dvcman->iface.CreateListener = dvcman_create_listener; dvcman->iface.PushEvent = dvcman_push_event; dvcman->iface.FindChannelById = dvcman_find_channel_by_id; dvcman->iface.GetChannelId = dvcman_get_channel_id; dvcman->drdynvc = plugin; dvcman->channels = ArrayList_New(TRUE); - - return (IWTSVirtualChannelManager*) dvcman; + return (IWTSVirtualChannelManager *) dvcman; } -int dvcman_load_addin(IWTSVirtualChannelManager* pChannelMgr, ADDIN_ARGV* args) +int dvcman_load_addin(IWTSVirtualChannelManager *pChannelMgr, ADDIN_ARGV *args) { DVCMAN_ENTRY_POINTS entryPoints; PDVC_PLUGIN_ENTRY pDVCPluginEntry = NULL; - fprintf(stderr, "Loading Dynamic Virtual Channel %s\n", args->argv[0]); - pDVCPluginEntry = (PDVC_PLUGIN_ENTRY) freerdp_load_channel_addin_entry(args->argv[0], - NULL, NULL, FREERDP_ADDIN_CHANNEL_DYNAMIC); - - if (pDVCPluginEntry) + NULL, NULL, FREERDP_ADDIN_CHANNEL_DYNAMIC); + if(pDVCPluginEntry) { entryPoints.iface.RegisterPlugin = dvcman_register_plugin; entryPoints.iface.GetPlugin = dvcman_get_plugin; entryPoints.iface.GetPluginData = dvcman_get_plugin_data; - entryPoints.dvcman = (DVCMAN*) pChannelMgr; + entryPoints.dvcman = (DVCMAN *) pChannelMgr; entryPoints.args = args; - - pDVCPluginEntry((IDRDYNVC_ENTRY_POINTS*) &entryPoints); + pDVCPluginEntry((IDRDYNVC_ENTRY_POINTS *) &entryPoints); } - return 0; } -static void dvcman_channel_free(DVCMAN_CHANNEL* channel) +static void dvcman_channel_free(DVCMAN_CHANNEL *channel) { - if (channel->channel_callback) + assert(channel); + if(channel->channel_callback) channel->channel_callback->OnClose(channel->channel_callback); - + if(channel->channel_name) + free(channel->channel_name); free(channel); } -void dvcman_free(IWTSVirtualChannelManager* pChannelMgr) +void dvcman_free(IWTSVirtualChannelManager *pChannelMgr) { int i; int count; - IWTSPlugin* pPlugin; - DVCMAN_LISTENER* listener; - DVCMAN_CHANNEL* channel; - DVCMAN* dvcman = (DVCMAN*) pChannelMgr; - + IWTSPlugin *pPlugin; + DVCMAN_LISTENER *listener; + DVCMAN_CHANNEL *channel; + DVCMAN *dvcman = (DVCMAN *) pChannelMgr; ArrayList_Lock(dvcman->channels); - count = ArrayList_Count(dvcman->channels); - - for (i = 0; i < count; i++) + for(i = 0; i < count; i++) { - channel = (DVCMAN_CHANNEL*) ArrayList_GetItem(dvcman->channels, i); + channel = (DVCMAN_CHANNEL *) ArrayList_GetItem(dvcman->channels, i); dvcman_channel_free(channel); } - ArrayList_Unlock(dvcman->channels); - ArrayList_Free(dvcman->channels); - - for (i = 0; i < dvcman->num_listeners; i++) + for(i = 0; i < dvcman->num_listeners; i++) { - listener = (DVCMAN_LISTENER*) dvcman->listeners[i]; + listener = (DVCMAN_LISTENER *) dvcman->listeners[i]; free(listener->channel_name); free(listener); } - - for (i = 0; i < dvcman->num_plugins; i++) + for(i = 0; i < dvcman->num_plugins; i++) { pPlugin = dvcman->plugins[i]; - - if (pPlugin->Terminated) + if(pPlugin->Terminated) pPlugin->Terminated(pPlugin); } - free(dvcman); } -int dvcman_init(IWTSVirtualChannelManager* pChannelMgr) +int dvcman_init(IWTSVirtualChannelManager *pChannelMgr) { int i; - IWTSPlugin* pPlugin; - DVCMAN* dvcman = (DVCMAN*) pChannelMgr; - - for (i = 0; i < dvcman->num_plugins; i++) + IWTSPlugin *pPlugin; + DVCMAN *dvcman = (DVCMAN *) pChannelMgr; + for(i = 0; i < dvcman->num_plugins; i++) { pPlugin = dvcman->plugins[i]; - - if (pPlugin->Initialize) + if(pPlugin->Initialize) pPlugin->Initialize(pPlugin, pChannelMgr); } - return 0; } -static int dvcman_write_channel(IWTSVirtualChannel* pChannel, UINT32 cbSize, BYTE* pBuffer, void* pReserved) +static int dvcman_write_channel(IWTSVirtualChannel *pChannel, UINT32 cbSize, BYTE *pBuffer, void *pReserved) { int status; - DVCMAN_CHANNEL* channel = (DVCMAN_CHANNEL*) pChannel; - + DVCMAN_CHANNEL *channel = (DVCMAN_CHANNEL *) pChannel; WaitForSingleObject(channel->dvc_chan_mutex, INFINITE); status = drdynvc_write_data(channel->dvcman->drdynvc, channel->channel_id, pBuffer, cbSize); ReleaseMutex(channel->dvc_chan_mutex); - return status; } -static int dvcman_close_channel_iface(IWTSVirtualChannel* pChannel) +static int dvcman_close_channel_iface(IWTSVirtualChannel *pChannel) { - DVCMAN_CHANNEL* channel = (DVCMAN_CHANNEL*) pChannel; - DVCMAN* dvcman = channel->dvcman; - + DVCMAN_CHANNEL *channel = (DVCMAN_CHANNEL *) pChannel; + DVCMAN *dvcman = channel->dvcman; DEBUG_DVC("id=%d", channel->channel_id); - ArrayList_Remove(dvcman->channels, channel); - dvcman_channel_free(channel); - return 1; } -int dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId, const char* ChannelName) +int dvcman_create_channel(IWTSVirtualChannelManager *pChannelMgr, UINT32 ChannelId, const char *ChannelName) { int i; int bAccept; - DVCMAN_LISTENER* listener; - DVCMAN_CHANNEL* channel; - DrdynvcClientContext* context; - IWTSVirtualChannelCallback* pCallback; - DVCMAN* dvcman = (DVCMAN*) pChannelMgr; - - channel = (DVCMAN_CHANNEL*) malloc(sizeof(DVCMAN_CHANNEL)); + DVCMAN_LISTENER *listener; + DVCMAN_CHANNEL *channel; + DrdynvcClientContext *context; + IWTSVirtualChannelCallback *pCallback; + DVCMAN *dvcman = (DVCMAN *) pChannelMgr; + channel = (DVCMAN_CHANNEL *) malloc(sizeof(DVCMAN_CHANNEL)); ZeroMemory(channel, sizeof(DVCMAN_CHANNEL)); - channel->dvcman = dvcman; channel->channel_id = ChannelId; channel->channel_name = _strdup(ChannelName); - - for (i = 0; i < dvcman->num_listeners; i++) + for(i = 0; i < dvcman->num_listeners; i++) { - listener = (DVCMAN_LISTENER*) dvcman->listeners[i]; - - if (strcmp(listener->channel_name, ChannelName) == 0) + listener = (DVCMAN_LISTENER *) dvcman->listeners[i]; + if(strcmp(listener->channel_name, ChannelName) == 0) { channel->iface.Write = dvcman_write_channel; channel->iface.Close = dvcman_close_channel_iface; channel->dvc_chan_mutex = CreateMutex(NULL, FALSE, NULL); - bAccept = 1; pCallback = NULL; - - if (listener->listener_callback->OnNewChannelConnection(listener->listener_callback, - (IWTSVirtualChannel*) channel, NULL, &bAccept, &pCallback) == 0 && bAccept == 1) + if(listener->listener_callback->OnNewChannelConnection(listener->listener_callback, + (IWTSVirtualChannel *) channel, NULL, &bAccept, &pCallback) == 0 && bAccept == 1) { DEBUG_DVC("listener %s created new channel %d", - listener->channel_name, channel->channel_id); - + listener->channel_name, channel->channel_id); channel->status = 0; channel->channel_callback = pCallback; channel->pInterface = listener->iface.pInterface; - ArrayList_Add(dvcman->channels, channel); - context = dvcman->drdynvc->context; IFCALL(context->OnChannelConnected, context, ChannelName, listener->iface.pInterface); - return 0; } else { DEBUG_WARN("channel rejected by plugin"); - free(channel); return 1; } } } - free(channel); return 1; } -int dvcman_close_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId) +int dvcman_close_channel(IWTSVirtualChannelManager *pChannelMgr, UINT32 ChannelId) { - DVCMAN_CHANNEL* channel; - IWTSVirtualChannel* ichannel; - DrdynvcClientContext* context; - DVCMAN* dvcman = (DVCMAN*) pChannelMgr; - - channel = (DVCMAN_CHANNEL*) dvcman_find_channel_by_id(pChannelMgr, ChannelId); - - if (!channel) + DVCMAN_CHANNEL *channel; + IWTSVirtualChannel *ichannel; + DrdynvcClientContext *context; + DVCMAN *dvcman = (DVCMAN *) pChannelMgr; + channel = (DVCMAN_CHANNEL *) dvcman_find_channel_by_id(pChannelMgr, ChannelId); + if(!channel) { DEBUG_WARN("ChannelId %d not found!", ChannelId); return 1; } - - if (channel->dvc_data) + if(channel->dvc_data) { Stream_Free(channel->dvc_data, TRUE); channel->dvc_data = NULL; } - - if (channel->status == 0) + if(channel->status == 0) { context = dvcman->drdynvc->context; - IFCALL(context->OnChannelDisconnected, context, channel->channel_name, channel->pInterface); - - free(channel->channel_name); - DEBUG_DVC("dvcman_close_channel: channel %d closed", ChannelId); - ichannel = (IWTSVirtualChannel*) channel; + ichannel = (IWTSVirtualChannel *) channel; ichannel->Close(ichannel); } - return 0; } -int dvcman_receive_channel_data_first(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId, UINT32 length) +int dvcman_receive_channel_data_first(IWTSVirtualChannelManager *pChannelMgr, UINT32 ChannelId, UINT32 length) { - DVCMAN_CHANNEL* channel; - - channel = (DVCMAN_CHANNEL*) dvcman_find_channel_by_id(pChannelMgr, ChannelId); - - if (!channel) + DVCMAN_CHANNEL *channel; + channel = (DVCMAN_CHANNEL *) dvcman_find_channel_by_id(pChannelMgr, ChannelId); + if(!channel) { DEBUG_WARN("ChannelId %d not found!", ChannelId); return 1; } - - if (channel->dvc_data) + if(channel->dvc_data) Stream_Free(channel->dvc_data, TRUE); - channel->dvc_data = Stream_New(NULL, length); - return 0; } -int dvcman_receive_channel_data(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId, BYTE* data, UINT32 data_size) +int dvcman_receive_channel_data(IWTSVirtualChannelManager *pChannelMgr, UINT32 ChannelId, BYTE *data, UINT32 data_size) { int error = 0; - DVCMAN_CHANNEL* channel; - - channel = (DVCMAN_CHANNEL*) dvcman_find_channel_by_id(pChannelMgr, ChannelId); - - if (!channel) + DVCMAN_CHANNEL *channel; + channel = (DVCMAN_CHANNEL *) dvcman_find_channel_by_id(pChannelMgr, ChannelId); + if(!channel) { DEBUG_WARN("ChannelId %d not found!", ChannelId); return 1; } - - if (channel->dvc_data) + if(channel->dvc_data) { /* Fragmented data */ - if (Stream_GetPosition(channel->dvc_data) + data_size > (UINT32) Stream_Capacity(channel->dvc_data)) + if(Stream_GetPosition(channel->dvc_data) + data_size > (UINT32) Stream_Capacity(channel->dvc_data)) { DEBUG_WARN("data exceeding declared length!"); Stream_Free(channel->dvc_data, TRUE); channel->dvc_data = NULL; return 1; } - Stream_Write(channel->dvc_data, data, data_size); - - if (((size_t) Stream_GetPosition(channel->dvc_data)) >= Stream_Capacity(channel->dvc_data)) + if(((size_t) Stream_GetPosition(channel->dvc_data)) >= Stream_Capacity(channel->dvc_data)) { error = channel->channel_callback->OnDataReceived(channel->channel_callback, - Stream_Capacity(channel->dvc_data), Stream_Buffer(channel->dvc_data)); + Stream_Capacity(channel->dvc_data), Stream_Buffer(channel->dvc_data)); Stream_Free(channel->dvc_data, TRUE); channel->dvc_data = NULL; } @@ -480,6 +412,89 @@ int dvcman_receive_channel_data(IWTSVirtualChannelManager* pChannelMgr, UINT32 C { error = channel->channel_callback->OnDataReceived(channel->channel_callback, data_size, data); } - return error; } + +static void dump_callbacks(void) +{ + wListDictionaryItem *cur; + DEBUG_DVC("Dumping all currently registered callbacks"); + if(!cb_dict) + { + DEBUG_DVC("cb_dict=NULL"); + return; + } + cur = cb_dict->head; + while(cur) + { + DEBUG_DVC("cb_dict %s:%p", cur->key, cur->value); + cur = cur->next; + } +} + +void *get_callback_by_name(const char *name, void **context) +{ + struct cb_value *rc; + if(!cb_dict) + { + DEBUG_WARN("'%s' not found, function list does not exist.", + name); + return NULL; + } + if(!ListDictionary_Contains(cb_dict, (void *)name)) + { + DEBUG_WARN("'%s' not found", name); + return NULL; + } + rc = ListDictionary_GetItemValue(cb_dict, (void *)name); + DEBUG_DVC("'%s'=%p found", name, rc); + assert(context); + *context = rc->context; + return rc->fkt; +} + +static BOOL callback_key_cmp(void *a, void *b) +{ + return strcmp(a, b) ? FALSE : TRUE; +} + +void add_callback_by_name(const char *name, void *fkt, void *context) +{ + struct cb_value *value = calloc(1, sizeof(struct cb_value)); + if(!cb_dict) + { + DEBUG_DVC("Function list is empty, allocating new."); + cb_dict = ListDictionary_New(TRUE); + ListDictionary_KeyObject(cb_dict)->fnObjectEquals = callback_key_cmp; + } + value->fkt = fkt; + value->context = context; + DEBUG_DVC("Adding '%s'=%p to function list.", name, fkt); + ListDictionary_Add(cb_dict, (void *)name, value); + dump_callbacks(); +} + +void remove_callback_by_name(const char *name, void *context) +{ + if(!cb_dict) + { + DEBUG_WARN("trying to remove '%s', but function list does not exist.", + name); + return; + } + if(!ListDictionary_Contains(cb_dict, (void *)name)) + { + DEBUG_WARN("trying to remove '%s', which is not in function list.", + name); + return; + } + DEBUG_DVC("Removing '%s' from function list.", name); + ListDictionary_Remove(cb_dict, (void *)name); + if(ListDictionary_Count(cb_dict) < 1) + { + DEBUG_DVC("Function list is empty, freeing resources."); + ListDictionary_Free(cb_dict); + cb_dict = NULL; + } + dump_callbacks(); +} diff --git a/include/freerdp/dvc.h b/include/freerdp/dvc.h index a2350bfe8..7911fa556 100644 --- a/include/freerdp/dvc.h +++ b/include/freerdp/dvc.h @@ -65,96 +65,100 @@ typedef struct _IWTSVirtualChannelCallback IWTSVirtualChannelCallback; struct _IWTSListener { /* Retrieves the listener-specific configuration. */ - int (*GetConfiguration) (IWTSListener* pListener, - void** ppPropertyBag); + int (*GetConfiguration)(IWTSListener *pListener, + void **ppPropertyBag); - void* pInterface; + void *pInterface; }; struct _IWTSVirtualChannel { /* Starts a write request on the channel. */ - int (*Write) (IWTSVirtualChannel* pChannel, - UINT32 cbSize, - BYTE* pBuffer, - void* pReserved); + int (*Write)(IWTSVirtualChannel *pChannel, + UINT32 cbSize, + BYTE *pBuffer, + void *pReserved); /* Closes the channel. */ - int (*Close) (IWTSVirtualChannel* pChannel); + int (*Close)(IWTSVirtualChannel *pChannel); }; struct _IWTSVirtualChannelManager { /* Returns an instance of a listener object that listens on a specific endpoint, or creates a static channel. */ - int (*CreateListener) (IWTSVirtualChannelManager* pChannelMgr, - const char* pszChannelName, - UINT32 ulFlags, - IWTSListenerCallback* pListenerCallback, - IWTSListener** ppListener); + int (*CreateListener)(IWTSVirtualChannelManager *pChannelMgr, + const char *pszChannelName, + UINT32 ulFlags, + IWTSListenerCallback *pListenerCallback, + IWTSListener **ppListener); /* Push a virtual channel event. This is a FreeRDP extension to standard MS API. */ - int (*PushEvent) (IWTSVirtualChannelManager* pChannelMgr, - wMessage* pEvent); + int (*PushEvent)(IWTSVirtualChannelManager *pChannelMgr, + wMessage *pEvent); /* Find the channel or ID to send data to a specific endpoint. */ - UINT32 (*GetChannelId) (IWTSVirtualChannel * channel); - IWTSVirtualChannel* (*FindChannelById) (IWTSVirtualChannelManager* pChannelMgr, - UINT32 ChannelId); + UINT32(*GetChannelId)(IWTSVirtualChannel *channel); + IWTSVirtualChannel *(*FindChannelById)(IWTSVirtualChannelManager *pChannelMgr, + UINT32 ChannelId); }; struct _IWTSPlugin { /* Used for the first call that is made from the client to the plug-in. */ - int (*Initialize) (IWTSPlugin* pPlugin, - IWTSVirtualChannelManager* pChannelMgr); + int (*Initialize)(IWTSPlugin *pPlugin, + IWTSVirtualChannelManager *pChannelMgr); /* Notifies the plug-in that the Remote Desktop Connection (RDC) client has successfully connected to the Remote Desktop Session Host (RD Session Host) server. */ - int (*Connected) (IWTSPlugin* pPlugin); + int (*Connected)(IWTSPlugin *pPlugin); /* Notifies the plug-in that the Remote Desktop Connection (RDC) client has disconnected from the RD Session Host server. */ - int (*Disconnected) (IWTSPlugin* pPlugin, - UINT32 dwDisconnectCode); + int (*Disconnected)(IWTSPlugin *pPlugin, + UINT32 dwDisconnectCode); /* Notifies the plug-in that the Remote Desktop Connection (RDC) client has terminated. */ - int (*Terminated) (IWTSPlugin* pPlugin); + int (*Terminated)(IWTSPlugin *pPlugin); /* Extended */ - void* pInterface; + void *pInterface; }; struct _IWTSListenerCallback { /* Accepts or denies a connection request for an incoming connection to the associated listener. */ - int (*OnNewChannelConnection) (IWTSListenerCallback* pListenerCallback, - IWTSVirtualChannel* pChannel, - BYTE* Data, - int* pbAccept, - IWTSVirtualChannelCallback** ppCallback); + int (*OnNewChannelConnection)(IWTSListenerCallback *pListenerCallback, + IWTSVirtualChannel *pChannel, + BYTE *Data, + int *pbAccept, + IWTSVirtualChannelCallback **ppCallback); }; struct _IWTSVirtualChannelCallback { /* Notifies the user about data that is being received. */ - int (*OnDataReceived) (IWTSVirtualChannelCallback* pChannelCallback, - UINT32 cbSize, - BYTE* pBuffer); + int (*OnDataReceived)(IWTSVirtualChannelCallback *pChannelCallback, + UINT32 cbSize, + BYTE *pBuffer); /* Notifies the user that the channel has been closed. */ - int (*OnClose) (IWTSVirtualChannelCallback* pChannelCallback); + int (*OnClose)(IWTSVirtualChannelCallback *pChannelCallback); }; /* The DVC Plugin entry points */ typedef struct _IDRDYNVC_ENTRY_POINTS IDRDYNVC_ENTRY_POINTS; struct _IDRDYNVC_ENTRY_POINTS { - int (*RegisterPlugin) (IDRDYNVC_ENTRY_POINTS* pEntryPoints, - const char* name, IWTSPlugin* pPlugin); - IWTSPlugin* (*GetPlugin) (IDRDYNVC_ENTRY_POINTS* pEntryPoints, - const char* name); - ADDIN_ARGV* (*GetPluginData) (IDRDYNVC_ENTRY_POINTS* pEntryPoints); + int (*RegisterPlugin)(IDRDYNVC_ENTRY_POINTS *pEntryPoints, + const char *name, IWTSPlugin *pPlugin); + IWTSPlugin *(*GetPlugin)(IDRDYNVC_ENTRY_POINTS *pEntryPoints, + const char *name); + ADDIN_ARGV *(*GetPluginData)(IDRDYNVC_ENTRY_POINTS *pEntryPoints); }; -typedef int (*PDVC_PLUGIN_ENTRY) (IDRDYNVC_ENTRY_POINTS*); +typedef int (*PDVC_PLUGIN_ENTRY)(IDRDYNVC_ENTRY_POINTS *); + +void *get_callback_by_name(const char *name, void **context); +void add_callback_by_name(const char *name, void *fkt, void *context); +void remove_callback_by_name(const char *name, void *context); #endif /* FREERDP_DVC_H */