From dadc5262ae40af89f02944797e90c4ef976f5aea Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 9 Aug 2016 12:04:06 +0200 Subject: [PATCH] Removed static channel variables. Global static variables do not work, if more than one instance of an RDP client is running in the same process space. Removed the varaibles where possible and replaced them with thread local storage where necessary. --- channels/cliprdr/client/cliprdr_main.c | 535 ++++++++++++++------------------- channels/cliprdr/client/cliprdr_main.h | 3 - channels/drdynvc/client/drdynvc_main.c | 149 +-------- channels/encomsp/client/encomsp_main.c | 417 +++++++++++-------------- channels/rail/client/rail_main.c | 338 +++++++++------------ channels/rdpdr/client/rdpdr_main.c | 134 +-------- channels/rdpsnd/client/rdpsnd_main.c | 495 ++++++++++++++---------------- channels/remdesk/client/remdesk_main.c | 345 ++++++++------------- client/Android/android_freerdp.c | 2 +- client/DirectFB/dfreerdp.c | 113 +++---- client/Mac/mf_client.m | 2 +- client/Sample/freerdp.c | 40 +-- client/Wayland/wlfreerdp.c | 2 +- client/Windows/wf_client.c | 116 ++++--- client/X11/xf_client.c | 2 +- client/iOS/FreeRDP/ios_freerdp.m | 2 +- include/freerdp/channels/channels.h | 39 ++- include/freerdp/freerdp.h | 71 +++-- libfreerdp/core/client.c | 118 +++----- libfreerdp/core/client.h | 4 +- libfreerdp/core/freerdp.c | 150 +++++---- winpr/include/winpr/winpr.h | 50 +-- 22 files changed, 1279 insertions(+), 1848 deletions(-) diff --git a/channels/cliprdr/client/cliprdr_main.c b/channels/cliprdr/client/cliprdr_main.c index 7ca0c94..43be6d5 100644 --- a/channels/cliprdr/client/cliprdr_main.c +++ b/channels/cliprdr/client/cliprdr_main.c @@ -34,7 +34,7 @@ #include "cliprdr_main.h" #include "cliprdr_format.h" -const char* const CB_MSG_TYPE_STRINGS[] = +static const char* const CB_MSG_TYPE_STRINGS[] = { "", "CB_MONITOR_READY", @@ -50,19 +50,23 @@ const char* const CB_MSG_TYPE_STRINGS[] = "CB_UNLOCK_CLIPDATA" }; +static WINPR_TLS cliprdrPlugin* s_TLSPluginContext = NULL; + CliprdrClientContext* cliprdr_get_client_interface(cliprdrPlugin* cliprdr) { CliprdrClientContext* pInterface; + if (!cliprdr) return NULL; + pInterface = (CliprdrClientContext*) cliprdr->channelEntryPoints.pInterface; return pInterface; } -wStream* cliprdr_packet_new(UINT16 msgType, UINT16 msgFlags, UINT32 dataLen) +static wStream* cliprdr_packet_new(UINT16 msgType, UINT16 msgFlags, + UINT32 dataLen) { wStream* s; - s = Stream_New(NULL, dataLen + 8); if (!s) @@ -73,10 +77,8 @@ wStream* cliprdr_packet_new(UINT16 msgType, UINT16 msgFlags, UINT32 dataLen) Stream_Write_UINT16(s, msgType); Stream_Write_UINT16(s, msgFlags); - /* Write actual length after the entire packet has been constructed. */ Stream_Seek(s, 4); - return s; } @@ -85,20 +87,16 @@ wStream* cliprdr_packet_new(UINT16 msgType, UINT16 msgFlags, UINT32 dataLen) * * @return 0 on success, otherwise a Win32 error code */ -UINT cliprdr_packet_send(cliprdrPlugin* cliprdr, wStream* s) +static UINT cliprdr_packet_send(cliprdrPlugin* cliprdr, wStream* s) { UINT32 pos; UINT32 dataLen; UINT status = CHANNEL_RC_OK; - pos = Stream_GetPosition(s); - dataLen = pos - 8; - Stream_SetPosition(s, 4); Stream_Write_UINT32(s, dataLen); Stream_SetPosition(s, pos); - #ifdef WITH_DEBUG_CLIPRDR WLog_DBG(TAG, "Cliprdr Sending (%d bytes)", dataLen + 8); winpr_HexDump(TAG, WLOG_DEBUG, Stream_Buffer(s), dataLen + 8); @@ -111,17 +109,17 @@ UINT cliprdr_packet_send(cliprdrPlugin* cliprdr, wStream* s) else { status = cliprdr->channelEntryPoints.pVirtualChannelWrite(cliprdr->OpenHandle, - Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); + Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); } if (status != CHANNEL_RC_OK) WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", - WTSErrorToString(status), status); + WTSErrorToString(status), status); return status; } -void cliprdr_print_general_capability_flags(UINT32 flags) +static void cliprdr_print_general_capability_flags(UINT32 flags) { WLog_INFO(TAG, "generalFlags (0x%08X) {", flags); @@ -145,7 +143,8 @@ void cliprdr_print_general_capability_flags(UINT32 flags) * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_process_general_capability(cliprdrPlugin* cliprdr, wStream* s) +static UINT cliprdr_process_general_capability(cliprdrPlugin* cliprdr, + wStream* s) { UINT32 version; UINT32 generalFlags; @@ -162,20 +161,22 @@ static UINT cliprdr_process_general_capability(cliprdrPlugin* cliprdr, wStream* Stream_Read_UINT32(s, version); /* version (4 bytes) */ Stream_Read_UINT32(s, generalFlags); /* generalFlags (4 bytes) */ - DEBUG_CLIPRDR("Version: %d", version); #ifdef WITH_DEBUG_CLIPRDR cliprdr_print_general_capability_flags(generalFlags); #endif if (cliprdr->useLongFormatNames) - cliprdr->useLongFormatNames = (generalFlags & CB_USE_LONG_FORMAT_NAMES) ? TRUE : FALSE; + cliprdr->useLongFormatNames = (generalFlags & CB_USE_LONG_FORMAT_NAMES) ? TRUE : + FALSE; if (cliprdr->streamFileClipEnabled) - cliprdr->streamFileClipEnabled = (generalFlags & CB_STREAM_FILECLIP_ENABLED) ? TRUE : FALSE; + cliprdr->streamFileClipEnabled = (generalFlags & CB_STREAM_FILECLIP_ENABLED) ? + TRUE : FALSE; if (cliprdr->fileClipNoFilePaths) - cliprdr->fileClipNoFilePaths = (generalFlags & CB_FILECLIP_NO_FILE_PATHS) ? TRUE : FALSE; + cliprdr->fileClipNoFilePaths = (generalFlags & CB_FILECLIP_NO_FILE_PATHS) ? + TRUE : FALSE; if (cliprdr->canLockClipData) cliprdr->canLockClipData = (generalFlags & CB_CAN_LOCK_CLIPDATA) ? TRUE : FALSE; @@ -189,14 +190,14 @@ static UINT cliprdr_process_general_capability(cliprdrPlugin* cliprdr, wStream* } capabilities.cCapabilitiesSets = 1; - capabilities.capabilitySets = (CLIPRDR_CAPABILITY_SET*) &(generalCapabilitySet); + capabilities.capabilitySets = (CLIPRDR_CAPABILITY_SET*) & + (generalCapabilitySet); generalCapabilitySet.capabilitySetType = CB_CAPSTYPE_GENERAL; generalCapabilitySet.capabilitySetLength = 12; generalCapabilitySet.version = version; generalCapabilitySet.generalFlags = generalFlags; - - IFCALLRET(context->ServerCapabilities, error, context, &capabilities); + if (error) WLog_ERR(TAG, "ServerCapabilities failed with error %lu!", error); @@ -208,17 +209,16 @@ static UINT cliprdr_process_general_capability(cliprdrPlugin* cliprdr, wStream* * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, wStream* s, UINT16 length, UINT16 flags) +static UINT cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, wStream* s, + UINT16 length, UINT16 flags) { UINT16 index; UINT16 lengthCapability; UINT16 cCapabilitiesSets; UINT16 capabilitySetType; UINT error = CHANNEL_RC_OK; - Stream_Read_UINT16(s, cCapabilitiesSets); /* cCapabilitiesSets (2 bytes) */ Stream_Seek_UINT16(s); /* pad1 (2 bytes) */ - WLog_Print(cliprdr->log, WLOG_DEBUG, "ServerCapabilities"); for (index = 0; index < cCapabilitiesSets; index++) @@ -231,9 +231,11 @@ static UINT cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, wStream* s, UINT16 case CB_CAPSTYPE_GENERAL: if ((error = cliprdr_process_general_capability(cliprdr, s))) { - WLog_ERR(TAG, "cliprdr_process_general_capability failed with error %lu!", error); + WLog_ERR(TAG, "cliprdr_process_general_capability failed with error %lu!", + error); return error; } + break; default: @@ -251,12 +253,12 @@ static UINT cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, wStream* s, UINT16 * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_process_monitor_ready(cliprdrPlugin* cliprdr, wStream* s, UINT16 length, UINT16 flags) +static UINT cliprdr_process_monitor_ready(cliprdrPlugin* cliprdr, wStream* s, + UINT16 length, UINT16 flags) { CLIPRDR_MONITOR_READY monitorReady; CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr); UINT error = CHANNEL_RC_OK; - WLog_Print(cliprdr->log, WLOG_DEBUG, "MonitorReady"); if (!context->custom) @@ -273,7 +275,6 @@ static UINT cliprdr_process_monitor_ready(cliprdrPlugin* cliprdr, wStream* s, UI * When the server capabilities pdu is not used, default capabilities * corresponding to a generalFlags field set to zero are assumed. */ - cliprdr->useLongFormatNames = FALSE; cliprdr->streamFileClipEnabled = FALSE; cliprdr->fileClipNoFilePaths = TRUE; @@ -283,8 +284,8 @@ static UINT cliprdr_process_monitor_ready(cliprdrPlugin* cliprdr, wStream* s, UI monitorReady.msgType = CB_MONITOR_READY; monitorReady.msgFlags = flags; monitorReady.dataLen = length; - IFCALLRET(context->MonitorReady, error, context, &monitorReady); + if (error) WLog_ERR(TAG, "MonitorReady failed with error %lu!", error); @@ -296,12 +297,12 @@ static UINT cliprdr_process_monitor_ready(cliprdrPlugin* cliprdr, wStream* s, UI * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_process_filecontents_request(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags) +static UINT cliprdr_process_filecontents_request(cliprdrPlugin* cliprdr, + wStream* s, UINT32 length, UINT16 flags) { CLIPRDR_FILE_CONTENTS_REQUEST request; CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr); UINT error = CHANNEL_RC_OK; - WLog_Print(cliprdr->log, WLOG_DEBUG, "FileContentsRequest"); if (!context->custom) @@ -319,20 +320,20 @@ static UINT cliprdr_process_filecontents_request(cliprdrPlugin* cliprdr, wStream request.msgType = CB_FILECONTENTS_REQUEST; request.msgFlags = flags; request.dataLen = length; - Stream_Read_UINT32(s, request.streamId); /* streamId (4 bytes) */ Stream_Read_UINT32(s, request.listIndex); /* listIndex (4 bytes) */ Stream_Read_UINT32(s, request.dwFlags); /* dwFlags (4 bytes) */ Stream_Read_UINT32(s, request.nPositionLow); /* nPositionLow (4 bytes) */ Stream_Read_UINT32(s, request.nPositionHigh); /* nPositionHigh (4 bytes) */ Stream_Read_UINT32(s, request.cbRequested); /* cbRequested (4 bytes) */ + if (Stream_GetRemainingLength(s) >= 4) Stream_Read_UINT32(s, request.clipDataId); /* clipDataId (4 bytes) */ else request.clipDataId = 0; - IFCALLRET(context->ServerFileContentsRequest, error, context, &request); + if (error) WLog_ERR(TAG, "ServerFileContentsRequest failed with error %lu!", error); @@ -344,12 +345,12 @@ static UINT cliprdr_process_filecontents_request(cliprdrPlugin* cliprdr, wStream * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_process_filecontents_response(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags) +static UINT cliprdr_process_filecontents_response(cliprdrPlugin* cliprdr, + wStream* s, UINT32 length, UINT16 flags) { CLIPRDR_FILE_CONTENTS_RESPONSE response; CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr); UINT error = CHANNEL_RC_OK; - WLog_Print(cliprdr->log, WLOG_DEBUG, "FileContentsResponse"); if (!context->custom) @@ -367,14 +368,11 @@ static UINT cliprdr_process_filecontents_response(cliprdrPlugin* cliprdr, wStrea response.msgType = CB_FILECONTENTS_RESPONSE; response.msgFlags = flags; response.dataLen = length; - Stream_Read_UINT32(s, response.streamId); /* streamId (4 bytes) */ - response.cbRequested = length - 4; response.requestedData = Stream_Pointer(s); /* requestedFileContentsData */ - - IFCALLRET(context->ServerFileContentsResponse, error, context, &response); + if (error) WLog_ERR(TAG, "ServerFileContentsResponse failed with error %lu!", error); @@ -386,12 +384,12 @@ static UINT cliprdr_process_filecontents_response(cliprdrPlugin* cliprdr, wStrea * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_process_lock_clipdata(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags) +static UINT cliprdr_process_lock_clipdata(cliprdrPlugin* cliprdr, wStream* s, + UINT32 length, UINT16 flags) { CLIPRDR_LOCK_CLIPBOARD_DATA lockClipboardData; CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr); UINT error = CHANNEL_RC_OK; - WLog_Print(cliprdr->log, WLOG_DEBUG, "LockClipData"); if (!context->custom) @@ -409,10 +407,9 @@ static UINT cliprdr_process_lock_clipdata(cliprdrPlugin* cliprdr, wStream* s, UI lockClipboardData.msgType = CB_LOCK_CLIPDATA; lockClipboardData.msgFlags = flags; lockClipboardData.dataLen = length; - Stream_Read_UINT32(s, lockClipboardData.clipDataId); /* clipDataId (4 bytes) */ - IFCALLRET(context->ServerLockClipboardData, error, context, &lockClipboardData); + if (error) WLog_ERR(TAG, "ServerLockClipboardData failed with error %lu!", error); @@ -424,12 +421,12 @@ static UINT cliprdr_process_lock_clipdata(cliprdrPlugin* cliprdr, wStream* s, UI * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_process_unlock_clipdata(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags) +static UINT cliprdr_process_unlock_clipdata(cliprdrPlugin* cliprdr, wStream* s, + UINT32 length, UINT16 flags) { CLIPRDR_UNLOCK_CLIPBOARD_DATA unlockClipboardData; CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr); UINT error = CHANNEL_RC_OK; - WLog_Print(cliprdr->log, WLOG_DEBUG, "UnlockClipData"); if (!context->custom) @@ -447,11 +444,11 @@ static UINT cliprdr_process_unlock_clipdata(cliprdrPlugin* cliprdr, wStream* s, unlockClipboardData.msgType = CB_UNLOCK_CLIPDATA; unlockClipboardData.msgFlags = flags; unlockClipboardData.dataLen = length; + Stream_Read_UINT32(s, + unlockClipboardData.clipDataId); /* clipDataId (4 bytes) */ + IFCALLRET(context->ServerUnlockClipboardData, error, context, + &unlockClipboardData); - Stream_Read_UINT32(s, unlockClipboardData.clipDataId); /* clipDataId (4 bytes) */ - - - IFCALLRET(context->ServerUnlockClipboardData, error, context, &unlockClipboardData); if (error) WLog_ERR(TAG, "ServerUnlockClipboardData failed with error %lu!", error); @@ -469,14 +466,12 @@ static UINT cliprdr_order_recv(cliprdrPlugin* cliprdr, wStream* s) UINT16 msgFlags; UINT32 dataLen; UINT error; - Stream_Read_UINT16(s, msgType); /* msgType (2 bytes) */ Stream_Read_UINT16(s, msgFlags); /* msgFlags (2 bytes) */ Stream_Read_UINT32(s, dataLen); /* dataLen (4 bytes) */ - #ifdef WITH_DEBUG_CLIPRDR WLog_DBG(TAG, "msgType: %s (%d), msgFlags: %d dataLen: %d", - CB_MSG_TYPE_STRINGS[msgType], msgType, msgFlags, dataLen); + CB_MSG_TYPE_STRINGS[msgType], msgType, msgFlags, dataLen); winpr_HexDump(TAG, WLOG_DEBUG, Stream_Buffer(s), dataLen + 8); #endif @@ -485,51 +480,71 @@ static UINT cliprdr_order_recv(cliprdrPlugin* cliprdr, wStream* s) case CB_CLIP_CAPS: if ((error = cliprdr_process_clip_caps(cliprdr, s, dataLen, msgFlags))) WLog_ERR(TAG, "cliprdr_process_clip_caps failed with error %lu!", error); + break; case CB_MONITOR_READY: if ((error = cliprdr_process_monitor_ready(cliprdr, s, dataLen, msgFlags))) WLog_ERR(TAG, "cliprdr_process_monitor_ready failed with error %lu!", error); + break; case CB_FORMAT_LIST: if ((error = cliprdr_process_format_list(cliprdr, s, dataLen, msgFlags))) WLog_ERR(TAG, "cliprdr_process_format_list failed with error %lu!", error); + break; case CB_FORMAT_LIST_RESPONSE: - if ((error = cliprdr_process_format_list_response(cliprdr, s, dataLen, msgFlags))) - WLog_ERR(TAG, "cliprdr_process_format_list_response failed with error %lu!", error); + if ((error = cliprdr_process_format_list_response(cliprdr, s, dataLen, + msgFlags))) + WLog_ERR(TAG, "cliprdr_process_format_list_response failed with error %lu!", + error); + break; case CB_FORMAT_DATA_REQUEST: - if ((error = cliprdr_process_format_data_request(cliprdr, s, dataLen, msgFlags))) - WLog_ERR(TAG, "cliprdr_process_format_data_request failed with error %lu!", error); + if ((error = cliprdr_process_format_data_request(cliprdr, s, dataLen, + msgFlags))) + WLog_ERR(TAG, "cliprdr_process_format_data_request failed with error %lu!", + error); + break; case CB_FORMAT_DATA_RESPONSE: - if ((error = cliprdr_process_format_data_response(cliprdr, s, dataLen, msgFlags))) - WLog_ERR(TAG, "cliprdr_process_format_data_response failed with error %lu!", error); + if ((error = cliprdr_process_format_data_response(cliprdr, s, dataLen, + msgFlags))) + WLog_ERR(TAG, "cliprdr_process_format_data_response failed with error %lu!", + error); + break; case CB_FILECONTENTS_REQUEST: - if ((error = cliprdr_process_filecontents_request(cliprdr, s, dataLen, msgFlags))) - WLog_ERR(TAG, "cliprdr_process_filecontents_request failed with error %lu!", error); + if ((error = cliprdr_process_filecontents_request(cliprdr, s, dataLen, + msgFlags))) + WLog_ERR(TAG, "cliprdr_process_filecontents_request failed with error %lu!", + error); + break; case CB_FILECONTENTS_RESPONSE: - if ((error = cliprdr_process_filecontents_response(cliprdr, s, dataLen, msgFlags))) - WLog_ERR(TAG, "cliprdr_process_filecontents_response failed with error %lu!", error); + if ((error = cliprdr_process_filecontents_response(cliprdr, s, dataLen, + msgFlags))) + WLog_ERR(TAG, "cliprdr_process_filecontents_response failed with error %lu!", + error); + break; case CB_LOCK_CLIPDATA: if ((error = cliprdr_process_lock_clipdata(cliprdr, s, dataLen, msgFlags))) WLog_ERR(TAG, "cliprdr_process_lock_clipdata failed with error %lu!", error); + break; case CB_UNLOCK_CLIPDATA: if ((error = cliprdr_process_unlock_clipdata(cliprdr, s, dataLen, msgFlags))) WLog_ERR(TAG, "cliprdr_process_lock_clipdata failed with error %lu!", error); + break; default: @@ -551,12 +566,12 @@ static UINT cliprdr_order_recv(cliprdrPlugin* cliprdr, wStream* s) * * @return 0 on success, otherwise a Win32 error code */ -UINT cliprdr_client_capabilities(CliprdrClientContext* context, CLIPRDR_CAPABILITIES* capabilities) +static UINT cliprdr_client_capabilities(CliprdrClientContext* context, + CLIPRDR_CAPABILITIES* capabilities) { wStream* s; CLIPRDR_GENERAL_CAPABILITY_SET* generalCapabilitySet; cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle; - s = cliprdr_packet_new(CB_CLIP_CAPS, 0, 4 + CB_CAPSTYPE_GENERAL_LEN); if (!s) @@ -567,13 +582,14 @@ UINT cliprdr_client_capabilities(CliprdrClientContext* context, CLIPRDR_CAPABILI Stream_Write_UINT16(s, 1); /* cCapabilitiesSets */ Stream_Write_UINT16(s, 0); /* pad1 */ - - generalCapabilitySet = (CLIPRDR_GENERAL_CAPABILITY_SET*) capabilities->capabilitySets; - Stream_Write_UINT16(s, generalCapabilitySet->capabilitySetType); /* capabilitySetType */ - Stream_Write_UINT16(s, generalCapabilitySet->capabilitySetLength); /* lengthCapability */ + generalCapabilitySet = (CLIPRDR_GENERAL_CAPABILITY_SET*) + capabilities->capabilitySets; + Stream_Write_UINT16(s, + generalCapabilitySet->capabilitySetType); /* capabilitySetType */ + Stream_Write_UINT16(s, + generalCapabilitySet->capabilitySetLength); /* lengthCapability */ Stream_Write_UINT32(s, generalCapabilitySet->version); /* version */ Stream_Write_UINT32(s, generalCapabilitySet->generalFlags); /* generalFlags */ - WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientCapabilities"); return cliprdr_packet_send(cliprdr, s); } @@ -583,13 +599,13 @@ UINT cliprdr_client_capabilities(CliprdrClientContext* context, CLIPRDR_CAPABILI * * @return 0 on success, otherwise a Win32 error code */ -UINT cliprdr_temp_directory(CliprdrClientContext* context, CLIPRDR_TEMP_DIRECTORY* tempDirectory) +static UINT cliprdr_temp_directory(CliprdrClientContext* context, + CLIPRDR_TEMP_DIRECTORY* tempDirectory) { int length; wStream* s; WCHAR* wszTempDir = NULL; cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle; - s = cliprdr_packet_new(CB_TEMP_DIRECTORY, 0, 520 * 2); if (!s) @@ -598,7 +614,8 @@ UINT cliprdr_temp_directory(CliprdrClientContext* context, CLIPRDR_TEMP_DIRECTOR return ERROR_INTERNAL_ERROR; } - length = ConvertToUnicode(CP_UTF8, 0, tempDirectory->szTempDir, -1, &wszTempDir, 0); + length = ConvertToUnicode(CP_UTF8, 0, tempDirectory->szTempDir, -1, &wszTempDir, + 0); if (length < 0) return ERROR_INTERNAL_ERROR; @@ -608,12 +625,9 @@ UINT cliprdr_temp_directory(CliprdrClientContext* context, CLIPRDR_TEMP_DIRECTOR Stream_Write(s, wszTempDir, length * 2); Stream_Zero(s, (520 - length) * 2); - free(wszTempDir); - WLog_Print(cliprdr->log, WLOG_DEBUG, "TempDirectory: %s", - tempDirectory->szTempDir); - + tempDirectory->szTempDir); return cliprdr_packet_send(cliprdr, s); } @@ -622,7 +636,8 @@ UINT cliprdr_temp_directory(CliprdrClientContext* context, CLIPRDR_TEMP_DIRECTOR * * @return 0 on success, otherwise a Win32 error code */ -UINT cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LIST* formatList) +static UINT cliprdr_client_format_list(CliprdrClientContext* context, + CLIPRDR_FORMAT_LIST* formatList) { wStream* s; UINT32 index; @@ -640,7 +655,6 @@ UINT cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LI if (!cliprdr->useLongFormatNames) { length = formatList->numFormats * 36; - s = cliprdr_packet_new(CB_FORMAT_LIST, 0, length); if (!s) @@ -651,13 +665,10 @@ UINT cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LI for (index = 0; index < formatList->numFormats; index++) { - format = (CLIPRDR_FORMAT*) &(formatList->formats[index]); - + format = (CLIPRDR_FORMAT*) & (formatList->formats[index]); Stream_Write_UINT32(s, format->formatId); /* formatId (4 bytes) */ - formatNameSize = 0; formatNameLength = 0; - szFormatName = format->formatName; if (asciiNames) @@ -676,7 +687,8 @@ UINT cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LI wszFormatName = NULL; if (szFormatName) - formatNameSize = ConvertToUnicode(CP_UTF8, 0, szFormatName, -1, &wszFormatName, 0); + formatNameSize = ConvertToUnicode(CP_UTF8, 0, szFormatName, -1, &wszFormatName, + 0); if (formatNameSize > 15) formatNameSize = 15; @@ -685,7 +697,6 @@ UINT cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LI Stream_Write(s, wszFormatName, formatNameSize * 2); Stream_Zero(s, 32 - (formatNameSize * 2)); - free(wszFormatName); } } @@ -694,12 +705,13 @@ UINT cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LI { for (index = 0; index < formatList->numFormats; index++) { - format = (CLIPRDR_FORMAT*) &(formatList->formats[index]); + format = (CLIPRDR_FORMAT*) & (formatList->formats[index]); length += 4; formatNameSize = 2; if (format->formatName) - formatNameSize = MultiByteToWideChar(CP_UTF8, 0, format->formatName, -1, NULL, 0) * 2; + formatNameSize = MultiByteToWideChar(CP_UTF8, 0, format->formatName, -1, NULL, + 0) * 2; length += formatNameSize; } @@ -714,7 +726,7 @@ UINT cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LI for (index = 0; index < formatList->numFormats; index++) { - format = (CLIPRDR_FORMAT*) &(formatList->formats[index]); + format = (CLIPRDR_FORMAT*) & (formatList->formats[index]); Stream_Write_UINT32(s, format->formatId); /* formatId (4 bytes) */ if (format->formatName) @@ -722,7 +734,7 @@ UINT cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LI lpWideCharStr = (LPWSTR) Stream_Pointer(s); cchWideChar = (Stream_Capacity(s) - Stream_GetPosition(s)) / 2; formatNameSize = MultiByteToWideChar(CP_UTF8, 0, - format->formatName, -1, lpWideCharStr, cchWideChar) * 2; + format->formatName, -1, lpWideCharStr, cchWideChar) * 2; Stream_Seek(s, formatNameSize); } else @@ -733,8 +745,7 @@ UINT cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LI } WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientFormatList: numFormats: %d", - formatList->numFormats); - + formatList->numFormats); return cliprdr_packet_send(cliprdr, s); } @@ -743,15 +754,15 @@ UINT cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LI * * @return 0 on success, otherwise a Win32 error code */ -UINT cliprdr_client_format_list_response(CliprdrClientContext* context, CLIPRDR_FORMAT_LIST_RESPONSE* formatListResponse) +static UINT cliprdr_client_format_list_response(CliprdrClientContext* context, + CLIPRDR_FORMAT_LIST_RESPONSE* formatListResponse) { wStream* s; cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle; - formatListResponse->msgType = CB_FORMAT_LIST_RESPONSE; formatListResponse->dataLen = 0; - - s = cliprdr_packet_new(formatListResponse->msgType, formatListResponse->msgFlags, formatListResponse->dataLen); + s = cliprdr_packet_new(formatListResponse->msgType, + formatListResponse->msgFlags, formatListResponse->dataLen); if (!s) { @@ -768,11 +779,11 @@ UINT cliprdr_client_format_list_response(CliprdrClientContext* context, CLIPRDR_ * * @return 0 on success, otherwise a Win32 error code */ -UINT cliprdr_client_lock_clipboard_data(CliprdrClientContext* context, CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData) +static UINT cliprdr_client_lock_clipboard_data(CliprdrClientContext* context, + CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData) { wStream* s; cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle; - s = cliprdr_packet_new(CB_LOCK_CLIPDATA, 0, 4); if (!s) @@ -781,11 +792,11 @@ UINT cliprdr_client_lock_clipboard_data(CliprdrClientContext* context, CLIPRDR_L return ERROR_INTERNAL_ERROR; } - Stream_Write_UINT32(s, lockClipboardData->clipDataId); /* clipDataId (4 bytes) */ - - WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientLockClipboardData: clipDataId: 0x%04X", - lockClipboardData->clipDataId); - + Stream_Write_UINT32(s, + lockClipboardData->clipDataId); /* clipDataId (4 bytes) */ + WLog_Print(cliprdr->log, WLOG_DEBUG, + "ClientLockClipboardData: clipDataId: 0x%04X", + lockClipboardData->clipDataId); return cliprdr_packet_send(cliprdr, s);; } @@ -794,23 +805,24 @@ UINT cliprdr_client_lock_clipboard_data(CliprdrClientContext* context, CLIPRDR_L * * @return 0 on success, otherwise a Win32 error code */ -UINT cliprdr_client_unlock_clipboard_data(CliprdrClientContext* context, CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData) +static UINT cliprdr_client_unlock_clipboard_data(CliprdrClientContext* context, + CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData) { wStream* s; cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle; - s = cliprdr_packet_new(CB_UNLOCK_CLIPDATA, 0, 4); - if (!s) { + if (!s) + { WLog_ERR(TAG, "cliprdr_packet_new failed!"); return ERROR_INTERNAL_ERROR; } - Stream_Write_UINT32(s, unlockClipboardData->clipDataId); /* clipDataId (4 bytes) */ - - WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientUnlockClipboardData: clipDataId: 0x%04X", - unlockClipboardData->clipDataId); - + Stream_Write_UINT32(s, + unlockClipboardData->clipDataId); /* clipDataId (4 bytes) */ + WLog_Print(cliprdr->log, WLOG_DEBUG, + "ClientUnlockClipboardData: clipDataId: 0x%04X", + unlockClipboardData->clipDataId); return cliprdr_packet_send(cliprdr, s); } @@ -819,16 +831,16 @@ UINT cliprdr_client_unlock_clipboard_data(CliprdrClientContext* context, CLIPRDR * * @return 0 on success, otherwise a Win32 error code */ -UINT cliprdr_client_format_data_request(CliprdrClientContext* context, CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest) +static UINT cliprdr_client_format_data_request(CliprdrClientContext* context, + CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest) { wStream* s; cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle; - formatDataRequest->msgType = CB_FORMAT_DATA_REQUEST; formatDataRequest->msgFlags = 0; formatDataRequest->dataLen = 4; - - s = cliprdr_packet_new(formatDataRequest->msgType, formatDataRequest->msgFlags, formatDataRequest->dataLen); + s = cliprdr_packet_new(formatDataRequest->msgType, formatDataRequest->msgFlags, + formatDataRequest->dataLen); if (!s) { @@ -836,8 +848,8 @@ UINT cliprdr_client_format_data_request(CliprdrClientContext* context, CLIPRDR_F return ERROR_INTERNAL_ERROR; } - Stream_Write_UINT32(s, formatDataRequest->requestedFormatId); /* requestedFormatId (4 bytes) */ - + Stream_Write_UINT32(s, + formatDataRequest->requestedFormatId); /* requestedFormatId (4 bytes) */ WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientFormatDataRequest"); return cliprdr_packet_send(cliprdr, s); } @@ -847,14 +859,14 @@ UINT cliprdr_client_format_data_request(CliprdrClientContext* context, CLIPRDR_F * * @return 0 on success, otherwise a Win32 error code */ -UINT cliprdr_client_format_data_response(CliprdrClientContext* context, CLIPRDR_FORMAT_DATA_RESPONSE* formatDataResponse) +static UINT cliprdr_client_format_data_response(CliprdrClientContext* context, + CLIPRDR_FORMAT_DATA_RESPONSE* formatDataResponse) { wStream* s; cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle; - formatDataResponse->msgType = CB_FORMAT_DATA_RESPONSE; - - s = cliprdr_packet_new(formatDataResponse->msgType, formatDataResponse->msgFlags, formatDataResponse->dataLen); + s = cliprdr_packet_new(formatDataResponse->msgType, + formatDataResponse->msgFlags, formatDataResponse->dataLen); if (!s) { @@ -862,8 +874,8 @@ UINT cliprdr_client_format_data_response(CliprdrClientContext* context, CLIPRDR_ return ERROR_INTERNAL_ERROR; } - Stream_Write(s, formatDataResponse->requestedFormatData, formatDataResponse->dataLen); - + Stream_Write(s, formatDataResponse->requestedFormatData, + formatDataResponse->dataLen); WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientFormatDataResponse"); return cliprdr_packet_send(cliprdr, s); } @@ -873,11 +885,11 @@ UINT cliprdr_client_format_data_response(CliprdrClientContext* context, CLIPRDR_ * * @return 0 on success, otherwise a Win32 error code */ -UINT cliprdr_client_file_contents_request(CliprdrClientContext* context, CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest) +static UINT cliprdr_client_file_contents_request(CliprdrClientContext* context, + CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest) { wStream* s; cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle; - s = cliprdr_packet_new(CB_FILECONTENTS_REQUEST, 0, 28); if (!s) @@ -887,16 +899,20 @@ UINT cliprdr_client_file_contents_request(CliprdrClientContext* context, CLIPRDR } Stream_Write_UINT32(s, fileContentsRequest->streamId); /* streamId (4 bytes) */ - Stream_Write_UINT32(s, fileContentsRequest->listIndex); /* listIndex (4 bytes) */ + Stream_Write_UINT32(s, + fileContentsRequest->listIndex); /* listIndex (4 bytes) */ Stream_Write_UINT32(s, fileContentsRequest->dwFlags); /* dwFlags (4 bytes) */ - Stream_Write_UINT32(s, fileContentsRequest->nPositionLow); /* nPositionLow (4 bytes) */ - Stream_Write_UINT32(s, fileContentsRequest->nPositionHigh); /* nPositionHigh (4 bytes) */ - Stream_Write_UINT32(s, fileContentsRequest->cbRequested); /* cbRequested (4 bytes) */ - Stream_Write_UINT32(s, fileContentsRequest->clipDataId); /* clipDataId (4 bytes) */ - - WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientFileContentsRequest: streamId: 0x%04X", - fileContentsRequest->streamId); - + Stream_Write_UINT32(s, + fileContentsRequest->nPositionLow); /* nPositionLow (4 bytes) */ + Stream_Write_UINT32(s, + fileContentsRequest->nPositionHigh); /* nPositionHigh (4 bytes) */ + Stream_Write_UINT32(s, + fileContentsRequest->cbRequested); /* cbRequested (4 bytes) */ + Stream_Write_UINT32(s, + fileContentsRequest->clipDataId); /* clipDataId (4 bytes) */ + WLog_Print(cliprdr->log, WLOG_DEBUG, + "ClientFileContentsRequest: streamId: 0x%04X", + fileContentsRequest->streamId); return cliprdr_packet_send(cliprdr, s); } @@ -905,7 +921,8 @@ UINT cliprdr_client_file_contents_request(CliprdrClientContext* context, CLIPRDR * * @return 0 on success, otherwise a Win32 error code */ -UINT cliprdr_client_file_contents_response(CliprdrClientContext* context, CLIPRDR_FILE_CONTENTS_RESPONSE* fileContentsResponse) +static UINT cliprdr_client_file_contents_response(CliprdrClientContext* context, + CLIPRDR_FILE_CONTENTS_RESPONSE* fileContentsResponse) { wStream* s; cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle; @@ -914,7 +931,7 @@ UINT cliprdr_client_file_contents_response(CliprdrClientContext* context, CLIPRD fileContentsResponse->cbRequested = sizeof(UINT64); s = cliprdr_packet_new(CB_FILECONTENTS_RESPONSE, fileContentsResponse->msgFlags, - 4 + fileContentsResponse->cbRequested); + 4 + fileContentsResponse->cbRequested); if (!s) { @@ -923,120 +940,26 @@ UINT cliprdr_client_file_contents_response(CliprdrClientContext* context, CLIPRD } Stream_Write_UINT32(s, fileContentsResponse->streamId); /* streamId (4 bytes) */ - /** * requestedFileContentsData: * FILECONTENTS_SIZE: file size as UINT64 * FILECONTENTS_RANGE: file data from requested range */ - - Stream_Write(s, fileContentsResponse->requestedData, fileContentsResponse->cbRequested); - - WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientFileContentsResponse: streamId: 0x%04X", - fileContentsResponse->streamId); - + Stream_Write(s, fileContentsResponse->requestedData, + fileContentsResponse->cbRequested); + WLog_Print(cliprdr->log, WLOG_DEBUG, + "ClientFileContentsResponse: streamId: 0x%04X", + fileContentsResponse->streamId); return cliprdr_packet_send(cliprdr, s); } -/****************************************************************************************/ - -static wListDictionary* g_InitHandles = NULL; -static wListDictionary* g_OpenHandles = NULL; - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -UINT cliprdr_add_init_handle_data(void* pInitHandle, void* pUserData) -{ - if (!g_InitHandles) - g_InitHandles = ListDictionary_New(TRUE); - if (!g_InitHandles) - { - WLog_ERR(TAG, "ListDictionary_New failed!"); - return ERROR_NOT_ENOUGH_MEMORY; - } - - if (!ListDictionary_Add(g_InitHandles, pInitHandle, pUserData)) - { - WLog_ERR(TAG, "ListDictionary_Add failed!"); - return ERROR_INTERNAL_ERROR; - } - return CHANNEL_RC_OK; -} - -void* cliprdr_get_init_handle_data(void* pInitHandle) -{ - void* pUserData = NULL; - pUserData = ListDictionary_GetItemValue(g_InitHandles, pInitHandle); - return pUserData; -} - -void cliprdr_remove_init_handle_data(void* pInitHandle) -{ - ListDictionary_Remove(g_InitHandles, pInitHandle); - if (ListDictionary_Count(g_InitHandles) < 1) - { - ListDictionary_Free(g_InitHandles); - g_InitHandles = NULL; - } -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -UINT cliprdr_add_open_handle_data(DWORD openHandle, void* pUserData) -{ - void* pOpenHandle = (void*) (size_t) openHandle; - - if (!g_OpenHandles) - g_OpenHandles = ListDictionary_New(TRUE); - - if (!g_OpenHandles) - { - WLog_ERR(TAG, "ListDictionary_New failed!"); - return ERROR_NOT_ENOUGH_MEMORY; - } - - if (!ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData)) - { - WLog_ERR(TAG, "ListDictionary_Add failed!"); - return ERROR_INTERNAL_ERROR; - } - - return CHANNEL_RC_OK; -} - -void* cliprdr_get_open_handle_data(DWORD openHandle) -{ - void* pUserData = NULL; - void* pOpenHandle = (void*) (size_t) openHandle; - pUserData = ListDictionary_GetItemValue(g_OpenHandles, pOpenHandle); - return pUserData; -} - -void cliprdr_remove_open_handle_data(DWORD openHandle) -{ - void* pOpenHandle = (void*) (size_t) openHandle; - ListDictionary_Remove(g_OpenHandles, pOpenHandle); - - if (ListDictionary_Count(g_OpenHandles) < 1) - { - ListDictionary_Free(g_OpenHandles); - g_OpenHandles = NULL; - } -} - /** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT cliprdr_virtual_channel_event_data_received(cliprdrPlugin* cliprdr, - void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) + void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { wStream* data_in; @@ -1059,7 +982,6 @@ static UINT cliprdr_virtual_channel_event_data_received(cliprdrPlugin* cliprdr, return CHANNEL_RC_NO_MEMORY; } - if (!Stream_EnsureRemainingCapacity(data_in, (int) dataLength)) { Stream_Free(cliprdr->data_in, TRUE); @@ -1087,18 +1009,18 @@ static UINT cliprdr_virtual_channel_event_data_received(cliprdrPlugin* cliprdr, return ERROR_INTERNAL_ERROR; } } + return CHANNEL_RC_OK; } -static VOID VCAPITYPE cliprdr_virtual_channel_open_event(DWORD openHandle, UINT event, - LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) +static VOID VCAPITYPE cliprdr_virtual_channel_open_event(DWORD openHandle, + UINT event, + LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { - cliprdrPlugin* cliprdr; + cliprdrPlugin* cliprdr = s_TLSPluginContext; UINT error = CHANNEL_RC_OK; - cliprdr = (cliprdrPlugin*) cliprdr_get_open_handle_data(openHandle); - - if (!cliprdr) + if (!cliprdr || (cliprdr->OpenHandle != openHandle)) { WLog_ERR(TAG, "cliprdr_virtual_channel_open_event: error no match"); return; @@ -1107,7 +1029,8 @@ static VOID VCAPITYPE cliprdr_virtual_channel_open_event(DWORD openHandle, UINT switch (event) { case CHANNEL_EVENT_DATA_RECEIVED: - error = cliprdr_virtual_channel_event_data_received(cliprdr, pData, dataLength, totalLength, dataFlags); + error = cliprdr_virtual_channel_event_data_received(cliprdr, pData, dataLength, + totalLength, dataFlags); break; case CHANNEL_EVENT_WRITE_COMPLETE: @@ -1119,8 +1042,8 @@ static VOID VCAPITYPE cliprdr_virtual_channel_open_event(DWORD openHandle, UINT } if (error && cliprdr->context->rdpcontext) - setChannelError(cliprdr->context->rdpcontext, error, "cliprdr_virtual_channel_open_event reported an error"); - + setChannelError(cliprdr->context->rdpcontext, error, + "cliprdr_virtual_channel_open_event reported an error"); } static void* cliprdr_virtual_channel_client_thread(void* arg) @@ -1145,12 +1068,14 @@ static void* cliprdr_virtual_channel_client_thread(void* arg) error = ERROR_INTERNAL_ERROR; break; } + if (message.id == WMQ_QUIT) break; if (message.id == 0) { data = (wStream*) message.wParam; + if ((error = cliprdr_order_recv(cliprdr, data))) { WLog_ERR(TAG, "cliprdr_order_recv failed with error %lu!", error); @@ -1160,7 +1085,8 @@ static void* cliprdr_virtual_channel_client_thread(void* arg) } if (error && cliprdr->context->rdpcontext) - setChannelError(cliprdr->context->rdpcontext, error, "cliprdr_virtual_channel_client_thread reported an error"); + setChannelError(cliprdr->context->rdpcontext, error, + "cliprdr_virtual_channel_client_thread reported an error"); ExitThread((DWORD)error); return NULL; @@ -1171,28 +1097,23 @@ static void* cliprdr_virtual_channel_client_thread(void* arg) * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_virtual_channel_event_connected(cliprdrPlugin* cliprdr, LPVOID pData, UINT32 dataLength) +static UINT cliprdr_virtual_channel_event_connected(cliprdrPlugin* cliprdr, + LPVOID pData, UINT32 dataLength) { UINT32 status; - UINT error; - status = cliprdr->channelEntryPoints.pVirtualChannelOpen(cliprdr->InitHandle, - &cliprdr->OpenHandle, cliprdr->channelDef.name, cliprdr_virtual_channel_open_event); + &cliprdr->OpenHandle, cliprdr->channelDef.name, + cliprdr_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; } - if ((error = cliprdr_add_open_handle_data(cliprdr->OpenHandle, cliprdr))) - { - WLog_ERR(TAG, "cliprdr_add_open_handle_data failed with error %lu", error); - return error; - } - cliprdr->queue = MessageQueue_New(NULL); + if (!cliprdr->queue) { WLog_ERR(TAG, "MessageQueue_New failed!"); @@ -1200,13 +1121,15 @@ static UINT cliprdr_virtual_channel_event_connected(cliprdrPlugin* cliprdr, LPVO } if (!(cliprdr->thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) cliprdr_virtual_channel_client_thread, (void*) cliprdr, 0, NULL))) + (LPTHREAD_START_ROUTINE) cliprdr_virtual_channel_client_thread, (void*) cliprdr, + 0, NULL))) { WLog_ERR(TAG, "CreateThread failed!"); MessageQueue_Free(cliprdr->queue); cliprdr->queue = NULL; return ERROR_INTERNAL_ERROR; } + return CHANNEL_RC_OK; } @@ -1219,31 +1142,33 @@ static UINT cliprdr_virtual_channel_event_disconnected(cliprdrPlugin* cliprdr) { UINT rc; - if (MessageQueue_PostQuit(cliprdr->queue, 0) && (WaitForSingleObject(cliprdr->thread, INFINITE) == WAIT_FAILED)) - { - rc = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", rc); - return rc; - } + if (MessageQueue_PostQuit(cliprdr->queue, 0) + && (WaitForSingleObject(cliprdr->thread, INFINITE) == WAIT_FAILED)) + { + rc = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", rc); + return rc; + } MessageQueue_Free(cliprdr->queue); CloseHandle(cliprdr->thread); - rc = cliprdr->channelEntryPoints.pVirtualChannelClose(cliprdr->OpenHandle); + if (CHANNEL_RC_OK != rc) { WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08X]", - WTSErrorToString(rc), rc); + WTSErrorToString(rc), rc); return rc; } + cliprdr->OpenHandle = 0; + if (cliprdr->data_in) { Stream_Free(cliprdr->data_in, TRUE); cliprdr->data_in = NULL; } - cliprdr_remove_open_handle_data(cliprdr->OpenHandle); return CHANNEL_RC_OK; } @@ -1254,22 +1179,18 @@ static UINT cliprdr_virtual_channel_event_disconnected(cliprdrPlugin* cliprdr) */ static UINT cliprdr_virtual_channel_event_terminated(cliprdrPlugin* cliprdr) { - cliprdr_remove_init_handle_data(cliprdr->InitHandle); - free(cliprdr); return CHANNEL_RC_OK; } static VOID VCAPITYPE cliprdr_virtual_channel_init_event(LPVOID pInitHandle, - UINT event, LPVOID pData, - UINT dataLength) + UINT event, LPVOID pData, + UINT dataLength) { - cliprdrPlugin* cliprdr; + cliprdrPlugin* cliprdr = s_TLSPluginContext; UINT error = CHANNEL_RC_OK; - cliprdr = (cliprdrPlugin*) cliprdr_get_init_handle_data(pInitHandle); - - if (!cliprdr) + if (!cliprdr || (cliprdr->InitHandle != pInitHandle)) { WLog_ERR(TAG, "error no match"); return; @@ -1278,22 +1199,31 @@ static VOID VCAPITYPE cliprdr_virtual_channel_init_event(LPVOID pInitHandle, switch (event) { case CHANNEL_EVENT_CONNECTED: - if ((error = cliprdr_virtual_channel_event_connected(cliprdr, pData, dataLength))) - WLog_ERR(TAG, "cliprdr_virtual_channel_event_connected failed with error %lu!", error); + if ((error = cliprdr_virtual_channel_event_connected(cliprdr, pData, + dataLength))) + WLog_ERR(TAG, "cliprdr_virtual_channel_event_connected failed with error %lu!", + error); + break; case CHANNEL_EVENT_DISCONNECTED: if ((error = cliprdr_virtual_channel_event_disconnected(cliprdr))) - WLog_ERR(TAG, "cliprdr_virtual_channel_event_disconnected failed with error %lu!", error); + WLog_ERR(TAG, + "cliprdr_virtual_channel_event_disconnected failed with error %lu!", error); + break; case CHANNEL_EVENT_TERMINATED: if ((error = cliprdr_virtual_channel_event_terminated(cliprdr))) - WLog_ERR(TAG, "cliprdr_virtual_channel_event_terminated failed with error %lu!", error); + WLog_ERR(TAG, "cliprdr_virtual_channel_event_terminated failed with error %lu!", + error); + break; } + if (error && cliprdr->context->rdpcontext) - setChannelError(cliprdr->context->rdpcontext, error, "cliprdr_virtual_channel_init_event reported an error"); + setChannelError(cliprdr->context->rdpcontext, error, + "cliprdr_virtual_channel_init_event reported an error"); } /* cliprdr is always built-in */ @@ -1302,13 +1232,11 @@ static VOID VCAPITYPE cliprdr_virtual_channel_init_event(LPVOID pInitHandle, BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) { UINT rc; - int error; - cliprdrPlugin* cliprdr; CliprdrClientContext* context; CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx; - cliprdr = (cliprdrPlugin*) calloc(1, sizeof(cliprdrPlugin)); + if (!cliprdr) { WLog_ERR(TAG, "calloc failed!"); @@ -1316,19 +1244,18 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) } cliprdr->channelDef.options = - CHANNEL_OPTION_INITIALIZED | - CHANNEL_OPTION_ENCRYPT_RDP | - CHANNEL_OPTION_COMPRESS_RDP | - CHANNEL_OPTION_SHOW_PROTOCOL; - + CHANNEL_OPTION_INITIALIZED | + CHANNEL_OPTION_ENCRYPT_RDP | + CHANNEL_OPTION_COMPRESS_RDP | + CHANNEL_OPTION_SHOW_PROTOCOL; strcpy(cliprdr->channelDef.name, "cliprdr"); - 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 = (CliprdrClientContext*) calloc(1, sizeof(CliprdrClientContext)); + if (!context) { free(cliprdr); @@ -1338,7 +1265,6 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) context->handle = (void*) cliprdr; context->custom = NULL; - context->ClientCapabilities = cliprdr_client_capabilities; context->TempDirectory = cliprdr_temp_directory; context->ClientFormatList = cliprdr_client_format_list; @@ -1349,45 +1275,36 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) context->ClientFormatDataResponse = cliprdr_client_format_data_response; context->ClientFileContentsRequest = cliprdr_client_file_contents_request; context->ClientFileContentsResponse = cliprdr_client_file_contents_response; - *(pEntryPointsEx->ppInterface) = (void*) context; cliprdr->context = context; context->rdpcontext = pEntryPointsEx->context; } cliprdr->log = WLog_Get("com.freerdp.channels.cliprdr.client"); - cliprdr->useLongFormatNames = TRUE; cliprdr->streamFileClipEnabled = FALSE; cliprdr->fileClipNoFilePaths = TRUE; cliprdr->canLockClipData = FALSE; - WLog_Print(cliprdr->log, WLOG_DEBUG, "VirtualChannelEntry"); - - CopyMemory(&(cliprdr->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); - + CopyMemory(&(cliprdr->channelEntryPoints), pEntryPoints, + sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); rc = cliprdr->channelEntryPoints.pVirtualChannelInit(&cliprdr->InitHandle, - &cliprdr->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, cliprdr_virtual_channel_init_event); + &cliprdr->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, + cliprdr_virtual_channel_init_event); if (CHANNEL_RC_OK != rc) { WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]", - WTSErrorToString(rc), rc); - free(cliprdr->context); - free(cliprdr); - return FALSE; - } - - cliprdr->channelEntryPoints.pInterface = *(cliprdr->channelEntryPoints.ppInterface); - cliprdr->channelEntryPoints.ppInterface = &(cliprdr->channelEntryPoints.pInterface); - - if ((error = cliprdr_add_init_handle_data(cliprdr->InitHandle, (void*) cliprdr))) - { - WLog_ERR(TAG, "cliprdr_add_init_handle_data failed with error %lu", error); + WTSErrorToString(rc), rc); free(cliprdr->context); free(cliprdr); return FALSE; } + cliprdr->channelEntryPoints.pInterface = * + (cliprdr->channelEntryPoints.ppInterface); + cliprdr->channelEntryPoints.ppInterface = & + (cliprdr->channelEntryPoints.pInterface); + s_TLSPluginContext = cliprdr; return TRUE; } diff --git a/channels/cliprdr/client/cliprdr_main.h b/channels/cliprdr/client/cliprdr_main.h index e801413..34d9cf8 100644 --- a/channels/cliprdr/client/cliprdr_main.h +++ b/channels/cliprdr/client/cliprdr_main.h @@ -52,9 +52,6 @@ struct cliprdr_plugin }; typedef struct cliprdr_plugin cliprdrPlugin; -wStream* cliprdr_packet_new(UINT16 msgType, UINT16 msgFlags, UINT32 dataLen); -UINT cliprdr_packet_send(cliprdrPlugin* cliprdr, wStream* data_out); - CliprdrClientContext* cliprdr_get_client_interface(cliprdrPlugin* cliprdr); #ifdef WITH_DEBUG_CLIPRDR diff --git a/channels/drdynvc/client/drdynvc_main.c b/channels/drdynvc/client/drdynvc_main.c index 36e073d..34ac296 100644 --- a/channels/drdynvc/client/drdynvc_main.c +++ b/channels/drdynvc/client/drdynvc_main.c @@ -30,6 +30,8 @@ #define TAG CHANNELS_TAG("drdynvc.client") +static WINPR_TLS drdynvcPlugin* s_TLSPluginContext = NULL; + static void dvcman_channel_free(void* channel); static UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, const BYTE* data, UINT32 dataSize); @@ -439,8 +441,8 @@ 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) +static UINT dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, + UINT32 ChannelId, const char* ChannelName) { int i; BOOL bAccept; @@ -740,8 +742,8 @@ 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) +static UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, + const BYTE* data, UINT32 dataSize) { wStream* data_out; unsigned long pos; @@ -1128,105 +1130,6 @@ static UINT drdynvc_order_recv(drdynvcPlugin* drdynvc, wStream* s) } } -/****************************************************************************************/ - -static wListDictionary* g_InitHandles = NULL; -static wListDictionary* g_OpenHandles = NULL; - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -static UINT drdynvc_add_init_handle_data(void* pInitHandle, void* pUserData) -{ - if (!g_InitHandles) - g_InitHandles = ListDictionary_New(TRUE); - - if (!g_InitHandles) - { - WLog_ERR(TAG, "ListDictionary_New failed!"); - return CHANNEL_RC_NO_MEMORY; - } - - if (!ListDictionary_Add(g_InitHandles, pInitHandle, pUserData)) - { - WLog_ERR(TAG, "ListDictionary_New failed!"); - return ERROR_INTERNAL_ERROR; - } - - return CHANNEL_RC_OK; -} - -static void* drdynvc_get_init_handle_data(void* pInitHandle) -{ - void* pUserData = NULL; - pUserData = ListDictionary_GetItemValue(g_InitHandles, pInitHandle); - return pUserData; -} - -static void drdynvc_remove_init_handle_data(void* pInitHandle) -{ - ListDictionary_Remove(g_InitHandles, pInitHandle); - - if (ListDictionary_Count(g_InitHandles) < 1) - { - ListDictionary_Free(g_InitHandles); - g_InitHandles = NULL; - } -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -static UINT drdynvc_add_open_handle_data(DWORD openHandle, void* pUserData) -{ - void* pOpenHandle = (void*)(size_t) openHandle; - - if (!g_OpenHandles) - g_OpenHandles = ListDictionary_New(TRUE); - - if (!g_OpenHandles) - { - WLog_ERR(TAG, "ListDictionary_New failed!"); - return CHANNEL_RC_NO_MEMORY; - } - - if (!ListDictionary_Add(g_OpenHandles, pOpenHandle, 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; - pUserData = ListDictionary_GetItemValue(g_OpenHandles, pOpenHandle); - return pUserData; -} - -static void drdynvc_remove_open_handle_data(DWORD openHandle) -{ - void* pOpenHandle = (void*)(size_t) openHandle; - - if (!g_OpenHandles) - return; - - ListDictionary_Remove(g_OpenHandles, pOpenHandle); - - if (ListDictionary_Count(g_OpenHandles) < 1) - { - ListDictionary_Free(g_OpenHandles); - g_OpenHandles = NULL; - } -} - /** * Function description * @@ -1292,11 +1195,10 @@ static void VCAPITYPE drdynvc_virtual_channel_open_event(DWORD openHandle, UINT event, LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { - drdynvcPlugin* drdynvc; + drdynvcPlugin* drdynvc = s_TLSPluginContext; UINT error = CHANNEL_RC_OK; - drdynvc = (drdynvcPlugin*) drdynvc_get_open_handle_data(openHandle); - if (!drdynvc) + if (!drdynvc || (drdynvc->OpenHandle != openHandle)) { WLog_ERR(TAG, "drdynvc_virtual_channel_open_event: error no match"); return; @@ -1331,6 +1233,7 @@ static void* drdynvc_virtual_channel_client_thread(void* arg) wMessage message; drdynvcPlugin* drdynvc = (drdynvcPlugin*) arg; UINT error = CHANNEL_RC_OK; + freerdp_channel_init_thread_context(drdynvc->rdpcontext); while (1) { @@ -1398,12 +1301,6 @@ static UINT drdynvc_virtual_channel_event_connected(drdynvcPlugin* drdynvc, return status; } - if ((error = drdynvc_add_open_handle_data(drdynvc->OpenHandle, drdynvc))) - { - WLog_ERR(TAG, "drdynvc_add_open_handle_data failed with error %lu!", error); - return error; - } - drdynvc->queue = MessageQueue_New(NULL); if (!drdynvc->queue) @@ -1450,9 +1347,7 @@ static UINT drdynvc_virtual_channel_event_connected(drdynvcPlugin* drdynvc, goto error; } - return CHANNEL_RC_OK; error: - drdynvc_remove_open_handle_data(drdynvc->OpenHandle); return error; } @@ -1485,6 +1380,8 @@ static UINT drdynvc_virtual_channel_event_disconnected(drdynvcPlugin* drdynvc) WTSErrorToString(status), status); } + drdynvc->OpenHandle = 0; + if (drdynvc->data_in) { Stream_Free(drdynvc->data_in, TRUE); @@ -1497,7 +1394,6 @@ static UINT drdynvc_virtual_channel_event_disconnected(drdynvcPlugin* drdynvc) drdynvc->channel_mgr = NULL; } - drdynvc_remove_open_handle_data(drdynvc->OpenHandle); return status; } @@ -1508,7 +1404,7 @@ static UINT drdynvc_virtual_channel_event_disconnected(drdynvcPlugin* drdynvc) */ static UINT drdynvc_virtual_channel_event_terminated(drdynvcPlugin* drdynvc) { - drdynvc_remove_init_handle_data(drdynvc->InitHandle); + drdynvc->InitHandle = 0; free(drdynvc); return CHANNEL_RC_OK; } @@ -1517,11 +1413,10 @@ static VOID VCAPITYPE drdynvc_virtual_channel_init_event(LPVOID pInitHandle, UINT event, LPVOID pData, UINT dataLength) { - drdynvcPlugin* drdynvc; + drdynvcPlugin* drdynvc = s_TLSPluginContext; UINT error = CHANNEL_RC_OK; - drdynvc = (drdynvcPlugin*) drdynvc_get_init_handle_data(pInitHandle); - if (!drdynvc) + if (!drdynvc || (drdynvc->InitHandle != pInitHandle)) { WLog_ERR(TAG, "drdynvc_virtual_channel_init_event: error no match"); return; @@ -1576,7 +1471,6 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) drdynvcPlugin* drdynvc; DrdynvcClientContext* context; CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx; - UINT error; drdynvc = (drdynvcPlugin*) calloc(1, sizeof(drdynvcPlugin)); if (!drdynvc) @@ -1625,9 +1519,8 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) { WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]", WTSErrorToString(rc), rc); + free(drdynvc->context); free(drdynvc); - free(*(pEntryPointsEx->ppInterface)); - *(pEntryPointsEx->ppInterface) = NULL; return FALSE; } @@ -1635,17 +1528,7 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) (drdynvc->channelEntryPoints.ppInterface); drdynvc->channelEntryPoints.ppInterface = & (drdynvc->channelEntryPoints.pInterface); - - if ((error = drdynvc_add_init_handle_data(drdynvc->InitHandle, - (void*) drdynvc))) - { - WLog_ERR(TAG, "drdynvc_add_init_handle_data failed with error %lu!", error); - free(drdynvc); - free(*(pEntryPointsEx->ppInterface)); - *(pEntryPointsEx->ppInterface) = NULL; - return FALSE; - } - + s_TLSPluginContext = drdynvc; return TRUE; } diff --git a/channels/encomsp/client/encomsp_main.c b/channels/encomsp/client/encomsp_main.c index 239954c..c4221b0 100644 --- a/channels/encomsp/client/encomsp_main.c +++ b/channels/encomsp/client/encomsp_main.c @@ -31,6 +31,8 @@ #include "encomsp_main.h" +static WINPR_TLS encomspPlugin* s_TLSPluginContext = NULL; + /** * Function description * @@ -46,7 +48,6 @@ static UINT encomsp_read_header(wStream* s, ENCOMSP_ORDER_HEADER* header) Stream_Read_UINT16(s, header->Type); /* Type (2 bytes) */ Stream_Read_UINT16(s, header->Length); /* Length (2 bytes) */ - return CHANNEL_RC_OK; } @@ -59,7 +60,6 @@ static UINT encomsp_write_header(wStream* s, ENCOMSP_ORDER_HEADER* header) { Stream_Write_UINT16(s, header->Type); /* Type (2 bytes) */ Stream_Write_UINT16(s, header->Length); /* Length (2 bytes) */ - return CHANNEL_RC_OK; } @@ -86,18 +86,18 @@ static UINT encomsp_read_unicode_string(wStream* s, ENCOMSP_UNICODE_STRING* str) return ERROR_INVALID_DATA; } - if (Stream_GetRemainingLength(s) < (size_t) (str->cchString * 2)) + if (Stream_GetRemainingLength(s) < (size_t)(str->cchString * 2)) { WLog_ERR(TAG, "Not enought data!"); return ERROR_INVALID_DATA; } Stream_Read(s, &(str->wString), (str->cchString * 2)); /* String (variable) */ - return CHANNEL_RC_OK; } -EncomspClientContext* encomsp_get_client_interface(encomspPlugin* encomsp) +static EncomspClientContext* encomsp_get_client_interface( + encomspPlugin* encomsp) { EncomspClientContext* pInterface; pInterface = (EncomspClientContext*) encomsp->channelEntryPoints.pInterface; @@ -109,7 +109,7 @@ EncomspClientContext* encomsp_get_client_interface(encomspPlugin* encomsp) * * @return 0 on success, otherwise a Win32 error code */ -UINT encomsp_virtual_channel_write(encomspPlugin* encomsp, wStream* s) +static UINT encomsp_virtual_channel_write(encomspPlugin* encomsp, wStream* s) { UINT status; @@ -120,13 +120,12 @@ UINT encomsp_virtual_channel_write(encomspPlugin* encomsp, wStream* s) WLog_INFO(TAG, "EncomspWrite (%d)", Stream_Length(s)); winpr_HexDump(Stream_Buffer(s), Stream_Length(s)); #endif - status = encomsp->channelEntryPoints.pVirtualChannelWrite(encomsp->OpenHandle, - Stream_Buffer(s), (UINT32) Stream_Length(s), s); + Stream_Buffer(s), (UINT32) Stream_Length(s), s); if (status != CHANNEL_RC_OK) WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", - WTSErrorToString(status), status); + WTSErrorToString(status), status); return status; } @@ -136,20 +135,19 @@ UINT encomsp_virtual_channel_write(encomspPlugin* encomsp, wStream* s) * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_recv_filter_updated_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static UINT encomsp_recv_filter_updated_pdu(encomspPlugin* encomsp, wStream* s, + ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; ENCOMSP_FILTER_UPDATED_PDU pdu; UINT error = CHANNEL_RC_OK; - context = encomsp_get_client_interface(encomsp); if (!context) return ERROR_INVALID_HANDLE; beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE; - CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); if (Stream_GetRemainingLength(s) < 1) @@ -159,7 +157,6 @@ static UINT encomsp_recv_filter_updated_pdu(encomspPlugin* encomsp, wStream* s, } Stream_Read_UINT8(s, pdu.Flags); /* Flags (1 byte) */ - end = (int) Stream_GetPosition(s); if ((beg + header->Length) < end) @@ -170,7 +167,7 @@ static UINT encomsp_recv_filter_updated_pdu(encomspPlugin* encomsp, wStream* s, if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) { WLog_ERR(TAG, "Not enought data!"); return ERROR_INVALID_DATA; @@ -180,6 +177,7 @@ static UINT encomsp_recv_filter_updated_pdu(encomspPlugin* encomsp, wStream* s, } IFCALLRET(context->FilterUpdated, error, context, &pdu); + if (error) WLog_ERR(TAG, "context->FilterUpdated failed with error %lu", error); @@ -191,20 +189,19 @@ static UINT encomsp_recv_filter_updated_pdu(encomspPlugin* encomsp, wStream* s, * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_recv_application_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static UINT encomsp_recv_application_created_pdu(encomspPlugin* encomsp, + wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; ENCOMSP_APPLICATION_CREATED_PDU pdu; UINT error; - context = encomsp_get_client_interface(encomsp); if (!context) return ERROR_INVALID_HANDLE; beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE; - CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); if (Stream_GetRemainingLength(s) < 6) @@ -216,7 +213,7 @@ static UINT encomsp_recv_application_created_pdu(encomspPlugin* encomsp, wStream Stream_Read_UINT16(s, pdu.Flags); /* Flags (2 bytes) */ Stream_Read_UINT32(s, pdu.AppId); /* AppId (4 bytes) */ - if ((error = encomsp_read_unicode_string(s, &(pdu.Name)) )) + if ((error = encomsp_read_unicode_string(s, &(pdu.Name)))) { WLog_ERR(TAG, "encomsp_read_unicode_string failed with error %lu", error); return error; @@ -232,7 +229,7 @@ static UINT encomsp_recv_application_created_pdu(encomspPlugin* encomsp, wStream if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) { WLog_ERR(TAG, "Not enought data!"); return ERROR_INVALID_DATA; @@ -242,6 +239,7 @@ static UINT encomsp_recv_application_created_pdu(encomspPlugin* encomsp, wStream } IFCALLRET(context->ApplicationCreated, error, context, &pdu); + if (error) WLog_ERR(TAG, "context->ApplicationCreated failed with error %lu", error); @@ -253,20 +251,19 @@ static UINT encomsp_recv_application_created_pdu(encomspPlugin* encomsp, wStream * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_recv_application_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static UINT encomsp_recv_application_removed_pdu(encomspPlugin* encomsp, + wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; ENCOMSP_APPLICATION_REMOVED_PDU pdu; UINT error = CHANNEL_RC_OK; - context = encomsp_get_client_interface(encomsp); if (!context) return ERROR_INVALID_HANDLE; beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE; - CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); if (Stream_GetRemainingLength(s) < 4) @@ -276,7 +273,6 @@ static UINT encomsp_recv_application_removed_pdu(encomspPlugin* encomsp, wStream } Stream_Read_UINT32(s, pdu.AppId); /* AppId (4 bytes) */ - end = (int) Stream_GetPosition(s); if ((beg + header->Length) < end) @@ -287,7 +283,7 @@ static UINT encomsp_recv_application_removed_pdu(encomspPlugin* encomsp, wStream if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) { WLog_ERR(TAG, "Not enought data!"); return ERROR_INVALID_DATA; @@ -297,6 +293,7 @@ static UINT encomsp_recv_application_removed_pdu(encomspPlugin* encomsp, wStream } IFCALLRET(context->ApplicationRemoved, error, context, &pdu); + if (error) WLog_ERR(TAG, "context->ApplicationRemoved failed with error %lu", error); @@ -308,20 +305,19 @@ static UINT encomsp_recv_application_removed_pdu(encomspPlugin* encomsp, wStream * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_recv_window_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static UINT encomsp_recv_window_created_pdu(encomspPlugin* encomsp, wStream* s, + ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; ENCOMSP_WINDOW_CREATED_PDU pdu; UINT error; - context = encomsp_get_client_interface(encomsp); if (!context) return ERROR_INVALID_HANDLE; beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE; - CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); if (Stream_GetRemainingLength(s) < 10) @@ -350,7 +346,7 @@ static UINT encomsp_recv_window_created_pdu(encomspPlugin* encomsp, wStream* s, if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) { WLog_ERR(TAG, "Not enought data!"); return ERROR_INVALID_DATA; @@ -360,6 +356,7 @@ static UINT encomsp_recv_window_created_pdu(encomspPlugin* encomsp, wStream* s, } IFCALLRET(context->WindowCreated, error, context, &pdu); + if (error) WLog_ERR(TAG, "context->WindowCreated failed with error %lu", error); @@ -371,20 +368,19 @@ static UINT encomsp_recv_window_created_pdu(encomspPlugin* encomsp, wStream* s, * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_recv_window_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static UINT encomsp_recv_window_removed_pdu(encomspPlugin* encomsp, wStream* s, + ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; ENCOMSP_WINDOW_REMOVED_PDU pdu; UINT error = CHANNEL_RC_OK; - context = encomsp_get_client_interface(encomsp); if (!context) return ERROR_INVALID_HANDLE; beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE; - CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); if (Stream_GetRemainingLength(s) < 4) @@ -394,7 +390,6 @@ static UINT encomsp_recv_window_removed_pdu(encomspPlugin* encomsp, wStream* s, } Stream_Read_UINT32(s, pdu.WndId); /* WndId (4 bytes) */ - end = (int) Stream_GetPosition(s); if ((beg + header->Length) < end) @@ -405,7 +400,7 @@ static UINT encomsp_recv_window_removed_pdu(encomspPlugin* encomsp, wStream* s, if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) { WLog_ERR(TAG, "Not enought data!"); return ERROR_INVALID_DATA; @@ -415,6 +410,7 @@ static UINT encomsp_recv_window_removed_pdu(encomspPlugin* encomsp, wStream* s, } IFCALLRET(context->WindowRemoved, error, context, &pdu); + if (error) WLog_ERR(TAG, "context->WindowRemoved failed with error %lu", error); @@ -426,20 +422,19 @@ static UINT encomsp_recv_window_removed_pdu(encomspPlugin* encomsp, wStream* s, * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_recv_show_window_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static UINT encomsp_recv_show_window_pdu(encomspPlugin* encomsp, wStream* s, + ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; ENCOMSP_SHOW_WINDOW_PDU pdu; UINT error = CHANNEL_RC_OK; - context = encomsp_get_client_interface(encomsp); if (!context) return ERROR_INVALID_HANDLE; beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE; - CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); if (Stream_GetRemainingLength(s) < 4) @@ -449,7 +444,6 @@ static UINT encomsp_recv_show_window_pdu(encomspPlugin* encomsp, wStream* s, ENC } Stream_Read_UINT32(s, pdu.WndId); /* WndId (4 bytes) */ - end = (int) Stream_GetPosition(s); if ((beg + header->Length) < end) @@ -460,7 +454,7 @@ static UINT encomsp_recv_show_window_pdu(encomspPlugin* encomsp, wStream* s, ENC if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) { WLog_ERR(TAG, "Not enought data!"); return ERROR_INVALID_DATA; @@ -470,6 +464,7 @@ static UINT encomsp_recv_show_window_pdu(encomspPlugin* encomsp, wStream* s, ENC } IFCALLRET(context->ShowWindow, error, context, &pdu); + if (error) WLog_ERR(TAG, "context->ShowWindow failed with error %lu", error); @@ -481,20 +476,19 @@ static UINT encomsp_recv_show_window_pdu(encomspPlugin* encomsp, wStream* s, ENC * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static UINT encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, + wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; ENCOMSP_PARTICIPANT_CREATED_PDU pdu; UINT error; - context = encomsp_get_client_interface(encomsp); if (!context) return ERROR_INVALID_HANDLE; beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE; - CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); if (Stream_GetRemainingLength(s) < 10) @@ -507,7 +501,6 @@ static UINT encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, wStream Stream_Read_UINT32(s, pdu.GroupId); /* GroupId (4 bytes) */ Stream_Read_UINT16(s, pdu.Flags); /* Flags (2 bytes) */ - if ((error = encomsp_read_unicode_string(s, &(pdu.FriendlyName)))) { WLog_ERR(TAG, "encomsp_read_unicode_string failed with error %lu", error); @@ -524,7 +517,7 @@ static UINT encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, wStream if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) { WLog_ERR(TAG, "Not enought data!"); return ERROR_INVALID_DATA; @@ -534,6 +527,7 @@ static UINT encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, wStream } IFCALLRET(context->ParticipantCreated, error, context, &pdu); + if (error) WLog_ERR(TAG, "context->ParticipantCreated failed with error %lu", error); @@ -545,20 +539,19 @@ static UINT encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, wStream * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static UINT encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, + wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; ENCOMSP_PARTICIPANT_REMOVED_PDU pdu; UINT error = CHANNEL_RC_OK; - context = encomsp_get_client_interface(encomsp); if (!context) return ERROR_INVALID_HANDLE; beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE; - CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); if (Stream_GetRemainingLength(s) < 12) @@ -570,7 +563,6 @@ static UINT encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, wStream Stream_Read_UINT32(s, pdu.ParticipantId); /* ParticipantId (4 bytes) */ Stream_Read_UINT32(s, pdu.DiscType); /* DiscType (4 bytes) */ Stream_Read_UINT32(s, pdu.DiscCode); /* DiscCode (4 bytes) */ - end = (int) Stream_GetPosition(s); if ((beg + header->Length) < end) @@ -581,7 +573,7 @@ static UINT encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, wStream if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) { WLog_ERR(TAG, "Not enought data!"); return ERROR_INVALID_DATA; @@ -591,6 +583,7 @@ static UINT encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, wStream } IFCALLRET(context->ParticipantRemoved, error, context, &pdu); + if (error) WLog_ERR(TAG, "context->ParticipantRemoved failed with error %lu", error); @@ -602,20 +595,19 @@ static UINT encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, wStream * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_recv_change_participant_control_level_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static UINT encomsp_recv_change_participant_control_level_pdu( + encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU pdu; UINT error = CHANNEL_RC_OK; - context = encomsp_get_client_interface(encomsp); if (!context) return ERROR_INVALID_HANDLE; beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE; - CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); if (Stream_GetRemainingLength(s) < 6) @@ -626,7 +618,6 @@ static UINT encomsp_recv_change_participant_control_level_pdu(encomspPlugin* enc Stream_Read_UINT16(s, pdu.Flags); /* Flags (2 bytes) */ Stream_Read_UINT32(s, pdu.ParticipantId); /* ParticipantId (4 bytes) */ - end = (int) Stream_GetPosition(s); if ((beg + header->Length) < end) @@ -637,7 +628,7 @@ static UINT encomsp_recv_change_participant_control_level_pdu(encomspPlugin* enc if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) { WLog_ERR(TAG, "Not enought data!"); return ERROR_INVALID_DATA; @@ -647,8 +638,10 @@ static UINT encomsp_recv_change_participant_control_level_pdu(encomspPlugin* enc } IFCALLRET(context->ChangeParticipantControlLevel, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->ChangeParticipantControlLevel failed with error %lu", error); + WLog_ERR(TAG, "context->ChangeParticipantControlLevel failed with error %lu", + error); return error; } @@ -658,18 +651,18 @@ static UINT encomsp_recv_change_participant_control_level_pdu(encomspPlugin* enc * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_send_change_participant_control_level_pdu(EncomspClientContext* context, ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU* pdu) +static UINT encomsp_send_change_participant_control_level_pdu( + EncomspClientContext* context, + ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU* pdu) { wStream* s; encomspPlugin* encomsp; UINT error; - encomsp = (encomspPlugin*) context->handle; - pdu->Type = ODTYPE_PARTICIPANT_CTRL_CHANGED; pdu->Length = ENCOMSP_ORDER_HEADER_SIZE + 6; - s = Stream_New(NULL, pdu->Length); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); @@ -684,9 +677,7 @@ static UINT encomsp_send_change_participant_control_level_pdu(EncomspClientConte Stream_Write_UINT16(s, pdu->Flags); /* Flags (2 bytes) */ Stream_Write_UINT32(s, pdu->ParticipantId); /* ParticipantId (4 bytes) */ - Stream_SealLength(s); - return encomsp_virtual_channel_write(encomsp, s); } @@ -695,22 +686,20 @@ static UINT encomsp_send_change_participant_control_level_pdu(EncomspClientConte * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_recv_graphics_stream_paused_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static UINT encomsp_recv_graphics_stream_paused_pdu(encomspPlugin* encomsp, + wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; ENCOMSP_GRAPHICS_STREAM_PAUSED_PDU pdu; UINT error = CHANNEL_RC_OK; - context = encomsp_get_client_interface(encomsp); if (!context) return ERROR_INVALID_HANDLE; beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE; - CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); - end = (int) Stream_GetPosition(s); if ((beg + header->Length) < end) @@ -721,7 +710,7 @@ static UINT encomsp_recv_graphics_stream_paused_pdu(encomspPlugin* encomsp, wStr if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) { WLog_ERR(TAG, "Not enought data!"); return ERROR_INVALID_DATA; @@ -731,6 +720,7 @@ static UINT encomsp_recv_graphics_stream_paused_pdu(encomspPlugin* encomsp, wStr } IFCALLRET(context->GraphicsStreamPaused, error, context, &pdu); + if (error) WLog_ERR(TAG, "context->GraphicsStreamPaused failed with error %lu", error); @@ -742,22 +732,20 @@ static UINT encomsp_recv_graphics_stream_paused_pdu(encomspPlugin* encomsp, wStr * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_recv_graphics_stream_resumed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static UINT encomsp_recv_graphics_stream_resumed_pdu(encomspPlugin* encomsp, + wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; ENCOMSP_GRAPHICS_STREAM_RESUMED_PDU pdu; UINT error = CHANNEL_RC_OK; - context = encomsp_get_client_interface(encomsp); if (!context) return ERROR_INVALID_HANDLE; beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE; - CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); - end = (int) Stream_GetPosition(s); if ((beg + header->Length) < end) @@ -768,7 +756,7 @@ static UINT encomsp_recv_graphics_stream_resumed_pdu(encomspPlugin* encomsp, wSt if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) { WLog_ERR(TAG, "Not enought data!"); return ERROR_INVALID_DATA; @@ -778,6 +766,7 @@ static UINT encomsp_recv_graphics_stream_resumed_pdu(encomspPlugin* encomsp, wSt } IFCALLRET(context->GraphicsStreamResumed, error, context, &pdu); + if (error) WLog_ERR(TAG, "context->GraphicsStreamResumed failed with error %lu", error); @@ -812,22 +801,27 @@ static UINT encomsp_process_receive(encomspPlugin* encomsp, wStream* s) WLog_ERR(TAG, "encomsp_recv_filter_updated_pdu failed with error %lu!", error); return error; } + break; case ODTYPE_APP_REMOVED: if ((error = encomsp_recv_application_removed_pdu(encomsp, s, &header))) { - WLog_ERR(TAG, "encomsp_recv_application_removed_pdu failed with error %lu!", error); + WLog_ERR(TAG, "encomsp_recv_application_removed_pdu failed with error %lu!", + error); return error; } + break; case ODTYPE_APP_CREATED: if ((error = encomsp_recv_application_created_pdu(encomsp, s, &header))) { - WLog_ERR(TAG, "encomsp_recv_application_removed_pdu failed with error %lu!", error); + WLog_ERR(TAG, "encomsp_recv_application_removed_pdu failed with error %lu!", + error); return error; } + break; case ODTYPE_WND_REMOVED: @@ -836,6 +830,7 @@ static UINT encomsp_process_receive(encomspPlugin* encomsp, wStream* s) WLog_ERR(TAG, "encomsp_recv_window_removed_pdu failed with error %lu!", error); return error; } + break; case ODTYPE_WND_CREATED: @@ -844,6 +839,7 @@ static UINT encomsp_process_receive(encomspPlugin* encomsp, wStream* s) WLog_ERR(TAG, "encomsp_recv_window_created_pdu failed with error %lu!", error); return error; } + break; case ODTYPE_WND_SHOW: @@ -852,46 +848,59 @@ static UINT encomsp_process_receive(encomspPlugin* encomsp, wStream* s) WLog_ERR(TAG, "encomsp_recv_show_window_pdu failed with error %lu!", error); return error; } + break; case ODTYPE_PARTICIPANT_REMOVED: if ((error = encomsp_recv_participant_removed_pdu(encomsp, s, &header))) { - WLog_ERR(TAG, "encomsp_recv_participant_removed_pdu failed with error %lu!", error); + WLog_ERR(TAG, "encomsp_recv_participant_removed_pdu failed with error %lu!", + error); return error; } + break; case ODTYPE_PARTICIPANT_CREATED: if ((error = encomsp_recv_participant_created_pdu(encomsp, s, &header))) { - WLog_ERR(TAG, "encomsp_recv_participant_created_pdu failed with error %lu!", error); + WLog_ERR(TAG, "encomsp_recv_participant_created_pdu failed with error %lu!", + error); return error; } + break; case ODTYPE_PARTICIPANT_CTRL_CHANGED: - if ((error = encomsp_recv_change_participant_control_level_pdu(encomsp, s, &header))) + if ((error = encomsp_recv_change_participant_control_level_pdu(encomsp, s, + &header))) { - WLog_ERR(TAG, "encomsp_recv_change_participant_control_level_pdu failed with error %lu!", error); + WLog_ERR(TAG, + "encomsp_recv_change_participant_control_level_pdu failed with error %lu!", + error); return error; } + break; case ODTYPE_GRAPHICS_STREAM_PAUSED: if ((error = encomsp_recv_graphics_stream_paused_pdu(encomsp, s, &header))) { - WLog_ERR(TAG, "encomsp_recv_graphics_stream_paused_pdu failed with error %lu!", error); + WLog_ERR(TAG, "encomsp_recv_graphics_stream_paused_pdu failed with error %lu!", + error); return error; } + break; case ODTYPE_GRAPHICS_STREAM_RESUMED: if ((error = encomsp_recv_graphics_stream_resumed_pdu(encomsp, s, &header))) { - WLog_ERR(TAG, "encomsp_recv_graphics_stream_resumed_pdu failed with error %lu!", error); + WLog_ERR(TAG, "encomsp_recv_graphics_stream_resumed_pdu failed with error %lu!", + error); return error; } + break; default: @@ -899,111 +908,16 @@ static UINT encomsp_process_receive(encomspPlugin* encomsp, wStream* s) return ERROR_INVALID_DATA; break; } - } + return error; } static void encomsp_process_connect(encomspPlugin* encomsp) { - } -/****************************************************************************************/ - -static wListDictionary* g_InitHandles = NULL; -static wListDictionary* g_OpenHandles = NULL; - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -UINT encomsp_add_init_handle_data(void* pInitHandle, void* pUserData) -{ - if (!g_InitHandles) - { - g_InitHandles = ListDictionary_New(TRUE); - } - if (!g_InitHandles) - { - WLog_ERR(TAG, "ListDictionary_New failed!"); - return CHANNEL_RC_NO_MEMORY; - } - - if (!ListDictionary_Add(g_InitHandles, pInitHandle, pUserData)) - { - WLog_ERR(TAG, "ListDictionary_Add failed!"); - return ERROR_INTERNAL_ERROR; - } - return CHANNEL_RC_OK; -} - -void* encomsp_get_init_handle_data(void* pInitHandle) -{ - void* pUserData = NULL; - pUserData = ListDictionary_GetItemValue(g_InitHandles, pInitHandle); - return pUserData; -} - -void encomsp_remove_init_handle_data(void* pInitHandle) -{ - ListDictionary_Remove(g_InitHandles, pInitHandle); - if (ListDictionary_Count(g_InitHandles) < 1) - { - ListDictionary_Free(g_InitHandles); - g_InitHandles = NULL; - } -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -UINT encomsp_add_open_handle_data(DWORD openHandle, void* pUserData) -{ - void* pOpenHandle = (void*) (size_t) openHandle; - - if (!g_OpenHandles) - { - g_OpenHandles = ListDictionary_New(TRUE); - } - - if (!g_OpenHandles) - { - WLog_ERR(TAG, "ListDictionary_New failed!"); - return CHANNEL_RC_NO_MEMORY; - } - - if (!ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData)) - { - WLog_ERR(TAG, "ListDictionary_Add failed!"); - return ERROR_INTERNAL_ERROR; - } - return CHANNEL_RC_OK; -} - -void* encomsp_get_open_handle_data(DWORD openHandle) -{ - void* pUserData = NULL; - void* pOpenHandle = (void*) (size_t) openHandle; - pUserData = ListDictionary_GetItemValue(g_OpenHandles, pOpenHandle); - return pUserData; -} - -void encomsp_remove_open_handle_data(DWORD openHandle) -{ - void* pOpenHandle = (void*) (size_t) openHandle; - ListDictionary_Remove(g_OpenHandles, pOpenHandle); - if (ListDictionary_Count(g_OpenHandles) < 1) - { - ListDictionary_Free(g_OpenHandles); - g_OpenHandles = NULL; - } -} - -int encomsp_send(encomspPlugin* encomsp, wStream* s) +static int encomsp_send(encomspPlugin* encomsp, wStream* s) { UINT32 status = 0; encomspPlugin* plugin = (encomspPlugin*) encomsp; @@ -1015,14 +929,14 @@ int encomsp_send(encomspPlugin* encomsp, wStream* s) else { status = plugin->channelEntryPoints.pVirtualChannelWrite(plugin->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; @@ -1034,7 +948,7 @@ int encomsp_send(encomspPlugin* encomsp, wStream* s) * @return 0 on success, otherwise a Win32 error code */ static UINT encomsp_virtual_channel_event_data_received(encomspPlugin* encomsp, - void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) + void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { wStream* data_in; @@ -1047,6 +961,7 @@ static UINT encomsp_virtual_channel_event_data_received(encomspPlugin* encomsp, Stream_Free(encomsp->data_in, TRUE); encomsp->data_in = Stream_New(NULL, totalLength); + if (!encomsp->data_in) { WLog_ERR(TAG, "Stream_New failed!"); @@ -1055,11 +970,13 @@ static UINT encomsp_virtual_channel_event_data_received(encomspPlugin* encomsp, } data_in = encomsp->data_in; + if (!Stream_EnsureRemainingCapacity(data_in, (int) dataLength)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return ERROR_INTERNAL_ERROR; } + Stream_Write(data_in, pData, dataLength); if (dataFlags & CHANNEL_FLAG_LAST) @@ -1080,18 +997,18 @@ static UINT encomsp_virtual_channel_event_data_received(encomspPlugin* encomsp, return ERROR_INTERNAL_ERROR; } } + return CHANNEL_RC_OK; } -static VOID VCAPITYPE encomsp_virtual_channel_open_event(DWORD openHandle, UINT event, - LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) +static VOID VCAPITYPE encomsp_virtual_channel_open_event(DWORD openHandle, + UINT event, + LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { - encomspPlugin* encomsp; + encomspPlugin* encomsp = s_TLSPluginContext; UINT error = CHANNEL_RC_OK; - encomsp = (encomspPlugin*) encomsp_get_open_handle_data(openHandle); - - if (!encomsp) + if (!encomsp || (encomsp->OpenHandle != openHandle)) { WLog_ERR(TAG, "encomsp_virtual_channel_open_event: error no match"); return; @@ -1100,8 +1017,11 @@ static VOID VCAPITYPE encomsp_virtual_channel_open_event(DWORD openHandle, UINT switch (event) { case CHANNEL_EVENT_DATA_RECEIVED: - if ((error = encomsp_virtual_channel_event_data_received(encomsp, pData, dataLength, totalLength, dataFlags))) - WLog_ERR(TAG, "encomsp_virtual_channel_event_data_received failed with error %lu", error); + if ((error = encomsp_virtual_channel_event_data_received(encomsp, pData, + dataLength, totalLength, dataFlags))) + WLog_ERR(TAG, + "encomsp_virtual_channel_event_data_received failed with error %lu", error); + break; case CHANNEL_EVENT_WRITE_COMPLETE: @@ -1111,8 +1031,10 @@ static VOID VCAPITYPE encomsp_virtual_channel_open_event(DWORD openHandle, UINT case CHANNEL_EVENT_USER: break; } + if (error && encomsp->rdpcontext) - setChannelError(encomsp->rdpcontext, error, "encomsp_virtual_channel_open_event reported an error"); + setChannelError(encomsp->rdpcontext, error, + "encomsp_virtual_channel_open_event reported an error"); return; } @@ -1123,7 +1045,6 @@ static void* encomsp_virtual_channel_client_thread(void* arg) wMessage message; encomspPlugin* encomsp = (encomspPlugin*) arg; UINT error = CHANNEL_RC_OK; - encomsp_process_connect(encomsp); while (1) @@ -1148,6 +1069,7 @@ static void* encomsp_virtual_channel_client_thread(void* arg) if (message.id == 0) { data = (wStream*) message.wParam; + if ((error = encomsp_process_receive(encomsp, data))) { WLog_ERR(TAG, "encomsp_process_receive failed with error %lu!", error); @@ -1157,7 +1079,8 @@ static void* encomsp_virtual_channel_client_thread(void* arg) } if (error && encomsp->rdpcontext) - setChannelError(encomsp->rdpcontext, error, "encomsp_virtual_channel_client_thread reported an error"); + setChannelError(encomsp->rdpcontext, error, + "encomsp_virtual_channel_client_thread reported an error"); ExitThread((DWORD)error); return NULL; @@ -1168,28 +1091,23 @@ static void* encomsp_virtual_channel_client_thread(void* arg) * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_virtual_channel_event_connected(encomspPlugin* encomsp, LPVOID pData, UINT32 dataLength) +static UINT encomsp_virtual_channel_event_connected(encomspPlugin* encomsp, + LPVOID pData, UINT32 dataLength) { UINT32 status; - UINT error; - status = encomsp->channelEntryPoints.pVirtualChannelOpen(encomsp->InitHandle, - &encomsp->OpenHandle, encomsp->channelDef.name, encomsp_virtual_channel_open_event); + &encomsp->OpenHandle, encomsp->channelDef.name, + encomsp_virtual_channel_open_event); if (status != CHANNEL_RC_OK) { WLog_ERR(TAG, "pVirtualChannelOpen failed with %s [%08X]", - WTSErrorToString(status), status); - return status; - } - - if ((error = encomsp_add_open_handle_data(encomsp->OpenHandle, encomsp))) - { - WLog_ERR(TAG, "encomsp_process_receive failed with error %lu!", error); + WTSErrorToString(status), status); return status; } encomsp->queue = MessageQueue_New(NULL); + if (!encomsp->queue) { WLog_ERR(TAG, "MessageQueue_New failed!"); @@ -1197,12 +1115,14 @@ static UINT encomsp_virtual_channel_event_connected(encomspPlugin* encomsp, LPVO } if (!(encomsp->thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) encomsp_virtual_channel_client_thread, (void*) encomsp, 0, NULL))) + (LPTHREAD_START_ROUTINE) encomsp_virtual_channel_client_thread, (void*) encomsp, + 0, NULL))) { WLog_ERR(TAG, "CreateThread failed!"); MessageQueue_Free(encomsp->queue); return ERROR_INTERNAL_ERROR; } + return CHANNEL_RC_OK; } @@ -1215,34 +1135,35 @@ static UINT encomsp_virtual_channel_event_disconnected(encomspPlugin* encomsp) { UINT rc; - if (MessageQueue_PostQuit(encomsp->queue, 0) && (WaitForSingleObject(encomsp->thread, INFINITE) == WAIT_FAILED)) - { - rc = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", rc); - return rc; - } + if (MessageQueue_PostQuit(encomsp->queue, 0) + && (WaitForSingleObject(encomsp->thread, INFINITE) == WAIT_FAILED)) + { + rc = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", rc); + return rc; + } MessageQueue_Free(encomsp->queue); CloseHandle(encomsp->thread); - encomsp->queue = NULL; encomsp->thread = NULL; - rc = encomsp->channelEntryPoints.pVirtualChannelClose(encomsp->OpenHandle); + if (CHANNEL_RC_OK != rc) { WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08X]", - WTSErrorToString(rc), rc); + WTSErrorToString(rc), rc); return rc; } + encomsp->OpenHandle = 0; + if (encomsp->data_in) { Stream_Free(encomsp->data_in, TRUE); encomsp->data_in = NULL; } - encomsp_remove_open_handle_data(encomsp->OpenHandle); return CHANNEL_RC_OK; } @@ -1254,21 +1175,19 @@ static UINT encomsp_virtual_channel_event_disconnected(encomspPlugin* encomsp) */ static UINT encomsp_virtual_channel_event_terminated(encomspPlugin* encomsp) { - encomsp_remove_init_handle_data(encomsp->InitHandle); + encomsp->InitHandle = 0; free(encomsp); return CHANNEL_RC_OK; } static VOID VCAPITYPE encomsp_virtual_channel_init_event(LPVOID pInitHandle, - UINT event, LPVOID pData, - UINT dataLength) + UINT event, LPVOID pData, + UINT dataLength) { - encomspPlugin* encomsp; + encomspPlugin* encomsp = s_TLSPluginContext; UINT error = CHANNEL_RC_OK; - encomsp = (encomspPlugin*) encomsp_get_init_handle_data(pInitHandle); - - if (!encomsp) + if (!encomsp || (encomsp->InitHandle != pInitHandle)) { WLog_ERR(TAG, "encomsp_virtual_channel_init_event: error no match"); return; @@ -1277,24 +1196,31 @@ static VOID VCAPITYPE encomsp_virtual_channel_init_event(LPVOID pInitHandle, switch (event) { case CHANNEL_EVENT_CONNECTED: - if ((error = encomsp_virtual_channel_event_connected(encomsp, pData, dataLength))) - WLog_ERR(TAG, "encomsp_virtual_channel_event_connected failed with error %lu", error); + if ((error = encomsp_virtual_channel_event_connected(encomsp, pData, + dataLength))) + WLog_ERR(TAG, "encomsp_virtual_channel_event_connected failed with error %lu", + error); + break; case CHANNEL_EVENT_DISCONNECTED: if ((error = encomsp_virtual_channel_event_disconnected(encomsp))) - WLog_ERR(TAG, "encomsp_virtual_channel_event_disconnected failed with error %lu", error); + WLog_ERR(TAG, + "encomsp_virtual_channel_event_disconnected failed with error %lu", error); + break; case CHANNEL_EVENT_TERMINATED: encomsp_virtual_channel_event_terminated(encomsp); break; + default: WLog_ERR(TAG, "Unhandled event type %d", event); } if (error && encomsp->rdpcontext) - setChannelError(encomsp->rdpcontext, error, "encomsp_virtual_channel_init_event reported an error"); + setChannelError(encomsp->rdpcontext, error, + "encomsp_virtual_channel_init_event reported an error"); } /* encomsp is always built-in */ @@ -1307,9 +1233,8 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) EncomspClientContext* context; CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx; BOOL isFreerdp = FALSE; - UINT error; - encomsp = (encomspPlugin*) calloc(1, sizeof(encomspPlugin)); + if (!encomsp) { WLog_ERR(TAG, "calloc failed!"); @@ -1317,19 +1242,18 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) } encomsp->channelDef.options = - CHANNEL_OPTION_INITIALIZED | - CHANNEL_OPTION_ENCRYPT_RDP | - CHANNEL_OPTION_COMPRESS_RDP | - CHANNEL_OPTION_SHOW_PROTOCOL; - + CHANNEL_OPTION_INITIALIZED | + CHANNEL_OPTION_ENCRYPT_RDP | + CHANNEL_OPTION_COMPRESS_RDP | + CHANNEL_OPTION_SHOW_PROTOCOL; strcpy(encomsp->channelDef.name, "encomsp"); - 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 = (EncomspClientContext*) calloc(1, sizeof(EncomspClientContext)); + if (!context) { WLog_ERR(TAG, "calloc failed!"); @@ -1337,7 +1261,6 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) } context->handle = (void*) encomsp; - context->FilterUpdated = NULL; context->ApplicationCreated = NULL; context->ApplicationRemoved = NULL; @@ -1346,40 +1269,40 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) context->ShowWindow = NULL; context->ParticipantCreated = NULL; context->ParticipantRemoved = NULL; - context->ChangeParticipantControlLevel = encomsp_send_change_participant_control_level_pdu; + context->ChangeParticipantControlLevel = + encomsp_send_change_participant_control_level_pdu; context->GraphicsStreamPaused = NULL; context->GraphicsStreamResumed = NULL; - *(pEntryPointsEx->ppInterface) = (void*) context; encomsp->context = context; encomsp->rdpcontext = pEntryPointsEx->context; isFreerdp = TRUE; } - CopyMemory(&(encomsp->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); - + CopyMemory(&(encomsp->channelEntryPoints), pEntryPoints, + sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); rc = encomsp->channelEntryPoints.pVirtualChannelInit(&encomsp->InitHandle, - &encomsp->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, encomsp_virtual_channel_init_event); + &encomsp->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, + encomsp_virtual_channel_init_event); + if (CHANNEL_RC_OK != rc) { WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]", - WTSErrorToString(rc), rc); - goto error_out; - } - - encomsp->channelEntryPoints.pInterface = *(encomsp->channelEntryPoints.ppInterface); - encomsp->channelEntryPoints.ppInterface = &(encomsp->channelEntryPoints.pInterface); - - if ((error = encomsp_add_init_handle_data(encomsp->InitHandle, (void*) encomsp))) - { - WLog_ERR(TAG, "encomsp_add_init_handle_data failed with error %lu!", error); + WTSErrorToString(rc), rc); goto error_out; } + encomsp->channelEntryPoints.pInterface = * + (encomsp->channelEntryPoints.ppInterface); + encomsp->channelEntryPoints.ppInterface = & + (encomsp->channelEntryPoints.pInterface); + s_TLSPluginContext = encomsp; return TRUE; error_out: + if (isFreerdp) free(encomsp->context); + free(encomsp); return FALSE; } diff --git a/channels/rail/client/rail_main.c b/channels/rail/client/rail_main.c index 618227b..0ab7ba4 100644 --- a/channels/rail/client/rail_main.c +++ b/channels/rail/client/rail_main.c @@ -33,6 +33,8 @@ #include "rail_orders.h" #include "rail_main.h" +static WINPR_TLS railPlugin* s_TLSPluginContext = NULL; + RailClientContext* rail_get_client_interface(railPlugin* rail) { RailClientContext* pInterface; @@ -45,7 +47,7 @@ RailClientContext* rail_get_client_interface(railPlugin* rail) * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_send(railPlugin* rail, wStream* s) +static UINT rail_send(railPlugin* rail, wStream* s) { UINT status; @@ -56,14 +58,14 @@ UINT rail_send(railPlugin* rail, wStream* s) else { status = rail->channelEntryPoints.pVirtualChannelWrite(rail->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; @@ -77,15 +79,15 @@ UINT rail_send(railPlugin* rail, wStream* s) UINT rail_send_channel_data(railPlugin* rail, void* data, size_t length) { wStream* s = NULL; - s = Stream_New(NULL, length); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); return CHANNEL_RC_NO_MEMORY; } - Stream_Write(s, data, length); + Stream_Write(s, data, length); return rail_send(rail, s); } @@ -98,11 +100,11 @@ UINT rail_send_channel_data(railPlugin* rail, void* data, size_t length) * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_client_execute(RailClientContext* context, RAIL_EXEC_ORDER* exec) +static UINT rail_client_execute(RailClientContext* context, + RAIL_EXEC_ORDER* exec) { char* exeOrFile; railPlugin* rail = (railPlugin*) context->handle; - exeOrFile = exec->RemoteApplicationProgram; if (!exeOrFile) @@ -114,10 +116,12 @@ UINT rail_client_execute(RailClientContext* context, RAIL_EXEC_ORDER* exec) exec->flags |= RAIL_EXEC_FLAG_FILE; } - rail_string_to_unicode_string(exec->RemoteApplicationProgram, &exec->exeOrFile); /* RemoteApplicationProgram */ - rail_string_to_unicode_string(exec->RemoteApplicationWorkingDir, &exec->workingDir); /* ShellWorkingDirectory */ - rail_string_to_unicode_string(exec->RemoteApplicationArguments, &exec->arguments); /* RemoteApplicationCmdLine */ - + rail_string_to_unicode_string(exec->RemoteApplicationProgram, + &exec->exeOrFile); /* RemoteApplicationProgram */ + rail_string_to_unicode_string(exec->RemoteApplicationWorkingDir, + &exec->workingDir); /* ShellWorkingDirectory */ + rail_string_to_unicode_string(exec->RemoteApplicationArguments, + &exec->arguments); /* RemoteApplicationCmdLine */ return rail_send_client_exec_order(rail, exec); } @@ -126,10 +130,10 @@ UINT rail_client_execute(RailClientContext* context, RAIL_EXEC_ORDER* exec) * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_client_activate(RailClientContext* context, RAIL_ACTIVATE_ORDER* activate) +static UINT rail_client_activate(RailClientContext* context, + RAIL_ACTIVATE_ORDER* activate) { railPlugin* rail = (railPlugin*) context->handle; - return rail_send_client_activate_order(rail, activate); } @@ -138,13 +142,13 @@ UINT rail_client_activate(RailClientContext* context, RAIL_ACTIVATE_ORDER* activ * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_send_client_sysparam(RailClientContext* context, RAIL_SYSPARAM_ORDER* sysparam) +static UINT rail_send_client_sysparam(RailClientContext* context, + RAIL_SYSPARAM_ORDER* sysparam) { wStream* s; int length; railPlugin* rail = (railPlugin*) context->handle; UINT error; - length = RAIL_SYSPARAM_ORDER_LENGTH; switch (sysparam->param) @@ -168,6 +172,7 @@ UINT rail_send_client_sysparam(RailClientContext* context, RAIL_SYSPARAM_ORDER* } s = rail_pdu_init(RAIL_SYSPARAM_ORDER_LENGTH + 8); + if (!s) { WLog_ERR(TAG, "rail_pdu_init failed!"); @@ -195,13 +200,15 @@ UINT rail_send_client_sysparam(RailClientContext* context, RAIL_SYSPARAM_ORDER* * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* sysparam) +static UINT rail_client_system_param(RailClientContext* context, + RAIL_SYSPARAM_ORDER* sysparam) { UINT error = CHANNEL_RC_OK; if (sysparam->params & SPI_MASK_SET_HIGH_CONTRAST) { sysparam->param = SPI_SET_HIGH_CONTRAST; + if ((error = rail_send_client_sysparam(context, sysparam))) { WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error); @@ -212,6 +219,7 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s if (sysparam->params & SPI_MASK_TASKBAR_POS) { sysparam->param = SPI_TASKBAR_POS; + if ((error = rail_send_client_sysparam(context, sysparam))) { WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error); @@ -222,6 +230,7 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s if (sysparam->params & SPI_MASK_SET_MOUSE_BUTTON_SWAP) { sysparam->param = SPI_SET_MOUSE_BUTTON_SWAP; + if ((error = rail_send_client_sysparam(context, sysparam))) { WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error); @@ -232,6 +241,7 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s if (sysparam->params & SPI_MASK_SET_KEYBOARD_PREF) { sysparam->param = SPI_SET_KEYBOARD_PREF; + if ((error = rail_send_client_sysparam(context, sysparam))) { WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error); @@ -242,6 +252,7 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s if (sysparam->params & SPI_MASK_SET_DRAG_FULL_WINDOWS) { sysparam->param = SPI_SET_DRAG_FULL_WINDOWS; + if ((error = rail_send_client_sysparam(context, sysparam))) { WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error); @@ -252,6 +263,7 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s if (sysparam->params & SPI_MASK_SET_KEYBOARD_CUES) { sysparam->param = SPI_SET_KEYBOARD_CUES; + if ((error = rail_send_client_sysparam(context, sysparam))) { WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error); @@ -262,6 +274,7 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s if (sysparam->params & SPI_MASK_SET_WORK_AREA) { sysparam->param = SPI_SET_WORK_AREA; + if ((error = rail_send_client_sysparam(context, sysparam))) { WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error); @@ -277,7 +290,8 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_server_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* sysparam) +static UINT rail_server_system_param(RailClientContext* context, + RAIL_SYSPARAM_ORDER* sysparam) { return CHANNEL_RC_OK; /* stub - should be registered by client */ } @@ -287,10 +301,10 @@ UINT rail_server_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_client_system_command(RailClientContext* context, RAIL_SYSCOMMAND_ORDER* syscommand) +static UINT rail_client_system_command(RailClientContext* context, + RAIL_SYSCOMMAND_ORDER* syscommand) { railPlugin* rail = (railPlugin*) context->handle; - return rail_send_client_syscommand_order(rail, syscommand); } @@ -299,10 +313,10 @@ UINT rail_client_system_command(RailClientContext* context, RAIL_SYSCOMMAND_ORDE * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_client_handshake(RailClientContext* context, RAIL_HANDSHAKE_ORDER* handshake) +static UINT rail_client_handshake(RailClientContext* context, + RAIL_HANDSHAKE_ORDER* handshake) { railPlugin* rail = (railPlugin*) context->handle; - return rail_send_handshake_order(rail, handshake); } @@ -311,7 +325,8 @@ UINT rail_client_handshake(RailClientContext* context, RAIL_HANDSHAKE_ORDER* han * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_server_handshake(RailClientContext* context, RAIL_HANDSHAKE_ORDER* handshake) +static UINT rail_server_handshake(RailClientContext* context, + RAIL_HANDSHAKE_ORDER* handshake) { return CHANNEL_RC_OK; /* stub - should be registered by client */ } @@ -321,10 +336,10 @@ UINT rail_server_handshake(RailClientContext* context, RAIL_HANDSHAKE_ORDER* han * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_client_handshake_ex(RailClientContext* context, RAIL_HANDSHAKE_EX_ORDER* handshakeEx) +static UINT rail_client_handshake_ex(RailClientContext* context, + RAIL_HANDSHAKE_EX_ORDER* handshakeEx) { railPlugin* rail = (railPlugin*) context->handle; - return rail_send_handshake_ex_order(rail, handshakeEx); } @@ -333,7 +348,8 @@ UINT rail_client_handshake_ex(RailClientContext* context, RAIL_HANDSHAKE_EX_ORDE * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_server_handshake_ex(RailClientContext* context, RAIL_HANDSHAKE_EX_ORDER* handshakeEx) +static UINT rail_server_handshake_ex(RailClientContext* context, + RAIL_HANDSHAKE_EX_ORDER* handshakeEx) { return CHANNEL_RC_OK; /* stub - should be registered by client */ } @@ -343,10 +359,10 @@ UINT rail_server_handshake_ex(RailClientContext* context, RAIL_HANDSHAKE_EX_ORDE * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_client_notify_event(RailClientContext* context, RAIL_NOTIFY_EVENT_ORDER* notifyEvent) +static UINT rail_client_notify_event(RailClientContext* context, + RAIL_NOTIFY_EVENT_ORDER* notifyEvent) { railPlugin* rail = (railPlugin*) context->handle; - return rail_send_client_notify_event_order(rail, notifyEvent); } @@ -355,10 +371,10 @@ UINT rail_client_notify_event(RailClientContext* context, RAIL_NOTIFY_EVENT_ORDE * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_client_window_move(RailClientContext* context, RAIL_WINDOW_MOVE_ORDER* windowMove) +static UINT rail_client_window_move(RailClientContext* context, + RAIL_WINDOW_MOVE_ORDER* windowMove) { railPlugin* rail = (railPlugin*) context->handle; - return rail_send_client_window_move_order(rail, windowMove); } @@ -367,7 +383,8 @@ UINT rail_client_window_move(RailClientContext* context, RAIL_WINDOW_MOVE_ORDER* * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_server_local_move_size(RailClientContext* context, RAIL_LOCALMOVESIZE_ORDER* localMoveSize) +static UINT rail_server_local_move_size(RailClientContext* context, + RAIL_LOCALMOVESIZE_ORDER* localMoveSize) { return CHANNEL_RC_OK; /* stub - should be registered by client */ } @@ -377,7 +394,8 @@ UINT rail_server_local_move_size(RailClientContext* context, RAIL_LOCALMOVESIZE_ * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_server_min_max_info(RailClientContext* context, RAIL_MINMAXINFO_ORDER* minMaxInfo) +static UINT rail_server_min_max_info(RailClientContext* context, + RAIL_MINMAXINFO_ORDER* minMaxInfo) { return CHANNEL_RC_OK; /* stub - should be registered by client */ } @@ -387,10 +405,10 @@ UINT rail_server_min_max_info(RailClientContext* context, RAIL_MINMAXINFO_ORDER* * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_client_information(RailClientContext* context, RAIL_CLIENT_STATUS_ORDER* clientStatus) +static UINT rail_client_information(RailClientContext* context, + RAIL_CLIENT_STATUS_ORDER* clientStatus) { railPlugin* rail = (railPlugin*) context->handle; - return rail_send_client_status_order(rail, clientStatus); } @@ -399,10 +417,10 @@ UINT rail_client_information(RailClientContext* context, RAIL_CLIENT_STATUS_ORDE * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_client_system_menu(RailClientContext* context, RAIL_SYSMENU_ORDER* sysmenu) +static UINT rail_client_system_menu(RailClientContext* context, + RAIL_SYSMENU_ORDER* sysmenu) { railPlugin* rail = (railPlugin*) context->handle; - return rail_send_client_sysmenu_order(rail, sysmenu); } @@ -411,10 +429,10 @@ UINT rail_client_system_menu(RailClientContext* context, RAIL_SYSMENU_ORDER* sys * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_client_language_bar_info(RailClientContext* context, RAIL_LANGBAR_INFO_ORDER* langBarInfo) +static UINT rail_client_language_bar_info(RailClientContext* context, + RAIL_LANGBAR_INFO_ORDER* langBarInfo) { railPlugin* rail = (railPlugin*) context->handle; - return rail_send_client_langbar_info_order(rail, langBarInfo); } @@ -423,7 +441,8 @@ UINT rail_client_language_bar_info(RailClientContext* context, RAIL_LANGBAR_INFO * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_server_language_bar_info(RailClientContext* context, RAIL_LANGBAR_INFO_ORDER* langBarInfo) +static UINT rail_server_language_bar_info(RailClientContext* context, + RAIL_LANGBAR_INFO_ORDER* langBarInfo) { return CHANNEL_RC_OK; /* stub - should be registered by client */ } @@ -433,7 +452,8 @@ UINT rail_server_language_bar_info(RailClientContext* context, RAIL_LANGBAR_INFO * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_server_execute_result(RailClientContext* context, RAIL_EXEC_RESULT_ORDER* execResult) +static UINT rail_server_execute_result(RailClientContext* context, + RAIL_EXEC_RESULT_ORDER* execResult) { return CHANNEL_RC_OK; /* stub - should be registered by client */ } @@ -443,10 +463,10 @@ UINT rail_server_execute_result(RailClientContext* context, RAIL_EXEC_RESULT_ORD * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_client_get_appid_request(RailClientContext* context, RAIL_GET_APPID_REQ_ORDER* getAppIdReq) +static UINT rail_client_get_appid_request(RailClientContext* context, + RAIL_GET_APPID_REQ_ORDER* getAppIdReq) { railPlugin* rail = (railPlugin*) context->handle; - return rail_send_client_get_appid_req_order(rail, getAppIdReq); } @@ -455,111 +475,19 @@ UINT rail_client_get_appid_request(RailClientContext* context, RAIL_GET_APPID_RE * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_server_get_appid_response(RailClientContext* context, RAIL_GET_APPID_RESP_ORDER* getAppIdResp) +static UINT rail_server_get_appid_response(RailClientContext* context, + RAIL_GET_APPID_RESP_ORDER* getAppIdResp) { return CHANNEL_RC_OK; /* stub - should be registered by client */ } -/****************************************************************************************/ - -static wListDictionary* g_InitHandles = NULL; -static wListDictionary* g_OpenHandles = NULL; - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -UINT rail_add_init_handle_data(void* pInitHandle, void* pUserData) -{ - if (!g_InitHandles) - { - g_InitHandles = ListDictionary_New(TRUE); - } - if (!g_InitHandles) - { - WLog_ERR(TAG, "ListDictionary_New failed!"); - return CHANNEL_RC_NO_MEMORY; - } - - if (!ListDictionary_Add(g_InitHandles, pInitHandle, pUserData)) - { - WLog_ERR(TAG, "ListDictionary_Add failed!"); - return ERROR_INTERNAL_ERROR; - } - return CHANNEL_RC_OK; -} - -void* rail_get_init_handle_data(void* pInitHandle) -{ - void* pUserData = NULL; - pUserData = ListDictionary_GetItemValue(g_InitHandles, pInitHandle); - return pUserData; -} - -void rail_remove_init_handle_data(void* pInitHandle) -{ - ListDictionary_Remove(g_InitHandles, pInitHandle); - if (ListDictionary_Count(g_InitHandles) < 1) - { - ListDictionary_Free(g_InitHandles); - g_InitHandles = NULL; - } -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -UINT rail_add_open_handle_data(DWORD openHandle, void* pUserData) -{ - void* pOpenHandle = (void*) (size_t) openHandle; - - if (!g_OpenHandles) - { - g_OpenHandles = ListDictionary_New(TRUE); - } - if (!g_OpenHandles) - { - WLog_ERR(TAG, "ListDictionary_New failed!"); - return CHANNEL_RC_NO_MEMORY; - } - - if (!ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData)) - { - WLog_ERR(TAG, "ListDictionary_Add failed!"); - return ERROR_INTERNAL_ERROR; - } - return CHANNEL_RC_OK; -} - -void* rail_get_open_handle_data(DWORD openHandle) -{ - void* pUserData = NULL; - void* pOpenHandle = (void*) (size_t) openHandle; - pUserData = ListDictionary_GetItemValue(g_OpenHandles, pOpenHandle); - return pUserData; -} - -void rail_remove_open_handle_data(DWORD openHandle) -{ - void* pOpenHandle = (void*) (size_t) openHandle; - ListDictionary_Remove(g_OpenHandles, pOpenHandle); - if (ListDictionary_Count(g_OpenHandles) < 1) - { - ListDictionary_Free(g_OpenHandles); - g_OpenHandles = NULL; - } -} - /** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT rail_virtual_channel_event_data_received(railPlugin* rail, - void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) + void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { wStream* data_in; @@ -574,6 +502,7 @@ static UINT rail_virtual_channel_event_data_received(railPlugin* rail, Stream_Free(rail->data_in, TRUE); rail->data_in = Stream_New(NULL, totalLength); + if (!rail->data_in) { WLog_ERR(TAG, "Stream_New failed!"); @@ -582,11 +511,13 @@ static UINT rail_virtual_channel_event_data_received(railPlugin* rail, } data_in = rail->data_in; + if (!Stream_EnsureRemainingCapacity(data_in, (int) dataLength)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return CHANNEL_RC_NO_MEMORY; } + Stream_Write(data_in, pData, dataLength); if (dataFlags & CHANNEL_FLAG_LAST) @@ -607,18 +538,18 @@ static UINT rail_virtual_channel_event_data_received(railPlugin* rail, return ERROR_INTERNAL_ERROR; } } + return CHANNEL_RC_OK; } -static VOID VCAPITYPE rail_virtual_channel_open_event(DWORD openHandle, UINT event, - LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) +static VOID VCAPITYPE rail_virtual_channel_open_event(DWORD openHandle, + UINT event, + LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { - railPlugin* rail; + railPlugin* rail = s_TLSPluginContext; UINT error = CHANNEL_RC_OK; - rail = (railPlugin*) rail_get_open_handle_data(openHandle); - - if (!rail) + if (!rail || (rail->OpenHandle != openHandle)) { WLog_ERR(TAG, "rail_virtual_channel_open_event: error no match"); return; @@ -627,8 +558,11 @@ static VOID VCAPITYPE rail_virtual_channel_open_event(DWORD openHandle, UINT eve switch (event) { case CHANNEL_EVENT_DATA_RECEIVED: - if ((error = rail_virtual_channel_event_data_received(rail, pData, dataLength, totalLength, dataFlags))) - WLog_ERR(TAG, "rail_virtual_channel_event_data_received failed with error %lu!", error); + if ((error = rail_virtual_channel_event_data_received(rail, pData, dataLength, + totalLength, dataFlags))) + WLog_ERR(TAG, "rail_virtual_channel_event_data_received failed with error %lu!", + error); + break; case CHANNEL_EVENT_WRITE_COMPLETE: @@ -640,7 +574,8 @@ static VOID VCAPITYPE rail_virtual_channel_open_event(DWORD openHandle, UINT eve } if (error && rail->rdpcontext) - setChannelError(rail->rdpcontext, error, "rail_virtual_channel_open_event reported an error"); + setChannelError(rail->rdpcontext, error, + "rail_virtual_channel_open_event reported an error"); return; } @@ -667,12 +602,14 @@ static void* rail_virtual_channel_client_thread(void* arg) error = ERROR_INTERNAL_ERROR; break; } + if (message.id == WMQ_QUIT) break; if (message.id == 0) { data = (wStream*) message.wParam; + if ((error = rail_order_recv(rail, data))) { WLog_ERR(TAG, "rail_order_recv failed with error %d!", error); @@ -682,7 +619,8 @@ static void* rail_virtual_channel_client_thread(void* arg) } if (error && rail->rdpcontext) - setChannelError(rail->rdpcontext, error, "rail_virtual_channel_client_thread reported an error"); + setChannelError(rail->rdpcontext, error, + "rail_virtual_channel_client_thread reported an error"); ExitThread((DWORD)error); return NULL; @@ -693,27 +631,22 @@ static void* rail_virtual_channel_client_thread(void* arg) * * @return 0 on success, otherwise a Win32 error code */ -static UINT rail_virtual_channel_event_connected(railPlugin* rail, LPVOID pData, UINT32 dataLength) +static UINT rail_virtual_channel_event_connected(railPlugin* rail, LPVOID pData, + UINT32 dataLength) { UINT status; - status = rail->channelEntryPoints.pVirtualChannelOpen(rail->InitHandle, - &rail->OpenHandle, rail->channelDef.name, rail_virtual_channel_open_event); + &rail->OpenHandle, rail->channelDef.name, rail_virtual_channel_open_event); if (status != CHANNEL_RC_OK) { WLog_ERR(TAG, "pVirtualChannelOpen failed with %s [%08X]", - WTSErrorToString(status), status); - return status; - } - - if ((status = rail_add_open_handle_data(rail->OpenHandle, rail))) - { - WLog_ERR(TAG, "rail_add_open_handle_data failed with error %lu!", status); + WTSErrorToString(status), status); return status; } rail->queue = MessageQueue_New(NULL); + if (!rail->queue) { WLog_ERR(TAG, "MessageQueue_New failed!"); @@ -721,13 +654,15 @@ static UINT rail_virtual_channel_event_connected(railPlugin* rail, LPVOID pData, } if (!(rail->thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) rail_virtual_channel_client_thread, (void*) rail, 0, NULL))) + (LPTHREAD_START_ROUTINE) rail_virtual_channel_client_thread, (void*) rail, 0, + NULL))) { WLog_ERR(TAG, "CreateThread failed!"); MessageQueue_Free(rail->queue); rail->queue = NULL; return ERROR_INTERNAL_ERROR; } + return CHANNEL_RC_OK; } @@ -739,51 +674,52 @@ static UINT rail_virtual_channel_event_connected(railPlugin* rail, LPVOID pData, static UINT rail_virtual_channel_event_disconnected(railPlugin* rail) { UINT rc; - if (MessageQueue_PostQuit(rail->queue, 0) && (WaitForSingleObject(rail->thread, INFINITE) == WAIT_FAILED)) - { - rc = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", rc); - return rc; - } + + if (MessageQueue_PostQuit(rail->queue, 0) + && (WaitForSingleObject(rail->thread, INFINITE) == WAIT_FAILED)) + { + rc = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", rc); + return rc; + } MessageQueue_Free(rail->queue); CloseHandle(rail->thread); - rail->queue = NULL; rail->thread = NULL; - rc = rail->channelEntryPoints.pVirtualChannelClose(rail->OpenHandle); + if (CHANNEL_RC_OK != rc) { WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08X]", - WTSErrorToString(rc), rc); - return rc; + WTSErrorToString(rc), rc); + return rc; } + rail->OpenHandle = 0; + if (rail->data_in) { Stream_Free(rail->data_in, TRUE); rail->data_in = NULL; } - rail_remove_open_handle_data(rail->OpenHandle); - return CHANNEL_RC_OK; + return CHANNEL_RC_OK; } static void rail_virtual_channel_event_terminated(railPlugin* rail) { - rail_remove_init_handle_data(rail->InitHandle); + rail->InitHandle = 0; free(rail); } -static VOID VCAPITYPE rail_virtual_channel_init_event(LPVOID pInitHandle, UINT event, LPVOID pData, UINT dataLength) +static VOID VCAPITYPE rail_virtual_channel_init_event(LPVOID pInitHandle, + UINT event, LPVOID pData, UINT dataLength) { - railPlugin* rail; + railPlugin* rail = s_TLSPluginContext; UINT error = CHANNEL_RC_OK; - rail = (railPlugin*) rail_get_init_handle_data(pInitHandle); - - if (!rail) + if (!rail || (rail->InitHandle != pInitHandle)) { WLog_ERR(TAG, "rail_virtual_channel_init_event: error no match"); return; @@ -793,12 +729,16 @@ static VOID VCAPITYPE rail_virtual_channel_init_event(LPVOID pInitHandle, UINT e { case CHANNEL_EVENT_CONNECTED: if ((error = rail_virtual_channel_event_connected(rail, pData, dataLength))) - WLog_ERR(TAG, "rail_virtual_channel_event_connected failed with error %lu!", error); + WLog_ERR(TAG, "rail_virtual_channel_event_connected failed with error %lu!", + error); + break; case CHANNEL_EVENT_DISCONNECTED: if ((error = rail_virtual_channel_event_disconnected(rail))) - WLog_ERR(TAG, "rail_virtual_channel_event_disconnected failed with error %lu!", error); + WLog_ERR(TAG, "rail_virtual_channel_event_disconnected failed with error %lu!", + error); + break; case CHANNEL_EVENT_TERMINATED: @@ -806,8 +746,9 @@ static VOID VCAPITYPE rail_virtual_channel_init_event(LPVOID pInitHandle, UINT e break; } - if(error && rail->rdpcontext) - setChannelError(rail->rdpcontext, error, "rail_virtual_channel_init_event reported an error"); + if (error && rail->rdpcontext) + setChannelError(rail->rdpcontext, error, + "rail_virtual_channel_init_event reported an error"); } /* rail is always built-in */ @@ -820,9 +761,8 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) RailClientContext* context; CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx; BOOL isFreerdp = FALSE; - UINT error; - rail = (railPlugin*) calloc(1, sizeof(railPlugin)); + if (!rail) { WLog_ERR(TAG, "calloc failed!"); @@ -830,19 +770,18 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) } rail->channelDef.options = - CHANNEL_OPTION_INITIALIZED | - CHANNEL_OPTION_ENCRYPT_RDP | - CHANNEL_OPTION_COMPRESS_RDP | - CHANNEL_OPTION_SHOW_PROTOCOL; - + CHANNEL_OPTION_INITIALIZED | + CHANNEL_OPTION_ENCRYPT_RDP | + CHANNEL_OPTION_COMPRESS_RDP | + CHANNEL_OPTION_SHOW_PROTOCOL; strcpy(rail->channelDef.name, "rail"); - 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 = (RailClientContext*) calloc(1, sizeof(RailClientContext)); + if (!context) { WLog_ERR(TAG, "calloc failed!"); @@ -852,7 +791,6 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) context->handle = (void*) rail; context->custom = NULL; - context->ClientExecute = rail_client_execute; context->ClientActivate = rail_client_activate; context->ClientSystemParam = rail_client_system_param; @@ -874,7 +812,6 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) context->ClientGetAppIdRequest = rail_client_get_appid_request; context->ServerGetAppIdResponse = rail_server_get_appid_response; rail->rdpcontext = pEntryPointsEx->context; - *(pEntryPointsEx->ppInterface) = (void*) context; rail->context = context; isFreerdp = TRUE; @@ -882,34 +819,29 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) WLog_Init(); rail->log = WLog_Get("com.freerdp.channels.rail.client"); - WLog_Print(rail->log, WLOG_DEBUG, "VirtualChannelEntry"); - - CopyMemory(&(rail->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); - + CopyMemory(&(rail->channelEntryPoints), pEntryPoints, + sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); rc = rail->channelEntryPoints.pVirtualChannelInit(&rail->InitHandle, - &rail->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, rail_virtual_channel_init_event); + &rail->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, + rail_virtual_channel_init_event); if (CHANNEL_RC_OK != rc) { WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]", - WTSErrorToString(rc), rc); + WTSErrorToString(rc), rc); goto error_out; } rail->channelEntryPoints.pInterface = *(rail->channelEntryPoints.ppInterface); rail->channelEntryPoints.ppInterface = &(rail->channelEntryPoints.pInterface); - - if ((error = rail_add_init_handle_data(rail->InitHandle, (void*) rail))) - { - WLog_ERR(TAG, "rail_add_init_handle_data failed with error %lu!", error); - goto error_out; - } - + s_TLSPluginContext = rail; return TRUE; error_out: + if (isFreerdp) free(rail->context); + free(rail); return FALSE; } diff --git a/channels/rdpdr/client/rdpdr_main.c b/channels/rdpdr/client/rdpdr_main.c index 7472b0c..7bc57f4 100755 --- a/channels/rdpdr/client/rdpdr_main.c +++ b/channels/rdpdr/client/rdpdr_main.c @@ -75,6 +75,8 @@ struct _DEVICE_DRIVE_EXT char* path; }; +static WINPR_TLS rdpdrPlugin* s_TLSPluginContext = NULL; + /** * Function description * @@ -842,7 +844,7 @@ cleanup: return error; } -void first_hotplug(rdpdrPlugin* rdpdr) +static void first_hotplug(rdpdrPlugin* rdpdr) { UINT error; @@ -1411,107 +1413,6 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s) return CHANNEL_RC_OK; } - -/****************************************************************************************/ - - -static wListDictionary* g_InitHandles = NULL; -static wListDictionary* g_OpenHandles = NULL; - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -UINT rdpdr_add_init_handle_data(void* pInitHandle, void* pUserData) -{ - if (!g_InitHandles) - { - g_InitHandles = ListDictionary_New(TRUE); - } - - if (!g_InitHandles) - { - WLog_ERR(TAG, "ListDictionary_New failed!"); - return CHANNEL_RC_NO_MEMORY; - } - - if (!ListDictionary_Add(g_InitHandles, pInitHandle, pUserData)) - { - WLog_ERR(TAG, "ListDictionary_Add failed!"); - return ERROR_INTERNAL_ERROR; - } - - return CHANNEL_RC_OK; -} - -void* rdpdr_get_init_handle_data(void* pInitHandle) -{ - void* pUserData = NULL; - pUserData = ListDictionary_GetItemValue(g_InitHandles, pInitHandle); - return pUserData; -} - -void rdpdr_remove_init_handle_data(void* pInitHandle) -{ - ListDictionary_Remove(g_InitHandles, pInitHandle); - - if (ListDictionary_Count(g_InitHandles) < 1) - { - ListDictionary_Free(g_InitHandles); - g_InitHandles = NULL; - } -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -UINT rdpdr_add_open_handle_data(DWORD openHandle, void* pUserData) -{ - void* pOpenHandle = (void*)(size_t) openHandle; - - if (!g_OpenHandles) - { - g_OpenHandles = ListDictionary_New(TRUE); - } - - if (!g_OpenHandles) - { - WLog_ERR(TAG, "ListDictionary_New failed!"); - return CHANNEL_RC_NO_MEMORY; - } - - if (!ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData)) - { - WLog_ERR(TAG, "ListDictionary_Add failed!"); - return ERROR_INTERNAL_ERROR; - } - - return CHANNEL_RC_OK; -} - -void* rdpdr_get_open_handle_data(DWORD openHandle) -{ - void* pUserData = NULL; - void* pOpenHandle = (void*)(size_t) openHandle; - pUserData = ListDictionary_GetItemValue(g_OpenHandles, pOpenHandle); - return pUserData; -} - -void rdpdr_remove_open_handle_data(DWORD openHandle) -{ - void* pOpenHandle = (void*)(size_t) openHandle; - ListDictionary_Remove(g_OpenHandles, pOpenHandle); - - if (ListDictionary_Count(g_OpenHandles) < 1) - { - ListDictionary_Free(g_OpenHandles); - g_OpenHandles = NULL; - } -} - /** * Function description * @@ -1614,11 +1515,10 @@ static VOID VCAPITYPE rdpdr_virtual_channel_open_event(DWORD openHandle, UINT event, LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { - rdpdrPlugin* rdpdr; + rdpdrPlugin* rdpdr = s_TLSPluginContext; UINT error = CHANNEL_RC_OK; - rdpdr = (rdpdrPlugin*) rdpdr_get_open_handle_data(openHandle); - if (!rdpdr || !pData) + if (!rdpdr || !pData || (rdpdr->OpenHandle != openHandle)) { WLog_ERR(TAG, "rdpdr_virtual_channel_open_event: error no match"); return; @@ -1716,7 +1616,6 @@ static UINT rdpdr_virtual_channel_event_connected(rdpdrPlugin* rdpdr, LPVOID pData, UINT32 dataLength) { UINT32 status; - UINT error; status = rdpdr->channelEntryPoints.pVirtualChannelOpen(rdpdr->InitHandle, &rdpdr->OpenHandle, rdpdr->channelDef.name, rdpdr_virtual_channel_open_event); @@ -1727,12 +1626,6 @@ static UINT rdpdr_virtual_channel_event_connected(rdpdrPlugin* rdpdr, return status; } - if ((error = rdpdr_add_open_handle_data(rdpdr->OpenHandle, rdpdr))) - { - WLog_ERR(TAG, "rdpdr_add_open_handle_data failed with error %lu!", error); - return error; - } - rdpdr->queue = MessageQueue_New(NULL); if (!rdpdr->queue) @@ -1788,6 +1681,8 @@ static UINT rdpdr_virtual_channel_event_disconnected(rdpdrPlugin* rdpdr) WTSErrorToString(error), error); } + rdpdr->OpenHandle = 0; + if (rdpdr->data_in) { Stream_Free(rdpdr->data_in, TRUE); @@ -1800,13 +1695,11 @@ static UINT rdpdr_virtual_channel_event_disconnected(rdpdrPlugin* rdpdr) rdpdr->devman = NULL; } - rdpdr_remove_open_handle_data(rdpdr->OpenHandle); return error; } static void rdpdr_virtual_channel_event_terminated(rdpdrPlugin* rdpdr) { - rdpdr_remove_init_handle_data(rdpdr->InitHandle); free(rdpdr); } @@ -1814,11 +1707,10 @@ static VOID VCAPITYPE rdpdr_virtual_channel_init_event(LPVOID pInitHandle, UINT event, LPVOID pData, UINT dataLength) { - rdpdrPlugin* rdpdr; + rdpdrPlugin* rdpdr = s_TLSPluginContext; UINT error = CHANNEL_RC_OK; - rdpdr = (rdpdrPlugin*) rdpdr_get_init_handle_data(pInitHandle); - if (!rdpdr) + if (!rdpdr || (rdpdr->InitHandle != pInitHandle)) { WLog_ERR(TAG, "error no match"); return; @@ -1902,12 +1794,6 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) return FALSE; } - if ((rc = rdpdr_add_init_handle_data(rdpdr->InitHandle, (void*) rdpdr))) - { - WLog_ERR(TAG, "rdpdr_add_init_handle_data failed with error %lu!", rc); - free(rdpdr); - return FALSE; - } - + s_TLSPluginContext = rdpdr; return TRUE; } diff --git a/channels/rdpsnd/client/rdpsnd_main.c b/channels/rdpsnd/client/rdpsnd_main.c index baf0c64..5baa05b 100755 --- a/channels/rdpsnd/client/rdpsnd_main.c +++ b/channels/rdpsnd/client/rdpsnd_main.c @@ -93,6 +93,8 @@ struct rdpsnd_plugin rdpContext* rdpcontext; }; +static WINPR_TLS rdpsndPlugin* s_TLSPluginContext = NULL; + /** * Function description * @@ -110,46 +112,43 @@ static void* rdpsnd_schedule_thread(void* arg) rdpsndPlugin* rdpsnd = (rdpsndPlugin*) arg; HANDLE events[2]; UINT error = CHANNEL_RC_OK; - DWORD status; - + DWORD status; events[0] = MessageQueue_Event(rdpsnd->MsgPipe->Out); events[1] = rdpsnd->stopEvent; while (1) { - status = WaitForMultipleObjects(2, events, FALSE, INFINITE); + status = WaitForMultipleObjects(2, events, FALSE, INFINITE); - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error); - break; - } - - status = WaitForSingleObject(rdpsnd->stopEvent, 0); - - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); - break; - } + if (status == WAIT_FAILED) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error); + break; + } - if (status == WAIT_OBJECT_0) - break; + status = WaitForSingleObject(rdpsnd->stopEvent, 0); + if (status == WAIT_FAILED) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); + break; + } - status = WaitForSingleObject(events[0], 0); + if (status == WAIT_OBJECT_0) + break; - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); - break; - } + status = WaitForSingleObject(events[0], 0); + if (status == WAIT_FAILED) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); + break; + } - if (!MessageQueue_Peek(rdpsnd->MsgPipe->Out, &message, TRUE)) + if (!MessageQueue_Peek(rdpsnd->MsgPipe->Out, &message, TRUE)) { WLog_ERR(TAG, "MessageQueue_Peek failed!"); error = ERROR_INTERNAL_ERROR; @@ -180,7 +179,8 @@ static void* rdpsnd_schedule_thread(void* arg) } if (error && rdpsnd->rdpcontext) - setChannelError(rdpsnd->rdpcontext, error, "rdpsnd_schedule_thread reported an error"); + setChannelError(rdpsnd->rdpcontext, error, + "rdpsnd_schedule_thread reported an error"); ExitThread((DWORD)error); return NULL; @@ -191,24 +191,23 @@ static void* rdpsnd_schedule_thread(void* arg) * * @return 0 on success, otherwise a Win32 error code */ -UINT rdpsnd_send_quality_mode_pdu(rdpsndPlugin* rdpsnd) +static UINT rdpsnd_send_quality_mode_pdu(rdpsndPlugin* rdpsnd) { wStream* pdu; - pdu = Stream_New(NULL, 8); + if (!pdu) { WLog_ERR(TAG, "Stream_New failed!"); return CHANNEL_RC_NO_MEMORY; } + Stream_Write_UINT8(pdu, SNDC_QUALITYMODE); /* msgType */ Stream_Write_UINT8(pdu, 0); /* bPad */ Stream_Write_UINT16(pdu, 4); /* BodySize */ Stream_Write_UINT16(pdu, rdpsnd->wQualityMode); /* wQualityMode */ Stream_Write_UINT16(pdu, 0); /* Reserved */ - WLog_Print(rdpsnd->log, WLOG_DEBUG, "QualityMode: %d", rdpsnd->wQualityMode); - return rdpsnd_virtual_channel_write(rdpsnd, pdu); } @@ -217,7 +216,6 @@ static void rdpsnd_select_supported_audio_formats(rdpsndPlugin* rdpsnd) int index; AUDIO_FORMAT* serverFormat; AUDIO_FORMAT* clientFormat; - rdpsnd_free_audio_formats(rdpsnd->ClientFormats, rdpsnd->NumberOfClientFormats); rdpsnd->NumberOfClientFormats = 0; rdpsnd->ClientFormats = NULL; @@ -225,24 +223,29 @@ static void rdpsnd_select_supported_audio_formats(rdpsndPlugin* rdpsnd) if (!rdpsnd->NumberOfServerFormats) return; - rdpsnd->ClientFormats = (AUDIO_FORMAT*) malloc(sizeof(AUDIO_FORMAT) * rdpsnd->NumberOfServerFormats); + rdpsnd->ClientFormats = (AUDIO_FORMAT*) malloc(sizeof(AUDIO_FORMAT) * + rdpsnd->NumberOfServerFormats); + for (index = 0; index < (int) rdpsnd->NumberOfServerFormats; index++) { serverFormat = &rdpsnd->ServerFormats[index]; - if (rdpsnd->fixedFormat > 0 && (rdpsnd->fixedFormat != serverFormat->wFormatTag)) + if (rdpsnd->fixedFormat > 0 + && (rdpsnd->fixedFormat != serverFormat->wFormatTag)) continue; - if (rdpsnd->fixedChannel > 0 && (rdpsnd->fixedChannel != serverFormat->nChannels)) + if (rdpsnd->fixedChannel > 0 + && (rdpsnd->fixedChannel != serverFormat->nChannels)) continue; - if (rdpsnd->fixedRate > 0 && (rdpsnd->fixedRate != serverFormat->nSamplesPerSec)) + if (rdpsnd->fixedRate > 0 + && (rdpsnd->fixedRate != serverFormat->nSamplesPerSec)) continue; - if (rdpsnd->device && rdpsnd->device->FormatSupported(rdpsnd->device, serverFormat)) + if (rdpsnd->device + && rdpsnd->device->FormatSupported(rdpsnd->device, serverFormat)) { clientFormat = &rdpsnd->ClientFormats[rdpsnd->NumberOfClientFormats++]; - CopyMemory(clientFormat, serverFormat, sizeof(AUDIO_FORMAT)); clientFormat->cbSize = 0; @@ -257,10 +260,12 @@ static void rdpsnd_select_supported_audio_formats(rdpsndPlugin* rdpsnd) #if 0 WLog_ERR(TAG, "Server "); - rdpsnd_print_audio_formats(rdpsnd->ServerFormats, rdpsnd->NumberOfServerFormats); + rdpsnd_print_audio_formats(rdpsnd->ServerFormats, + rdpsnd->NumberOfServerFormats); WLog_ERR(TAG, ""); WLog_ERR(TAG, "Client "); - rdpsnd_print_audio_formats(rdpsnd->ClientFormats, rdpsnd->NumberOfClientFormats); + rdpsnd_print_audio_formats(rdpsnd->ClientFormats, + rdpsnd->NumberOfClientFormats); WLog_ERR(TAG, ""); #endif } @@ -270,7 +275,7 @@ static void rdpsnd_select_supported_audio_formats(rdpsndPlugin* rdpsnd) * * @return 0 on success, otherwise a Win32 error code */ -UINT rdpsnd_send_client_audio_formats(rdpsndPlugin* rdpsnd) +static UINT rdpsnd_send_client_audio_formats(rdpsndPlugin* rdpsnd) { int index; wStream* pdu; @@ -280,7 +285,6 @@ UINT rdpsnd_send_client_audio_formats(rdpsndPlugin* rdpsnd) UINT16 dwVolumeRight; UINT16 wNumberOfFormats; AUDIO_FORMAT* clientFormat; - dwVolumeLeft = ((50 * 0xFFFF) / 100); /* 50% */ dwVolumeRight = ((50 * 0xFFFF) / 100); /* 50% */ dwVolume = (dwVolumeLeft << 16) | dwVolumeRight; @@ -292,13 +296,13 @@ UINT rdpsnd_send_client_audio_formats(rdpsndPlugin* rdpsnd) } wNumberOfFormats = rdpsnd->NumberOfClientFormats; - length = 4 + 20; for (index = 0; index < (int) wNumberOfFormats; index++) length += (18 + rdpsnd->ClientFormats[index].cbSize); pdu = Stream_New(NULL, length); + if (!pdu) { WLog_ERR(TAG, "Stream_New failed!"); @@ -308,7 +312,6 @@ UINT rdpsnd_send_client_audio_formats(rdpsndPlugin* rdpsnd) Stream_Write_UINT8(pdu, SNDC_FORMATS); /* msgType */ Stream_Write_UINT8(pdu, 0); /* bPad */ Stream_Write_UINT16(pdu, length - 4); /* BodySize */ - Stream_Write_UINT32(pdu, TSSNDCAPS_ALIVE | TSSNDCAPS_VOLUME); /* dwFlags */ Stream_Write_UINT32(pdu, dwVolume); /* dwVolume */ Stream_Write_UINT32(pdu, 0); /* dwPitch */ @@ -321,7 +324,6 @@ UINT rdpsnd_send_client_audio_formats(rdpsndPlugin* rdpsnd) for (index = 0; index < (int) wNumberOfFormats; index++) { clientFormat = &rdpsnd->ClientFormats[index]; - Stream_Write_UINT16(pdu, clientFormat->wFormatTag); Stream_Write_UINT16(pdu, clientFormat->nChannels); Stream_Write_UINT32(pdu, clientFormat->nSamplesPerSec); @@ -335,7 +337,6 @@ UINT rdpsnd_send_client_audio_formats(rdpsndPlugin* rdpsnd) } WLog_Print(rdpsnd->log, WLOG_DEBUG, "Client Audio Formats"); - return rdpsnd_virtual_channel_write(rdpsnd, pdu); } @@ -344,14 +345,14 @@ UINT rdpsnd_send_client_audio_formats(rdpsndPlugin* rdpsnd) * * @return 0 on success, otherwise a Win32 error code */ -UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, wStream* s) +static UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, + wStream* s) { int index; UINT16 wVersion; AUDIO_FORMAT* format; UINT16 wNumberOfFormats; UINT ret = ERROR_BAD_LENGTH; - rdpsnd_free_audio_formats(rdpsnd->ServerFormats, rdpsnd->NumberOfServerFormats); rdpsnd->NumberOfServerFormats = 0; rdpsnd->ServerFormats = NULL; @@ -368,12 +369,14 @@ UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, wStream* s) Stream_Read_UINT8(s, rdpsnd->cBlockNo); /* cLastBlockConfirmed */ Stream_Read_UINT16(s, wVersion); /* wVersion */ Stream_Seek_UINT8(s); /* bPad */ - rdpsnd->NumberOfServerFormats = wNumberOfFormats; + if (Stream_GetRemainingLength(s) / 14 < wNumberOfFormats) return ERROR_BAD_LENGTH; - rdpsnd->ServerFormats = (AUDIO_FORMAT*) calloc(wNumberOfFormats, sizeof(AUDIO_FORMAT)); + rdpsnd->ServerFormats = (AUDIO_FORMAT*) calloc(wNumberOfFormats, + sizeof(AUDIO_FORMAT)); + if (!rdpsnd->ServerFormats) return CHANNEL_RC_NO_MEMORY; @@ -383,6 +386,7 @@ UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, wStream* s) if (Stream_GetRemainingLength(s) < 14) goto out_fail; + Stream_Read_UINT16(s, format->wFormatTag); /* wFormatTag */ Stream_Read_UINT16(s, format->nChannels); /* nChannels */ Stream_Read_UINT32(s, format->nSamplesPerSec); /* nSamplesPerSec */ @@ -397,20 +401,21 @@ UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, wStream* s) goto out_fail; format->data = (BYTE*) malloc(format->cbSize); + if (!format->data) { ret = CHANNEL_RC_NO_MEMORY; goto out_fail; } + Stream_Read(s, format->data, format->cbSize); } } rdpsnd_select_supported_audio_formats(rdpsnd); - WLog_Print(rdpsnd->log, WLOG_DEBUG, "Server Audio Formats"); - ret = rdpsnd_send_client_audio_formats(rdpsnd); + if (ret == CHANNEL_RC_OK) { if (wVersion >= 6) @@ -418,8 +423,8 @@ UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, wStream* s) } return ret; - out_fail: + for (index = 0; index < (int) wNumberOfFormats; index++) free(format->data); @@ -433,11 +438,12 @@ out_fail: * * @return 0 on success, otherwise a Win32 error code */ -UINT rdpsnd_send_training_confirm_pdu(rdpsndPlugin* rdpsnd, UINT16 wTimeStamp, UINT16 wPackSize) +static UINT rdpsnd_send_training_confirm_pdu(rdpsndPlugin* rdpsnd, + UINT16 wTimeStamp, UINT16 wPackSize) { wStream* pdu; - pdu = Stream_New(NULL, 8); + if (!pdu) { WLog_ERR(TAG, "Stream_New failed!"); @@ -449,10 +455,9 @@ UINT rdpsnd_send_training_confirm_pdu(rdpsndPlugin* rdpsnd, UINT16 wTimeStamp, U Stream_Write_UINT16(pdu, 4); /* BodySize */ Stream_Write_UINT16(pdu, wTimeStamp); Stream_Write_UINT16(pdu, wPackSize); - - WLog_Print(rdpsnd->log, WLOG_DEBUG, "Training Response: wTimeStamp: %d wPackSize: %d", - wTimeStamp, wPackSize); - + WLog_Print(rdpsnd->log, WLOG_DEBUG, + "Training Response: wTimeStamp: %d wPackSize: %d", + wTimeStamp, wPackSize); return rdpsnd_virtual_channel_write(rdpsnd, pdu); } @@ -471,10 +476,9 @@ static UINT rdpsnd_recv_training_pdu(rdpsndPlugin* rdpsnd, wStream* s) Stream_Read_UINT16(s, wTimeStamp); Stream_Read_UINT16(s, wPackSize); - - WLog_Print(rdpsnd->log, WLOG_DEBUG, "Training Request: wTimeStamp: %d wPackSize: %d", - wTimeStamp, wPackSize); - + WLog_Print(rdpsnd->log, WLOG_DEBUG, + "Training Request: wTimeStamp: %d wPackSize: %d", + wTimeStamp, wPackSize); return rdpsnd_send_training_confirm_pdu(rdpsnd, wTimeStamp, wPackSize); } @@ -483,11 +487,11 @@ static UINT rdpsnd_recv_training_pdu(rdpsndPlugin* rdpsnd, wStream* s) * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpsnd_recv_wave_info_pdu(rdpsndPlugin* rdpsnd, wStream* s, UINT16 BodySize) +static UINT rdpsnd_recv_wave_info_pdu(rdpsndPlugin* rdpsnd, wStream* s, + UINT16 BodySize) { UINT16 wFormatNo; AUDIO_FORMAT* format; - rdpsnd->expectingWave = TRUE; if (Stream_GetRemainingLength(s) < 12) @@ -498,13 +502,10 @@ static UINT rdpsnd_recv_wave_info_pdu(rdpsndPlugin* rdpsnd, wStream* s, UINT16 B Stream_Read_UINT8(s, rdpsnd->cBlockNo); Stream_Seek(s, 3); /* bPad */ Stream_Read(s, rdpsnd->waveData, 4); - rdpsnd->waveDataSize = BodySize - 8; - format = &rdpsnd->ClientFormats[wFormatNo]; - WLog_Print(rdpsnd->log, WLOG_DEBUG, "WaveInfo: cBlockNo: %d wFormatNo: %d", - rdpsnd->cBlockNo, wFormatNo); + rdpsnd->cBlockNo, wFormatNo); if (!rdpsnd->isOpen) { @@ -514,9 +515,9 @@ static UINT rdpsnd_recv_wave_info_pdu(rdpsndPlugin* rdpsnd, wStream* s, UINT16 B //rdpsnd_print_audio_format(format); if (rdpsnd->device && rdpsnd->device->Open && - !rdpsnd->device->Open(rdpsnd->device, format, rdpsnd->latency)) + !rdpsnd->device->Open(rdpsnd->device, format, rdpsnd->latency)) { - return CHANNEL_RC_INITIALIZATION_ERROR; + return CHANNEL_RC_INITIALIZATION_ERROR; } } else if (wFormatNo != rdpsnd->wCurrentFormatNo) @@ -525,8 +526,9 @@ static UINT rdpsnd_recv_wave_info_pdu(rdpsndPlugin* rdpsnd, wStream* s, UINT16 B if (rdpsnd->device) { - if(rdpsnd->device->SetFormat && !rdpsnd->device->SetFormat(rdpsnd->device, format, rdpsnd->latency)) - return CHANNEL_RC_INITIALIZATION_ERROR; + if (rdpsnd->device->SetFormat + && !rdpsnd->device->SetFormat(rdpsnd->device, format, rdpsnd->latency)) + return CHANNEL_RC_INITIALIZATION_ERROR; } } @@ -538,11 +540,12 @@ static UINT rdpsnd_recv_wave_info_pdu(rdpsndPlugin* rdpsnd, wStream* s, UINT16 B * * @return 0 on success, otherwise a Win32 error code */ -UINT rdpsnd_send_wave_confirm_pdu(rdpsndPlugin* rdpsnd, UINT16 wTimeStamp, BYTE cConfirmedBlockNo) +static UINT rdpsnd_send_wave_confirm_pdu(rdpsndPlugin* rdpsnd, + UINT16 wTimeStamp, BYTE cConfirmedBlockNo) { wStream* pdu; - pdu = Stream_New(NULL, 8); + if (!pdu) { WLog_ERR(TAG, "Stream_New failed!"); @@ -555,7 +558,6 @@ UINT rdpsnd_send_wave_confirm_pdu(rdpsndPlugin* rdpsnd, UINT16 wTimeStamp, BYTE Stream_Write_UINT16(pdu, wTimeStamp); Stream_Write_UINT8(pdu, cConfirmedBlockNo); /* cConfirmedBlockNo */ Stream_Write_UINT8(pdu, 0); /* bPad */ - return rdpsnd_virtual_channel_write(rdpsnd, pdu); } @@ -564,11 +566,11 @@ UINT rdpsnd_send_wave_confirm_pdu(rdpsndPlugin* rdpsnd, UINT16 wTimeStamp, BYTE * * @return 0 on success, otherwise a Win32 error code */ -UINT rdpsnd_confirm_wave(rdpsndPlugin* rdpsnd, RDPSND_WAVE* wave) +static UINT rdpsnd_confirm_wave(rdpsndPlugin* rdpsnd, RDPSND_WAVE* wave) { - WLog_Print(rdpsnd->log, WLOG_DEBUG, "WaveConfirm: cBlockNo: %d wTimeStamp: %d wTimeDiff: %d", - wave->cBlockNo, wave->wTimeStampB, wave->wTimeStampB - wave->wTimeStampA); - + WLog_Print(rdpsnd->log, WLOG_DEBUG, + "WaveConfirm: cBlockNo: %d wTimeStamp: %d wTimeDiff: %d", + wave->cBlockNo, wave->wTimeStampB, wave->wTimeStampB - wave->wTimeStampA); return rdpsnd_send_wave_confirm_pdu(rdpsnd, wave->wTimeStampB, wave->cBlockNo); } @@ -577,19 +579,20 @@ UINT rdpsnd_confirm_wave(rdpsndPlugin* rdpsnd, RDPSND_WAVE* wave) * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpsnd_device_send_wave_confirm_pdu(rdpsndDevicePlugin* device, RDPSND_WAVE* wave) +static UINT rdpsnd_device_send_wave_confirm_pdu(rdpsndDevicePlugin* device, + RDPSND_WAVE* wave) { if (device->DisableConfirmThread) return rdpsnd_confirm_wave(device->rdpsnd, wave); - if (!MessageQueue_Post(device->rdpsnd->MsgPipe->Out, NULL, 0, (void*) wave, NULL)) + if (!MessageQueue_Post(device->rdpsnd->MsgPipe->Out, NULL, 0, (void*) wave, + NULL)) { WLog_ERR(TAG, "MessageQueue_Post failed!"); return ERROR_INTERNAL_ERROR; } return CHANNEL_RC_OK; - } /** @@ -604,22 +607,18 @@ static UINT rdpsnd_recv_wave_pdu(rdpsndPlugin* rdpsnd, wStream* s) RDPSND_WAVE* wave; AUDIO_FORMAT* format; UINT status; - rdpsnd->expectingWave = FALSE; - /** * The Wave PDU is a special case: it is always sent after a Wave Info PDU, * and we do not process its header. Instead, the header is pad that needs * to be filled with the first four bytes of the audio sample data sent as * part of the preceding Wave Info PDU. */ - CopyMemory(Stream_Buffer(s), rdpsnd->waveData, 4); - data = Stream_Buffer(s); size = (int) Stream_Capacity(s); - wave = (RDPSND_WAVE*) calloc(1, sizeof(RDPSND_WAVE)); + if (!wave) { WLog_ERR(TAG, "calloc failed!"); @@ -630,16 +629,13 @@ static UINT rdpsnd_recv_wave_pdu(rdpsndPlugin* rdpsnd, wStream* s) wave->wTimeStampA = rdpsnd->wTimeStamp; wave->wFormatNo = rdpsnd->wCurrentFormatNo; wave->cBlockNo = rdpsnd->cBlockNo; - wave->data = data; wave->length = size; wave->AutoConfirm = TRUE; - format = &rdpsnd->ClientFormats[rdpsnd->wCurrentFormatNo]; wave->wAudioLength = rdpsnd_compute_audio_time_length(format, size); - WLog_Print(rdpsnd->log, WLOG_DEBUG, "Wave: cBlockNo: %d wTimeStamp: %d", - wave->cBlockNo, wave->wTimeStampA); + wave->cBlockNo, wave->wTimeStampA); if (!rdpsnd->device) { @@ -650,7 +646,8 @@ static UINT rdpsnd_recv_wave_pdu(rdpsndPlugin* rdpsnd, wStream* s) return status; } - if (rdpsnd->device->WaveDecode && !rdpsnd->device->WaveDecode(rdpsnd->device, wave)) + if (rdpsnd->device->WaveDecode + && !rdpsnd->device->WaveDecode(rdpsnd->device, wave)) { free(wave); return CHANNEL_RC_NO_MEMORY; @@ -672,8 +669,10 @@ static UINT rdpsnd_recv_wave_pdu(rdpsndPlugin* rdpsnd, wStream* s) } status = CHANNEL_RC_OK; + if (wave->AutoConfirm) status = rdpsnd->device->WaveConfirm(rdpsnd->device, wave); + return status; } @@ -702,15 +701,15 @@ static UINT rdpsnd_recv_volume_pdu(rdpsndPlugin* rdpsnd, wStream* s) return ERROR_BAD_LENGTH; Stream_Read_UINT32(s, dwVolume); - WLog_Print(rdpsnd->log, WLOG_DEBUG, "Volume: 0x%04X", dwVolume); if (rdpsnd->device && rdpsnd->device->SetVolume && - !rdpsnd->device->SetVolume(rdpsnd->device, dwVolume)) + !rdpsnd->device->SetVolume(rdpsnd->device, dwVolume)) { WLog_ERR(TAG, "error setting volume"); return CHANNEL_RC_INITIALIZATION_ERROR; } + return CHANNEL_RC_OK; } @@ -775,7 +774,8 @@ out: return status; } -static void rdpsnd_register_device_plugin(rdpsndPlugin* rdpsnd, rdpsndDevicePlugin* device) +static void rdpsnd_register_device_plugin(rdpsndPlugin* rdpsnd, + rdpsndDevicePlugin* device) { if (rdpsnd->device) { @@ -785,7 +785,6 @@ static void rdpsnd_register_device_plugin(rdpsndPlugin* rdpsnd, rdpsndDevicePlug rdpsnd->device = device; device->rdpsnd = rdpsnd; - device->WaveConfirm = rdpsnd_device_send_wave_confirm_pdu; } @@ -794,13 +793,15 @@ static void rdpsnd_register_device_plugin(rdpsndPlugin* rdpsnd, rdpsndDevicePlug * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpsnd_load_device_plugin(rdpsndPlugin* rdpsnd, const char* name, ADDIN_ARGV* args) +static UINT rdpsnd_load_device_plugin(rdpsndPlugin* rdpsnd, const char* name, + ADDIN_ARGV* args) { PFREERDP_RDPSND_DEVICE_ENTRY entry; - FREERDP_RDPSND_DEVICE_ENTRY_POINTS entryPoints;\ + FREERDP_RDPSND_DEVICE_ENTRY_POINTS entryPoints; + \ UINT error; - - entry = (PFREERDP_RDPSND_DEVICE_ENTRY) freerdp_load_channel_addin_entry("rdpsnd", (LPSTR) name, NULL, 0); + entry = (PFREERDP_RDPSND_DEVICE_ENTRY) + freerdp_load_channel_addin_entry("rdpsnd", (LPSTR) name, NULL, 0); if (!entry) return ERROR_INTERNAL_ERROR; @@ -816,7 +817,7 @@ static UINT rdpsnd_load_device_plugin(rdpsndPlugin* rdpsnd, const char* name, AD return error; } -BOOL rdpsnd_set_subsystem(rdpsndPlugin* rdpsnd, const char* subsystem) +static BOOL rdpsnd_set_subsystem(rdpsndPlugin* rdpsnd, const char* subsystem) { free(rdpsnd->subsystem); rdpsnd->subsystem = _strdup(subsystem); @@ -852,15 +853,13 @@ static UINT rdpsnd_process_addin_args(rdpsndPlugin* rdpsnd, ADDIN_ARGV* args) int status; DWORD flags; COMMAND_LINE_ARGUMENT_A* arg; - rdpsnd->wQualityMode = HIGH_QUALITY; /* default quality mode */ - if (args->argc > 1) { flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON; - status = CommandLineParseArgumentsA(args->argc, (const char **) args->argv, - rdpsnd_args, flags, rdpsnd, NULL, NULL); + status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv, + rdpsnd_args, flags, rdpsnd, NULL, NULL); if (status < 0) return CHANNEL_RC_INITIALIZATION_ERROR; @@ -873,7 +872,6 @@ static UINT rdpsnd_process_addin_args(rdpsndPlugin* rdpsnd, ADDIN_ARGV* args) continue; CommandLineSwitchStart(arg) - CommandLineSwitchCase(arg, "sys") { if (!rdpsnd_set_subsystem(rdpsnd, arg->Value)) @@ -920,9 +918,7 @@ static UINT rdpsnd_process_addin_args(rdpsndPlugin* rdpsnd, ADDIN_ARGV* args) } CommandLineSwitchDefault(arg) { - } - CommandLineSwitchEnd(arg) } while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); @@ -940,14 +936,14 @@ static UINT rdpsnd_process_connect(rdpsndPlugin* rdpsnd) { ADDIN_ARGV* args; UINT status = ERROR_INTERNAL_ERROR; - char *subsystem_name = NULL, *device_name = NULL; - + char* subsystem_name = NULL, *device_name = NULL; rdpsnd->latency = -1; - args = (ADDIN_ARGV*) rdpsnd->channelEntryPoints.pExtendedData; + if (args) { status = rdpsnd_process_addin_args(rdpsnd, args); + if (status != CHANNEL_RC_OK) return status; } @@ -959,88 +955,112 @@ static UINT rdpsnd_process_connect(rdpsndPlugin* rdpsnd) if ((status = rdpsnd_load_device_plugin(rdpsnd, rdpsnd->subsystem, args))) { - WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %lu", rdpsnd->subsystem, status); + WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %lu", + rdpsnd->subsystem, status); return status; } } else { #if defined(WITH_IOSAUDIO) + if (!rdpsnd->device) { subsystem_name = "ios"; device_name = ""; + if ((status = rdpsnd_load_device_plugin(rdpsnd, subsystem_name, args))) - WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %lu", subsystem_name, status); + WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %lu", + subsystem_name, status); } -#endif +#endif #if defined(WITH_OPENSLES) + if (!rdpsnd->device) { subsystem_name = "opensles"; device_name = ""; + if ((status = rdpsnd_load_device_plugin(rdpsnd, subsystem_name, args))) - WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %lu", subsystem_name, status); + WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %lu", + subsystem_name, status); } -#endif +#endif #if defined(WITH_PULSE) + if (!rdpsnd->device) { subsystem_name = "pulse"; device_name = ""; + if ((status = rdpsnd_load_device_plugin(rdpsnd, subsystem_name, args))) - WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %lu", subsystem_name, status); + WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %lu", + subsystem_name, status); } -#endif +#endif #if defined(WITH_ALSA) + if (!rdpsnd->device) { subsystem_name = "alsa"; device_name = "default"; + if ((status = rdpsnd_load_device_plugin(rdpsnd, subsystem_name, args))) - WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %lu", subsystem_name, status); + WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %lu", + subsystem_name, status); } -#endif +#endif #if defined(WITH_OSS) + if (!rdpsnd->device) { subsystem_name = "oss"; device_name = ""; + if ((status = rdpsnd_load_device_plugin(rdpsnd, subsystem_name, args))) - WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %lu", subsystem_name, status); + WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %lu", + subsystem_name, status); } -#endif - +#endif #if defined(WITH_MACAUDIO) + if (!rdpsnd->device) { subsystem_name = "mac"; device_name = "default"; + if ((status = rdpsnd_load_device_plugin(rdpsnd, subsystem_name, args))) - WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %lu", subsystem_name, status); + WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %lu", + subsystem_name, status); } -#endif +#endif #if defined(WITH_WINMM) + if (!rdpsnd->device) { subsystem_name = "winmm"; device_name = ""; + if ((status = rdpsnd_load_device_plugin(rdpsnd, subsystem_name, args))) - WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %lu", subsystem_name, status); + WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %lu", + subsystem_name, status); } + #endif + if (status) return status; if (rdpsnd->device) { - if (!rdpsnd_set_subsystem(rdpsnd, subsystem_name) || !rdpsnd_set_device_name(rdpsnd, device_name)) + if (!rdpsnd_set_subsystem(rdpsnd, subsystem_name) + || !rdpsnd_set_device_name(rdpsnd, device_name)) return CHANNEL_RC_NO_MEMORY; } } @@ -1051,10 +1071,10 @@ static UINT rdpsnd_process_connect(rdpsndPlugin* rdpsnd) return CHANNEL_RC_INITIALIZATION_ERROR; } - if (!rdpsnd->device->DisableConfirmThread) { rdpsnd->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!rdpsnd->stopEvent) { WLog_ERR(TAG, "CreateEvent failed!"); @@ -1062,8 +1082,9 @@ static UINT rdpsnd_process_connect(rdpsndPlugin* rdpsnd) } rdpsnd->ScheduleThread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) rdpsnd_schedule_thread, - (void*) rdpsnd, 0, NULL); + (LPTHREAD_START_ROUTINE) rdpsnd_schedule_thread, + (void*) rdpsnd, 0, NULL); + if (!rdpsnd->ScheduleThread) { WLog_ERR(TAG, "CreateThread failed!"); @@ -1079,84 +1100,18 @@ static void rdpsnd_process_disconnect(rdpsndPlugin* rdpsnd) if (rdpsnd->ScheduleThread) { SetEvent(rdpsnd->stopEvent); + if (WaitForSingleObject(rdpsnd->ScheduleThread, INFINITE) == WAIT_FAILED) - { - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", GetLastError()); - return; - } + { + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", GetLastError()); + return; + } + CloseHandle(rdpsnd->ScheduleThread); CloseHandle(rdpsnd->stopEvent); } } -/****************************************************************************************/ - - -static wListDictionary* g_InitHandles = NULL; -static wListDictionary* g_OpenHandles = NULL; - -BOOL rdpsnd_add_init_handle_data(void* pInitHandle, void* pUserData) -{ - if (!g_InitHandles) - { - g_InitHandles = ListDictionary_New(TRUE); - if (!g_InitHandles) - return FALSE; - } - - return ListDictionary_Add(g_InitHandles, pInitHandle, pUserData); -} - -void* rdpsnd_get_init_handle_data(void* pInitHandle) -{ - void* pUserData = NULL; - pUserData = ListDictionary_GetItemValue(g_InitHandles, pInitHandle); - return pUserData; -} - -void rdpsnd_remove_init_handle_data(void* pInitHandle) -{ - ListDictionary_Remove(g_InitHandles, pInitHandle); - if (ListDictionary_Count(g_InitHandles) < 1) - { - ListDictionary_Free(g_InitHandles); - g_InitHandles = NULL; - } -} - -BOOL rdpsnd_add_open_handle_data(DWORD openHandle, void* pUserData) -{ - void* pOpenHandle = (void*) (size_t) openHandle; - - if (!g_OpenHandles) - { - g_OpenHandles = ListDictionary_New(TRUE); - if (!g_OpenHandles) - return FALSE; - } - - return ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData); -} - -void* rdpsnd_get_open_handle_data(DWORD openHandle) -{ - void* pUserData = NULL; - void* pOpenHandle = (void*) (size_t) openHandle; - pUserData = ListDictionary_GetItemValue(g_OpenHandles, pOpenHandle); - return pUserData; -} - -void rdpsnd_remove_open_handle_data(DWORD openHandle) -{ - void* pOpenHandle = (void*) (size_t) openHandle; - ListDictionary_Remove(g_OpenHandles, pOpenHandle); - if (ListDictionary_Count(g_OpenHandles) < 1) - { - ListDictionary_Free(g_OpenHandles); - g_OpenHandles = NULL; - } -} - /** * Function description * @@ -1173,14 +1128,14 @@ UINT rdpsnd_virtual_channel_write(rdpsndPlugin* rdpsnd, wStream* s) else { status = rdpsnd->channelEntryPoints.pVirtualChannelWrite(rdpsnd->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; @@ -1192,7 +1147,7 @@ UINT rdpsnd_virtual_channel_write(rdpsndPlugin* rdpsnd, wStream* s) * @return 0 on success, otherwise a Win32 error code */ static UINT rdpsnd_virtual_channel_event_data_received(rdpsndPlugin* plugin, - void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) + void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { wStream* s; @@ -1207,6 +1162,7 @@ static UINT rdpsnd_virtual_channel_event_data_received(rdpsndPlugin* plugin, Stream_Free(plugin->data_in, TRUE); plugin->data_in = Stream_New(NULL, totalLength); + if (!plugin->data_in) { WLog_ERR(TAG, "Stream_New failed!"); @@ -1242,18 +1198,18 @@ static UINT rdpsnd_virtual_channel_event_data_received(rdpsndPlugin* plugin, return ERROR_INTERNAL_ERROR; } } + return CHANNEL_RC_OK; } -static VOID VCAPITYPE rdpsnd_virtual_channel_open_event(DWORD openHandle, UINT event, - LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) +static VOID VCAPITYPE rdpsnd_virtual_channel_open_event(DWORD openHandle, + UINT event, + LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { - rdpsndPlugin* rdpsnd; + rdpsndPlugin* rdpsnd = s_TLSPluginContext; UINT error = CHANNEL_RC_OK; - rdpsnd = (rdpsndPlugin*) rdpsnd_get_open_handle_data(openHandle); - - if (!rdpsnd) + if (!rdpsnd || (rdpsnd->OpenHandle != openHandle)) { WLog_ERR(TAG, "rdpsnd_virtual_channel_open_event: error no match"); return; @@ -1262,8 +1218,11 @@ static VOID VCAPITYPE rdpsnd_virtual_channel_open_event(DWORD openHandle, UINT e switch (event) { case CHANNEL_EVENT_DATA_RECEIVED: - if ((error = rdpsnd_virtual_channel_event_data_received(rdpsnd, pData, dataLength, totalLength, dataFlags))) - WLog_ERR(TAG, "rdpsnd_virtual_channel_event_data_received failed with error %lu", error); + if ((error = rdpsnd_virtual_channel_event_data_received(rdpsnd, pData, + dataLength, totalLength, dataFlags))) + WLog_ERR(TAG, + "rdpsnd_virtual_channel_event_data_received failed with error %lu", error); + break; case CHANNEL_EVENT_WRITE_COMPLETE: @@ -1273,9 +1232,10 @@ static VOID VCAPITYPE rdpsnd_virtual_channel_open_event(DWORD openHandle, UINT e case CHANNEL_EVENT_USER: break; } - if (error && rdpsnd->rdpcontext) - setChannelError(rdpsnd->rdpcontext, error, "rdpsnd_virtual_channel_open_event reported an error"); + if (error && rdpsnd->rdpcontext) + setChannelError(rdpsnd->rdpcontext, error, + "rdpsnd_virtual_channel_open_event reported an error"); } static void* rdpsnd_virtual_channel_client_thread(void* arg) @@ -1313,6 +1273,7 @@ static void* rdpsnd_virtual_channel_client_thread(void* arg) if (message.id == 0) { data = (wStream*) message.wParam; + if ((error = rdpsnd_recv_pdu(rdpsnd, data))) { WLog_ERR(TAG, "error treating sound channel message"); @@ -1322,11 +1283,12 @@ static void* rdpsnd_virtual_channel_client_thread(void* arg) } out: + if (error && rdpsnd->rdpcontext) - setChannelError(rdpsnd->rdpcontext, error, "rdpsnd_virtual_channel_client_thread reported an error"); + setChannelError(rdpsnd->rdpcontext, error, + "rdpsnd_virtual_channel_client_thread reported an error"); rdpsnd_process_disconnect(rdpsnd); - ExitThread((DWORD)error); return NULL; } @@ -1336,27 +1298,23 @@ out: * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpsnd_virtual_channel_event_connected(rdpsndPlugin* plugin, LPVOID pData, UINT32 dataLength) +static UINT rdpsnd_virtual_channel_event_connected(rdpsndPlugin* plugin, + LPVOID pData, UINT32 dataLength) { UINT32 status; - status = plugin->channelEntryPoints.pVirtualChannelOpen(plugin->InitHandle, - &plugin->OpenHandle, plugin->channelDef.name, rdpsnd_virtual_channel_open_event); + &plugin->OpenHandle, plugin->channelDef.name, + rdpsnd_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; } - if (!rdpsnd_add_open_handle_data(plugin->OpenHandle, plugin)) - { - WLog_ERR(TAG, "unable to register opened handle"); - return ERROR_INTERNAL_ERROR; - } - plugin->MsgPipe = MessagePipe_New(); + if (!plugin->MsgPipe) { WLog_ERR(TAG, "unable to create message pipe"); @@ -1364,7 +1322,9 @@ static UINT rdpsnd_virtual_channel_event_connected(rdpsndPlugin* plugin, LPVOID } plugin->thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) rdpsnd_virtual_channel_client_thread, (void*) plugin, 0, NULL); + (LPTHREAD_START_ROUTINE) rdpsnd_virtual_channel_client_thread, (void*) plugin, + 0, NULL); + if (!plugin->thread) { WLog_ERR(TAG, "unable to create thread"); @@ -1384,26 +1344,28 @@ static UINT rdpsnd_virtual_channel_event_connected(rdpsndPlugin* plugin, LPVOID static UINT rdpsnd_virtual_channel_event_disconnected(rdpsndPlugin* rdpsnd) { UINT error; - MessagePipe_PostQuit(rdpsnd->MsgPipe, 0); + if (WaitForSingleObject(rdpsnd->thread, INFINITE) == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); - return error; - } + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); + return error; + } CloseHandle(rdpsnd->thread); rdpsnd->thread = NULL; - error = rdpsnd->channelEntryPoints.pVirtualChannelClose(rdpsnd->OpenHandle); + if (CHANNEL_RC_OK != error) { WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08X]", - WTSErrorToString(error), error); + WTSErrorToString(error), error); return error; } + rdpsnd->OpenHandle = 0; + if (rdpsnd->data_in) { Stream_Free(rdpsnd->data_in, TRUE); @@ -1412,11 +1374,9 @@ static UINT rdpsnd_virtual_channel_event_disconnected(rdpsndPlugin* rdpsnd) MessagePipe_Free(rdpsnd->MsgPipe); rdpsnd->MsgPipe = NULL; - rdpsnd_free_audio_formats(rdpsnd->ClientFormats, rdpsnd->NumberOfClientFormats); rdpsnd->NumberOfClientFormats = 0; rdpsnd->ClientFormats = NULL; - rdpsnd_free_audio_formats(rdpsnd->ServerFormats, rdpsnd->NumberOfServerFormats); rdpsnd->NumberOfServerFormats = 0; rdpsnd->ServerFormats = NULL; @@ -1439,26 +1399,22 @@ static UINT rdpsnd_virtual_channel_event_disconnected(rdpsndPlugin* rdpsnd) rdpsnd->device_name = NULL; } - rdpsnd_remove_open_handle_data(rdpsnd->OpenHandle); - return CHANNEL_RC_OK; } static void rdpsnd_virtual_channel_event_terminated(rdpsndPlugin* rdpsnd) { - rdpsnd_remove_init_handle_data(rdpsnd->InitHandle); - + rdpsnd->InitHandle = 0; free(rdpsnd); } -static VOID VCAPITYPE rdpsnd_virtual_channel_init_event(LPVOID pInitHandle, UINT event, LPVOID pData, UINT dataLength) +static VOID VCAPITYPE rdpsnd_virtual_channel_init_event(LPVOID pInitHandle, + UINT event, LPVOID pData, UINT dataLength) { - rdpsndPlugin* plugin; + rdpsndPlugin* plugin = s_TLSPluginContext; UINT error = CHANNEL_RC_OK; - plugin = (rdpsndPlugin*) rdpsnd_get_init_handle_data(pInitHandle); - - if (!plugin) + if (!plugin || (plugin->InitHandle != pInitHandle)) { WLog_ERR(TAG, "rdpsnd_virtual_channel_init_event: error no match"); return; @@ -1468,12 +1424,16 @@ static VOID VCAPITYPE rdpsnd_virtual_channel_init_event(LPVOID pInitHandle, UINT { case CHANNEL_EVENT_CONNECTED: if ((error = rdpsnd_virtual_channel_event_connected(plugin, pData, dataLength))) - WLog_ERR(TAG, "rdpsnd_virtual_channel_event_connected failed with error %lu!", error); + WLog_ERR(TAG, "rdpsnd_virtual_channel_event_connected failed with error %lu!", + error); + break; case CHANNEL_EVENT_DISCONNECTED: if ((error = rdpsnd_virtual_channel_event_disconnected(plugin))) - WLog_ERR(TAG, "rdpsnd_virtual_channel_event_disconnected failed with error %lu!", error); + WLog_ERR(TAG, + "rdpsnd_virtual_channel_event_disconnected failed with error %lu!", error); + break; case CHANNEL_EVENT_TERMINATED: @@ -1483,8 +1443,10 @@ static VOID VCAPITYPE rdpsnd_virtual_channel_init_event(LPVOID pInitHandle, UINT rdpsnd_virtual_channel_event_terminated(plugin); break; } + if (error && plugin->rdpcontext) - setChannelError(plugin->rdpcontext, error, "rdpsnd_virtual_channel_init_event reported an error"); + setChannelError(plugin->rdpcontext, error, + "rdpsnd_virtual_channel_init_event reported an error"); } /* rdpsnd is always built-in */ @@ -1493,12 +1455,10 @@ static VOID VCAPITYPE rdpsnd_virtual_channel_init_event(LPVOID pInitHandle, UINT BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) { UINT rc; - rdpsndPlugin* rdpsnd; CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx; - - rdpsnd = (rdpsndPlugin*) calloc(1, sizeof(rdpsndPlugin)); + if (!rdpsnd) { WLog_ERR(TAG, "calloc failed!"); @@ -1513,34 +1473,33 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) pthread_sigmask(SIG_BLOCK, &mask, NULL); } #endif - rdpsnd->channelDef.options = - CHANNEL_OPTION_INITIALIZED | - CHANNEL_OPTION_ENCRYPT_RDP; - + CHANNEL_OPTION_INITIALIZED | + CHANNEL_OPTION_ENCRYPT_RDP; strcpy(rdpsnd->channelDef.name, "rdpsnd"); - 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)) { rdpsnd->rdpcontext = pEntryPointsEx->context; } - CopyMemory(&(rdpsnd->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); - + CopyMemory(&(rdpsnd->channelEntryPoints), pEntryPoints, + sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); rdpsnd->log = WLog_Get("com.freerdp.channels.rdpsnd.client"); - rc = rdpsnd->channelEntryPoints.pVirtualChannelInit(&rdpsnd->InitHandle, - &rdpsnd->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, rdpsnd_virtual_channel_init_event); + &rdpsnd->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, + rdpsnd_virtual_channel_init_event); + if (CHANNEL_RC_OK != rc) { WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]", - WTSErrorToString(rc), rc); + WTSErrorToString(rc), rc); free(rdpsnd); return FALSE; } - return rdpsnd_add_init_handle_data(rdpsnd->InitHandle, (void*) rdpsnd); + s_TLSPluginContext = rdpsnd; + return TRUE; } diff --git a/channels/remdesk/client/remdesk_main.c b/channels/remdesk/client/remdesk_main.c index 7e34d59..ea4dd2f 100644 --- a/channels/remdesk/client/remdesk_main.c +++ b/channels/remdesk/client/remdesk_main.c @@ -33,7 +33,10 @@ #include "remdesk_main.h" -RemdeskClientContext* remdesk_get_client_interface(remdeskPlugin* remdesk) +static WINPR_TLS remdeskPlugin* s_TLSPluginContext = NULL; + +static RemdeskClientContext* remdesk_get_client_interface( + remdeskPlugin* remdesk) { RemdeskClientContext* pInterface; pInterface = (RemdeskClientContext*) remdesk->channelEntryPoints.pInterface; @@ -56,11 +59,11 @@ static UINT remdesk_virtual_channel_write(remdeskPlugin* remdesk, wStream* s) } status = remdesk->channelEntryPoints.pVirtualChannelWrite(remdesk->OpenHandle, - Stream_Buffer(s), (UINT32) Stream_Length(s), s); + Stream_Buffer(s), (UINT32) Stream_Length(s), s); if (status != CHANNEL_RC_OK) WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", - WTSErrorToString(status), status); + WTSErrorToString(status), status); return status; } @@ -70,7 +73,7 @@ static UINT remdesk_virtual_channel_write(remdeskPlugin* remdesk, wStream* s) * * @return 0 on success, otherwise a Win32 error code */ -UINT remdesk_generate_expert_blob(remdeskPlugin* remdesk) +static UINT remdesk_generate_expert_blob(remdeskPlugin* remdesk) { char* name; char* pass; @@ -97,7 +100,7 @@ UINT remdesk_generate_expert_blob(remdeskPlugin* remdesk) name = "Expert"; remdesk->EncryptedPassStub = freerdp_assistance_encrypt_pass_stub(password, - settings->RemoteAssistancePassStub, &(remdesk->EncryptedPassStubSize)); + settings->RemoteAssistancePassStub, &(remdesk->EncryptedPassStubSize)); if (!remdesk->EncryptedPassStub) { @@ -105,7 +108,8 @@ UINT remdesk_generate_expert_blob(remdeskPlugin* remdesk) return ERROR_INTERNAL_ERROR; } - pass = freerdp_assistance_bin_to_hex_string(remdesk->EncryptedPassStub, remdesk->EncryptedPassStubSize); + pass = freerdp_assistance_bin_to_hex_string(remdesk->EncryptedPassStub, + remdesk->EncryptedPassStubSize); if (!pass) { @@ -129,7 +133,8 @@ UINT remdesk_generate_expert_blob(remdeskPlugin* remdesk) * * @return 0 on success, otherwise a Win32 error code */ -static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header) +static UINT remdesk_read_channel_header(wStream* s, + REMDESK_CHANNEL_HEADER* header) { int status; UINT32 ChannelNameLen; @@ -163,11 +168,9 @@ static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* head } ZeroMemory(header->ChannelName, sizeof(header->ChannelName)); - pChannelName = (char*) header->ChannelName; status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), - ChannelNameLen / 2, &pChannelName, 32, NULL, NULL); - + ChannelNameLen / 2, &pChannelName, 32, NULL, NULL); Stream_Seek(s, ChannelNameLen); if (status <= 0) @@ -184,12 +187,12 @@ static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* head * * @return 0 on success, otherwise a Win32 error code */ -static UINT remdesk_write_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header) +static UINT remdesk_write_channel_header(wStream* s, + REMDESK_CHANNEL_HEADER* header) { int index; UINT32 ChannelNameLen; WCHAR ChannelNameW[32]; - ZeroMemory(ChannelNameW, sizeof(ChannelNameW)); for (index = 0; index < 32; index++) @@ -198,12 +201,9 @@ static UINT remdesk_write_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* hea } ChannelNameLen = (strlen(header->ChannelName) + 1) * 2; - Stream_Write_UINT32(s, ChannelNameLen); /* ChannelNameLen (4 bytes) */ Stream_Write_UINT32(s, header->DataLength); /* DataLen (4 bytes) */ - Stream_Write(s, ChannelNameW, ChannelNameLen); /* ChannelName (variable) */ - return CHANNEL_RC_OK; } @@ -224,7 +224,8 @@ static UINT remdesk_write_ctl_header(wStream* s, REMDESK_CTL_HEADER* ctlHeader) * * @return 0 on success, otherwise a Win32 error code */ -static UINT remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, UINT32 msgType, UINT32 msgSize) +static UINT remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, + UINT32 msgType, UINT32 msgSize) { ctlHeader->msgType = msgType; strcpy(ctlHeader->ChannelName, REMDESK_CHANNEL_CTL_NAME); @@ -237,7 +238,8 @@ static UINT remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, UINT32 msg * * @return 0 on success, otherwise a Win32 error code */ -static UINT remdesk_recv_ctl_server_announce_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header) +static UINT remdesk_recv_ctl_server_announce_pdu(remdeskPlugin* remdesk, + wStream* s, REMDESK_CHANNEL_HEADER* header) { return CHANNEL_RC_OK; } @@ -247,7 +249,8 @@ static UINT remdesk_recv_ctl_server_announce_pdu(remdeskPlugin* remdesk, wStream * * @return 0 on success, otherwise a Win32 error code */ -static UINT remdesk_recv_ctl_version_info_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header) +static UINT remdesk_recv_ctl_version_info_pdu(remdeskPlugin* remdesk, + wStream* s, REMDESK_CHANNEL_HEADER* header) { UINT32 versionMajor; UINT32 versionMinor; @@ -260,9 +263,7 @@ static UINT remdesk_recv_ctl_version_info_pdu(remdeskPlugin* remdesk, wStream* s Stream_Read_UINT32(s, versionMajor); /* versionMajor (4 bytes) */ Stream_Read_UINT32(s, versionMinor); /* versionMinor (4 bytes) */ - remdesk->Version = versionMajor; - return CHANNEL_RC_OK; } @@ -276,13 +277,11 @@ static UINT remdesk_send_ctl_version_info_pdu(remdeskPlugin* remdesk) wStream* s; REMDESK_CTL_VERSION_INFO_PDU pdu; UINT error; - remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_VERSIONINFO, 8); - pdu.versionMajor = 1; pdu.versionMinor = 2; - s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); @@ -290,10 +289,8 @@ static UINT remdesk_send_ctl_version_info_pdu(remdeskPlugin* remdesk) } remdesk_write_ctl_header(s, &(pdu.ctlHeader)); - Stream_Write_UINT32(s, pdu.versionMajor); /* versionMajor (4 bytes) */ Stream_Write_UINT32(s, pdu.versionMinor); /* versionMinor (4 bytes) */ - Stream_SealLength(s); if ((error = remdesk_virtual_channel_write(remdesk, s))) @@ -301,6 +298,7 @@ static UINT remdesk_send_ctl_version_info_pdu(remdeskPlugin* remdesk) if (error != CHANNEL_RC_OK) Stream_Free(s, TRUE); + return error; } @@ -309,7 +307,8 @@ static UINT remdesk_send_ctl_version_info_pdu(remdeskPlugin* remdesk) * * @return 0 on success, otherwise a Win32 error code */ -static UINT remdesk_recv_ctl_result_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header, UINT32 *pResult) +static UINT remdesk_recv_ctl_result_pdu(remdeskPlugin* remdesk, wStream* s, + REMDESK_CHANNEL_HEADER* header, UINT32* pResult) { UINT32 result; @@ -320,7 +319,6 @@ static UINT remdesk_recv_ctl_result_pdu(remdeskPlugin* remdesk, wStream* s, REMD } Stream_Read_UINT32(s, result); /* result (4 bytes) */ - *pResult = result; //WLog_DBG(TAG, "RemdeskRecvResult: 0x%04X", result); return CHANNEL_RC_OK; @@ -350,8 +348,8 @@ static UINT remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk) pdu.expertBlob = remdesk->ExpertBlob; pdu.raConnectionString = remdesk->settings->RemoteAssistanceRCTicket; - - status = ConvertToUnicode(CP_UTF8, 0, pdu.raConnectionString, -1, &raConnectionStringW, 0); + status = ConvertToUnicode(CP_UTF8, 0, pdu.raConnectionString, -1, + &raConnectionStringW, 0); if (status <= 0) { @@ -360,7 +358,6 @@ static UINT remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk) } cbRaConnectionStringW = status * 2; - status = ConvertToUnicode(CP_UTF8, 0, pdu.expertBlob, -1, &expertBlobW, 0); if (status <= 0) @@ -371,11 +368,10 @@ static UINT remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk) } cbExpertBlobW = status * 2; - remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_AUTHENTICATE, - cbRaConnectionStringW + cbExpertBlobW); - + cbRaConnectionStringW + cbExpertBlobW); s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); @@ -384,10 +380,8 @@ static UINT remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk) } remdesk_write_ctl_header(s, &(pdu.ctlHeader)); - Stream_Write(s, (BYTE*) raConnectionStringW, cbRaConnectionStringW); Stream_Write(s, (BYTE*) expertBlobW, cbExpertBlobW); - Stream_SealLength(s); if ((error = remdesk_virtual_channel_write(remdesk, s))) @@ -396,6 +390,7 @@ static UINT remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk) out: free(raConnectionStringW); free(expertBlobW); + if (error != CHANNEL_RC_OK) Stream_Free(s, TRUE); @@ -415,10 +410,9 @@ static UINT remdesk_send_ctl_remote_control_desktop_pdu(remdeskPlugin* remdesk) int cbRaConnectionStringW = 0; WCHAR* raConnectionStringW = NULL; REMDESK_CTL_REMOTE_CONTROL_DESKTOP_PDU pdu; - pdu.raConnectionString = remdesk->settings->RemoteAssistanceRCTicket; - - status = ConvertToUnicode(CP_UTF8, 0, pdu.raConnectionString, -1, &raConnectionStringW, 0); + status = ConvertToUnicode(CP_UTF8, 0, pdu.raConnectionString, -1, + &raConnectionStringW, 0); if (status <= 0) { @@ -427,10 +421,10 @@ static UINT remdesk_send_ctl_remote_control_desktop_pdu(remdeskPlugin* remdesk) } cbRaConnectionStringW = status * 2; - - remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_REMOTE_CONTROL_DESKTOP, cbRaConnectionStringW); - + remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_REMOTE_CONTROL_DESKTOP, + cbRaConnectionStringW); s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); @@ -439,9 +433,7 @@ static UINT remdesk_send_ctl_remote_control_desktop_pdu(remdeskPlugin* remdesk) } remdesk_write_ctl_header(s, &(pdu.ctlHeader)); - Stream_Write(s, (BYTE*) raConnectionStringW, cbRaConnectionStringW); - Stream_SealLength(s); if ((error = remdesk_virtual_channel_write(remdesk, s))) @@ -449,6 +441,7 @@ static UINT remdesk_send_ctl_remote_control_desktop_pdu(remdeskPlugin* remdesk) out: free(raConnectionStringW); + if (error != CHANNEL_RC_OK) Stream_Free(s, TRUE); @@ -476,7 +469,6 @@ static UINT remdesk_send_ctl_verify_password_pdu(remdeskPlugin* remdesk) } pdu.expertBlob = remdesk->ExpertBlob; - status = ConvertToUnicode(CP_UTF8, 0, pdu.expertBlob, -1, &expertBlobW, 0); if (status <= 0) @@ -486,10 +478,10 @@ static UINT remdesk_send_ctl_verify_password_pdu(remdeskPlugin* remdesk) } cbExpertBlobW = status * 2; - - remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_VERIFY_PASSWORD, cbExpertBlobW); - + remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_VERIFY_PASSWORD, + cbExpertBlobW); s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); @@ -498,9 +490,7 @@ static UINT remdesk_send_ctl_verify_password_pdu(remdeskPlugin* remdesk) } remdesk_write_ctl_header(s, &(pdu.ctlHeader)); - Stream_Write(s, (BYTE*) expertBlobW, cbExpertBlobW); - Stream_SealLength(s); if ((error = remdesk_virtual_channel_write(remdesk, s))) @@ -508,6 +498,7 @@ static UINT remdesk_send_ctl_verify_password_pdu(remdeskPlugin* remdesk) out: free(expertBlobW); + if (error != CHANNEL_RC_OK) Stream_Free(s, TRUE); @@ -533,11 +524,10 @@ static UINT remdesk_send_ctl_expert_on_vista_pdu(remdeskPlugin* remdesk) pdu.EncryptedPasswordLength = remdesk->EncryptedPassStubSize; pdu.EncryptedPassword = remdesk->EncryptedPassStub; - remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_EXPERT_ON_VISTA, - pdu.EncryptedPasswordLength); - + pdu.EncryptedPasswordLength); s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); @@ -545,11 +535,8 @@ static UINT remdesk_send_ctl_expert_on_vista_pdu(remdeskPlugin* remdesk) } remdesk_write_ctl_header(s, &(pdu.ctlHeader)); - Stream_Write(s, pdu.EncryptedPassword, pdu.EncryptedPasswordLength); - Stream_SealLength(s); - return remdesk_virtual_channel_write(remdesk, s); } @@ -558,7 +545,8 @@ static UINT remdesk_send_ctl_expert_on_vista_pdu(remdeskPlugin* remdesk) * * @return 0 on success, otherwise a Win32 error code */ -static UINT remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header) +static UINT remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, + REMDESK_CHANNEL_HEADER* header) { UINT error = CHANNEL_RC_OK; UINT32 msgType = 0; @@ -582,6 +570,7 @@ static UINT remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHA case REMDESK_CTL_RESULT: if ((error = remdesk_recv_ctl_result_pdu(remdesk, s, header, &result))) WLog_ERR(TAG, "remdesk_recv_ctl_result_pdu failed with error %lu", error); + break; case REMDESK_CTL_AUTHENTICATE: @@ -589,7 +578,9 @@ static UINT remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHA case REMDESK_CTL_SERVER_ANNOUNCE: if ((error = remdesk_recv_ctl_server_announce_pdu(remdesk, s, header))) - WLog_ERR(TAG, "remdesk_recv_ctl_server_announce_pdu failed with error %lu", error); + WLog_ERR(TAG, "remdesk_recv_ctl_server_announce_pdu failed with error %lu", + error); + break; case REMDESK_CTL_DISCONNECT: @@ -618,7 +609,8 @@ static UINT remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHA if ((error = remdesk_send_ctl_remote_control_desktop_pdu(remdesk))) { - WLog_ERR(TAG, "remdesk_send_ctl_remote_control_desktop_pdu failed with error %lu", error); + WLog_ERR(TAG, + "remdesk_send_ctl_remote_control_desktop_pdu failed with error %lu", error); break; } } @@ -626,13 +618,15 @@ static UINT remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHA { if ((error = remdesk_send_ctl_expert_on_vista_pdu(remdesk))) { - WLog_ERR(TAG, "remdesk_send_ctl_expert_on_vista_pdu failed with error %lu", error); + WLog_ERR(TAG, "remdesk_send_ctl_expert_on_vista_pdu failed with error %lu", + error); break; } if ((error = remdesk_send_ctl_verify_password_pdu(remdesk))) { - WLog_ERR(TAG, "remdesk_send_ctl_verify_password_pdu failed with error %lu", error); + WLog_ERR(TAG, "remdesk_send_ctl_verify_password_pdu failed with error %lu", + error); break; } } @@ -675,7 +669,6 @@ static UINT remdesk_process_receive(remdeskPlugin* remdesk, wStream* s) { UINT status; REMDESK_CHANNEL_HEADER header; - #if 0 WLog_DBG(TAG, "RemdeskReceive: %d", Stream_GetRemainingLength(s)); winpr_HexDump(Stream_Pointer(s), Stream_GetRemainingLength(s)); @@ -693,27 +686,21 @@ static UINT remdesk_process_receive(remdeskPlugin* remdesk, wStream* s) } else if (strcmp(header.ChannelName, "70") == 0) { - } else if (strcmp(header.ChannelName, "71") == 0) { - } else if (strcmp(header.ChannelName, ".") == 0) { - } else if (strcmp(header.ChannelName, "1000.") == 0) { - } else if (strcmp(header.ChannelName, "RA_FX") == 0) { - } else { - } return status; @@ -724,89 +711,12 @@ static void remdesk_process_connect(remdeskPlugin* remdesk) remdesk->settings = (rdpSettings*) remdesk->channelEntryPoints.pExtendedData; } -/****************************************************************************************/ - -static wListDictionary* g_InitHandles = NULL; -static wListDictionary* g_OpenHandles = NULL; - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -UINT remdesk_add_init_handle_data(void* pInitHandle, void* pUserData) -{ - if (!g_InitHandles) - { - g_InitHandles = ListDictionary_New(TRUE); - if (!g_InitHandles) - return CHANNEL_RC_NO_MEMORY; - } - - return ListDictionary_Add(g_InitHandles, pInitHandle, pUserData) ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; -} - -void* remdesk_get_init_handle_data(void* pInitHandle) -{ - void* pUserData = NULL; - pUserData = ListDictionary_GetItemValue(g_InitHandles, pInitHandle); - return pUserData; -} - -void remdesk_remove_init_handle_data(void* pInitHandle) -{ - ListDictionary_Remove(g_InitHandles, pInitHandle); - if (ListDictionary_Count(g_InitHandles) < 1) - { - ListDictionary_Free(g_InitHandles); - g_InitHandles = NULL; - } -} - /** * Function description * * @return 0 on success, otherwise a Win32 error code */ -UINT remdesk_add_open_handle_data(DWORD openHandle, void* pUserData) -{ - void* pOpenHandle = (void*) (size_t) openHandle; - - if (!g_OpenHandles) - { - g_OpenHandles = ListDictionary_New(TRUE); - if (!g_OpenHandles) - return CHANNEL_RC_NO_MEMORY; - } - - return ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData) ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; -} - -void* remdesk_get_open_handle_data(DWORD openHandle) -{ - void* pUserData = NULL; - void* pOpenHandle = (void*) (size_t) openHandle; - pUserData = ListDictionary_GetItemValue(g_OpenHandles, pOpenHandle); - return pUserData; -} - -void remdesk_remove_open_handle_data(DWORD openHandle) -{ - void* pOpenHandle = (void*) (size_t) openHandle; - ListDictionary_Remove(g_OpenHandles, pOpenHandle); - if (ListDictionary_Count(g_OpenHandles) < 1) - { - ListDictionary_Free(g_OpenHandles); - g_OpenHandles = NULL; - } -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -UINT remdesk_send(remdeskPlugin* remdesk, wStream* s) +static UINT remdesk_send(remdeskPlugin* remdesk, wStream* s) { UINT status = 0; remdeskPlugin* plugin = (remdeskPlugin*) remdesk; @@ -818,14 +728,14 @@ UINT remdesk_send(remdeskPlugin* remdesk, wStream* s) else { status = plugin->channelEntryPoints.pVirtualChannelWrite(plugin->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; @@ -837,7 +747,7 @@ UINT remdesk_send(remdeskPlugin* remdesk, wStream* s) * @return 0 on success, otherwise a Win32 error code */ static UINT remdesk_virtual_channel_event_data_received(remdeskPlugin* remdesk, - void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) + void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { wStream* data_in; @@ -852,6 +762,7 @@ static UINT remdesk_virtual_channel_event_data_received(remdeskPlugin* remdesk, Stream_Free(remdesk->data_in, TRUE); remdesk->data_in = Stream_New(NULL, totalLength); + if (!remdesk->data_in) { WLog_ERR(TAG, "Stream_New failed!"); @@ -860,11 +771,13 @@ static UINT remdesk_virtual_channel_event_data_received(remdeskPlugin* remdesk, } data_in = remdesk->data_in; + if (!Stream_EnsureRemainingCapacity(data_in, (int) dataLength)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return CHANNEL_RC_NO_MEMORY; } + Stream_Write(data_in, pData, dataLength); if (dataFlags & CHANNEL_FLAG_LAST) @@ -885,18 +798,18 @@ static UINT remdesk_virtual_channel_event_data_received(remdeskPlugin* remdesk, return ERROR_INTERNAL_ERROR; } } + return CHANNEL_RC_OK; } -static VOID VCAPITYPE remdesk_virtual_channel_open_event(DWORD openHandle, UINT event, - LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) +static VOID VCAPITYPE remdesk_virtual_channel_open_event(DWORD openHandle, + UINT event, + LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { - remdeskPlugin* remdesk; + remdeskPlugin* remdesk = s_TLSPluginContext; UINT error = CHANNEL_RC_OK; - remdesk = (remdeskPlugin*) remdesk_get_open_handle_data(openHandle); - - if (!remdesk) + if (!remdesk || (remdesk->OpenHandle != openHandle)) { WLog_ERR(TAG, "error no match"); return; @@ -905,8 +818,11 @@ static VOID VCAPITYPE remdesk_virtual_channel_open_event(DWORD openHandle, UINT switch (event) { case CHANNEL_EVENT_DATA_RECEIVED: - if ((error = remdesk_virtual_channel_event_data_received(remdesk, pData, dataLength, totalLength, dataFlags))) - WLog_ERR(TAG, "remdesk_virtual_channel_event_data_received failed with error %lu!", error); + if ((error = remdesk_virtual_channel_event_data_received(remdesk, pData, + dataLength, totalLength, dataFlags))) + WLog_ERR(TAG, + "remdesk_virtual_channel_event_data_received failed with error %lu!", error); + break; case CHANNEL_EVENT_WRITE_COMPLETE: @@ -919,11 +835,11 @@ static VOID VCAPITYPE remdesk_virtual_channel_open_event(DWORD openHandle, UINT default: WLog_ERR(TAG, "unhandled event %lu!", event); error = ERROR_INTERNAL_ERROR; - } - if (error && remdesk->rdpcontext) - setChannelError(remdesk->rdpcontext, error, "remdesk_virtual_channel_open_event reported an error"); + if (error && remdesk->rdpcontext) + setChannelError(remdesk->rdpcontext, error, + "remdesk_virtual_channel_open_event reported an error"); } static void* remdesk_virtual_channel_client_thread(void* arg) @@ -932,7 +848,6 @@ static void* remdesk_virtual_channel_client_thread(void* arg) wMessage message; remdeskPlugin* remdesk = (remdeskPlugin*) arg; UINT error = CHANNEL_RC_OK; - remdesk_process_connect(remdesk); while (1) @@ -944,17 +859,20 @@ static void* remdesk_virtual_channel_client_thread(void* arg) break; } - if (!MessageQueue_Peek(remdesk->queue, &message, TRUE)) { + if (!MessageQueue_Peek(remdesk->queue, &message, TRUE)) + { WLog_ERR(TAG, "MessageQueue_Peek failed!"); error = ERROR_INTERNAL_ERROR; break; } + if (message.id == WMQ_QUIT) break; if (message.id == 0) { data = (wStream*) message.wParam; + if ((error = remdesk_process_receive(remdesk, data))) { WLog_ERR(TAG, "remdesk_process_receive failed with error %lu!", error); @@ -964,7 +882,8 @@ static void* remdesk_virtual_channel_client_thread(void* arg) } if (error && remdesk->rdpcontext) - setChannelError(remdesk->rdpcontext, error, "remdesk_virtual_channel_client_thread reported an error"); + setChannelError(remdesk->rdpcontext, error, + "remdesk_virtual_channel_client_thread reported an error"); ExitThread((DWORD)error); return NULL; @@ -975,28 +894,24 @@ static void* remdesk_virtual_channel_client_thread(void* arg) * * @return 0 on success, otherwise a Win32 error code */ -static UINT remdesk_virtual_channel_event_connected(remdeskPlugin* remdesk, LPVOID pData, UINT32 dataLength) +static UINT remdesk_virtual_channel_event_connected(remdeskPlugin* remdesk, + LPVOID pData, UINT32 dataLength) { UINT32 status; UINT error; - status = remdesk->channelEntryPoints.pVirtualChannelOpen(remdesk->InitHandle, - &remdesk->OpenHandle, remdesk->channelDef.name, remdesk_virtual_channel_open_event); + &remdesk->OpenHandle, remdesk->channelDef.name, + remdesk_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; } - if ((error = remdesk_add_open_handle_data(remdesk->OpenHandle, remdesk))) - { - WLog_ERR(TAG, "remdesk_add_open_handle_data failed with error %lu", error); - return error; - } - remdesk->queue = MessageQueue_New(NULL); + if (!remdesk->queue) { WLog_ERR(TAG, "MessageQueue_New failed!"); @@ -1005,16 +920,18 @@ static UINT remdesk_virtual_channel_event_connected(remdeskPlugin* remdesk, LPVO } remdesk->thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) remdesk_virtual_channel_client_thread, (void*) remdesk, 0, NULL); + (LPTHREAD_START_ROUTINE) remdesk_virtual_channel_client_thread, (void*) remdesk, + 0, NULL); + if (!remdesk->thread) { WLog_ERR(TAG, "CreateThread failed"); error = ERROR_INTERNAL_ERROR; goto error_out; } + return CHANNEL_RC_OK; error_out: - remdesk_remove_open_handle_data(remdesk->OpenHandle); MessageQueue_Free(remdesk->queue); remdesk->queue = NULL; return error; @@ -1029,7 +946,8 @@ static UINT remdesk_virtual_channel_event_disconnected(remdeskPlugin* remdesk) { UINT rc; - if (MessageQueue_PostQuit(remdesk->queue, 0) && (WaitForSingleObject(remdesk->thread, INFINITE) == WAIT_FAILED)) + if (MessageQueue_PostQuit(remdesk->queue, 0) + && (WaitForSingleObject(remdesk->thread, INFINITE) == WAIT_FAILED)) { rc = GetLastError(); WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", rc); @@ -1038,44 +956,41 @@ static UINT remdesk_virtual_channel_event_disconnected(remdeskPlugin* remdesk) MessageQueue_Free(remdesk->queue); CloseHandle(remdesk->thread); - remdesk->queue = NULL; remdesk->thread = NULL; - rc = remdesk->channelEntryPoints.pVirtualChannelClose(remdesk->OpenHandle); + if (CHANNEL_RC_OK != rc) { WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08X]", - WTSErrorToString(rc), rc); + WTSErrorToString(rc), rc); } + remdesk->OpenHandle = 0; + if (remdesk->data_in) { Stream_Free(remdesk->data_in, TRUE); remdesk->data_in = NULL; } - remdesk_remove_open_handle_data(remdesk->OpenHandle); return rc; } static void remdesk_virtual_channel_event_terminated(remdeskPlugin* remdesk) { - remdesk_remove_init_handle_data(remdesk->InitHandle); - + remdesk->InitHandle = 0; free(remdesk); } static VOID VCAPITYPE remdesk_virtual_channel_init_event(LPVOID pInitHandle, - UINT event, LPVOID pData, - UINT dataLength) + UINT event, LPVOID pData, + UINT dataLength) { - remdeskPlugin* remdesk; + remdeskPlugin* remdesk = s_TLSPluginContext; UINT error = CHANNEL_RC_OK; - remdesk = (remdeskPlugin*) remdesk_get_init_handle_data(pInitHandle); - - if (!remdesk) + if (!remdesk || (remdesk->InitHandle != pInitHandle)) { WLog_ERR(TAG, "error no match"); return; @@ -1084,21 +999,28 @@ static VOID VCAPITYPE remdesk_virtual_channel_init_event(LPVOID pInitHandle, switch (event) { case CHANNEL_EVENT_CONNECTED: - if ((error = remdesk_virtual_channel_event_connected(remdesk, pData, dataLength))) - WLog_ERR(TAG, "remdesk_virtual_channel_event_connected failed with error %lu", error); + if ((error = remdesk_virtual_channel_event_connected(remdesk, pData, + dataLength))) + WLog_ERR(TAG, "remdesk_virtual_channel_event_connected failed with error %lu", + error); + break; case CHANNEL_EVENT_DISCONNECTED: if ((error = remdesk_virtual_channel_event_disconnected(remdesk))) - WLog_ERR(TAG, "remdesk_virtual_channel_event_disconnected failed with error %lu", error); + WLog_ERR(TAG, + "remdesk_virtual_channel_event_disconnected failed with error %lu", error); + break; case CHANNEL_EVENT_TERMINATED: remdesk_virtual_channel_event_terminated(remdesk); break; } + if (error && remdesk->rdpcontext) - setChannelError(remdesk->rdpcontext, error, "remdesk_virtual_channel_init_event reported an error"); + setChannelError(remdesk->rdpcontext, error, + "remdesk_virtual_channel_init_event reported an error"); } /* remdesk is always built-in */ @@ -1107,12 +1029,9 @@ static VOID VCAPITYPE remdesk_virtual_channel_init_event(LPVOID pInitHandle, BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) { UINT rc; - UINT error; - remdeskPlugin* remdesk; RemdeskClientContext* context = NULL; CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx; - remdesk = (remdeskPlugin*) calloc(1, sizeof(remdeskPlugin)); if (!remdesk) @@ -1122,21 +1041,19 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) } remdesk->channelDef.options = - CHANNEL_OPTION_INITIALIZED | - CHANNEL_OPTION_ENCRYPT_RDP | - CHANNEL_OPTION_COMPRESS_RDP | - CHANNEL_OPTION_SHOW_PROTOCOL; - + CHANNEL_OPTION_INITIALIZED | + CHANNEL_OPTION_ENCRYPT_RDP | + CHANNEL_OPTION_COMPRESS_RDP | + CHANNEL_OPTION_SHOW_PROTOCOL; strcpy(remdesk->channelDef.name, "remdesk"); - remdesk->Version = 2; - 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 = (RemdeskClientContext*) calloc(1, sizeof(RemdeskClientContext)); + if (!context) { WLog_ERR(TAG, "calloc failed!"); @@ -1144,31 +1061,29 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) } context->handle = (void*) remdesk; - *(pEntryPointsEx->ppInterface) = (void*) context; remdesk->context = context; remdesk->rdpcontext = pEntryPointsEx->context; } - CopyMemory(&(remdesk->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); - + CopyMemory(&(remdesk->channelEntryPoints), pEntryPoints, + sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); rc = remdesk->channelEntryPoints.pVirtualChannelInit(&remdesk->InitHandle, - &remdesk->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, remdesk_virtual_channel_init_event); + &remdesk->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, + remdesk_virtual_channel_init_event); + if (CHANNEL_RC_OK != rc) { WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]", - WTSErrorToString(rc), rc); + WTSErrorToString(rc), rc); goto error_out; } - remdesk->channelEntryPoints.pInterface = *(remdesk->channelEntryPoints.ppInterface); - remdesk->channelEntryPoints.ppInterface = &(remdesk->channelEntryPoints.pInterface); - - if ((error = remdesk_add_init_handle_data(remdesk->InitHandle, (void*) remdesk))) - { - WLog_ERR(TAG, "remdesk_add_init_handle_data failed with error %lu!", error); - goto error_out; - } + remdesk->channelEntryPoints.pInterface = * + (remdesk->channelEntryPoints.ppInterface); + remdesk->channelEntryPoints.ppInterface = & + (remdesk->channelEntryPoints.pInterface); + s_TLSPluginContext = remdesk; return TRUE; error_out: free(remdesk); diff --git a/client/Android/android_freerdp.c b/client/Android/android_freerdp.c index de3b0dc..87a006d 100644 --- a/client/Android/android_freerdp.c +++ b/client/Android/android_freerdp.c @@ -721,7 +721,7 @@ static BOOL android_client_new(freerdp* instance, rdpContext* context) if (!instance || !context) return FALSE; - if (!(context->channels = freerdp_channels_new())) + if (!(context->channels = freerdp_channels_new(instance))) return FALSE; if (!android_event_queue_init(instance)) diff --git a/client/DirectFB/dfreerdp.c b/client/DirectFB/dfreerdp.c index 5c801cd..d5d1aa7 100644 --- a/client/DirectFB/dfreerdp.c +++ b/client/DirectFB/dfreerdp.c @@ -51,7 +51,7 @@ struct thread_data BOOL df_context_new(freerdp* instance, rdpContext* context) { - if (!(context->channels = freerdp_channels_new())) + if (!(context->channels = freerdp_channels_new(instance))) return FALSE; return TRUE; @@ -77,7 +77,6 @@ void df_end_paint(rdpContext* context) { rdpGdi* gdi; dfInfo* dfi; - gdi = context->gdi; dfi = ((dfContext*) context)->dfi; @@ -95,26 +94,23 @@ void df_end_paint(rdpContext* context) dfi->update_rect.w = gdi->width; dfi->update_rect.h = gdi->height; #endif - - dfi->primary->Blit(dfi->primary, dfi->surface, &(dfi->update_rect), dfi->update_rect.x, dfi->update_rect.y); + dfi->primary->Blit(dfi->primary, dfi->surface, &(dfi->update_rect), + dfi->update_rect.x, dfi->update_rect.y); } -BOOL df_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount) +BOOL df_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, + int* wcount) { dfInfo* dfi; - dfi = ((dfContext*) instance->context)->dfi; - rfds[*rcount] = (void*)(long)(dfi->read_fds); (*rcount)++; - return TRUE; } BOOL df_check_fds(freerdp* instance, fd_set* set) { dfInfo* dfi; - dfi = ((dfContext*) instance->context)->dfi; if (!FD_ISSET(dfi->read_fds, set)) @@ -132,16 +128,12 @@ BOOL df_pre_connect(freerdp* instance) BOOL bitmap_cache; dfContext* context; rdpSettings* settings; - dfi = (dfInfo*) malloc(sizeof(dfInfo)); ZeroMemory(dfi, sizeof(dfInfo)); - context = ((dfContext*) instance->context); context->dfi = dfi; - settings = instance->settings; bitmap_cache = settings->BitmapCacheEnabled; - settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE; settings->OrderSupport[NEG_PATBLT_INDEX] = TRUE; settings->OrderSupport[NEG_SCRBLT_INDEX] = TRUE; @@ -166,18 +158,16 @@ BOOL df_pre_connect(freerdp* instance) settings->OrderSupport[NEG_POLYGON_CB_INDEX] = FALSE; settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE; settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE; - dfi->clrconv = (CLRCONV*) malloc(sizeof(CLRCONV)); ZeroMemory(dfi->clrconv, sizeof(CLRCONV)); - dfi->clrconv->alpha = 1; dfi->clrconv->invert = 0; dfi->clrconv->rgb555 = 0; - dfi->clrconv->palette = (rdpPalette*) malloc(sizeof(rdpPalette)); ZeroMemory(dfi->clrconv->palette, sizeof(rdpPalette)); - if (freerdp_channels_pre_connect(instance->context->channels, instance) != CHANNEL_RC_OK) + if (freerdp_channels_pre_connect(instance->context->channels, + instance) != CHANNEL_RC_OK) return FALSE; return (instance->context->cache = cache_new(instance->settings)) != NULL; @@ -188,29 +178,27 @@ BOOL df_post_connect(freerdp* instance) rdpGdi* gdi; dfInfo* dfi; dfContext* context; - context = ((dfContext*) instance->context); dfi = context->dfi; - if (!gdi_init(instance, CLRCONV_ALPHA | CLRCONV_INVERT | CLRBUF_16BPP | CLRBUF_32BPP, NULL)) + if (!gdi_init(instance, CLRCONV_ALPHA | CLRCONV_INVERT | CLRBUF_16BPP | + CLRBUF_32BPP, NULL)) return FALSE; gdi = instance->context->gdi; - dfi->err = DirectFBCreate(&(dfi->dfb)); - dfi->dsc.flags = DSDESC_CAPS; dfi->dsc.caps = DSCAPS_PRIMARY; dfi->err = dfi->dfb->CreateSurface(dfi->dfb, &(dfi->dsc), &(dfi->primary)); dfi->err = dfi->primary->GetSize(dfi->primary, &(gdi->width), &(gdi->height)); dfi->dfb->SetVideoMode(dfi->dfb, gdi->width, gdi->height, gdi->dstBpp); - dfi->dfb->CreateInputEventBuffer(dfi->dfb, DICAPS_ALL, DFB_TRUE, &(dfi->event_buffer)); + dfi->dfb->CreateInputEventBuffer(dfi->dfb, DICAPS_ALL, DFB_TRUE, + &(dfi->event_buffer)); dfi->event_buffer->CreateFileDescriptor(dfi->event_buffer, &(dfi->read_fds)); - dfi->dfb->GetDisplayLayer(dfi->dfb, 0, &(dfi->layer)); dfi->layer->EnableCursor(dfi->layer, 1); - - dfi->dsc.flags = DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PREALLOCATED | DSDESC_PIXELFORMAT; + dfi->dsc.flags = DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT | + DSDESC_PREALLOCATED | DSDESC_PIXELFORMAT; dfi->dsc.caps = DSCAPS_SYSTEMONLY; dfi->dsc.width = gdi->width; dfi->dsc.height = gdi->height; @@ -227,28 +215,27 @@ BOOL df_post_connect(freerdp* instance) dfi->dsc.preallocated[0].data = gdi->primary_buffer; dfi->dsc.preallocated[0].pitch = gdi->width * gdi->bytesPerPixel; dfi->dfb->CreateSurface(dfi->dfb, &(dfi->dsc), &(dfi->surface)); - instance->update->BeginPaint = df_begin_paint; instance->update->EndPaint = df_end_paint; - df_keyboard_init(); - pointer_cache_register_callbacks(instance->update); df_register_graphics(instance->context->graphics); - - return freerdp_channels_post_connect(instance->context->channels, instance) == CHANNEL_RC_OK; + return freerdp_channels_post_connect(instance->context->channels, + instance) == CHANNEL_RC_OK; } -BOOL df_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint) +BOOL df_verify_certificate(freerdp* instance, char* subject, char* issuer, + char* fingerprint) { char answer; WLog_INFO(TAG, "Certificate details:"); WLog_INFO(TAG, "\tSubject: %s", subject); WLog_INFO(TAG, "\tIssuer: %s", issuer); WLog_INFO(TAG, "\tThumbprint: %s", fingerprint); - WLog_INFO(TAG, "The above X.509 certificate could not be verified, possibly because you do not have " - "the CA certificate in your certificate store, or the certificate has expired. " - "Please look at the documentation on how to create local certificate store for a private CA."); + WLog_INFO(TAG, + "The above X.509 certificate could not be verified, possibly because you do not have " + "the CA certificate in your certificate store, or the certificate has expired. " + "Please look at the documentation on how to create local certificate store for a private CA."); while (1) { @@ -268,28 +255,28 @@ BOOL df_verify_certificate(freerdp* instance, char* subject, char* issuer, char* return FALSE; } -static int df_receive_channel_data(freerdp* instance, UINT16 channelId, BYTE* data, int size, int flags, int total_size) +static int df_receive_channel_data(freerdp* instance, UINT16 channelId, + BYTE* data, int size, int flags, int total_size) { - return freerdp_channels_data(instance, channelId, data, size, flags, total_size); + return freerdp_channels_data(instance, channelId, data, size, flags, + total_size); } -static void df_process_cb_monitor_ready_event(rdpChannels* channels, freerdp* instance) +static void df_process_cb_monitor_ready_event(rdpChannels* channels, + freerdp* instance) { wMessage* event; RDP_CB_FORMAT_LIST_EVENT* format_list_event; - - event = freerdp_event_new(CliprdrChannel_Class, CliprdrChannel_FormatList, NULL, NULL); - + event = freerdp_event_new(CliprdrChannel_Class, CliprdrChannel_FormatList, NULL, + NULL); format_list_event = (RDP_CB_FORMAT_LIST_EVENT*) event; format_list_event->num_formats = 0; - freerdp_channels_send_event(channels, event); } static void df_process_channel_event(rdpChannels* channels, freerdp* instance) { wMessage* event; - event = freerdp_channels_pop_event(channels); if (event) @@ -301,7 +288,8 @@ static void df_process_channel_event(rdpChannels* channels, freerdp* instance) break; default: - WLog_ERR(TAG, "df_process_channel_event: unknown event type %d", GetMessageType(event->id)); + WLog_ERR(TAG, "df_process_channel_event: unknown event type %d", + GetMessageType(event->id)); break; } @@ -329,7 +317,6 @@ int dfreerdp_run(freerdp* instance) dfInfo* dfi; dfContext* context; rdpChannels* channels; - ZeroMemory(rfds, sizeof(rfds)); ZeroMemory(wfds, sizeof(wfds)); @@ -337,7 +324,6 @@ int dfreerdp_run(freerdp* instance) return 0; context = (dfContext*) instance->context; - dfi = context->dfi; channels = instance->context->channels; @@ -351,11 +337,14 @@ int dfreerdp_run(freerdp* instance) WLog_ERR(TAG, "Failed to get FreeRDP file descriptor"); break; } - if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != TRUE) + + if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, + &wcount) != TRUE) { WLog_ERR(TAG, "Failed to get channel manager file descriptor"); break; } + if (df_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE) { WLog_ERR(TAG, "Failed to get dfreerdp file descriptor"); @@ -383,9 +372,9 @@ int dfreerdp_run(freerdp* instance) { /* these are not really errors */ if (!((errno == EAGAIN) || - (errno == EWOULDBLOCK) || - (errno == EINPROGRESS) || - (errno == EINTR))) /* signal occurred */ + (errno == EWOULDBLOCK) || + (errno == EINPROGRESS) || + (errno == EINTR))) /* signal occurred */ { WLog_ERR(TAG, "dfreerdp_run: select failed"); break; @@ -397,29 +386,30 @@ int dfreerdp_run(freerdp* instance) WLog_ERR(TAG, "Failed to check FreeRDP file descriptor"); break; } + if (df_check_fds(instance, &rfds_set) != TRUE) { WLog_ERR(TAG, "Failed to check dfreerdp file descriptor"); break; } + if (freerdp_channels_check_fds(channels, instance) != TRUE) { WLog_ERR(TAG, "Failed to check channel manager file descriptor"); break; } + df_process_channel_event(channels, instance); } freerdp_channels_disconnect(channels, instance); freerdp_disconnect(instance); - freerdp_channels_close(channels, instance); freerdp_channels_free(channels); df_free(dfi); gdi_free(instance); freerdp_disconnect(instance); freerdp_free(instance); - return 0; } @@ -427,17 +417,13 @@ void* thread_func(void* param) { struct thread_data* data; data = (struct thread_data*) param; - dfreerdp_run(data->instance); - free(data); - pthread_detach(pthread_self()); - g_thread_count--; - if (g_thread_count < 1) - ReleaseSemaphore(g_sem, 1, NULL); + if (g_thread_count < 1) + ReleaseSemaphore(g_sem, 1, NULL); return NULL; } @@ -450,7 +436,6 @@ int main(int argc, char* argv[]) dfContext* context; rdpChannels* channels; struct thread_data* data; - setlocale(LC_ALL, ""); if (!(g_sem = CreateSemaphore(NULL, 0, 1, NULL))) @@ -464,7 +449,6 @@ int main(int argc, char* argv[]) instance->PostConnect = df_post_connect; instance->VerifyCertificate = df_verify_certificate; instance->ReceiveChannelData = df_receive_channel_data; - instance->ContextSize = sizeof(dfContext); instance->ContextNew = df_context_new; instance->ContextFree = df_context_free; @@ -477,25 +461,22 @@ int main(int argc, char* argv[]) context = (dfContext*) instance->context; channels = instance->context->channels; - DirectFBInit(&argc, &argv); - instance->context->argc = argc; instance->context->argv = argv; - - status = freerdp_client_settings_parse_command_line(instance->settings, argc, argv, FALSE); + status = freerdp_client_settings_parse_command_line(instance->settings, argc, + argv, FALSE); if (status < 0) exit(0); - if (!freerdp_client_load_addins(instance->context->channels, instance->settings)) + if (!freerdp_client_load_addins(instance->context->channels, + instance->settings)) exit(-1); data = (struct thread_data*) malloc(sizeof(struct thread_data)); ZeroMemory(data, sizeof(sizeof(struct thread_data))); - data->instance = instance; - g_thread_count++; pthread_create(&thread, 0, thread_func, data); diff --git a/client/Mac/mf_client.m b/client/Mac/mf_client.m index 009af91..a35c5b2 100644 --- a/client/Mac/mf_client.m +++ b/client/Mac/mf_client.m @@ -89,7 +89,7 @@ static BOOL mfreerdp_client_new(freerdp* instance, rdpContext* context) context->instance->PreConnect = mac_pre_connect; context->instance->PostConnect = mac_post_connect; context->instance->Authenticate = mac_authenticate; - context->channels = freerdp_channels_new(); + context->channels = freerdp_channels_new(instance); settings = instance->settings; settings->AsyncTransport = TRUE; settings->AsyncUpdate = TRUE; diff --git a/client/Sample/freerdp.c b/client/Sample/freerdp.c index b00bc98..5712257 100644 --- a/client/Sample/freerdp.c +++ b/client/Sample/freerdp.c @@ -49,7 +49,7 @@ typedef struct tf_context tfContext; static BOOL tf_context_new(freerdp* instance, rdpContext* context) { - if (!(context->channels = freerdp_channels_new())) + if (!(context->channels = freerdp_channels_new(instance))) return FALSE; return TRUE; @@ -69,7 +69,7 @@ static BOOL tf_begin_paint(rdpContext* context) { rdpGdi* gdi = context->gdi; gdi->primary->hdc->hwnd->invalid->null = 1; - return TRUE; + return TRUE; } static BOOL tf_end_paint(rdpContext* context) @@ -78,16 +78,14 @@ static BOOL tf_end_paint(rdpContext* context) if (gdi->primary->hdc->hwnd->invalid->null) return TRUE; + return TRUE; } static BOOL tf_pre_connect(freerdp* instance) { rdpSettings* settings; - - settings = instance->settings; - settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE; settings->OrderSupport[NEG_PATBLT_INDEX] = TRUE; settings->OrderSupport[NEG_SCRBLT_INDEX] = TRUE; @@ -111,7 +109,8 @@ static BOOL tf_pre_connect(freerdp* instance) settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = TRUE; settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = TRUE; - if (freerdp_channels_pre_connect(instance->context->channels, instance) != CHANNEL_RC_OK) + if (freerdp_channels_pre_connect(instance->context->channels, + instance) != CHANNEL_RC_OK) return FALSE; return TRUE; @@ -124,8 +123,8 @@ static BOOL tf_post_connect(freerdp* instance) instance->update->BeginPaint = tf_begin_paint; instance->update->EndPaint = tf_end_paint; - - return (freerdp_channels_post_connect(instance->context->channels, instance) == CHANNEL_RC_OK); + return (freerdp_channels_post_connect(instance->context->channels, + instance) == CHANNEL_RC_OK); } static void* tf_client_thread_proc(freerdp* instance) @@ -146,16 +145,17 @@ static void* tf_client_thread_proc(freerdp* instance) if (nCount == 0) { - WLog_ERR(TAG, "%s: freerdp_get_event_handles failed", __FUNCTION__); - break; + WLog_ERR(TAG, "%s: freerdp_get_event_handles failed", __FUNCTION__); + break; } status = WaitForMultipleObjects(nCount, handles, FALSE, 100); if (status == WAIT_FAILED) { - WLog_ERR(TAG, "%s: WaitForMultipleObjects failed with %lu", __FUNCTION__, status); - break; + WLog_ERR(TAG, "%s: WaitForMultipleObjects failed with %lu", __FUNCTION__, + status); + break; } if (!freerdp_check_event_handles(instance->context)) @@ -166,7 +166,6 @@ static void* tf_client_thread_proc(freerdp* instance) } freerdp_disconnect(instance); - ExitThread(0); return NULL; } @@ -176,16 +175,16 @@ int main(int argc, char* argv[]) int status; HANDLE thread; freerdp* instance; - instance = freerdp_new(); + if (!instance) { WLog_ERR(TAG, "Couldn't create instance"); exit(1); } + instance->PreConnect = tf_pre_connect; instance->PostConnect = tf_post_connect; - instance->ContextSize = sizeof(tfContext); instance->ContextNew = tf_context_new; instance->ContextFree = tf_context_free; @@ -196,18 +195,20 @@ int main(int argc, char* argv[]) exit(1); } - status = freerdp_client_settings_parse_command_line(instance->settings, argc, argv, FALSE); + status = freerdp_client_settings_parse_command_line(instance->settings, argc, + argv, FALSE); if (status < 0) { exit(0); } - if (!freerdp_client_load_addins(instance->context->channels, instance->settings)) - exit (-1); + if (!freerdp_client_load_addins(instance->context->channels, + instance->settings)) + exit(-1); if (!(thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) - tf_client_thread_proc, instance, 0, NULL))) + tf_client_thread_proc, instance, 0, NULL))) { WLog_ERR(TAG, "Failed to create client thread"); } @@ -218,6 +219,5 @@ int main(int argc, char* argv[]) freerdp_context_free(instance); freerdp_free(instance); - return 0; } diff --git a/client/Wayland/wlfreerdp.c b/client/Wayland/wlfreerdp.c index 1fdc015..40c5add 100644 --- a/client/Wayland/wlfreerdp.c +++ b/client/Wayland/wlfreerdp.c @@ -366,7 +366,7 @@ static BOOL wlf_client_new(freerdp* instance, rdpContext* context) if (!instance || !context) return FALSE; - if (!(context->channels = freerdp_channels_new())) + if (!(context->channels = freerdp_channels_new(instance))) return FALSE; instance->PreConnect = wl_pre_connect; diff --git a/client/Windows/wf_client.c b/client/Windows/wf_client.c index af58fca..6a61c33 100644 --- a/client/Windows/wf_client.c +++ b/client/Windows/wf_client.c @@ -145,7 +145,7 @@ static BOOL wf_sw_desktop_resize(rdpContext* context) { wf_image_free(wfc->primary); wfc->primary = wf_image_new(wfc, settings->DesktopWidth, - settings->DesktopHeight, wfc->context.gdi->dstFormat, NULL); + settings->DesktopHeight, wfc->context.gdi->dstFormat, NULL); } return TRUE; @@ -190,7 +190,7 @@ static BOOL wf_hw_desktop_resize(rdpContext* context) same = (wfc->primary == wfc->drawing) ? TRUE : FALSE; wf_image_free(wfc->primary); wfc->primary = wf_image_new(wfc, settings->DesktopWidth, - settings->DesktopHeight, wfc->context.gdi->dstFormat, NULL); + settings->DesktopHeight, wfc->context.gdi->dstFormat, NULL); if (same) wfc->drawing = wfc->primary; @@ -200,7 +200,7 @@ static BOOL wf_hw_desktop_resize(rdpContext* context) { if (wfc->hwnd) SetWindowPos(wfc->hwnd, HWND_TOP, -1, -1, settings->DesktopWidth + wfc->diff.x, - settings->DesktopHeight + wfc->diff.y, SWP_NOMOVE); + settings->DesktopHeight + wfc->diff.y, SWP_NOMOVE); } else { @@ -296,22 +296,22 @@ static BOOL wf_pre_connect(freerdp* instance) } if ((settings->DesktopWidth < 64) || (settings->DesktopHeight < 64) || - (settings->DesktopWidth > 4096) || (settings->DesktopHeight > 4096)) + (settings->DesktopWidth > 4096) || (settings->DesktopHeight > 4096)) { WLog_ERR(TAG, "invalid dimensions %d %d", settings->DesktopWidth, - settings->DesktopHeight); + settings->DesktopHeight); return FALSE; } freerdp_set_param_uint32(settings, FreeRDP_KeyboardLayout, - (int) GetKeyboardLayout(0) & 0x0000FFFF); + (int) GetKeyboardLayout(0) & 0x0000FFFF); PubSub_SubscribeChannelConnected(instance->context->pubSub, - (pChannelConnectedEventHandler) wf_OnChannelConnectedEventHandler); + (pChannelConnectedEventHandler) wf_OnChannelConnectedEventHandler); PubSub_SubscribeChannelDisconnected(instance->context->pubSub, - (pChannelDisconnectedEventHandler) wf_OnChannelDisconnectedEventHandler); + (pChannelDisconnectedEventHandler) wf_OnChannelDisconnectedEventHandler); if (freerdp_channels_pre_connect(instance->context->channels, - instance) != CHANNEL_RC_OK) + instance) != CHANNEL_RC_OK) return FALSE; return TRUE; @@ -323,7 +323,7 @@ static void wf_add_system_menu(wfContext* wfc) MENUITEMINFO item_info; ZeroMemory(&item_info, sizeof(MENUITEMINFO)); item_info.fMask = MIIM_CHECKMARKS | MIIM_FTYPE | MIIM_ID | MIIM_STRING | - MIIM_DATA; + MIIM_DATA; item_info.cbSize = sizeof(MENUITEMINFO); item_info.wID = SYSCOMMAND_ID_SMARTSIZING; item_info.fType = MFT_STRING; @@ -349,13 +349,12 @@ static BOOL wf_post_connect(freerdp* instance) rdpSettings* settings; EmbedWindowEventArgs e; const UINT32 format = PIXEL_FORMAT_BGRX32; - settings = instance->settings; context = instance->context; wfc = (wfContext*) instance->context; cache = instance->context->cache; wfc->primary = wf_image_new(wfc, settings->DesktopWidth, - settings->DesktopHeight, format, NULL); + settings->DesktopHeight, format, NULL); if (!gdi_init_ex(instance, format, 0, wfc->primary->pdata, wf_image_free)) return FALSE; @@ -371,10 +370,10 @@ static BOOL wf_post_connect(freerdp* instance) _snwprintf(lpWindowName, ARRAYSIZE(lpWindowName), L"%S", settings->WindowTitle); else if (settings->ServerPort == 3389) _snwprintf(lpWindowName, ARRAYSIZE(lpWindowName), L"FreeRDP: %S", - settings->ServerHostname); + settings->ServerHostname); else _snwprintf(lpWindowName, ARRAYSIZE(lpWindowName), L"FreeRDP: %S:%d", - settings->ServerHostname, settings->ServerPort); + settings->ServerHostname, settings->ServerPort); if (settings->EmbeddedWindow) settings->Decorations = FALSE; @@ -385,20 +384,20 @@ static BOOL wf_post_connect(freerdp* instance) dwStyle = WS_CHILD | WS_BORDER; else dwStyle = WS_CAPTION | WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX | WS_SIZEBOX - | WS_MAXIMIZEBOX; + | WS_MAXIMIZEBOX; if (!wfc->hwnd) { wfc->hwnd = CreateWindowEx((DWORD) NULL, wfc->wndClassName, lpWindowName, - dwStyle, - 0, 0, 0, 0, wfc->hWndParent, NULL, wfc->hInstance, NULL); + dwStyle, + 0, 0, 0, 0, wfc->hWndParent, NULL, wfc->hInstance, NULL); SetWindowLongPtr(wfc->hwnd, GWLP_USERDATA, (LONG_PTR) wfc); } wf_resize_window(wfc); wf_add_system_menu(wfc); BitBlt(wfc->primary->hdc, 0, 0, settings->DesktopWidth, settings->DesktopHeight, - NULL, 0, 0, BLACKNESS); + NULL, 0, 0, BLACKNESS); wfc->drawing = wfc->primary; EventArgsInit(&e, "wfreerdp"); e.embed = FALSE; @@ -453,7 +452,7 @@ static CREDUI_INFOA wfUiInfo = }; static BOOL wf_authenticate_raw(freerdp* instance, const char* title, - char** username, char** password, char** domain) + char** username, char** password, char** domain) { BOOL fSave; DWORD status; @@ -467,8 +466,8 @@ static BOOL wf_authenticate_raw(freerdp* instance, const char* title, ZeroMemory(Password, sizeof(Password)); dwFlags = CREDUI_FLAGS_DO_NOT_PERSIST | CREDUI_FLAGS_EXCLUDE_CERTIFICATES; status = CredUIPromptForCredentialsA(&wfUiInfo, title, NULL, 0, - UserName, CREDUI_MAX_USERNAME_LENGTH + 1, - Password, CREDUI_MAX_PASSWORD_LENGTH + 1, &fSave, dwFlags); + UserName, CREDUI_MAX_USERNAME_LENGTH + 1, + Password, CREDUI_MAX_PASSWORD_LENGTH + 1, &fSave, dwFlags); if (status != NO_ERROR) { @@ -479,7 +478,7 @@ static BOOL wf_authenticate_raw(freerdp* instance, const char* title, ZeroMemory(User, sizeof(User)); ZeroMemory(Domain, sizeof(Domain)); status = CredUIParseUserNameA(UserName, User, sizeof(User), Domain, - sizeof(Domain)); + sizeof(Domain)); //WLog_ERR(TAG, "User: %s Domain: %s Password: %s", User, Domain, Password); *username = _strdup(User); @@ -514,14 +513,14 @@ static BOOL wf_authenticate_raw(freerdp* instance, const char* title, } static BOOL wf_authenticate(freerdp* instance, - char** username, char** password, char** domain) + char** username, char** password, char** domain) { return wf_authenticate_raw(instance, instance->settings->ServerHostname, - username, password, domain); + username, password, domain); } static BOOL wf_gw_authenticate(freerdp* instance, - char** username, char** password, char** domain) + char** username, char** password, char** domain) { char tmp[MAX_PATH]; sprintf_s(tmp, sizeof(tmp), "Gateway %s", instance->settings->GatewayHostname); @@ -529,11 +528,11 @@ static BOOL wf_gw_authenticate(freerdp* instance, } static DWORD wf_verify_certificate(freerdp* instance, - const char* common_name, - const char* subject, - const char* issuer, - const char* fingerprint, - BOOL host_mismatch) + const char* common_name, + const char* subject, + const char* issuer, + const char* fingerprint, + BOOL host_mismatch) { #if 0 DWORD mode; @@ -550,9 +549,9 @@ static DWORD wf_verify_certificate(freerdp* instance, WLog_INFO(TAG, "\tThumbprint: %s", fingerprint); WLog_INFO(TAG, "\tHostMismatch: %s", host_mismatch ? "Yes" : "No"); WLog_INFO(TAG, - "The above X.509 certificate could not be verified, possibly because you do not have " - "the CA certificate in your certificate store, or the certificate has expired. " - "Please look at the documentation on how to create local certificate store for a private CA."); + "The above X.509 certificate could not be verified, possibly because you do not have " + "the CA certificate in your certificate store, or the certificate has expired. " + "Please look at the documentation on how to create local certificate store for a private CA."); /* TODO: ask for user validation */ #if 0 input_handle = GetStdHandle(STD_INPUT_HANDLE); @@ -566,11 +565,11 @@ static DWORD wf_verify_certificate(freerdp* instance, } static DWORD wf_verify_changed_certificate(freerdp* instance, - const char* common_name, - const char* subject, const char* issuer, - const char* fingerprint, - const char* old_subject, const char* old_issuer, - const char* old_fingerprint) + const char* common_name, + const char* subject, const char* issuer, + const char* fingerprint, + const char* old_subject, const char* old_issuer, + const char* old_fingerprint) { WLog_ERR(TAG, "!!! Certificate has changed !!!"); WLog_ERR(TAG, "New Certificate details:"); @@ -582,9 +581,9 @@ static DWORD wf_verify_changed_certificate(freerdp* instance, WLog_ERR(TAG, "\tIssuer: %s", old_issuer); WLog_ERR(TAG, "\tThumbprint: %s", old_fingerprint); WLog_ERR(TAG, - "The above X.509 certificate does not match the certificate used for previous connections. " - "This may indicate that the certificate has been tampered with." - "Please contact the administrator of the RDP server and clarify."); + "The above X.509 certificate does not match the certificate used for previous connections. " + "This may indicate that the certificate has been tampered with." + "Please contact the administrator of the RDP server and clarify."); return 0; } @@ -645,7 +644,7 @@ static void* wf_input_thread(void* arg) while (MessageQueue_Peek(queue, &message, TRUE)) { status = freerdp_message_queue_process_message(instance, - FREERDP_INPUT_MESSAGE_QUEUE, &message); + FREERDP_INPUT_MESSAGE_QUEUE, &message); if (!status) break; @@ -691,8 +690,8 @@ static DWORD WINAPI wf_client_thread(LPVOID lpParam) if (async_input) { if (!(input_thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) wf_input_thread, - instance, 0, NULL))) + (LPTHREAD_START_ROUTINE) wf_input_thread, + instance, 0, NULL))) { WLog_ERR(TAG, "Failed to create async input thread."); goto disconnect; @@ -723,10 +722,10 @@ static DWORD WINAPI wf_client_thread(LPVOID lpParam) } if (MsgWaitForMultipleObjects(nCount, handles, FALSE, 1000, - QS_ALLINPUT) == WAIT_FAILED) + QS_ALLINPUT) == WAIT_FAILED) { WLog_ERR(TAG, "wfreerdp_run: WaitForMultipleObjects failed: 0x%04X", - GetLastError()); + GetLastError()); break; } @@ -814,7 +813,7 @@ static DWORD WINAPI wf_keyboard_thread(LPVOID lpParam) wfc = (wfContext*) lpParam; assert(NULL != wfc); hook_handle = SetWindowsHookEx(WH_KEYBOARD_LL, wf_ll_kbd_proc, wfc->hInstance, - 0); + 0); if (hook_handle) { @@ -868,14 +867,14 @@ static int freerdp_client_set_window_size(wfContext* wfc, int width, int height) if ((width != wfc->client_width) || (height != wfc->client_height)) { PostThreadMessage(wfc->mainThreadId, WM_SIZE, SIZE_RESTORED, - ((UINT) height << 16) | (UINT) width); + ((UINT) height << 16) | (UINT) width); } return 0; } void wf_size_scrollbars(wfContext* wfc, UINT32 client_width, - UINT32 client_height) + UINT32 client_height) { if (wfc->disablewindowtracking) return; @@ -908,8 +907,8 @@ void wf_size_scrollbars(wfContext* wfc, UINT32 client_width, horiz = TRUE; } else if (horiz - && client_width >= - wfc->context.settings->DesktopWidth/* - GetSystemMetrics(SM_CXVSCROLL)*/) + && client_width >= + wfc->context.settings->DesktopWidth/* - GetSystemMetrics(SM_CXVSCROLL)*/) { horiz = FALSE; } @@ -919,14 +918,14 @@ void wf_size_scrollbars(wfContext* wfc, UINT32 client_width, vert = TRUE; } else if (vert - && client_height >= - wfc->context.settings->DesktopHeight/* - GetSystemMetrics(SM_CYHSCROLL)*/) + && client_height >= + wfc->context.settings->DesktopHeight/* - GetSystemMetrics(SM_CYHSCROLL)*/) { vert = FALSE; } if (horiz == vert && (horiz != wfc->xScrollVisible - && vert != wfc->yScrollVisible)) + && vert != wfc->yScrollVisible)) { if (ShowScrollBar(wfc->hwnd, SB_BOTH, horiz)) { @@ -973,7 +972,7 @@ void wf_size_scrollbars(wfContext* wfc, UINT32 client_width, // (bitmap_height) - (client_height). The current vertical // scroll value remains within the vertical scrolling range. wfc->yMaxScroll = MAX(wfc->context.settings->DesktopHeight - client_height, - 0); + 0); wfc->yCurrentScroll = MIN(wfc->yCurrentScroll, wfc->yMaxScroll); si.cbSize = sizeof(si); si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; @@ -1019,7 +1018,7 @@ static BOOL wfreerdp_client_new(freerdp* instance, rdpContext* context) if (!(wfreerdp_client_global_init())) return FALSE; - if (!(context->channels = freerdp_channels_new())) + if (!(context->channels = freerdp_channels_new(instance))) return FALSE; instance->PreConnect = wf_pre_connect; @@ -1028,7 +1027,6 @@ static BOOL wfreerdp_client_new(freerdp* instance, rdpContext* context) instance->GatewayAuthenticate = wf_gw_authenticate; instance->VerifyCertificate = wf_verify_certificate; instance->VerifyChangedCertificate = wf_verify_changed_certificate; - return TRUE; } @@ -1073,7 +1071,7 @@ static int wfreerdp_client_start(rdpContext* context) wfc->wndClass.hIconSm = wfc->icon; RegisterClassEx(&(wfc->wndClass)); wfc->keyboardThread = CreateThread(NULL, 0, wf_keyboard_thread, (void*) wfc, 0, - &wfc->keyboardThreadId); + &wfc->keyboardThreadId); if (!wfc->keyboardThread) return -1; @@ -1082,7 +1080,7 @@ static int wfreerdp_client_start(rdpContext* context) return -1; wfc->thread = CreateThread(NULL, 0, wf_client_thread, (void*) instance, 0, - &wfc->mainThreadId); + &wfc->mainThreadId); if (!wfc->thread) return -1; diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index aa63b41..b869afb 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -1758,7 +1758,7 @@ static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context) assert(!xfc->mutex); assert(!xfc->x11event); - if (!(context->channels = freerdp_channels_new())) + if (!(context->channels = freerdp_channels_new(instance))) goto fail_channels_new; instance->PreConnect = xf_pre_connect; diff --git a/client/iOS/FreeRDP/ios_freerdp.m b/client/iOS/FreeRDP/ios_freerdp.m index f9e4024..0f1cec8 100644 --- a/client/iOS/FreeRDP/ios_freerdp.m +++ b/client/iOS/FreeRDP/ios_freerdp.m @@ -435,7 +435,7 @@ static BOOL ios_client_new(freerdp* instance, rdpContext* context) if (!instance || !context) return FALSE; - if (!(context->channels = freerdp_channels_new())) + if (!(context->channels = freerdp_channels_new(instance))) return FALSE; if ((ctx->mfi = calloc(1, sizeof(mfInfo))) == NULL) diff --git a/include/freerdp/channels/channels.h b/include/freerdp/channels/channels.h index 816afbb..31c86e6 100644 --- a/include/freerdp/channels/channels.h +++ b/include/freerdp/channels/channels.h @@ -32,27 +32,36 @@ extern "C" { #endif -FREERDP_API rdpChannels* freerdp_channels_new(void); +FREERDP_API rdpChannels* freerdp_channels_new(freerdp* instance); FREERDP_API void freerdp_channels_free(rdpChannels* channels); -FREERDP_API int freerdp_channels_client_load(rdpChannels* channels, rdpSettings* settings, - PVIRTUALCHANNELENTRY entry, void* data); -FREERDP_API int freerdp_channels_load_plugin(rdpChannels* channels, rdpSettings* settings, - const char* name, void* data); -FREERDP_API UINT freerdp_channels_pre_connect(rdpChannels* channels, freerdp* instance); -FREERDP_API UINT freerdp_channels_post_connect(rdpChannels* channels, freerdp* instance); -FREERDP_API UINT freerdp_channels_disconnect(rdpChannels* channels, freerdp* instance); -FREERDP_API BOOL freerdp_channels_get_fds(rdpChannels* channels, freerdp* instance, void** read_fds, - int* read_count, void** write_fds, int* write_count); -FREERDP_API BOOL freerdp_channels_check_fds(rdpChannels* channels, freerdp* instance); -FREERDP_API void freerdp_channels_close(rdpChannels* channels, freerdp* instance); - -FREERDP_API void* freerdp_channels_get_static_channel_interface(rdpChannels* channels, const char* name); +FREERDP_API int freerdp_channels_client_load(rdpChannels* channels, + rdpSettings* settings, + PVIRTUALCHANNELENTRY entry, void* data); +FREERDP_API int freerdp_channels_load_plugin(rdpChannels* channels, + rdpSettings* settings, + const char* name, void* data); +FREERDP_API UINT freerdp_channels_pre_connect(rdpChannels* channels, + freerdp* instance); +FREERDP_API UINT freerdp_channels_post_connect(rdpChannels* channels, + freerdp* instance); +FREERDP_API UINT freerdp_channels_disconnect(rdpChannels* channels, + freerdp* instance); +FREERDP_API BOOL freerdp_channels_get_fds(rdpChannels* channels, + freerdp* instance, void** read_fds, + int* read_count, void** write_fds, int* write_count); +FREERDP_API BOOL freerdp_channels_check_fds(rdpChannels* channels, + freerdp* instance); +FREERDP_API void freerdp_channels_close(rdpChannels* channels, + freerdp* instance); + +FREERDP_API void* freerdp_channels_get_static_channel_interface( + rdpChannels* channels, const char* name); FREERDP_API HANDLE freerdp_channels_get_event_handle(freerdp* instance); FREERDP_API int freerdp_channels_process_pending_messages(freerdp* instance); FREERDP_API int freerdp_channels_data(freerdp* instance, - UINT16 channelId, BYTE* data, int dataSize, int flags, int totalSize); + UINT16 channelId, BYTE* data, int dataSize, int flags, int totalSize); FREERDP_API PWtsApiFunctionTable FreeRDP_InitWtsApi(void); diff --git a/include/freerdp/freerdp.h b/include/freerdp/freerdp.h index 22b2b35..f06c177 100644 --- a/include/freerdp/freerdp.h +++ b/include/freerdp/freerdp.h @@ -66,7 +66,7 @@ typedef BOOL (*pPreConnect)(freerdp* instance); typedef BOOL (*pPostConnect)(freerdp* instance); typedef void (*pPostDisconnect)(freerdp* instance); typedef BOOL (*pAuthenticate)(freerdp* instance, char** username, - char** password, char** domain); + char** password, char** domain); /** @brief Callback used if user interaction is required to accept * an unknown certificate. @@ -82,11 +82,11 @@ typedef BOOL (*pAuthenticate)(freerdp* instance, char** username, * a certificate only for this session, 0 otherwise. */ typedef DWORD (*pVerifyCertificate)(freerdp* instance, - const char* common_name, - const char* subject, - const char* issuer, - const char* fingerprint, - BOOL host_mismatch); + const char* common_name, + const char* subject, + const char* issuer, + const char* fingerprint, + BOOL host_mismatch); /** @brief Callback used if user interaction is required to accept * a changed certificate. @@ -104,21 +104,23 @@ typedef DWORD (*pVerifyCertificate)(freerdp* instance, */ typedef DWORD (*pVerifyChangedCertificate)(freerdp* instance, - const char* common_name, - const char* subject, - const char* issuer, - const char* new_fingerprint, - const char* old_subject, - const char* old_issuer, - const char* old_fingerprint); + const char* common_name, + const char* subject, + const char* issuer, + const char* new_fingerprint, + const char* old_subject, + const char* old_issuer, + const char* old_fingerprint); typedef int (*pVerifyX509Certificate)(freerdp* instance, BYTE* data, - int length, const char* hostname, - int port, DWORD flags); + int length, const char* hostname, + int port, DWORD flags); typedef int (*pLogonErrorInfo)(freerdp* instance, UINT32 data, UINT32 type); -typedef int (*pSendChannelData)(freerdp* instance, UINT16 channelId, BYTE* data, int size); -typedef int (*pReceiveChannelData)(freerdp* instance, UINT16 channelId, BYTE* data, int size, int flags, int totalSize); +typedef int (*pSendChannelData)(freerdp* instance, UINT16 channelId, BYTE* data, + int size); +typedef int (*pReceiveChannelData)(freerdp* instance, UINT16 channelId, + BYTE* data, int size, int flags, int totalSize); /** * Defines the context for a given instance of RDP connection. @@ -261,9 +263,11 @@ struct rdp_freerdp Used when a certificate differs from stored fingerprint. If returns TRUE, the new fingerprint will be trusted and old thrown out. */ - ALIGN64 pVerifyX509Certificate VerifyX509Certificate; /**< (offset 53) Callback for X509 certificate verification (PEM format) */ + ALIGN64 pVerifyX509Certificate + VerifyX509Certificate; /**< (offset 53) Callback for X509 certificate verification (PEM format) */ - ALIGN64 pLogonErrorInfo LogonErrorInfo; /**< (offset 54) Callback for logon error info, important for logon system messages with RemoteApp */ + ALIGN64 pLogonErrorInfo + LogonErrorInfo; /**< (offset 54) Callback for logon error info, important for logon system messages with RemoteApp */ ALIGN64 pPostDisconnect PostDisconnect; /**< (offset 55) Callback for cleaning up resources allocated @@ -296,16 +300,27 @@ FREERDP_API BOOL freerdp_shall_disconnect(freerdp* instance); FREERDP_API BOOL freerdp_disconnect(freerdp* instance); FREERDP_API BOOL freerdp_reconnect(freerdp* instance); -FREERDP_API BOOL freerdp_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount); +FREERDP_API void freerdp_channel_init_thread_context(rdpContext* context); +FREERDP_API freerdp* freerdp_channel_get_instance(void); +FREERDP_API rdpContext* freerdp_channel_get_context(void); +FREERDP_API rdpChannels* freerdp_channel_get_channels_context(void); + +FREERDP_API BOOL freerdp_get_fds(freerdp* instance, void** rfds, int* rcount, + void** wfds, int* wcount); FREERDP_API BOOL freerdp_check_fds(freerdp* instance); -FREERDP_API DWORD freerdp_get_event_handles(rdpContext* context, HANDLE* events, DWORD count); +FREERDP_API DWORD freerdp_get_event_handles(rdpContext* context, HANDLE* events, + DWORD count); FREERDP_API BOOL freerdp_check_event_handles(rdpContext* context); -FREERDP_API wMessageQueue* freerdp_get_message_queue(freerdp* instance, DWORD id); -FREERDP_API HANDLE freerdp_get_message_queue_event_handle(freerdp* instance, DWORD id); -FREERDP_API int freerdp_message_queue_process_message(freerdp* instance, DWORD id, wMessage* message); -FREERDP_API int freerdp_message_queue_process_pending_messages(freerdp* instance, DWORD id); +FREERDP_API wMessageQueue* freerdp_get_message_queue(freerdp* instance, + DWORD id); +FREERDP_API HANDLE freerdp_get_message_queue_event_handle(freerdp* instance, + DWORD id); +FREERDP_API int freerdp_message_queue_process_message(freerdp* instance, + DWORD id, wMessage* message); +FREERDP_API int freerdp_message_queue_process_pending_messages( + freerdp* instance, DWORD id); FREERDP_API UINT32 freerdp_error_info(freerdp* instance); FREERDP_API void freerdp_set_error_info(rdpRdp* rdp, UINT32 error); @@ -327,13 +342,15 @@ FREERDP_API const char* freerdp_get_last_error_name(UINT32 error); FREERDP_API const char* freerdp_get_last_error_string(UINT32 error); FREERDP_API void freerdp_set_last_error(rdpContext* context, UINT32 lastError); -FREERDP_API ULONG freerdp_get_transport_sent(rdpContext* context, BOOL resetCount); +FREERDP_API ULONG freerdp_get_transport_sent(rdpContext* context, + BOOL resetCount); FREERDP_API void clearChannelError(rdpContext* context); FREERDP_API HANDLE getChannelErrorEventHandle(rdpContext* context); FREERDP_API UINT getChannelError(rdpContext* context); FREERDP_API const char* getChannelErrorDescription(rdpContext* context); -FREERDP_API void setChannelError(rdpContext* context, UINT errorNum, char* description); +FREERDP_API void setChannelError(rdpContext* context, UINT errorNum, + char* description); FREERDP_API BOOL checkChannelErrorEvent(rdpContext* context); #ifdef __cplusplus diff --git a/libfreerdp/core/client.c b/libfreerdp/core/client.c index 4e3bcb0..ea53fc6 100644 --- a/libfreerdp/core/client.c +++ b/libfreerdp/core/client.c @@ -31,18 +31,9 @@ #define TAG FREERDP_TAG("core.client") -static void* g_pInterface = NULL; -static CHANNEL_INIT_DATA g_ChannelInitData; +static WINPR_TLS void* g_pInterface = NULL; -static wHashTable* g_OpenHandles = NULL; - -/* To generate unique sequence for all open handles */ -int g_open_handle_sequence = 1; - -/* For locking the global resources */ -static CRITICAL_SECTION g_channels_lock; - -CHANNEL_OPEN_DATA* freerdp_channels_find_channel_open_data_by_name( +static CHANNEL_OPEN_DATA* freerdp_channels_find_channel_open_data_by_name( rdpChannels* channels, const char* name) { int index; @@ -60,7 +51,7 @@ CHANNEL_OPEN_DATA* freerdp_channels_find_channel_open_data_by_name( } /* returns rdpChannel for the channel name passed in */ -rdpMcsChannel* freerdp_channels_find_channel_by_name(rdpRdp* rdp, +static rdpMcsChannel* freerdp_channels_find_channel_by_name(rdpRdp* rdp, const char* name) { UINT32 index; @@ -80,7 +71,7 @@ rdpMcsChannel* freerdp_channels_find_channel_by_name(rdpRdp* rdp, return NULL; } -rdpChannels* freerdp_channels_new(void) +rdpChannels* freerdp_channels_new(freerdp* instance) { rdpChannels* channels; channels = (rdpChannels*) calloc(1, sizeof(rdpChannels)); @@ -88,40 +79,37 @@ rdpChannels* freerdp_channels_new(void) if (!channels) return NULL; + if (!InitializeCriticalSectionAndSpinCount(&channels->channelsLock, 4000)) + goto error; + + channels->instance = instance; + channels->openHandleSeq = 1; channels->queue = MessageQueue_New(NULL); if (!channels->queue) - goto error_queue; - - if (!g_OpenHandles) - { - g_OpenHandles = HashTable_New(TRUE); + goto error; - if (!g_OpenHandles) - goto error_open_handles; + channels->openHandles = HashTable_New(TRUE); - if (!InitializeCriticalSectionAndSpinCount(&g_channels_lock, 4000)) - goto error_open_handles; - } + if (!channels->openHandles) + goto error; return channels; -error_open_handles: - MessageQueue_Free(channels->queue); -error_queue: - free(channels); +error: + freerdp_channels_free(channels); return NULL; } void freerdp_channels_free(rdpChannels* channels) { int index; - int nkeys; - ULONG_PTR* pKeys = NULL; CHANNEL_OPEN_DATA* pChannelOpenData; if (!channels) return; + DeleteCriticalSection(&channels->channelsLock); + if (channels->queue) { MessageQueue_Free(channels->queue); @@ -138,22 +126,13 @@ void freerdp_channels_free(rdpChannels* channels) pChannelOpenData->pInterface = NULL; } - HashTable_Remove(g_OpenHandles, (void*)(UINT_PTR)pChannelOpenData->OpenHandle); + if (channels->openHandles) + HashTable_Remove(channels->openHandles, + (void*)(UINT_PTR)pChannelOpenData->OpenHandle); } - if (g_OpenHandles) - { - nkeys = HashTable_GetKeys(g_OpenHandles, &pKeys); - - if (nkeys == 0) - { - HashTable_Free(g_OpenHandles); - DeleteCriticalSection(&g_channels_lock); - g_OpenHandles = NULL; - } - - free(pKeys); - } + if (channels->openHandles) + HashTable_Free(channels->openHandles); free(channels); } @@ -163,7 +142,7 @@ void freerdp_channels_free(rdpChannels* channels) * * @return 0 on success, otherwise a Win32 error code */ -UINT freerdp_drdynvc_on_channel_connected(DrdynvcClientContext* context, +static UINT freerdp_drdynvc_on_channel_connected(DrdynvcClientContext* context, const char* name, void* pInterface) { UINT status = CHANNEL_RC_OK; @@ -182,7 +161,8 @@ UINT freerdp_drdynvc_on_channel_connected(DrdynvcClientContext* context, * * @return 0 on success, otherwise a Win32 error code */ -UINT freerdp_drdynvc_on_channel_disconnected(DrdynvcClientContext* context, +static UINT freerdp_drdynvc_on_channel_disconnected(DrdynvcClientContext* + context, const char* name, void* pInterface) { UINT status = CHANNEL_RC_OK; @@ -205,7 +185,6 @@ UINT freerdp_channels_pre_connect(rdpChannels* channels, freerdp* instance) UINT error = CHANNEL_RC_OK; int index; CHANNEL_CLIENT_DATA* pChannelClientData; - channels->instance = instance; for (index = 0; index < channels->clientDataCount; index++) { @@ -522,7 +501,7 @@ void freerdp_channels_close(rdpChannels* channels, freerdp* instance) MessageQueue_PostQuit(channels->queue, 0); } -UINT VCAPITYPE FreeRDP_VirtualChannelInit(LPVOID* ppInitHandle, +static UINT VCAPITYPE FreeRDP_VirtualChannelInit(LPVOID* ppInitHandle, PCHANNEL_DEF pChannel, INT channelCount, ULONG versionRequested, PCHANNEL_INIT_EVENT_FN pChannelInitEventProc) @@ -531,20 +510,19 @@ UINT VCAPITYPE FreeRDP_VirtualChannelInit(LPVOID* ppInitHandle, void* pInterface; DWORD OpenHandle; CHANNEL_DEF* channel; - rdpChannels* channels; + rdpChannels* channels = freerdp_channel_get_channels_context(); rdpSettings* settings; PCHANNEL_DEF pChannelDef; CHANNEL_INIT_DATA* pChannelInitData; CHANNEL_OPEN_DATA* pChannelOpenData; CHANNEL_CLIENT_DATA* pChannelClientData; - if (!ppInitHandle) + if (!ppInitHandle || !channels) return CHANNEL_RC_BAD_INIT_HANDLE; if (!pChannel || (channelCount <= 0) || !pChannelInitEventProc) return CHANNEL_RC_INITIALIZATION_ERROR; - channels = g_ChannelInitData.channels; pInterface = g_pInterface; pChannelInitData = &(channels->initDataList[channels->initDataCount]); *ppInitHandle = pChannelInitData; @@ -583,16 +561,16 @@ UINT VCAPITYPE FreeRDP_VirtualChannelInit(LPVOID* ppInitHandle, pChannelClientData->pChannelInitEventProc = pChannelInitEventProc; pChannelClientData->pInitHandle = *ppInitHandle; channels->clientDataCount++; - settings = channels->settings; + settings = channels->instance->context->settings; for (index = 0; index < channelCount; index++) { pChannelDef = &pChannel[index]; pChannelOpenData = &channels->openDataList[channels->openDataCount]; - OpenHandle = g_open_handle_sequence++; + OpenHandle = channels->openHandleSeq++; pChannelOpenData->OpenHandle = OpenHandle; pChannelOpenData->channels = channels; - HashTable_Add(g_OpenHandles, (void*)(UINT_PTR) OpenHandle, + HashTable_Add(channels->openHandles, (void*)(UINT_PTR) OpenHandle, (void*) pChannelOpenData); pChannelOpenData->flags = 1; /* init */ strncpy(pChannelOpenData->name, pChannelDef->name, CHANNEL_NAME_LEN); @@ -603,7 +581,7 @@ UINT VCAPITYPE FreeRDP_VirtualChannelInit(LPVOID* ppInitHandle, channel = &settings->ChannelDefArray[settings->ChannelCount]; strncpy(channel->name, pChannelDef->name, 7); channel->options = pChannelDef->options; - channels->settings->ChannelCount++; + settings->ChannelCount++; } channels->openDataCount++; @@ -612,7 +590,7 @@ UINT VCAPITYPE FreeRDP_VirtualChannelInit(LPVOID* ppInitHandle, return CHANNEL_RC_OK; } -UINT VCAPITYPE FreeRDP_VirtualChannelOpen(LPVOID pInitHandle, +static UINT VCAPITYPE FreeRDP_VirtualChannelOpen(LPVOID pInitHandle, LPDWORD pOpenHandle, PCHAR pChannelName, PCHANNEL_OPEN_EVENT_FN pChannelOpenEventProc) { @@ -649,10 +627,15 @@ UINT VCAPITYPE FreeRDP_VirtualChannelOpen(LPVOID pInitHandle, return CHANNEL_RC_OK; } -UINT VCAPITYPE FreeRDP_VirtualChannelClose(DWORD openHandle) +static UINT VCAPITYPE FreeRDP_VirtualChannelClose(DWORD openHandle) { + rdpChannels* channels = freerdp_channel_get_channels_context(); CHANNEL_OPEN_DATA* pChannelOpenData; - pChannelOpenData = HashTable_GetItemValue(g_OpenHandles, + + if (!channels) + return CHANNEL_RC_BAD_CHANNEL_HANDLE; + + pChannelOpenData = HashTable_GetItemValue(channels->openHandles, (void*)(UINT_PTR) openHandle); if (!pChannelOpenData) @@ -665,21 +648,21 @@ UINT VCAPITYPE FreeRDP_VirtualChannelClose(DWORD openHandle) return CHANNEL_RC_OK; } -UINT VCAPITYPE FreeRDP_VirtualChannelWrite(DWORD openHandle, LPVOID pData, +static UINT VCAPITYPE FreeRDP_VirtualChannelWrite(DWORD openHandle, + LPVOID pData, ULONG dataLength, LPVOID pUserData) { - rdpChannels* channels; + rdpChannels* channels = freerdp_channel_get_channels_context(); CHANNEL_OPEN_DATA* pChannelOpenData; CHANNEL_OPEN_EVENT* pChannelOpenEvent; - pChannelOpenData = HashTable_GetItemValue(g_OpenHandles, - (void*)(UINT_PTR) openHandle); - if (!pChannelOpenData) + if (!channels) return CHANNEL_RC_BAD_CHANNEL_HANDLE; - channels = pChannelOpenData->channels; + pChannelOpenData = HashTable_GetItemValue(channels->openHandles, + (void*)(UINT_PTR) openHandle); - if (!channels) + if (!pChannelOpenData) return CHANNEL_RC_BAD_CHANNEL_HANDLE; if (!channels->connected) @@ -764,14 +747,11 @@ int freerdp_channels_client_load(rdpChannels* channels, rdpSettings* settings, EntryPoints.context = ((freerdp*)settings->instance)->context; /* enable VirtualChannelInit */ channels->can_call_init = TRUE; - channels->settings = settings; - EnterCriticalSection(&g_channels_lock); + EnterCriticalSection(&channels->channelsLock); g_pInterface = NULL; - g_ChannelInitData.channels = channels; status = pChannelClientData->entry((PCHANNEL_ENTRY_POINTS) &EntryPoints); - LeaveCriticalSection(&g_channels_lock); + LeaveCriticalSection(&channels->channelsLock); /* disable MyVirtualChannelInit */ - channels->settings = NULL; channels->can_call_init = FALSE; if (!status) diff --git a/libfreerdp/core/client.h b/libfreerdp/core/client.h index 7a87c8f..2337b6b 100644 --- a/libfreerdp/core/client.h +++ b/libfreerdp/core/client.h @@ -93,7 +93,6 @@ struct rdp_channels /* control for entry into MyVirtualChannelInit */ int can_call_init; - rdpSettings* settings; /* true once freerdp_channels_post_connect is called */ BOOL connected; @@ -104,6 +103,9 @@ struct rdp_channels wMessageQueue* queue; DrdynvcClientContext* drdynvc; + UINT64 openHandleSeq; + CRITICAL_SECTION channelsLock; + wHashTable* openHandles; }; #endif /* FREERDP_CORE_CLIENT_H */ diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c index 1257660..a5fcc78 100644 --- a/libfreerdp/core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -50,6 +50,37 @@ /* connectErrorCode is 'extern' in error.h. See comment there.*/ +/* Thread local storage variables. + * They need to be initialized in every thread that + * has to use them. */ +static WINPR_TLS rdpContext* s_TLSContext = NULL; + +void freerdp_channel_init_thread_context(rdpContext* context) +{ + s_TLSContext = context; +} + +freerdp* freerdp_channel_get_instance(void) +{ + if (!s_TLSContext) + return NULL; + + return s_TLSContext->instance; +} + +rdpContext* freerdp_channel_get_context(void) +{ + return s_TLSContext; +} + +rdpChannels* freerdp_channel_get_channels_context(void) +{ + if (!s_TLSContext) + return NULL; + + return s_TLSContext->channels; +} + /** Creates a new connection based on the settings found in the "instance" parameter * It will use the callbacks registered on the structure to process the pre/post connect operations * that the caller requires. @@ -68,15 +99,17 @@ BOOL freerdp_connect(freerdp* instance) rdpSettings* settings; ConnectionResultEventArgs e; + if (!instance) + return FALSE; + + freerdp_channel_init_thread_context(instance->context); /* We always set the return code to 0 before we start the connect sequence*/ connectErrorCode = 0; freerdp_set_last_error(instance->context, FREERDP_ERROR_SUCCESS); clearChannelError(instance->context); ResetEvent(instance->context->abortEvent); - rdp = instance->context->rdp; settings = instance->settings; - instance->context->codecs = codecs_new(instance->context); IFCALLRET(instance->PreConnect, status, instance); @@ -112,7 +145,9 @@ BOOL freerdp_connect(freerdp* instance) { if (instance->settings->DumpRemoteFx) { - instance->update->pcap_rfx = pcap_open(instance->settings->DumpRemoteFxFile, TRUE); + instance->update->pcap_rfx = pcap_open(instance->settings->DumpRemoteFxFile, + TRUE); + if (instance->update->pcap_rfx) instance->update->dump_rfx = TRUE; } @@ -135,9 +170,7 @@ BOOL freerdp_connect(freerdp* instance) wStream* s; rdpUpdate* update; pcap_record record; - update = instance->update; - update->pcap_rfx = pcap_open(settings->PlayRemoteFxFile, FALSE); if (!update->pcap_rfx) @@ -152,18 +185,15 @@ BOOL freerdp_connect(freerdp* instance) while (pcap_has_next_record(update->pcap_rfx)) { - pcap_get_next_record_header(update->pcap_rfx, &record); if (!(s = StreamPool_Take(rdp->transport->ReceivePool, record.length))) break; record.data = Stream_Buffer(s); - pcap_get_next_record_content(update->pcap_rfx, &record); - Stream_SetLength(s,record.length); + Stream_SetLength(s, record.length); Stream_SetPosition(s, 0); - update->BeginPaint(update->context); update_recv_surfcmds(update, Stream_Length(s) , s); update->EndPaint(update->context); @@ -178,14 +208,14 @@ BOOL freerdp_connect(freerdp* instance) } if (rdp->errorInfo == ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES) - freerdp_set_last_error(instance->context, FREERDP_ERROR_INSUFFICIENT_PRIVILEGES); + freerdp_set_last_error(instance->context, + FREERDP_ERROR_INSUFFICIENT_PRIVILEGES); SetEvent(rdp->transport->connectedEvent); freerdp_connect_finally: EventArgsInit(&e, "freerdp"); e.result = status ? 0 : -1; PubSub_OnConnectionResult(instance->context->pubSub, instance->context, &e); - return status; } @@ -197,7 +227,8 @@ BOOL freerdp_abort_connect(freerdp* instance) return SetEvent(instance->context->abortEvent); } -BOOL freerdp_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount) +BOOL freerdp_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, + int* wcount) { rdpRdp* rdp = instance->context->rdp; transport_get_fds(rdp->transport, rfds, rcount); @@ -219,29 +250,26 @@ BOOL freerdp_check_fds(freerdp* instance) return FALSE; rdp = instance->context->rdp; - status = rdp_check_fds(rdp); if (status < 0) { TerminateEventArgs e; rdpContext* context = instance->context; - WLog_DBG(TAG, "rdp_check_fds() - %i", status); EventArgsInit(&e, "freerdp"); e.code = 0; PubSub_OnTerminate(context->pubSub, context, &e); - return FALSE; } return TRUE; } -DWORD freerdp_get_event_handles(rdpContext* context, HANDLE* events, DWORD count) +DWORD freerdp_get_event_handles(rdpContext* context, HANDLE* events, + DWORD count) { DWORD nCount = 0; - nCount += transport_get_event_handles(context->rdp->transport, events, count); if (nCount == 0) @@ -261,7 +289,6 @@ DWORD freerdp_get_event_handles(rdpContext* context, HANDLE* events, DWORD count BOOL freerdp_check_event_handles(rdpContext* context) { BOOL status; - status = freerdp_check_fds(context->instance); if (!status) @@ -271,6 +298,7 @@ BOOL freerdp_check_event_handles(rdpContext* context) } status = freerdp_channels_check_fds(context->channels, context->instance); + if (!status) { WLog_ERR(TAG, "freerdp_channels_check_fds() failed - %i", status); @@ -281,7 +309,6 @@ BOOL freerdp_check_event_handles(rdpContext* context) return FALSE; status = checkChannelErrorEvent(context); - return status; } @@ -307,7 +334,6 @@ HANDLE freerdp_get_message_queue_event_handle(freerdp* instance, DWORD id) { HANDLE event = NULL; wMessageQueue* queue = NULL; - queue = freerdp_get_message_queue(instance, id); if (queue) @@ -316,7 +342,8 @@ HANDLE freerdp_get_message_queue_event_handle(freerdp* instance, DWORD id) return event; } -int freerdp_message_queue_process_message(freerdp* instance, DWORD id, wMessage* message) +int freerdp_message_queue_process_message(freerdp* instance, DWORD id, + wMessage* message) { int status = -1; @@ -352,7 +379,8 @@ int freerdp_message_queue_process_pending_messages(freerdp* instance, DWORD id) return status; } -static int freerdp_send_channel_data(freerdp* instance, UINT16 channelId, BYTE* data, int size) +static int freerdp_send_channel_data(freerdp* instance, UINT16 channelId, + BYTE* data, int size) { return rdp_send_channel_data(instance->context->rdp, channelId, data, size); } @@ -360,12 +388,9 @@ static int freerdp_send_channel_data(freerdp* instance, UINT16 channelId, BYTE* BOOL freerdp_disconnect(freerdp* instance) { rdpRdp* rdp; - rdp = instance->context->rdp; - rdp_client_disconnect(rdp); update_post_disconnect(instance->update); - IFCALL(instance->PostDisconnect, instance); if (instance->update->pcap_rfx) @@ -383,10 +408,8 @@ BOOL freerdp_reconnect(freerdp* instance) { BOOL status; rdpRdp* rdp = instance->context->rdp; - ResetEvent(instance->context->abortEvent); status = rdp_client_reconnect(rdp); - return status; } @@ -394,8 +417,10 @@ BOOL freerdp_shall_disconnect(freerdp* instance) { if (!instance || !instance->context) return FALSE; + if (WaitForSingleObject(instance->context->abortEvent, 0) != WAIT_OBJECT_0) return FALSE; + return TRUE; } @@ -403,7 +428,6 @@ BOOL freerdp_focus_required(freerdp* instance) { rdpRdp* rdp; BOOL bRetCode = FALSE; - rdp = instance->context->rdp; if (rdp->resendFocus) @@ -418,7 +442,6 @@ BOOL freerdp_focus_required(freerdp* instance) void freerdp_set_focus(freerdp* instance) { rdpRdp* rdp; - rdp = instance->context->rdp; rdp->resendFocus = TRUE; } @@ -443,19 +466,17 @@ const char* freerdp_get_version_string(void) const char* freerdp_get_build_date(void) { static char build_date[] = __DATE__ " " __TIME__; - return build_date; } const char* freerdp_get_build_config(void) { static const char build_config[] = - "Build configuration: " BUILD_CONFIG "\n" - "Build type: " BUILD_TYPE "\n" - "CFLAGS: " CFLAGS "\n" - "Compiler: " COMPILER_ID ", " COMPILER_VERSION "\n" - "Target architecture: " TARGET_ARCH "\n"; - + "Build configuration: " BUILD_CONFIG "\n" + "Build type: " BUILD_TYPE "\n" + "CFLAGS: " CFLAGS "\n" + "Compiler: " COMPILER_ID ", " COMPILER_VERSION "\n" + "Target architecture: " TARGET_ARCH "\n"; return build_config; } @@ -493,27 +514,29 @@ BOOL freerdp_context_new(freerdp* instance) rdpRdp* rdp; rdpContext* context; BOOL ret = TRUE; - instance->context = (rdpContext*) calloc(1, instance->ContextSize); + if (!instance->context) return FALSE; context = instance->context; context->instance = instance; - context->ServerMode = FALSE; context->settings = instance->settings; - context->pubSub = PubSub_New(TRUE); - if(!context->pubSub) + + if (!context->pubSub) goto out_error_pubsub; - PubSub_AddEventTypes(context->pubSub, FreeRDP_Events, sizeof(FreeRDP_Events) / sizeof(wEventType)); + PubSub_AddEventTypes(context->pubSub, FreeRDP_Events, + sizeof(FreeRDP_Events) / sizeof(wEventType)); context->metrics = metrics_new(context); + if (!context->metrics) goto out_error_metrics_new; rdp = rdp_new(context); + if (!rdp) goto out_error_rdp_new; @@ -521,26 +544,22 @@ BOOL freerdp_context_new(freerdp* instance) instance->update = rdp->update; instance->settings = rdp->settings; instance->autodetect = rdp->autodetect; - context->graphics = graphics_new(context); - if(!context->graphics) + + if (!context->graphics) goto out_error_graphics_new; context->rdp = rdp; - context->input = instance->input; context->update = instance->update; context->settings = instance->settings; context->autodetect = instance->autodetect; - instance->update->context = instance->context; instance->update->pointer->context = instance->context; instance->update->primary->context = instance->context; instance->update->secondary->context = instance->context; instance->update->altsec->context = instance->context; - instance->input->context = context; - instance->autodetect->context = context; if (!(context->errorDescription = calloc(1, 500))) @@ -556,8 +575,8 @@ BOOL freerdp_context_new(freerdp* instance) } update_register_client_callbacks(rdp->update); - instance->context->abortEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!instance->context->abortEvent) goto out_error_abort_event; @@ -601,26 +620,18 @@ void freerdp_context_free(freerdp* instance) return; IFCALL(instance->ContextFree, instance, instance->context); - rdp_free(instance->context->rdp); instance->context->rdp = NULL; - graphics_free(instance->context->graphics); instance->context->graphics = NULL; - PubSub_Free(instance->context->pubSub); - metrics_free(instance->context->metrics); - CloseHandle(instance->context->channelErrorEvent); free(instance->context->errorDescription); - CloseHandle(instance->context->abortEvent); instance->context->abortEvent = NULL; - free(instance->context); instance->context = NULL; - } UINT32 freerdp_error_info(freerdp* instance) @@ -643,21 +654,24 @@ UINT32 freerdp_get_last_error(rdpContext* context) const char* freerdp_get_last_error_name(UINT32 code) { - const char *name = NULL; + const char* name = NULL; const UINT32 cls = GET_FREERDP_ERROR_CLASS(code); const UINT32 type = GET_FREERDP_ERROR_TYPE(code); - switch(cls) + switch (cls) { case FREERDP_ERROR_ERRBASE_CLASS: name = freerdp_get_error_base_name(type); break; + case FREERDP_ERROR_ERRINFO_CLASS: name = freerdp_get_error_info_name(type); break; + case FREERDP_ERROR_CONNECT_CLASS: name = freerdp_get_error_connect_name(type); break; + default: name = "Unknown error class"; break; @@ -672,17 +686,20 @@ const char* freerdp_get_last_error_string(UINT32 code) const UINT32 cls = GET_FREERDP_ERROR_CLASS(code); const UINT32 type = GET_FREERDP_ERROR_TYPE(code); - switch(cls) + switch (cls) { case FREERDP_ERROR_ERRBASE_CLASS: string = freerdp_get_error_base_string(type); break; + case FREERDP_ERROR_ERRINFO_CLASS: string = freerdp_get_error_info_string(type); break; + case FREERDP_ERROR_CONNECT_CLASS: string = freerdp_get_error_connect_string(type); break; + default: string = "Unknown error class"; break; @@ -695,7 +712,7 @@ void freerdp_set_last_error(rdpContext* context, UINT32 lastError) { if (lastError) WLog_ERR(TAG, "freerdp_set_last_error %s [0x%04X]", - freerdp_get_last_error_name(lastError), lastError); + freerdp_get_last_error_name(lastError), lastError); context->LastError = lastError; @@ -761,7 +778,6 @@ void freerdp_set_last_error(rdpContext* context, UINT32 lastError) freerdp* freerdp_new() { freerdp* instance; - instance = (freerdp*) calloc(1, sizeof(freerdp)); if (!instance) @@ -770,7 +786,6 @@ freerdp* freerdp_new() instance->ContextSize = sizeof(rdpContext); instance->SendChannelData = freerdp_send_channel_data; instance->ReceiveChannelData = freerdp_channels_data; - return instance; } @@ -783,10 +798,13 @@ void freerdp_free(freerdp* instance) free(instance); } -ULONG freerdp_get_transport_sent(rdpContext* context, BOOL resetCount) { +ULONG freerdp_get_transport_sent(rdpContext* context, BOOL resetCount) +{ ULONG written = context->rdp->transport->written; + if (resetCount) context->rdp->transport->written = 0; + return written; } @@ -797,11 +815,13 @@ HANDLE getChannelErrorEventHandle(rdpContext* context) BOOL checkChannelErrorEvent(rdpContext* context) { - if (WaitForSingleObject( context->channelErrorEvent, 0) == WAIT_OBJECT_0) + if (WaitForSingleObject(context->channelErrorEvent, 0) == WAIT_OBJECT_0) { - WLog_ERR(TAG, "%s. Error was %lu", context->errorDescription, context->channelErrorNum); + WLog_ERR(TAG, "%s. Error was %lu", context->errorDescription, + context->channelErrorNum); return FALSE; } + return TRUE; } diff --git a/winpr/include/winpr/winpr.h b/winpr/include/winpr/winpr.h index 4e92509..67a1ed7 100644 --- a/winpr/include/winpr/winpr.h +++ b/winpr/include/winpr/winpr.h @@ -20,26 +20,38 @@ #define WINPR_H #if defined _WIN32 || defined __CYGWIN__ - #ifdef WINPR_EXPORTS - #ifdef __GNUC__ - #define WINPR_API __attribute__((dllexport)) - #else - #define WINPR_API __declspec(dllexport) - #endif - #else - #ifdef __GNUC__ - #define WINPR_API __attribute__((dllimport)) - #else - #define WINPR_API __declspec(dllimport) - #endif - #endif -#else - #if __GNUC__ >= 4 - #define WINPR_API __attribute__ ((visibility("default"))) - #else - #define WINPR_API - #endif +#ifdef WINPR_EXPORTS +#ifdef __GNUC__ +#define WINPR_API __attribute__((dllexport)) +#else +#define WINPR_API __declspec(dllexport) +#endif +#else +#ifdef __GNUC__ +#define WINPR_API __attribute__((dllimport)) +#else +#define WINPR_API __declspec(dllimport) +#endif +#endif +#else +#if __GNUC__ >= 4 +#define WINPR_API __attribute__ ((visibility("default"))) +#else +#define WINPR_API #endif +#endif + +/* Thread local storage keyword define */ +#if defined _WIN32 || defined __CYGWIN__ +#ifdef __GNUC__ +#define WINPR_TLS __thread +#else +#define WINPR_TLS __declspec(thread) +#endif +#else +#define WINPR_TLS __thread +#endif + #ifdef _WIN32 #define INLINE __inline -- 2.7.4