diff --git a/channels/CMakeLists.txt b/channels/CMakeLists.txt index d9eb7faa7..e5c0a3906 100644 --- a/channels/CMakeLists.txt +++ b/channels/CMakeLists.txt @@ -77,7 +77,7 @@ macro(define_channel_client_subsystem _channel_name _subsystem _type) if(_type_length GREATER 0) set(SUBSYSTEM_TYPE ${_type}) set(MODULE_NAME "${CHANNEL_NAME}-client-${CHANNEL_SUBSYSTEM}-${SUBSYSTEM_TYPE}") - string(TOUPPER "CHANNEL_${CHANNEL_NAME}_CLIENT_${CHANNEL_SUBSYSTEM}-${SUBSYSTEM_TYPE}" MODULE_PREFIX) + string(TOUPPER "CHANNEL_${CHANNEL_NAME}_CLIENT_${CHANNEL_SUBSYSTEM}_${SUBSYSTEM_TYPE}" MODULE_PREFIX) else() set(MODULE_NAME "${CHANNEL_NAME}-client-${CHANNEL_SUBSYSTEM}") string(TOUPPER "CHANNEL_${CHANNEL_NAME}_CLIENT_${CHANNEL_SUBSYSTEM}" MODULE_PREFIX) @@ -116,10 +116,19 @@ endmacro(add_channel_server) macro(add_channel_client_subsystem _channel_prefix _channel_name _subsystem _type) add_subdirectory(${_subsystem}) set(_channel_module_name "${_channel_name}-client") - string(TOUPPER "CHANNEL_${_channel_name}_CLIENT_${_subsystem}" _subsystem_prefix) + string(LENGTH "${_type}" _type_length) + if(_type_length GREATER 0) + string(TOUPPER "CHANNEL_${_channel_name}_CLIENT_${_subsystem}_${_type}" _subsystem_prefix) + else() + string(TOUPPER "CHANNEL_${_channel_name}_CLIENT_${_subsystem}" _subsystem_prefix) + endif() if(${${_subsystem_prefix}_STATIC}) get_target_property(CHANNEL_SUBSYSTEMS ${_channel_module_name} SUBSYSTEMS) - set(SUBSYSTEMS ${SUBSYSTEMS} ${_subsystem}) + if(_type_length GREATER 0) + set(SUBSYSTEMS ${SUBSYSTEMS} "${_subsystem}-${_type}") + else() + set(SUBSYSTEMS ${SUBSYSTEMS} ${_subsystem}) + endif() set_target_properties(${_channel_module_name} PROPERTIES SUBSYSTEMS "${SUBSYSTEMS}") endif() endmacro(add_channel_client_subsystem) @@ -139,7 +148,7 @@ macro(add_channel_client_library _module_prefix _module_name _channel_name _dyna endif() endmacro(add_channel_client_library) -macro(add_channel_client_subsystem_library _module_prefix _module_name _channel_name _dynamic _entry) +macro(add_channel_client_subsystem_library _module_prefix _module_name _channel_name _type _dynamic _entry) if(${_dynamic} AND MSVC AND (NOT STATIC_CHANNELS)) set(${_module_prefix}_SRCS ${${_module_prefix}_SRCS} module.def) endif() @@ -148,6 +157,7 @@ macro(add_channel_client_subsystem_library _module_prefix _module_name _channel_ else() set(${_module_prefix}_STATIC ON PARENT_SCOPE) set(${_module_prefix}_NAME ${_module_name} PARENT_SCOPE) + set(${_module_prefix}_TYPE ${_type} PARENT_SCOPE) add_library(${_module_name} STATIC ${${_module_prefix}_SRCS}) endif() endmacro(add_channel_client_subsystem_library) diff --git a/channels/audin/client/alsa/CMakeLists.txt b/channels/audin/client/alsa/CMakeLists.txt index f49bd6131..b39ec52b3 100644 --- a/channels/audin/client/alsa/CMakeLists.txt +++ b/channels/audin/client/alsa/CMakeLists.txt @@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS include_directories(..) include_directories(${ALSA_INCLUDE_DIRS}) -add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "") +add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "") set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") diff --git a/channels/audin/client/alsa/audin_alsa.c b/channels/audin/client/alsa/audin_alsa.c index 80c6b70e1..4af683367 100644 --- a/channels/audin/client/alsa/audin_alsa.c +++ b/channels/audin/client/alsa/audin_alsa.c @@ -25,7 +25,12 @@ #include #include +#include +#include + #include + +#include #include #include #include @@ -36,7 +41,7 @@ typedef struct _AudinALSADevice { IAudinDevice iface; - char device_name[32]; + char* device_name; UINT32 frames_per_packet; UINT32 target_rate; UINT32 actual_rate; @@ -236,6 +241,9 @@ static void audin_alsa_free(IAudinDevice* device) freerdp_thread_free(alsa->thread); freerdp_dsp_context_free(alsa->dsp_context); + + free(alsa->device_name); + free(alsa); } @@ -328,40 +336,66 @@ static void audin_alsa_close(IAudinDevice* device) alsa->user_data = NULL; } +COMMAND_LINE_ARGUMENT_A audin_alsa_args[] = +{ + { "audio-dev", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "audio device name" }, + { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL } +}; + +static void audin_alsa_parse_addin_args(AudinALSADevice* device, ADDIN_ARGV* args) +{ + int status; + DWORD flags; + COMMAND_LINE_ARGUMENT_A* arg; + AudinALSADevice* alsa = (AudinALSADevice*) device; + + flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON; + + status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv, audin_alsa_args, flags, alsa, NULL, NULL); + + arg = audin_alsa_args; + + do + { + if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT)) + continue; + + CommandLineSwitchStart(arg) + + CommandLineSwitchCase(arg, "audio-dev") + { + alsa->device_name = _strdup(arg->Value); + } + + CommandLineSwitchEnd(arg) + } + while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); +} + #ifdef STATIC_CHANNELS #define freerdp_audin_client_subsystem_entry alsa_freerdp_audin_client_subsystem_entry #endif int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints) { + ADDIN_ARGV* args; AudinALSADevice* alsa; - RDP_PLUGIN_DATA* data; - alsa = xnew(AudinALSADevice); + alsa = (AudinALSADevice*) malloc(sizeof(AudinALSADevice)); + ZeroMemory(alsa, sizeof(AudinALSADevice)); alsa->iface.Open = audin_alsa_open; alsa->iface.FormatSupported = audin_alsa_format_supported; alsa->iface.SetFormat = audin_alsa_set_format; alsa->iface.Close = audin_alsa_close; alsa->iface.Free = audin_alsa_free; - alsa->device_name[0] = '\0'; - data = pEntryPoints->plugin_data; - if (data) - { - char *data2 = (char *) (data->data[2]); - if (data->data[0] && (strcmp(data->data[0], "audin") == 0) && - data->data[1] && (strcmp(data->data[1], "alsa") == 0) && - data2 && (*data2 != '\0')) - { - strncpy(alsa->device_name, data2, sizeof(alsa->device_name)); - } - } + args = pEntryPoints->args; - if (alsa->device_name[0] == '\0') - { - strcpy(alsa->device_name, "default"); - } + audin_alsa_parse_addin_args(alsa, args); + + if (!alsa->device_name) + alsa->device_name = _strdup("default"); alsa->frames_per_packet = 128; alsa->target_rate = 22050; @@ -378,4 +412,3 @@ int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEnt return 0; } - diff --git a/channels/audin/client/audin_main.c b/channels/audin/client/audin_main.c index 85e915c9e..6a01ccd51 100644 --- a/channels/audin/client/audin_main.c +++ b/channels/audin/client/audin_main.c @@ -25,6 +25,9 @@ #include #include +#include +#include + #include #include @@ -78,6 +81,8 @@ struct _AUDIN_PLUGIN UINT16 fixed_format; UINT16 fixed_channel; UINT32 fixed_rate; + char* subsystem; + char* device_name; /* Device interface */ IAudinDevice* device; @@ -437,7 +442,7 @@ static void audin_register_device_plugin(IWTSPlugin* pPlugin, IAudinDevice* devi audin->device = device; } -static BOOL audin_load_device_plugin(IWTSPlugin* pPlugin, const char* name, RDP_PLUGIN_DATA* data) +static BOOL audin_load_device_plugin(IWTSPlugin* pPlugin, const char* name, ADDIN_ARGV* args) { PFREERDP_AUDIN_DEVICE_ENTRY entry; FREERDP_AUDIN_DEVICE_ENTRY_POINTS entryPoints; @@ -449,7 +454,7 @@ static BOOL audin_load_device_plugin(IWTSPlugin* pPlugin, const char* name, RDP_ entryPoints.plugin = pPlugin; entryPoints.pRegisterAudinDevice = audin_register_device_plugin; - entryPoints.plugin_data = data; + entryPoints.args = args; if (entry(&entryPoints) != 0) { @@ -460,54 +465,81 @@ static BOOL audin_load_device_plugin(IWTSPlugin* pPlugin, const char* name, RDP_ return TRUE; } -static BOOL audin_process_plugin_data(IWTSPlugin* pPlugin, RDP_PLUGIN_DATA* data) +void audin_set_subsystem(AUDIN_PLUGIN* audin, char* subsystem) { - BOOL ret; + if (audin->subsystem) + free(audin->subsystem); + + audin->subsystem = _strdup(subsystem); +} + +void audin_set_device_name(AUDIN_PLUGIN* audin, char* device_name) +{ + if (audin->device_name) + free(audin->device_name); + + audin->device_name = _strdup(device_name); +} + +COMMAND_LINE_ARGUMENT_A audin_args[] = +{ + { "sys", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "subsystem" }, + { "dev", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "device" }, + { "format", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "format" }, + { "rate", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "rate" }, + { "channel", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "channel" }, + { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL } +}; + +static BOOL audin_process_addin_args(IWTSPlugin* pPlugin, ADDIN_ARGV* args) +{ + int status; + DWORD flags; + COMMAND_LINE_ARGUMENT_A* arg; AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) pPlugin; - RDP_PLUGIN_DATA default_data[2] = { { 0 }, { 0 } }; - if (data->data[0] && (strcmp((char*)data->data[0], "audin") == 0 || strstr((char*) data->data[0], "/audin.") != NULL)) + flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON; + + status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv, + audin_args, flags, audin, NULL, NULL); + + arg = audin_args; + + do { - if (data->data[1] && strcmp((char*)data->data[1], "format") == 0) - { - audin->fixed_format = atoi(data->data[2]); - return TRUE; - } - else if (data->data[1] && strcmp((char*)data->data[1], "rate") == 0) - { - audin->fixed_rate = atoi(data->data[2]); - return TRUE; - } - else if (data->data[1] && strcmp((char*)data->data[1], "channel") == 0) - { - audin->fixed_channel = atoi(data->data[2]); - return TRUE; - } - else if (data->data[1] && ((char*)data->data[1])[0]) - { - return audin_load_device_plugin(pPlugin, (char*) data->data[1], data); - } - else - { - default_data[0].size = sizeof(RDP_PLUGIN_DATA); - default_data[0].data[0] = "audin"; - default_data[0].data[1] = "pulse"; - default_data[0].data[2] = ""; + if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT)) + continue; - ret = audin_load_device_plugin(pPlugin, "pulse", default_data); + CommandLineSwitchStart(arg) - if (!ret) - { - default_data[0].size = sizeof(RDP_PLUGIN_DATA); - default_data[0].data[0] = "audin"; - default_data[0].data[1] = "alsa"; - default_data[0].data[2] = "default"; - ret = audin_load_device_plugin(pPlugin, "alsa", default_data); - } - - return ret; + CommandLineSwitchCase(arg, "sys") + { + audin_set_subsystem(audin, arg->Value); } + CommandLineSwitchCase(arg, "dev") + { + audin_set_device_name(audin, arg->Value); + } + CommandLineSwitchCase(arg, "format") + { + audin->fixed_format = atoi(arg->Value); + } + CommandLineSwitchCase(arg, "rate") + { + audin->fixed_rate = atoi(arg->Value); + } + CommandLineSwitchCase(arg, "channel") + { + audin->fixed_channel = atoi(arg->Value); + } + CommandLineSwitchDefault(arg) + { + + } + + CommandLineSwitchEnd(arg) } + while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); return TRUE; } @@ -519,23 +551,50 @@ static BOOL audin_process_plugin_data(IWTSPlugin* pPlugin, RDP_PLUGIN_DATA* data int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) { int error = 0; + ADDIN_ARGV* args; AUDIN_PLUGIN* audin; audin = (AUDIN_PLUGIN*) pEntryPoints->GetPlugin(pEntryPoints, "audin"); if (audin == NULL) { - audin = xnew(AUDIN_PLUGIN); + audin = (AUDIN_PLUGIN*) malloc(sizeof(AUDIN_PLUGIN)); + ZeroMemory(audin, sizeof(AUDIN_PLUGIN)); audin->iface.Initialize = audin_plugin_initialize; audin->iface.Connected = NULL; audin->iface.Disconnected = NULL; audin->iface.Terminated = audin_plugin_terminated; + error = pEntryPoints->RegisterPlugin(pEntryPoints, "audin", (IWTSPlugin*) audin); } + args = pEntryPoints->GetPluginData(pEntryPoints); + if (error == 0) - audin_process_plugin_data((IWTSPlugin*) audin, pEntryPoints->GetPluginData(pEntryPoints)); + audin_process_addin_args((IWTSPlugin*) audin, args); + + if (audin->subsystem) + audin_load_device_plugin((IWTSPlugin*) audin, audin->subsystem, args); + + if (!audin->device) + { + audin_set_subsystem(audin, "pulse"); + audin_set_device_name(audin, ""); + audin_load_device_plugin((IWTSPlugin*) audin, audin->subsystem, args); + } + + if (!audin->device) + { + audin_set_subsystem(audin, "alsa"); + audin_set_device_name(audin, "default"); + audin_load_device_plugin((IWTSPlugin*) audin, audin->subsystem, args); + } + + if (audin->device == NULL) + { + DEBUG_WARN("no sound device."); + } return error; } diff --git a/channels/audin/client/audin_main.h b/channels/audin/client/audin_main.h index 4eb30564f..6249382a4 100644 --- a/channels/audin/client/audin_main.h +++ b/channels/audin/client/audin_main.h @@ -26,6 +26,7 @@ #include #include +#include #include #ifdef WITH_DEBUG_DVC @@ -66,7 +67,7 @@ struct _FREERDP_AUDIN_DEVICE_ENTRY_POINTS { IWTSPlugin* plugin; PREGISTERAUDINDEVICE pRegisterAudinDevice; - RDP_PLUGIN_DATA* plugin_data; + ADDIN_ARGV* args; }; typedef struct _FREERDP_AUDIN_DEVICE_ENTRY_POINTS FREERDP_AUDIN_DEVICE_ENTRY_POINTS; typedef FREERDP_AUDIN_DEVICE_ENTRY_POINTS* PFREERDP_AUDIN_DEVICE_ENTRY_POINTS; diff --git a/channels/audin/client/pulse/CMakeLists.txt b/channels/audin/client/pulse/CMakeLists.txt index d0d773636..a183ced3c 100644 --- a/channels/audin/client/pulse/CMakeLists.txt +++ b/channels/audin/client/pulse/CMakeLists.txt @@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS include_directories(..) include_directories(${PULSE_INCLUDE_DIR}) -add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "") +add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "") set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") diff --git a/channels/audin/client/pulse/audin_pulse.c b/channels/audin/client/pulse/audin_pulse.c index 244eb81b5..edd721883 100644 --- a/channels/audin/client/pulse/audin_pulse.c +++ b/channels/audin/client/pulse/audin_pulse.c @@ -25,8 +25,13 @@ #include #include +#include +#include + #include + #include +#include #include #include @@ -36,7 +41,7 @@ typedef struct _AudinPulseDevice { IAudinDevice iface; - char device_name[32]; + char* device_name; UINT32 frames_per_packet; pa_threaded_mainloop* mainloop; pa_context* context; @@ -430,16 +435,53 @@ static void audin_pulse_open(IAudinDevice* device, AudinReceive receive, void* u } } +COMMAND_LINE_ARGUMENT_A audin_pulse_args[] = +{ + { "audio-dev", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "audio device name" }, + { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL } +}; + +static void audin_pulse_parse_addin_args(AudinPulseDevice* device, ADDIN_ARGV* args) +{ + int status; + DWORD flags; + COMMAND_LINE_ARGUMENT_A* arg; + AudinPulseDevice* pulse = (AudinPulseDevice*) device; + + flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON; + + status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv, audin_pulse_args, flags, pulse, NULL, NULL); + + arg = audin_pulse_args; + + do + { + if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT)) + continue; + + CommandLineSwitchStart(arg) + + CommandLineSwitchCase(arg, "audio-dev") + { + pulse->device_name = _strdup(arg->Value); + } + + CommandLineSwitchEnd(arg) + } + while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); +} + #ifdef STATIC_CHANNELS #define freerdp_audin_client_subsystem_entry pulse_freerdp_audin_client_subsystem_entry #endif int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints) { + ADDIN_ARGV* args; AudinPulseDevice* pulse; - RDP_PLUGIN_DATA * data; - pulse = xnew(AudinPulseDevice); + pulse = (AudinPulseDevice*) malloc(sizeof(AudinPulseDevice)); + ZeroMemory(pulse, sizeof(AudinPulseDevice)); pulse->iface.Open = audin_pulse_open; pulse->iface.FormatSupported = audin_pulse_format_supported; @@ -447,30 +489,35 @@ int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEnt pulse->iface.Close = audin_pulse_close; pulse->iface.Free = audin_pulse_free; - data = pEntryPoints->plugin_data; - if (data && data->data[0] && strcmp(data->data[0], "audin") == 0 && - data->data[1] && strcmp(data->data[1], "pulse") == 0) - { - strncpy(pulse->device_name, (char*)data->data[2], sizeof(pulse->device_name)); - } + args = pEntryPoints->args; + + audin_pulse_parse_addin_args(pulse, args); + + if (!pulse->device_name) + pulse->device_name = _strdup("default"); pulse->dsp_context = freerdp_dsp_context_new(); pulse->mainloop = pa_threaded_mainloop_new(); + if (!pulse->mainloop) { DEBUG_WARN("pa_threaded_mainloop_new failed"); audin_pulse_free((IAudinDevice*) pulse); return 1; } + pulse->context = pa_context_new(pa_threaded_mainloop_get_api(pulse->mainloop), "freerdp"); + if (!pulse->context) { DEBUG_WARN("pa_context_new failed"); audin_pulse_free((IAudinDevice*) pulse); return 1; } + pa_context_set_state_callback(pulse->context, audin_pulse_context_state_callback, pulse); + if (!audin_pulse_connect((IAudinDevice*) pulse)) { audin_pulse_free((IAudinDevice*) pulse); @@ -481,4 +528,3 @@ int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEnt return 0; } - diff --git a/channels/client/CMakeLists.txt b/channels/client/CMakeLists.txt index fb633c387..5733f5b5b 100644 --- a/channels/client/CMakeLists.txt +++ b/channels/client/CMakeLists.txt @@ -62,12 +62,24 @@ foreach(STATIC_MODULE ${CHANNEL_STATIC_CLIENT_MODULES}) if(CHANNEL_SUBSYSTEMS MATCHES "NOTFOUND") set(CHANNEL_SUBSYSTEMS "") endif() + message(STATUS "Channel: ${STATIC_MODULE_CHANNEL} Subsystems: ${CHANNEL_SUBSYSTEMS}") foreach(STATIC_SUBSYSTEM ${CHANNEL_SUBSYSTEMS}) - string(TOUPPER "${STATIC_MODULE}_CLIENT_${STATIC_SUBSYSTEM}" SUBSYSTEM_PREFIX) + if(${STATIC_SUBSYSTEM} MATCHES "^([^-]*)-(.*)") + string(REGEX REPLACE "^([^-]*)-(.*)" "\\1" STATIC_SUBSYSTEM_NAME ${STATIC_SUBSYSTEM}) + string(REGEX REPLACE "^([^-]*)-(.*)" "\\2" STATIC_SUBSYSTEM_TYPE ${STATIC_SUBSYSTEM}) + else() + set(STATIC_SUBSYSTEM_NAME "${STATIC_SUBSYSTEM}") + set(STATIC_SUBSYSTEM_TYPE "") + endif() + string(LENGTH "${STATIC_SUBSYSTEM_TYPE}" _type_length) set(SUBSYSTEM_MODULE_NAME "${STATIC_MODULE_NAME}-${STATIC_SUBSYSTEM}") set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${SUBSYSTEM_MODULE_NAME}) - set(STATIC_SUBSYSTEM_ENTRY "${STATIC_SUBSYSTEM}_freerdp_${STATIC_MODULE_CHANNEL}_client_subsystem_entry") - set(SUBSYSTEM_TABLE "${SUBSYSTEM_TABLE}\n\t{ \"${STATIC_SUBSYSTEM}\", \"\", ${STATIC_SUBSYSTEM_ENTRY} },") + if(_type_length GREATER 0) + set(STATIC_SUBSYSTEM_ENTRY "${STATIC_SUBSYSTEM_NAME}_freerdp_${STATIC_MODULE_CHANNEL}_client_${STATIC_SUBSYSTEM_TYPE}_subsystem_entry") + else() + set(STATIC_SUBSYSTEM_ENTRY "${STATIC_SUBSYSTEM_NAME}_freerdp_${STATIC_MODULE_CHANNEL}_client_subsystem_entry") + endif() + set(SUBSYSTEM_TABLE "${SUBSYSTEM_TABLE}\n\t{ \"${STATIC_SUBSYSTEM_NAME}\", \"${STATIC_SUBSYSTEM_TYPE}\", ${STATIC_SUBSYSTEM_ENTRY} },") set(SUBSYSTEM_IMPORT "extern void ${STATIC_SUBSYSTEM_ENTRY}();") set(CLIENT_STATIC_SUBSYSTEM_IMPORTS "${CLIENT_STATIC_SUBSYSTEM_IMPORTS}\n${SUBSYSTEM_IMPORT}") endforeach() diff --git a/channels/client/channels.c b/channels/client/channels.c index c4a75b778..4f4b84deb 100644 --- a/channels/client/channels.c +++ b/channels/client/channels.c @@ -361,7 +361,10 @@ void* freerdp_channels_load_static_addin_entry(LPCSTR pszName, LPSTR pszSubsyste } else { - return (void*) CLIENT_STATIC_ADDIN_TABLE[i].entry; + if (strcmp(CLIENT_STATIC_ADDIN_TABLE[i].name, pszName) == 0) + { + return (void*) CLIENT_STATIC_ADDIN_TABLE[i].entry; + } } } @@ -990,7 +993,7 @@ int freerdp_channels_client_load(rdpChannels* channels, rdpSettings* settings, v if (channels->num_libs_data + 1 >= CHANNEL_MAX_COUNT) { - DEBUG_CHANNELS("too many channels"); + printf("error: too many channels\n"); return 1; } @@ -1024,7 +1027,7 @@ int freerdp_channels_client_load(rdpChannels* channels, rdpSettings* settings, v if (!status) { - DEBUG_CHANNELS("export function call failed"); + printf("error: channel export function call failed\n"); return 1; } diff --git a/channels/drdynvc/client/drdynvc_main.c b/channels/drdynvc/client/drdynvc_main.c index c4a189035..c9e0ebc87 100644 --- a/channels/drdynvc/client/drdynvc_main.c +++ b/channels/drdynvc/client/drdynvc_main.c @@ -37,11 +37,11 @@ #include "drdynvc_types.h" #include "drdynvc_main.h" -#define CREATE_REQUEST_PDU 0x01 -#define DATA_FIRST_PDU 0x02 -#define DATA_PDU 0x03 -#define CLOSE_REQUEST_PDU 0x04 -#define CAPABILITY_REQUEST_PDU 0x05 +#define CREATE_REQUEST_PDU 0x01 +#define DATA_FIRST_PDU 0x02 +#define DATA_PDU 0x03 +#define CLOSE_REQUEST_PDU 0x04 +#define CAPABILITY_REQUEST_PDU 0x05 struct drdynvc_plugin { @@ -76,6 +76,7 @@ static int drdynvc_write_variable_uint(STREAM* stream, UINT32 val) cb = 2; stream_write_UINT32(stream, val); } + return cb; } @@ -97,13 +98,13 @@ int drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, BYTE* data, UIN stream_set_pos(data_out, 1); cbChId = drdynvc_write_variable_uint(data_out, ChannelId); - if(data_size == 0) + if (data_size == 0) { pos = stream_get_pos(data_out); stream_set_pos(data_out, 0); stream_write_BYTE(data_out, 0x40 | cbChId); stream_set_pos(data_out, pos); - error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out); + error = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out); } else if (data_size <= CHANNEL_CHUNK_LENGTH - pos) { @@ -112,7 +113,7 @@ int drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, BYTE* data, UIN stream_write_BYTE(data_out, 0x30 | cbChId); stream_set_pos(data_out, pos); stream_write(data_out, data, data_size); - error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out); + error = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out); } else { @@ -126,7 +127,7 @@ int drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, BYTE* data, UIN stream_write(data_out, data, chunk_len); data += chunk_len; data_size -= chunk_len; - error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out); + error = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out); while (error == CHANNEL_RC_OK && data_size > 0) { @@ -148,12 +149,14 @@ int drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, BYTE* data, UIN error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out); } } + if (error != CHANNEL_RC_OK) { drdynvc->channel_error = error; DEBUG_WARN("VirtualChannelWrite failed %d", error); return 1; } + return 0; } @@ -161,12 +164,14 @@ int drdynvc_push_event(drdynvcPlugin* drdynvc, RDP_EVENT* event) { int error; - error = svc_plugin_send_event((rdpSvcPlugin*)drdynvc, event); + error = svc_plugin_send_event((rdpSvcPlugin*) drdynvc, event); + if (error != CHANNEL_RC_OK) { DEBUG_WARN("pVirtualChannelEventPush failed %d", error); return 1; } + return 0; } @@ -178,6 +183,7 @@ static int drdynvc_process_capability_request(drdynvcPlugin* drdynvc, int Sp, in DEBUG_DVC("Sp=%d cbChId=%d", Sp, cbChId); stream_seek(s, 1); /* pad */ stream_read_UINT16(s, drdynvc->version); + if (drdynvc->version == 2) { stream_read_UINT16(s, drdynvc->PriorityCharge0); @@ -185,15 +191,18 @@ static int drdynvc_process_capability_request(drdynvcPlugin* drdynvc, int Sp, in stream_read_UINT16(s, drdynvc->PriorityCharge2); stream_read_UINT16(s, drdynvc->PriorityCharge3); } + data_out = stream_new(4); stream_write_UINT16(data_out, 0x0050); /* Cmd+Sp+cbChId+Pad. Note: MSTSC sends 0x005c */ stream_write_UINT16(data_out, drdynvc->version); - error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out); + error = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out); + if (error != CHANNEL_RC_OK) { DEBUG_WARN("VirtualChannelWrite failed %d", error); return 1; } + drdynvc->channel_error = error; return 0; @@ -208,28 +217,31 @@ static UINT32 drdynvc_read_variable_uint(STREAM* stream, int cbLen) case 0: stream_read_BYTE(stream, val); break; + case 1: stream_read_UINT16(stream, val); break; + default: stream_read_UINT32(stream, val); break; } + return val; } static int drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, int cbChId, STREAM* s) { - STREAM* data_out; int pos; int error; UINT32 ChannelId; + STREAM* data_out; ChannelId = drdynvc_read_variable_uint(s, cbChId); pos = stream_get_pos(s); DEBUG_DVC("ChannelId=%d ChannelName=%s", ChannelId, stream_get_tail(s)); - error = dvcman_create_channel(drdynvc->channel_mgr, ChannelId, (char*)stream_get_tail(s)); + error = dvcman_create_channel(drdynvc->channel_mgr, ChannelId, (char*) stream_get_tail(s)); data_out = stream_new(pos + 4); stream_write_BYTE(data_out, 0x10 | cbChId); @@ -247,26 +259,29 @@ static int drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, int cb stream_write_UINT32(data_out, (UINT32)(-1)); } - error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out); + error = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out); + if (error != CHANNEL_RC_OK) { DEBUG_WARN("VirtualChannelWrite failed %d", error); return 1; } + return 0; } static int drdynvc_process_data_first(drdynvcPlugin* drdynvc, int Sp, int cbChId, STREAM* s) { - UINT32 ChannelId; - UINT32 Length; int error; + UINT32 Length; + UINT32 ChannelId; ChannelId = drdynvc_read_variable_uint(s, cbChId); Length = drdynvc_read_variable_uint(s, Sp); DEBUG_DVC("ChannelId=%d Length=%d", ChannelId, Length); error = dvcman_receive_channel_data_first(drdynvc->channel_mgr, ChannelId, Length); + if (error) return error; @@ -298,11 +313,11 @@ static int drdynvc_process_close_request(drdynvcPlugin* drdynvc, int Sp, int cbC static void drdynvc_process_receive(rdpSvcPlugin* plugin, STREAM* s) { - drdynvcPlugin* drdynvc = (drdynvcPlugin*)plugin; int value; int Cmd; int Sp; int cbChId; + drdynvcPlugin* drdynvc = (drdynvcPlugin*) plugin; stream_read_BYTE(s, value); Cmd = (value & 0xf0) >> 4; @@ -338,13 +353,24 @@ static void drdynvc_process_receive(rdpSvcPlugin* plugin, STREAM* s) static void drdynvc_process_connect(rdpSvcPlugin* plugin) { + int index; + ADDIN_ARGV* args; + rdpSettings* settings; drdynvcPlugin* drdynvc = (drdynvcPlugin*)plugin; DEBUG_DVC("connecting"); drdynvc->channel_mgr = dvcman_new(drdynvc); drdynvc->channel_error = 0; - dvcman_load_plugin(drdynvc->channel_mgr, svc_plugin_get_data(plugin)); + + settings = (rdpSettings*) ((rdpSvcPlugin*) plugin)->channel_entry_points.pExtendedData; + + for (index = 0; index < settings->DynamicChannelCount; index++) + { + args = settings->DynamicChannelArray[index]; + dvcman_load_addin(drdynvc->channel_mgr, args); + } + dvcman_init(drdynvc->channel_mgr); } @@ -355,7 +381,7 @@ static void drdynvc_process_event(rdpSvcPlugin* plugin, RDP_EVENT* event) static void drdynvc_process_terminate(rdpSvcPlugin* plugin) { - drdynvcPlugin* drdynvc = (drdynvcPlugin*)plugin; + drdynvcPlugin* drdynvc = (drdynvcPlugin*) plugin; DEBUG_DVC("terminating"); @@ -391,4 +417,3 @@ int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) return 1; } - diff --git a/channels/drdynvc/client/dvcman.c b/channels/drdynvc/client/dvcman.c index 17807a858..39c6385b0 100644 --- a/channels/drdynvc/client/dvcman.c +++ b/channels/drdynvc/client/dvcman.c @@ -74,7 +74,7 @@ struct _DVCMAN_ENTRY_POINTS IDRDYNVC_ENTRY_POINTS iface; DVCMAN* dvcman; - RDP_PLUGIN_DATA* plugin_data; + ADDIN_ARGV* args; }; typedef struct _DVCMAN_CHANNEL DVCMAN_CHANNEL; @@ -183,14 +183,14 @@ IWTSPlugin* dvcman_get_plugin(IDRDYNVC_ENTRY_POINTS* pEntryPoints, const char* n return NULL; } -RDP_PLUGIN_DATA* dvcman_get_plugin_data(IDRDYNVC_ENTRY_POINTS* pEntryPoints) +ADDIN_ARGV* dvcman_get_plugin_data(IDRDYNVC_ENTRY_POINTS* pEntryPoints) { - return ((DVCMAN_ENTRY_POINTS*) pEntryPoints)->plugin_data; + return ((DVCMAN_ENTRY_POINTS*) pEntryPoints)->args; } UINT32 dvcman_get_channel_id(IWTSVirtualChannel * channel) { - return ((DVCMAN_CHANNEL*)channel)->channel_id; + return ((DVCMAN_CHANNEL*) channel)->channel_id; } IWTSVirtualChannel* dvcman_find_channel_by_id(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId) @@ -202,7 +202,7 @@ IWTSVirtualChannel* dvcman_find_channel_by_id(IWTSVirtualChannelManager* pChanne { if (((DVCMAN_CHANNEL*) curr->data)->channel_id == ChannelId) { - return (IWTSVirtualChannel*)curr->data; + return (IWTSVirtualChannel*) curr->data; } } @@ -224,29 +224,24 @@ IWTSVirtualChannelManager* dvcman_new(drdynvcPlugin* plugin) return (IWTSVirtualChannelManager*) dvcman; } -int dvcman_load_plugin(IWTSVirtualChannelManager* pChannelMgr, RDP_PLUGIN_DATA* data) +int dvcman_load_addin(IWTSVirtualChannelManager* pChannelMgr, ADDIN_ARGV* args) { DVCMAN_ENTRY_POINTS entryPoints; PDVC_PLUGIN_ENTRY pDVCPluginEntry = NULL; - while (data && data->size > 0) + printf("Loading Dynamic Virtual Channel %s\n", args->argv[0]); + + pDVCPluginEntry = (PDVC_PLUGIN_ENTRY) freerdp_load_channel_addin_entry(args->argv[0], + NULL, NULL, FREERDP_ADDIN_CHANNEL_DYNAMIC); + + if (pDVCPluginEntry != NULL) { - printf("Loading Dynamic Virtual Channel %s\n", data->data[0]); - - pDVCPluginEntry = (PDVC_PLUGIN_ENTRY) freerdp_load_channel_addin_entry((char*) data->data[0], - NULL, NULL, FREERDP_ADDIN_CHANNEL_DYNAMIC); - - if (pDVCPluginEntry != NULL) - { - entryPoints.iface.RegisterPlugin = dvcman_register_plugin; - entryPoints.iface.GetPlugin = dvcman_get_plugin; - entryPoints.iface.GetPluginData = dvcman_get_plugin_data; - entryPoints.dvcman = (DVCMAN*) pChannelMgr; - entryPoints.plugin_data = data; - pDVCPluginEntry((IDRDYNVC_ENTRY_POINTS*) &entryPoints); - } - - data = (RDP_PLUGIN_DATA*)(((BYTE*) data) + data->size); + entryPoints.iface.RegisterPlugin = dvcman_register_plugin; + entryPoints.iface.GetPlugin = dvcman_get_plugin; + entryPoints.iface.GetPluginData = dvcman_get_plugin_data; + entryPoints.dvcman = (DVCMAN*) pChannelMgr; + entryPoints.args = args; + pDVCPluginEntry((IDRDYNVC_ENTRY_POINTS*) &entryPoints); } return 0; @@ -346,7 +341,7 @@ int dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 Channel for (i = 0; i < dvcman->num_listeners; i++) { - listener = (DVCMAN_LISTENER*)dvcman->listeners[i]; + listener = (DVCMAN_LISTENER*) dvcman->listeners[i]; if (strcmp(listener->channel_name, ChannelName) == 0) { @@ -382,7 +377,6 @@ int dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 Channel return 1; } - int dvcman_close_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId) { DVCMAN_CHANNEL* channel; diff --git a/channels/drdynvc/client/dvcman.h b/channels/drdynvc/client/dvcman.h index 479434187..c41835a0f 100644 --- a/channels/drdynvc/client/dvcman.h +++ b/channels/drdynvc/client/dvcman.h @@ -21,10 +21,12 @@ #define __DVCMAN_H #include +#include + #include "drdynvc_main.h" IWTSVirtualChannelManager* dvcman_new(drdynvcPlugin* plugin); -int dvcman_load_plugin(IWTSVirtualChannelManager* pChannelMgr, RDP_PLUGIN_DATA* data); +int dvcman_load_addin(IWTSVirtualChannelManager* pChannelMgr, ADDIN_ARGV* args); void dvcman_free(IWTSVirtualChannelManager* pChannelMgr); int dvcman_init(IWTSVirtualChannelManager* pChannelMgr); int dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId, const char* ChannelName); diff --git a/channels/rdpsnd/client/alsa/CMakeLists.txt b/channels/rdpsnd/client/alsa/CMakeLists.txt index 8e5696cbb..0f2afc47b 100644 --- a/channels/rdpsnd/client/alsa/CMakeLists.txt +++ b/channels/rdpsnd/client/alsa/CMakeLists.txt @@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS include_directories(..) include_directories(${ALSA_INCLUDE_DIRS}) -add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "") +add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "") set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") diff --git a/channels/rdpsnd/client/alsa/rdpsnd_alsa.c b/channels/rdpsnd/client/alsa/rdpsnd_alsa.c index 29dc5c3f7..b978c8053 100644 --- a/channels/rdpsnd/client/alsa/rdpsnd_alsa.c +++ b/channels/rdpsnd/client/alsa/rdpsnd_alsa.c @@ -462,7 +462,8 @@ int freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pE ADDIN_ARGV* args; rdpsndAlsaPlugin* alsa; - alsa = xnew(rdpsndAlsaPlugin); + alsa = (rdpsndAlsaPlugin*) malloc(sizeof(rdpsndAlsaPlugin)); + ZeroMemory(alsa, sizeof(rdpsndAlsaPlugin)); alsa->device.Open = rdpsnd_alsa_open; alsa->device.FormatSupported = rdpsnd_alsa_format_supported; diff --git a/channels/rdpsnd/client/mac/CMakeLists.txt b/channels/rdpsnd/client/mac/CMakeLists.txt index 0074888f0..9dd538eb7 100644 --- a/channels/rdpsnd/client/mac/CMakeLists.txt +++ b/channels/rdpsnd/client/mac/CMakeLists.txt @@ -24,7 +24,7 @@ set(${MODULE_PREFIX}_SRCS include_directories(..) include_directories(${MACAUDIO_INCLUDE_DIRS}) -add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "") +add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "") set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") diff --git a/channels/rdpsnd/client/pulse/CMakeLists.txt b/channels/rdpsnd/client/pulse/CMakeLists.txt index 40568d6f3..d14f5c85a 100644 --- a/channels/rdpsnd/client/pulse/CMakeLists.txt +++ b/channels/rdpsnd/client/pulse/CMakeLists.txt @@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS include_directories(..) include_directories(${PULSE_INCLUDE_DIR}) -add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "") +add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "") set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") diff --git a/channels/tsmf/CMakeLists.txt b/channels/tsmf/CMakeLists.txt index 7776633de..8b4073eb0 100644 --- a/channels/tsmf/CMakeLists.txt +++ b/channels/tsmf/CMakeLists.txt @@ -20,5 +20,3 @@ define_channel("tsmf") if(WITH_CLIENT_CHANNELS) add_channel_client(${MODULE_PREFIX} ${CHANNEL_NAME}) endif() - - diff --git a/channels/tsmf/client/CMakeLists.txt b/channels/tsmf/client/CMakeLists.txt index d12ab79b8..e4560ab5c 100644 --- a/channels/tsmf/client/CMakeLists.txt +++ b/channels/tsmf/client/CMakeLists.txt @@ -43,7 +43,7 @@ set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHIC_BUILD} MODULE freerdp - MODULES freerdp-utils) + MODULES freerdp-utils freerdp-common) target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) @@ -54,19 +54,19 @@ endif() set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client") if(WITH_FFMPEG) - add_subdirectory(ffmpeg) + add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "ffmpeg" "decoder") endif() if(WITH_XRANDR) if(GSTREAMER_FOUND) - add_subdirectory(gstreamer) + add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "gstreamer" "decoder") endif() endif() if(WITH_ALSA) - add_subdirectory(alsa) + add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "alsa" "audio") endif() if(WITH_PULSE) - add_subdirectory(pulse) + add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "pulse" "audio") endif() diff --git a/channels/tsmf/client/alsa/CMakeLists.txt b/channels/tsmf/client/alsa/CMakeLists.txt index fac1c8289..2ad1dcb71 100644 --- a/channels/tsmf/client/alsa/CMakeLists.txt +++ b/channels/tsmf/client/alsa/CMakeLists.txt @@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS include_directories(..) include_directories(${ALSA_INCLUDE_DIRS}) -add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) +add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "") set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") @@ -36,6 +36,6 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${ALSA_LIBRARIES}) target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) -install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH}) - - +if(NOT STATIC_CHANNELS) + install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH}) +endif() diff --git a/channels/tsmf/client/alsa/tsmf_alsa.c b/channels/tsmf/client/alsa/tsmf_alsa.c index 176e89dce..83a3ba131 100644 --- a/channels/tsmf/client/alsa/tsmf_alsa.c +++ b/channels/tsmf/client/alsa/tsmf_alsa.c @@ -26,7 +26,11 @@ #include #include #include + +#include + #include + #include #include #include @@ -248,11 +252,16 @@ static void tsmf_alsa_free(ITSMFAudioDevice* audio) free(alsa); } -ITSMFAudioDevice* TSMFAudioDeviceEntry(void) +#ifdef STATIC_CHANNELS +#define freerdp_tsmf_client_audio_subsystem_entry alsa_freerdp_tsmf_client_audio_subsystem_entry +#endif + +ITSMFAudioDevice* freerdp_tsmf_client_audio_subsystem_entry(void) { TSMFALSAAudioDevice* alsa; - alsa = xnew(TSMFALSAAudioDevice); + alsa = (TSMFALSAAudioDevice*) malloc(sizeof(TSMFALSAAudioDevice)); + ZeroMemory(alsa, sizeof(TSMFALSAAudioDevice)); alsa->iface.Open = tsmf_alsa_open; alsa->iface.SetFormat = tsmf_alsa_set_format; @@ -265,4 +274,3 @@ ITSMFAudioDevice* TSMFAudioDeviceEntry(void) return (ITSMFAudioDevice*) alsa; } - diff --git a/channels/tsmf/client/ffmpeg/CMakeLists.txt b/channels/tsmf/client/ffmpeg/CMakeLists.txt index d7bd66162..ddb4e7c62 100644 --- a/channels/tsmf/client/ffmpeg/CMakeLists.txt +++ b/channels/tsmf/client/ffmpeg/CMakeLists.txt @@ -15,7 +15,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -define_channel_client_subsystem("tsmf" "ffmpeg" "video") +define_channel_client_subsystem("tsmf" "ffmpeg" "decoder") set(${MODULE_PREFIX}_SRCS tsmf_ffmpeg.c) @@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS include_directories(..) include_directories(${FFMPEG_INCLUDE_DIRS}) -add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) +add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "") set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") @@ -36,4 +36,6 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${FFMPEG_LIBRARIES}) target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) -install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH}) +if(NOT STATIC_CHANNELS) + install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH}) +endif() diff --git a/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c b/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c index c45989cf7..6d93f82be 100644 --- a/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c +++ b/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c @@ -25,6 +25,8 @@ #include #include +#include + #include #include #include @@ -60,6 +62,7 @@ static BOOL tsmf_ffmpeg_init_context(ITSMFDecoder* decoder) TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder; mdecoder->codec_context = avcodec_alloc_context3(NULL); + if (!mdecoder->codec_context) { DEBUG_WARN("avcodec_alloc_context failed."); @@ -108,12 +111,13 @@ static BOOL tsmf_ffmpeg_init_audio_stream(ITSMFDecoder* decoder, const TS_AM_MED static BOOL tsmf_ffmpeg_init_stream(ITSMFDecoder* decoder, const TS_AM_MEDIA_TYPE* media_type) { - TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder; + BYTE* p; UINT32 size; const BYTE* s; - BYTE* p; + TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder; mdecoder->codec = avcodec_find_decoder(mdecoder->codec_id); + if (!mdecoder->codec) { DEBUG_WARN("avcodec_find_decoder failed."); @@ -345,7 +349,7 @@ static BOOL tsmf_ffmpeg_decode_audio(ITSMFDecoder* decoder, const BYTE* data, UI mdecoder->decoded_size_max = AVCODEC_MAX_AUDIO_FRAME_SIZE + 16; mdecoder->decoded_data = xzalloc(mdecoder->decoded_size_max); /* align the memory for SSE2 needs */ - dst = (BYTE*) (((uintptr_t)mdecoder->decoded_data + 15) & ~ 0x0F); + dst = (BYTE*) (((uintptr_t) mdecoder->decoded_data + 15) & ~ 0x0F); dst_offset = dst - mdecoder->decoded_data; src = data; src_size = data_size; @@ -373,7 +377,7 @@ static BOOL tsmf_ffmpeg_decode_audio(ITSMFDecoder* decoder, const BYTE* data, UI (int16_t*) dst, &frame_size, src, src_size); #else { - AVFrame* decoded_frame = avcodec_alloc_frame(); + AVFrame* decoded_frame = avcodec_alloc_frame(); int got_frame = 0; AVPacket pkt; av_init_packet(&pkt); @@ -383,7 +387,7 @@ static BOOL tsmf_ffmpeg_decode_audio(ITSMFDecoder* decoder, const BYTE* data, UI if (len >= 0 && got_frame) { - frame_size = av_samples_get_buffer_size(NULL, mdecoder->codec_context->channels, + frame_size = av_samples_get_buffer_size(NULL, mdecoder->codec_context->channels, decoded_frame->nb_samples, mdecoder->codec_context->sample_fmt, 1); memcpy(dst, decoded_frame->data[0], frame_size); } @@ -396,6 +400,7 @@ static BOOL tsmf_ffmpeg_decode_audio(ITSMFDecoder* decoder, const BYTE* data, UI DEBUG_WARN("error decoding"); break; } + src += len; src_size -= len; mdecoder->decoded_size += frame_size; @@ -444,13 +449,14 @@ static BOOL tsmf_ffmpeg_decode(ITSMFDecoder* decoder, const BYTE* data, UINT32 d static BYTE* tsmf_ffmpeg_get_decoded_data(ITSMFDecoder* decoder, UINT32* size) { - TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder; BYTE* buf; + TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder; *size = mdecoder->decoded_size; buf = mdecoder->decoded_data; mdecoder->decoded_data = NULL; mdecoder->decoded_size = 0; + return buf; } @@ -492,8 +498,10 @@ static void tsmf_ffmpeg_free(ITSMFDecoder* decoder) if (mdecoder->frame) av_free(mdecoder->frame); + if (mdecoder->decoded_data) free(mdecoder->decoded_data); + if (mdecoder->codec_context) { if (mdecoder->prepared) @@ -502,12 +510,17 @@ static void tsmf_ffmpeg_free(ITSMFDecoder* decoder) free(mdecoder->codec_context->extradata); av_free(mdecoder->codec_context); } + free(decoder); } static BOOL initialized = FALSE; -ITSMFDecoder* TSMFDecoderEntry(void) +#ifdef STATIC_CHANNELS +#define freerdp_tsmf_client_decoder_subsystem_entry ffmpeg_freerdp_tsmf_client_decoder_subsystem_entry +#endif + +ITSMFDecoder* freerdp_tsmf_client_decoder_subsystem_entry(void) { TSMFFFmpegDecoder* decoder; @@ -517,7 +530,10 @@ ITSMFDecoder* TSMFDecoderEntry(void) initialized = TRUE; } - decoder = xnew(TSMFFFmpegDecoder); + printf("TSMFDecoderEntry FFMPEG\n"); + + decoder = (TSMFFFmpegDecoder*) malloc(sizeof(TSMFFFmpegDecoder)); + ZeroMemory(decoder, sizeof(TSMFFFmpegDecoder)); decoder->iface.SetFormat = tsmf_ffmpeg_set_format; decoder->iface.Decode = tsmf_ffmpeg_decode; @@ -528,4 +544,3 @@ ITSMFDecoder* TSMFDecoderEntry(void) return (ITSMFDecoder*) decoder; } - diff --git a/channels/tsmf/client/gstreamer/CMakeLists.txt b/channels/tsmf/client/gstreamer/CMakeLists.txt index 2276dd484..872831c36 100644 --- a/channels/tsmf/client/gstreamer/CMakeLists.txt +++ b/channels/tsmf/client/gstreamer/CMakeLists.txt @@ -15,7 +15,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -define_channel_client_subsystem("tsmf" "gstreamer" "video") +define_channel_client_subsystem("tsmf" "gstreamer" "decoder") set(${MODULE_PREFIX}_SRCS tsmf_gstreamer.c) @@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS include_directories(..) include_directories(${GSTREAMER_INCLUDE_DIRS}) -add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) +add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "") set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") @@ -40,4 +40,6 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) -install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH}) +if(NOT STATIC_CHANNELS) + install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH}) +endif() diff --git a/channels/tsmf/client/gstreamer/tsmf_gstreamer.c b/channels/tsmf/client/gstreamer/tsmf_gstreamer.c index 2dee3189b..9e2c1674d 100644 --- a/channels/tsmf/client/gstreamer/tsmf_gstreamer.c +++ b/channels/tsmf/client/gstreamer/tsmf_gstreamer.c @@ -1565,10 +1565,13 @@ static void tsmf_gstreamer_update_rendering_area(ITSMFDecoder * decoder, int new static int initialized = 0; -ITSMFDecoder * -TSMFDecoderEntry(void) +#ifdef STATIC_CHANNELS +#define freerdp_tsmf_client_decoder_subsystem_entry gstreamer_freerdp_tsmf_client_decoder_subsystem_entry +#endif + +ITSMFDecoder* freerdp_tsmf_client_decoder_subsystem_entry(void) { - TSMFGstreamerDecoder * decoder; + TSMFGstreamerDecoder* decoder; if (!initialized) { diff --git a/channels/tsmf/client/pulse/CMakeLists.txt b/channels/tsmf/client/pulse/CMakeLists.txt index 6c9965450..613485b80 100644 --- a/channels/tsmf/client/pulse/CMakeLists.txt +++ b/channels/tsmf/client/pulse/CMakeLists.txt @@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS include_directories(..) include_directories(${PULSE_INCLUDE_DIR}) -add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) +add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "") set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") @@ -36,4 +36,7 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${PULSE_LIBRARY}) target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) -install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH}) +if(NOT STATIC_CHANNELS) + install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH}) +endif() + diff --git a/channels/tsmf/client/pulse/tsmf_pulse.c b/channels/tsmf/client/pulse/tsmf_pulse.c index 4d3bc35f2..92cf0d0ae 100644 --- a/channels/tsmf/client/pulse/tsmf_pulse.c +++ b/channels/tsmf/client/pulse/tsmf_pulse.c @@ -26,7 +26,10 @@ #include #include +#include + #include + #include #include "tsmf_audio.h" @@ -389,11 +392,16 @@ static void tsmf_pulse_free(ITSMFAudioDevice* audio) free(pulse); } -ITSMFAudioDevice* TSMFAudioDeviceEntry(void) +#ifdef STATIC_CHANNELS +#define freerdp_tsmf_client_audio_subsystem_entry pulse_freerdp_tsmf_client_audio_subsystem_entry +#endif + +ITSMFAudioDevice* freerdp_tsmf_client_audio_subsystem_entry(void) { TSMFPulseAudioDevice* pulse; - pulse = xnew(TSMFPulseAudioDevice); + pulse = (TSMFPulseAudioDevice*) malloc(sizeof(TSMFPulseAudioDevice)); + ZeroMemory(pulse, sizeof(TSMFPulseAudioDevice)); pulse->iface.Open = tsmf_pulse_open; pulse->iface.SetFormat = tsmf_pulse_set_format; diff --git a/channels/tsmf/client/tsmf_audio.c b/channels/tsmf/client/tsmf_audio.c index dfe8793f6..ce4398227 100644 --- a/channels/tsmf/client/tsmf_audio.c +++ b/channels/tsmf/client/tsmf_audio.c @@ -34,34 +34,26 @@ static ITSMFAudioDevice* tsmf_load_audio_device_by_name(const char* name, const { ITSMFAudioDevice* audio; TSMF_AUDIO_DEVICE_ENTRY entry; - char* fullname; - if (strrchr(name, '.') != NULL) - entry = (TSMF_AUDIO_DEVICE_ENTRY) freerdp_load_plugin(name, TSMF_AUDIO_DEVICE_EXPORT_FUNC_NAME); - else - { - fullname = xzalloc(strlen(name) + 6); - strcpy(fullname, "tsmf_"); - strcat(fullname, name); - entry = (TSMF_AUDIO_DEVICE_ENTRY) freerdp_load_plugin(fullname, TSMF_AUDIO_DEVICE_EXPORT_FUNC_NAME); - free(fullname); - } + entry = (TSMF_AUDIO_DEVICE_ENTRY) freerdp_load_channel_addin_entry("tsmf", (LPSTR) name, "audio", 0); + if (entry == NULL) - { return NULL; - } audio = entry(); + if (audio == NULL) { DEBUG_WARN("failed to call export function in %s", name); return NULL; } + if (!audio->Open(audio, device)) { audio->Free(audio); audio = NULL; } + return audio; } @@ -76,6 +68,7 @@ ITSMFAudioDevice* tsmf_load_audio_device(const char* name, const char* device) else { audio = tsmf_load_audio_device_by_name("pulse", device); + if (!audio) audio = tsmf_load_audio_device_by_name("alsa", device); } diff --git a/channels/tsmf/client/tsmf_decoder.c b/channels/tsmf/client/tsmf_decoder.c index b9b850198..dabda3fdc 100644 --- a/channels/tsmf/client/tsmf_decoder.c +++ b/channels/tsmf/client/tsmf_decoder.c @@ -25,31 +25,22 @@ #include #include +#include +#include + #include #include -#include - #include "tsmf_types.h" #include "tsmf_constants.h" #include "tsmf_decoder.h" static ITSMFDecoder* tsmf_load_decoder_by_name(const char* name, TS_AM_MEDIA_TYPE* media_type) { - char* fullname; ITSMFDecoder* decoder; TSMF_DECODER_ENTRY entry; - if (strrchr(name, '.') != NULL) - entry = (TSMF_DECODER_ENTRY) freerdp_load_plugin(name, TSMF_DECODER_EXPORT_FUNC_NAME); - else - { - fullname = xzalloc(strlen(name) + 6); - strcpy(fullname, "tsmf_"); - strcat(fullname, name); - entry = (TSMF_DECODER_ENTRY) freerdp_load_plugin(fullname, TSMF_DECODER_EXPORT_FUNC_NAME); - free(fullname); - } + entry = (TSMF_DECODER_ENTRY) freerdp_load_channel_addin_entry("tsmf", (LPSTR) name, "decoder", 0); if (entry == NULL) return NULL; @@ -86,4 +77,3 @@ ITSMFDecoder* tsmf_load_decoder(const char* name, TS_AM_MEDIA_TYPE* media_type) return decoder; } - diff --git a/channels/tsmf/client/tsmf_main.c b/channels/tsmf/client/tsmf_main.c index 7e892c24a..24c8ad8f3 100644 --- a/channels/tsmf/client/tsmf_main.c +++ b/channels/tsmf/client/tsmf_main.c @@ -25,7 +25,9 @@ #include #include -#include +#include +#include + #include #include "tsmf_types.h" @@ -76,7 +78,7 @@ void tsmf_playback_ack(IWTSVirtualChannelCallback* pChannelCallback, UINT32 message_id, UINT64 duration, UINT32 data_size) { STREAM* s; - int error; + int status; TSMF_CHANNEL_CALLBACK* callback = (TSMF_CHANNEL_CALLBACK*) pChannelCallback; s = stream_new(32); @@ -88,26 +90,29 @@ void tsmf_playback_ack(IWTSVirtualChannelCallback* pChannelCallback, stream_write_UINT64(s, data_size); /* cbData */ DEBUG_DVC("response size %d", (int) stream_get_length(s)); - error = callback->channel->Write(callback->channel, stream_get_length(s), stream_get_head(s), NULL); - if (error) + status = callback->channel->Write(callback->channel, stream_get_length(s), stream_get_head(s), NULL); + + if (status) { - DEBUG_WARN("response error %d", error); + DEBUG_WARN("response error %d", status); } + stream_free(s); } -BOOL tsmf_push_event(IWTSVirtualChannelCallback* pChannelCallback, - RDP_EVENT* event) +BOOL tsmf_push_event(IWTSVirtualChannelCallback* pChannelCallback, RDP_EVENT* event) { - int error; + int status; TSMF_CHANNEL_CALLBACK* callback = (TSMF_CHANNEL_CALLBACK*) pChannelCallback; - error = callback->channel_mgr->PushEvent(callback->channel_mgr, event); - if (error) + status = callback->channel_mgr->PushEvent(callback->channel_mgr, event); + + if (status) { - DEBUG_WARN("response error %d", error); + DEBUG_WARN("response error %d", status); return FALSE; } + return TRUE; } @@ -118,7 +123,7 @@ static int tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, int length; STREAM* input; STREAM* output; - int error = -1; + int status = -1; TSMF_IFMAN ifman; UINT32 MessageId; UINT32 FunctionId; @@ -163,7 +168,7 @@ static int tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, switch (FunctionId) { case RIM_EXCHANGE_CAPABILITY_REQUEST: - error = tsmf_ifman_rim_exchange_capability_request(&ifman); + status = tsmf_ifman_rim_exchange_capability_request(&ifman); break; default: @@ -181,91 +186,91 @@ static int tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, stream_read_UINT32(input, callback->stream_id); DEBUG_DVC("SET_CHANNEL_PARAMS StreamId=%d", callback->stream_id); ifman.output_pending = TRUE; - error = 0; + status = 0; break; case EXCHANGE_CAPABILITIES_REQ: - error = tsmf_ifman_exchange_capability_request(&ifman); + status = tsmf_ifman_exchange_capability_request(&ifman); break; case CHECK_FORMAT_SUPPORT_REQ: - error = tsmf_ifman_check_format_support_request(&ifman); + status = tsmf_ifman_check_format_support_request(&ifman); break; case ON_NEW_PRESENTATION: - error = tsmf_ifman_on_new_presentation(&ifman); + status = tsmf_ifman_on_new_presentation(&ifman); break; case ADD_STREAM: - error = tsmf_ifman_add_stream(&ifman); + status = tsmf_ifman_add_stream(&ifman); break; case SET_TOPOLOGY_REQ: - error = tsmf_ifman_set_topology_request(&ifman); + status = tsmf_ifman_set_topology_request(&ifman); break; case REMOVE_STREAM: - error = tsmf_ifman_remove_stream(&ifman); + status = tsmf_ifman_remove_stream(&ifman); break; case SHUTDOWN_PRESENTATION_REQ: - error = tsmf_ifman_shutdown_presentation(&ifman); + status = tsmf_ifman_shutdown_presentation(&ifman); break; case ON_STREAM_VOLUME: - error = tsmf_ifman_on_stream_volume(&ifman); + status = tsmf_ifman_on_stream_volume(&ifman); break; case ON_CHANNEL_VOLUME: - error = tsmf_ifman_on_channel_volume(&ifman); + status = tsmf_ifman_on_channel_volume(&ifman); break; case SET_VIDEO_WINDOW: - error = tsmf_ifman_set_video_window(&ifman); + status = tsmf_ifman_set_video_window(&ifman); break; case UPDATE_GEOMETRY_INFO: - error = tsmf_ifman_update_geometry_info(&ifman); + status = tsmf_ifman_update_geometry_info(&ifman); break; case SET_ALLOCATOR: - error = tsmf_ifman_set_allocator(&ifman); + status = tsmf_ifman_set_allocator(&ifman); break; case NOTIFY_PREROLL: - error = tsmf_ifman_notify_preroll(&ifman); + status = tsmf_ifman_notify_preroll(&ifman); break; case ON_SAMPLE: - error = tsmf_ifman_on_sample(&ifman); + status = tsmf_ifman_on_sample(&ifman); break; case ON_FLUSH: - error = tsmf_ifman_on_flush(&ifman); + status = tsmf_ifman_on_flush(&ifman); break; case ON_END_OF_STREAM: - error = tsmf_ifman_on_end_of_stream(&ifman); + status = tsmf_ifman_on_end_of_stream(&ifman); break; case ON_PLAYBACK_STARTED: - error = tsmf_ifman_on_playback_started(&ifman); + status = tsmf_ifman_on_playback_started(&ifman); break; case ON_PLAYBACK_PAUSED: - error = tsmf_ifman_on_playback_paused(&ifman); + status = tsmf_ifman_on_playback_paused(&ifman); break; case ON_PLAYBACK_RESTARTED: - error = tsmf_ifman_on_playback_restarted(&ifman); + status = tsmf_ifman_on_playback_restarted(&ifman); break; case ON_PLAYBACK_STOPPED: - error = tsmf_ifman_on_playback_stopped(&ifman); + status = tsmf_ifman_on_playback_stopped(&ifman); break; case ON_PLAYBACK_RATE_CHANGED: - error = tsmf_ifman_on_playback_rate_changed(&ifman); + status = tsmf_ifman_on_playback_rate_changed(&ifman); break; default: @@ -282,34 +287,34 @@ static int tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, input = NULL; ifman.input = NULL; - if (error == -1) + if (status == -1) { switch (FunctionId) { case RIMCALL_RELEASE: /* [MS-RDPEXPS] 2.2.2.2 Interface Release (IFACE_RELEASE) This message does not require a reply. */ - error = 0; + status = 0; ifman.output_pending = 1; break; case RIMCALL_QUERYINTERFACE: /* [MS-RDPEXPS] 2.2.2.1.2 Query Interface Response (QI_RSP) This message is not supported in this channel. */ - error = 0; + status = 0; break; } - if (error == -1) + if (status == -1) { DEBUG_WARN("InterfaceId 0x%X FunctionId 0x%X not processed.", InterfaceId, FunctionId); /* When a request is not implemented we return empty response indicating error */ } - error = 0; + status = 0; } - if (error == 0 && !ifman.output_pending) + if (status == 0 && !ifman.output_pending) { /* Response packet does not have FunctionId */ length = stream_get_length(output); @@ -318,16 +323,16 @@ static int tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, stream_write_UINT32(output, MessageId); DEBUG_DVC("response size %d", length); - error = callback->channel->Write(callback->channel, length, stream_get_head(output), NULL); - if (error) + status = callback->channel->Write(callback->channel, length, stream_get_head(output), NULL); + if (status) { - DEBUG_WARN("response error %d", error); + DEBUG_WARN("response error %d", status); } } stream_free(output); - return error; + return status; } static int tsmf_on_close(IWTSVirtualChannelCallback* pChannelCallback) @@ -341,13 +346,16 @@ static int tsmf_on_close(IWTSVirtualChannelCallback* pChannelCallback) if (callback->stream_id) { presentation = tsmf_presentation_find_by_id(callback->presentation_id); + if (presentation) { stream = tsmf_stream_find_by_id(presentation, callback->stream_id); + if (stream) tsmf_stream_free(stream); } } + free(pChannelCallback); return 0; @@ -364,7 +372,9 @@ static int tsmf_on_new_channel_connection(IWTSListenerCallback* pListenerCallbac DEBUG_DVC(""); - callback = xnew(TSMF_CHANNEL_CALLBACK); + callback = (TSMF_CHANNEL_CALLBACK*) malloc(sizeof(TSMF_CHANNEL_CALLBACK)); + ZeroMemory(callback, sizeof(TSMF_CHANNEL_CALLBACK)); + callback->iface.OnDataReceived = tsmf_on_data_received; callback->iface.OnClose = tsmf_on_close; callback->plugin = listener_callback->plugin; @@ -381,10 +391,13 @@ static int tsmf_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager DEBUG_DVC(""); - tsmf->listener_callback = xnew(TSMF_LISTENER_CALLBACK); + tsmf->listener_callback = (TSMF_LISTENER_CALLBACK*) malloc(sizeof(TSMF_LISTENER_CALLBACK)); + ZeroMemory(tsmf->listener_callback, sizeof(TSMF_LISTENER_CALLBACK)); + tsmf->listener_callback->iface.OnNewChannelConnection = tsmf_on_new_channel_connection; tsmf->listener_callback->plugin = pPlugin; tsmf->listener_callback->channel_mgr = pChannelMgr; + return pChannelMgr->CreateListener(pChannelMgr, "TSMF", 0, (IWTSListenerCallback*) tsmf->listener_callback, NULL); } @@ -402,27 +415,55 @@ static int tsmf_plugin_terminated(IWTSPlugin* pPlugin) return 0; } -static void tsmf_process_plugin_data(IWTSPlugin* pPlugin, RDP_PLUGIN_DATA* data) +COMMAND_LINE_ARGUMENT_A tsmf_args[] = { + { "audio", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "audio subsystem" }, + { "audio-dev", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "audio device name" }, + { "decoder", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "decoder subsystem" }, + { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL } +}; + +static void tsmf_process_addin_args(IWTSPlugin* pPlugin, ADDIN_ARGV* args) +{ + int status; + DWORD flags; + COMMAND_LINE_ARGUMENT_A* arg; TSMF_PLUGIN* tsmf = (TSMF_PLUGIN*) pPlugin; - while (data && data->size > 0) + flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON; + + status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv, + tsmf_args, flags, tsmf, NULL, NULL); + + arg = tsmf_args; + + do { - if (data->data[0] && ( strcmp((char*)data->data[0], "tsmf") == 0 || strstr((char*)data->data[0], "/tsmf.") != NULL) ) + if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT)) + continue; + + CommandLineSwitchStart(arg) + + CommandLineSwitchCase(arg, "audio") { - if (data->data[1] && strcmp((char*)data->data[1], "decoder") == 0) - { - tsmf->decoder_name = data->data[2]; - } - else if (data->data[1] && strcmp((char*)data->data[1], "audio") == 0) - { - tsmf->audio_name = data->data[2]; - tsmf->audio_device = data->data[3]; - } + tsmf->audio_name = _strdup(arg->Value); } - - data = (RDP_PLUGIN_DATA*)(((BYTE*)data) + data->size); + CommandLineSwitchCase(arg, "audio-dev") + { + tsmf->audio_device = _strdup(arg->Value); + } + CommandLineSwitchCase(arg, "decoder") + { + tsmf->decoder_name = _strdup(arg->Value); + } + CommandLineSwitchDefault(arg) + { + + } + + CommandLineSwitchEnd(arg) } + while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); } #ifdef STATIC_CHANNELS @@ -431,29 +472,29 @@ static void tsmf_process_plugin_data(IWTSPlugin* pPlugin, RDP_PLUGIN_DATA* data) int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) { - int error = 0; + int status = 0; TSMF_PLUGIN* tsmf; tsmf = (TSMF_PLUGIN*) pEntryPoints->GetPlugin(pEntryPoints, "tsmf"); if (tsmf == NULL) { - tsmf = xnew(TSMF_PLUGIN); + tsmf = (TSMF_PLUGIN*) malloc(sizeof(TSMF_PLUGIN)); + ZeroMemory(tsmf, sizeof(TSMF_PLUGIN)); tsmf->iface.Initialize = tsmf_plugin_initialize; tsmf->iface.Connected = NULL; tsmf->iface.Disconnected = NULL; tsmf->iface.Terminated = tsmf_plugin_terminated; - error = pEntryPoints->RegisterPlugin(pEntryPoints, "tsmf", (IWTSPlugin*) tsmf); + status = pEntryPoints->RegisterPlugin(pEntryPoints, "tsmf", (IWTSPlugin*) tsmf); tsmf_media_init(); } - if (error == 0) + + if (status == 0) { - tsmf_process_plugin_data((IWTSPlugin*) tsmf, - pEntryPoints->GetPluginData(pEntryPoints)); + tsmf_process_addin_args((IWTSPlugin*) tsmf, pEntryPoints->GetPluginData(pEntryPoints)); } - return error; + return status; } - diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 34e42fd77..d4a4da714 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -837,7 +837,7 @@ int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings) args = settings->StaticChannelArray[index]; - entry = freerdp_load_channel_addin_entry(args->argv[0], NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC); + entry = freerdp_load_channel_addin_entry(args->argv[0], NULL, NULL, 0); if (entry) { @@ -848,7 +848,7 @@ int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings) if (settings->DeviceRedirection) { - entry = freerdp_load_channel_addin_entry("rdpdr", NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC); + entry = freerdp_load_channel_addin_entry("rdpdr", NULL, NULL, 0); if (entry) { @@ -859,7 +859,7 @@ int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings) if (settings->RemoteApplicationMode) { - entry = freerdp_load_channel_addin_entry("rail", NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC); + entry = freerdp_load_channel_addin_entry("rail", NULL, NULL, 0); if (entry) { @@ -870,7 +870,7 @@ int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings) if (settings->DynamicChannelCount) { - entry = freerdp_load_channel_addin_entry("drdynvc", NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC); + entry = freerdp_load_channel_addin_entry("drdynvc", NULL, NULL, 0); if (entry) { diff --git a/include/freerdp/dvc.h b/include/freerdp/dvc.h index 1835e4928..ecd25d4b2 100644 --- a/include/freerdp/dvc.h +++ b/include/freerdp/dvc.h @@ -52,6 +52,7 @@ #define __FREERDP_DVC_H #include +#include typedef struct _IWTSVirtualChannelManager IWTSVirtualChannelManager; typedef struct _IWTSListener IWTSListener; @@ -145,7 +146,7 @@ struct _IDRDYNVC_ENTRY_POINTS const char* name, IWTSPlugin* pPlugin); IWTSPlugin* (*GetPlugin) (IDRDYNVC_ENTRY_POINTS* pEntryPoints, const char* name); - RDP_PLUGIN_DATA* (*GetPluginData) (IDRDYNVC_ENTRY_POINTS* pEntryPoints); + ADDIN_ARGV* (*GetPluginData) (IDRDYNVC_ENTRY_POINTS* pEntryPoints); }; typedef int (*PDVC_PLUGIN_ENTRY) (IDRDYNVC_ENTRY_POINTS*); diff --git a/include/freerdp/utils/svc_plugin.h b/include/freerdp/utils/svc_plugin.h index 005c6874d..2748853db 100644 --- a/include/freerdp/utils/svc_plugin.h +++ b/include/freerdp/utils/svc_plugin.h @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -52,8 +53,6 @@ FREERDP_API void svc_plugin_init(rdpSvcPlugin* plugin, CHANNEL_ENTRY_POINTS* pEn FREERDP_API int svc_plugin_send(rdpSvcPlugin* plugin, STREAM* data_out); FREERDP_API int svc_plugin_send_event(rdpSvcPlugin* plugin, RDP_EVENT* event); -#define svc_plugin_get_data(_p) (RDP_PLUGIN_DATA*)(((rdpSvcPlugin*)_p)->channel_entry_points.pExtendedData) - #ifdef WITH_DEBUG_SVC #define DEBUG_SVC(fmt, ...) DEBUG_CLASS(SVC, fmt, ## __VA_ARGS__) #else diff --git a/libfreerdp/common/CMakeLists.txt b/libfreerdp/common/CMakeLists.txt index e184f563f..608c43a0d 100644 --- a/libfreerdp/common/CMakeLists.txt +++ b/libfreerdp/common/CMakeLists.txt @@ -30,7 +30,7 @@ set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION_FULL} set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHIC_BUILD} MODULE winpr - MODULES winpr-crt winpr-path winpr-file winpr-utils) + MODULES winpr-crt winpr-path winpr-file winpr-library winpr-utils) if(MONOLITHIC_BUILD) set(FREERDP_LIBS ${FREERDP_LIBS} ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE) diff --git a/libfreerdp/utils/load_plugin.c b/libfreerdp/utils/load_plugin.c index a986faa68..f4f9195ac 100644 --- a/libfreerdp/utils/load_plugin.c +++ b/libfreerdp/utils/load_plugin.c @@ -111,37 +111,6 @@ void* freerdp_load_library_symbol(const char* file, const char* name) */ void* freerdp_load_plugin(const char* name, const char* entry_name) { -#if 0 - char* path; - void* entry; - char* suffixed_name; - - suffixed_name = freerdp_append_shared_library_suffix((char*) name); - - if (!freerdp_path_contains_separator(suffixed_name)) - { - /* no explicit path given, use default path */ - path = freerdp_construct_path(FREERDP_PLUGIN_PATH, suffixed_name); - } - else - { - /* explicit path given, use it instead of default path */ - path = _strdup(suffixed_name); - } - - entry = freerdp_load_library_symbol(path, entry_name); - - free(suffixed_name); - free(path); - - if (entry == NULL) - { - printf("freerdp_load_plugin: failed to load %s/%s\n", name, entry_name); - return NULL; - } - - return entry; -#endif return freerdp_load_dynamic_addin(name, NULL, entry_name); } diff --git a/libfreerdp/utils/svc_plugin.c b/libfreerdp/utils/svc_plugin.c index 0dd70b41e..2f232b230 100644 --- a/libfreerdp/utils/svc_plugin.c +++ b/libfreerdp/utils/svc_plugin.c @@ -164,12 +164,14 @@ static void svc_plugin_process_received(rdpSvcPlugin* plugin, void* pData, UINT3 STREAM* data_in; svc_data_in_item* item; - if ( (dataFlags & CHANNEL_FLAG_SUSPEND) || (dataFlags & CHANNEL_FLAG_RESUME)) + if ((dataFlags & CHANNEL_FLAG_SUSPEND) || (dataFlags & CHANNEL_FLAG_RESUME)) { - /* According to MS-RDPBCGR 2.2.6.1, "All virtual channel traffic MUST be suspended. - This flag is only valid in server-to-client virtual channel traffic. It MUST be - ignored in client-to-server data." Thus it would be best practice to cease data - transmission. However, simply returning here avoids a crash. */ + /* + * According to MS-RDPBCGR 2.2.6.1, "All virtual channel traffic MUST be suspended. + * This flag is only valid in server-to-client virtual channel traffic. It MUST be + * ignored in client-to-server data." Thus it would be best practice to cease data + * transmission. However, simply returning here avoids a crash. + */ return; }