Skip to content

Commit

Permalink
Added attach/detach support for channels.
Browse files Browse the repository at this point in the history
  • Loading branch information
akallabeth committed Dec 19, 2016
1 parent 8d0809c commit 9f19da7
Show file tree
Hide file tree
Showing 12 changed files with 447 additions and 148 deletions.
164 changes: 91 additions & 73 deletions channels/audin/client/audin_main.c

Large diffs are not rendered by default.

78 changes: 76 additions & 2 deletions channels/drdynvc/client/drdynvc_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,8 @@ static UINT drdynvc_send(drdynvcPlugin* drdynvc, wStream* s)
if (status != CHANNEL_RC_OK)
{
Stream_Free(s, TRUE);
WLog_ERR(TAG, "VirtualChannelWriteEx failed with %s [%08"PRIX32"]", WTSErrorToString(status), status);
WLog_ERR(TAG, "VirtualChannelWriteEx failed with %s [%08"PRIX32"]", WTSErrorToString(status),
status);
}

return status;
Expand Down Expand Up @@ -1073,7 +1074,7 @@ static UINT drdynvc_order_recv(drdynvcPlugin* drdynvc, wStream* s)
Cmd = (value & 0xf0) >> 4;
Sp = (value & 0x0c) >> 2;
cbChId = (value & 0x03) >> 0;
WLog_DBG(TAG, "order_recv: Cmd=0x%x, Sp=%d cbChId=%d", Cmd, Sp,cbChId);
WLog_DBG(TAG, "order_recv: Cmd=0x%x, Sp=%d cbChId=%d", Cmd, Sp, cbChId);

switch (Cmd)
{
Expand Down Expand Up @@ -1379,6 +1380,64 @@ static UINT drdynvc_virtual_channel_event_terminated(drdynvcPlugin* drdynvc)
return CHANNEL_RC_OK;
}

static UINT drdynvc_virtual_channel_event_attached(drdynvcPlugin* drdynvc)
{
int i;
DVCMAN* dvcman;

if (!drdynvc)
return CHANNEL_RC_BAD_CHANNEL_HANDLE;

dvcman = (DVCMAN*) drdynvc->channel_mgr;

if (!dvcman)
return CHANNEL_RC_BAD_CHANNEL_HANDLE;

for (i = 0; i < dvcman->num_plugins; i++)
{
UINT error;
IWTSPlugin* pPlugin = dvcman->plugins[i];

if (pPlugin->Attached)
if ((error = pPlugin->Attached(pPlugin)))
{
WLog_ERR(TAG, "Attach failed with error %"PRIu32"!", error);
return error;
}
}

return CHANNEL_RC_OK;
}

static UINT drdynvc_virtual_channel_event_detached(drdynvcPlugin* drdynvc)
{
int i;
DVCMAN* dvcman;

if (!drdynvc)
return CHANNEL_RC_BAD_CHANNEL_HANDLE;

dvcman = (DVCMAN*) drdynvc->channel_mgr;

if (!dvcman)
return CHANNEL_RC_BAD_CHANNEL_HANDLE;

for (i = 0; i < dvcman->num_plugins; i++)
{
UINT error;
IWTSPlugin* pPlugin = dvcman->plugins[i];

if (pPlugin->Detached)
if ((error = pPlugin->Detached(pPlugin)))
{
WLog_ERR(TAG, "Detach failed with error %"PRIu32"!", error);
return error;
}
}

return CHANNEL_RC_OK;
}

static VOID VCAPITYPE drdynvc_virtual_channel_init_event_ex(LPVOID lpUserParam, LPVOID pInitHandle,
UINT event, LPVOID pData, UINT dataLength)
{
Expand Down Expand Up @@ -1410,6 +1469,21 @@ static VOID VCAPITYPE drdynvc_virtual_channel_init_event_ex(LPVOID lpUserParam,
WLog_ERR(TAG, "drdynvc_virtual_channel_event_terminated failed with error %"PRIu32"", error);

break;

case CHANNEL_EVENT_ATTACHED:
if ((error = drdynvc_virtual_channel_event_attached(drdynvc)))
WLog_ERR(TAG, "drdynvc_virtual_channel_event_attached failed with error %"PRIu32"", error);

break;

case CHANNEL_EVENT_DETACHED:
if ((error = drdynvc_virtual_channel_event_detached(drdynvc)))
WLog_ERR(TAG, "drdynvc_virtual_channel_event_detached failed with error %"PRIu32"", error);

break;

default:
break;
}

if (error && drdynvc->rdpcontext)
Expand Down
5 changes: 5 additions & 0 deletions channels/rail/client/rail_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,11 @@ static VOID VCAPITYPE rail_virtual_channel_init_event_ex(LPVOID lpUserParam, LPV
case CHANNEL_EVENT_TERMINATED:
rail_virtual_channel_event_terminated(rail);
break;

case CHANNEL_EVENT_ATTACHED:
case CHANNEL_EVENT_DETACHED:
default:
break;
}

if (error && rail->rdpcontext)
Expand Down
3 changes: 2 additions & 1 deletion channels/rdpdr/client/rdpdr_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1738,9 +1738,10 @@ static VOID VCAPITYPE rdpdr_virtual_channel_init_event_ex(LPVOID lpUserParam, LP
rdpdr_virtual_channel_event_terminated(rdpdr);
break;

case CHANNEL_EVENT_ATTACHED:
case CHANNEL_EVENT_DETACHED:
default:
WLog_ERR(TAG, "unknown event %"PRIu32"!", event);
error = ERROR_INVALID_DATA;
break;
}

Expand Down
19 changes: 17 additions & 2 deletions channels/rdpsnd/client/rdpsnd_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ struct rdpsnd_plugin
AUDIO_FORMAT* ClientFormats;
UINT16 NumberOfClientFormats;

BOOL attached;

BOOL expectingWave;
BYTE waveData[4];
UINT16 waveDataSize;
Expand Down Expand Up @@ -741,6 +743,9 @@ static UINT rdpsnd_recv_pdu(rdpsndPlugin* rdpsnd, wStream* s)
Stream_Seek_UINT8(s); /* bPad */
Stream_Read_UINT16(s, BodySize);

if (!rdpsnd->attached)
goto out;

//WLog_ERR(TAG, "msgType %"PRIu8" BodySize %"PRIu16"", msgType, BodySize);

switch (msgType)
Expand Down Expand Up @@ -1445,6 +1450,17 @@ static VOID VCAPITYPE rdpsnd_virtual_channel_init_event_ex(LPVOID lpUserParam, L
rdpsnd_virtual_channel_event_terminated(plugin);
plugin = NULL;
break;

case CHANNEL_EVENT_ATTACHED:
plugin->attached = TRUE;
break;

case CHANNEL_EVENT_DETACHED:
plugin->attached = FALSE;
break;

default:
break;
}

if (error && plugin && plugin->rdpcontext)
Expand Down Expand Up @@ -1474,6 +1490,7 @@ BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID p
return FALSE;
}

rdpsnd->attached = TRUE;
#if !defined(_WIN32) && !defined(ANDROID)
{
sigset_t mask;
Expand All @@ -1497,9 +1514,7 @@ BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID p
rdpsnd->log = WLog_Get("com.freerdp.channels.rdpsnd.client");
CopyMemory(&(rdpsnd->channelEntryPoints), pEntryPoints,
sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX));

rdpsnd->InitHandle = pInitHandle;

rc = rdpsnd->channelEntryPoints.pVirtualChannelInitEx(rdpsnd, NULL, pInitHandle,
&rdpsnd->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000,
rdpsnd_virtual_channel_init_event_ex);
Expand Down
5 changes: 5 additions & 0 deletions channels/remdesk/client/remdesk_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1015,6 +1015,11 @@ static VOID VCAPITYPE remdesk_virtual_channel_init_event_ex(LPVOID lpUserParam,
case CHANNEL_EVENT_TERMINATED:
remdesk_virtual_channel_event_terminated(remdesk);
break;

case CHANNEL_EVENT_ATTACHED:
case CHANNEL_EVENT_DETACHED:
default:
break;
}

if (error && remdesk->rdpcontext)
Expand Down
12 changes: 10 additions & 2 deletions include/freerdp/client/drdynvc.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,14 @@
typedef struct _drdynvc_client_context DrdynvcClientContext;

typedef int (*pcDrdynvcGetVersion)(DrdynvcClientContext* context);
typedef UINT (*pcDrdynvcOnChannelConnected)(DrdynvcClientContext* context, const char* name, void* pInterface);
typedef UINT (*pcDrdynvcOnChannelDisconnected)(DrdynvcClientContext* context, const char* name, void* pInterface);
typedef UINT(*pcDrdynvcOnChannelConnected)(DrdynvcClientContext* context, const char* name,
void* pInterface);
typedef UINT(*pcDrdynvcOnChannelDisconnected)(DrdynvcClientContext* context, const char* name,
void* pInterface);
typedef UINT(*pcDrdynvcOnChannelAttached)(DrdynvcClientContext* context, const char* name,
void* pInterface);
typedef UINT(*pcDrdynvcOnChannelDetached)(DrdynvcClientContext* context, const char* name,
void* pInterface);

struct _drdynvc_client_context
{
Expand All @@ -40,6 +46,8 @@ struct _drdynvc_client_context
pcDrdynvcGetVersion GetVersion;
pcDrdynvcOnChannelConnected OnChannelConnected;
pcDrdynvcOnChannelDisconnected OnChannelDisconnected;
pcDrdynvcOnChannelAttached OnChannelAttached;
pcDrdynvcOnChannelDetached OnChannelDetached;
};

#endif /* FREERDP_CHANNEL_CLIENT_DRDYNVC_H */
82 changes: 43 additions & 39 deletions include/freerdp/dvc.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,97 +67,101 @@ typedef struct _IWTSVirtualChannelCallback IWTSVirtualChannelCallback;
struct _IWTSListener
{
/* Retrieves the listener-specific configuration. */
UINT (*GetConfiguration)(IWTSListener *pListener,
void **ppPropertyBag);
UINT(*GetConfiguration)(IWTSListener* pListener,
void** ppPropertyBag);

void *pInterface;
void* pInterface;
};

struct _IWTSVirtualChannel
{
/* Starts a write request on the channel. */
UINT (*Write)(IWTSVirtualChannel *pChannel,
ULONG cbSize,
const BYTE *pBuffer,
void *pReserved);
UINT(*Write)(IWTSVirtualChannel* pChannel,
ULONG cbSize,
const BYTE* pBuffer,
void* pReserved);
/* Closes the channel. */
UINT (*Close)(IWTSVirtualChannel *pChannel);
UINT(*Close)(IWTSVirtualChannel* pChannel);
};

struct _IWTSVirtualChannelManager
{
/* Returns an instance of a listener object that listens on a specific
endpoint, or creates a static channel. */
UINT (*CreateListener)(IWTSVirtualChannelManager *pChannelMgr,
const char *pszChannelName,
ULONG ulFlags,
IWTSListenerCallback *pListenerCallback,
IWTSListener **ppListener);
UINT(*CreateListener)(IWTSVirtualChannelManager* pChannelMgr,
const char* pszChannelName,
ULONG ulFlags,
IWTSListenerCallback* pListenerCallback,
IWTSListener** ppListener);
/* Find the channel or ID to send data to a specific endpoint. */
UINT32(*GetChannelId)(IWTSVirtualChannel *channel);
IWTSVirtualChannel *(*FindChannelById)(IWTSVirtualChannelManager *pChannelMgr,
UINT32 ChannelId);
UINT32(*GetChannelId)(IWTSVirtualChannel* channel);
IWTSVirtualChannel* (*FindChannelById)(IWTSVirtualChannelManager* pChannelMgr,
UINT32 ChannelId);
};

struct _IWTSPlugin
{
/* Used for the first call that is made from the client to the plug-in. */
UINT (*Initialize)(IWTSPlugin *pPlugin,
IWTSVirtualChannelManager *pChannelMgr);
UINT(*Initialize)(IWTSPlugin* pPlugin,
IWTSVirtualChannelManager* pChannelMgr);
/* Notifies the plug-in that the Remote Desktop Connection (RDC) client
has successfully connected to the Remote Desktop Session Host (RD
Session Host) server. */
UINT (*Connected)(IWTSPlugin *pPlugin);
UINT(*Connected)(IWTSPlugin* pPlugin);
/* Notifies the plug-in that the Remote Desktop Connection (RDC) client
has disconnected from the RD Session Host server. */
UINT (*Disconnected)(IWTSPlugin *pPlugin,
DWORD dwDisconnectCode);
UINT(*Disconnected)(IWTSPlugin* pPlugin,
DWORD dwDisconnectCode);
/* Notifies the plug-in that the Remote Desktop Connection (RDC) client
has terminated. */
UINT (*Terminated)(IWTSPlugin *pPlugin);
UINT(*Terminated)(IWTSPlugin* pPlugin);

UINT(*Attached)(IWTSPlugin* pPlugin);

UINT(*Detached)(IWTSPlugin* pPlugin);

/* Extended */

void *pInterface;
void* pInterface;
};

struct _IWTSListenerCallback
{
/* Accepts or denies a connection request for an incoming connection to
the associated listener. */
UINT (*OnNewChannelConnection)(IWTSListenerCallback *pListenerCallback,
IWTSVirtualChannel *pChannel,
BYTE *Data,
BOOL *pbAccept,
IWTSVirtualChannelCallback **ppCallback);
UINT(*OnNewChannelConnection)(IWTSListenerCallback* pListenerCallback,
IWTSVirtualChannel* pChannel,
BYTE* Data,
BOOL* pbAccept,
IWTSVirtualChannelCallback** ppCallback);
};

struct _IWTSVirtualChannelCallback
{
/* Notifies the user about data that is being received. */
UINT (*OnDataReceived) (IWTSVirtualChannelCallback* pChannelCallback, wStream* data);
UINT(*OnDataReceived)(IWTSVirtualChannelCallback* pChannelCallback, wStream* data);
/* Notifies the user that the channel has been opened. */
UINT (*OnOpen) (IWTSVirtualChannelCallback* pChannelCallback);
UINT(*OnOpen)(IWTSVirtualChannelCallback* pChannelCallback);
/* Notifies the user that the channel has been closed. */
UINT (*OnClose) (IWTSVirtualChannelCallback* pChannelCallback);
UINT(*OnClose)(IWTSVirtualChannelCallback* pChannelCallback);
};

/* The DVC Plugin entry points */
typedef struct _IDRDYNVC_ENTRY_POINTS IDRDYNVC_ENTRY_POINTS;
struct _IDRDYNVC_ENTRY_POINTS
{
UINT (*RegisterPlugin)(IDRDYNVC_ENTRY_POINTS *pEntryPoints,
const char *name, IWTSPlugin *pPlugin);
IWTSPlugin *(*GetPlugin)(IDRDYNVC_ENTRY_POINTS *pEntryPoints,
const char *name);
UINT(*RegisterPlugin)(IDRDYNVC_ENTRY_POINTS* pEntryPoints,
const char* name, IWTSPlugin* pPlugin);
IWTSPlugin* (*GetPlugin)(IDRDYNVC_ENTRY_POINTS* pEntryPoints,
const char* name);
ADDIN_ARGV* (*GetPluginData)(IDRDYNVC_ENTRY_POINTS* pEntryPoints);
void* (*GetRdpSettings)(IDRDYNVC_ENTRY_POINTS* pEntryPoints);
};

typedef UINT (*PDVC_PLUGIN_ENTRY)(IDRDYNVC_ENTRY_POINTS *);
typedef UINT(*PDVC_PLUGIN_ENTRY)(IDRDYNVC_ENTRY_POINTS*);

void *get_callback_by_name(const char *name, void **context);
void add_callback_by_name(const char *name, void *fkt, void *context);
void remove_callback_by_name(const char *name, void *context);
void* get_callback_by_name(const char* name, void** context);
void add_callback_by_name(const char* name, void* fkt, void* context);
void remove_callback_by_name(const char* name, void* context);

#endif /* FREERDP_DVC_H */
Loading

0 comments on commit 9f19da7

Please sign in to comment.