diff --git a/channels/drdynvc/client/drdynvc_main.c b/channels/drdynvc/client/drdynvc_main.c index 7fd9a1cca..9edd7a9c0 100644 --- a/channels/drdynvc/client/drdynvc_main.c +++ b/channels/drdynvc/client/drdynvc_main.c @@ -30,8 +30,6 @@ #define TAG CHANNELS_TAG("drdynvc.client") -static rdpChannelHandles g_ChannelHandles = { NULL, NULL }; - static void dvcman_channel_free(void* channel); static UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, const BYTE* data, UINT32 dataSize); @@ -184,31 +182,6 @@ static IWTSVirtualChannel* dvcman_find_channel_by_id(IWTSVirtualChannelManager* return (found) ? ((IWTSVirtualChannel*) channel) : NULL; } -static void* dvcman_get_channel_interface_by_name(IWTSVirtualChannelManager* - pChannelMgr, - const char* ChannelName) -{ - int i; - BOOL found = FALSE; - void* pInterface = NULL; - DVCMAN_LISTENER* listener; - DVCMAN* dvcman = (DVCMAN*) pChannelMgr; - - for (i = 0; i < dvcman->num_listeners; i++) - { - listener = (DVCMAN_LISTENER*) dvcman->listeners[i]; - - if (strcmp(listener->channel_name, ChannelName) == 0) - { - pInterface = listener->iface.pInterface; - found = TRUE; - break; - } - } - - return (found) ? pInterface : NULL; -} - static IWTSVirtualChannelManager* dvcman_new(drdynvcPlugin* plugin) { DVCMAN* dvcman; @@ -727,15 +700,14 @@ static UINT drdynvc_send(drdynvcPlugin* drdynvc, wStream* s) } else { - status = drdynvc->channelEntryPoints.pVirtualChannelWrite(drdynvc->OpenHandle, - Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); + status = drdynvc->channelEntryPoints.pVirtualChannelWriteEx(drdynvc->InitHandle, + drdynvc->OpenHandle, Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); } if (status != CHANNEL_RC_OK) { Stream_Free(s, TRUE); - WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", - WTSErrorToString(status), status); + WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", WTSErrorToString(status), status); } return status; @@ -1195,12 +1167,11 @@ static UINT drdynvc_virtual_channel_event_data_received(drdynvcPlugin* drdynvc, return CHANNEL_RC_OK; } -static void VCAPITYPE drdynvc_virtual_channel_open_event(DWORD openHandle, - UINT event, - LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) +static void VCAPITYPE drdynvc_virtual_channel_open_event_ex(LPVOID lpUserParam, DWORD openHandle, + UINT event, LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { UINT error = CHANNEL_RC_OK; - drdynvcPlugin* drdynvc = (drdynvcPlugin*) freerdp_channel_get_open_handle_data(&g_ChannelHandles, openHandle); + drdynvcPlugin* drdynvc = (drdynvcPlugin*) lpUserParam; if (!drdynvc || (drdynvc->OpenHandle != openHandle)) { @@ -1211,11 +1182,8 @@ static void VCAPITYPE drdynvc_virtual_channel_open_event(DWORD openHandle, switch (event) { case CHANNEL_EVENT_DATA_RECEIVED: - if ((error = drdynvc_virtual_channel_event_data_received(drdynvc, pData, - dataLength, totalLength, dataFlags))) - WLog_ERR(TAG, - "drdynvc_virtual_channel_event_data_received failed with error %lu", error); - + if ((error = drdynvc_virtual_channel_event_data_received(drdynvc, pData, dataLength, totalLength, dataFlags))) + WLog_ERR(TAG, "drdynvc_virtual_channel_event_data_received failed with error %lu", error); break; case CHANNEL_EVENT_WRITE_COMPLETE: @@ -1227,17 +1195,15 @@ static void VCAPITYPE drdynvc_virtual_channel_open_event(DWORD openHandle, } if (error && drdynvc->rdpcontext) - setChannelError(drdynvc->rdpcontext, error, - "drdynvc_virtual_channel_open_event reported an error"); + setChannelError(drdynvc->rdpcontext, error, "drdynvc_virtual_channel_open_event reported an error"); } static void* drdynvc_virtual_channel_client_thread(void* arg) { wStream* data; wMessage message; - drdynvcPlugin* drdynvc = (drdynvcPlugin*) arg; UINT error = CHANNEL_RC_OK; - freerdp_channel_init_thread_context(drdynvc->rdpcontext); + drdynvcPlugin* drdynvc = (drdynvcPlugin*) arg; while (1) { @@ -1274,8 +1240,7 @@ static void* drdynvc_virtual_channel_client_thread(void* arg) } if (error && drdynvc->rdpcontext) - setChannelError(drdynvc->rdpcontext, error, - "drdynvc_virtual_channel_client_thread reported an error"); + setChannelError(drdynvc->rdpcontext, error, "drdynvc_virtual_channel_client_thread reported an error"); ExitThread((DWORD) error); return NULL; @@ -1286,17 +1251,16 @@ static void* drdynvc_virtual_channel_client_thread(void* arg) * * @return 0 on success, otherwise a Win32 error code */ -static UINT drdynvc_virtual_channel_event_connected(drdynvcPlugin* drdynvc, - LPVOID pData, UINT32 dataLength) +static UINT drdynvc_virtual_channel_event_connected(drdynvcPlugin* drdynvc, LPVOID pData, UINT32 dataLength) { + UINT error; UINT32 status; UINT32 index; ADDIN_ARGV* args; rdpSettings* settings; - UINT error; - status = drdynvc->channelEntryPoints.pVirtualChannelOpen(drdynvc->InitHandle, - &drdynvc->OpenHandle, drdynvc->channelDef.name, - drdynvc_virtual_channel_open_event); + + status = drdynvc->channelEntryPoints.pVirtualChannelOpenEx(drdynvc->InitHandle, + &drdynvc->OpenHandle, drdynvc->channelDef.name, drdynvc_virtual_channel_open_event_ex); if (status != CHANNEL_RC_OK) { @@ -1305,8 +1269,6 @@ static UINT drdynvc_virtual_channel_event_connected(drdynvcPlugin* drdynvc, return status; } - freerdp_channel_add_open_handle_data(&g_ChannelHandles, drdynvc->OpenHandle, (void*) drdynvc); - drdynvc->queue = MessageQueue_New(NULL); if (!drdynvc->queue) @@ -1367,7 +1329,7 @@ static UINT drdynvc_virtual_channel_event_disconnected(drdynvcPlugin* drdynvc) UINT status; if (MessageQueue_PostQuit(drdynvc->queue, 0) && - (WaitForSingleObject(drdynvc->thread, INFINITE) == WAIT_FAILED)) + (WaitForSingleObject(drdynvc->thread, INFINITE) == WAIT_FAILED)) { status = GetLastError(); WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", status); @@ -1378,7 +1340,8 @@ static UINT drdynvc_virtual_channel_event_disconnected(drdynvcPlugin* drdynvc) CloseHandle(drdynvc->thread); drdynvc->queue = NULL; drdynvc->thread = NULL; - status = drdynvc->channelEntryPoints.pVirtualChannelClose(drdynvc->OpenHandle); + + status = drdynvc->channelEntryPoints.pVirtualChannelCloseEx(drdynvc->InitHandle, drdynvc->OpenHandle); if (status != CHANNEL_RC_OK) { @@ -1400,8 +1363,6 @@ static UINT drdynvc_virtual_channel_event_disconnected(drdynvcPlugin* drdynvc) drdynvc->channel_mgr = NULL; } - freerdp_channel_remove_open_handle_data(&g_ChannelHandles, drdynvc->OpenHandle); - return status; } @@ -1412,18 +1373,15 @@ static UINT drdynvc_virtual_channel_event_disconnected(drdynvcPlugin* drdynvc) */ static UINT drdynvc_virtual_channel_event_terminated(drdynvcPlugin* drdynvc) { - freerdp_channel_remove_init_handle_data(&g_ChannelHandles, (void*) drdynvc); drdynvc->InitHandle = 0; free(drdynvc); return CHANNEL_RC_OK; } -static VOID VCAPITYPE drdynvc_virtual_channel_init_event(LPVOID pInitHandle, - UINT event, LPVOID pData, - UINT dataLength) +static VOID VCAPITYPE drdynvc_virtual_channel_init_event_ex(LPVOID lpUserParam, LPVOID pInitHandle, UINT event, LPVOID pData, UINT dataLength) { UINT error = CHANNEL_RC_OK; - drdynvcPlugin* drdynvc = (drdynvcPlugin*) freerdp_channel_get_init_handle_data(&g_ChannelHandles, pInitHandle); + drdynvcPlugin* drdynvc = (drdynvcPlugin*) lpUserParam; if (!drdynvc || (drdynvc->InitHandle != pInitHandle)) { @@ -1434,31 +1392,23 @@ static VOID VCAPITYPE drdynvc_virtual_channel_init_event(LPVOID pInitHandle, switch (event) { case CHANNEL_EVENT_CONNECTED: - if ((error = drdynvc_virtual_channel_event_connected(drdynvc, pData, - dataLength))) - WLog_ERR(TAG, "drdynvc_virtual_channel_event_connected failed with error %lu", - error); - + if ((error = drdynvc_virtual_channel_event_connected(drdynvc, pData, dataLength))) + WLog_ERR(TAG, "drdynvc_virtual_channel_event_connected failed with error %lu", error); break; case CHANNEL_EVENT_DISCONNECTED: if ((error = drdynvc_virtual_channel_event_disconnected(drdynvc))) - WLog_ERR(TAG, - "drdynvc_virtual_channel_event_disconnected failed with error %lu", error); - + WLog_ERR(TAG, "drdynvc_virtual_channel_event_disconnected failed with error %lu", error); break; case CHANNEL_EVENT_TERMINATED: if ((error = drdynvc_virtual_channel_event_terminated(drdynvc))) - WLog_ERR(TAG, "drdynvc_virtual_channel_event_terminated failed with error %lu", - error); - + WLog_ERR(TAG, "drdynvc_virtual_channel_event_terminated failed with error %lu", error); break; } if (error && drdynvc->rdpcontext) - setChannelError(drdynvc->rdpcontext, error, - "drdynvc_virtual_channel_init_event reported an error"); + setChannelError(drdynvc->rdpcontext, error, "drdynvc_virtual_channel_init_event_ex reported an error"); } /** @@ -1472,14 +1422,14 @@ static int drdynvc_get_version(DrdynvcClientContext* context) } /* drdynvc is always built-in */ -#define VirtualChannelEntry drdynvc_VirtualChannelEntry +#define VirtualChannelEntryEx drdynvc_VirtualChannelEntry -BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) +BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS_EX pEntryPoints, PVOID pInitHandle) { UINT rc; drdynvcPlugin* drdynvc; DrdynvcClientContext* context = NULL; - CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx; + CHANNEL_ENTRY_POINTS_FREERDP_EX* pEntryPointsEx; drdynvc = (drdynvcPlugin*) calloc(1, sizeof(drdynvcPlugin)); if (!drdynvc) @@ -1489,14 +1439,16 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) } drdynvc->channelDef.options = - CHANNEL_OPTION_INITIALIZED | - CHANNEL_OPTION_ENCRYPT_RDP | - CHANNEL_OPTION_COMPRESS_RDP; + CHANNEL_OPTION_INITIALIZED | + CHANNEL_OPTION_ENCRYPT_RDP | + CHANNEL_OPTION_COMPRESS_RDP; + strcpy(drdynvc->channelDef.name, "drdynvc"); drdynvc->state = DRDYNVC_STATE_INITIAL; - pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints; - if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP)) && + pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP_EX*) pEntryPoints; + + if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)) && (pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER)) { context = (DrdynvcClientContext*) calloc(1, sizeof(DrdynvcClientContext)); @@ -1517,12 +1469,14 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) } drdynvc->log = WLog_Get("com.freerdp.channels.drdynvc.client"); - WLog_Print(drdynvc->log, WLOG_DEBUG, "VirtualChannelEntry"); - CopyMemory(&(drdynvc->channelEntryPoints), pEntryPoints, - sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); - rc = drdynvc->channelEntryPoints.pVirtualChannelInit(&drdynvc->InitHandle, - &drdynvc->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, - drdynvc_virtual_channel_init_event); + WLog_Print(drdynvc->log, WLOG_DEBUG, "VirtualChannelEntryEx"); + + CopyMemory(&(drdynvc->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)); + + drdynvc->InitHandle = pInitHandle; + + rc = drdynvc->channelEntryPoints.pVirtualChannelInitEx((void*) drdynvc, pInitHandle, + &drdynvc->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, drdynvc_virtual_channel_init_event_ex); if (CHANNEL_RC_OK != rc) { @@ -1542,8 +1496,6 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) drdynvc->channelEntryPoints.ppInterface = & (drdynvc->channelEntryPoints.pInterface); - freerdp_channel_add_init_handle_data(&g_ChannelHandles, drdynvc->InitHandle, (void*) drdynvc); - return TRUE; } diff --git a/channels/drdynvc/client/drdynvc_main.h b/channels/drdynvc/client/drdynvc_main.h index 6829745cb..261fcd86e 100644 --- a/channels/drdynvc/client/drdynvc_main.h +++ b/channels/drdynvc/client/drdynvc_main.h @@ -115,7 +115,7 @@ typedef enum _DRDYNVC_STATE DRDYNVC_STATE; struct drdynvc_plugin { CHANNEL_DEF channelDef; - CHANNEL_ENTRY_POINTS_FREERDP channelEntryPoints; + CHANNEL_ENTRY_POINTS_FREERDP_EX channelEntryPoints; wLog* log; HANDLE thread; @@ -134,7 +134,6 @@ struct drdynvc_plugin int PriorityCharge3; rdpContext* rdpcontext; - IWTSVirtualChannelManager* channel_mgr; }; diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 654401758..fb5d0c08f 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -2521,11 +2521,23 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, static BOOL freerdp_client_load_static_channel_addin(rdpChannels* channels, rdpSettings* settings, char* name, void* data) { - PVIRTUALCHANNELENTRY entry; + PVIRTUALCHANNELENTRY entry = NULL; + PVIRTUALCHANNELENTRYEX entryEx = NULL; entry = freerdp_load_channel_addin_entry(name, NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC); - if (entry) + if (!strcmp(name, "drdynvc")) + entryEx = (PVIRTUALCHANNELENTRYEX) entry; + + if (entryEx) + { + if (freerdp_channels_client_load_ex(channels, settings, entryEx, data) == 0) + { + WLog_INFO(TAG, "loading channelEx %s", name); + return TRUE; + } + } + else if (entry) { if (freerdp_channels_client_load(channels, settings, entry, data) == 0) { diff --git a/include/freerdp/channels/channels.h b/include/freerdp/channels/channels.h index 2c0ca26eb..e0b21a7eb 100644 --- a/include/freerdp/channels/channels.h +++ b/include/freerdp/channels/channels.h @@ -33,8 +33,9 @@ extern "C" { #endif FREERDP_API int freerdp_channels_client_load(rdpChannels* channels, - rdpSettings* settings, - PVIRTUALCHANNELENTRY entry, void* data); + rdpSettings* settings, PVIRTUALCHANNELENTRY entry, void* data); +FREERDP_API int freerdp_channels_client_load_ex(rdpChannels* channels, + rdpSettings* settings, PVIRTUALCHANNELENTRYEX entryEx, void* data); FREERDP_API int freerdp_channels_load_plugin(rdpChannels* channels, rdpSettings* settings, const char* name, void* data); diff --git a/libfreerdp/core/client.c b/libfreerdp/core/client.c index 08b83cd3b..badef117d 100644 --- a/libfreerdp/core/client.c +++ b/libfreerdp/core/client.c @@ -1071,7 +1071,7 @@ int freerdp_channels_client_load_ex(rdpChannels* channels, rdpSettings* settings if (!status) { - WLog_ERR(TAG, "error: channel export function call failed"); + WLog_ERR(TAG, "error: channel export function call failed"); return 1; }