diff --git a/channels/client/channels.c b/channels/client/channels.c index 0ee52d9a4..6531d2a92 100644 --- a/channels/client/channels.c +++ b/channels/client/channels.c @@ -438,6 +438,28 @@ int freerdp_channels_load_plugin(rdpChannels* channels, rdpSettings* settings, c return freerdp_channels_client_load(channels, settings, entry, data); } +int freerdp_drdynvc_on_channel_connected(DrdynvcClientContext* context, const char* name, void* pInterface) +{ + int status = 0; + rdpChannels* channels = (rdpChannels*) context->custom; + freerdp* instance = channels->instance; + + IFCALLRET(instance->OnChannelConnected, status, instance, name, pInterface); + + return status; +} + +int freerdp_drdynvc_on_channel_disconnected(DrdynvcClientContext* context, const char* name, void* pInterface) +{ + int status = 0; + rdpChannels* channels = (rdpChannels*) context->custom; + freerdp* instance = channels->instance; + + IFCALLRET(instance->OnChannelDisconnected, status, instance, name, pInterface); + + return status; +} + /** * go through and inform all the libraries that we are initialized * called only from main thread @@ -489,6 +511,13 @@ int freerdp_channels_post_connect(rdpChannels* channels, freerdp* instance) channels->drdynvc = (DrdynvcClientContext*) freerdp_channels_get_static_channel_interface(channels, "drdynvc"); + if (channels->drdynvc) + { + channels->drdynvc->custom = (void*) channels; + channels->drdynvc->OnChannelConnected = freerdp_drdynvc_on_channel_connected; + channels->drdynvc->OnChannelDisconnected = freerdp_drdynvc_on_channel_disconnected; + } + return 0; } diff --git a/channels/client/channels.h b/channels/client/channels.h index 3a165748d..7e801e59b 100644 --- a/channels/client/channels.h +++ b/channels/client/channels.h @@ -84,6 +84,8 @@ typedef struct rdp_channel_init_data CHANNEL_INIT_DATA; struct rdp_channels { + /* internal */ + int clientDataCount; CHANNEL_CLIENT_DATA clientDataList[CHANNEL_MAX_COUNT]; diff --git a/channels/drdynvc/client/drdynvc_main.c b/channels/drdynvc/client/drdynvc_main.c index d912bef6a..a605ba205 100644 --- a/channels/drdynvc/client/drdynvc_main.c +++ b/channels/drdynvc/client/drdynvc_main.c @@ -26,35 +26,15 @@ #include #include +#include #include -#include #include #include "dvcman.h" #include "drdynvc_types.h" #include "drdynvc_main.h" -#define CREATE_REQUEST_PDU 0x01 -#define DATA_FIRST_PDU 0x02 -#define DATA_PDU 0x03 -#define CLOSE_REQUEST_PDU 0x04 -#define CAPABILITY_REQUEST_PDU 0x05 - -struct drdynvc_plugin -{ - rdpSvcPlugin plugin; - - int version; - int PriorityCharge0; - int PriorityCharge1; - int PriorityCharge2; - int PriorityCharge3; - int channel_error; - - IWTSVirtualChannelManager* channel_mgr; -}; - static int drdynvc_write_variable_uint(wStream* stream, UINT32 val) { int cb; @@ -273,7 +253,7 @@ static int drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, int cb static int drdynvc_process_data_first(drdynvcPlugin* drdynvc, int Sp, int cbChId, wStream* s) { - int error; + int status; UINT32 Length; UINT32 ChannelId; @@ -281,10 +261,10 @@ static int drdynvc_process_data_first(drdynvcPlugin* drdynvc, int Sp, int cbChId Length = drdynvc_read_variable_uint(s, Sp); DEBUG_DVC("ChannelId=%d Length=%d", ChannelId, Length); - error = dvcman_receive_channel_data_first(drdynvc->channel_mgr, ChannelId, Length); + status = dvcman_receive_channel_data_first(drdynvc->channel_mgr, ChannelId, Length); - if (error) - return error; + if (status) + return status; return dvcman_receive_channel_data(drdynvc->channel_mgr, ChannelId, Stream_Pointer(s), Stream_GetRemainingLength(s)); @@ -439,6 +419,8 @@ int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) context = (DrdynvcClientContext*) malloc(sizeof(DrdynvcClientContext)); context->handle = (void*) _p; + _p->context = context; + context->GetVersion = drdynvc_get_version; *(pEntryPointsEx->ppInterface) = (void*) context; diff --git a/channels/drdynvc/client/drdynvc_main.h b/channels/drdynvc/client/drdynvc_main.h index a363324df..369084a19 100644 --- a/channels/drdynvc/client/drdynvc_main.h +++ b/channels/drdynvc/client/drdynvc_main.h @@ -20,11 +20,36 @@ #ifndef __DRDYNVC_MAIN_H #define __DRDYNVC_MAIN_H -#include +#include +#include +#include #include +#include + +#define CREATE_REQUEST_PDU 0x01 +#define DATA_FIRST_PDU 0x02 +#define DATA_PDU 0x03 +#define CLOSE_REQUEST_PDU 0x04 +#define CAPABILITY_REQUEST_PDU 0x05 typedef struct drdynvc_plugin drdynvcPlugin; +struct drdynvc_plugin +{ + rdpSvcPlugin plugin; + + DrdynvcClientContext* context; + + int version; + int PriorityCharge0; + int PriorityCharge1; + int PriorityCharge2; + int PriorityCharge3; + int channel_error; + + IWTSVirtualChannelManager* channel_mgr; +}; + int drdynvc_write_data(drdynvcPlugin* plugin, UINT32 ChannelId, BYTE* data, UINT32 data_size); int drdynvc_push_event(drdynvcPlugin* plugin, wMessage* event); diff --git a/channels/drdynvc/client/dvcman.c b/channels/drdynvc/client/dvcman.c index accabb56f..f10637689 100644 --- a/channels/drdynvc/client/dvcman.c +++ b/channels/drdynvc/client/dvcman.c @@ -331,6 +331,7 @@ int dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 Channel int bAccept; DVCMAN_LISTENER* listener; DVCMAN_CHANNEL* channel; + DrdynvcClientContext* context; IWTSVirtualChannelCallback* pCallback; DVCMAN* dvcman = (DVCMAN*) pChannelMgr; @@ -361,6 +362,9 @@ int dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 Channel channel->channel_callback = pCallback; ArrayList_Add(dvcman->channels, channel); + context = dvcman->drdynvc->context; + IFCALL(context->OnChannelConnected, context, ChannelName, listener->iface.pInterface); + return 0; } else diff --git a/channels/rdpei/client/rdpei_main.c b/channels/rdpei/client/rdpei_main.c index 400404d0e..a624d83e0 100644 --- a/channels/rdpei/client/rdpei_main.c +++ b/channels/rdpei/client/rdpei_main.c @@ -318,7 +318,7 @@ static int rdpei_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManage rdpei->listener_callback->plugin = pPlugin; rdpei->listener_callback->channel_mgr = pChannelMgr; - status = pChannelMgr->CreateListener(pChannelMgr, "Microsoft::Windows::RDS::Input", 0, + status = pChannelMgr->CreateListener(pChannelMgr, RDPEI_DVC_CHANNEL_NAME, 0, (IWTSListenerCallback*) rdpei->listener_callback, &(rdpei->listener)); rdpei->listener->pInterface = rdpei->iface.pInterface; diff --git a/client/X11/xf_interface.c b/client/X11/xf_interface.c index 7e0d185bd..6eee091bf 100644 --- a/client/X11/xf_interface.c +++ b/client/X11/xf_interface.c @@ -52,6 +52,7 @@ #include #include +#include #include #include #include @@ -652,6 +653,17 @@ int _xf_error_handler(Display* d, XErrorEvent* ev) return xf_error_handler(d, ev); } +int xf_on_channel_connected(freerdp* instance, const char* name, void* pInterface) +{ + //printf("OnChannelConnected: %s\n", name); + return 0; +} + +int xf_on_channel_disconnected(freerdp* instance, const char* name, void* pInterface) +{ + return 0; +} + /** * Callback given to freerdp_connect() to process the pre-connect operations. * It will fill the rdp_freerdp structure (instance) with the appropriate options to use for the connection. @@ -665,6 +677,7 @@ int _xf_error_handler(Display* d, XErrorEvent* ev) BOOL xf_pre_connect(freerdp* instance) { xfInfo* xfi; + rdpChannels* channels; rdpSettings* settings; xfi = ((xfContext*) instance->context)->xfi; @@ -676,13 +689,17 @@ BOOL xf_pre_connect(freerdp* instance) xfi->context->settings = instance->settings; xfi->instance = instance; settings = instance->settings; + channels = instance->context->channels; + + instance->OnChannelConnected = xf_on_channel_connected; + instance->OnChannelDisconnected = xf_on_channel_disconnected; //if (status < 0) // exit(XF_EXIT_PARSE_ARGUMENTS); - freerdp_client_load_addins(instance->context->channels, instance->settings); + freerdp_client_load_addins(channels, instance->settings); - freerdp_channels_pre_connect(xfi->_context->channels, instance); + freerdp_channels_pre_connect(channels, instance); if (settings->AuthenticationOnly) { diff --git a/include/freerdp/client/drdynvc.h b/include/freerdp/client/drdynvc.h index 9e84f328d..bb74ee26e 100644 --- a/include/freerdp/client/drdynvc.h +++ b/include/freerdp/client/drdynvc.h @@ -27,11 +27,17 @@ typedef struct _drdynvc_client_context DrdynvcClientContext; typedef int (*pcDrdynvcGetVersion)(DrdynvcClientContext* context); +typedef int (*pcDrdynvcOnChannelConnected)(DrdynvcClientContext* context, const char* name, void* pInterface); +typedef int (*pcDrdynvcOnChannelDisconnected)(DrdynvcClientContext* context, const char* name, void* pInterface); struct _drdynvc_client_context { void* handle; + void* custom; + pcDrdynvcGetVersion GetVersion; + pcDrdynvcOnChannelConnected OnChannelConnected; + pcDrdynvcOnChannelDisconnected OnChannelDisconnected; }; #endif /* FREERDP_CHANNEL_CLIENT_DRDYNVC_H */ diff --git a/include/freerdp/client/rdpei.h b/include/freerdp/client/rdpei.h index a35534c06..3ebf41c8a 100644 --- a/include/freerdp/client/rdpei.h +++ b/include/freerdp/client/rdpei.h @@ -24,6 +24,8 @@ * Client Interface */ +#define RDPEI_DVC_CHANNEL_NAME "Microsoft::Windows::RDS::Input" + typedef struct _rdpei_client_context RdpeiClientContext; typedef int (*pcRdpeiGetVersion)(RdpeiClientContext* context); @@ -31,6 +33,8 @@ typedef int (*pcRdpeiGetVersion)(RdpeiClientContext* context); struct _rdpei_client_context { void* handle; + void* custom; + pcRdpeiGetVersion GetVersion; }; diff --git a/include/freerdp/freerdp.h b/include/freerdp/freerdp.h index cef859d5b..1c531d992 100644 --- a/include/freerdp/freerdp.h +++ b/include/freerdp/freerdp.h @@ -63,6 +63,9 @@ typedef int (*pLogonErrorInfo)(freerdp* instance, UINT32 data, UINT32 type); typedef int (*pSendChannelData)(freerdp* instance, int channelId, BYTE* data, int size); typedef int (*pReceiveChannelData)(freerdp* instance, int channelId, BYTE* data, int size, int flags, int total_size); +typedef int (*pOnChannelConnected)(freerdp* instance, const char* name, void* pInterface); +typedef int (*pOnChannelDisconnected)(freerdp* instance, const char* name, void* pInterface); + /** * Defines the context for a given instance of RDP connection. * It is embedded in the rdp_freerdp structure, and allocated by a call to freerdp_context_new(). @@ -193,6 +196,10 @@ struct rdp_freerdp Callback for receiving data from a channel. This is called by freerdp_channel_process() (if not NULL). Clients will typically use a function that calls freerdp_channels_data() to perform the needed tasks. */ + + pOnChannelConnected OnChannelConnected; + pOnChannelDisconnected OnChannelDisconnected; + UINT32 paddingE[80 - 66]; /* 66 */ };