diff --git a/channels/cliprdr/client/cliprdr_main.c b/channels/cliprdr/client/cliprdr_main.c index 7ca0c94aa..43be6d545 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 e80141347..34d9cf825 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 36e073d11..34ac296c2 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 239954c97..c4221b04c 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 618227b21..0ab7ba49d 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 7472b0c58..7bc57f42b 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 baf0c6401..5baa05b1c 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; - } + if (status == WAIT_FAILED) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error); + break; + } - status = WaitForSingleObject(rdpsnd->stopEvent, 0); + 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, "WaitForSingleObject failed with error %lu!", error); + break; + } - if (status == WAIT_OBJECT_0) - break; + if (status == WAIT_OBJECT_0) + break; + status = WaitForSingleObject(events[0], 0); - status = WaitForSingleObject(events[0], 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, "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); - } -#endif + 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); + } + +#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); - } -#endif + 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); + } + +#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); - } -#endif + 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); + } + +#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); - } -#endif + 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); + } + +#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 - - #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); - } -#endif + 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); + } + +#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 7e34d5992..ea4dd2fe3 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 de3b0dc7c..87a006d37 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 5c801cda4..d5d1aa7d1 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 009af9165..a35c5b217 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 b00bc98f3..571225712 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 1fdc015cf..40c5add54 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 af58fca08..6a61c33fe 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 aa63b4138..b869afbc5 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 f9e4024f1..0f1cec823 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 816afbb2e..31c86e6a3 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 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 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 22b2b3502..f06c177f1 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 4e3bcb00a..ea53fc645 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; + goto error; - if (!g_OpenHandles) - { - g_OpenHandles = HashTable_New(TRUE); + channels->openHandles = HashTable_New(TRUE); - if (!g_OpenHandles) - goto error_open_handles; - - 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,23 +648,23 @@ 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, + + if (!channels) + return CHANNEL_RC_BAD_CHANNEL_HANDLE; + + pChannelOpenData = HashTable_GetItemValue(channels->openHandles, (void*)(UINT_PTR) openHandle); if (!pChannelOpenData) return CHANNEL_RC_BAD_CHANNEL_HANDLE; - channels = pChannelOpenData->channels; - - if (!channels) - return CHANNEL_RC_BAD_CHANNEL_HANDLE; - if (!channels->connected) return CHANNEL_RC_NOT_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 7a87c8f33..2337b6bbe 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 1257660c7..a5fcc788e 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) - goto out_error_pubsub; - PubSub_AddEventTypes(context->pubSub, FreeRDP_Events, sizeof(FreeRDP_Events) / sizeof(wEventType)); + if (!context->pubSub) + goto out_error_pubsub; + + 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 4e9250974..67a1ed73b 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 +#ifdef WINPR_EXPORTS +#ifdef __GNUC__ +#define WINPR_API __attribute__((dllexport)) #else - #if __GNUC__ >= 4 - #define WINPR_API __attribute__ ((visibility("default"))) - #else - #define WINPR_API - #endif +#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