From dc12641b233b6781d6f7b664711d3416bf7e36f6 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 14 Jul 2016 12:44:17 +0200 Subject: [PATCH] Fixed a windows 8.1 issue. --- channels/drdynvc/client/drdynvc_main.c | 350 ++++++++++++------------- 1 file changed, 172 insertions(+), 178 deletions(-) diff --git a/channels/drdynvc/client/drdynvc_main.c b/channels/drdynvc/client/drdynvc_main.c index 03e71d9d4..36e073d11 100644 --- a/channels/drdynvc/client/drdynvc_main.c +++ b/channels/drdynvc/client/drdynvc_main.c @@ -32,14 +32,15 @@ static void dvcman_channel_free(void* channel); static UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, - const BYTE* data, UINT32 dataSize); + const BYTE* data, UINT32 dataSize); /** * Function description * * @return 0 on success, otherwise a Win32 error code */ -static UINT dvcman_get_configuration(IWTSListener* pListener, void** ppPropertyBag) +static UINT dvcman_get_configuration(IWTSListener* pListener, + void** ppPropertyBag) { *ppPropertyBag = NULL; return ERROR_INTERNAL_ERROR; @@ -51,8 +52,8 @@ static UINT dvcman_get_configuration(IWTSListener* pListener, void** ppPropertyB * @return 0 on success, otherwise a Win32 error code */ static UINT dvcman_create_listener(IWTSVirtualChannelManager* pChannelMgr, - const char* pszChannelName, ULONG ulFlags, - IWTSListenerCallback* pListenerCallback, IWTSListener** ppListener) + const char* pszChannelName, ULONG ulFlags, + IWTSListenerCallback* pListenerCallback, IWTSListener** ppListener) { DVCMAN* dvcman = (DVCMAN*) pChannelMgr; DVCMAN_LISTENER* listener; @@ -60,7 +61,6 @@ static UINT dvcman_create_listener(IWTSVirtualChannelManager* pChannelMgr, if (dvcman->num_listeners < MAX_PLUGINS) { WLog_DBG(TAG, "create_listener: %d.%s.", dvcman->num_listeners, pszChannelName); - listener = (DVCMAN_LISTENER*) calloc(1, sizeof(DVCMAN_LISTENER)); if (!listener) @@ -71,15 +71,16 @@ static UINT dvcman_create_listener(IWTSVirtualChannelManager* pChannelMgr, listener->iface.GetConfiguration = dvcman_get_configuration; listener->iface.pInterface = NULL; - listener->dvcman = dvcman; listener->channel_name = _strdup(pszChannelName); + if (!listener->channel_name) { WLog_ERR(TAG, "_strdup failed!"); free(listener); return CHANNEL_RC_NO_MEMORY; } + listener->flags = ulFlags; listener->listener_callback = pListenerCallback; @@ -87,7 +88,6 @@ static UINT dvcman_create_listener(IWTSVirtualChannelManager* pChannelMgr, *ppListener = (IWTSListener*) listener; dvcman->listeners[dvcman->num_listeners++] = (IWTSListener*) listener; - return CHANNEL_RC_OK; } else @@ -103,7 +103,7 @@ static UINT dvcman_create_listener(IWTSVirtualChannelManager* pChannelMgr, * @return 0 on success, otherwise a Win32 error code */ static UINT dvcman_register_plugin(IDRDYNVC_ENTRY_POINTS* pEntryPoints, - const char* name, IWTSPlugin* pPlugin) + const char* name, IWTSPlugin* pPlugin) { DVCMAN* dvcman = ((DVCMAN_ENTRY_POINTS*) pEntryPoints)->dvcman; @@ -116,12 +116,14 @@ static UINT dvcman_register_plugin(IDRDYNVC_ENTRY_POINTS* pEntryPoints, } else { - WLog_ERR(TAG, "register_plugin: Maximum DVC plugin number %d reached.", MAX_PLUGINS); + WLog_ERR(TAG, "register_plugin: Maximum DVC plugin number %d reached.", + MAX_PLUGINS); return ERROR_INTERNAL_ERROR; } } -static IWTSPlugin* dvcman_get_plugin(IDRDYNVC_ENTRY_POINTS* pEntryPoints, const char* name) +static IWTSPlugin* dvcman_get_plugin(IDRDYNVC_ENTRY_POINTS* pEntryPoints, + const char* name) { int i; DVCMAN* dvcman = ((DVCMAN_ENTRY_POINTS*) pEntryPoints)->dvcman; @@ -129,7 +131,7 @@ static IWTSPlugin* dvcman_get_plugin(IDRDYNVC_ENTRY_POINTS* pEntryPoints, const for (i = 0; i < dvcman->num_plugins; i++) { if (dvcman->plugin_names[i] == name || - strcmp(dvcman->plugin_names[i], name) == 0) + strcmp(dvcman->plugin_names[i], name) == 0) { return dvcman->plugins[i]; } @@ -145,24 +147,23 @@ static ADDIN_ARGV* dvcman_get_plugin_data(IDRDYNVC_ENTRY_POINTS* pEntryPoints) static void* dvcman_get_rdp_settings(IDRDYNVC_ENTRY_POINTS* pEntryPoints) { - return (void*) ((DVCMAN_ENTRY_POINTS*) pEntryPoints)->settings; + return (void*)((DVCMAN_ENTRY_POINTS*) pEntryPoints)->settings; } -static UINT32 dvcman_get_channel_id(IWTSVirtualChannel * channel) +static UINT32 dvcman_get_channel_id(IWTSVirtualChannel* channel) { return ((DVCMAN_CHANNEL*) channel)->channel_id; } -static IWTSVirtualChannel* dvcman_find_channel_by_id(IWTSVirtualChannelManager* pChannelMgr, - UINT32 ChannelId) +static IWTSVirtualChannel* dvcman_find_channel_by_id(IWTSVirtualChannelManager* + pChannelMgr, + UINT32 ChannelId) { int index; BOOL found = FALSE; DVCMAN_CHANNEL* channel; DVCMAN* dvcman = (DVCMAN*) pChannelMgr; - ArrayList_Lock(dvcman->channels); - index = 0; channel = (DVCMAN_CHANNEL*) ArrayList_GetItem(dvcman->channels, index++); @@ -178,12 +179,12 @@ static IWTSVirtualChannel* dvcman_find_channel_by_id(IWTSVirtualChannelManager* } ArrayList_Unlock(dvcman->channels); - return (found) ? ((IWTSVirtualChannel*) channel) : NULL; } -static void* dvcman_get_channel_interface_by_name(IWTSVirtualChannelManager* pChannelMgr, - const char* ChannelName) +static void* dvcman_get_channel_interface_by_name(IWTSVirtualChannelManager* + pChannelMgr, + const char* ChannelName) { int i; BOOL found = FALSE; @@ -209,8 +210,8 @@ static void* dvcman_get_channel_interface_by_name(IWTSVirtualChannelManager* pCh static IWTSVirtualChannelManager* dvcman_new(drdynvcPlugin* plugin) { DVCMAN* dvcman; - dvcman = (DVCMAN*) calloc(1, sizeof(DVCMAN)); + if (!dvcman) { WLog_ERR(TAG, "calloc failed!"); @@ -222,14 +223,17 @@ static IWTSVirtualChannelManager* dvcman_new(drdynvcPlugin* plugin) dvcman->iface.GetChannelId = dvcman_get_channel_id; dvcman->drdynvc = plugin; dvcman->channels = ArrayList_New(TRUE); + if (!dvcman->channels) { WLog_ERR(TAG, "ArrayList_New failed!"); free(dvcman); return NULL; } + dvcman->channels->object.fnObjectFree = dvcman_channel_free; dvcman->pool = StreamPool_New(TRUE, 10); + if (!dvcman->pool) { WLog_ERR(TAG, "StreamPool_New failed!"); @@ -246,16 +250,16 @@ static IWTSVirtualChannelManager* dvcman_new(drdynvcPlugin* plugin) * * @return 0 on success, otherwise a Win32 error code */ -static UINT dvcman_load_addin(IWTSVirtualChannelManager* pChannelMgr, ADDIN_ARGV* args, - rdpSettings* settings) +static UINT dvcman_load_addin(IWTSVirtualChannelManager* pChannelMgr, + ADDIN_ARGV* args, + rdpSettings* settings) { DVCMAN_ENTRY_POINTS entryPoints; PDVC_PLUGIN_ENTRY pDVCPluginEntry = NULL; - WLog_INFO(TAG, "Loading Dynamic Virtual Channel %s", args->argv[0]); - - pDVCPluginEntry = (PDVC_PLUGIN_ENTRY) freerdp_load_channel_addin_entry(args->argv[0], - NULL, NULL, FREERDP_ADDIN_CHANNEL_DYNAMIC); + pDVCPluginEntry = (PDVC_PLUGIN_ENTRY) freerdp_load_channel_addin_entry( + args->argv[0], + NULL, NULL, FREERDP_ADDIN_CHANNEL_DYNAMIC); if (pDVCPluginEntry) { @@ -266,21 +270,22 @@ static UINT dvcman_load_addin(IWTSVirtualChannelManager* pChannelMgr, ADDIN_ARGV entryPoints.dvcman = (DVCMAN*) pChannelMgr; entryPoints.args = args; entryPoints.settings = settings; - return pDVCPluginEntry((IDRDYNVC_ENTRY_POINTS*) &entryPoints); } return CHANNEL_RC_OK; } -static DVCMAN_CHANNEL* dvcman_channel_new(IWTSVirtualChannelManager* pChannelMgr, - UINT32 ChannelId, const char* ChannelName) +static DVCMAN_CHANNEL* dvcman_channel_new(IWTSVirtualChannelManager* + pChannelMgr, + UINT32 ChannelId, const char* ChannelName) { DVCMAN_CHANNEL* channel; if (dvcman_find_channel_by_id(pChannelMgr, ChannelId)) { - WLog_ERR(TAG, "Protocol error: Duplicated ChannelId %d (%s)!", ChannelId, ChannelName); + WLog_ERR(TAG, "Protocol error: Duplicated ChannelId %d (%s)!", ChannelId, + ChannelName); return NULL; } @@ -295,6 +300,7 @@ static DVCMAN_CHANNEL* dvcman_channel_new(IWTSVirtualChannelManager* pChannelMgr channel->dvcman = (DVCMAN*) pChannelMgr; channel->channel_id = ChannelId; channel->channel_name = _strdup(ChannelName); + if (!channel->channel_name) { WLog_ERR(TAG, "_strdup failed!"); @@ -302,7 +308,7 @@ static DVCMAN_CHANNEL* dvcman_channel_new(IWTSVirtualChannelManager* pChannelMgr return NULL; } - if (!InitializeCriticalSectionEx(&(channel->lock), 0 ,0)) + if (!InitializeCriticalSectionEx(&(channel->lock), 0 , 0)) { WLog_ERR(TAG, "InitializeCriticalSectionEx failed!"); free(channel->channel_name); @@ -347,7 +353,6 @@ static void dvcman_free(IWTSVirtualChannelManager* pChannelMgr) DVCMAN_LISTENER* listener; DVCMAN* dvcman = (DVCMAN*) pChannelMgr; UINT error; - ArrayList_Free(dvcman->channels); for (i = 0; i < dvcman->num_listeners; i++) @@ -369,9 +374,7 @@ static void dvcman_free(IWTSVirtualChannelManager* pChannelMgr) } dvcman->num_plugins = 0; - StreamPool_Free(dvcman->pool); - free(dvcman); } @@ -408,18 +411,14 @@ static UINT dvcman_init(IWTSVirtualChannelManager* pChannelMgr) * @return 0 on success, otherwise a Win32 error code */ static UINT dvcman_write_channel(IWTSVirtualChannel* pChannel, ULONG cbSize, - const BYTE* pBuffer, void* pReserved) + const BYTE* pBuffer, void* pReserved) { UINT status; DVCMAN_CHANNEL* channel = (DVCMAN_CHANNEL*) pChannel; - EnterCriticalSection(&(channel->lock)); - status = drdynvc_write_data(channel->dvcman->drdynvc, - channel->channel_id, pBuffer, cbSize); - + channel->channel_id, pBuffer, cbSize); LeaveCriticalSection(&(channel->lock)); - return status; } @@ -431,9 +430,7 @@ static UINT dvcman_write_channel(IWTSVirtualChannel* pChannel, ULONG cbSize, static UINT dvcman_close_channel_iface(IWTSVirtualChannel* pChannel) { DVCMAN_CHANNEL* channel = (DVCMAN_CHANNEL*) pChannel; - WLog_DBG(TAG, "close_channel_iface: id=%d", channel->channel_id); - return CHANNEL_RC_OK; } @@ -443,7 +440,7 @@ static UINT dvcman_close_channel_iface(IWTSVirtualChannel* pChannel) * @return 0 on success, otherwise a Win32 error code */ UINT dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, - UINT32 ChannelId, const char* ChannelName) + UINT32 ChannelId, const char* ChannelName) { int i; BOOL bAccept; @@ -471,25 +468,25 @@ UINT dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, { channel->iface.Write = dvcman_write_channel; channel->iface.Close = dvcman_close_channel_iface; - bAccept = TRUE; pCallback = NULL; - if ((error = listener->listener_callback->OnNewChannelConnection(listener->listener_callback, - (IWTSVirtualChannel*) channel, NULL, &bAccept, &pCallback)) == CHANNEL_RC_OK && bAccept) + if ((error = listener->listener_callback->OnNewChannelConnection( + listener->listener_callback, + (IWTSVirtualChannel*) channel, NULL, &bAccept, &pCallback)) == CHANNEL_RC_OK + && bAccept) { WLog_DBG(TAG, "listener %s created new channel %d", - listener->channel_name, channel->channel_id); - + listener->channel_name, channel->channel_id); channel->status = 0; channel->channel_callback = pCallback; channel->pInterface = listener->iface.pInterface; - context = dvcman->drdynvc->context; - IFCALLRET(context->OnChannelConnected, error, context, ChannelName, listener->iface.pInterface); + IFCALLRET(context->OnChannelConnected, error, context, ChannelName, + listener->iface.pInterface); - if (error) - WLog_ERR(TAG, "context.ReceiveSamples failed with error %lu", error); + if (error) + WLog_ERR(TAG, "context.ReceiveSamples failed with error %lu", error); return error; } @@ -518,12 +515,11 @@ UINT dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, * @return 0 on success, otherwise a Win32 error code */ static UINT dvcman_open_channel(IWTSVirtualChannelManager* pChannelMgr, - UINT32 ChannelId) + UINT32 ChannelId) { DVCMAN_CHANNEL* channel; IWTSVirtualChannelCallback* pCallback; UINT error; - channel = (DVCMAN_CHANNEL*) dvcman_find_channel_by_id(pChannelMgr, ChannelId); if (!channel) @@ -535,11 +531,13 @@ static UINT dvcman_open_channel(IWTSVirtualChannelManager* pChannelMgr, if (channel->status == CHANNEL_RC_OK) { pCallback = channel->channel_callback; + if ((pCallback->OnOpen) && (error = pCallback->OnOpen(pCallback))) { WLog_ERR(TAG, "OnOpen failed with eror %lu!", error); return error; } + WLog_DBG(TAG, "open_channel: ChannelId %d", ChannelId); } @@ -552,14 +550,13 @@ static UINT dvcman_open_channel(IWTSVirtualChannelManager* pChannelMgr, * @return 0 on success, otherwise a Win32 error code */ static UINT dvcman_close_channel(IWTSVirtualChannelManager* pChannelMgr, - UINT32 ChannelId) + UINT32 ChannelId) { DVCMAN_CHANNEL* channel; IWTSVirtualChannel* ichannel; DrdynvcClientContext* context; DVCMAN* dvcman = (DVCMAN*) pChannelMgr; UINT error = CHANNEL_RC_OK; - channel = (DVCMAN_CHANNEL*) dvcman_find_channel_by_id(pChannelMgr, ChannelId); if (!channel) @@ -575,8 +572,9 @@ static UINT dvcman_close_channel(IWTSVirtualChannelManager* pChannelMgr, if (channel->status == CHANNEL_RC_OK) { context = dvcman->drdynvc->context; + IFCALLRET(context->OnChannelDisconnected, error, context, channel->channel_name, + channel->pInterface); - IFCALLRET(context->OnChannelDisconnected, error, context, channel->channel_name, channel->pInterface); if (error) { WLog_ERR(TAG, "OnChannelDisconnected returned with error %lu!", error); @@ -584,7 +582,6 @@ static UINT dvcman_close_channel(IWTSVirtualChannelManager* pChannelMgr, } WLog_DBG(TAG, "dvcman_close_channel: channel %d closed", ChannelId); - ichannel = (IWTSVirtualChannel*) channel; if ((ichannel->Close) && (error = ichannel->Close(ichannel))) @@ -595,7 +592,6 @@ static UINT dvcman_close_channel(IWTSVirtualChannelManager* pChannelMgr, } ArrayList_Remove(dvcman->channels, channel); - return CHANNEL_RC_OK; } @@ -604,11 +600,11 @@ static UINT dvcman_close_channel(IWTSVirtualChannelManager* pChannelMgr, * * @return 0 on success, otherwise a Win32 error code */ -static UINT dvcman_receive_channel_data_first(IWTSVirtualChannelManager* pChannelMgr, - UINT32 ChannelId, UINT32 length) +static UINT dvcman_receive_channel_data_first(IWTSVirtualChannelManager* + pChannelMgr, + UINT32 ChannelId, UINT32 length) { DVCMAN_CHANNEL* channel; - channel = (DVCMAN_CHANNEL*) dvcman_find_channel_by_id(pChannelMgr, ChannelId); if (!channel) @@ -627,8 +623,8 @@ static UINT dvcman_receive_channel_data_first(IWTSVirtualChannelManager* pChanne WLog_ERR(TAG, "StreamPool_Take failed!"); return CHANNEL_RC_NO_MEMORY; } - channel->dvc_data_length = length; + channel->dvc_data_length = length; return CHANNEL_RC_OK; } @@ -638,24 +634,26 @@ static UINT dvcman_receive_channel_data_first(IWTSVirtualChannelManager* pChanne * @return 0 on success, otherwise a Win32 error code */ static UINT dvcman_receive_channel_data(IWTSVirtualChannelManager* pChannelMgr, - UINT32 ChannelId, wStream* data) + UINT32 ChannelId, wStream* data) { UINT status = CHANNEL_RC_OK; DVCMAN_CHANNEL* channel; size_t dataSize = Stream_GetRemainingLength(data); - channel = (DVCMAN_CHANNEL*) dvcman_find_channel_by_id(pChannelMgr, ChannelId); if (!channel) { + /* Windows 8.1 tries to open channels not created. + * Ignore cases like this. */ WLog_ERR(TAG, "ChannelId %d not found!", ChannelId); - return ERROR_INTERNAL_ERROR; + return CHANNEL_RC_OK; } if (channel->dvc_data) { /* Fragmented data */ - if (Stream_GetPosition(channel->dvc_data) + dataSize > (UINT32) Stream_Capacity(channel->dvc_data)) + if (Stream_GetPosition(channel->dvc_data) + dataSize > (UINT32) Stream_Capacity( + channel->dvc_data)) { WLog_ERR(TAG, "data exceeding declared length!"); Stream_Release(channel->dvc_data); @@ -665,18 +663,21 @@ static UINT dvcman_receive_channel_data(IWTSVirtualChannelManager* pChannelMgr, Stream_Write(channel->dvc_data, Stream_Pointer(data), dataSize); - if (((size_t) Stream_GetPosition(channel->dvc_data)) >= channel->dvc_data_length) + if (((size_t) Stream_GetPosition(channel->dvc_data)) >= + channel->dvc_data_length) { Stream_SealLength(channel->dvc_data); Stream_SetPosition(channel->dvc_data, 0); - status = channel->channel_callback->OnDataReceived(channel->channel_callback, channel->dvc_data); + status = channel->channel_callback->OnDataReceived(channel->channel_callback, + channel->dvc_data); Stream_Release(channel->dvc_data); channel->dvc_data = NULL; } } else { - status = channel->channel_callback->OnDataReceived(channel->channel_callback, data); + status = channel->channel_callback->OnDataReceived(channel->channel_callback, + data); } return status; @@ -721,14 +722,14 @@ static UINT drdynvc_send(drdynvcPlugin* drdynvc, wStream* s) else { status = drdynvc->channelEntryPoints.pVirtualChannelWrite(drdynvc->OpenHandle, - Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); + 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); + WTSErrorToString(status), status); } return status; @@ -740,7 +741,7 @@ static UINT drdynvc_send(drdynvcPlugin* drdynvc, wStream* s) * @return 0 on success, otherwise a Win32 error code */ UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, - const BYTE* data, UINT32 dataSize) + const BYTE* data, UINT32 dataSize) { wStream* data_out; unsigned long pos; @@ -748,9 +749,7 @@ UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, UINT32 cbLen; unsigned long chunkLength; UINT status; - WLog_DBG(TAG, "write_data: ChannelId=%d size=%d", ChannelId, dataSize); - data_out = Stream_New(NULL, CHANNEL_CHUNK_LENGTH); if (!data_out) @@ -761,14 +760,13 @@ UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, Stream_SetPosition(data_out, 1); cbChId = drdynvc_write_variable_uint(data_out, ChannelId); - pos = Stream_GetPosition(data_out); + if (dataSize == 0) { Stream_SetPosition(data_out, 0); Stream_Write_UINT8(data_out, 0x40 | cbChId); Stream_SetPosition(data_out, pos); - status = drdynvc_send(drdynvc, data_out); } else if (dataSize <= CHANNEL_CHUNK_LENGTH - pos) @@ -777,7 +775,6 @@ UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, Stream_Write_UINT8(data_out, 0x30 | cbChId); Stream_SetPosition(data_out, pos); Stream_Write(data_out, data, dataSize); - status = drdynvc_send(drdynvc, data_out); } else @@ -788,19 +785,16 @@ UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, Stream_SetPosition(data_out, 0); Stream_Write_UINT8(data_out, 0x20 | cbChId | (cbLen << 2)); Stream_SetPosition(data_out, pos); - chunkLength = CHANNEL_CHUNK_LENGTH - pos; - Stream_Write(data_out, data, chunkLength); - data += chunkLength; dataSize -= chunkLength; - status = drdynvc_send(drdynvc, data_out); while (status == CHANNEL_RC_OK && dataSize > 0) { data_out = Stream_New(NULL, CHANNEL_CHUNK_LENGTH); + if (!data_out) { WLog_ERR(TAG, "Stream_New failed!"); @@ -809,22 +803,18 @@ UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, Stream_SetPosition(data_out, 1); cbChId = drdynvc_write_variable_uint(data_out, ChannelId); - pos = Stream_GetPosition(data_out); Stream_SetPosition(data_out, 0); Stream_Write_UINT8(data_out, 0x30 | cbChId); Stream_SetPosition(data_out, pos); - chunkLength = dataSize; if (chunkLength > CHANNEL_CHUNK_LENGTH - pos) chunkLength = CHANNEL_CHUNK_LENGTH - pos; Stream_Write(data_out, data, chunkLength); - data += chunkLength; dataSize -= chunkLength; - status = drdynvc_send(drdynvc, data_out); } } @@ -832,7 +822,7 @@ UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, if (status != CHANNEL_RC_OK) { WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", - WTSErrorToString(status), status); + WTSErrorToString(status), status); return status; } @@ -848,9 +838,7 @@ static UINT drdynvc_send_capability_response(drdynvcPlugin* drdynvc) { UINT status; wStream* s; - WLog_DBG(TAG, "capability_response"); - s = Stream_New(NULL, 4); if (!s) @@ -859,15 +847,15 @@ static UINT drdynvc_send_capability_response(drdynvcPlugin* drdynvc) return CHANNEL_RC_NO_MEMORY; } - Stream_Write_UINT16(s, 0x0050); /* Cmd+Sp+cbChId+Pad. Note: MSTSC sends 0x005c */ + Stream_Write_UINT16(s, + 0x0050); /* Cmd+Sp+cbChId+Pad. Note: MSTSC sends 0x005c */ Stream_Write_UINT16(s, drdynvc->version); - status = drdynvc_send(drdynvc, s); if (status != CHANNEL_RC_OK) { WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", - WTSErrorToString(status), status); + WTSErrorToString(status), status); } return status; @@ -879,12 +867,10 @@ static UINT drdynvc_send_capability_response(drdynvcPlugin* drdynvc) * @return 0 on success, otherwise a Win32 error code */ static UINT drdynvc_process_capability_request(drdynvcPlugin* drdynvc, int Sp, - int cbChId, wStream* s) + int cbChId, wStream* s) { UINT status; - WLog_DBG(TAG, "capability_request Sp=%d cbChId=%d", Sp, cbChId); - Stream_Seek(s, 1); /* pad */ Stream_Read_UINT16(s, drdynvc->version); @@ -900,9 +886,7 @@ static UINT drdynvc_process_capability_request(drdynvcPlugin* drdynvc, int Sp, } status = drdynvc_send_capability_response(drdynvc); - drdynvc->state = DRDYNVC_STATE_READY; - return status; } @@ -934,7 +918,7 @@ static UINT32 drdynvc_read_variable_uint(wStream* s, int cbLen) * @return 0 on success, otherwise a Win32 error code */ static UINT drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, - int cbChId, wStream* s) + int cbChId, wStream* s) { unsigned long pos; UINT status; @@ -949,22 +933,23 @@ static UINT drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, * capabilities pdu as it should. When this happens, * send a capabilities response. */ - drdynvc->version = 3; + if ((status = drdynvc_send_capability_response(drdynvc))) { WLog_ERR(TAG, "drdynvc_send_capability_response failed!"); return status; } + drdynvc->state = DRDYNVC_STATE_READY; } ChannelId = drdynvc_read_variable_uint(s, cbChId); pos = Stream_GetPosition(s); - WLog_DBG(TAG, "process_create_request: ChannelId=%d ChannelName=%s", ChannelId, Stream_Pointer(s)); - - channel_status = dvcman_create_channel(drdynvc->channel_mgr, ChannelId, (char*) Stream_Pointer(s)); - + WLog_DBG(TAG, "process_create_request: ChannelId=%d ChannelName=%s", ChannelId, + Stream_Pointer(s)); + channel_status = dvcman_create_channel(drdynvc->channel_mgr, ChannelId, + (char*) Stream_Pointer(s)); data_out = Stream_New(NULL, pos + 4); if (!s) @@ -985,7 +970,8 @@ static UINT drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, else { WLog_DBG(TAG, "no listener"); - Stream_Write_UINT32(data_out, (UINT32) 0xC0000001); /* same code used by mstsc */ + Stream_Write_UINT32(data_out, + (UINT32) 0xC0000001); /* same code used by mstsc */ } status = drdynvc_send(drdynvc, data_out); @@ -993,7 +979,7 @@ static UINT drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, if (status != CHANNEL_RC_OK) { WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", - WTSErrorToString(status), status); + WTSErrorToString(status), status); return status; } @@ -1020,17 +1006,17 @@ static UINT drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, * @return 0 on success, otherwise a Win32 error code */ static UINT drdynvc_process_data_first(drdynvcPlugin* drdynvc, int Sp, - int cbChId, wStream* s) + int cbChId, wStream* s) { UINT status; UINT32 Length; UINT32 ChannelId; - ChannelId = drdynvc_read_variable_uint(s, cbChId); Length = drdynvc_read_variable_uint(s, Sp); - WLog_DBG(TAG, "process_data_first: Sp=%d cbChId=%d, ChannelId=%d Length=%d", Sp, cbChId, ChannelId, Length); - - status = dvcman_receive_channel_data_first(drdynvc->channel_mgr, ChannelId, Length); + WLog_DBG(TAG, "process_data_first: Sp=%d cbChId=%d, ChannelId=%d Length=%d", Sp, + cbChId, ChannelId, Length); + status = dvcman_receive_channel_data_first(drdynvc->channel_mgr, ChannelId, + Length); if (status) return status; @@ -1043,13 +1029,13 @@ static UINT drdynvc_process_data_first(drdynvcPlugin* drdynvc, int Sp, * * @return 0 on success, otherwise a Win32 error code */ -static UINT drdynvc_process_data(drdynvcPlugin* drdynvc, int Sp, int cbChId, wStream* s) +static UINT drdynvc_process_data(drdynvcPlugin* drdynvc, int Sp, int cbChId, + wStream* s) { UINT32 ChannelId; - ChannelId = drdynvc_read_variable_uint(s, cbChId); - WLog_DBG(TAG, "process_data: Sp=%d cbChId=%d, ChannelId=%d", Sp, cbChId, ChannelId); - + WLog_DBG(TAG, "process_data: Sp=%d cbChId=%d, ChannelId=%d", Sp, cbChId, + ChannelId); return dvcman_receive_channel_data(drdynvc->channel_mgr, ChannelId, s); } @@ -1059,16 +1045,15 @@ static UINT drdynvc_process_data(drdynvcPlugin* drdynvc, int Sp, int cbChId, wSt * @return 0 on success, otherwise a Win32 error code */ static UINT drdynvc_process_close_request(drdynvcPlugin* drdynvc, int Sp, - int cbChId, wStream* s) + int cbChId, wStream* s) { int value; UINT error; UINT32 ChannelId; wStream* data_out; - ChannelId = drdynvc_read_variable_uint(s, cbChId); - - WLog_DBG(TAG, "process_close_request: Sp=%d cbChId=%d, ChannelId=%d", Sp, cbChId, ChannelId); + WLog_DBG(TAG, "process_close_request: Sp=%d cbChId=%d, ChannelId=%d", Sp, + cbChId, ChannelId); if ((error = dvcman_close_channel(drdynvc->channel_mgr, ChannelId))) { @@ -1085,15 +1070,13 @@ static UINT drdynvc_process_close_request(drdynvcPlugin* drdynvc, int Sp, } value = (CLOSE_REQUEST_PDU << 4) | (cbChId & 0x03); - Stream_Write_UINT8(data_out, value); drdynvc_write_variable_uint(data_out, ChannelId); - error = drdynvc_send(drdynvc, data_out); if (error) WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", - WTSErrorToString(error), error); + WTSErrorToString(error), error); return error; } @@ -1109,14 +1092,12 @@ static UINT drdynvc_order_recv(drdynvcPlugin* drdynvc, wStream* s) int Cmd; int Sp; int cbChId; - Stream_Read_UINT8(s, value); - Cmd = (value & 0xf0) >> 4; Sp = (value & 0x0c) >> 2; cbChId = (value & 0x03) >> 0; - - WLog_DBG(TAG, "order_recv: Cmd=0x%x, Sp=%d cbChId=%d, ChannelId=%d", Cmd, Sp, cbChId); + WLog_DBG(TAG, "order_recv: Cmd=0x%x, Sp=%d cbChId=%d, ChannelId=%d", Cmd, Sp, + cbChId); switch (Cmd) { @@ -1172,8 +1153,8 @@ static UINT drdynvc_add_init_handle_data(void* pInitHandle, void* pUserData) { WLog_ERR(TAG, "ListDictionary_New failed!"); return ERROR_INTERNAL_ERROR; - } + return CHANNEL_RC_OK; } @@ -1202,7 +1183,7 @@ static void drdynvc_remove_init_handle_data(void* pInitHandle) */ static UINT drdynvc_add_open_handle_data(DWORD openHandle, void* pUserData) { - void* pOpenHandle = (void*) (size_t) openHandle; + void* pOpenHandle = (void*)(size_t) openHandle; if (!g_OpenHandles) g_OpenHandles = ListDictionary_New(TRUE); @@ -1217,22 +1198,22 @@ static UINT drdynvc_add_open_handle_data(DWORD openHandle, void* pUserData) { WLog_ERR(TAG, "ListDictionary_New failed!"); return ERROR_INTERNAL_ERROR; - } + return CHANNEL_RC_OK; } static void* drdynvc_get_open_handle_data(DWORD openHandle) { void* pUserData = NULL; - void* pOpenHandle = (void*) (size_t) openHandle; + void* pOpenHandle = (void*)(size_t) openHandle; pUserData = ListDictionary_GetItemValue(g_OpenHandles, pOpenHandle); return pUserData; } static void drdynvc_remove_open_handle_data(DWORD openHandle) { - void* pOpenHandle = (void*) (size_t) openHandle; + void* pOpenHandle = (void*)(size_t) openHandle; if (!g_OpenHandles) return; @@ -1252,7 +1233,7 @@ static void drdynvc_remove_open_handle_data(DWORD openHandle) * @return 0 on success, otherwise a Win32 error code */ static UINT drdynvc_virtual_channel_event_data_received(drdynvcPlugin* drdynvc, - void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) + void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { wStream* data_in; @@ -1303,15 +1284,16 @@ static UINT drdynvc_virtual_channel_event_data_received(drdynvcPlugin* drdynvc, return ERROR_INTERNAL_ERROR; } } + 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(DWORD openHandle, + UINT event, + LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { drdynvcPlugin* drdynvc; UINT error = CHANNEL_RC_OK; - drdynvc = (drdynvcPlugin*) drdynvc_get_open_handle_data(openHandle); if (!drdynvc) @@ -1323,8 +1305,11 @@ static void VCAPITYPE drdynvc_virtual_channel_open_event(DWORD openHandle, UINT 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: @@ -1334,9 +1319,10 @@ static void VCAPITYPE drdynvc_virtual_channel_open_event(DWORD openHandle, UINT case CHANNEL_EVENT_USER: break; } - if (error && drdynvc->rdpcontext) - setChannelError(drdynvc->rdpcontext, error, "drdynvc_virtual_channel_open_event reported an error"); + if (error && drdynvc->rdpcontext) + setChannelError(drdynvc->rdpcontext, error, + "drdynvc_virtual_channel_open_event reported an error"); } static void* drdynvc_virtual_channel_client_thread(void* arg) @@ -1368,18 +1354,22 @@ static void* drdynvc_virtual_channel_client_thread(void* arg) if (message.id == 0) { data = (wStream*) message.wParam; + if ((error = drdynvc_order_recv(drdynvc, data))) { Stream_Free(data, TRUE); WLog_ERR(TAG, "drdynvc_order_recv failed with error %lu!", error); break; } + Stream_Free(data, TRUE); } } 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; } @@ -1390,21 +1380,21 @@ 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) + LPVOID pData, UINT32 dataLength) { 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); + &drdynvc->OpenHandle, drdynvc->channelDef.name, + drdynvc_virtual_channel_open_event); if (status != CHANNEL_RC_OK) { WLog_ERR(TAG, "pVirtualChannelOpen failed with %s [%08X]", - WTSErrorToString(status), status); + WTSErrorToString(status), status); return status; } @@ -1415,6 +1405,7 @@ static UINT drdynvc_virtual_channel_event_connected(drdynvcPlugin* drdynvc, } drdynvc->queue = MessageQueue_New(NULL); + if (!drdynvc->queue) { error = CHANNEL_RC_NO_MEMORY; @@ -1423,6 +1414,7 @@ static UINT drdynvc_virtual_channel_event_connected(drdynvcPlugin* drdynvc, } drdynvc->channel_mgr = dvcman_new(drdynvc); + if (!drdynvc->channel_mgr) { error = CHANNEL_RC_NO_MEMORY; @@ -1436,6 +1428,7 @@ static UINT drdynvc_virtual_channel_event_connected(drdynvcPlugin* drdynvc, { args = settings->DynamicChannelArray[index]; error = dvcman_load_addin(drdynvc->channel_mgr, args, settings); + if (CHANNEL_RC_OK != error) goto error; } @@ -1449,7 +1442,8 @@ static UINT drdynvc_virtual_channel_event_connected(drdynvcPlugin* drdynvc, drdynvc->state = DRDYNVC_STATE_CAPABILITIES; if (!(drdynvc->thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) drdynvc_virtual_channel_client_thread, (void*) drdynvc, 0, NULL))) + (LPTHREAD_START_ROUTINE) drdynvc_virtual_channel_client_thread, (void*) drdynvc, + 0, NULL))) { error = ERROR_INTERNAL_ERROR; WLog_ERR(TAG, "CreateThread failed!"); @@ -1457,7 +1451,6 @@ static UINT drdynvc_virtual_channel_event_connected(drdynvcPlugin* drdynvc, } return CHANNEL_RC_OK; - error: drdynvc_remove_open_handle_data(drdynvc->OpenHandle); return error; @@ -1482,16 +1475,14 @@ static UINT drdynvc_virtual_channel_event_disconnected(drdynvcPlugin* drdynvc) MessageQueue_Free(drdynvc->queue); CloseHandle(drdynvc->thread); - drdynvc->queue = NULL; drdynvc->thread = NULL; - status = drdynvc->channelEntryPoints.pVirtualChannelClose(drdynvc->OpenHandle); if (status != CHANNEL_RC_OK) { WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08X]", - WTSErrorToString(status), status); + WTSErrorToString(status), status); } if (drdynvc->data_in) @@ -1523,12 +1514,11 @@ static UINT drdynvc_virtual_channel_event_terminated(drdynvcPlugin* drdynvc) } static VOID VCAPITYPE drdynvc_virtual_channel_init_event(LPVOID pInitHandle, - UINT event, LPVOID pData, - UINT dataLength) + UINT event, LPVOID pData, + UINT dataLength) { drdynvcPlugin* drdynvc; UINT error = CHANNEL_RC_OK; - drdynvc = (drdynvcPlugin*) drdynvc_get_init_handle_data(pInitHandle); if (!drdynvc) @@ -1540,22 +1530,31 @@ 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 reported an error"); } /** @@ -1578,7 +1577,6 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) DrdynvcClientContext* context; CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx; UINT error; - drdynvc = (drdynvcPlugin*) calloc(1, sizeof(drdynvcPlugin)); if (!drdynvc) @@ -1588,18 +1586,15 @@ 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->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER)) + (pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER)) { context = (DrdynvcClientContext*) calloc(1, sizeof(DrdynvcClientContext)); @@ -1612,40 +1607,39 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) context->handle = (void*) drdynvc; context->custom = NULL; - drdynvc->context = context; - context->GetVersion = drdynvc_get_version; drdynvc->rdpcontext = pEntryPointsEx->context; - *(pEntryPointsEx->ppInterface) = (void*) context; } 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)); - + 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); + &drdynvc->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, + drdynvc_virtual_channel_init_event); if (CHANNEL_RC_OK != rc) { WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]", - WTSErrorToString(rc), rc); + WTSErrorToString(rc), rc); free(drdynvc); free(*(pEntryPointsEx->ppInterface)); *(pEntryPointsEx->ppInterface) = NULL; return FALSE; } - drdynvc->channelEntryPoints.pInterface = *(drdynvc->channelEntryPoints.ppInterface); - drdynvc->channelEntryPoints.ppInterface = &(drdynvc->channelEntryPoints.pInterface); + drdynvc->channelEntryPoints.pInterface = * + (drdynvc->channelEntryPoints.ppInterface); + drdynvc->channelEntryPoints.ppInterface = & + (drdynvc->channelEntryPoints.pInterface); - if ((error = drdynvc_add_init_handle_data(drdynvc->InitHandle, (void*) drdynvc))) + if ((error = drdynvc_add_init_handle_data(drdynvc->InitHandle, + (void*) drdynvc))) { - WLog_ERR(TAG, "drdynvc_add_init_handle_data failed with error %lu!",error); + WLog_ERR(TAG, "drdynvc_add_init_handle_data failed with error %lu!", error); free(drdynvc); free(*(pEntryPointsEx->ppInterface)); *(pEntryPointsEx->ppInterface) = NULL;