Merge pull request #6173 from akallabeth/drdynvc_cleanup
Drdynvc cleanup
This commit is contained in:
commit
c882a0c1b6
@ -687,7 +687,7 @@ static UINT audin_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManag
|
|||||||
audin->listener_callback->plugin = pPlugin;
|
audin->listener_callback->plugin = pPlugin;
|
||||||
audin->listener_callback->channel_mgr = pChannelMgr;
|
audin->listener_callback->channel_mgr = pChannelMgr;
|
||||||
return pChannelMgr->CreateListener(pChannelMgr, "AUDIO_INPUT", 0,
|
return pChannelMgr->CreateListener(pChannelMgr, "AUDIO_INPUT", 0,
|
||||||
(IWTSListenerCallback*)audin->listener_callback, NULL);
|
&audin->listener_callback->iface, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -704,6 +704,13 @@ static UINT audin_plugin_terminated(IWTSPlugin* pPlugin)
|
|||||||
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
|
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
|
||||||
|
|
||||||
WLog_Print(audin->log, WLOG_TRACE, "...");
|
WLog_Print(audin->log, WLOG_TRACE, "...");
|
||||||
|
|
||||||
|
if (audin->listener_callback)
|
||||||
|
{
|
||||||
|
IWTSVirtualChannelManager* mgr = audin->listener_callback->channel_mgr;
|
||||||
|
if (mgr)
|
||||||
|
IFCALL(mgr->DestroyListener, mgr, &audin->iface);
|
||||||
|
}
|
||||||
audio_formats_free(audin->fixed_format, 1);
|
audio_formats_free(audin->fixed_format, 1);
|
||||||
|
|
||||||
if (audin->device)
|
if (audin->device)
|
||||||
|
@ -308,8 +308,7 @@ static UINT disp_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManage
|
|||||||
disp->listener_callback->plugin = pPlugin;
|
disp->listener_callback->plugin = pPlugin;
|
||||||
disp->listener_callback->channel_mgr = pChannelMgr;
|
disp->listener_callback->channel_mgr = pChannelMgr;
|
||||||
status = pChannelMgr->CreateListener(pChannelMgr, DISP_DVC_CHANNEL_NAME, 0,
|
status = pChannelMgr->CreateListener(pChannelMgr, DISP_DVC_CHANNEL_NAME, 0,
|
||||||
(IWTSListenerCallback*)disp->listener_callback,
|
&disp->listener_callback->iface, &(disp->listener));
|
||||||
&(disp->listener));
|
|
||||||
disp->listener->pInterface = disp->iface.pInterface;
|
disp->listener->pInterface = disp->iface.pInterface;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -322,6 +321,14 @@ static UINT disp_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManage
|
|||||||
static UINT disp_plugin_terminated(IWTSPlugin* pPlugin)
|
static UINT disp_plugin_terminated(IWTSPlugin* pPlugin)
|
||||||
{
|
{
|
||||||
DISP_PLUGIN* disp = (DISP_PLUGIN*)pPlugin;
|
DISP_PLUGIN* disp = (DISP_PLUGIN*)pPlugin;
|
||||||
|
|
||||||
|
if (disp && disp->listener_callback)
|
||||||
|
{
|
||||||
|
IWTSVirtualChannelManager* mgr = disp->listener_callback->channel_mgr;
|
||||||
|
if (mgr)
|
||||||
|
IFCALL(mgr->DestroyListener, mgr, &disp->iface);
|
||||||
|
}
|
||||||
|
|
||||||
free(disp->listener_callback);
|
free(disp->listener_callback);
|
||||||
free(disp->iface.pInterface);
|
free(disp->iface.pInterface);
|
||||||
free(pPlugin);
|
free(pPlugin);
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#define TAG CHANNELS_TAG("drdynvc.client")
|
#define TAG CHANNELS_TAG("drdynvc.client")
|
||||||
|
|
||||||
|
static void dvcman_free(drdynvcPlugin* drdynvc, IWTSVirtualChannelManager* pChannelMgr);
|
||||||
static void dvcman_channel_free(void* channel);
|
static void dvcman_channel_free(void* channel);
|
||||||
static UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, const BYTE* data,
|
static UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, const BYTE* data,
|
||||||
UINT32 dataSize);
|
UINT32 dataSize);
|
||||||
@ -67,9 +68,8 @@ static UINT dvcman_create_listener(IWTSVirtualChannelManager* pChannelMgr,
|
|||||||
DVCMAN* dvcman = (DVCMAN*)pChannelMgr;
|
DVCMAN* dvcman = (DVCMAN*)pChannelMgr;
|
||||||
DVCMAN_LISTENER* listener;
|
DVCMAN_LISTENER* listener;
|
||||||
|
|
||||||
if (dvcman->num_listeners < MAX_PLUGINS)
|
WLog_DBG(TAG, "create_listener: %d.%s.", ArrayList_Count(dvcman->listeners) + 1,
|
||||||
{
|
pszChannelName);
|
||||||
WLog_DBG(TAG, "create_listener: %d.%s.", dvcman->num_listeners, pszChannelName);
|
|
||||||
listener = (DVCMAN_LISTENER*)calloc(1, sizeof(DVCMAN_LISTENER));
|
listener = (DVCMAN_LISTENER*)calloc(1, sizeof(DVCMAN_LISTENER));
|
||||||
|
|
||||||
if (!listener)
|
if (!listener)
|
||||||
@ -96,35 +96,22 @@ static UINT dvcman_create_listener(IWTSVirtualChannelManager* pChannelMgr,
|
|||||||
if (ppListener)
|
if (ppListener)
|
||||||
*ppListener = (IWTSListener*)listener;
|
*ppListener = (IWTSListener*)listener;
|
||||||
|
|
||||||
dvcman->listeners[dvcman->num_listeners++] = (IWTSListener*)listener;
|
if (ArrayList_Add(dvcman->listeners, listener) < 0)
|
||||||
return CHANNEL_RC_OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "create_listener: Maximum DVC listener number reached.");
|
|
||||||
return ERROR_INTERNAL_ERROR;
|
return ERROR_INTERNAL_ERROR;
|
||||||
}
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT dvcman_destroy_listener(IWTSVirtualChannelManager* pChannelMgr, IWTSListener* pListener)
|
static UINT dvcman_destroy_listener(IWTSVirtualChannelManager* pChannelMgr, IWTSListener* pListener)
|
||||||
{
|
{
|
||||||
size_t x;
|
|
||||||
DVCMAN_LISTENER* listener = (DVCMAN_LISTENER*)pListener;
|
DVCMAN_LISTENER* listener = (DVCMAN_LISTENER*)pListener;
|
||||||
|
|
||||||
|
WINPR_UNUSED(pChannelMgr);
|
||||||
|
|
||||||
if (listener)
|
if (listener)
|
||||||
{
|
{
|
||||||
DVCMAN* dvcman = listener->dvcman;
|
DVCMAN* dvcman = listener->dvcman;
|
||||||
for (x = 0; x < dvcman->num_listeners; x++)
|
if (dvcman)
|
||||||
{
|
ArrayList_Remove(dvcman->listeners, listener);
|
||||||
if (dvcman->listeners[x] == pListener)
|
|
||||||
{
|
|
||||||
size_t rest = (dvcman->num_listeners - x - 1) * sizeof(IWTSListener*);
|
|
||||||
MoveMemory(&dvcman->listeners[x], &dvcman->listeners[x + 1], rest);
|
|
||||||
dvcman->num_listeners--;
|
|
||||||
dvcman_wtslistener_free(listener);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
@ -140,34 +127,42 @@ static UINT dvcman_register_plugin(IDRDYNVC_ENTRY_POINTS* pEntryPoints, const ch
|
|||||||
{
|
{
|
||||||
DVCMAN* dvcman = ((DVCMAN_ENTRY_POINTS*)pEntryPoints)->dvcman;
|
DVCMAN* dvcman = ((DVCMAN_ENTRY_POINTS*)pEntryPoints)->dvcman;
|
||||||
|
|
||||||
if (dvcman->num_plugins < MAX_PLUGINS)
|
if (ArrayList_Add(dvcman->plugin_names, _strdup(name)) < 0)
|
||||||
{
|
|
||||||
dvcman->plugin_names[dvcman->num_plugins] = name;
|
|
||||||
dvcman->plugins[dvcman->num_plugins++] = pPlugin;
|
|
||||||
WLog_DBG(TAG, "register_plugin: num_plugins %d", dvcman->num_plugins);
|
|
||||||
return CHANNEL_RC_OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "register_plugin: Maximum DVC plugin number %u reached.", MAX_PLUGINS);
|
|
||||||
return ERROR_INTERNAL_ERROR;
|
return ERROR_INTERNAL_ERROR;
|
||||||
}
|
if (ArrayList_Add(dvcman->plugins, pPlugin) < 0)
|
||||||
|
return ERROR_INTERNAL_ERROR;
|
||||||
|
|
||||||
|
WLog_DBG(TAG, "register_plugin: num_plugins %d", ArrayList_Count(dvcman->plugins));
|
||||||
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static IWTSPlugin* dvcman_get_plugin(IDRDYNVC_ENTRY_POINTS* pEntryPoints, const char* name)
|
static IWTSPlugin* dvcman_get_plugin(IDRDYNVC_ENTRY_POINTS* pEntryPoints, const char* name)
|
||||||
{
|
{
|
||||||
size_t i;
|
IWTSPlugin* plugin = NULL;
|
||||||
|
size_t i, nc, pc;
|
||||||
DVCMAN* dvcman = ((DVCMAN_ENTRY_POINTS*)pEntryPoints)->dvcman;
|
DVCMAN* dvcman = ((DVCMAN_ENTRY_POINTS*)pEntryPoints)->dvcman;
|
||||||
|
if (!dvcman || !pEntryPoints || !name)
|
||||||
for (i = 0; i < dvcman->num_plugins; i++)
|
|
||||||
{
|
|
||||||
if (dvcman->plugin_names[i] == name || strcmp(dvcman->plugin_names[i], name) == 0)
|
|
||||||
{
|
|
||||||
return dvcman->plugins[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
nc = ArrayList_Count(dvcman->plugin_names);
|
||||||
|
pc = ArrayList_Count(dvcman->plugins);
|
||||||
|
if (nc != pc)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ArrayList_Lock(dvcman->plugin_names);
|
||||||
|
ArrayList_Lock(dvcman->plugins);
|
||||||
|
for (i = 0; i < pc; i++)
|
||||||
|
{
|
||||||
|
const char* cur = ArrayList_GetItem(dvcman->plugin_names, i);
|
||||||
|
if (strcmp(cur, name) == 0)
|
||||||
|
{
|
||||||
|
plugin = ArrayList_GetItem(dvcman->plugins, i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ArrayList_Unlock(dvcman->plugin_names);
|
||||||
|
ArrayList_Unlock(dvcman->plugins);
|
||||||
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ADDIN_ARGV* dvcman_get_plugin_data(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
|
static ADDIN_ARGV* dvcman_get_plugin_data(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
|
||||||
@ -196,38 +191,40 @@ static IWTSVirtualChannel* dvcman_find_channel_by_id(IWTSVirtualChannelManager*
|
|||||||
UINT32 ChannelId)
|
UINT32 ChannelId)
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
BOOL found = FALSE;
|
IWTSVirtualChannel* channel = NULL;
|
||||||
DVCMAN_CHANNEL* channel;
|
|
||||||
DVCMAN* dvcman = (DVCMAN*)pChannelMgr;
|
DVCMAN* dvcman = (DVCMAN*)pChannelMgr;
|
||||||
ArrayList_Lock(dvcman->channels);
|
ArrayList_Lock(dvcman->channels);
|
||||||
index = 0;
|
for (index = 0; index < ArrayList_Count(dvcman->channels); index++)
|
||||||
channel = (DVCMAN_CHANNEL*)ArrayList_GetItem(dvcman->channels, index++);
|
|
||||||
|
|
||||||
while (channel)
|
|
||||||
{
|
{
|
||||||
if (channel->channel_id == ChannelId)
|
DVCMAN_CHANNEL* cur = (DVCMAN_CHANNEL*)ArrayList_GetItem(dvcman->channels, index);
|
||||||
|
if (cur->channel_id == ChannelId)
|
||||||
{
|
{
|
||||||
found = TRUE;
|
channel = &cur->iface;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel = (DVCMAN_CHANNEL*)ArrayList_GetItem(dvcman->channels, index++);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayList_Unlock(dvcman->channels);
|
ArrayList_Unlock(dvcman->channels);
|
||||||
return (found) ? ((IWTSVirtualChannel*)channel) : NULL;
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dvcman_plugin_terminate(void* plugin)
|
||||||
|
{
|
||||||
|
IWTSPlugin* pPlugin = plugin;
|
||||||
|
|
||||||
|
UINT error = IFCALLRESULT(CHANNEL_RC_OK, pPlugin->Terminated, pPlugin);
|
||||||
|
if (error != CHANNEL_RC_OK)
|
||||||
|
WLog_ERR(TAG, "Terminated failed with error %" PRIu32 "!", error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static IWTSVirtualChannelManager* dvcman_new(drdynvcPlugin* plugin)
|
static IWTSVirtualChannelManager* dvcman_new(drdynvcPlugin* plugin)
|
||||||
{
|
{
|
||||||
|
wObject* obj;
|
||||||
DVCMAN* dvcman;
|
DVCMAN* dvcman;
|
||||||
dvcman = (DVCMAN*)calloc(1, sizeof(DVCMAN));
|
dvcman = (DVCMAN*)calloc(1, sizeof(DVCMAN));
|
||||||
|
|
||||||
if (!dvcman)
|
if (!dvcman)
|
||||||
{
|
|
||||||
WLog_Print(plugin->log, WLOG_ERROR, "calloc failed!");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
dvcman->iface.CreateListener = dvcman_create_listener;
|
dvcman->iface.CreateListener = dvcman_create_listener;
|
||||||
dvcman->iface.DestroyListener = dvcman_destroy_listener;
|
dvcman->iface.DestroyListener = dvcman_destroy_listener;
|
||||||
@ -238,24 +235,36 @@ static IWTSVirtualChannelManager* dvcman_new(drdynvcPlugin* plugin)
|
|||||||
dvcman->channels = ArrayList_New(TRUE);
|
dvcman->channels = ArrayList_New(TRUE);
|
||||||
|
|
||||||
if (!dvcman->channels)
|
if (!dvcman->channels)
|
||||||
{
|
goto fail;
|
||||||
WLog_Print(plugin->log, WLOG_ERROR, "ArrayList_New failed!");
|
|
||||||
free(dvcman);
|
obj = ArrayList_Object(dvcman->channels);
|
||||||
return NULL;
|
obj->fnObjectFree = dvcman_channel_free;
|
||||||
}
|
|
||||||
|
|
||||||
dvcman->channels->object.fnObjectFree = dvcman_channel_free;
|
|
||||||
dvcman->pool = StreamPool_New(TRUE, 10);
|
dvcman->pool = StreamPool_New(TRUE, 10);
|
||||||
|
|
||||||
if (!dvcman->pool)
|
if (!dvcman->pool)
|
||||||
{
|
goto fail;
|
||||||
WLog_Print(plugin->log, WLOG_ERROR, "StreamPool_New failed!");
|
|
||||||
ArrayList_Free(dvcman->channels);
|
|
||||||
free(dvcman);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (IWTSVirtualChannelManager*)dvcman;
|
dvcman->listeners = ArrayList_New(TRUE);
|
||||||
|
if (!dvcman->listeners)
|
||||||
|
goto fail;
|
||||||
|
obj = ArrayList_Object(dvcman->listeners);
|
||||||
|
obj->fnObjectFree = dvcman_wtslistener_free;
|
||||||
|
|
||||||
|
dvcman->plugin_names = ArrayList_New(TRUE);
|
||||||
|
if (!dvcman->plugin_names)
|
||||||
|
goto fail;
|
||||||
|
obj = ArrayList_Object(dvcman->plugin_names);
|
||||||
|
obj->fnObjectFree = free;
|
||||||
|
|
||||||
|
dvcman->plugins = ArrayList_New(TRUE);
|
||||||
|
if (!dvcman->plugins)
|
||||||
|
goto fail;
|
||||||
|
obj = ArrayList_Object(dvcman->plugins);
|
||||||
|
obj->fnObjectFree = dvcman_plugin_terminate;
|
||||||
|
return &dvcman->iface;
|
||||||
|
fail:
|
||||||
|
dvcman_free(plugin, &dvcman->iface);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -304,31 +313,22 @@ static DVCMAN_CHANNEL* dvcman_channel_new(drdynvcPlugin* drdynvc,
|
|||||||
channel = (DVCMAN_CHANNEL*)calloc(1, sizeof(DVCMAN_CHANNEL));
|
channel = (DVCMAN_CHANNEL*)calloc(1, sizeof(DVCMAN_CHANNEL));
|
||||||
|
|
||||||
if (!channel)
|
if (!channel)
|
||||||
{
|
goto fail;
|
||||||
WLog_Print(drdynvc->log, WLOG_ERROR, "calloc failed!");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
channel->dvcman = (DVCMAN*)pChannelMgr;
|
channel->dvcman = (DVCMAN*)pChannelMgr;
|
||||||
channel->channel_id = ChannelId;
|
channel->channel_id = ChannelId;
|
||||||
channel->channel_name = _strdup(ChannelName);
|
channel->channel_name = _strdup(ChannelName);
|
||||||
|
|
||||||
if (!channel->channel_name)
|
if (!channel->channel_name)
|
||||||
{
|
goto fail;
|
||||||
WLog_Print(drdynvc->log, WLOG_ERROR, "_strdup failed!");
|
|
||||||
free(channel);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!InitializeCriticalSectionEx(&(channel->lock), 0, 0))
|
if (!InitializeCriticalSectionEx(&(channel->lock), 0, 0))
|
||||||
{
|
goto fail;
|
||||||
WLog_Print(drdynvc->log, WLOG_ERROR, "InitializeCriticalSectionEx failed!");
|
|
||||||
free(channel->channel_name);
|
|
||||||
free(channel);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return channel;
|
return channel;
|
||||||
|
fail:
|
||||||
|
dvcman_channel_free(channel);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dvcman_channel_free(void* arg)
|
static void dvcman_channel_free(void* arg)
|
||||||
@ -376,31 +376,13 @@ static void dvcman_channel_free(void* arg)
|
|||||||
|
|
||||||
static void dvcman_free(drdynvcPlugin* drdynvc, IWTSVirtualChannelManager* pChannelMgr)
|
static void dvcman_free(drdynvcPlugin* drdynvc, IWTSVirtualChannelManager* pChannelMgr)
|
||||||
{
|
{
|
||||||
size_t i;
|
|
||||||
IWTSPlugin* pPlugin;
|
|
||||||
DVCMAN* dvcman = (DVCMAN*)pChannelMgr;
|
DVCMAN* dvcman = (DVCMAN*)pChannelMgr;
|
||||||
UINT error;
|
|
||||||
|
ArrayList_Free(dvcman->listeners);
|
||||||
ArrayList_Free(dvcman->channels);
|
ArrayList_Free(dvcman->channels);
|
||||||
|
ArrayList_Free(dvcman->plugin_names);
|
||||||
|
ArrayList_Free(dvcman->plugins);
|
||||||
|
|
||||||
for (i = 0; i < dvcman->num_listeners; i++)
|
|
||||||
{
|
|
||||||
DVCMAN_LISTENER* listener = (DVCMAN_LISTENER*)dvcman->listeners[i];
|
|
||||||
dvcman_wtslistener_free(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
dvcman->num_listeners = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < dvcman->num_plugins; i++)
|
|
||||||
{
|
|
||||||
pPlugin = dvcman->plugins[i];
|
|
||||||
|
|
||||||
if (pPlugin->Terminated)
|
|
||||||
if ((error = pPlugin->Terminated(pPlugin)))
|
|
||||||
WLog_Print(drdynvc->log, WLOG_ERROR, "Terminated failed with error %" PRIu32 "!",
|
|
||||||
error);
|
|
||||||
}
|
|
||||||
|
|
||||||
dvcman->num_plugins = 0;
|
|
||||||
StreamPool_Free(dvcman->pool);
|
StreamPool_Free(dvcman->pool);
|
||||||
free(dvcman);
|
free(dvcman);
|
||||||
}
|
}
|
||||||
@ -413,24 +395,26 @@ static void dvcman_free(drdynvcPlugin* drdynvc, IWTSVirtualChannelManager* pChan
|
|||||||
static UINT dvcman_init(drdynvcPlugin* drdynvc, IWTSVirtualChannelManager* pChannelMgr)
|
static UINT dvcman_init(drdynvcPlugin* drdynvc, IWTSVirtualChannelManager* pChannelMgr)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
IWTSPlugin* pPlugin;
|
|
||||||
DVCMAN* dvcman = (DVCMAN*)pChannelMgr;
|
DVCMAN* dvcman = (DVCMAN*)pChannelMgr;
|
||||||
UINT error;
|
UINT error = CHANNEL_RC_OK;
|
||||||
|
|
||||||
for (i = 0; i < dvcman->num_plugins; i++)
|
ArrayList_Lock(dvcman->plugins);
|
||||||
|
for (i = 0; i < ArrayList_Count(dvcman->plugins); i++)
|
||||||
{
|
{
|
||||||
pPlugin = dvcman->plugins[i];
|
IWTSPlugin* pPlugin = ArrayList_GetItem(dvcman->plugins, i);
|
||||||
|
|
||||||
if (pPlugin->Initialize)
|
error = IFCALLRESULT(CHANNEL_RC_OK, pPlugin->Initialize, pPlugin, pChannelMgr);
|
||||||
if ((error = pPlugin->Initialize(pPlugin, pChannelMgr)))
|
if (error != CHANNEL_RC_OK)
|
||||||
{
|
{
|
||||||
WLog_Print(drdynvc->log, WLOG_ERROR, "Initialize failed with error %" PRIu32 "!",
|
WLog_Print(drdynvc->log, WLOG_ERROR, "Initialize failed with error %" PRIu32 "!",
|
||||||
error);
|
error);
|
||||||
return error;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return CHANNEL_RC_OK;
|
fail:
|
||||||
|
ArrayList_Unlock(dvcman->plugins);
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -493,11 +477,13 @@ static UINT dvcman_create_channel(drdynvcPlugin* drdynvc, IWTSVirtualChannelMana
|
|||||||
}
|
}
|
||||||
|
|
||||||
channel->status = ERROR_NOT_CONNECTED;
|
channel->status = ERROR_NOT_CONNECTED;
|
||||||
ArrayList_Add(dvcman->channels, channel);
|
if (ArrayList_Add(dvcman->channels, channel) < 0)
|
||||||
|
return ERROR_INTERNAL_ERROR;
|
||||||
|
|
||||||
for (i = 0; i < dvcman->num_listeners; i++)
|
ArrayList_Lock(dvcman->listeners);
|
||||||
|
for (i = 0; i < ArrayList_Count(dvcman->listeners); i++)
|
||||||
{
|
{
|
||||||
DVCMAN_LISTENER* listener = (DVCMAN_LISTENER*)dvcman->listeners[i];
|
DVCMAN_LISTENER* listener = (DVCMAN_LISTENER*)ArrayList_GetItem(dvcman->listeners, i);
|
||||||
|
|
||||||
if (strcmp(listener->channel_name, ChannelName) == 0)
|
if (strcmp(listener->channel_name, ChannelName) == 0)
|
||||||
{
|
{
|
||||||
@ -524,7 +510,7 @@ static UINT dvcman_create_channel(drdynvcPlugin* drdynvc, IWTSVirtualChannelMana
|
|||||||
WLog_Print(drdynvc->log, WLOG_ERROR,
|
WLog_Print(drdynvc->log, WLOG_ERROR,
|
||||||
"context.OnChannelConnected failed with error %" PRIu32 "", error);
|
"context.OnChannelConnected failed with error %" PRIu32 "", error);
|
||||||
|
|
||||||
return error;
|
goto fail;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -532,19 +518,23 @@ static UINT dvcman_create_channel(drdynvcPlugin* drdynvc, IWTSVirtualChannelMana
|
|||||||
{
|
{
|
||||||
WLog_Print(drdynvc->log, WLOG_ERROR,
|
WLog_Print(drdynvc->log, WLOG_ERROR,
|
||||||
"OnNewChannelConnection failed with error %" PRIu32 "!", error);
|
"OnNewChannelConnection failed with error %" PRIu32 "!", error);
|
||||||
return error;
|
goto fail;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WLog_Print(drdynvc->log, WLOG_ERROR,
|
WLog_Print(drdynvc->log, WLOG_ERROR,
|
||||||
"OnNewChannelConnection returned with bAccept FALSE!");
|
"OnNewChannelConnection returned with bAccept FALSE!");
|
||||||
return ERROR_INTERNAL_ERROR;
|
error = ERROR_INTERNAL_ERROR;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
error = ERROR_INTERNAL_ERROR;
|
||||||
|
fail:
|
||||||
|
ArrayList_Unlock(dvcman->listeners);
|
||||||
|
|
||||||
return ERROR_INTERNAL_ERROR;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -590,6 +580,7 @@ static UINT dvcman_open_channel(drdynvcPlugin* drdynvc, IWTSVirtualChannelManage
|
|||||||
static UINT dvcman_close_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId,
|
static UINT dvcman_close_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId,
|
||||||
BOOL bSendClosePDU)
|
BOOL bSendClosePDU)
|
||||||
{
|
{
|
||||||
|
size_t i;
|
||||||
DVCMAN_CHANNEL* channel;
|
DVCMAN_CHANNEL* channel;
|
||||||
UINT error = CHANNEL_RC_OK;
|
UINT error = CHANNEL_RC_OK;
|
||||||
DVCMAN* dvcman = (DVCMAN*)pChannelMgr;
|
DVCMAN* dvcman = (DVCMAN*)pChannelMgr;
|
||||||
@ -608,10 +599,10 @@ static UINT dvcman_close_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32
|
|||||||
|
|
||||||
if (drdynvc && bSendClosePDU)
|
if (drdynvc && bSendClosePDU)
|
||||||
{
|
{
|
||||||
wStream* s = Stream_New(NULL, 5);
|
wStream* s = StreamPool_Take(dvcman->pool, 5);
|
||||||
if (!s)
|
if (!s)
|
||||||
{
|
{
|
||||||
WLog_Print(drdynvc->log, WLOG_ERROR, "Stream_New failed!");
|
WLog_Print(drdynvc->log, WLOG_ERROR, "StreamPool_Take failed!");
|
||||||
error = CHANNEL_RC_NO_MEMORY;
|
error = CHANNEL_RC_NO_MEMORY;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -619,9 +610,18 @@ static UINT dvcman_close_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32
|
|||||||
Stream_Write_UINT8(s, (CLOSE_REQUEST_PDU << 4) | 0x02);
|
Stream_Write_UINT8(s, (CLOSE_REQUEST_PDU << 4) | 0x02);
|
||||||
Stream_Write_UINT32(s, ChannelId);
|
Stream_Write_UINT32(s, ChannelId);
|
||||||
error = drdynvc_send(drdynvc, s);
|
error = drdynvc_send(drdynvc, s);
|
||||||
|
Stream_Release(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArrayList_Lock(dvcman->listeners);
|
||||||
|
for (i = ArrayList_Count(dvcman->listeners); i > 0; i--)
|
||||||
|
{
|
||||||
|
DVCMAN_LISTENER* listener = ArrayList_GetItem(dvcman->listeners, i - 1);
|
||||||
|
if (strcmp(listener->channel_name, channel->channel_name) == 0)
|
||||||
|
ArrayList_Remove(dvcman->listeners, listener);
|
||||||
|
}
|
||||||
|
ArrayList_Unlock(dvcman->listeners);
|
||||||
ArrayList_Remove(dvcman->channels, channel);
|
ArrayList_Remove(dvcman->channels, channel);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@ -689,7 +689,7 @@ static UINT dvcman_receive_channel_data(drdynvcPlugin* drdynvc,
|
|||||||
if (channel->dvc_data)
|
if (channel->dvc_data)
|
||||||
{
|
{
|
||||||
/* Fragmented data */
|
/* Fragmented data */
|
||||||
if (Stream_GetPosition(channel->dvc_data) + dataSize > Stream_Capacity(channel->dvc_data))
|
if (Stream_GetPosition(channel->dvc_data) + dataSize > channel->dvc_data_length)
|
||||||
{
|
{
|
||||||
WLog_Print(drdynvc->log, WLOG_ERROR, "data exceeding declared length!");
|
WLog_Print(drdynvc->log, WLOG_ERROR, "data exceeding declared length!");
|
||||||
Stream_Release(channel->dvc_data);
|
Stream_Release(channel->dvc_data);
|
||||||
@ -761,19 +761,17 @@ static UINT drdynvc_send(drdynvcPlugin* drdynvc, wStream* s)
|
|||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
case CHANNEL_RC_OK:
|
case CHANNEL_RC_OK:
|
||||||
|
Stream_AddRef(s);
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
|
|
||||||
case CHANNEL_RC_NOT_CONNECTED:
|
case CHANNEL_RC_NOT_CONNECTED:
|
||||||
Stream_Free(s, TRUE);
|
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
|
|
||||||
case CHANNEL_RC_BAD_CHANNEL_HANDLE:
|
case CHANNEL_RC_BAD_CHANNEL_HANDLE:
|
||||||
Stream_Free(s, TRUE);
|
|
||||||
WLog_ERR(TAG, "VirtualChannelWriteEx failed with CHANNEL_RC_BAD_CHANNEL_HANDLE");
|
WLog_ERR(TAG, "VirtualChannelWriteEx failed with CHANNEL_RC_BAD_CHANNEL_HANDLE");
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Stream_Free(s, TRUE);
|
|
||||||
WLog_Print(drdynvc->log, WLOG_ERROR,
|
WLog_Print(drdynvc->log, WLOG_ERROR,
|
||||||
"VirtualChannelWriteEx failed with %s [%08" PRIX32 "]",
|
"VirtualChannelWriteEx failed with %s [%08" PRIX32 "]",
|
||||||
WTSErrorToString(status), status);
|
WTSErrorToString(status), status);
|
||||||
@ -795,17 +793,20 @@ static UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, const B
|
|||||||
UINT8 cbLen;
|
UINT8 cbLen;
|
||||||
unsigned long chunkLength;
|
unsigned long chunkLength;
|
||||||
UINT status = CHANNEL_RC_BAD_INIT_HANDLE;
|
UINT status = CHANNEL_RC_BAD_INIT_HANDLE;
|
||||||
|
DVCMAN* dvcman;
|
||||||
|
|
||||||
if (!drdynvc)
|
if (!drdynvc)
|
||||||
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
|
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
|
||||||
|
|
||||||
|
dvcman = (DVCMAN*)drdynvc->channel_mgr;
|
||||||
|
|
||||||
WLog_Print(drdynvc->log, WLOG_DEBUG, "write_data: ChannelId=%" PRIu32 " size=%" PRIu32 "",
|
WLog_Print(drdynvc->log, WLOG_DEBUG, "write_data: ChannelId=%" PRIu32 " size=%" PRIu32 "",
|
||||||
ChannelId, dataSize);
|
ChannelId, dataSize);
|
||||||
data_out = Stream_New(NULL, CHANNEL_CHUNK_LENGTH);
|
data_out = StreamPool_Take(dvcman->pool, CHANNEL_CHUNK_LENGTH);
|
||||||
|
|
||||||
if (!data_out)
|
if (!data_out)
|
||||||
{
|
{
|
||||||
WLog_Print(drdynvc->log, WLOG_ERROR, "Stream_New failed!");
|
WLog_Print(drdynvc->log, WLOG_ERROR, "StreamPool_Take failed!");
|
||||||
return CHANNEL_RC_NO_MEMORY;
|
return CHANNEL_RC_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -815,7 +816,7 @@ static UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, const B
|
|||||||
|
|
||||||
if (dataSize == 0)
|
if (dataSize == 0)
|
||||||
{
|
{
|
||||||
status = dvcman_close_channel(drdynvc->channel_mgr, ChannelId, TRUE);
|
dvcman_close_channel(drdynvc->channel_mgr, ChannelId, TRUE);
|
||||||
}
|
}
|
||||||
else if (dataSize <= CHANNEL_CHUNK_LENGTH - pos)
|
else if (dataSize <= CHANNEL_CHUNK_LENGTH - pos)
|
||||||
{
|
{
|
||||||
@ -841,11 +842,11 @@ static UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, const B
|
|||||||
|
|
||||||
while (status == CHANNEL_RC_OK && dataSize > 0)
|
while (status == CHANNEL_RC_OK && dataSize > 0)
|
||||||
{
|
{
|
||||||
data_out = Stream_New(NULL, CHANNEL_CHUNK_LENGTH);
|
data_out = StreamPool_Take(dvcman->pool, CHANNEL_CHUNK_LENGTH);
|
||||||
|
|
||||||
if (!data_out)
|
if (!data_out)
|
||||||
{
|
{
|
||||||
WLog_Print(drdynvc->log, WLOG_ERROR, "Stream_New failed!");
|
WLog_Print(drdynvc->log, WLOG_ERROR, "StreamPool_Take failed!");
|
||||||
return CHANNEL_RC_NO_MEMORY;
|
return CHANNEL_RC_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -886,12 +887,14 @@ static UINT drdynvc_send_capability_response(drdynvcPlugin* drdynvc)
|
|||||||
{
|
{
|
||||||
UINT status;
|
UINT status;
|
||||||
wStream* s;
|
wStream* s;
|
||||||
|
DVCMAN* dvcman;
|
||||||
|
|
||||||
if (!drdynvc)
|
if (!drdynvc)
|
||||||
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
|
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
|
||||||
|
|
||||||
|
dvcman = (DVCMAN*)drdynvc->channel_mgr;
|
||||||
WLog_Print(drdynvc->log, WLOG_TRACE, "capability_response");
|
WLog_Print(drdynvc->log, WLOG_TRACE, "capability_response");
|
||||||
s = Stream_New(NULL, 4);
|
s = StreamPool_Take(dvcman->pool, 4);
|
||||||
|
|
||||||
if (!s)
|
if (!s)
|
||||||
{
|
{
|
||||||
@ -1002,11 +1005,13 @@ static UINT drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, int c
|
|||||||
UINT channel_status;
|
UINT channel_status;
|
||||||
char* name;
|
char* name;
|
||||||
size_t length;
|
size_t length;
|
||||||
|
DVCMAN* dvcman;
|
||||||
|
|
||||||
WINPR_UNUSED(Sp);
|
WINPR_UNUSED(Sp);
|
||||||
if (!drdynvc)
|
if (!drdynvc)
|
||||||
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
|
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
|
||||||
|
|
||||||
|
dvcman = (DVCMAN*)drdynvc->channel_mgr;
|
||||||
if (drdynvc->state == DRDYNVC_STATE_CAPABILITIES)
|
if (drdynvc->state == DRDYNVC_STATE_CAPABILITIES)
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -1039,11 +1044,11 @@ static UINT drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, int c
|
|||||||
WLog_Print(drdynvc->log, WLOG_DEBUG,
|
WLog_Print(drdynvc->log, WLOG_DEBUG,
|
||||||
"process_create_request: ChannelId=%" PRIu32 " ChannelName=%s", ChannelId, name);
|
"process_create_request: ChannelId=%" PRIu32 " ChannelName=%s", ChannelId, name);
|
||||||
channel_status = dvcman_create_channel(drdynvc, drdynvc->channel_mgr, ChannelId, name);
|
channel_status = dvcman_create_channel(drdynvc, drdynvc->channel_mgr, ChannelId, name);
|
||||||
data_out = Stream_New(NULL, pos + 4);
|
data_out = StreamPool_Take(dvcman->pool, pos + 4);
|
||||||
|
|
||||||
if (!data_out)
|
if (!data_out)
|
||||||
{
|
{
|
||||||
WLog_Print(drdynvc->log, WLOG_ERROR, "Stream_New failed!");
|
WLog_Print(drdynvc->log, WLOG_ERROR, "StreamPool_Take failed!");
|
||||||
return CHANNEL_RC_NO_MEMORY;
|
return CHANNEL_RC_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1231,22 +1236,23 @@ static UINT drdynvc_virtual_channel_event_data_received(drdynvcPlugin* drdynvc,
|
|||||||
|
|
||||||
if (dataFlags & CHANNEL_FLAG_FIRST)
|
if (dataFlags & CHANNEL_FLAG_FIRST)
|
||||||
{
|
{
|
||||||
|
DVCMAN* mgr = (DVCMAN*)drdynvc->channel_mgr;
|
||||||
if (drdynvc->data_in)
|
if (drdynvc->data_in)
|
||||||
Stream_Free(drdynvc->data_in, TRUE);
|
Stream_Release(drdynvc->data_in);
|
||||||
|
|
||||||
drdynvc->data_in = Stream_New(NULL, totalLength);
|
drdynvc->data_in = StreamPool_Take(mgr->pool, totalLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(data_in = drdynvc->data_in))
|
if (!(data_in = drdynvc->data_in))
|
||||||
{
|
{
|
||||||
WLog_Print(drdynvc->log, WLOG_ERROR, "Stream_New failed!");
|
WLog_Print(drdynvc->log, WLOG_ERROR, "StreamPool_Take failed!");
|
||||||
return CHANNEL_RC_NO_MEMORY;
|
return CHANNEL_RC_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Stream_EnsureRemainingCapacity(data_in, dataLength))
|
if (!Stream_EnsureRemainingCapacity(data_in, dataLength))
|
||||||
{
|
{
|
||||||
WLog_Print(drdynvc->log, WLOG_ERROR, "Stream_EnsureRemainingCapacity failed!");
|
WLog_Print(drdynvc->log, WLOG_ERROR, "Stream_EnsureRemainingCapacity failed!");
|
||||||
Stream_Free(drdynvc->data_in, TRUE);
|
Stream_Release(drdynvc->data_in);
|
||||||
drdynvc->data_in = NULL;
|
drdynvc->data_in = NULL;
|
||||||
return ERROR_INTERNAL_ERROR;
|
return ERROR_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
@ -1255,7 +1261,9 @@ static UINT drdynvc_virtual_channel_event_data_received(drdynvcPlugin* drdynvc,
|
|||||||
|
|
||||||
if (dataFlags & CHANNEL_FLAG_LAST)
|
if (dataFlags & CHANNEL_FLAG_LAST)
|
||||||
{
|
{
|
||||||
if (Stream_Capacity(data_in) != Stream_GetPosition(data_in))
|
const size_t cap = Stream_Capacity(data_in);
|
||||||
|
const size_t pos = Stream_GetPosition(data_in);
|
||||||
|
if (cap < pos)
|
||||||
{
|
{
|
||||||
WLog_Print(drdynvc->log, WLOG_ERROR, "drdynvc_plugin_process_received: read error");
|
WLog_Print(drdynvc->log, WLOG_ERROR, "drdynvc_plugin_process_received: read error");
|
||||||
return ERROR_INVALID_DATA;
|
return ERROR_INVALID_DATA;
|
||||||
@ -1304,7 +1312,7 @@ static void VCAPITYPE drdynvc_virtual_channel_open_event_ex(LPVOID lpUserParam,
|
|||||||
case CHANNEL_EVENT_WRITE_COMPLETE:
|
case CHANNEL_EVENT_WRITE_COMPLETE:
|
||||||
{
|
{
|
||||||
wStream* s = (wStream*)pData;
|
wStream* s = (wStream*)pData;
|
||||||
Stream_Free(s, TRUE);
|
Stream_Release(s);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1359,7 +1367,7 @@ static DWORD WINAPI drdynvc_virtual_channel_client_thread(LPVOID arg)
|
|||||||
"drdynvc_order_recv failed with error %" PRIu32 "!", error);
|
"drdynvc_order_recv failed with error %" PRIu32 "!", error);
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream_Free(data, TRUE);
|
Stream_Release(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1397,7 +1405,7 @@ static void drdynvc_queue_object_free(void* obj)
|
|||||||
s = (wStream*)msg->wParam;
|
s = (wStream*)msg->wParam;
|
||||||
|
|
||||||
if (s)
|
if (s)
|
||||||
Stream_Free(s, TRUE);
|
Stream_Release(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1529,7 +1537,7 @@ static UINT drdynvc_virtual_channel_event_disconnected(drdynvcPlugin* drdynvc)
|
|||||||
|
|
||||||
if (drdynvc->data_in)
|
if (drdynvc->data_in)
|
||||||
{
|
{
|
||||||
Stream_Free(drdynvc->data_in, TRUE);
|
Stream_Release(drdynvc->data_in);
|
||||||
drdynvc->data_in = NULL;
|
drdynvc->data_in = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1560,6 +1568,7 @@ static UINT drdynvc_virtual_channel_event_terminated(drdynvcPlugin* drdynvc)
|
|||||||
|
|
||||||
static UINT drdynvc_virtual_channel_event_attached(drdynvcPlugin* drdynvc)
|
static UINT drdynvc_virtual_channel_event_attached(drdynvcPlugin* drdynvc)
|
||||||
{
|
{
|
||||||
|
UINT error = CHANNEL_RC_OK;
|
||||||
size_t i;
|
size_t i;
|
||||||
DVCMAN* dvcman;
|
DVCMAN* dvcman;
|
||||||
|
|
||||||
@ -1571,25 +1580,27 @@ static UINT drdynvc_virtual_channel_event_attached(drdynvcPlugin* drdynvc)
|
|||||||
if (!dvcman)
|
if (!dvcman)
|
||||||
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
|
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
|
||||||
|
|
||||||
for (i = 0; i < dvcman->num_plugins; i++)
|
ArrayList_Lock(dvcman->plugins);
|
||||||
|
for (i = 0; i < ArrayList_Count(dvcman->plugins); i++)
|
||||||
{
|
{
|
||||||
UINT error;
|
IWTSPlugin* pPlugin = ArrayList_GetItem(dvcman->plugins, i);
|
||||||
IWTSPlugin* pPlugin = dvcman->plugins[i];
|
|
||||||
|
|
||||||
if (pPlugin->Attached)
|
error = IFCALLRESULT(CHANNEL_RC_OK, pPlugin->Attached, pPlugin);
|
||||||
if ((error = pPlugin->Attached(pPlugin)))
|
if (error != CHANNEL_RC_OK)
|
||||||
{
|
{
|
||||||
WLog_Print(drdynvc->log, WLOG_ERROR, "Attach failed with error %" PRIu32 "!",
|
WLog_Print(drdynvc->log, WLOG_ERROR, "Attach failed with error %" PRIu32 "!", error);
|
||||||
error);
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fail:
|
||||||
|
ArrayList_Unlock(dvcman->plugins);
|
||||||
return error;
|
return error;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return CHANNEL_RC_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT drdynvc_virtual_channel_event_detached(drdynvcPlugin* drdynvc)
|
static UINT drdynvc_virtual_channel_event_detached(drdynvcPlugin* drdynvc)
|
||||||
{
|
{
|
||||||
|
UINT error = CHANNEL_RC_OK;
|
||||||
size_t i;
|
size_t i;
|
||||||
DVCMAN* dvcman;
|
DVCMAN* dvcman;
|
||||||
|
|
||||||
@ -1601,21 +1612,23 @@ static UINT drdynvc_virtual_channel_event_detached(drdynvcPlugin* drdynvc)
|
|||||||
if (!dvcman)
|
if (!dvcman)
|
||||||
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
|
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
|
||||||
|
|
||||||
for (i = 0; i < dvcman->num_plugins; i++)
|
ArrayList_Lock(dvcman->plugins);
|
||||||
|
for (i = 0; i < ArrayList_Count(dvcman->plugins); i++)
|
||||||
{
|
{
|
||||||
UINT error;
|
IWTSPlugin* pPlugin = ArrayList_GetItem(dvcman->plugins, i);
|
||||||
IWTSPlugin* pPlugin = dvcman->plugins[i];
|
|
||||||
|
|
||||||
if (pPlugin->Detached)
|
error = IFCALLRESULT(CHANNEL_RC_OK, pPlugin->Detached, pPlugin);
|
||||||
if ((error = pPlugin->Detached(pPlugin)))
|
if (error != CHANNEL_RC_OK)
|
||||||
{
|
{
|
||||||
WLog_Print(drdynvc->log, WLOG_ERROR, "Detach failed with error %" PRIu32 "!",
|
WLog_Print(drdynvc->log, WLOG_ERROR, "Detach failed with error %" PRIu32 "!", error);
|
||||||
error);
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fail:
|
||||||
|
ArrayList_Unlock(dvcman->plugins);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return CHANNEL_RC_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID VCAPITYPE drdynvc_virtual_channel_init_event_ex(LPVOID lpUserParam, LPVOID pInitHandle,
|
static VOID VCAPITYPE drdynvc_virtual_channel_init_event_ex(LPVOID lpUserParam, LPVOID pInitHandle,
|
||||||
|
@ -37,21 +37,16 @@
|
|||||||
|
|
||||||
typedef struct drdynvc_plugin drdynvcPlugin;
|
typedef struct drdynvc_plugin drdynvcPlugin;
|
||||||
|
|
||||||
#define MAX_PLUGINS 32
|
|
||||||
|
|
||||||
struct _DVCMAN
|
struct _DVCMAN
|
||||||
{
|
{
|
||||||
IWTSVirtualChannelManager iface;
|
IWTSVirtualChannelManager iface;
|
||||||
|
|
||||||
drdynvcPlugin* drdynvc;
|
drdynvcPlugin* drdynvc;
|
||||||
|
|
||||||
size_t num_plugins;
|
wArrayList* plugin_names;
|
||||||
const char* plugin_names[MAX_PLUGINS];
|
wArrayList* plugins;
|
||||||
IWTSPlugin* plugins[MAX_PLUGINS];
|
|
||||||
|
|
||||||
size_t num_listeners;
|
|
||||||
IWTSListener* listeners[MAX_PLUGINS];
|
|
||||||
|
|
||||||
|
wArrayList* listeners;
|
||||||
wArrayList* channels;
|
wArrayList* channels;
|
||||||
wStreamPool* pool;
|
wStreamPool* pool;
|
||||||
};
|
};
|
||||||
|
@ -142,8 +142,8 @@ static UINT echo_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManage
|
|||||||
echo->listener_callback->plugin = pPlugin;
|
echo->listener_callback->plugin = pPlugin;
|
||||||
echo->listener_callback->channel_mgr = pChannelMgr;
|
echo->listener_callback->channel_mgr = pChannelMgr;
|
||||||
|
|
||||||
return pChannelMgr->CreateListener(pChannelMgr, "ECHO", 0,
|
return pChannelMgr->CreateListener(pChannelMgr, "ECHO", 0, &echo->listener_callback->iface,
|
||||||
(IWTSListenerCallback*)echo->listener_callback, NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -154,7 +154,12 @@ static UINT echo_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManage
|
|||||||
static UINT echo_plugin_terminated(IWTSPlugin* pPlugin)
|
static UINT echo_plugin_terminated(IWTSPlugin* pPlugin)
|
||||||
{
|
{
|
||||||
ECHO_PLUGIN* echo = (ECHO_PLUGIN*)pPlugin;
|
ECHO_PLUGIN* echo = (ECHO_PLUGIN*)pPlugin;
|
||||||
|
if (echo && echo->listener_callback)
|
||||||
|
{
|
||||||
|
IWTSVirtualChannelManager* mgr = echo->listener_callback->channel_mgr;
|
||||||
|
if (mgr)
|
||||||
|
IFCALL(mgr->DestroyListener, mgr, &echo->iface);
|
||||||
|
}
|
||||||
free(echo);
|
free(echo);
|
||||||
|
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
|
@ -410,9 +410,9 @@ static UINT geometry_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelMa
|
|||||||
geometry->listener_callback->iface.OnNewChannelConnection = geometry_on_new_channel_connection;
|
geometry->listener_callback->iface.OnNewChannelConnection = geometry_on_new_channel_connection;
|
||||||
geometry->listener_callback->plugin = pPlugin;
|
geometry->listener_callback->plugin = pPlugin;
|
||||||
geometry->listener_callback->channel_mgr = pChannelMgr;
|
geometry->listener_callback->channel_mgr = pChannelMgr;
|
||||||
status = pChannelMgr->CreateListener(pChannelMgr, GEOMETRY_DVC_CHANNEL_NAME, 0,
|
status =
|
||||||
(IWTSListenerCallback*)geometry->listener_callback,
|
pChannelMgr->CreateListener(pChannelMgr, GEOMETRY_DVC_CHANNEL_NAME, 0,
|
||||||
&(geometry->listener));
|
&geometry->listener_callback->iface, &(geometry->listener));
|
||||||
geometry->listener->pInterface = geometry->iface.pInterface;
|
geometry->listener->pInterface = geometry->iface.pInterface;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -427,6 +427,13 @@ static UINT geometry_plugin_terminated(IWTSPlugin* pPlugin)
|
|||||||
GEOMETRY_PLUGIN* geometry = (GEOMETRY_PLUGIN*)pPlugin;
|
GEOMETRY_PLUGIN* geometry = (GEOMETRY_PLUGIN*)pPlugin;
|
||||||
GeometryClientContext* context = (GeometryClientContext*)geometry->iface.pInterface;
|
GeometryClientContext* context = (GeometryClientContext*)geometry->iface.pInterface;
|
||||||
|
|
||||||
|
if (geometry && geometry->listener_callback)
|
||||||
|
{
|
||||||
|
IWTSVirtualChannelManager* mgr = geometry->listener_callback->channel_mgr;
|
||||||
|
if (mgr)
|
||||||
|
IFCALL(mgr->DestroyListener, mgr, &geometry->iface);
|
||||||
|
}
|
||||||
|
|
||||||
if (context)
|
if (context)
|
||||||
HashTable_Free(context->geometries);
|
HashTable_Free(context->geometries);
|
||||||
|
|
||||||
|
@ -571,8 +571,7 @@ static UINT rdpei_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManag
|
|||||||
rdpei->listener_callback->channel_mgr = pChannelMgr;
|
rdpei->listener_callback->channel_mgr = pChannelMgr;
|
||||||
|
|
||||||
if ((error = pChannelMgr->CreateListener(pChannelMgr, RDPEI_DVC_CHANNEL_NAME, 0,
|
if ((error = pChannelMgr->CreateListener(pChannelMgr, RDPEI_DVC_CHANNEL_NAME, 0,
|
||||||
(IWTSListenerCallback*)rdpei->listener_callback,
|
&rdpei->listener_callback->iface, &(rdpei->listener))))
|
||||||
&(rdpei->listener))))
|
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "ChannelMgr->CreateListener failed with error %" PRIu32 "!", error);
|
WLog_ERR(TAG, "ChannelMgr->CreateListener failed with error %" PRIu32 "!", error);
|
||||||
goto error_out;
|
goto error_out;
|
||||||
@ -598,6 +597,12 @@ static UINT rdpei_plugin_terminated(IWTSPlugin* pPlugin)
|
|||||||
if (!pPlugin)
|
if (!pPlugin)
|
||||||
return ERROR_INVALID_PARAMETER;
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (rdpei && rdpei->listener_callback)
|
||||||
|
{
|
||||||
|
IWTSVirtualChannelManager* mgr = rdpei->listener_callback->channel_mgr;
|
||||||
|
if (mgr)
|
||||||
|
IFCALL(mgr->DestroyListener, mgr, &rdpei->iface);
|
||||||
|
}
|
||||||
free(rdpei->listener_callback);
|
free(rdpei->listener_callback);
|
||||||
free(rdpei->context);
|
free(rdpei->context);
|
||||||
free(rdpei);
|
free(rdpei);
|
||||||
|
@ -1896,8 +1896,7 @@ static UINT rdpgfx_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelMana
|
|||||||
gfx->listener_callback->plugin = pPlugin;
|
gfx->listener_callback->plugin = pPlugin;
|
||||||
gfx->listener_callback->channel_mgr = pChannelMgr;
|
gfx->listener_callback->channel_mgr = pChannelMgr;
|
||||||
error = pChannelMgr->CreateListener(pChannelMgr, RDPGFX_DVC_CHANNEL_NAME, 0,
|
error = pChannelMgr->CreateListener(pChannelMgr, RDPGFX_DVC_CHANNEL_NAME, 0,
|
||||||
(IWTSListenerCallback*)gfx->listener_callback,
|
&gfx->listener_callback->iface, &(gfx->listener));
|
||||||
&(gfx->listener));
|
|
||||||
gfx->listener->pInterface = gfx->iface.pInterface;
|
gfx->listener->pInterface = gfx->iface.pInterface;
|
||||||
DEBUG_RDPGFX(gfx->log, "Initialize");
|
DEBUG_RDPGFX(gfx->log, "Initialize");
|
||||||
return error;
|
return error;
|
||||||
@ -1913,6 +1912,12 @@ static UINT rdpgfx_plugin_terminated(IWTSPlugin* pPlugin)
|
|||||||
RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*)pPlugin;
|
RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*)pPlugin;
|
||||||
RdpgfxClientContext* context = (RdpgfxClientContext*)gfx->iface.pInterface;
|
RdpgfxClientContext* context = (RdpgfxClientContext*)gfx->iface.pInterface;
|
||||||
DEBUG_RDPGFX(gfx->log, "Terminated");
|
DEBUG_RDPGFX(gfx->log, "Terminated");
|
||||||
|
if (gfx && gfx->listener_callback)
|
||||||
|
{
|
||||||
|
IWTSVirtualChannelManager* mgr = gfx->listener_callback->channel_mgr;
|
||||||
|
if (mgr)
|
||||||
|
IFCALL(mgr->DestroyListener, mgr, &gfx->iface);
|
||||||
|
}
|
||||||
rdpgfx_client_context_free(context);
|
rdpgfx_client_context_free(context);
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
@ -1541,8 +1541,7 @@ static UINT rdpsnd_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelMana
|
|||||||
rdpsnd->listener_callback->plugin = pPlugin;
|
rdpsnd->listener_callback->plugin = pPlugin;
|
||||||
rdpsnd->listener_callback->channel_mgr = pChannelMgr;
|
rdpsnd->listener_callback->channel_mgr = pChannelMgr;
|
||||||
status = pChannelMgr->CreateListener(pChannelMgr, RDPSND_DVC_CHANNEL_NAME, 0,
|
status = pChannelMgr->CreateListener(pChannelMgr, RDPSND_DVC_CHANNEL_NAME, 0,
|
||||||
(IWTSListenerCallback*)rdpsnd->listener_callback,
|
&rdpsnd->listener_callback->iface, &(rdpsnd->listener));
|
||||||
&(rdpsnd->listener));
|
|
||||||
rdpsnd->listener->pInterface = rdpsnd->iface.pInterface;
|
rdpsnd->listener->pInterface = rdpsnd->iface.pInterface;
|
||||||
return rdpsnd_virtual_channel_event_initialized(rdpsnd);
|
return rdpsnd_virtual_channel_event_initialized(rdpsnd);
|
||||||
}
|
}
|
||||||
@ -1557,6 +1556,12 @@ static UINT rdpsnd_plugin_terminated(IWTSPlugin* pPlugin)
|
|||||||
rdpsndPlugin* rdpsnd = (rdpsndPlugin*)pPlugin;
|
rdpsndPlugin* rdpsnd = (rdpsndPlugin*)pPlugin;
|
||||||
if (rdpsnd)
|
if (rdpsnd)
|
||||||
{
|
{
|
||||||
|
if (rdpsnd->listener_callback)
|
||||||
|
{
|
||||||
|
IWTSVirtualChannelManager* mgr = rdpsnd->listener_callback->channel_mgr;
|
||||||
|
if (mgr)
|
||||||
|
IFCALL(mgr->DestroyListener, mgr, &rdpsnd->iface);
|
||||||
|
}
|
||||||
free(rdpsnd->listener_callback);
|
free(rdpsnd->listener_callback);
|
||||||
free(rdpsnd->iface.pInterface);
|
free(rdpsnd->iface.pInterface);
|
||||||
}
|
}
|
||||||
|
@ -709,7 +709,12 @@ static UINT urbdrc_plugin_terminated(IWTSPlugin* pPlugin)
|
|||||||
|
|
||||||
if (!urbdrc)
|
if (!urbdrc)
|
||||||
return ERROR_INVALID_DATA;
|
return ERROR_INVALID_DATA;
|
||||||
|
if (urbdrc->listener_callback)
|
||||||
|
{
|
||||||
|
IWTSVirtualChannelManager* mgr = urbdrc->listener_callback->channel_mgr;
|
||||||
|
if (mgr)
|
||||||
|
IFCALL(mgr->DestroyListener, mgr, &urbdrc->iface);
|
||||||
|
}
|
||||||
udevman = urbdrc->udevman;
|
udevman = urbdrc->udevman;
|
||||||
|
|
||||||
if (udevman)
|
if (udevman)
|
||||||
|
@ -1048,7 +1048,7 @@ static UINT video_plugin_initialize(IWTSPlugin* plugin, IWTSVirtualChannelManage
|
|||||||
callback->channel_mgr = channelMgr;
|
callback->channel_mgr = channelMgr;
|
||||||
|
|
||||||
status = channelMgr->CreateListener(channelMgr, VIDEO_CONTROL_DVC_CHANNEL_NAME, 0,
|
status = channelMgr->CreateListener(channelMgr, VIDEO_CONTROL_DVC_CHANNEL_NAME, 0,
|
||||||
(IWTSListenerCallback*)callback, &(video->controlListener));
|
&callback->iface, &(video->controlListener));
|
||||||
|
|
||||||
if (status != CHANNEL_RC_OK)
|
if (status != CHANNEL_RC_OK)
|
||||||
return status;
|
return status;
|
||||||
@ -1067,7 +1067,7 @@ static UINT video_plugin_initialize(IWTSPlugin* plugin, IWTSVirtualChannelManage
|
|||||||
callback->channel_mgr = channelMgr;
|
callback->channel_mgr = channelMgr;
|
||||||
|
|
||||||
status = channelMgr->CreateListener(channelMgr, VIDEO_DATA_DVC_CHANNEL_NAME, 0,
|
status = channelMgr->CreateListener(channelMgr, VIDEO_DATA_DVC_CHANNEL_NAME, 0,
|
||||||
(IWTSListenerCallback*)callback, &(video->dataListener));
|
&callback->iface, &(video->dataListener));
|
||||||
|
|
||||||
if (status == CHANNEL_RC_OK)
|
if (status == CHANNEL_RC_OK)
|
||||||
video->dataListener->pInterface = video->wtsPlugin.pInterface;
|
video->dataListener->pInterface = video->wtsPlugin.pInterface;
|
||||||
@ -1084,6 +1084,19 @@ static UINT video_plugin_terminated(IWTSPlugin* pPlugin)
|
|||||||
{
|
{
|
||||||
VIDEO_PLUGIN* video = (VIDEO_PLUGIN*)pPlugin;
|
VIDEO_PLUGIN* video = (VIDEO_PLUGIN*)pPlugin;
|
||||||
|
|
||||||
|
if (video->control_callback)
|
||||||
|
{
|
||||||
|
IWTSVirtualChannelManager* mgr = video->control_callback->channel_mgr;
|
||||||
|
if (mgr)
|
||||||
|
IFCALL(mgr->DestroyListener, mgr, &video->control_callback->iface);
|
||||||
|
}
|
||||||
|
if (video->data_callback)
|
||||||
|
{
|
||||||
|
IWTSVirtualChannelManager* mgr = video->data_callback->channel_mgr;
|
||||||
|
if (mgr)
|
||||||
|
IFCALL(mgr->DestroyListener, mgr, &video->data_callback->iface);
|
||||||
|
}
|
||||||
|
|
||||||
if (video->context)
|
if (video->context)
|
||||||
VideoClientContextPriv_free(video->context->priv);
|
VideoClientContextPriv_free(video->context->priv);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user