20 #include <freerdp/config.h>
21 #include <freerdp/log.h>
22 #include <freerdp/client/channels.h>
24 #define TAG FREERDP_TAG("genericdynvc")
26 static UINT generic_on_new_channel_connection(IWTSListenerCallback* pListenerCallback,
27 IWTSVirtualChannel* pChannel, BYTE* Data,
29 IWTSVirtualChannelCallback** ppCallback)
35 if (!listener_callback || !listener_callback->plugin)
36 return ERROR_INTERNAL_ERROR;
39 WLog_Print(plugin->log, WLOG_TRACE,
"...");
44 WLog_Print(plugin->log, WLOG_ERROR,
"calloc failed!");
45 return CHANNEL_RC_NO_MEMORY;
49 callback->iface = *plugin->channel_callbacks;
51 callback->plugin = listener_callback->plugin;
52 callback->channel_mgr = listener_callback->channel_mgr;
53 callback->channel = pChannel;
55 listener_callback->channel_callback = callback;
56 listener_callback->channel = pChannel;
58 *ppCallback = (IWTSVirtualChannelCallback*)callback;
62 static UINT generic_dynvc_plugin_initialize(IWTSPlugin* pPlugin,
63 IWTSVirtualChannelManager* pChannelMgr)
70 return CHANNEL_RC_BAD_CHANNEL_HANDLE;
73 return ERROR_INVALID_PARAMETER;
75 if (plugin->initialized)
77 WLog_ERR(TAG,
"[%s] channel initialized twice, aborting", plugin->dynvc_name);
78 return ERROR_INVALID_DATA;
81 WLog_Print(plugin->log, WLOG_TRACE,
"...");
83 if (!listener_callback)
85 WLog_Print(plugin->log, WLOG_ERROR,
"calloc failed!");
86 return CHANNEL_RC_NO_MEMORY;
89 plugin->listener_callback = listener_callback;
90 listener_callback->iface.OnNewChannelConnection = generic_on_new_channel_connection;
91 listener_callback->plugin = pPlugin;
92 listener_callback->channel_mgr = pChannelMgr;
93 rc = pChannelMgr->CreateListener(pChannelMgr, plugin->dynvc_name, 0, &listener_callback->iface,
96 plugin->listener->pInterface = plugin->iface.pInterface;
97 plugin->initialized = (rc == CHANNEL_RC_OK);
101 static UINT generic_plugin_terminated(IWTSPlugin* pPlugin)
104 UINT error = CHANNEL_RC_OK;
107 return CHANNEL_RC_BAD_CHANNEL_HANDLE;
109 WLog_Print(plugin->log, WLOG_TRACE,
"...");
112 plugin->initialized = FALSE;
114 if (plugin->terminatePluginFn)
115 plugin->terminatePluginFn(plugin);
117 if (plugin->listener_callback)
119 IWTSVirtualChannelManager* mgr = plugin->listener_callback->channel_mgr;
121 IFCALL(mgr->DestroyListener, mgr, plugin->listener);
124 free(plugin->listener_callback);
125 free(plugin->dynvc_name);
130 static UINT generic_dynvc_plugin_attached(IWTSPlugin* pPlugin)
133 UINT error = CHANNEL_RC_OK;
136 return CHANNEL_RC_BAD_CHANNEL_HANDLE;
138 pluginn->attached = TRUE;
142 static UINT generic_dynvc_plugin_detached(IWTSPlugin* pPlugin)
145 UINT error = CHANNEL_RC_OK;
148 return CHANNEL_RC_BAD_CHANNEL_HANDLE;
150 plugin->attached = FALSE;
154 UINT freerdp_generic_DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints,
const char* logTag,
155 const char* name,
size_t pluginSize,
size_t channelCallbackSize,
156 const IWTSVirtualChannelCallback* channel_callbacks,
157 DYNVC_PLUGIN_INIT_FN initPluginFn,
158 DYNVC_PLUGIN_TERMINATE_FN terminatePluginFn)
161 UINT error = CHANNEL_RC_INITIALIZATION_ERROR;
163 WINPR_ASSERT(pEntryPoints);
164 WINPR_ASSERT(pEntryPoints->GetPlugin);
165 WINPR_ASSERT(logTag);
167 WINPR_ASSERT(pluginSize >=
sizeof(*plugin));
172 return CHANNEL_RC_ALREADY_INITIALIZED;
177 WLog_ERR(TAG,
"calloc failed!");
178 return CHANNEL_RC_NO_MEMORY;
181 plugin->log = WLog_Get(logTag);
182 plugin->attached = TRUE;
183 plugin->channel_callbacks = channel_callbacks;
184 plugin->channelCallbackSize = channelCallbackSize;
185 plugin->iface.Initialize = generic_dynvc_plugin_initialize;
186 plugin->iface.Connected = NULL;
187 plugin->iface.Disconnected = NULL;
188 plugin->iface.Terminated = generic_plugin_terminated;
189 plugin->iface.Attached = generic_dynvc_plugin_attached;
190 plugin->iface.Detached = generic_dynvc_plugin_detached;
191 plugin->terminatePluginFn = terminatePluginFn;
195 rdpSettings* settings = pEntryPoints->GetRdpSettings(pEntryPoints);
196 rdpContext* context = pEntryPoints->GetRdpContext(pEntryPoints);
198 error = initPluginFn(plugin, context, settings);
199 if (error != CHANNEL_RC_OK)
203 plugin->dynvc_name = _strdup(name);
204 if (!plugin->dynvc_name)
207 error = pEntryPoints->RegisterPlugin(pEntryPoints, name, &plugin->iface);
208 if (error == CHANNEL_RC_OK)
212 generic_plugin_terminated(&plugin->iface);