#include <winpr/stream.h>
#include <freerdp/freerdp.h>
#include <freerdp/codec/dsp.h>
+#include <freerdp/channels/audin.h>
#include "audin_main.h"
wLog* log;
IWTSListener* listener;
+
+ BOOL initialized;
};
static BOOL audin_process_addin_args(AUDIN_PLUGIN* audin, ADDIN_ARGV* args);
*/
static UINT audin_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager* pChannelMgr)
{
+ UINT rc;
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*)pPlugin;
if (!audin)
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));
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;
}
/**
#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>
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)
{
UINT32 MaxNumMonitors;
UINT32 MaxMonitorAreaFactorA;
UINT32 MaxMonitorAreaFactorB;
+ BOOL initialized;
};
typedef struct _DISP_PLUGIN DISP_PLUGIN;
{
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)
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;
}
#include "echo_main.h"
#include <freerdp/channels/log.h>
+#include <freerdp/channels/echo.h>
#define TAG CHANNELS_TAG("echo.client")
ECHO_LISTENER_CALLBACK* listener_callback;
IWTSListener* listener;
+ BOOL initialized;
};
/**
*/
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)
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;
}
/**
GEOMETRY_LISTENER_CALLBACK* listener_callback;
GeometryClientContext* context;
+ BOOL initialized;
};
typedef struct _GEOMETRY_PLUGIN GEOMETRY_PLUGIN;
{
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));
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;
}
RDPINPUT_CONTACT_POINT* contactPoints;
rdpContext* rdpcontext;
+ BOOL initialized;
};
typedef struct _RDPEI_PLUGIN RDPEI_PLUGIN;
{
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)
rdpei->listener->pInterface = rdpei->iface.pInterface;
+ rdpei->initialized = TRUE;
return error;
error_out:
free(rdpei->listener_callback);
{
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)
&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;
}
wLog* log;
RDPGFX_CAPSET ConnectionCaps;
BOOL SendQoeAck;
+ BOOL initialized;
};
typedef struct _RDPGFX_PLUGIN RDPGFX_PLUGIN;
HANDLE thread;
wMessageQueue* queue;
+ BOOL initialized;
};
static const char* rdpsnd_is_dyn_str(BOOL dynamic)
{
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));
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;
}
/**
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));
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;
}
/**
wLog* log;
IWTSListener* listener;
+ BOOL initialized;
};
typedef BOOL (*PREGISTERURBDRCSERVICE)(IWTSPlugin* plugin, IUDEVMAN* udevman);
VIDEO_LISTENER_CALLBACK* data_callback;
VideoClientContext* context;
+ BOOL initialized;
};
typedef struct _VIDEO_PLUGIN VIDEO_PLUGIN;
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)
if (status == CHANNEL_RC_OK)
video->dataListener->pInterface = video->wtsPlugin.pInterface;
+ video->initialized = status == CHANNEL_RC_OK;
return status;
}
#include <freerdp/dvc.h>
#include <freerdp/types.h>
+#define AUDIN_DVC_CHANNEL_NAME "AUDIO_INPUT"
+
#endif /* FREERDP_CHANNEL_AUDIN_H */
--- /dev/null
+/**
+ * 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 */