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.
This commit is contained in:
Armin Novak 2020-02-27 16:54:17 +01:00 committed by akallabeth
parent da354feed0
commit 4eb4f58fbb
8 changed files with 161 additions and 120 deletions

View File

@ -33,19 +33,20 @@ 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})
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_NAME "${STATIC_MODULE_CHANNEL}_${ENTRY}")
if(${ENTRY} STREQUAL "VirtualChannelEntry")
set(ENTRY_POINT_IMPORT "extern BOOL VCAPITYPE ${ENTRY_POINT_NAME}(PCHANNEL_ENTRY_POINTS);")
elseif(${${STATIC_MODULE}_CLIENT_ENTRY} STREQUAL "VirtualChannelEntryEx")
elseif(${ENTRY} STREQUAL "VirtualChannelEntryEx")
set(ENTRY_POINT_IMPORT "extern BOOL VCAPITYPE ${ENTRY_POINT_NAME}(PCHANNEL_ENTRY_POINTS,PVOID);")
elseif(${${STATIC_MODULE}_CLIENT_ENTRY} MATCHES "DVCPluginEntry$")
elseif(${ENTRY} MATCHES "DVCPluginEntry$")
set(ENTRY_POINT_IMPORT "extern UINT ${ENTRY_POINT_NAME}(IDRDYNVC_ENTRY_POINTS* pEntryPoints);")
elseif(${${STATIC_MODULE}_CLIENT_ENTRY} MATCHES "DeviceServiceEntry$")
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);")
@ -55,6 +56,7 @@ foreach(STATIC_ENTRY ${CHANNEL_STATIC_CLIENT_ENTRIES})
endif()
endforeach()
endforeach()
endforeach()
set(CLIENT_STATIC_ENTRY_TABLES_LIST "${CLIENT_STATIC_ENTRY_TABLES_LIST}\nconst STATIC_ENTRY_TABLE CLIENT_STATIC_ENTRY_TABLES[] =\n{")
@ -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()
set(CLIENT_STATIC_ADDIN_TABLE "${CLIENT_STATIC_ADDIN_TABLE}\n\t{ NULL, NULL, NULL }\n};")
endforeach()
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)

View File

@ -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;

View File

@ -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;
};

View File

@ -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()

View File

@ -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})

View File

@ -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}

View File

@ -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->dynamic)
{
IWTSVirtualChannel* channel;
if (rdpsnd->listener_callback)
{
IWTSVirtualChannel* channel = rdpsnd->listener_callback->channel_callback->channel;
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;
}

View File

@ -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";