From 75aab487e242f347868bd6c2ad5872d25a7c2c9a Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 10 Aug 2020 15:36:31 +0200 Subject: [PATCH] Added duplicate initialization check for plugins. --- channels/audin/client/audin_main.c | 17 ++++++++++++-- channels/audin/server/audin.c | 5 ++-- channels/disp/client/disp_main.c | 8 +++++++ channels/echo/client/echo_main.c | 16 ++++++++++--- channels/geometry/client/geometry_main.c | 8 +++++++ channels/rdpei/client/rdpei_main.c | 8 +++++++ channels/rdpgfx/client/rdpgfx_main.c | 7 ++++++ channels/rdpgfx/client/rdpgfx_main.h | 1 + channels/rdpsnd/client/rdpsnd_main.c | 11 ++++++++- channels/urbdrc/client/urbdrc_main.c | 11 +++++++-- channels/urbdrc/client/urbdrc_main.h | 1 + channels/video/client/video_main.c | 7 ++++++ include/freerdp/channels/audin.h | 2 ++ include/freerdp/channels/echo.h | 30 ++++++++++++++++++++++++ 14 files changed, 122 insertions(+), 10 deletions(-) create mode 100644 include/freerdp/channels/echo.h diff --git a/channels/audin/client/audin_main.c b/channels/audin/client/audin_main.c index 26ac48390..a5b941679 100644 --- a/channels/audin/client/audin_main.c +++ b/channels/audin/client/audin_main.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "audin_main.h" @@ -102,6 +103,8 @@ struct _AUDIN_PLUGIN wLog* log; IWTSListener* listener; + + BOOL initialized; }; static BOOL audin_process_addin_args(AUDIN_PLUGIN* audin, ADDIN_ARGV* args); @@ -668,6 +671,7 @@ static UINT audin_on_new_channel_connection(IWTSListenerCallback* pListenerCallb */ static UINT audin_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager* pChannelMgr) { + UINT rc; AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*)pPlugin; if (!audin) @@ -676,6 +680,12 @@ static UINT audin_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManag if (!pChannelMgr) return ERROR_INVALID_PARAMETER; + if (audin->initialized) + { + WLog_ERR(TAG, "[%s] channel initialized twice, aborting", AUDIN_DVC_CHANNEL_NAME); + return ERROR_INVALID_DATA; + } + WLog_Print(audin->log, WLOG_TRACE, "..."); audin->listener_callback = (AUDIN_LISTENER_CALLBACK*)calloc(1, sizeof(AUDIN_LISTENER_CALLBACK)); @@ -688,8 +698,11 @@ static UINT audin_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManag audin->listener_callback->iface.OnNewChannelConnection = audin_on_new_channel_connection; audin->listener_callback->plugin = pPlugin; audin->listener_callback->channel_mgr = pChannelMgr; - return pChannelMgr->CreateListener(pChannelMgr, "AUDIO_INPUT", 0, - &audin->listener_callback->iface, &audin->listener); + rc = pChannelMgr->CreateListener(pChannelMgr, AUDIN_DVC_CHANNEL_NAME, 0, + &audin->listener_callback->iface, &audin->listener); + + audin->initialized = rc == CHANNEL_RC_OK; + return rc; } /** diff --git a/channels/audin/server/audin.c b/channels/audin/server/audin.c index aa1979ce5..e5c51bbf2 100644 --- a/channels/audin/server/audin.c +++ b/channels/audin/server/audin.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -567,8 +568,8 @@ static BOOL audin_server_open(audin_server_context* context) WTSFreeMemory(pSessionId); } - audin->audin_channel = - WTSVirtualChannelOpenEx(audin->SessionId, "AUDIO_INPUT", WTS_CHANNEL_OPTION_DYNAMIC); + audin->audin_channel = WTSVirtualChannelOpenEx(audin->SessionId, AUDIN_DVC_CHANNEL_NAME, + WTS_CHANNEL_OPTION_DYNAMIC); if (!audin->audin_channel) { diff --git a/channels/disp/client/disp_main.c b/channels/disp/client/disp_main.c index fa92c252a..d718958a1 100644 --- a/channels/disp/client/disp_main.c +++ b/channels/disp/client/disp_main.c @@ -72,6 +72,7 @@ struct _DISP_PLUGIN UINT32 MaxNumMonitors; UINT32 MaxMonitorAreaFactorA; UINT32 MaxMonitorAreaFactorB; + BOOL initialized; }; typedef struct _DISP_PLUGIN DISP_PLUGIN; @@ -296,6 +297,11 @@ static UINT disp_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManage { UINT status; DISP_PLUGIN* disp = (DISP_PLUGIN*)pPlugin; + if (disp->initialized) + { + WLog_ERR(TAG, "[%s] channel initialized twice, aborting", DISP_DVC_CHANNEL_NAME); + return ERROR_INVALID_DATA; + } disp->listener_callback = (DISP_LISTENER_CALLBACK*)calloc(1, sizeof(DISP_LISTENER_CALLBACK)); if (!disp->listener_callback) @@ -310,6 +316,8 @@ static UINT disp_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManage status = pChannelMgr->CreateListener(pChannelMgr, DISP_DVC_CHANNEL_NAME, 0, &disp->listener_callback->iface, &(disp->listener)); disp->listener->pInterface = disp->iface.pInterface; + + disp->initialized = status == CHANNEL_RC_OK; return status; } diff --git a/channels/echo/client/echo_main.c b/channels/echo/client/echo_main.c index c8dc4d8a5..714294033 100644 --- a/channels/echo/client/echo_main.c +++ b/channels/echo/client/echo_main.c @@ -31,6 +31,7 @@ #include "echo_main.h" #include +#include #define TAG CHANNELS_TAG("echo.client") @@ -60,6 +61,7 @@ struct _ECHO_PLUGIN ECHO_LISTENER_CALLBACK* listener_callback; IWTSListener* listener; + BOOL initialized; }; /** @@ -129,8 +131,13 @@ static UINT echo_on_new_channel_connection(IWTSListenerCallback* pListenerCallba */ static UINT echo_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager* pChannelMgr) { + UINT status; ECHO_PLUGIN* echo = (ECHO_PLUGIN*)pPlugin; - + if (echo->initialized) + { + WLog_ERR(TAG, "[%s] channel initialized twice, aborting", ECHO_DVC_CHANNEL_NAME); + return ERROR_INVALID_DATA; + } echo->listener_callback = (ECHO_LISTENER_CALLBACK*)calloc(1, sizeof(ECHO_LISTENER_CALLBACK)); if (!echo->listener_callback) @@ -143,8 +150,11 @@ static UINT echo_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManage echo->listener_callback->plugin = pPlugin; echo->listener_callback->channel_mgr = pChannelMgr; - return pChannelMgr->CreateListener(pChannelMgr, "ECHO", 0, &echo->listener_callback->iface, - &echo->listener); + status = pChannelMgr->CreateListener(pChannelMgr, ECHO_DVC_CHANNEL_NAME, 0, + &echo->listener_callback->iface, &echo->listener); + + echo->initialized = status == CHANNEL_RC_OK; + return status; } /** diff --git a/channels/geometry/client/geometry_main.c b/channels/geometry/client/geometry_main.c index cb5e2ae40..12588067f 100644 --- a/channels/geometry/client/geometry_main.c +++ b/channels/geometry/client/geometry_main.c @@ -68,6 +68,7 @@ struct _GEOMETRY_PLUGIN GEOMETRY_LISTENER_CALLBACK* listener_callback; GeometryClientContext* context; + BOOL initialized; }; typedef struct _GEOMETRY_PLUGIN GEOMETRY_PLUGIN; @@ -380,6 +381,11 @@ static UINT geometry_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelMa { UINT status; GEOMETRY_PLUGIN* geometry = (GEOMETRY_PLUGIN*)pPlugin; + if (geometry->initialized) + { + WLog_ERR(TAG, "[%s] channel initialized twice, aborting", GEOMETRY_DVC_CHANNEL_NAME); + return ERROR_INVALID_DATA; + } geometry->listener_callback = (GEOMETRY_LISTENER_CALLBACK*)calloc(1, sizeof(GEOMETRY_LISTENER_CALLBACK)); @@ -396,6 +402,8 @@ static UINT geometry_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelMa pChannelMgr->CreateListener(pChannelMgr, GEOMETRY_DVC_CHANNEL_NAME, 0, &geometry->listener_callback->iface, &(geometry->listener)); geometry->listener->pInterface = geometry->iface.pInterface; + + geometry->initialized = status == CHANNEL_RC_OK; return status; } diff --git a/channels/rdpei/client/rdpei_main.c b/channels/rdpei/client/rdpei_main.c index 7da9ae73b..0134c6043 100644 --- a/channels/rdpei/client/rdpei_main.c +++ b/channels/rdpei/client/rdpei_main.c @@ -102,6 +102,7 @@ struct _RDPEI_PLUGIN RDPINPUT_CONTACT_POINT* contactPoints; rdpContext* rdpcontext; + BOOL initialized; }; typedef struct _RDPEI_PLUGIN RDPEI_PLUGIN; @@ -558,6 +559,12 @@ static UINT rdpei_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManag { UINT error; RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*)pPlugin; + + if (rdpei->initialized) + { + WLog_ERR(TAG, "[%s] channel initialized twice, aborting", RDPEI_DVC_CHANNEL_NAME); + return ERROR_INVALID_DATA; + } rdpei->listener_callback = (RDPEI_LISTENER_CALLBACK*)calloc(1, sizeof(RDPEI_LISTENER_CALLBACK)); if (!rdpei->listener_callback) @@ -579,6 +586,7 @@ static UINT rdpei_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManag rdpei->listener->pInterface = rdpei->iface.pInterface; + rdpei->initialized = TRUE; return error; error_out: free(rdpei->listener_callback); diff --git a/channels/rdpgfx/client/rdpgfx_main.c b/channels/rdpgfx/client/rdpgfx_main.c index 6ca75bd1d..94b5b68de 100644 --- a/channels/rdpgfx/client/rdpgfx_main.c +++ b/channels/rdpgfx/client/rdpgfx_main.c @@ -1878,6 +1878,11 @@ static UINT rdpgfx_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelMana { UINT error; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*)pPlugin; + if (gfx->initialized) + { + WLog_ERR(TAG, "[%s] channel initialized twice, aborting", RDPGFX_DVC_CHANNEL_NAME); + return ERROR_INVALID_DATA; + } gfx->listener_callback = (RDPGFX_LISTENER_CALLBACK*)calloc(1, sizeof(RDPGFX_LISTENER_CALLBACK)); if (!gfx->listener_callback) @@ -1893,6 +1898,8 @@ static UINT rdpgfx_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelMana &gfx->listener_callback->iface, &(gfx->listener)); gfx->listener->pInterface = gfx->iface.pInterface; DEBUG_RDPGFX(gfx->log, "Initialize"); + + gfx->initialized = error == CHANNEL_RC_OK; return error; } diff --git a/channels/rdpgfx/client/rdpgfx_main.h b/channels/rdpgfx/client/rdpgfx_main.h index 362f4099d..760d1be56 100644 --- a/channels/rdpgfx/client/rdpgfx_main.h +++ b/channels/rdpgfx/client/rdpgfx_main.h @@ -85,6 +85,7 @@ struct _RDPGFX_PLUGIN wLog* log; RDPGFX_CAPSET ConnectionCaps; BOOL SendQoeAck; + BOOL initialized; }; typedef struct _RDPGFX_PLUGIN RDPGFX_PLUGIN; diff --git a/channels/rdpsnd/client/rdpsnd_main.c b/channels/rdpsnd/client/rdpsnd_main.c index 9318c95c6..43bbbc5b2 100644 --- a/channels/rdpsnd/client/rdpsnd_main.c +++ b/channels/rdpsnd/client/rdpsnd_main.c @@ -125,6 +125,7 @@ struct rdpsnd_plugin HANDLE thread; wMessageQueue* queue; + BOOL initialized; }; static const char* rdpsnd_is_dyn_str(BOOL dynamic) @@ -1528,6 +1529,11 @@ static UINT rdpsnd_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelMana { UINT status; rdpsndPlugin* rdpsnd = (rdpsndPlugin*)pPlugin; + if (rdpsnd->initialized) + { + WLog_ERR(TAG, "[%s] channel initialized twice, aborting", RDPSND_DVC_CHANNEL_NAME); + return ERROR_INVALID_DATA; + } rdpsnd->listener_callback = (RDPSND_LISTENER_CALLBACK*)calloc(1, sizeof(RDPSND_LISTENER_CALLBACK)); @@ -1543,7 +1549,10 @@ static UINT rdpsnd_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelMana status = pChannelMgr->CreateListener(pChannelMgr, RDPSND_DVC_CHANNEL_NAME, 0, &rdpsnd->listener_callback->iface, &(rdpsnd->listener)); rdpsnd->listener->pInterface = rdpsnd->iface.pInterface; - return rdpsnd_virtual_channel_event_initialized(rdpsnd); + status = rdpsnd_virtual_channel_event_initialized(rdpsnd); + + rdpsnd->initialized = status == CHANNEL_RC_OK; + return status; } /** diff --git a/channels/urbdrc/client/urbdrc_main.c b/channels/urbdrc/client/urbdrc_main.c index 2ed6a6f2e..dd2bbe506 100644 --- a/channels/urbdrc/client/urbdrc_main.c +++ b/channels/urbdrc/client/urbdrc_main.c @@ -673,6 +673,11 @@ static UINT urbdrc_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelMana if (!urbdrc || !urbdrc->udevman) return ERROR_INVALID_PARAMETER; + if (urbdrc->initialized) + { + WLog_ERR(TAG, "[%s] channel initialized twice, aborting", URBDRC_CHANNEL_NAME); + return ERROR_INVALID_DATA; + } udevman = urbdrc->udevman; urbdrc->listener_callback = (URBDRC_LISTENER_CALLBACK*)calloc(1, sizeof(URBDRC_LISTENER_CALLBACK)); @@ -691,10 +696,12 @@ static UINT urbdrc_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelMana if (status != CHANNEL_RC_OK) return status; + status = CHANNEL_RC_OK; if (udevman->listener_created_callback) - return udevman->listener_created_callback(udevman); + status = udevman->listener_created_callback(udevman); - return CHANNEL_RC_OK; + urbdrc->initialized = status == CHANNEL_RC_OK; + return status; } /** diff --git a/channels/urbdrc/client/urbdrc_main.h b/channels/urbdrc/client/urbdrc_main.h index 2b643f7cb..e832dd98e 100644 --- a/channels/urbdrc/client/urbdrc_main.h +++ b/channels/urbdrc/client/urbdrc_main.h @@ -85,6 +85,7 @@ struct _URBDRC_PLUGIN wLog* log; IWTSListener* listener; + BOOL initialized; }; typedef BOOL (*PREGISTERURBDRCSERVICE)(IWTSPlugin* plugin, IUDEVMAN* udevman); diff --git a/channels/video/client/video_main.c b/channels/video/client/video_main.c index 9a68d92d3..10fb30d1a 100644 --- a/channels/video/client/video_main.c +++ b/channels/video/client/video_main.c @@ -76,6 +76,7 @@ struct _VIDEO_PLUGIN VIDEO_LISTENER_CALLBACK* data_callback; VideoClientContext* context; + BOOL initialized; }; typedef struct _VIDEO_PLUGIN VIDEO_PLUGIN; @@ -1035,6 +1036,11 @@ static UINT video_plugin_initialize(IWTSPlugin* plugin, IWTSVirtualChannelManage VIDEO_PLUGIN* video = (VIDEO_PLUGIN*)plugin; VIDEO_LISTENER_CALLBACK* callback; + if (video->initialized) + { + WLog_ERR(TAG, "[%s] channel initialized twice, aborting", VIDEO_CONTROL_DVC_CHANNEL_NAME); + return ERROR_INVALID_DATA; + } video->control_callback = callback = (VIDEO_LISTENER_CALLBACK*)calloc(1, sizeof(VIDEO_LISTENER_CALLBACK)); if (!callback) @@ -1072,6 +1078,7 @@ static UINT video_plugin_initialize(IWTSPlugin* plugin, IWTSVirtualChannelManage if (status == CHANNEL_RC_OK) video->dataListener->pInterface = video->wtsPlugin.pInterface; + video->initialized = status == CHANNEL_RC_OK; return status; } diff --git a/include/freerdp/channels/audin.h b/include/freerdp/channels/audin.h index e7a6a093c..ebc27f1d1 100644 --- a/include/freerdp/channels/audin.h +++ b/include/freerdp/channels/audin.h @@ -24,4 +24,6 @@ #include #include +#define AUDIN_DVC_CHANNEL_NAME "AUDIO_INPUT" + #endif /* FREERDP_CHANNEL_AUDIN_H */ diff --git a/include/freerdp/channels/echo.h b/include/freerdp/channels/echo.h new file mode 100644 index 000000000..47e78f299 --- /dev/null +++ b/include/freerdp/channels/echo.h @@ -0,0 +1,30 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Audio Input Redirection Virtual Channel + * + * Copyright 2020 Armin Novak + * Copyright 2020 Thincast Technologies GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_CHANNEL_ECHO_H +#define FREERDP_CHANNEL_ECHO_H + +#include +#include +#include + +#define ECHO_DVC_CHANNEL_NAME "ECHO" + +#endif /* FREERDP_CHANNEL_ECHO_H */