From 4eb4f58fbb02338bfc3f2010f2937cb80607d209 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 27 Feb 2020 16:54:17 +0100 Subject: [PATCH] Updated CMake channel detection * Now both, dynamic and static channel entries can be defined by a single channel. * Added better logging to distinguish between static and dynamic channel messages. --- channels/client/CMakeLists.txt | 52 +++---- channels/client/addin.c | 17 +++ channels/client/tables.h | 1 + channels/rdpsnd/CMakeLists.txt | 7 - channels/rdpsnd/ChannelOptions.cmake | 2 +- channels/rdpsnd/client/CMakeLists.txt | 2 +- channels/rdpsnd/client/rdpsnd_main.c | 193 +++++++++++++++----------- client/common/cmdline.c | 7 +- 8 files changed, 161 insertions(+), 120 deletions(-) diff --git a/channels/client/CMakeLists.txt b/channels/client/CMakeLists.txt index f1089d1e2..a0d3a7358 100644 --- a/channels/client/CMakeLists.txt +++ b/channels/client/CMakeLists.txt @@ -33,26 +33,28 @@ set(CLIENT_STATIC_TYPEDEFS "${CLIENT_STATIC_TYPEDEFS}typedef UINT (*static_addin foreach(STATIC_ENTRY ${CHANNEL_STATIC_CLIENT_ENTRIES}) foreach(STATIC_MODULE ${CHANNEL_STATIC_CLIENT_MODULES}) - if(${${STATIC_MODULE}_CLIENT_ENTRY} STREQUAL ${STATIC_ENTRY}) - set(STATIC_MODULE_NAME ${${STATIC_MODULE}_CLIENT_NAME}) - set(STATIC_MODULE_CHANNEL ${${STATIC_MODULE}_CLIENT_CHANNEL}) - set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${STATIC_MODULE_NAME}) + foreach(ENTRY ${${STATIC_MODULE}_CLIENT_ENTRY}) + if(${ENTRY} STREQUAL ${STATIC_ENTRY}) + set(STATIC_MODULE_NAME ${${STATIC_MODULE}_CLIENT_NAME}) + set(STATIC_MODULE_CHANNEL ${${STATIC_MODULE}_CLIENT_CHANNEL}) + set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${STATIC_MODULE_NAME}) - set(ENTRY_POINT_NAME "${STATIC_MODULE_CHANNEL}_${${STATIC_MODULE}_CLIENT_ENTRY}") - if(${${STATIC_MODULE}_CLIENT_ENTRY} STREQUAL "VirtualChannelEntry") - set(ENTRY_POINT_IMPORT "extern BOOL VCAPITYPE ${ENTRY_POINT_NAME}(PCHANNEL_ENTRY_POINTS);") - elseif(${${STATIC_MODULE}_CLIENT_ENTRY} STREQUAL "VirtualChannelEntryEx") - set(ENTRY_POINT_IMPORT "extern BOOL VCAPITYPE ${ENTRY_POINT_NAME}(PCHANNEL_ENTRY_POINTS,PVOID);") - elseif(${${STATIC_MODULE}_CLIENT_ENTRY} MATCHES "DVCPluginEntry$") - set(ENTRY_POINT_IMPORT "extern UINT ${ENTRY_POINT_NAME}(IDRDYNVC_ENTRY_POINTS* pEntryPoints);") - elseif(${${STATIC_MODULE}_CLIENT_ENTRY} MATCHES "DeviceServiceEntry$") - set(ENTRY_POINT_IMPORT "extern UINT ${ENTRY_POINT_NAME}(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints);") - else() - set(ENTRY_POINT_IMPORT "extern UINT ${ENTRY_POINT_NAME}(void);") + set(ENTRY_POINT_NAME "${STATIC_MODULE_CHANNEL}_${ENTRY}") + if(${ENTRY} STREQUAL "VirtualChannelEntry") + set(ENTRY_POINT_IMPORT "extern BOOL VCAPITYPE ${ENTRY_POINT_NAME}(PCHANNEL_ENTRY_POINTS);") + elseif(${ENTRY} STREQUAL "VirtualChannelEntryEx") + set(ENTRY_POINT_IMPORT "extern BOOL VCAPITYPE ${ENTRY_POINT_NAME}(PCHANNEL_ENTRY_POINTS,PVOID);") + elseif(${ENTRY} MATCHES "DVCPluginEntry$") + set(ENTRY_POINT_IMPORT "extern UINT ${ENTRY_POINT_NAME}(IDRDYNVC_ENTRY_POINTS* pEntryPoints);") + elseif(${ENTRY} MATCHES "DeviceServiceEntry$") + set(ENTRY_POINT_IMPORT "extern UINT ${ENTRY_POINT_NAME}(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints);") + else() + set(ENTRY_POINT_IMPORT "extern UINT ${ENTRY_POINT_NAME}(void);") + endif() + set(${STATIC_ENTRY}_IMPORTS "${${STATIC_ENTRY}_IMPORTS}\n${ENTRY_POINT_IMPORT}") + set(${STATIC_ENTRY}_TABLE "${${STATIC_ENTRY}_TABLE}\n\t{ \"${STATIC_MODULE_CHANNEL}\", (static_entry_fkt)${ENTRY_POINT_NAME} },") endif() - set(${STATIC_ENTRY}_IMPORTS "${${STATIC_ENTRY}_IMPORTS}\n${ENTRY_POINT_IMPORT}") - set(${STATIC_ENTRY}_TABLE "${${STATIC_ENTRY}_TABLE}\n\t{ \"${STATIC_MODULE_CHANNEL}\", (static_entry_fkt)${ENTRY_POINT_NAME} },") - endif() + endforeach() endforeach() endforeach() @@ -75,7 +77,7 @@ foreach(STATIC_MODULE ${CHANNEL_STATIC_CLIENT_MODULES}) string(TOUPPER "CLIENT_${STATIC_MODULE_CHANNEL}_SUBSYSTEM_TABLE" SUBSYSTEM_TABLE_NAME) set(SUBSYSTEM_TABLE "const STATIC_SUBSYSTEM_ENTRY ${SUBSYSTEM_TABLE_NAME}[] =\n{") get_target_property(CHANNEL_SUBSYSTEMS ${STATIC_MODULE_NAME} SUBSYSTEMS) - if(CHANNEL_SUBSYSTEMS MATCHES "NOTFOUND" OR STATIC_MODULE MATCHES "CHANNEL_RDPSNDDYN") # do not generate subsystem table for dynamic rdpsnd channel + if(CHANNEL_SUBSYSTEMS MATCHES "NOTFOUND") set(CHANNEL_SUBSYSTEMS "") endif() foreach(STATIC_SUBSYSTEM ${CHANNEL_SUBSYSTEMS}) @@ -100,14 +102,12 @@ foreach(STATIC_MODULE ${CHANNEL_STATIC_CLIENT_MODULES}) endforeach() set(SUBSYSTEM_TABLE "${SUBSYSTEM_TABLE}\n\t{ NULL, NULL, NULL }\n};") set(CLIENT_STATIC_SUBSYSTEM_TABLES "${CLIENT_STATIC_SUBSYSTEM_TABLES}\n${SUBSYSTEM_TABLE}") - set(ENTRY_POINT_NAME "${STATIC_MODULE_CHANNEL}_${${STATIC_MODULE}_CLIENT_ENTRY}") - # Little hack for dynamic channels support in rdpsnd - if(STATIC_MODULE MATCHES "CHANNEL_RDPSNDDYN") - set(SUBSYSTEM_TABLE_NAME "CLIENT_RDPSND_SUBSYSTEM_TABLE") - endif() - set(CLIENT_STATIC_ADDIN_TABLE "${CLIENT_STATIC_ADDIN_TABLE}\n\t{ \"${STATIC_MODULE_CHANNEL}\", (static_addin_fkt)${ENTRY_POINT_NAME}, ${SUBSYSTEM_TABLE_NAME} },") + foreach(ENTRY ${${STATIC_MODULE}_CLIENT_ENTRY}) + set (ENTRY_POINT_NAME ${STATIC_MODULE_CHANNEL}_${ENTRY}) + set(CLIENT_STATIC_ADDIN_TABLE "${CLIENT_STATIC_ADDIN_TABLE}\n\t{ \"${STATIC_MODULE_CHANNEL}\", \"${ENTRY}\", (static_addin_fkt)${ENTRY_POINT_NAME}, ${SUBSYSTEM_TABLE_NAME} },") + endforeach() endforeach() -set(CLIENT_STATIC_ADDIN_TABLE "${CLIENT_STATIC_ADDIN_TABLE}\n\t{ NULL, NULL, NULL }\n};") +set(CLIENT_STATIC_ADDIN_TABLE "${CLIENT_STATIC_ADDIN_TABLE}\n\t{ NULL, NULL, NULL, NULL }\n};") configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tables.c.in ${CMAKE_CURRENT_BINARY_DIR}/tables.c) diff --git a/channels/client/addin.c b/channels/client/addin.c index 336de3b03..cd6f90e99 100644 --- a/channels/client/addin.c +++ b/channels/client/addin.c @@ -349,13 +349,30 @@ PVIRTUALCHANNELENTRY freerdp_channels_load_static_addin_entry(LPCSTR pszName, LP LPCSTR pszType, DWORD dwFlags) { const STATIC_ADDIN_TABLE* table = CLIENT_STATIC_ADDIN_TABLE; + const char* type = NULL; + if (!pszName) return NULL; + if (dwFlags & FREERDP_ADDIN_CHANNEL_DYNAMIC) + type = "DVCPluginEntry"; + else if (dwFlags & FREERDP_ADDIN_CHANNEL_DEVICE) + type = "DeviceServiceEntry"; + else if (dwFlags & FREERDP_ADDIN_CHANNEL_STATIC) + { + if (dwFlags & FREERDP_ADDIN_CHANNEL_ENTRYEX) + type = "VirtualChannelEntryEx"; + else + type = "VirtualChannelEntry"; + } + for (; table->name != NULL; table++) { if (strncmp(table->name, pszName, MAX_PATH) == 0) { + if (type && strncmp(table->type, type, MAX_PATH)) + continue; + if (pszSubsystem != NULL) { const STATIC_SUBSYSTEM_ENTRY* subsystems = table->table; diff --git a/channels/client/tables.h b/channels/client/tables.h index 378021073..fd998a6ae 100644 --- a/channels/client/tables.h +++ b/channels/client/tables.h @@ -44,6 +44,7 @@ typedef struct _STATIC_SUBSYSTEM_ENTRY STATIC_SUBSYSTEM_ENTRY; struct _STATIC_ADDIN_TABLE { const char* name; + const char* type; UINT (*entry)(); const STATIC_SUBSYSTEM_ENTRY* table; }; diff --git a/channels/rdpsnd/CMakeLists.txt b/channels/rdpsnd/CMakeLists.txt index f77eeeaf6..08b68365a 100644 --- a/channels/rdpsnd/CMakeLists.txt +++ b/channels/rdpsnd/CMakeLists.txt @@ -20,13 +20,6 @@ define_channel("rdpsnd") include_directories(common) add_subdirectory(common) -# Define dynamic entry point of sound channel -set(CHANNEL_STATIC_CLIENT_MODULES ${CHANNEL_STATIC_CLIENT_MODULES} "CHANNEL_RDPSNDDYN") -set(CHANNEL_RDPSNDDYN_CLIENT_NAME "rdpsnd-client" PARENT_SCOPE) -set(CHANNEL_RDPSNDDYN_CLIENT_CHANNEL "rdpsnd_dyn" PARENT_SCOPE) -set(CHANNEL_RDPSNDDYN_CLIENT_ENTRY "DVCPluginEntry" PARENT_SCOPE) -set(CHANNEL_STATIC_CLIENT_ENTRIES ${CHANNEL_STATIC_CLIENT_ENTRIES} ${CHANNEL_RDPSNDDYN_CLIENT_ENTRY}) - if(WITH_CLIENT_CHANNELS) add_channel_client(${MODULE_PREFIX} ${CHANNEL_NAME}) endif() diff --git a/channels/rdpsnd/ChannelOptions.cmake b/channels/rdpsnd/ChannelOptions.cmake index 909da1de5..948ba9799 100644 --- a/channels/rdpsnd/ChannelOptions.cmake +++ b/channels/rdpsnd/ChannelOptions.cmake @@ -3,7 +3,7 @@ set(OPTION_DEFAULT OFF) set(OPTION_CLIENT_DEFAULT ON) set(OPTION_SERVER_DEFAULT ON) -define_channel_options(NAME "rdpsnd" TYPE "static" +define_channel_options(NAME "rdpsnd" TYPE "static;dynamic" DESCRIPTION "Audio Output Virtual Channel Extension" SPECIFICATIONS "[MS-RDPEA]" DEFAULT ${OPTION_DEFAULT}) diff --git a/channels/rdpsnd/client/CMakeLists.txt b/channels/rdpsnd/client/CMakeLists.txt index 1860fd8be..70f4aa2e6 100644 --- a/channels/rdpsnd/client/CMakeLists.txt +++ b/channels/rdpsnd/client/CMakeLists.txt @@ -21,7 +21,7 @@ set(${MODULE_PREFIX}_SRCS rdpsnd_main.c rdpsnd_main.h) -add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntryEx") +add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntryEx;DVCPluginEntry") target_link_libraries(${MODULE_NAME} winpr freerdp ${CMAKE_THREAD_LIBS_INIT} diff --git a/channels/rdpsnd/client/rdpsnd_main.c b/channels/rdpsnd/client/rdpsnd_main.c index 550c80534..53129e7b3 100644 --- a/channels/rdpsnd/client/rdpsnd_main.c +++ b/channels/rdpsnd/client/rdpsnd_main.c @@ -99,6 +99,7 @@ struct rdpsnd_plugin BOOL attached; BOOL connected; + BOOL dynamic; BOOL expectingWave; BYTE waveData[4]; @@ -123,6 +124,13 @@ struct rdpsnd_plugin FREERDP_DSP_CONTEXT* dsp_context; }; +static const char* rdpsnd_is_dyn_str(BOOL dynamic) +{ + if (dynamic) + return "[dynamic]"; + return "[static]"; +} + static void rdpsnd_virtual_channel_event_terminated(rdpsndPlugin* rdpsnd); /** @@ -144,7 +152,7 @@ static UINT rdpsnd_send_quality_mode_pdu(rdpsndPlugin* rdpsnd) if (!pdu) { - WLog_ERR(TAG, "Stream_New failed!"); + WLog_ERR(TAG, "%s Stream_New failed!", rdpsnd_is_dyn_str(rdpsnd->dynamic)); return CHANNEL_RC_NO_MEMORY; } @@ -153,7 +161,8 @@ static UINT rdpsnd_send_quality_mode_pdu(rdpsndPlugin* rdpsnd) 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: %" PRIu16 "", rdpsnd->wQualityMode); + WLog_Print(rdpsnd->log, WLOG_DEBUG, "%s QualityMode: %" PRIu16 "", + rdpsnd_is_dyn_str(rdpsnd->dynamic), rdpsnd->wQualityMode); return rdpsnd_virtual_channel_write(rdpsnd, pdu); } @@ -211,7 +220,7 @@ static UINT rdpsnd_send_client_audio_formats(rdpsndPlugin* rdpsnd) if (!pdu) { - WLog_ERR(TAG, "Stream_New failed!"); + WLog_ERR(TAG, "%s Stream_New failed!", rdpsnd_is_dyn_str(rdpsnd->dynamic)); return CHANNEL_RC_NO_MEMORY; } @@ -238,7 +247,8 @@ static UINT rdpsnd_send_client_audio_formats(rdpsndPlugin* rdpsnd) } } - WLog_Print(rdpsnd->log, WLOG_DEBUG, "Client Audio Formats"); + WLog_Print(rdpsnd->log, WLOG_DEBUG, "%s Client Audio Formats", + rdpsnd_is_dyn_str(rdpsnd->dynamic)); return rdpsnd_virtual_channel_write(rdpsnd, pdu); } @@ -288,7 +298,8 @@ static UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, wStream* } rdpsnd_select_supported_audio_formats(rdpsnd); - WLog_Print(rdpsnd->log, WLOG_DEBUG, "Server Audio Formats"); + WLog_Print(rdpsnd->log, WLOG_DEBUG, "%s Server Audio Formats", + rdpsnd_is_dyn_str(rdpsnd->dynamic)); ret = rdpsnd_send_client_audio_formats(rdpsnd); if (ret == CHANNEL_RC_OK) @@ -318,7 +329,7 @@ static UINT rdpsnd_send_training_confirm_pdu(rdpsndPlugin* rdpsnd, UINT16 wTimeS if (!pdu) { - WLog_ERR(TAG, "Stream_New failed!"); + WLog_ERR(TAG, "%s Stream_New failed!", rdpsnd_is_dyn_str(rdpsnd->dynamic)); return CHANNEL_RC_NO_MEMORY; } @@ -328,8 +339,8 @@ static UINT rdpsnd_send_training_confirm_pdu(rdpsndPlugin* rdpsnd, UINT16 wTimeS Stream_Write_UINT16(pdu, wTimeStamp); Stream_Write_UINT16(pdu, wPackSize); WLog_Print(rdpsnd->log, WLOG_DEBUG, - "Training Response: wTimeStamp: %" PRIu16 " wPackSize: %" PRIu16 "", wTimeStamp, - wPackSize); + "%s Training Response: wTimeStamp: %" PRIu16 " wPackSize: %" PRIu16 "", + rdpsnd_is_dyn_str(rdpsnd->dynamic), wTimeStamp, wPackSize); return rdpsnd_virtual_channel_write(rdpsnd, pdu); } @@ -349,8 +360,8 @@ 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: %" PRIu16 " wPackSize: %" PRIu16 "", wTimeStamp, - wPackSize); + "%s Training Request: wTimeStamp: %" PRIu16 " wPackSize: %" PRIu16 "", + rdpsnd_is_dyn_str(rdpsnd->dynamic), wTimeStamp, wPackSize); return rdpsnd_send_training_confirm_pdu(rdpsnd, wTimeStamp, wPackSize); } @@ -380,7 +391,8 @@ static BOOL rdpsnd_ensure_device_is_open(rdpsndPlugin* rdpsnd, UINT32 wFormatNo, } } - WLog_Print(rdpsnd->log, WLOG_DEBUG, "Opening device with format %s [backend %s]", + WLog_Print(rdpsnd->log, WLOG_DEBUG, "%s Opening device with format %s [backend %s]", + rdpsnd_is_dyn_str(rdpsnd->dynamic), audio_format_get_tag_string(format->wFormatTag), audio_format_get_tag_string(deviceFormat.wFormatTag)); rc = IFCALLRESULT(FALSE, rdpsnd->device->Open, rdpsnd->device, &deviceFormat, @@ -430,8 +442,9 @@ static UINT rdpsnd_recv_wave_info_pdu(rdpsndPlugin* rdpsnd, wStream* s, UINT16 B rdpsnd->waveDataSize = BodySize - 8; format = &rdpsnd->ClientFormats[wFormatNo]; WLog_Print(rdpsnd->log, WLOG_DEBUG, - "WaveInfo: cBlockNo: %" PRIu8 " wFormatNo: %" PRIu16 " [%s]", rdpsnd->cBlockNo, - wFormatNo, audio_format_get_tag_string(format->wFormatTag)); + "%s WaveInfo: cBlockNo: %" PRIu8 " wFormatNo: %" PRIu16 " [%s]", + rdpsnd_is_dyn_str(rdpsnd->dynamic), rdpsnd->cBlockNo, wFormatNo, + audio_format_get_tag_string(format->wFormatTag)); if (!rdpsnd_ensure_device_is_open(rdpsnd, wFormatNo, format)) return ERROR_INTERNAL_ERROR; @@ -453,7 +466,7 @@ static UINT rdpsnd_send_wave_confirm_pdu(rdpsndPlugin* rdpsnd, UINT16 wTimeStamp if (!pdu) { - WLog_ERR(TAG, "Stream_New failed!"); + WLog_ERR(TAG, "%s Stream_New failed!", rdpsnd_is_dyn_str(rdpsnd->dynamic)); return CHANNEL_RC_NO_MEMORY; } @@ -495,7 +508,8 @@ static BOOL rdpsnd_detect_overrun(rdpsndPlugin* rdpsnd, const AUDIO_FORMAT* form else if (now - rdpsnd->startPlayTime > totalDuration + 10) { /* Buffer underrun */ - WLog_Print(rdpsnd->log, WLOG_DEBUG, "Buffer underrun by %u ms", + WLog_Print(rdpsnd->log, WLOG_DEBUG, "%s Buffer underrun by %u ms", + rdpsnd_is_dyn_str(rdpsnd->dynamic), (UINT)(now - rdpsnd->startPlayTime - totalDuration)); rdpsnd->startPlayTime = now; rdpsnd->totalPlaySize = size; @@ -511,8 +525,8 @@ static BOOL rdpsnd_detect_overrun(rdpsndPlugin* rdpsnd, const AUDIO_FORMAT* form if (remainingDuration + duration > maxDuration) { - WLog_Print(rdpsnd->log, WLOG_DEBUG, "Buffer overrun pending %u ms dropping %u ms", - remainingDuration, duration); + WLog_Print(rdpsnd->log, WLOG_DEBUG, "%s Buffer overrun pending %u ms dropping %u ms", + rdpsnd_is_dyn_str(rdpsnd->dynamic), remainingDuration, duration); return TRUE; } @@ -535,8 +549,8 @@ static UINT rdpsnd_treat_wave(rdpsndPlugin* rdpsnd, wStream* s, size_t size) data = Stream_Pointer(s); format = &rdpsnd->ClientFormats[rdpsnd->wCurrentFormatNo]; WLog_Print(rdpsnd->log, WLOG_DEBUG, - "Wave: cBlockNo: %" PRIu8 " wTimeStamp: %" PRIu16 ", size: %" PRIdz, - rdpsnd->cBlockNo, rdpsnd->wTimeStamp, size); + "%s Wave: cBlockNo: %" PRIu8 " wTimeStamp: %" PRIu16 ", size: %" PRIdz, + rdpsnd_is_dyn_str(rdpsnd->dynamic), rdpsnd->cBlockNo, rdpsnd->wTimeStamp, size); if (rdpsnd->device && rdpsnd->attached && !rdpsnd_detect_overrun(rdpsnd, format, size)) { @@ -564,8 +578,8 @@ static UINT rdpsnd_treat_wave(rdpsndPlugin* rdpsnd, wStream* s, size_t size) diffMS = end - rdpsnd->wArrivalTime + latency; ts = (rdpsnd->wTimeStamp + diffMS) % UINT16_MAX; - /* Don't send wave confirm PDU if not on static channel */ - if (rdpsnd->listener_callback) + /* Don't send wave confirm PDU if on dynamic channel */ + if (rdpsnd->dynamic) return CHANNEL_RC_OK; return rdpsnd_send_wave_confirm_pdu(rdpsnd, (UINT16)ts, rdpsnd->cBlockNo); @@ -611,8 +625,9 @@ static UINT rdpsnd_recv_wave2_pdu(rdpsndPlugin* rdpsnd, wStream* s, UINT16 BodyS format = &rdpsnd->ClientFormats[wFormatNo]; rdpsnd->wArrivalTime = GetTickCount64(); WLog_Print(rdpsnd->log, WLOG_DEBUG, - "Wave2PDU: cBlockNo: %" PRIu8 " wFormatNo: %" PRIu16 ", align=%hu", rdpsnd->cBlockNo, - wFormatNo, format->nBlockAlign); + "%s Wave2PDU: cBlockNo: %" PRIu8 " wFormatNo: %" PRIu16 ", align=%hu", + rdpsnd_is_dyn_str(rdpsnd->dynamic), rdpsnd->cBlockNo, wFormatNo, + format->nBlockAlign); if (!rdpsnd_ensure_device_is_open(rdpsnd, wFormatNo, format)) return ERROR_INTERNAL_ERROR; @@ -624,10 +639,12 @@ static void rdpsnd_recv_close_pdu(rdpsndPlugin* rdpsnd) { if (rdpsnd->isOpen) { - WLog_Print(rdpsnd->log, WLOG_DEBUG, "Closing device"); + WLog_Print(rdpsnd->log, WLOG_DEBUG, "%s Closing device", + rdpsnd_is_dyn_str(rdpsnd->dynamic)); } else - WLog_Print(rdpsnd->log, WLOG_DEBUG, "Device already closed"); + WLog_Print(rdpsnd->log, WLOG_DEBUG, "%s Device already closed", + rdpsnd_is_dyn_str(rdpsnd->dynamic)); } /** @@ -644,12 +661,13 @@ 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%08" PRIX32 "", dwVolume); + WLog_Print(rdpsnd->log, WLOG_DEBUG, "%s Volume: 0x%08" PRIX32 "", + rdpsnd_is_dyn_str(rdpsnd->dynamic), dwVolume); rc = IFCALLRESULT(FALSE, rdpsnd->device->SetVolume, rdpsnd->device, dwVolume); if (!rc) { - WLog_ERR(TAG, "error setting volume"); + WLog_ERR(TAG, "%s error setting volume", rdpsnd_is_dyn_str(rdpsnd->dynamic)); return CHANNEL_RC_INITIALIZATION_ERROR; } @@ -710,7 +728,8 @@ static UINT rdpsnd_recv_pdu(rdpsndPlugin* rdpsnd, wStream* s) break; default: - WLog_ERR(TAG, "unknown msgType %" PRIu8 "", msgType); + WLog_ERR(TAG, "%s unknown msgType %" PRIu8 "", rdpsnd_is_dyn_str(rdpsnd->dynamic), + msgType); break; } @@ -723,7 +742,7 @@ static void rdpsnd_register_device_plugin(rdpsndPlugin* rdpsnd, rdpsndDevicePlug { if (rdpsnd->device) { - WLog_ERR(TAG, "existing device, abort."); + WLog_ERR(TAG, "%s existing device, abort.", rdpsnd_is_dyn_str(FALSE)); return; } @@ -741,7 +760,11 @@ static UINT rdpsnd_load_device_plugin(rdpsndPlugin* rdpsnd, const char* name, AD PFREERDP_RDPSND_DEVICE_ENTRY entry; FREERDP_RDPSND_DEVICE_ENTRY_POINTS entryPoints; UINT error; - entry = (PFREERDP_RDPSND_DEVICE_ENTRY)freerdp_load_channel_addin_entry("rdpsnd", name, NULL, 0); + DWORD flags = FREERDP_ADDIN_CHANNEL_STATIC | FREERDP_ADDIN_CHANNEL_ENTRYEX; + if (rdpsnd->dynamic) + flags = FREERDP_ADDIN_CHANNEL_DYNAMIC; + entry = + (PFREERDP_RDPSND_DEVICE_ENTRY)freerdp_load_channel_addin_entry("rdpsnd", name, NULL, flags); if (!entry) return ERROR_INTERNAL_ERROR; @@ -751,9 +774,10 @@ static UINT rdpsnd_load_device_plugin(rdpsndPlugin* rdpsnd, const char* name, AD entryPoints.args = args; if ((error = entry(&entryPoints))) - WLog_ERR(TAG, "%s entry returns error %" PRIu32 "", name, error); + WLog_ERR(TAG, "%s %s entry returns error %" PRIu32 "", rdpsnd_is_dyn_str(rdpsnd->dynamic), + name, error); - WLog_INFO(TAG, "Loaded %s backend for rdpsnd", name); + WLog_INFO(TAG, "%s Loaded %s backend for rdpsnd", rdpsnd_is_dyn_str(rdpsnd->dynamic), name); return error; } @@ -942,8 +966,9 @@ static UINT rdpsnd_process_connect(rdpsndPlugin* rdpsnd) { if ((status = rdpsnd_load_device_plugin(rdpsnd, rdpsnd->subsystem, args))) { - WLog_ERR(TAG, "Unable to load sound playback subsystem %s because of error %" PRIu32 "", - rdpsnd->subsystem, status); + WLog_ERR(TAG, + "%s Unable to load sound playback subsystem %s because of error %" PRIu32 "", + rdpsnd_is_dyn_str(rdpsnd->dynamic), rdpsnd->subsystem, status); return status; } } @@ -958,8 +983,9 @@ static UINT rdpsnd_process_connect(rdpsndPlugin* rdpsnd) if ((status = rdpsnd_load_device_plugin(rdpsnd, subsystem_name, args))) WLog_ERR(TAG, - "Unable to load sound playback subsystem %s because of error %" PRIu32 "", - subsystem_name, status); + "%s Unable to load sound playback subsystem %s because of error %" PRIu32 + "", + rdpsnd_is_dyn_str(rdpsnd->dynamic), subsystem_name, status); if (!rdpsnd->device) continue; @@ -989,10 +1015,14 @@ UINT rdpsnd_virtual_channel_write(rdpsndPlugin* rdpsnd, wStream* s) if (rdpsnd) { - if (rdpsnd->listener_callback) + if (rdpsnd->dynamic) { - IWTSVirtualChannel* channel = rdpsnd->listener_callback->channel_callback->channel; - status = channel->Write(channel, (UINT32)Stream_Length(s), Stream_Buffer(s), NULL); + IWTSVirtualChannel* channel; + if (rdpsnd->listener_callback) + { + channel = rdpsnd->listener_callback->channel_callback->channel; + status = channel->Write(channel, (UINT32)Stream_Length(s), Stream_Buffer(s), NULL); + } Stream_Free(s, TRUE); } else @@ -1004,8 +1034,8 @@ UINT rdpsnd_virtual_channel_write(rdpsndPlugin* rdpsnd, wStream* s) if (status != CHANNEL_RC_OK) { Stream_Free(s, TRUE); - WLog_ERR(TAG, "pVirtualChannelWriteEx failed with %s [%08" PRIX32 "]", - WTSErrorToString(status), status); + WLog_ERR(TAG, "%s pVirtualChannelWriteEx failed with %s [%08" PRIX32 "]", + rdpsnd_is_dyn_str(FALSE), WTSErrorToString(status), status); } } } @@ -1068,14 +1098,15 @@ static VOID VCAPITYPE rdpsnd_virtual_channel_open_event_ex(LPVOID lpUserParam, D case CHANNEL_EVENT_DATA_RECEIVED: if (!rdpsnd || (rdpsnd->OpenHandle != openHandle)) { - WLog_ERR(TAG, "error no match"); + WLog_ERR(TAG, "%s error no match", rdpsnd_is_dyn_str(rdpsnd->dynamic)); return; } 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 %" PRIu32 "", - error); + "%s rdpsnd_virtual_channel_event_data_received failed with error %" PRIu32 + "", + rdpsnd_is_dyn_str(rdpsnd->dynamic), error); break; @@ -1092,8 +1123,13 @@ static VOID VCAPITYPE rdpsnd_virtual_channel_open_event_ex(LPVOID lpUserParam, D } if (error && rdpsnd && rdpsnd->rdpcontext) - setChannelError(rdpsnd->rdpcontext, error, - "rdpsnd_virtual_channel_open_event_ex reported an error"); + { + char buffer[8192]; + snprintf(buffer, sizeof(buffer), + "%s rdpsnd_virtual_channel_open_event_ex reported an error", + rdpsnd_is_dyn_str(rdpsnd->dynamic)); + setChannelError(rdpsnd->rdpcontext, error, buffer); + } } /** @@ -1105,14 +1141,17 @@ static UINT rdpsnd_virtual_channel_event_connected(rdpsndPlugin* rdpsnd, LPVOID UINT32 dataLength) { UINT32 status; + WINPR_UNUSED(pData); + WINPR_UNUSED(dataLength); + status = rdpsnd->channelEntryPoints.pVirtualChannelOpenEx( rdpsnd->InitHandle, &rdpsnd->OpenHandle, rdpsnd->channelDef.name, rdpsnd_virtual_channel_open_event_ex); if (status != CHANNEL_RC_OK) { - WLog_ERR(TAG, "pVirtualChannelOpenEx failed with %s [%08" PRIX32 "]", - WTSErrorToString(status), status); + WLog_ERR(TAG, "%s pVirtualChannelOpenEx failed with %s [%08" PRIX32 "]", + rdpsnd_is_dyn_str(rdpsnd->dynamic), WTSErrorToString(status), status); return status; } @@ -1153,8 +1192,8 @@ static UINT rdpsnd_virtual_channel_event_disconnected(rdpsndPlugin* rdpsnd) if (CHANNEL_RC_OK != error) { - WLog_ERR(TAG, "pVirtualChannelCloseEx failed with %s [%08" PRIX32 "]", - WTSErrorToString(error), error); + WLog_ERR(TAG, "%s pVirtualChannelCloseEx failed with %s [%08" PRIX32 "]", + rdpsnd_is_dyn_str(rdpsnd->dynamic), WTSErrorToString(error), error); return error; } @@ -1201,7 +1240,7 @@ static VOID VCAPITYPE rdpsnd_virtual_channel_init_event_ex(LPVOID lpUserParam, L if (!plugin || (plugin->InitHandle != pInitHandle)) { - WLog_ERR(TAG, "error no match"); + WLog_ERR(TAG, "%s error no match", rdpsnd_is_dyn_str(plugin->dynamic)); return; } @@ -1211,19 +1250,11 @@ static VOID VCAPITYPE rdpsnd_virtual_channel_init_event_ex(LPVOID lpUserParam, L break; 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 %" PRIu32 "!", - error); - + error = rdpsnd_virtual_channel_event_connected(plugin, pData, dataLength); break; case CHANNEL_EVENT_DISCONNECTED: - if ((error = rdpsnd_virtual_channel_event_disconnected(plugin))) - WLog_ERR(TAG, - "rdpsnd_virtual_channel_event_disconnected failed with error %" PRIu32 "!", - error); - + error = rdpsnd_virtual_channel_event_disconnected(plugin); break; case CHANNEL_EVENT_TERMINATED: @@ -1243,8 +1274,12 @@ static VOID VCAPITYPE rdpsnd_virtual_channel_init_event_ex(LPVOID lpUserParam, L } if (error && plugin && plugin->rdpcontext) - setChannelError(plugin->rdpcontext, error, - "rdpsnd_virtual_channel_init_event reported an error"); + { + char buffer[8192]; + snprintf(buffer, sizeof(buffer), "%s %s reported an error", + rdpsnd_is_dyn_str(plugin->dynamic), __FUNCTION__); + setChannelError(plugin->rdpcontext, error, buffer); + } } rdpContext* freerdp_rdpsnd_get_context(rdpsndPlugin* plugin) @@ -1256,9 +1291,7 @@ rdpContext* freerdp_rdpsnd_get_context(rdpsndPlugin* plugin) } /* rdpsnd is always built-in */ -#define VirtualChannelEntryEx rdpsnd_VirtualChannelEntryEx - -BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID pInitHandle) +BOOL VCAPITYPE rdpsnd_VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID pInitHandle) { UINT rc; rdpsndPlugin* rdpsnd; @@ -1301,8 +1334,8 @@ BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID p if (CHANNEL_RC_OK != rc) { - WLog_ERR(TAG, "pVirtualChannelInitEx failed with %s [%08" PRIX32 "]", WTSErrorToString(rc), - rc); + WLog_ERR(TAG, "%s pVirtualChannelInitEx failed with %s [%08" PRIX32 "]", + rdpsnd_is_dyn_str(FALSE), WTSErrorToString(rc), rc); free(rdpsnd); return FALSE; } @@ -1371,9 +1404,12 @@ static UINT rdpsnd_on_new_channel_connection(IWTSListenerCallback* pListenerCall RDPSND_LISTENER_CALLBACK* listener_callback = (RDPSND_LISTENER_CALLBACK*)pListenerCallback; callback = (RDPSND_CHANNEL_CALLBACK*)calloc(1, sizeof(RDPSND_CHANNEL_CALLBACK)); + WINPR_UNUSED(Data); + WINPR_UNUSED(pbAccept); + if (!callback) { - WLog_ERR(TAG, "calloc failed!"); + WLog_ERR(TAG, "%s calloc failed!", rdpsnd_is_dyn_str(TRUE)); return CHANNEL_RC_NO_MEMORY; } @@ -1397,7 +1433,7 @@ static UINT rdpsnd_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelMana if (!rdpsnd->listener_callback) { - WLog_ERR(TAG, "calloc failed!"); + WLog_ERR(TAG, "%s calloc failed!", rdpsnd_is_dyn_str(TRUE)); return CHANNEL_RC_NO_MEMORY; } @@ -1425,28 +1461,22 @@ static UINT rdpsnd_plugin_terminated(IWTSPlugin* pPlugin) return CHANNEL_RC_OK; } -#ifdef BUILTIN_CHANNELS -#define DVCPluginEntry rdpsnd_dyn_DVCPluginEntry -#else -#define DVCPluginEntry FREERDP_API DVCPluginEntry -#endif - /** * Function description * * @return 0 on success, otherwise a Win32 error code */ -UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) +UINT rdpsnd_DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) { UINT error = CHANNEL_RC_OK; - rdpsndPlugin* rdpsnd = (rdpsndPlugin*)pEntryPoints->GetPlugin(pEntryPoints, "rdpsnd_dyn"); + rdpsndPlugin* rdpsnd = (rdpsndPlugin*)pEntryPoints->GetPlugin(pEntryPoints, "rdpsnd"); if (!rdpsnd) { rdpsnd = (rdpsndPlugin*)calloc(1, sizeof(rdpsndPlugin)); if (!rdpsnd) { - WLog_ERR(TAG, "calloc failed!"); + WLog_ERR(TAG, "%s calloc failed!", rdpsnd_is_dyn_str(TRUE)); return CHANNEL_RC_NO_MEMORY; } @@ -1455,6 +1485,7 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) rdpsnd->iface.Disconnected = NULL; rdpsnd->iface.Terminated = rdpsnd_plugin_terminated; rdpsnd->attached = TRUE; + rdpsnd->dynamic = TRUE; rdpsnd->fixed_format = audio_format_new(); if (!rdpsnd->fixed_format) { @@ -1464,11 +1495,11 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) rdpsnd->log = WLog_Get("com.freerdp.channels.rdpsnd.client"); rdpsnd->channelEntryPoints.pExtendedData = pEntryPoints->GetPluginData(pEntryPoints); - error = pEntryPoints->RegisterPlugin(pEntryPoints, "rdpsnd_dyn", (IWTSPlugin*)rdpsnd); + error = pEntryPoints->RegisterPlugin(pEntryPoints, "rdpsnd", &rdpsnd->iface); } else { - WLog_ERR(TAG, "could not get disp Plugin."); + WLog_ERR(TAG, "%s could not get disp Plugin.", rdpsnd_is_dyn_str(TRUE)); return CHANNEL_RC_BAD_CHANNEL; } diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 9a2df5d9f..4649bd5e9 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -926,7 +926,6 @@ static int freerdp_client_command_line_post_filter(void* context, COMMAND_LINE_A status = freerdp_client_add_static_channel(settings, count, p); if (status) { - p[0] = "rdpsnd_dyn"; status = freerdp_client_add_dynamic_channel(settings, count, p); } free(p); @@ -3272,7 +3271,7 @@ BOOL freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings) /* for audio playback also load the dynamic sound channel */ if (settings->AudioPlayback) { - char* p[] = { "rdpsnd_dyn" }; + char* p[] = { "rdpsnd" }; if (!freerdp_client_add_dynamic_channel(settings, ARRAYSIZE(p), p)) return FALSE; @@ -3287,7 +3286,7 @@ BOOL freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings) } if ((freerdp_static_channel_collection_find(settings, "rdpsnd")) || - (freerdp_dynamic_channel_collection_find(settings, "rdpsnd_dyn")) + (freerdp_dynamic_channel_collection_find(settings, "rdpsnd")) #if defined(CHANNEL_TSMF_CLIENT) || (freerdp_dynamic_channel_collection_find(settings, "tsmf")) #endif @@ -3413,7 +3412,7 @@ BOOL freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings) return FALSE; if (!freerdp_static_channel_collection_find(settings, "rdpsnd") && - !freerdp_dynamic_channel_collection_find(settings, "rdpsnd_dyn")) + !freerdp_dynamic_channel_collection_find(settings, "rdpsnd")) { char* params[2]; params[0] = "rdpsnd";