20#include <freerdp/config.h>
21#include <freerdp/log.h>
22#include <freerdp/client/channels.h>
24#define TAG FREERDP_TAG("genericdynvc")
26static UINT generic_on_new_channel_connection(IWTSListenerCallback* pListenerCallback,
27 IWTSVirtualChannel* pChannel,
28 WINPR_ATTR_UNUSED BYTE* Data,
29 WINPR_ATTR_UNUSED BOOL* pbAccept,
30 IWTSVirtualChannelCallback** ppCallback)
36 if (!listener_callback || !listener_callback->plugin)
37 return ERROR_INTERNAL_ERROR;
40 WLog_Print(plugin->log, WLOG_TRACE,
"...");
45 WLog_Print(plugin->log, WLOG_ERROR,
"calloc failed!");
46 return CHANNEL_RC_NO_MEMORY;
50 callback->iface = *plugin->channel_callbacks;
52 callback->plugin = listener_callback->plugin;
53 callback->channel_mgr = listener_callback->channel_mgr;
54 callback->channel = pChannel;
56 listener_callback->channel_callback = callback;
57 listener_callback->channel = pChannel;
59 *ppCallback = (IWTSVirtualChannelCallback*)callback;
63static UINT generic_dynvc_plugin_initialize(IWTSPlugin* pPlugin,
64 IWTSVirtualChannelManager* pChannelMgr)
71 return CHANNEL_RC_BAD_CHANNEL_HANDLE;
74 return ERROR_INVALID_PARAMETER;
76 if (plugin->initialized)
78 WLog_ERR(TAG,
"[%s] channel initialized twice, aborting", plugin->dynvc_name);
79 return ERROR_INVALID_DATA;
82 WLog_Print(plugin->log, WLOG_TRACE,
"...");
84 if (!listener_callback)
86 WLog_Print(plugin->log, WLOG_ERROR,
"calloc failed!");
87 return CHANNEL_RC_NO_MEMORY;
90 plugin->listener_callback = listener_callback;
91 listener_callback->iface.OnNewChannelConnection = generic_on_new_channel_connection;
92 listener_callback->plugin = pPlugin;
93 listener_callback->channel_mgr = pChannelMgr;
94 rc = pChannelMgr->CreateListener(pChannelMgr, plugin->dynvc_name, 0, &listener_callback->iface,
97 plugin->listener->pInterface = plugin->iface.pInterface;
98 plugin->initialized = (rc == CHANNEL_RC_OK);
102static UINT generic_plugin_terminated(IWTSPlugin* pPlugin)
105 UINT error = CHANNEL_RC_OK;
108 return CHANNEL_RC_BAD_CHANNEL_HANDLE;
110 WLog_Print(plugin->log, WLOG_TRACE,
"...");
113 plugin->initialized = FALSE;
115 if (plugin->terminatePluginFn)
116 plugin->terminatePluginFn(plugin);
118 if (plugin->listener_callback)
120 IWTSVirtualChannelManager* mgr = plugin->listener_callback->channel_mgr;
122 IFCALL(mgr->DestroyListener, mgr, plugin->listener);
125 free(plugin->listener_callback);
126 free(plugin->dynvc_name);
131static UINT generic_dynvc_plugin_attached(IWTSPlugin* pPlugin)
134 UINT error = CHANNEL_RC_OK;
137 return CHANNEL_RC_BAD_CHANNEL_HANDLE;
139 pluginn->attached = TRUE;
143static UINT generic_dynvc_plugin_detached(IWTSPlugin* pPlugin)
146 UINT error = CHANNEL_RC_OK;
149 return CHANNEL_RC_BAD_CHANNEL_HANDLE;
151 plugin->attached = FALSE;
155UINT freerdp_generic_DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints,
const char* logTag,
156 const char* name,
size_t pluginSize,
size_t channelCallbackSize,
157 const IWTSVirtualChannelCallback* channel_callbacks,
158 DYNVC_PLUGIN_INIT_FN initPluginFn,
159 DYNVC_PLUGIN_TERMINATE_FN terminatePluginFn)
162 UINT error = CHANNEL_RC_INITIALIZATION_ERROR;
164 WINPR_ASSERT(pEntryPoints);
165 WINPR_ASSERT(pEntryPoints->GetPlugin);
166 WINPR_ASSERT(logTag);
168 WINPR_ASSERT(pluginSize >=
sizeof(*plugin));
173 return CHANNEL_RC_ALREADY_INITIALIZED;
178 WLog_ERR(TAG,
"calloc failed!");
179 return CHANNEL_RC_NO_MEMORY;
182 plugin->log = WLog_Get(logTag);
183 plugin->attached = TRUE;
184 plugin->channel_callbacks = channel_callbacks;
185 plugin->channelCallbackSize = channelCallbackSize;
186 plugin->iface.Initialize = generic_dynvc_plugin_initialize;
187 plugin->iface.Connected = NULL;
188 plugin->iface.Disconnected = NULL;
189 plugin->iface.Terminated = generic_plugin_terminated;
190 plugin->iface.Attached = generic_dynvc_plugin_attached;
191 plugin->iface.Detached = generic_dynvc_plugin_detached;
192 plugin->terminatePluginFn = terminatePluginFn;
196 rdpSettings* settings = pEntryPoints->GetRdpSettings(pEntryPoints);
197 rdpContext* context = pEntryPoints->GetRdpContext(pEntryPoints);
199 error = initPluginFn(plugin, context, settings);
200 if (error != CHANNEL_RC_OK)
204 plugin->dynvc_name = _strdup(name);
205 if (!plugin->dynvc_name)
208 error = pEntryPoints->RegisterPlugin(pEntryPoints, name, &plugin->iface);
209 if (error == CHANNEL_RC_OK)
213 generic_plugin_terminated(&plugin->iface);