Added duplicate initialization check for plugins.
authorArmin Novak <armin.novak@thincast.com>
Mon, 10 Aug 2020 13:36:31 +0000 (15:36 +0200)
committerakallabeth <akallabeth@users.noreply.github.com>
Tue, 1 Dec 2020 14:10:23 +0000 (15:10 +0100)
(cherry picked from commit 75aab487e242f347868bd6c2ad5872d25a7c2c9a)

14 files changed:
channels/audin/client/audin_main.c
channels/audin/server/audin.c
channels/disp/client/disp_main.c
channels/echo/client/echo_main.c
channels/geometry/client/geometry_main.c
channels/rdpei/client/rdpei_main.c
channels/rdpgfx/client/rdpgfx_main.c
channels/rdpgfx/client/rdpgfx_main.h
channels/rdpsnd/client/rdpsnd_main.c
channels/urbdrc/client/urbdrc_main.c
channels/urbdrc/client/urbdrc_main.h
channels/video/client/video_main.c
include/freerdp/channels/audin.h
include/freerdp/channels/echo.h [new file with mode: 0644]

index 26ac483..a5b9416 100644 (file)
@@ -39,6 +39,7 @@
 #include <winpr/stream.h>
 #include <freerdp/freerdp.h>
 #include <freerdp/codec/dsp.h>
+#include <freerdp/channels/audin.h>
 
 #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;
 }
 
 /**
index aa1979c..e5c51bb 100644 (file)
@@ -35,6 +35,7 @@
 #include <freerdp/codec/dsp.h>
 #include <freerdp/codec/audio.h>
 #include <freerdp/channels/wtsvc.h>
+#include <freerdp/channels/audin.h>
 #include <freerdp/server/audin.h>
 #include <freerdp/channels/log.h>
 
@@ -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)
                {
index fa92c25..d718958 100644 (file)
@@ -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;
 }
 
index c8dc4d8..7142940 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "echo_main.h"
 #include <freerdp/channels/log.h>
+#include <freerdp/channels/echo.h>
 
 #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;
 }
 
 /**
index cb5e2ae..1258806 100644 (file)
@@ -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;
 }
 
index 7da9ae7..0134c60 100644 (file)
@@ -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);
index 6ca75bd..94b5b68 100644 (file)
@@ -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;
 }
 
index 362f409..760d1be 100644 (file)
@@ -85,6 +85,7 @@ struct _RDPGFX_PLUGIN
        wLog* log;
        RDPGFX_CAPSET ConnectionCaps;
        BOOL SendQoeAck;
+       BOOL initialized;
 };
 typedef struct _RDPGFX_PLUGIN RDPGFX_PLUGIN;
 
index 9318c95..43bbbc5 100644 (file)
@@ -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;
 }
 
 /**
index 2ed6a6f..dd2bbe5 100644 (file)
@@ -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;
 }
 
 /**
index 2b643f7..e832dd9 100644 (file)
@@ -85,6 +85,7 @@ struct _URBDRC_PLUGIN
 
        wLog* log;
        IWTSListener* listener;
+       BOOL initialized;
 };
 
 typedef BOOL (*PREGISTERURBDRCSERVICE)(IWTSPlugin* plugin, IUDEVMAN* udevman);
index 9a68d92..10fb30d 100644 (file)
@@ -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;
 }
 
index e7a6a09..ebc27f1 100644 (file)
@@ -24,4 +24,6 @@
 #include <freerdp/dvc.h>
 #include <freerdp/types.h>
 
+#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 (file)
index 0000000..47e78f2
--- /dev/null
@@ -0,0 +1,30 @@
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * Audio Input Redirection Virtual Channel
+ *
+ * Copyright 2020 Armin Novak <anovak@thincast.com>
+ * 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 <freerdp/api.h>
+#include <freerdp/dvc.h>
+#include <freerdp/types.h>
+
+#define ECHO_DVC_CHANNEL_NAME "ECHO"
+
+#endif /* FREERDP_CHANNEL_ECHO_H */