wfreerdp-server: merge upstream

This commit is contained in:
Corey C
2013-01-14 14:22:07 -05:00
496 changed files with 23496 additions and 10885 deletions

View File

@@ -24,6 +24,12 @@ project(FreeRDP C)
set(CMAKE_COLOR_MAKEFILE ON)
# Include our extra modules
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/)
# Check for cmake compatibility (enable/disable features)
include(CheckCmakeCompat)
# Include cmake modules
include(CheckIncludeFiles)
include(CheckLibraryExists)
@@ -32,12 +38,6 @@ include(CMakeDetermineSystem)
include(FindPkgConfig)
include(TestBigEndian)
# Include our extra modules
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/)
# Check for cmake compatibility (enable/disable features)
include(CheckCmakeCompat)
include(FindFeature)
include(AutoVersioning)
include(ConfigOptions)
@@ -50,8 +50,14 @@ include(GNUInstallDirsWrapper)
set(FREERDP_VERSION_MAJOR "1")
set(FREERDP_VERSION_MINOR "1")
set(FREERDP_VERSION_REVISION "0")
set(FREERDP_VERSION "${FREERDP_VERSION_MAJOR}.${FREERDP_VERSION_MINOR}")
set(FREERDP_VERSION_FULL "${FREERDP_VERSION}.${FREERDP_VERSION_REVISION}")
set(FREERDP_VERSION_SUFFIX "dev")
set(FREERDP_API_VERSION "${FREERDP_VERSION_MAJOR}.${FREERDP_VERSION_MINOR}")
set(FREERDP_VERSION "${FREERDP_API_VERSION}.${FREERDP_VERSION_REVISION}")
if (FREERDP_VERSION_SUFFIX)
set(FREERDP_VERSION_FULL "${FREERDP_VERSION}-${FREERDP_VERSION_SUFFIX}")
else()
set(FREERDP_VERSION_FULL "${FREERDP_VERSION}")
endif()
include(GetGitRevisionDescription)
git_describe(GIT_REVISION --match "[0-9]*" --abbrev=4 --tags --always)
message(STATUS "Git Revision ${GIT_REVISION}")
@@ -73,7 +79,7 @@ if(NOT DEFINED BUILD_SHARED_LIBS)
endif()
if(NOT DEFINED EXPORT_ALL_SYMBOLS)
set(EXPORT_ALL_SYMBOLS FALSE)
set(EXPORT_ALL_SYMBOLS TRUE)
endif()
# Configure MSVC Runtime
@@ -92,6 +98,9 @@ endif()
# Compiler-specific flags
if(CMAKE_COMPILER_IS_GNUCC)
if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT ANDROID)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=i686")
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
CHECK_C_COMPILER_FLAG (-Wno-unused-result Wno-unused-result)
if(Wno-unused-result)
@@ -173,7 +182,9 @@ if(APPLE)
endif()
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
find_package(Threads REQUIRED)
if(NOT ANDROID)
find_package(Threads REQUIRED)
endif()
if(UNIX OR CYGWIN)
set(X11_FEATURE_TYPE "RECOMMENDED")
@@ -286,6 +297,8 @@ set(FREERDP_KEYMAP_PATH "${FREERDP_DATA_PATH}/keymaps")
# Path to put plugins
set(FREERDP_LIBRARY_PATH "${CMAKE_INSTALL_LIBDIR}")
set(FREERDP_PLUGIN_PATH "${CMAKE_INSTALL_LIBDIR}/freerdp")
set(FREERDP_ADDIN_PATH "${FREERDP_PLUGIN_PATH}")

View File

@@ -22,14 +22,35 @@ include(CMakeDependentOption)
macro(define_channel_options)
set(PREFIX "CHANNEL")
cmake_parse_arguments(${PREFIX}
""
"NAME;TYPE;DESCRIPTION;SPECIFICATIONS;DEFAULT"
""
${ARGN})
string(TOUPPER "CHANNEL_${CHANNEL_NAME}" CHANNEL_OPTION)
string(TOUPPER "CHANNEL_${CHANNEL_NAME}_CLIENT" CHANNEL_CLIENT_OPTION)
string(TOUPPER "CHANNEL_${CHANNEL_NAME}_SERVER" CHANNEL_SERVER_OPTION)
if(${${CHANNEL_CLIENT_OPTION}})
set(OPTION_CLIENT_DEFAULT ${${CHANNEL_CLIENT_OPTION}})
endif()
if(${${CHANNEL_SERVER_OPTION}})
set(OPTION_SERVER_DEFAULT ${${CHANNEL_SERVER_OPTION}})
endif()
if(${${CHANNEL_OPTION}})
set(OPTION_DEFAULT ${${CHANNEL_OPTION}})
endif()
if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT})
set(OPTION_DEFAULT "ON")
endif()
set(CHANNEL_DEFAULT ${OPTION_DEFAULT})
set(CHANNEL_OPTION_DOC "Build ${CHANNEL_NAME} ${CHANNEL_TYPE} channel")
option(${CHANNEL_OPTION} "${CHANNEL_OPTION_DOC}" ${CHANNEL_DEFAULT})
@@ -77,7 +98,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,11 +137,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})
message(STATUS "Static Subsystem: ${_subsystem_prefix} / ${_subsystem}")
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)
@@ -140,7 +169,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()
@@ -149,6 +178,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)

View File

@@ -8,10 +8,6 @@ if(ANDROID)
set(OPTION_SERVER_DEFAULT OFF)
endif()
if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT})
set(OPTION_DEFAULT ON)
endif()
define_channel_options(NAME "audin" TYPE "dynamic"
DESCRIPTION "Audio Input Redirection Virtual Channel Extension"
SPECIFICATIONS "[MS-RDPEAI]"
@@ -19,3 +15,4 @@ define_channel_options(NAME "audin" TYPE "dynamic"
define_channel_client_options(${OPTION_CLIENT_DEFAULT})
define_channel_server_options(${OPTION_SERVER_DEFAULT})

View File

@@ -30,7 +30,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-common freerdp-utils)
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})

View File

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

View File

@@ -25,10 +25,14 @@
#include <stdlib.h>
#include <string.h>
#include <winpr/crt.h>
#include <winpr/cmdline.h>
#include <alsa/asoundlib.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/thread.h>
#include <freerdp/addin.h>
#include <freerdp/utils/dsp.h>
#include <freerdp/utils/thread.h>
#include "audin_main.h"
@@ -36,7 +40,7 @@ typedef struct _AudinALSADevice
{
IAudinDevice iface;
char device_name[32];
char* device_name;
UINT32 frames_per_packet;
UINT32 target_rate;
UINT32 actual_rate;
@@ -183,10 +187,13 @@ static void* audin_alsa_thread_func(void* arg)
rbytes_per_frame = alsa->actual_channels * alsa->bytes_per_channel;
tbytes_per_frame = alsa->target_channels * alsa->bytes_per_channel;
alsa->buffer = (BYTE*) xzalloc(tbytes_per_frame * alsa->frames_per_packet);
alsa->buffer = (BYTE*) malloc(tbytes_per_frame * alsa->frames_per_packet);
ZeroMemory(alsa->buffer, tbytes_per_frame * alsa->frames_per_packet);
alsa->buffer_frames = 0;
buffer = (BYTE*) xzalloc(rbytes_per_frame * alsa->frames_per_packet);
buffer = (BYTE*) malloc(rbytes_per_frame * alsa->frames_per_packet);
ZeroMemory(buffer, rbytes_per_frame * alsa->frames_per_packet);
freerdp_dsp_context_reset_adpcm(alsa->dsp_context);
do
{
if ((error = snd_pcm_open(&capture_handle, alsa->device_name, SND_PCM_STREAM_CAPTURE, 0)) < 0)
@@ -236,6 +243,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 +338,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, "<device>", 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 +414,3 @@ int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEnt
return 0;
}

View File

@@ -25,9 +25,12 @@
#include <stdlib.h>
#include <string.h>
#include <freerdp/utils/memory.h>
#include <winpr/crt.h>
#include <winpr/cmdline.h>
#include <freerdp/addin.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/load_plugin.h>
#include "audin_main.h"
@@ -77,6 +80,8 @@ struct _AUDIN_PLUGIN
UINT16 fixed_format;
UINT16 fixed_channel;
UINT32 fixed_rate;
char* subsystem;
char* device_name;
/* Device interface */
IAudinDevice* device;
@@ -132,7 +137,8 @@ static int audin_process_formats(IWTSVirtualChannelCallback* pChannelCallback, S
}
stream_seek_UINT32(s); /* cbSizeFormatsPacket */
callback->formats = (audinFormat*) xzalloc(NumFormats * sizeof(audinFormat));
callback->formats = (audinFormat*) malloc(NumFormats * sizeof(audinFormat));
ZeroMemory(callback->formats, NumFormats * sizeof(audinFormat));
out = stream_new(9);
stream_seek(out, 9);
@@ -373,7 +379,8 @@ static int audin_on_new_channel_connection(IWTSListenerCallback* pListenerCallba
DEBUG_DVC("");
callback = xnew(AUDIN_CHANNEL_CALLBACK);
callback = (AUDIN_CHANNEL_CALLBACK*) malloc(sizeof(AUDIN_CHANNEL_CALLBACK));
ZeroMemory(callback, sizeof(AUDIN_CHANNEL_CALLBACK));
callback->iface.OnDataReceived = audin_on_data_received;
callback->iface.OnClose = audin_on_close;
@@ -392,7 +399,8 @@ static int audin_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManage
DEBUG_DVC("");
audin->listener_callback = xnew(AUDIN_LISTENER_CALLBACK);
audin->listener_callback = (AUDIN_LISTENER_CALLBACK*) malloc(sizeof(AUDIN_LISTENER_CALLBACK));
ZeroMemory(audin->listener_callback, sizeof(AUDIN_LISTENER_CALLBACK));
audin->listener_callback->iface.OnNewChannelConnection = audin_on_new_channel_connection;
audin->listener_callback->plugin = pPlugin;
@@ -436,31 +444,19 @@ 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)
{
char* fullname;
PFREERDP_AUDIN_DEVICE_ENTRY entry;
FREERDP_AUDIN_DEVICE_ENTRY_POINTS entryPoints;
if (strrchr(name, '.') != NULL)
{
entry = (PFREERDP_AUDIN_DEVICE_ENTRY) freerdp_load_plugin(name, AUDIN_DEVICE_EXPORT_FUNC_NAME);
}
else
{
fullname = xzalloc(strlen(name) + 8);
strcpy(fullname, "audin_");
strcat(fullname, name);
entry = (PFREERDP_AUDIN_DEVICE_ENTRY) freerdp_load_plugin(fullname, AUDIN_DEVICE_EXPORT_FUNC_NAME);
free(fullname);
}
entry = (PFREERDP_AUDIN_DEVICE_ENTRY) freerdp_load_channel_addin_entry("audin", (LPSTR) name, NULL, 0);
if (entry == NULL)
return FALSE;
entryPoints.plugin = pPlugin;
entryPoints.pRegisterAudinDevice = audin_register_device_plugin;
entryPoints.plugin_data = data;
entryPoints.args = args;
if (entry(&entryPoints) != 0)
{
@@ -471,54 +467,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, "<subsystem>", NULL, NULL, -1, NULL, "subsystem" },
{ "dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "device" },
{ "format", COMMAND_LINE_VALUE_REQUIRED, "<format>", NULL, NULL, -1, NULL, "format" },
{ "rate", COMMAND_LINE_VALUE_REQUIRED, "<rate>", NULL, NULL, -1, NULL, "rate" },
{ "channel", COMMAND_LINE_VALUE_REQUIRED, "<channel>", 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;
}
@@ -530,23 +553,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;
}

View File

@@ -26,6 +26,7 @@
#include <freerdp/dvc.h>
#include <freerdp/types.h>
#include <freerdp/addin.h>
#include <freerdp/utils/debug.h>
#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;

View File

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

View File

@@ -25,9 +25,13 @@
#include <stdlib.h>
#include <string.h>
#include <winpr/crt.h>
#include <winpr/cmdline.h>
#include <pulse/pulseaudio.h>
#include <freerdp/types.h>
#include <freerdp/utils/memory.h>
#include <freerdp/addin.h>
#include <freerdp/utils/dsp.h>
#include "audin_main.h"
@@ -36,7 +40,7 @@ typedef struct _AudinPulseDevice
{
IAudinDevice iface;
char device_name[32];
char* device_name;
UINT32 frames_per_packet;
pa_threaded_mainloop* mainloop;
pa_context* context;
@@ -420,7 +424,8 @@ static void audin_pulse_open(IAudinDevice* device, AudinReceive receive, void* u
if (state == PA_STREAM_READY)
{
freerdp_dsp_context_reset_adpcm(pulse->dsp_context);
pulse->buffer = xzalloc(pulse->bytes_per_frame * pulse->frames_per_packet);
pulse->buffer = malloc(pulse->bytes_per_frame * pulse->frames_per_packet);
ZeroMemory(pulse->buffer, pulse->bytes_per_frame * pulse->frames_per_packet);
pulse->buffer_frames = 0;
DEBUG_DVC("connected");
}
@@ -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, "<device>", 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;
}

View File

@@ -25,11 +25,11 @@
#include <stdlib.h>
#include <string.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/memory.h>
#include <winpr/crt.h>
#include <freerdp/utils/dsp.h>
#include <freerdp/utils/thread.h>
#include <freerdp/utils/wait_obj.h>
#include <freerdp/utils/stream.h>
#include <freerdp/channels/wtsvc.h>
#include <freerdp/server/audin.h>
@@ -134,7 +134,9 @@ static BOOL audin_server_recv_formats(audin_server* audin, STREAM* s, UINT32 len
if (audin->context.num_client_formats <= 0)
return FALSE;
audin->context.client_formats = xzalloc(audin->context.num_client_formats * sizeof(rdpsndFormat));
audin->context.client_formats = malloc(audin->context.num_client_formats * sizeof(rdpsndFormat));
ZeroMemory(audin->context.client_formats, audin->context.num_client_formats * sizeof(rdpsndFormat));
for (i = 0; i < audin->context.num_client_formats; i++)
{
if (length < 18)
@@ -273,22 +275,27 @@ static void* audin_server_thread_func(void* arg)
if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualFileHandle, &buffer, &bytes_returned) == TRUE)
{
fd = *((void**)buffer);
fd = *((void**) buffer);
WTSFreeMemory(buffer);
thread->signals[thread->num_signals++] = wait_obj_new_with_fd(fd);
thread->signals[thread->num_signals++] = CreateWaitObjectEvent(NULL, TRUE, FALSE, fd);
}
/* Wait for the client to confirm that the Audio Input dynamic channel is ready */
while (1)
{
freerdp_thread_wait(thread);
if (freerdp_thread_is_stopped(thread))
break;
if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualChannelReady, &buffer, &bytes_returned) == FALSE)
break;
ready = *((BOOL*)buffer);
ready = *((BOOL*) buffer);
WTSFreeMemory(buffer);
if (ready)
break;
}
@@ -410,7 +417,9 @@ audin_server_context* audin_server_context_new(WTSVirtualChannelManager* vcm)
{
audin_server* audin;
audin = xnew(audin_server);
audin = (audin_server*) malloc(sizeof(audin_server));
ZeroMemory(audin, sizeof(audin_server));
audin->context.vcm = vcm;
audin->context.selected_client_format = -1;
audin->context.frames_per_packet = 4096;
@@ -428,9 +437,12 @@ void audin_server_context_free(audin_server_context* context)
audin_server* audin = (audin_server*) context;
audin_server_close(context);
if (audin->dsp_context)
freerdp_dsp_context_free(audin->dsp_context);
if (audin->context.client_formats)
free(audin->context.client_formats);
free(audin);
}

View File

@@ -63,12 +63,22 @@ foreach(STATIC_MODULE ${CHANNEL_STATIC_CLIENT_MODULES})
set(CHANNEL_SUBSYSTEMS "")
endif()
foreach(STATIC_SUBSYSTEM ${CHANNEL_SUBSYSTEMS})
message(STATUS "STATIC_SUBSYSTEM: ${STATIC_SUBSYSTEM}")
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()

View File

@@ -34,9 +34,7 @@
#include <freerdp/client/channels.h>
#include <freerdp/channels/channels.h>
#include <freerdp/svc.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/wait_obj.h>
#include <freerdp/utils/load_plugin.h>
#include <freerdp/addin.h>
#include <freerdp/utils/file.h>
#include <freerdp/utils/event.h>
#include <freerdp/utils/debug.h>
@@ -112,40 +110,9 @@ void* freerdp_channels_client_find_static_entry(const char* name, const char* id
return NULL;
}
void* freerdp_channels_client_find_dynamic_entry(const char* name, const char* identifier)
{
char* path;
void* entry;
char* module;
module = freerdp_append_shared_library_suffix((char*) identifier);
path = freerdp_construct_path(FREERDP_PLUGIN_PATH, module);
entry = freerdp_load_library_symbol(path, module);
free(module);
free(path);
return entry;
}
void* freerdp_channels_client_find_entry(const char* name, const char* identifier)
{
void* pChannelEntry = NULL;
pChannelEntry = freerdp_channels_client_find_static_entry(name, identifier);
if (!pChannelEntry)
{
pChannelEntry = freerdp_channels_client_find_dynamic_entry(name, identifier);
}
return pChannelEntry;
}
extern const STATIC_ADDIN_TABLE CLIENT_STATIC_ADDIN_TABLE[];
FREERDP_ADDIN** freerdp_channels_list_client_static_addins(LPSTR lpName, LPSTR lpSubsystem, LPSTR lpType, DWORD dwFlags)
FREERDP_ADDIN** freerdp_channels_list_client_static_addins(LPSTR pszName, LPSTR pszSubsystem, LPSTR pszType, DWORD dwFlags)
{
int i, j;
DWORD nAddins;
@@ -194,64 +161,63 @@ FREERDP_ADDIN** freerdp_channels_list_client_static_addins(LPSTR lpName, LPSTR l
return ppAddins;
}
LPCSTR gAddinPath = FREERDP_ADDIN_PATH;
LPCSTR gInstallPrefix = FREERDP_INSTALL_PREFIX;
FREERDP_ADDIN** freerdp_channels_list_client_dynamic_addins(LPSTR lpName, LPSTR lpSubsystem, LPSTR lpType, DWORD dwFlags)
FREERDP_ADDIN** freerdp_channels_list_dynamic_addins(LPSTR pszName, LPSTR pszSubsystem, LPSTR pszType, DWORD dwFlags)
{
int index;
int nDashes;
HANDLE hFind;
DWORD nAddins;
LPSTR lpPattern;
LPSTR pszPattern;
size_t cchPattern;
LPCSTR lpExtension;
LPSTR lpSearchPath;
LPCSTR pszAddinPath = FREERDP_ADDIN_PATH;
LPCSTR pszInstallPrefix = FREERDP_INSTALL_PREFIX;
LPCSTR pszExtension;
LPSTR pszSearchPath;
size_t cchSearchPath;
size_t cchAddinPath;
size_t cchInstallPrefix;
FREERDP_ADDIN** ppAddins;
WIN32_FIND_DATAA FindData;
cchAddinPath = strlen(gAddinPath);
cchInstallPrefix = strlen(gInstallPrefix);
cchAddinPath = strlen(pszAddinPath);
cchInstallPrefix = strlen(pszInstallPrefix);
lpExtension = PathGetSharedLibraryExtensionA(0);
pszExtension = PathGetSharedLibraryExtensionA(0);
cchPattern = 128 + strlen(lpExtension) + 2;
lpPattern = (LPSTR) malloc(cchPattern + 1);
cchPattern = 128 + strlen(pszExtension) + 2;
pszPattern = (LPSTR) malloc(cchPattern + 1);
if (lpName && lpSubsystem && lpType)
if (pszName && pszSubsystem && pszType)
{
sprintf_s(lpPattern, cchPattern, "%s-client-%s-%s.%s", lpName, lpSubsystem, lpType, lpExtension);
sprintf_s(pszPattern, cchPattern, "%s-client-%s-%s.%s", pszName, pszSubsystem, pszType, pszExtension);
}
else if (lpName && lpType)
else if (pszName && pszType)
{
sprintf_s(lpPattern, cchPattern, "%s-client-?-%s.%s", lpName, lpType, lpExtension);
sprintf_s(pszPattern, cchPattern, "%s-client-?-%s.%s", pszName, pszType, pszExtension);
}
else if (lpName)
else if (pszName)
{
sprintf_s(lpPattern, cchPattern, "%s-client*.%s", lpName, lpExtension);
sprintf_s(pszPattern, cchPattern, "%s-client*.%s", pszName, pszExtension);
}
else
{
sprintf_s(lpPattern, cchPattern, "?-client*.%s", lpExtension);
sprintf_s(pszPattern, cchPattern, "?-client*.%s", pszExtension);
}
cchPattern = strlen(lpPattern);
cchPattern = strlen(pszPattern);
cchSearchPath = cchInstallPrefix + cchAddinPath + cchPattern + 3;
lpSearchPath = (LPSTR) malloc(cchSearchPath + 1);
pszSearchPath = (LPSTR) malloc(cchSearchPath + 1);
CopyMemory(lpSearchPath, gInstallPrefix, cchInstallPrefix);
lpSearchPath[cchInstallPrefix] = '\0';
CopyMemory(pszSearchPath, pszInstallPrefix, cchInstallPrefix);
pszSearchPath[cchInstallPrefix] = '\0';
NativePathCchAppendA(lpSearchPath, cchSearchPath + 1, gAddinPath);
NativePathCchAppendA(lpSearchPath, cchSearchPath + 1, lpPattern);
NativePathCchAppendA(pszSearchPath, cchSearchPath + 1, pszAddinPath);
NativePathCchAppendA(pszSearchPath, cchSearchPath + 1, pszPattern);
cchSearchPath = strlen(lpSearchPath);
cchSearchPath = strlen(pszSearchPath);
hFind = FindFirstFileA(lpSearchPath, &FindData);
hFind = FindFirstFileA(pszSearchPath, &FindData);
nAddins = 0;
ppAddins = (FREERDP_ADDIN**) malloc(sizeof(FREERDP_ADDIN*) * 128);
@@ -342,12 +308,12 @@ FREERDP_ADDIN** freerdp_channels_list_client_dynamic_addins(LPSTR lpName, LPSTR
return ppAddins;
}
FREERDP_ADDIN** freerdp_channels_list_client_addins(LPSTR lpName, LPSTR lpSubsystem, LPSTR lpType, DWORD dwFlags)
FREERDP_ADDIN** freerdp_channels_list_addins(LPSTR pszName, LPSTR pszSubsystem, LPSTR pszType, DWORD dwFlags)
{
if (dwFlags & FREERDP_ADDIN_STATIC)
return freerdp_channels_list_client_static_addins(lpName, lpSubsystem, lpType, dwFlags);
return freerdp_channels_list_client_static_addins(pszName, pszSubsystem, pszType, dwFlags);
else if (dwFlags & FREERDP_ADDIN_DYNAMIC)
return freerdp_channels_list_client_dynamic_addins(lpName, lpSubsystem, lpType, dwFlags);
return freerdp_channels_list_dynamic_addins(pszName, pszSubsystem, pszType, dwFlags);
return NULL;
}
@@ -362,139 +328,43 @@ void freerdp_channels_addin_list_free(FREERDP_ADDIN** ppAddins)
free(ppAddins);
}
void* freerdp_channels_load_static_addin_entry(LPCSTR lpName, LPSTR lpSubsystem, LPSTR lpType, DWORD dwFlags)
void* freerdp_channels_load_static_addin_entry(LPCSTR pszName, LPSTR pszSubsystem, LPSTR pszType, DWORD dwFlags)
{
int i, j;
STATIC_SUBSYSTEM_ENTRY* subsystems;
for (i = 0; CLIENT_STATIC_ADDIN_TABLE[i].name != NULL; i++)
{
if ((lpSubsystem == NULL) && (lpType == NULL))
if (strcmp(CLIENT_STATIC_ADDIN_TABLE[i].name, pszName) == 0)
{
return (void*) CLIENT_STATIC_ADDIN_TABLE[i].entry;
}
subsystems = (STATIC_SUBSYSTEM_ENTRY*) CLIENT_STATIC_ADDIN_TABLE[i].table;
for (j = 0; subsystems[j].name != NULL; j++)
{
if (strcmp(subsystems[j].name, lpSubsystem) == 0)
if (pszSubsystem != NULL)
{
if (lpType)
subsystems = (STATIC_SUBSYSTEM_ENTRY*) CLIENT_STATIC_ADDIN_TABLE[i].table;
for (j = 0; subsystems[j].name != NULL; j++)
{
if (strcmp(subsystems[j].type, lpType) == 0)
return (void*) subsystems[j].entry;
}
else
{
return (void*) subsystems[j].entry;
if (strcmp(subsystems[j].name, pszSubsystem) == 0)
{
if (pszType)
{
if (strcmp(subsystems[j].type, pszType) == 0)
return (void*) subsystems[j].entry;
}
else
{
return (void*) subsystems[j].entry;
}
}
}
}
else
return (void*) CLIENT_STATIC_ADDIN_TABLE[i].entry;
}
}
return NULL;
}
void* freerdp_channels_load_dynamic_addin_entry(LPCSTR lpName, LPSTR lpSubsystem, LPSTR lpType, DWORD dwFlags)
{
void* entry;
LPSTR lpFileName;
LPSTR lpFilePath;
size_t cchFileName;
size_t cchFilePath;
size_t cchAddinPath;
size_t cchInstallPrefix;
LPCSTR lpExtension;
HINSTANCE library;
cchAddinPath = strlen(gAddinPath);
cchInstallPrefix = strlen(gInstallPrefix);
lpExtension = PathGetSharedLibraryExtensionA(0);
if (lpName && lpSubsystem && lpType)
{
cchFileName = strlen(lpName) + strlen(lpSubsystem) + strlen(lpType) + strlen(lpExtension) + 32;
lpFileName = (LPSTR) malloc(cchFileName);
sprintf_s(lpFileName, cchFileName, "%s-client-%s-%s.%s", lpName, lpSubsystem, lpType, lpExtension);
cchFileName = strlen(lpFileName);
}
else if (lpName && lpSubsystem)
{
cchFileName = strlen(lpName) + strlen(lpSubsystem) + strlen(lpExtension) + 32;
lpFileName = (LPSTR) malloc(cchFileName);
sprintf_s(lpFileName, cchFileName, "%s-client-%s.%s", lpName, lpSubsystem, lpExtension);
cchFileName = strlen(lpFileName);
}
else if (lpName)
{
cchFileName = strlen(lpName) + strlen(lpExtension) + 32;
lpFileName = (LPSTR) malloc(cchFileName);
sprintf_s(lpFileName, cchFileName, "%s-client.%s", lpName, lpExtension);
cchFileName = strlen(lpFileName);
}
else
{
return NULL;
}
cchFilePath = cchInstallPrefix + cchAddinPath + cchFileName + 32;
lpFilePath = (LPSTR) malloc(cchFilePath + 1);
CopyMemory(lpFilePath, gInstallPrefix, cchInstallPrefix);
lpFilePath[cchInstallPrefix] = '\0';
NativePathCchAppendA(lpFilePath, cchFilePath + 1, gAddinPath);
NativePathCchAppendA(lpFilePath, cchFilePath + 1, lpFileName);
cchFilePath = strlen(lpFilePath);
library = LoadLibraryA(lpFilePath);
if (!library)
return NULL;
if (lpSubsystem)
{
LPSTR lpEntryName;
size_t cchEntryName;
/* subsystem add-in */
cchEntryName = 64 + strlen(lpName);
lpEntryName = (LPSTR) malloc(cchEntryName + 1);
sprintf_s(lpEntryName, cchEntryName + 1, "freerdp_%s_client_subsystem_entry", lpName);
entry = GetProcAddress(library, lpEntryName);
if (entry)
return entry;
}
else
{
/* channel add-in */
entry = GetProcAddress(library, lpType);
if (entry)
return entry;
}
return NULL;
}
void* freerdp_channels_load_addin_entry(LPCSTR lpName, LPSTR lpSubsystem, LPSTR lpType, DWORD dwFlags)
{
void* entry = NULL;
entry = freerdp_channels_load_static_addin_entry(lpName, lpSubsystem, lpType, dwFlags);
if (!entry)
entry = freerdp_channels_load_dynamic_addin_entry(lpName, lpSubsystem, lpType, dwFlags);
return entry;
}
struct lib_data
{
PVIRTUALCHANNELENTRY entry; /* the one and only exported function */
@@ -559,7 +429,7 @@ struct rdp_channels
freerdp* instance;
/* signal for incoming data or event */
struct wait_obj* signal;
HANDLE signal;
/* used for sync write */
PSLIST_HEADER pSyncDataList;
@@ -966,7 +836,7 @@ static UINT32 FREERDP_CC MyVirtualChannelWrite(UINT32 openHandle, void* pData, U
InterlockedPushEntrySList(channels->pSyncDataList, &(item->ItemEntry));
/* set the event */
wait_obj_set(channels->signal);
SetEvent(channels->signal);
return CHANNEL_RC_OK;
}
@@ -1017,7 +887,7 @@ static UINT32 FREERDP_CC MyVirtualChannelEventPush(UINT32 openHandle, RDP_EVENT*
channels->event = event;
/* set the event */
wait_obj_set(channels->signal);
SetEvent(channels->signal);
return CHANNEL_RC_OK;
}
@@ -1054,16 +924,18 @@ rdpChannels* freerdp_channels_new(void)
rdpChannels* channels;
rdpChannelsList* channels_list;
channels = xnew(rdpChannels);
channels = (rdpChannels*) malloc(sizeof(rdpChannels));
ZeroMemory(channels, sizeof(rdpChannels));
channels->pSyncDataList = (PSLIST_HEADER) _aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT);
InitializeSListHead(channels->pSyncDataList);
channels->event_sem = CreateSemaphore(NULL, 1, 16, NULL);
channels->signal = wait_obj_new();
channels->signal = CreateEvent(NULL, TRUE, FALSE, NULL);
/* Add it to the global list */
channels_list = xnew(rdpChannelsList);
channels_list = (rdpChannelsList*) malloc(sizeof(rdpChannelsList));
ZeroMemory(channels_list, sizeof(rdpChannelsList));
channels_list->channels = channels;
WaitForSingleObject(g_mutex_list, INFINITE);
@@ -1083,7 +955,7 @@ void freerdp_channels_free(rdpChannels* channels)
_aligned_free(channels->pSyncDataList);
CloseHandle(channels->event_sem);
wait_obj_free(channels->signal);
CloseHandle(channels->signal);
/* Remove from global list */
@@ -1117,7 +989,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;
}
@@ -1151,7 +1023,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;
}
@@ -1166,9 +1038,9 @@ int freerdp_channels_load_plugin(rdpChannels* channels, rdpSettings* settings, c
{
void* entry;
DEBUG_CHANNELS("%s", Name);
DEBUG_CHANNELS("%s", name);
entry = (PVIRTUALCHANNELENTRY) freerdp_load_plugin(name, CHANNEL_EXPORT_FUNC_NAME);
entry = (PVIRTUALCHANNELENTRY) freerdp_load_channel_addin_entry(name, NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC);
if (entry == NULL)
{
@@ -1244,7 +1116,7 @@ int freerdp_channels_post_connect(rdpChannels* channels, freerdp* instance)
hostname = instance->settings->ServerHostname;
hostname_len = strlen(hostname);
DEBUG_CHANNELS("hostname [%s] channels->num_libs [%d]", Hostname, channels->num_libs_data);
DEBUG_CHANNELS("hostname [%s] channels->num_libs [%d]", hostname, channels->num_libs_data);
for (index = 0; index < channels->num_libs_data; index++)
{
@@ -1335,7 +1207,7 @@ FREERDP_API int freerdp_channels_send_event(rdpChannels* channels, RDP_EVENT* ev
if (lchannel_data == NULL)
{
DEBUG_CHANNELS("could not find channel name %s", Name);
DEBUG_CHANNELS("could not find channel name %s", name);
freerdp_event_free(event);
return 1;
}
@@ -1390,7 +1262,16 @@ static void freerdp_channels_process_sync(rdpChannels* channels, freerdp* instan
BOOL freerdp_channels_get_fds(rdpChannels* channels, freerdp* instance, void** read_fds,
int* read_count, void** write_fds, int* write_count)
{
wait_obj_get_fds(channels->signal, read_fds, read_count);
void* pfd;
pfd = GetEventWaitObject(channels->signal);
if (pfd)
{
read_fds[*read_count] = pfd;
(*read_count)++;
}
return TRUE;
}
@@ -1399,9 +1280,9 @@ BOOL freerdp_channels_get_fds(rdpChannels* channels, freerdp* instance, void** r
*/
BOOL freerdp_channels_check_fds(rdpChannels* channels, freerdp* instance)
{
if (wait_obj_is_set(channels->signal))
if (WaitForSingleObject(channels->signal, 0) == WAIT_OBJECT_0)
{
wait_obj_clear(channels->signal);
ResetEvent(channels->signal);
freerdp_channels_process_sync(channels, instance);
}
@@ -1443,3 +1324,7 @@ void freerdp_channels_close(rdpChannels* channels, freerdp* instance)
}
}
/* Local variables: */
/* c-basic-offset: 8 */
/* c-file-style: "linux" */
/* End: */

View File

@@ -3,10 +3,6 @@ set(OPTION_DEFAULT OFF)
set(OPTION_CLIENT_DEFAULT ON)
set(OPTION_SERVER_DEFAULT OFF)
if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT})
set(OPTION_DEFAULT ON)
endif()
define_channel_options(NAME "cliprdr" TYPE "static"
DESCRIPTION "Clipboard Virtual Channel Extension"
SPECIFICATIONS "[MS-RDPECLIP]"

View File

@@ -27,12 +27,10 @@
#include <string.h>
#include <winpr/crt.h>
#include <winpr/print.h>
#include <freerdp/types.h>
#include <freerdp/constants.h>
#include <freerdp/utils/hexdump.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/unicode.h>
#include <freerdp/utils/svc_plugin.h>
#include <freerdp/client/cliprdr.h>
@@ -146,7 +144,7 @@ void cliprdr_process_short_format_names(cliprdrPlugin* cliprdr, STREAM* s, UINT3
}
else
{
format_name->length = freerdp_UnicodeToAsciiAlloc((WCHAR*) s->p, &format_name->name, 32 / 2);
format_name->length = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) s->p, 32 / 2, &format_name->name, 0, NULL, NULL);
}
stream_seek(s, 32);
@@ -189,7 +187,8 @@ void cliprdr_process_long_format_names(cliprdrPlugin* cliprdr, STREAM* s, UINT32
break;
}
format_name->length = freerdp_UnicodeToAsciiAlloc((WCHAR*) stream_get_tail(s), &format_name->name, name_len / 2);
format_name->length = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(s), name_len / 2, &format_name->name, 0, NULL, NULL);
stream_seek(s, name_len + 2);
}
}

View File

@@ -30,8 +30,6 @@
#include <freerdp/types.h>
#include <freerdp/constants.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/unicode.h>
#include <freerdp/utils/svc_plugin.h>
#include <freerdp/client/cliprdr.h>

View File

@@ -3,10 +3,6 @@ set(OPTION_DEFAULT OFF)
set(OPTION_CLIENT_DEFAULT ON)
set(OPTION_SERVER_DEFAULT OFF)
if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT})
set(OPTION_DEFAULT ON)
endif()
define_channel_options(NAME "drdynvc" TYPE "static"
DESCRIPTION "Dynamic Virtual Channel Extension"
SPECIFICATIONS "[MS-RDPEDYC]"

View File

@@ -28,20 +28,18 @@
#include <winpr/crt.h>
#include <freerdp/constants.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/svc_plugin.h>
#include <freerdp/utils/wait_obj.h>
#include "dvcman.h"
#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 +74,7 @@ static int drdynvc_write_variable_uint(STREAM* stream, UINT32 val)
cb = 2;
stream_write_UINT32(stream, val);
}
return cb;
}
@@ -97,13 +96,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 +111,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 +125,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 +147,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 +162,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 +181,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 +189,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 +215,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 +257,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 +311,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 +351,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 +379,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 +415,3 @@ int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
return 1;
}

View File

@@ -28,10 +28,10 @@
#include <winpr/crt.h>
#include <winpr/synch.h>
#include <freerdp/utils/memory.h>
#include <freerdp/addin.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/list.h>
#include <freerdp/utils/load_plugin.h>
#include "drdynvc_types.h"
#include "dvcman.h"
@@ -39,6 +39,7 @@
#define MAX_PLUGINS 10
typedef struct _DVCMAN DVCMAN;
struct _DVCMAN
{
IWTSVirtualChannelManager iface;
@@ -72,7 +73,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;
@@ -100,13 +101,16 @@ static int dvcman_create_listener(IWTSVirtualChannelManager* pChannelMgr,
const char* pszChannelName, UINT32 ulFlags,
IWTSListenerCallback* pListenerCallback, IWTSListener** ppListener)
{
DVCMAN* dvcman = (DVCMAN*)pChannelMgr;
DVCMAN* dvcman = (DVCMAN*) pChannelMgr;
DVCMAN_LISTENER* listener;
if (dvcman->num_listeners < MAX_PLUGINS)
{
DEBUG_DVC("%d.%s.", dvcman->num_listeners, pszChannelName);
listener = xnew(DVCMAN_LISTENER);
listener = (DVCMAN_LISTENER*) malloc(sizeof(DVCMAN_LISTENER));
ZeroMemory(listener, sizeof(DVCMAN_LISTENER));
listener->iface.GetConfiguration = dvcman_get_configuration;
listener->dvcman = dvcman;
listener->channel_name = _strdup(pszChannelName);
@@ -181,14 +185,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)
@@ -200,7 +204,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;
}
}
@@ -211,7 +215,9 @@ IWTSVirtualChannelManager* dvcman_new(drdynvcPlugin* plugin)
{
DVCMAN* dvcman;
dvcman = xnew(DVCMAN);
dvcman = (DVCMAN*) malloc(sizeof(DVCMAN));
ZeroMemory(dvcman, sizeof(DVCMAN));
dvcman->iface.CreateListener = dvcman_create_listener;
dvcman->iface.PushEvent = dvcman_push_event;
dvcman->iface.FindChannelById = dvcman_find_channel_by_id;
@@ -222,26 +228,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)
{
pDVCPluginEntry = (PDVC_PLUGIN_ENTRY) freerdp_load_plugin((char*) data->data[0], "DVCPluginEntry");
printf("Loading Dynamic Virtual Channel %s\n", args->argv[0]);
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);
pDVCPluginEntry = (PDVC_PLUGIN_ENTRY) freerdp_load_channel_addin_entry(args->argv[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.args = args;
pDVCPluginEntry((IDRDYNVC_ENTRY_POINTS*) &entryPoints);
}
return 0;
@@ -341,11 +345,13 @@ 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)
{
channel = xnew(DVCMAN_CHANNEL);
channel = (DVCMAN_CHANNEL*) malloc(sizeof(DVCMAN_CHANNEL));
ZeroMemory(channel, sizeof(DVCMAN_CHANNEL));
channel->iface.Write = dvcman_write_channel;
channel->iface.Close = dvcman_close_channel_iface;
channel->dvcman = dvcman;
@@ -377,7 +383,6 @@ int dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 Channel
return 1;
}
int dvcman_close_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId)
{
DVCMAN_CHANNEL* channel;

View File

@@ -21,10 +21,12 @@
#define __DVCMAN_H
#include <freerdp/dvc.h>
#include <freerdp/addin.h>
#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);

View File

@@ -8,10 +8,6 @@ if(ANDROID)
set(OPTION_SERVER_DEFAULT OFF)
endif()
if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT})
set(OPTION_DEFAULT ON)
endif()
define_channel_options(NAME "drive" TYPE "device"
DESCRIPTION "Drive Redirection Virtual Channel Extension"
SPECIFICATIONS "[MS-RDPEFS]"

View File

@@ -41,9 +41,7 @@
#include <winpr/crt.h>
#include <winpr/file.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/unicode.h>
#include <freerdp/channels/rdpdr.h>
#include <freerdp/utils/svc_plugin.h>
@@ -291,7 +289,9 @@ DRIVE_FILE* drive_file_new(const char* base_path, const char* path, UINT32 id,
{
DRIVE_FILE* file;
file = xnew(DRIVE_FILE);
file = (DRIVE_FILE*) malloc(sizeof(DRIVE_FILE));
ZeroMemory(file, sizeof(DRIVE_FILE));
file->id = id;
file->basepath = (char*) base_path;
drive_file_set_fullpath(file, drive_file_combine_fullpath(base_path, path));
@@ -431,9 +431,9 @@ BOOL drive_file_query_information(DRIVE_FILE* file, UINT32 FsInformationClass, S
BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UINT32 Length, STREAM* input)
{
char* s;
mode_t m;
UINT64 size;
int status;
char* fullpath;
struct STAT st;
struct timeval tv[2];
@@ -501,7 +501,11 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
stream_seek_BYTE(input); /* RootDirectory */
stream_read_UINT32(input, FileNameLength);
freerdp_UnicodeToAsciiAlloc((WCHAR*) stream_get_tail(input), &s, FileNameLength / 2);
status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(input),
FileNameLength / 2, &s, 0, NULL, NULL);
if (status < 1)
s = (char*) calloc(1, 1);
fullpath = drive_file_combine_fullpath(file->basepath, s);
free(s);
@@ -597,8 +601,9 @@ BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYT
DEBUG_SVC(" pattern %s matched %s", file->pattern, ent_path);
free(ent_path);
ent_path = NULL;
length = freerdp_AsciiToUnicodeAlloc(ent->d_name, &ent_path, 0) * 2;
length = ConvertToUnicode(CP_UTF8, 0, ent->d_name, -1, &ent_path, 0) * 2;
ret = TRUE;

View File

@@ -35,18 +35,16 @@
#include <stdlib.h>
#include <string.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/unicode.h>
#include <freerdp/utils/list.h>
#include <freerdp/channels/rdpdr.h>
#include <freerdp/utils/svc_plugin.h>
#include <winpr/crt.h>
#include <winpr/synch.h>
#include <winpr/thread.h>
#include <winpr/interlocked.h>
#include <freerdp/utils/list.h>
#include <freerdp/utils/stream.h>
#include <freerdp/channels/rdpdr.h>
#include <freerdp/utils/svc_plugin.h>
#include "drive_file.h"
typedef struct _DRIVE_DEVICE DRIVE_DEVICE;
@@ -120,6 +118,7 @@ static DRIVE_FILE* drive_get_file_by_id(DRIVE_DEVICE* disk, UINT32 id)
static void drive_process_irp_create(DRIVE_DEVICE* disk, IRP* irp)
{
char* path;
int status;
UINT32 FileId;
DRIVE_FILE* file;
BYTE Information;
@@ -134,7 +133,11 @@ static void drive_process_irp_create(DRIVE_DEVICE* disk, IRP* irp)
stream_read_UINT32(irp->input, CreateOptions);
stream_read_UINT32(irp->input, PathLength);
freerdp_UnicodeToAsciiAlloc((WCHAR*) stream_get_tail(irp->input), &path, PathLength / 2);
status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(irp->input),
PathLength / 2, &path, 0, NULL, NULL);
if (status < 1)
path = (char*) calloc(1, 1);
FileId = irp->devman->id_sequence++;
@@ -388,7 +391,7 @@ static void drive_process_irp_query_volume_information(DRIVE_DEVICE* disk, IRP*
struct STAT st;
char* volumeLabel = {"FREERDP"};
char* diskType = {"FAT32"};
WCHAR* outStr;
WCHAR* outStr = NULL;
int length;
stream_read_UINT32(irp->input, FsInformationClass);
@@ -400,7 +403,7 @@ static void drive_process_irp_query_volume_information(DRIVE_DEVICE* disk, IRP*
{
case FileFsVolumeInformation:
/* http://msdn.microsoft.com/en-us/library/cc232108.aspx */
length = freerdp_AsciiToUnicodeAlloc(volumeLabel, &outStr, 0) * 2;
length = ConvertToUnicode(CP_UTF8, 0, volumeLabel, -1, &outStr, 0) * 2;
stream_write_UINT32(output, 17 + length); /* Length */
stream_check_size(output, 17 + length);
stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* VolumeCreationTime */
@@ -424,7 +427,7 @@ static void drive_process_irp_query_volume_information(DRIVE_DEVICE* disk, IRP*
case FileFsAttributeInformation:
/* http://msdn.microsoft.com/en-us/library/cc232101.aspx */
length = freerdp_AsciiToUnicodeAlloc(diskType, &outStr, 0) * 2;
length = ConvertToUnicode(CP_UTF8, 0, diskType, -1, &outStr, 0) * 2;
stream_write_UINT32(output, 12 + length); /* Length */
stream_check_size(output, 12 + length);
stream_write_UINT32(output,
@@ -469,6 +472,7 @@ static void drive_process_irp_query_volume_information(DRIVE_DEVICE* disk, IRP*
static void drive_process_irp_query_directory(DRIVE_DEVICE* disk, IRP* irp)
{
char* path;
int status;
DRIVE_FILE* file;
BYTE InitialQuery;
UINT32 PathLength;
@@ -479,7 +483,11 @@ static void drive_process_irp_query_directory(DRIVE_DEVICE* disk, IRP* irp)
stream_read_UINT32(irp->input, PathLength);
stream_seek(irp->input, 23); /* Padding */
freerdp_UnicodeToAsciiAlloc((WCHAR*) stream_get_tail(irp->input), &path, PathLength / 2);
status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(irp->input),
PathLength / 2, &path, 0, NULL, NULL);
if (status < 1)
path = (char*) calloc(1, 1);
file = drive_get_file_by_id(disk, irp->FileId);
@@ -640,6 +648,7 @@ static void drive_free(DEVICE* device)
drive_file_free(file);
list_free(disk->files);
free(disk);
}
@@ -664,7 +673,8 @@ void drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char*
if (name[0] && path[0])
{
disk = xnew(DRIVE_DEVICE);
disk = (DRIVE_DEVICE*) malloc(sizeof(DRIVE_DEVICE));
ZeroMemory(disk, sizeof(DRIVE_DEVICE));
disk->device.type = RDPDR_DTYP_FILESYSTEM;
disk->device.name = name;

View File

@@ -13,10 +13,6 @@ if(ANDROID)
set(OPTION_SERVER_DEFAULT OFF)
endif()
if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT})
set(OPTION_DEFAULT ON)
endif()
define_channel_options(NAME "parallel" TYPE "device"
DESCRIPTION "Parallel Port Virtual Channel Extension"
SPECIFICATIONS "[MS-RDPESP]"

View File

@@ -53,9 +53,7 @@
#include <freerdp/constants.h>
#include <freerdp/utils/list.h>
#include <freerdp/utils/thread.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/unicode.h>
#include <freerdp/utils/svc_plugin.h>
#include <freerdp/channels/rdpdr.h>
@@ -75,6 +73,7 @@ typedef struct _PARALLEL_DEVICE PARALLEL_DEVICE;
static void parallel_process_irp_create(PARALLEL_DEVICE* parallel, IRP* irp)
{
char* path;
int status;
UINT32 PathLength;
stream_seek(irp->input, 28);
@@ -82,7 +81,11 @@ static void parallel_process_irp_create(PARALLEL_DEVICE* parallel, IRP* irp)
/* SharedAccess(4) CreateDisposition(4), CreateOptions(4) */
stream_read_UINT32(irp->input, PathLength);
freerdp_UnicodeToAsciiAlloc((WCHAR*) stream_get_tail(irp->input), &path, PathLength / 2);
status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(irp->input),
PathLength / 2, &path, 0, NULL, NULL);
if (status < 1)
path = (char*) calloc(1, 1);
parallel->id = irp->devman->id_sequence++;
parallel->file = open(parallel->path, O_RDWR);
@@ -325,7 +328,8 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
if (name[0] && path[0])
{
parallel = xnew(PARALLEL_DEVICE);
parallel = (PARALLEL_DEVICE*) malloc(sizeof(PARALLEL_DEVICE));
ZeroMemory(parallel, sizeof(PARALLEL_DEVICE));
parallel->device.type = RDPDR_DTYP_PARALLEL;
parallel->device.name = name;

View File

@@ -14,10 +14,6 @@ else()
set(OPTION_SERVER_DEFAULT OFF)
endif()
if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT})
set(OPTION_DEFAULT ON)
endif()
define_channel_options(NAME "printer" TYPE "device"
DESCRIPTION "Print Virtual Channel Extension"
SPECIFICATIONS "[MS-RDPEPC]"

View File

@@ -31,7 +31,6 @@
#include <winpr/crt.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/svc_plugin.h>
#include <freerdp/channels/rdpdr.h>
@@ -79,36 +78,39 @@ static void printer_cups_get_printjob_name(char* buf, int size)
static void printer_cups_write_printjob(rdpPrintJob* printjob, BYTE* data, int size)
{
rdpCupsPrintJob* cups_printjob = (rdpCupsPrintJob*)printjob;
rdpCupsPrintJob* cups_printjob = (rdpCupsPrintJob*) printjob;
#ifndef _CUPS_API_1_4
{
FILE* fp;
fp = fopen((const char*)cups_printjob->printjob_object, "a+b");
fp = fopen((const char*) cups_printjob->printjob_object, "a+b");
if (fp == NULL)
{
DEBUG_WARN("failed to open file %s", (char*)cups_printjob->printjob_object);
DEBUG_WARN("failed to open file %s", (char*) cups_printjob->printjob_object);
return;
}
if (fwrite(data, 1, size, fp) < size)
{
DEBUG_WARN("failed to write file %s", (char*)cups_printjob->printjob_object);
DEBUG_WARN("failed to write file %s", (char*) cups_printjob->printjob_object);
}
fclose(fp);
}
#else
cupsWriteRequestData((http_t*)cups_printjob->printjob_object, (const char*)data, size);
cupsWriteRequestData((http_t*) cups_printjob->printjob_object, (const char*) data, size);
#endif
}
static void printer_cups_close_printjob(rdpPrintJob* printjob)
{
rdpCupsPrintJob* cups_printjob = (rdpCupsPrintJob*)printjob;
rdpCupsPrintJob* cups_printjob = (rdpCupsPrintJob*) printjob;
#ifndef _CUPS_API_1_4
@@ -116,35 +118,38 @@ static void printer_cups_close_printjob(rdpPrintJob* printjob)
char buf[100];
printer_cups_get_printjob_name(buf, sizeof(buf));
if (cupsPrintFile(printjob->printer->name, (const char *)cups_printjob->printjob_object, buf, 0, NULL) == 0)
if (cupsPrintFile(printjob->printer->name, (const char*) cups_printjob->printjob_object, buf, 0, NULL) == 0)
{
DEBUG_WARN("cupsPrintFile: %s", cupsLastErrorString());
}
unlink(cups_printjob->printjob_object);
free(cups_printjob->printjob_object);
}
#else
cupsFinishDocument((http_t*)cups_printjob->printjob_object, printjob->printer->name);
cupsFinishDocument((http_t*) cups_printjob->printjob_object, printjob->printer->name);
cups_printjob->printjob_id = 0;
httpClose((http_t*)cups_printjob->printjob_object);
httpClose((http_t*) cups_printjob->printjob_object);
#endif
((rdpCupsPrinter*)printjob->printer)->printjob = NULL;
((rdpCupsPrinter*) printjob->printer)->printjob = NULL;
free(cups_printjob) ;
}
static rdpPrintJob* printer_cups_create_printjob(rdpPrinter* printer, UINT32 id)
{
rdpCupsPrinter* cups_printer = (rdpCupsPrinter*)printer;
rdpCupsPrinter* cups_printer = (rdpCupsPrinter*) printer;
rdpCupsPrintJob* cups_printjob;
if (cups_printer->printjob != NULL)
return NULL;
cups_printjob = xnew(rdpCupsPrintJob);
cups_printjob = (rdpCupsPrintJob*) malloc(sizeof(rdpCupsPrintJob));
ZeroMemory(cups_printjob, sizeof(rdpCupsPrintJob));
cups_printjob->printjob.id = id;
cups_printjob->printjob.printer = printer;
@@ -161,6 +166,7 @@ static rdpPrintJob* printer_cups_create_printjob(rdpPrinter* printer, UINT32 id)
char buf[100];
cups_printjob->printjob_object = httpConnectEncrypt(cupsServer(), ippPort(), HTTP_ENCRYPT_IF_REQUESTED);
if (cups_printjob->printjob_object == NULL)
{
DEBUG_WARN("httpConnectEncrypt: %s", cupsLastErrorString());
@@ -169,19 +175,19 @@ static rdpPrintJob* printer_cups_create_printjob(rdpPrinter* printer, UINT32 id)
}
printer_cups_get_printjob_name(buf, sizeof(buf));
cups_printjob->printjob_id = cupsCreateJob((http_t*)cups_printjob->printjob_object,
cups_printjob->printjob_id = cupsCreateJob((http_t*) cups_printjob->printjob_object,
printer->name, buf, 0, NULL);
if (cups_printjob->printjob_id == 0)
{
DEBUG_WARN("cupsCreateJob: %s", cupsLastErrorString());
httpClose((http_t*)cups_printjob->printjob_object);
httpClose((http_t*) cups_printjob->printjob_object);
free(cups_printjob);
return NULL;
}
cupsStartDocument((http_t*)cups_printjob->printjob_object,
printer->name, cups_printjob->printjob_id, buf,
CUPS_FORMAT_AUTO, 1);
cupsStartDocument((http_t*) cups_printjob->printjob_object,
printer->name, cups_printjob->printjob_id, buf, CUPS_FORMAT_AUTO, 1);
}
#endif
@@ -205,10 +211,11 @@ static rdpPrintJob* printer_cups_find_printjob(rdpPrinter* printer, UINT32 id)
static void printer_cups_free_printer(rdpPrinter* printer)
{
rdpCupsPrinter* cups_printer = (rdpCupsPrinter*)printer;
rdpCupsPrinter* cups_printer = (rdpCupsPrinter*) printer;
if (cups_printer->printjob)
cups_printer->printjob->printjob.Close((rdpPrintJob*)cups_printer->printjob);
cups_printer->printjob->printjob.Close((rdpPrintJob*) cups_printer->printjob);
free(printer->name);
free(printer);
}
@@ -217,7 +224,8 @@ static rdpPrinter* printer_cups_new_printer(rdpCupsPrinterDriver* cups_driver, c
{
rdpCupsPrinter* cups_printer;
cups_printer = xnew(rdpCupsPrinter);
cups_printer = (rdpCupsPrinter*) malloc(sizeof(rdpCupsPrinter));
ZeroMemory(cups_printer, sizeof(rdpCupsPrinter));
cups_printer->printer.id = cups_driver->id_sequence++;
cups_printer->printer.name = _strdup(name);
@@ -229,7 +237,7 @@ static rdpPrinter* printer_cups_new_printer(rdpCupsPrinterDriver* cups_driver, c
cups_printer->printer.FindPrintJob = printer_cups_find_printjob;
cups_printer->printer.Free = printer_cups_free_printer;
return (rdpPrinter*)cups_printer;
return (rdpPrinter*) cups_printer;
}
static rdpPrinter** printer_cups_enum_printers(rdpPrinterDriver* driver)
@@ -242,13 +250,16 @@ static rdpPrinter** printer_cups_enum_printers(rdpPrinterDriver* driver)
int i;
num_dests = cupsGetDests(&dests);
printers = (rdpPrinter**)xzalloc(sizeof(rdpPrinter*) * (num_dests + 1));
printers = (rdpPrinter**) malloc(sizeof(rdpPrinter*) * (num_dests + 1));
ZeroMemory(printers, sizeof(rdpPrinter*) * (num_dests + 1));
num_printers = 0;
for (i = 0, dest = dests; i < num_dests; i++, dest++)
{
if (dest->instance == NULL)
{
printers[num_printers++] = printer_cups_new_printer((rdpCupsPrinterDriver*)driver,
printers[num_printers++] = printer_cups_new_printer((rdpCupsPrinterDriver*) driver,
dest->name, dest->is_default);
}
}
@@ -259,7 +270,7 @@ static rdpPrinter** printer_cups_enum_printers(rdpPrinterDriver* driver)
static rdpPrinter* printer_cups_get_printer(rdpPrinterDriver* driver, const char* name)
{
rdpCupsPrinterDriver* cups_driver = (rdpCupsPrinterDriver*)driver;
rdpCupsPrinterDriver* cups_driver = (rdpCupsPrinterDriver*) driver;
return printer_cups_new_printer(cups_driver, name, cups_driver->id_sequence == 1 ? TRUE : FALSE);
}
@@ -270,7 +281,8 @@ rdpPrinterDriver* printer_cups_get_driver(void)
{
if (cups_driver == NULL)
{
cups_driver = xnew(rdpCupsPrinterDriver);
cups_driver = (rdpCupsPrinterDriver*) malloc(sizeof(rdpCupsPrinterDriver));
ZeroMemory(cups_driver, sizeof(rdpCupsPrinterDriver));
cups_driver->driver.EnumPrinters = printer_cups_enum_printers;
cups_driver->driver.GetPrinter = printer_cups_get_printer;
@@ -284,6 +296,6 @@ rdpPrinterDriver* printer_cups_get_driver(void)
#endif
}
return (rdpPrinterDriver*)cups_driver;
return (rdpPrinterDriver*) cups_driver;
}

View File

@@ -31,8 +31,6 @@
#include <winpr/interlocked.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/unicode.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/thread.h>
#include <freerdp/utils/svc_plugin.h>
#include <freerdp/channels/rdpdr.h>
@@ -237,9 +235,9 @@ void printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* pri
char* port;
UINT32 Flags;
int DriverNameLen;
WCHAR* DriverName;
WCHAR* DriverName = NULL;
int PrintNameLen;
WCHAR* PrintName;
WCHAR* PrintName = NULL;
UINT32 CachedFieldsLen;
BYTE* CachedPrinterConfigData;
PRINTER_DEVICE* printer_dev;
@@ -247,7 +245,8 @@ void printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* pri
port = malloc(10);
snprintf(port, 10, "PRN%d", printer->id);
printer_dev = xnew(PRINTER_DEVICE);
printer_dev = (PRINTER_DEVICE*) malloc(sizeof(PRINTER_DEVICE));
ZeroMemory(printer_dev, sizeof(PRINTER_DEVICE));
printer_dev->device.type = RDPDR_DTYP_PRINT;
printer_dev->device.name = port;
@@ -266,8 +265,8 @@ void printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* pri
if (printer->is_default)
Flags |= RDPDR_PRINTER_ANNOUNCE_FLAG_DEFAULTPRINTER;
DriverNameLen = freerdp_AsciiToUnicodeAlloc(printer->driver, &DriverName, 0) * 2;
PrintNameLen = freerdp_AsciiToUnicodeAlloc(printer->name, &PrintName, 0) * 2;
DriverNameLen = ConvertToUnicode(CP_UTF8, 0, printer->driver, -1, &DriverName, 0) * 2;
PrintNameLen = ConvertToUnicode(CP_UTF8, 0, printer->name, -1, &PrintName, 0) * 2;
printer_dev->device.data = stream_new(28 + DriverNameLen + PrintNameLen + CachedFieldsLen);

View File

@@ -30,7 +30,6 @@
#include <string.h>
#include <winspool.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/svc_plugin.h>
#include "printer_main.h"
@@ -121,7 +120,8 @@ static rdpPrintJob* printer_win_create_printjob(rdpPrinter* printer, UINT32 id)
if (win_printer->printjob != NULL)
return NULL;
win_printjob = xnew(rdpWinPrintJob);
win_printjob = (rdpWinPrintJob*) malloc(sizeof(rdpWinPrintJob));
ZeroMemory(win_printjob, sizeof(rdpWinPrintJob));
win_printjob->printjob.id = id;
win_printjob->printjob.printer = printer;
@@ -129,44 +129,46 @@ static rdpPrintJob* printer_win_create_printjob(rdpPrinter* printer, UINT32 id)
win_printjob->di.pDatatype= NULL;
win_printjob->di.pOutputFile = NULL;
win_printjob->handle = StartDocPrinter(win_printer->hPrinter, 1, (LPBYTE)&(win_printjob->di) );
if(! win_printjob->handle) DEBUG_WINPR("StartDocPrinter failed");
if ( ! StartPagePrinter(win_printer->hPrinter) )
DEBUG_WINPR("ClosePrinter failed");
win_printjob->handle = StartDocPrinter(win_printer->hPrinter, 1, (LPBYTE) &(win_printjob->di));
if (!win_printjob->handle)
DEBUG_WINPR("StartDocPrinter failed");
if (!StartPagePrinter(win_printer->hPrinter))
DEBUG_WINPR("ClosePrinter failed");
win_printjob->printjob.Write = printer_win_write_printjob;
win_printjob->printjob.Close = printer_win_close_printjob;
win_printer->printjob = win_printjob;
return (rdpPrintJob*)win_printjob;
return (rdpPrintJob*) win_printjob;
}
static rdpPrintJob* printer_win_find_printjob(rdpPrinter* printer, UINT32 id)
{
rdpWinPrinter* win_printer = (rdpWinPrinter*)printer;
rdpWinPrinter* win_printer = (rdpWinPrinter*) printer;
DEBUG_WINPR("");
DEBUG_WINPR("");
if (win_printer->printjob == NULL)
return NULL;
if (win_printer->printjob->printjob.id != id)
return NULL;
return (rdpPrintJob*)win_printer->printjob;
return (rdpPrintJob*) win_printer->printjob;
}
static void printer_win_free_printer(rdpPrinter* printer)
{
rdpWinPrinter* win_printer = (rdpWinPrinter*)printer;
rdpWinPrinter* win_printer = (rdpWinPrinter*) printer;
DEBUG_WINPR("");
DEBUG_WINPR("");
if (win_printer->printjob)
win_printer->printjob->printjob.Close((rdpPrintJob*)win_printer->printjob);
win_printer->printjob->printjob.Close((rdpPrintJob*) win_printer->printjob);
free(printer->name);
free(printer);
}
@@ -174,13 +176,14 @@ static void printer_win_free_printer(rdpPrinter* printer)
static rdpPrinter* printer_win_new_printer(rdpWinPrinterDriver* win_driver, const char* name, const wchar_t* drivername, BOOL is_default)
{
rdpWinPrinter* win_printer;
wchar_t wname[256];
wchar_t wname[256];
DWORD needed;
PRINTER_INFO_2 *prninfo=NULL;
size_t charsConverted;
DEBUG_WINPR("");
win_printer = xnew(rdpWinPrinter);
win_printer = (rdpWinPrinter*) malloc(sizeof(rdpWinPrinter));
ZeroMemory(win_printer, sizeof(rdpWinPrinter));
win_printer->printer.id = win_driver->id_sequence++;
win_printer->printer.name = _strdup(name);
@@ -190,7 +193,7 @@ static rdpPrinter* printer_win_new_printer(rdpWinPrinterDriver* win_driver, cons
win_printer->printer.FindPrintJob = printer_win_find_printjob;
win_printer->printer.Free = printer_win_free_printer;
swprintf(wname, 256, L"%hs", name);
swprintf(wname, 256, L"%hs", name);
OpenPrinter(wname, &(win_printer->hPrinter), NULL);
DEBUG_WINPR("handle: 0x%08X", win_printer->hPrinter);
@@ -211,31 +214,30 @@ static rdpPrinter** printer_win_enum_printers(rdpPrinterDriver* driver)
int i;
char pname[1000];
size_t charsConverted;
PRINTER_INFO_2 *prninfo=NULL;
DWORD needed, returned;
PRINTER_INFO_2* prninfo = NULL;
DWORD needed, returned;
DEBUG_WINPR("");
DEBUG_WINPR("");
/* find required size for the buffer */
EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, NULL, 2, NULL, 0, &needed, &returned);
//find required size for the buffer
EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, NULL, 2, NULL, 0, &needed, &returned);
//allocate array of PRINTER_INFO structures
prninfo = (PRINTER_INFO_2*) GlobalAlloc(GPTR,needed);
/* allocate array of PRINTER_INFO structures */
prninfo = (PRINTER_INFO_2*) GlobalAlloc(GPTR,needed);
//call again
if ( !EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, NULL, 2, (LPBYTE) prninfo, needed, &needed, &returned) ) {
/* call again */
if ( !EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, NULL, 2, (LPBYTE) prninfo, needed, &needed, &returned) )
{
DEBUG_WINPR("EnumPrinters failed");
} ; /* eRROR... */
} ; /* ERROR... */
DEBUG_WINPR("printers found: %d", returned);
printers = (rdpPrinter**) malloc(sizeof(rdpPrinter*) * (returned + 1));
ZeroMemory(printers, sizeof(rdpPrinter*) * (returned + 1));
printers = (rdpPrinter**)xzalloc(sizeof(rdpPrinter*) * (returned + 1));
num_printers = 0;
num_printers = 0;
for (i = 0; i < (int)returned; i++)
{
@@ -268,20 +270,15 @@ rdpPrinterDriver* printer_win_get_driver(void)
if (win_driver == NULL)
{
win_driver = xnew(rdpWinPrinterDriver);
win_driver = (rdpWinPrinterDriver*) malloc(sizeof(rdpWinPrinterDriver));
ZeroMemory(win_driver, sizeof(rdpWinPrinterDriver));
win_driver->driver.EnumPrinters = printer_win_enum_printers;
win_driver->driver.GetPrinter = printer_win_get_printer;
win_driver->id_sequence = 1;
//#ifdef _win_API_1_4
// DEBUG_SVC("using win API 1.4");
//#else
// DEBUG_SVC("using win API 1.2");
//#endif
}
return (rdpPrinterDriver*)win_driver;
return (rdpPrinterDriver*) win_driver;
}

View File

@@ -3,10 +3,6 @@ set(OPTION_DEFAULT OFF)
set(OPTION_CLIENT_DEFAULT ON)
set(OPTION_SERVER_DEFAULT OFF)
if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT})
set(OPTION_DEFAULT ON)
endif()
define_channel_options(NAME "rail" TYPE "static"
DESCRIPTION "Remote Programs Virtual Channel Extension"
SPECIFICATIONS "[MS-RDPERP]"

View File

@@ -31,7 +31,6 @@
#include <freerdp/types.h>
#include <freerdp/constants.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/svc_plugin.h>
#include <freerdp/utils/rail.h>
#include <freerdp/rail.h>
@@ -80,7 +79,7 @@ static void rail_process_connect(rdpSvcPlugin* plugin)
railPlugin* rail = (railPlugin*) plugin;
rail->rail_order = rail_order_new();
rail->rail_order->plugin_data = (RDP_PLUGIN_DATA*)plugin->channel_entry_points.pExtendedData;
rail->rail_order->settings = (rdpSettings*) plugin->channel_entry_points.pExtendedData;
rail->rail_order->plugin = rail;
}
@@ -96,11 +95,11 @@ static void rail_process_receive(rdpSvcPlugin* plugin, STREAM* s)
stream_free(s);
}
static void rail_process_plugin_data(rdpRailOrder* rail_order, RDP_PLUGIN_DATA* data)
static void rail_process_addin_args(rdpRailOrder* rail_order, rdpSettings* settings)
{
char* exeOrFile;
exeOrFile = (char*) data->data[0];
exeOrFile = settings->RemoteApplicationProgram;
if (strlen(exeOrFile) >= 2)
{
@@ -108,21 +107,20 @@ static void rail_process_plugin_data(rdpRailOrder* rail_order, RDP_PLUGIN_DATA*
rail_order->exec.flags |= RAIL_EXEC_FLAG_FILE;
}
rail_string_to_unicode_string(rail_order, (char*) data->data[0], &rail_order->exec.exeOrFile);
rail_string_to_unicode_string(rail_order, (char*) data->data[1], &rail_order->exec.workingDir);
rail_string_to_unicode_string(rail_order, (char*) data->data[2], &rail_order->exec.arguments);
rail_string_to_unicode_string(rail_order, settings->RemoteApplicationProgram, &rail_order->exec.exeOrFile);
rail_string_to_unicode_string(rail_order, settings->ShellWorkingDirectory, &rail_order->exec.workingDir);
rail_string_to_unicode_string(rail_order, settings->RemoteApplicationCmdLine, &rail_order->exec.arguments);
rail_send_client_exec_order(rail_order);
}
static void rail_recv_set_sysparams_event(rdpRailOrder* rail_order, RDP_EVENT* event)
{
RDP_PLUGIN_DATA* data;
RAIL_SYSPARAM_ORDER* sysparam;
/* Send System Parameters */
sysparam = (RAIL_SYSPARAM_ORDER*)event->user_data;
sysparam = (RAIL_SYSPARAM_ORDER*) event->user_data;
memmove(&rail_order->sysparam, sysparam, sizeof(RAIL_SYSPARAM_ORDER));
rail_send_client_sysparams_order(rail_order);
@@ -131,19 +129,18 @@ static void rail_recv_set_sysparams_event(rdpRailOrder* rail_order, RDP_EVENT* e
rail_order->exec.flags = RAIL_EXEC_FLAG_EXPAND_ARGUMENTS;
data = rail_order->plugin_data;
while (data && data->size > 0)
{
rail_process_plugin_data(rail_order, data);
data = (RDP_PLUGIN_DATA*)((char *)(data) + data->size);
}
rail_process_addin_args(rail_order, rail_order->settings);
}
static void rail_recv_exec_remote_app_event(rdpRailOrder* rail_order, RDP_EVENT* event)
{
RDP_PLUGIN_DATA* data = (RDP_PLUGIN_DATA*) event->user_data;
/**
* TODO: replace event system by an API to allow the execution
* of multiple remote apps over the same connection. RAIL is
* always built-in, so clients can safely link to it.
*/
rail_process_plugin_data(rail_order, data);
//rail_process_addin_args(rail_order, data);
}
static void rail_recv_activate_event(rdpRailOrder* rail_order, RDP_EVENT* event)
@@ -279,4 +276,3 @@ int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
return 1;
}

View File

@@ -19,17 +19,18 @@
* limitations under the License.
*/
#ifndef __RAIL_MAIN_H
#define __RAIL_MAIN_H
#ifndef FREERDP_CHANNEL_CLIENT_RAIL_MAIN_H
#define FREERDP_CHANNEL_CLIENT_RAIL_MAIN_H
#include <freerdp/rail.h>
#include <freerdp/settings.h>
#include <freerdp/utils/debug.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/svc_plugin.h>
struct rdp_rail_order
{
RDP_PLUGIN_DATA* plugin_data;
rdpSettings* settings;
void* plugin;
RAIL_HANDSHAKE_ORDER handshake;
RAIL_CLIENT_STATUS_ORDER client_status;
@@ -65,4 +66,4 @@ void rail_send_channel_data(void* rail_object, void* data, size_t length);
#define DEBUG_RAIL(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
#endif
#endif /* __RAIL_MAIN_H */
#endif /* FREERDP_CHANNEL_CLIENT_RAIL_MAIN_H */

View File

@@ -28,7 +28,6 @@
#include <winpr/crt.h>
#include <freerdp/utils/rail.h>
#include <freerdp/utils/unicode.h>
#include "rail_orders.h"
@@ -71,7 +70,7 @@ static const char* const RAIL_ORDER_TYPE_STRINGS[] =
void rail_string_to_unicode_string(rdpRailOrder* rail_order, char* string, RAIL_UNICODE_STRING* unicode_string)
{
WCHAR* buffer;
WCHAR* buffer = NULL;
int length = 0;
if (unicode_string->string != NULL)
@@ -83,16 +82,19 @@ void rail_string_to_unicode_string(rdpRailOrder* rail_order, char* string, RAIL_
if (string == NULL || strlen(string) < 1)
return;
length = freerdp_AsciiToUnicodeAlloc(string, &buffer, 0) * 2;
length = ConvertToUnicode(CP_UTF8, 0, string, -1, &buffer, 0) * 2;
unicode_string->string = (BYTE*) buffer;
unicode_string->length = (UINT16) length;
}
void rail_read_pdu_header(STREAM* s, UINT16* orderType, UINT16* orderLength)
BOOL rail_read_pdu_header(STREAM* s, UINT16* orderType, UINT16* orderLength)
{
if(stream_get_left(s) < 4)
return FALSE;
stream_read_UINT16(s, *orderType); /* orderType (2 bytes) */
stream_read_UINT16(s, *orderLength); /* orderLength (2 bytes) */
return TRUE;
}
void rail_write_pdu_header(STREAM* s, UINT16 orderType, UINT16 orderLength)
@@ -134,23 +136,31 @@ void rail_write_high_contrast(STREAM* s, HIGH_CONTRAST* high_contrast)
rail_write_unicode_string(s, &high_contrast->colorScheme); /* colorScheme */
}
void rail_read_handshake_order(STREAM* s, RAIL_HANDSHAKE_ORDER* handshake)
BOOL rail_read_handshake_order(STREAM* s, RAIL_HANDSHAKE_ORDER* handshake)
{
if(stream_get_left(s) < 4)
return FALSE;
stream_read_UINT32(s, handshake->buildNumber); /* buildNumber (4 bytes) */
return TRUE;
}
void rail_read_server_exec_result_order(STREAM* s, RAIL_EXEC_RESULT_ORDER* exec_result)
BOOL rail_read_server_exec_result_order(STREAM* s, RAIL_EXEC_RESULT_ORDER* exec_result)
{
if(stream_get_left(s) < 8)
return FALSE;
stream_read_UINT16(s, exec_result->flags); /* flags (2 bytes) */
stream_read_UINT16(s, exec_result->execResult); /* execResult (2 bytes) */
stream_read_UINT32(s, exec_result->rawResult); /* rawResult (4 bytes) */
stream_seek_UINT16(s); /* padding (2 bytes) */
rail_read_unicode_string(s, &exec_result->exeOrFile); /* exeOrFile */
return rail_read_unicode_string(s, &exec_result->exeOrFile); /* exeOrFile */
}
void rail_read_server_sysparam_order(STREAM* s, RAIL_SYSPARAM_ORDER* sysparam)
BOOL rail_read_server_sysparam_order(STREAM* s, RAIL_SYSPARAM_ORDER* sysparam)
{
BYTE body;
if(stream_get_left(s) < 5)
return FALSE;
stream_read_UINT32(s, sysparam->param); /* systemParam (4 bytes) */
stream_read_BYTE(s, body); /* body (1 byte) */
@@ -167,10 +177,13 @@ void rail_read_server_sysparam_order(STREAM* s, RAIL_SYSPARAM_ORDER* sysparam)
default:
break;
}
return TRUE;
}
void rail_read_server_minmaxinfo_order(STREAM* s, RAIL_MINMAXINFO_ORDER* minmaxinfo)
BOOL rail_read_server_minmaxinfo_order(STREAM* s, RAIL_MINMAXINFO_ORDER* minmaxinfo)
{
if(stream_get_left(s) < 20)
return FALSE;
stream_read_UINT32(s, minmaxinfo->windowId); /* windowId (4 bytes) */
stream_read_UINT16(s, minmaxinfo->maxWidth); /* maxWidth (2 bytes) */
stream_read_UINT16(s, minmaxinfo->maxHeight); /* maxHeight (2 bytes) */
@@ -180,11 +193,14 @@ void rail_read_server_minmaxinfo_order(STREAM* s, RAIL_MINMAXINFO_ORDER* minmaxi
stream_read_UINT16(s, minmaxinfo->minTrackHeight); /* minTrackHeight (2 bytes) */
stream_read_UINT16(s, minmaxinfo->maxTrackWidth); /* maxTrackWidth (2 bytes) */
stream_read_UINT16(s, minmaxinfo->maxTrackHeight); /* maxTrackHeight (2 bytes) */
return TRUE;
}
void rail_read_server_localmovesize_order(STREAM* s, RAIL_LOCALMOVESIZE_ORDER* localmovesize)
BOOL rail_read_server_localmovesize_order(STREAM* s, RAIL_LOCALMOVESIZE_ORDER* localmovesize)
{
UINT16 isMoveSizeStart;
if(stream_get_left(s) < 12)
return FALSE;
stream_read_UINT32(s, localmovesize->windowId); /* windowId (4 bytes) */
stream_read_UINT16(s, isMoveSizeStart); /* isMoveSizeStart (2 bytes) */
@@ -193,20 +209,27 @@ void rail_read_server_localmovesize_order(STREAM* s, RAIL_LOCALMOVESIZE_ORDER* l
stream_read_UINT16(s, localmovesize->moveSizeType); /* moveSizeType (2 bytes) */
stream_read_UINT16(s, localmovesize->posX); /* posX (2 bytes) */
stream_read_UINT16(s, localmovesize->posY); /* posY (2 bytes) */
return TRUE;
}
void rail_read_server_get_appid_resp_order(STREAM* s, RAIL_GET_APPID_RESP_ORDER* get_appid_resp)
BOOL rail_read_server_get_appid_resp_order(STREAM* s, RAIL_GET_APPID_RESP_ORDER* get_appid_resp)
{
if(stream_get_left(s) < 516)
return FALSE;
stream_read_UINT32(s, get_appid_resp->windowId); /* windowId (4 bytes) */
stream_read(s, &get_appid_resp->applicationIdBuffer[0], 512); /* applicationId (256 UNICODE chars) */
get_appid_resp->applicationId.length = 512;
get_appid_resp->applicationId.string = &get_appid_resp->applicationIdBuffer[0];
return TRUE;
}
void rail_read_langbar_info_order(STREAM* s, RAIL_LANGBAR_INFO_ORDER* langbar_info)
BOOL rail_read_langbar_info_order(STREAM* s, RAIL_LANGBAR_INFO_ORDER* langbar_info)
{
if(stream_get_left(s) < 4)
return FALSE;
stream_read_UINT32(s, langbar_info->languageBarStatus); /* languageBarStatus (4 bytes) */
return TRUE;
}
void rail_write_handshake_order(STREAM* s, RAIL_HANDSHAKE_ORDER* handshake)
@@ -333,9 +356,10 @@ void rail_write_langbar_info_order(STREAM* s, RAIL_LANGBAR_INFO_ORDER* langbar_i
stream_write_UINT32(s, langbar_info->languageBarStatus); /* languageBarStatus (4 bytes) */
}
void rail_recv_handshake_order(rdpRailOrder* rail_order, STREAM* s)
BOOL rail_recv_handshake_order(rdpRailOrder* rail_order, STREAM* s)
{
rail_read_handshake_order(s, &rail_order->handshake);
if(!rail_read_handshake_order(s, &rail_order->handshake))
return FALSE;
rail_order->handshake.buildNumber = 0x00001DB0;
rail_send_handshake_order(rail_order);
@@ -372,56 +396,70 @@ void rail_recv_handshake_order(rdpRailOrder* rail_order, STREAM* s)
rail_send_channel_event(rail_order->plugin,
RDP_EVENT_TYPE_RAIL_CHANNEL_GET_SYSPARAMS, &rail_order->sysparam);
return TRUE;
}
void rail_recv_exec_result_order(rdpRailOrder* rail_order, STREAM* s)
BOOL rail_recv_exec_result_order(rdpRailOrder* rail_order, STREAM* s)
{
rail_read_server_exec_result_order(s, &rail_order->exec_result);
if(!rail_read_server_exec_result_order(s, &rail_order->exec_result))
return FALSE;
rail_send_channel_event(rail_order->plugin,
RDP_EVENT_TYPE_RAIL_CHANNEL_EXEC_RESULTS, &rail_order->exec_result);
return TRUE;
}
void rail_recv_server_sysparam_order(rdpRailOrder* rail_order, STREAM* s)
BOOL rail_recv_server_sysparam_order(rdpRailOrder* rail_order, STREAM* s)
{
rail_read_server_sysparam_order(s, &rail_order->sysparam);
if(!rail_read_server_sysparam_order(s, &rail_order->sysparam))
return FALSE;
rail_send_channel_event(rail_order->plugin,
RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_SYSPARAM, &rail_order->sysparam);
return TRUE;
}
void rail_recv_server_minmaxinfo_order(rdpRailOrder* rail_order, STREAM* s)
BOOL rail_recv_server_minmaxinfo_order(rdpRailOrder* rail_order, STREAM* s)
{
rail_read_server_minmaxinfo_order(s, &rail_order->minmaxinfo);
if(!rail_read_server_minmaxinfo_order(s, &rail_order->minmaxinfo))
return FALSE;
rail_send_channel_event(rail_order->plugin,
RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_MINMAXINFO, &rail_order->minmaxinfo);
return TRUE;
}
void rail_recv_server_localmovesize_order(rdpRailOrder* rail_order, STREAM* s)
BOOL rail_recv_server_localmovesize_order(rdpRailOrder* rail_order, STREAM* s)
{
rail_read_server_localmovesize_order(s, &rail_order->localmovesize);
if(!rail_read_server_localmovesize_order(s, &rail_order->localmovesize))
return FALSE;
rail_send_channel_event(rail_order->plugin,
RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_LOCALMOVESIZE, &rail_order->localmovesize);
return TRUE;
}
void rail_recv_server_get_appid_resp_order(rdpRailOrder* rail_order, STREAM* s)
BOOL rail_recv_server_get_appid_resp_order(rdpRailOrder* rail_order, STREAM* s)
{
rail_read_server_get_appid_resp_order(s, &rail_order->get_appid_resp);
if(!rail_read_server_get_appid_resp_order(s, &rail_order->get_appid_resp))
return FALSE;
rail_send_channel_event(rail_order->plugin,
RDP_EVENT_TYPE_RAIL_CHANNEL_APPID_RESP, &rail_order->get_appid_resp);
return TRUE;
}
void rail_recv_langbar_info_order(rdpRailOrder* rail_order, STREAM* s)
BOOL rail_recv_langbar_info_order(rdpRailOrder* rail_order, STREAM* s)
{
rail_read_langbar_info_order(s, &rail_order->langbar_info);
if(!rail_read_langbar_info_order(s, &rail_order->langbar_info))
return FALSE;
rail_send_channel_event(rail_order->plugin,
RDP_EVENT_TYPE_RAIL_CHANNEL_LANGBARINFO, &rail_order->langbar_info);
return TRUE;
}
void rail_order_recv(rdpRailOrder* rail_order, STREAM* s)
BOOL rail_order_recv(rdpRailOrder* rail_order, STREAM* s)
{
UINT16 orderType;
UINT16 orderLength;
rail_read_pdu_header(s, &orderType, &orderLength);
if(!rail_read_pdu_header(s, &orderType, &orderLength))
return FALSE;
DEBUG_RAIL("Received %s PDU, length:%d",
RAIL_ORDER_TYPE_STRINGS[((orderType & 0xF0) >> 3) + (orderType & 0x0F)], orderLength);
@@ -429,37 +467,31 @@ void rail_order_recv(rdpRailOrder* rail_order, STREAM* s)
switch (orderType)
{
case RDP_RAIL_ORDER_HANDSHAKE:
rail_recv_handshake_order(rail_order, s);
break;
return rail_recv_handshake_order(rail_order, s);
case RDP_RAIL_ORDER_EXEC_RESULT:
rail_recv_exec_result_order(rail_order, s);
break;
return rail_recv_exec_result_order(rail_order, s);
case RDP_RAIL_ORDER_SYSPARAM:
rail_recv_server_sysparam_order(rail_order, s);
break;
return rail_recv_server_sysparam_order(rail_order, s);
case RDP_RAIL_ORDER_MINMAXINFO:
rail_recv_server_minmaxinfo_order(rail_order, s);
break;
return rail_recv_server_minmaxinfo_order(rail_order, s);
case RDP_RAIL_ORDER_LOCALMOVESIZE:
rail_recv_server_localmovesize_order(rail_order, s);
break;
return rail_recv_server_localmovesize_order(rail_order, s);
case RDP_RAIL_ORDER_GET_APPID_RESP:
rail_recv_server_get_appid_resp_order(rail_order, s);
break;
return rail_recv_server_get_appid_resp_order(rail_order, s);
case RDP_RAIL_ORDER_LANGBARINFO:
rail_recv_langbar_info_order(rail_order, s);
break;
return rail_recv_langbar_info_order(rail_order, s);
default:
printf("Unknown RAIL PDU order reveived.");
break;
}
return TRUE;
}
void rail_send_handshake_order(rdpRailOrder* rail_order)

View File

@@ -56,13 +56,13 @@
void rail_string_to_unicode_string(rdpRailOrder* rail_order, char* string, RAIL_UNICODE_STRING* unicode_string);
void rail_read_handshake_order(STREAM* s, RAIL_HANDSHAKE_ORDER* handshake);
void rail_read_server_exec_result_order(STREAM* s, RAIL_EXEC_RESULT_ORDER* exec_result);
void rail_read_server_sysparam_order(STREAM* s, RAIL_SYSPARAM_ORDER* sysparam);
void rail_read_server_minmaxinfo_order(STREAM* s, RAIL_MINMAXINFO_ORDER* minmaxinfo);
void rail_read_server_localmovesize_order(STREAM* s, RAIL_LOCALMOVESIZE_ORDER* localmovesize);
void rail_read_server_get_appid_resp_order(STREAM* s, RAIL_GET_APPID_RESP_ORDER* get_appid_resp);
void rail_read_langbar_info_order(STREAM* s, RAIL_LANGBAR_INFO_ORDER* langbar_info);
BOOL rail_read_handshake_order(STREAM* s, RAIL_HANDSHAKE_ORDER* handshake);
BOOL rail_read_server_exec_result_order(STREAM* s, RAIL_EXEC_RESULT_ORDER* exec_result);
BOOL rail_read_server_sysparam_order(STREAM* s, RAIL_SYSPARAM_ORDER* sysparam);
BOOL rail_read_server_minmaxinfo_order(STREAM* s, RAIL_MINMAXINFO_ORDER* minmaxinfo);
BOOL rail_read_server_localmovesize_order(STREAM* s, RAIL_LOCALMOVESIZE_ORDER* localmovesize);
BOOL rail_read_server_get_appid_resp_order(STREAM* s, RAIL_GET_APPID_RESP_ORDER* get_appid_resp);
BOOL rail_read_langbar_info_order(STREAM* s, RAIL_LANGBAR_INFO_ORDER* langbar_info);
void rail_write_handshake_order(STREAM* s, RAIL_HANDSHAKE_ORDER* handshake);
void rail_write_client_status_order(STREAM* s, RAIL_CLIENT_STATUS_ORDER* client_status);
@@ -76,7 +76,7 @@ void rail_write_client_window_move_order(STREAM* s, RAIL_WINDOW_MOVE_ORDER* wind
void rail_write_client_get_appid_req_order(STREAM* s, RAIL_GET_APPID_REQ_ORDER* get_appid_req);
void rail_write_langbar_info_order(STREAM* s, RAIL_LANGBAR_INFO_ORDER* langbar_info);
void rail_order_recv(rdpRailOrder* rail_order, STREAM* s);
BOOL rail_order_recv(rdpRailOrder* rail_order, STREAM* s);
void rail_send_handshake_order(rdpRailOrder* rail_order);
void rail_send_client_status_order(rdpRailOrder* rail_order);

View File

@@ -3,10 +3,6 @@ set(OPTION_DEFAULT OFF)
set(OPTION_CLIENT_DEFAULT ON)
set(OPTION_SERVER_DEFAULT OFF)
if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT})
set(OPTION_DEFAULT ON)
endif()
define_channel_options(NAME "rdpdr" TYPE "static"
DESCRIPTION "Device Redirection Virtual Channel Extension"
SPECIFICATIONS "[MS-RDPEFS] [MS-RDPEPC] [MS-RDPESC] [MS-RDPESP]"

View File

@@ -29,10 +29,10 @@
#include <winpr/crt.h>
#include <freerdp/types.h>
#include <freerdp/addin.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/list.h>
#include <freerdp/utils/svc_plugin.h>
#include <freerdp/utils/load_plugin.h>
#include <freerdp/client/channels.h>
#include "rdpdr_main.h"
@@ -99,17 +99,8 @@ BOOL devman_load_device_service(DEVMAN* devman, RDPDR_DEVICE* device)
if (!ServiceName)
return FALSE;
entry = (PDEVICE_SERVICE_ENTRY) freerdp_channels_client_find_static_entry("DeviceServiceEntry", ServiceName);
if (!entry)
{
printf("loading device service %s (dynamic)\n", ServiceName);
entry = freerdp_load_plugin(ServiceName, "DeviceServiceEntry");
}
else
{
printf("loading device service %s (static)\n", ServiceName);
}
printf("Loading device service %s (static)\n", ServiceName);
entry = (PDEVICE_SERVICE_ENTRY) freerdp_load_channel_addin_entry(ServiceName, NULL, "DeviceServiceEntry", 0);
if (entry == NULL)
return FALSE;

View File

@@ -28,7 +28,6 @@
#include <winpr/crt.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/svc_plugin.h>

View File

@@ -30,9 +30,7 @@
#include <freerdp/types.h>
#include <freerdp/constants.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/unicode.h>
#include <freerdp/channels/rdpdr.h>
#include <freerdp/utils/svc_plugin.h>
@@ -94,13 +92,13 @@ static void rdpdr_send_client_announce_reply(rdpdrPlugin* rdpdr)
static void rdpdr_send_client_name_request(rdpdrPlugin* rdpdr)
{
STREAM* data_out;
WCHAR* computerNameW;
WCHAR* computerNameW = NULL;
size_t computerNameLenW;
if (!rdpdr->computerName[0])
gethostname(rdpdr->computerName, sizeof(rdpdr->computerName) - 1);
computerNameLenW = freerdp_AsciiToUnicodeAlloc(rdpdr->computerName, &computerNameW, 0) * 2;
computerNameLenW = ConvertToUnicode(CP_UTF8, 0, rdpdr->computerName, -1, &computerNameW, 0) * 2;
data_out = stream_new(16 + computerNameLenW + 2);
@@ -173,8 +171,9 @@ static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL use
* 2. smartcard devices should be always sent
* 3. other devices are sent only after user_loggedon
*/
if (rdpdr->versionMinor == 0x0005 ||
device->type == RDPDR_DTYP_SMARTCARD || user_loggedon)
if ((rdpdr->versionMinor == 0x0005) ||
(device->type == RDPDR_DTYP_SMARTCARD) || user_loggedon)
{
data_len = (device->data == NULL ? 0 : stream_get_length(device->data));
stream_check_size(data_out, 20 + data_len);

View File

@@ -3,10 +3,6 @@ set(OPTION_DEFAULT OFF)
set(OPTION_CLIENT_DEFAULT ON)
set(OPTION_SERVER_DEFAULT ON)
if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT})
set(OPTION_DEFAULT ON)
endif()
define_channel_options(NAME "rdpsnd" TYPE "static"
DESCRIPTION "Audio Output Virtual Channel Extension"
SPECIFICATIONS "[MS-RDPEA]"

View File

@@ -29,6 +29,11 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
MONOLITHIC ${MONOLITHIC_BUILD}
MODULE freerdp
MODULES freerdp-utils)
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
MONOLITHIC ${MONOLITHIC_BUILD}
MODULE winpr
MODULES winpr-utils)
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
@@ -45,3 +50,7 @@ endif()
if(WITH_MACAUDIO)
add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "mac" "")
endif()
if(WITH_WINMM)
add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "winmm" "")
endif()

View File

@@ -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 "")
@@ -32,6 +32,11 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
MODULE freerdp
MODULES freerdp-utils)
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
MONOLITHIC ${MONOLITHIC_BUILD}
MODULE winpr
MODULES winpr-utils)
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${ALSA_LIBRARIES})
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})

View File

@@ -27,17 +27,18 @@
#include <string.h>
#include <winpr/crt.h>
#include <winpr/cmdline.h>
#include <alsa/asoundlib.h>
#include <freerdp/types.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/dsp.h>
#include <freerdp/utils/svc_plugin.h>
#include "rdpsnd_main.h"
typedef struct rdpsnd_alsa_plugin rdpsndAlsaPlugin;
struct rdpsnd_alsa_plugin
{
rdpsndDevicePlugin device;
@@ -416,16 +417,53 @@ static void rdpsnd_alsa_start(rdpsndDevicePlugin* device)
snd_pcm_start(alsa->out_handle);
}
COMMAND_LINE_ARGUMENT_A rdpsnd_alsa_args[] =
{
{ "dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "device" },
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
};
static void rdpsnd_alsa_parse_addin_args(rdpsndDevicePlugin* device, ADDIN_ARGV* args)
{
int status;
DWORD flags;
COMMAND_LINE_ARGUMENT_A* arg;
rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*) device;
flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON;
status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv, rdpsnd_alsa_args, flags, alsa, NULL, NULL);
arg = rdpsnd_alsa_args;
do
{
if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT))
continue;
CommandLineSwitchStart(arg)
CommandLineSwitchCase(arg, "dev")
{
alsa->device_name = _strdup(arg->Value);
}
CommandLineSwitchEnd(arg)
}
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
}
#ifdef STATIC_CHANNELS
#define freerdp_rdpsnd_client_subsystem_entry alsa_freerdp_rdpsnd_client_subsystem_entry
#endif
int freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints)
{
ADDIN_ARGV* args;
rdpsndAlsaPlugin* alsa;
RDP_PLUGIN_DATA* data;
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;
@@ -436,17 +474,11 @@ int freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pE
alsa->device.Close = rdpsnd_alsa_close;
alsa->device.Free = rdpsnd_alsa_free;
data = pEntryPoints->plugin_data;
args = pEntryPoints->args;
rdpsnd_alsa_parse_addin_args((rdpsndDevicePlugin*) alsa, args);
if (data && strcmp((char*) data->data[0], "alsa") == 0)
{
alsa->device_name = _strdup((char*) data->data[1]);
}
if (alsa->device_name == NULL)
{
if (!alsa->device_name)
alsa->device_name = _strdup("default");
}
alsa->out_handle = 0;
alsa->source_rate = 22050;

View File

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

View File

@@ -29,8 +29,9 @@
#include <stdlib.h>
#include <string.h>
#include <winpr/crt.h>
#include <freerdp/types.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/dsp.h>
#include <freerdp/utils/svc_plugin.h>
@@ -203,10 +204,11 @@ static void aq_playback_cb(void* user_data, AudioQueueRef aq_ref, AudioQueueBuff
int freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints)
{
ADDIN_ARGV* args;
rdpsndAudioQPlugin* aqPlugin;
RDP_PLUGIN_DATA* data;
aqPlugin = xnew(rdpsndAudioQPlugin);
aqPlugin = (rdpsndAudioQPlugin*) malloc(sizeof(rdpsndAudioQPlugin));
ZeroMemory(aqPlugin, sizeof(rdpsndAudioQPlugin));
aqPlugin->device.Open = rdpsnd_audio_open;
aqPlugin->device.FormatSupported = rdpsnd_audio_format_supported;
@@ -217,14 +219,11 @@ int freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pE
aqPlugin->device.Close = rdpsnd_audio_close;
aqPlugin->device.Free = rdpsnd_audio_free;
data = pEntryPoints->plugin_data;
args = pEntryPoints->args;
if (data && strcmp((char *)data->data[0], "macaudio") == 0)
if (args->argc > 2)
{
if(strlen((char *)data->data[1]) > 0)
aqPlugin->device_name = strdup((char *)data->data[1]);
else
aqPlugin->device_name = NULL;
/* TODO: parse device name */
}
pEntryPoints->pRegisterRdpsndDevice(pEntryPoints->rdpsnd, (rdpsndDevicePlugin*) aqPlugin);

View File

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

View File

@@ -26,11 +26,11 @@
#include <string.h>
#include <winpr/crt.h>
#include <winpr/cmdline.h>
#include <pulse/pulseaudio.h>
#include <freerdp/types.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/dsp.h>
#include <freerdp/utils/svc_plugin.h>
@@ -523,16 +523,54 @@ static void rdpsnd_pulse_start(rdpsndDevicePlugin* device)
pa_stream_trigger(pulse->stream, NULL, NULL);
}
COMMAND_LINE_ARGUMENT_A rdpsnd_pulse_args[] =
{
{ "dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "device" },
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
};
static void rdpsnd_pulse_parse_addin_args(rdpsndDevicePlugin* device, ADDIN_ARGV* args)
{
int status;
DWORD flags;
COMMAND_LINE_ARGUMENT_A* arg;
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*) device;
flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON;
status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv,
rdpsnd_pulse_args, flags, pulse, NULL, NULL);
arg = rdpsnd_pulse_args;
do
{
if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT))
continue;
CommandLineSwitchStart(arg)
CommandLineSwitchCase(arg, "dev")
{
pulse->device_name = _strdup(arg->Value);
}
CommandLineSwitchEnd(arg)
}
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
}
#ifdef STATIC_CHANNELS
#define freerdp_rdpsnd_client_subsystem_entry pulse_freerdp_rdpsnd_client_subsystem_entry
#endif
int freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints)
{
ADDIN_ARGV* args;
rdpsndPulsePlugin* pulse;
RDP_PLUGIN_DATA* data;
pulse = xnew(rdpsndPulsePlugin);
pulse = (rdpsndPulsePlugin*) malloc(sizeof(rdpsndPulsePlugin));
ZeroMemory(pulse, sizeof(rdpsndPulsePlugin));
pulse->device.Open = rdpsnd_pulse_open;
pulse->device.FormatSupported = rdpsnd_pulse_format_supported;
@@ -543,15 +581,8 @@ int freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pE
pulse->device.Close = rdpsnd_pulse_close;
pulse->device.Free = rdpsnd_pulse_free;
data = pEntryPoints->plugin_data;
if (data && strcmp((char*)data->data[0], "pulse") == 0)
{
if(data->data[1] && strlen((char*)data->data[1]) > 0)
pulse->device_name = _strdup((char*)data->data[1]);
else
pulse->device_name = NULL;
}
args = pEntryPoints->args;
rdpsnd_pulse_parse_addin_args((rdpsndDevicePlugin*) pulse, args);
pulse->dsp_context = freerdp_dsp_context_new();

View File

@@ -31,13 +31,13 @@
#include <string.h>
#include <winpr/crt.h>
#include <winpr/cmdline.h>
#include <freerdp/constants.h>
#include <freerdp/types.h>
#include <freerdp/utils/memory.h>
#include <freerdp/addin.h>
#include <freerdp/constants.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/list.h>
#include <freerdp/utils/load_plugin.h>
#include <freerdp/utils/svc_plugin.h>
#include "rdpsnd_main.h"
@@ -67,6 +67,9 @@ struct rdpsnd_plugin
UINT32 fixed_rate;
int latency;
char* subsystem;
char* device_name;
/* Device plugin */
rdpsndDevicePlugin* device;
};
@@ -190,7 +193,8 @@ static void rdpsnd_process_message_formats(rdpsndPlugin* rdpsnd, STREAM* data_in
return;
}
out_formats = (rdpsndFormat*)xzalloc(wNumberOfFormats * sizeof(rdpsndFormat));
out_formats = (rdpsndFormat*) malloc(wNumberOfFormats * sizeof(rdpsndFormat));
ZeroMemory(out_formats, wNumberOfFormats * sizeof(rdpsndFormat));
n_out_formats = 0;
data_out = stream_new(24);
@@ -315,20 +319,27 @@ static void rdpsnd_process_message_wave_info(rdpsndPlugin* rdpsnd, STREAM* data_
DEBUG_SVC("waveDataSize %d wFormatNo %d", rdpsnd->waveDataSize, wFormatNo);
rdpsnd->close_timestamp = 0;
if (!rdpsnd->is_open)
{
rdpsnd->current_format = wFormatNo;
rdpsnd->is_open = TRUE;
if (rdpsnd->device)
{
IFCALL(rdpsnd->device->Open, rdpsnd->device, &rdpsnd->supported_formats[wFormatNo],
rdpsnd->latency);
}
}
else if (wFormatNo != rdpsnd->current_format)
{
rdpsnd->current_format = wFormatNo;
if (rdpsnd->device)
{
IFCALL(rdpsnd->device->SetFormat, rdpsnd->device, &rdpsnd->supported_formats[wFormatNo],
rdpsnd->latency);
}
}
}
@@ -341,14 +352,19 @@ static void rdpsnd_process_message_wave(rdpsndPlugin* rdpsnd, STREAM* data_in)
struct data_out_item* item;
rdpsnd->expectingWave = 0;
memcpy(stream_get_head(data_in), rdpsnd->waveData, 4);
if (stream_get_size(data_in) != rdpsnd->waveDataSize)
{
DEBUG_WARN("size error");
return;
}
if (rdpsnd->device)
{
IFCALL(rdpsnd->device->Play, rdpsnd->device, stream_get_head(data_in), stream_get_size(data_in));
}
process_ms = get_mstime() - rdpsnd->wave_timestamp;
delay_ms = 250;
@@ -357,7 +373,9 @@ static void rdpsnd_process_message_wave(rdpsndPlugin* rdpsnd, STREAM* data_in)
DEBUG_SVC("data_size %d delay_ms %u process_ms %u",
stream_get_size(data_in), delay_ms, process_ms);
item = xnew(struct data_out_item);
item = (struct data_out_item*) malloc(sizeof(struct data_out_item));
ZeroMemory(item, sizeof(struct data_out_item));
item->data_out = stream_new(8);
stream_write_BYTE(item->data_out, SNDC_WAVECONFIRM);
stream_write_BYTE(item->data_out, 0);
@@ -374,8 +392,12 @@ static void rdpsnd_process_message_wave(rdpsndPlugin* rdpsnd, STREAM* data_in)
static void rdpsnd_process_message_close(rdpsndPlugin* rdpsnd)
{
DEBUG_SVC("server closes.");
if (rdpsnd->device)
{
IFCALL(rdpsnd->device->Start, rdpsnd->device);
}
rdpsnd->close_timestamp = get_mstime() + 2000;
rdpsnd->plugin.interval_ms = 10;
}
@@ -386,8 +408,11 @@ static void rdpsnd_process_message_setvolume(rdpsndPlugin* rdpsnd, STREAM* data_
stream_read_UINT32(data_in, dwVolume);
DEBUG_SVC("dwVolume 0x%X", dwVolume);
if (rdpsnd->device)
{
IFCALL(rdpsnd->device->SetVolume, rdpsnd->device, dwVolume);
}
}
static void rdpsnd_process_receive(rdpSvcPlugin* plugin, STREAM* data_in)
@@ -414,18 +439,23 @@ static void rdpsnd_process_receive(rdpSvcPlugin* plugin, STREAM* data_in)
case SNDC_FORMATS:
rdpsnd_process_message_formats(rdpsnd, data_in);
break;
case SNDC_TRAINING:
rdpsnd_process_message_training(rdpsnd, data_in);
break;
case SNDC_WAVE:
rdpsnd_process_message_wave_info(rdpsnd, data_in, BodySize);
break;
case SNDC_CLOSE:
rdpsnd_process_message_close(rdpsnd);
break;
case SNDC_SETVOLUME:
rdpsnd_process_message_setvolume(rdpsnd, data_in);
break;
default:
DEBUG_WARN("unknown msgType %d", msgType);
break;
@@ -444,32 +474,19 @@ static void rdpsnd_register_device_plugin(rdpsndPlugin* rdpsnd, rdpsndDevicePlug
rdpsnd->device = device;
}
static BOOL rdpsnd_load_device_plugin(rdpsndPlugin* rdpsnd, const char* name, RDP_PLUGIN_DATA* data)
static BOOL rdpsnd_load_device_plugin(rdpsndPlugin* rdpsnd, const char* name, ADDIN_ARGV* args)
{
FREERDP_RDPSND_DEVICE_ENTRY_POINTS entryPoints;
PFREERDP_RDPSND_DEVICE_ENTRY entry;
char* fullname;
FREERDP_RDPSND_DEVICE_ENTRY_POINTS entryPoints;
entry = (PFREERDP_RDPSND_DEVICE_ENTRY) freerdp_load_channel_addin_entry("rdpsnd", (LPSTR) name, NULL, 0);
if (strrchr(name, '.') != NULL)
{
entry = (PFREERDP_RDPSND_DEVICE_ENTRY) freerdp_load_plugin(name, RDPSND_DEVICE_EXPORT_FUNC_NAME);
}
else
{
fullname = xzalloc(strlen(name) + 8);
strcpy(fullname, "rdpsnd-client-");
strcat(fullname, name);
entry = (PFREERDP_RDPSND_DEVICE_ENTRY) freerdp_load_plugin(fullname, RDPSND_DEVICE_EXPORT_FUNC_NAME);
free(fullname);
}
if (entry == NULL)
{
return FALSE;
}
entryPoints.rdpsnd = rdpsnd;
entryPoints.pRegisterRdpsndDevice = rdpsnd_register_device_plugin;
entryPoints.plugin_data = data;
entryPoints.args = args;
if (entry(&entryPoints) != 0)
{
@@ -480,35 +497,91 @@ static BOOL rdpsnd_load_device_plugin(rdpsndPlugin* rdpsnd, const char* name, RD
return TRUE;
}
static void rdpsnd_process_plugin_data(rdpsndPlugin* rdpsnd, RDP_PLUGIN_DATA* data)
void rdpsnd_set_subsystem(rdpsndPlugin* rdpsnd, char* subsystem)
{
if (strcmp((char*)data->data[0], "format") == 0)
if (rdpsnd->subsystem)
free(rdpsnd->subsystem);
rdpsnd->subsystem = _strdup(subsystem);
}
void rdpsnd_set_device_name(rdpsndPlugin* rdpsnd, char* device_name)
{
if (rdpsnd->device_name)
free(rdpsnd->device_name);
rdpsnd->device_name = _strdup(device_name);
}
COMMAND_LINE_ARGUMENT_A rdpsnd_args[] =
{
{ "sys", COMMAND_LINE_VALUE_REQUIRED, "<subsystem>", NULL, NULL, -1, NULL, "subsystem" },
{ "dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "device" },
{ "format", COMMAND_LINE_VALUE_REQUIRED, "<format>", NULL, NULL, -1, NULL, "format" },
{ "rate", COMMAND_LINE_VALUE_REQUIRED, "<rate>", NULL, NULL, -1, NULL, "rate" },
{ "channel", COMMAND_LINE_VALUE_REQUIRED, "<channel>", NULL, NULL, -1, NULL, "channel" },
{ "latency", COMMAND_LINE_VALUE_REQUIRED, "<latency>", NULL, NULL, -1, NULL, "latency" },
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
};
static void rdpsnd_process_addin_args(rdpsndPlugin* rdpsnd, ADDIN_ARGV* args)
{
int status;
DWORD flags;
COMMAND_LINE_ARGUMENT_A* arg;
flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON;
status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv,
rdpsnd_args, flags, rdpsnd, NULL, NULL);
arg = rdpsnd_args;
do
{
rdpsnd->fixed_format = atoi(data->data[1]);
}
else if (strcmp((char*)data->data[0], "rate") == 0)
{
rdpsnd->fixed_rate = atoi(data->data[1]);
}
else if (strcmp((char*)data->data[0], "channel") == 0)
{
rdpsnd->fixed_channel = atoi(data->data[1]);
}
else if (strcmp((char*)data->data[0], "latency") == 0)
{
rdpsnd->latency = atoi(data->data[1]);
}
else
{
rdpsnd_load_device_plugin(rdpsnd, (char*) data->data[0], data);
if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT))
continue;
CommandLineSwitchStart(arg)
CommandLineSwitchCase(arg, "sys")
{
rdpsnd_set_subsystem(rdpsnd, arg->Value);
}
CommandLineSwitchCase(arg, "dev")
{
rdpsnd_set_device_name(rdpsnd, arg->Value);
}
CommandLineSwitchCase(arg, "format")
{
rdpsnd->fixed_format = atoi(arg->Value);
}
CommandLineSwitchCase(arg, "rate")
{
rdpsnd->fixed_rate = atoi(arg->Value);
}
CommandLineSwitchCase(arg, "channel")
{
rdpsnd->fixed_channel = atoi(arg->Value);
}
CommandLineSwitchCase(arg, "latency")
{
rdpsnd->latency = atoi(arg->Value);
}
CommandLineSwitchDefault(arg)
{
}
CommandLineSwitchEnd(arg)
}
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
}
static void rdpsnd_process_connect(rdpSvcPlugin* plugin)
{
ADDIN_ARGV* args;
rdpsndPlugin* rdpsnd = (rdpsndPlugin*) plugin;
RDP_PLUGIN_DATA* data;
RDP_PLUGIN_DATA default_data[2] = { { 0 }, { 0 } };
DEBUG_SVC("connecting");
@@ -517,42 +590,47 @@ static void rdpsnd_process_connect(rdpSvcPlugin* plugin)
rdpsnd->data_out_list = list_new();
rdpsnd->latency = -1;
data = (RDP_PLUGIN_DATA*) plugin->channel_entry_points.pExtendedData;
args = (ADDIN_ARGV*) plugin->channel_entry_points.pExtendedData;
while (data && data->size > 0)
if (args)
rdpsnd_process_addin_args(rdpsnd, args);
if (rdpsnd->subsystem)
{
rdpsnd_process_plugin_data(rdpsnd, data);
data = (RDP_PLUGIN_DATA*) (((BYTE*) data) + data->size);
if (strcmp(rdpsnd->subsystem, "fake") == 0)
return;
rdpsnd_load_device_plugin(rdpsnd, rdpsnd->subsystem, args);
}
if (rdpsnd->device == NULL)
if (!rdpsnd->device)
{
default_data[0].size = sizeof(RDP_PLUGIN_DATA);
default_data[0].data[0] = "pulse";
default_data[0].data[1] = "";
if (!rdpsnd_load_device_plugin(rdpsnd, "pulse", default_data))
{
default_data[0].data[0] = "alsa";
default_data[0].data[1] = "default";
if (!rdpsnd_load_device_plugin(rdpsnd, "alsa", default_data))
{
default_data[0].data[0] = "macaudio";
default_data[0].data[1] = "default";
rdpsnd_load_device_plugin(rdpsnd, "macaudio", default_data);
}
else
{
printf("rdpsnd: successfully loaded alsa plugin\n");
}
}
else
{
printf("rdpsnd: successfully loaded pulseaudio plugin\n");
}
rdpsnd_set_subsystem(rdpsnd, "pulse");
rdpsnd_set_device_name(rdpsnd, "");
rdpsnd_load_device_plugin(rdpsnd, rdpsnd->subsystem, args);
}
if (!rdpsnd->device)
{
rdpsnd_set_subsystem(rdpsnd, "alsa");
rdpsnd_set_device_name(rdpsnd, "default");
rdpsnd_load_device_plugin(rdpsnd, rdpsnd->subsystem, args);
}
if (!rdpsnd->device)
{
rdpsnd_set_subsystem(rdpsnd, "macaudio");
rdpsnd_set_device_name(rdpsnd, "default");
rdpsnd_load_device_plugin(rdpsnd, rdpsnd->subsystem, args);
}
if (!rdpsnd->device)
{
rdpsnd_set_subsystem(rdpsnd, "winmm");
rdpsnd_set_device_name(rdpsnd, "");
rdpsnd_load_device_plugin(rdpsnd, rdpsnd->subsystem, args);
}
if (rdpsnd->device == NULL)
{
DEBUG_WARN("no sound device.");
@@ -579,6 +657,12 @@ static void rdpsnd_process_terminate(rdpSvcPlugin* plugin)
}
list_free(rdpsnd->data_out_list);
if (rdpsnd->subsystem)
free(rdpsnd->subsystem);
if (rdpsnd->device_name)
free(rdpsnd->device_name);
rdpsnd_free_supported_formats(rdpsnd);
free(plugin);

View File

@@ -55,7 +55,7 @@ struct _FREERDP_RDPSND_DEVICE_ENTRY_POINTS
{
rdpsndPlugin* rdpsnd;
PREGISTERRDPSNDDEVICE pRegisterRdpsndDevice;
RDP_PLUGIN_DATA* plugin_data;
ADDIN_ARGV* args;
};
typedef struct _FREERDP_RDPSND_DEVICE_ENTRY_POINTS FREERDP_RDPSND_DEVICE_ENTRY_POINTS;
typedef FREERDP_RDPSND_DEVICE_ENTRY_POINTS* PFREERDP_RDPSND_DEVICE_ENTRY_POINTS;

View File

@@ -0,0 +1,45 @@
# FreeRDP: A Remote Desktop Protocol Implementation
# FreeRDP cmake build script
#
# Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
define_channel_client_subsystem("rdpsnd" "winmm" "")
set(${MODULE_PREFIX}_SRCS
rdpsnd_winmm.c)
include_directories(..)
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "")
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
MONOLITHIC ${MONOLITHIC_BUILD}
MODULE freerdp
MODULES freerdp-utils)
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
MONOLITHIC ${MONOLITHIC_BUILD}
MODULE winpr
MODULES winpr-utils)
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} winmm.lib)
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
if(NOT STATIC_CHANNELS)
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH})
endif()

View File

@@ -0,0 +1,290 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Audio Output Virtual Channel
*
* Copyright 2009-2012 Jay Sorg
* Copyright 2010-2012 Vic Lee
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Windows.h>
#include <MMSystem.h>
#include <winpr/crt.h>
#include <winpr/cmdline.h>
#include <freerdp/types.h>
#include <freerdp/utils/dsp.h>
#include <freerdp/utils/svc_plugin.h>
#include "rdpsnd_main.h"
typedef struct rdpsnd_winmm_datablock rdpsndWinmmDatablock;
struct rdpsnd_winmm_datablock
{
WAVEHDR header;
rdpsndWinmmDatablock* next;
};
typedef struct rdpsnd_winmm_plugin rdpsndWinmmPlugin;
struct rdpsnd_winmm_plugin
{
rdpsndDevicePlugin device;
HWAVEOUT out_handle;
WAVEFORMATEX format;
int wformat;
int block_size;
int latency;
HANDLE event;
rdpsndWinmmDatablock* datablock_head;
FREERDP_DSP_CONTEXT* dsp_context;
};
static BOOL rdpsnd_winmm_convert_format(const rdpsndFormat* in, WAVEFORMATEX* out)
{
BOOL result = FALSE;
ZeroMemory(out, sizeof(WAVEFORMATEX));
out->wFormatTag = WAVE_FORMAT_PCM;
out->nChannels = in->nChannels;
out->nSamplesPerSec = in->nSamplesPerSec;
switch (in->wFormatTag)
{
case WAVE_FORMAT_PCM:
out->wBitsPerSample = in->wBitsPerSample;
result = TRUE;
break;
case 2: /* MS ADPCM */
case 0x11: /* IMA ADPCM */
out->wBitsPerSample = 16;
result = TRUE;
break;
}
out->nBlockAlign = out->nChannels * out->wBitsPerSample / 8;
out->nAvgBytesPerSec = out->nSamplesPerSec * out->nBlockAlign;
return result;
}
static void rdpsnd_winmm_clear_datablocks(rdpsndWinmmPlugin* winmm, BOOL drain)
{
rdpsndWinmmDatablock* datablock;
while ((datablock = winmm->datablock_head) != NULL)
{
if (!drain && (datablock->header.dwFlags & WHDR_DONE) == 0)
break;
while ((datablock->header.dwFlags & WHDR_DONE) == 0)
WaitForSingleObject(winmm->event, INFINITE);
winmm->datablock_head = datablock->next;
free(datablock->header.lpData);
free(datablock);
}
}
static void rdpsnd_winmm_set_format(rdpsndDevicePlugin* device, rdpsndFormat* format, int latency)
{
rdpsndWinmmPlugin* winmm = (rdpsndWinmmPlugin*)device;
if (format != NULL)
{
rdpsnd_winmm_convert_format(format, &winmm->format);
winmm->wformat = format->wFormatTag;
winmm->block_size = format->nBlockAlign;
}
winmm->latency = latency;
}
static void rdpsnd_winmm_open(rdpsndDevicePlugin* device, rdpsndFormat* format, int latency)
{
MMRESULT result;
rdpsndWinmmPlugin* winmm = (rdpsndWinmmPlugin*) device;
if (winmm->out_handle != NULL)
return;
DEBUG_SVC("opening");
rdpsnd_winmm_set_format(device, format, latency);
freerdp_dsp_context_reset_adpcm(winmm->dsp_context);
result = waveOutOpen(&winmm->out_handle, WAVE_MAPPER, &winmm->format, (DWORD_PTR) winmm->event, 0, CALLBACK_EVENT);
if (result != MMSYSERR_NOERROR)
{
DEBUG_WARN("waveOutOpen failed: %d", result);
}
}
static void rdpsnd_winmm_close(rdpsndDevicePlugin* device)
{
rdpsndWinmmPlugin* winmm = (rdpsndWinmmPlugin*)device;
if (winmm->out_handle != NULL)
{
DEBUG_SVC("close");
rdpsnd_winmm_clear_datablocks(winmm, TRUE);
if (waveOutClose(winmm->out_handle) != MMSYSERR_NOERROR)
{
DEBUG_WARN("waveOutClose error");
}
winmm->out_handle = NULL;
}
}
static void rdpsnd_winmm_free(rdpsndDevicePlugin* device)
{
rdpsndWinmmPlugin* winmm = (rdpsndWinmmPlugin*)device;
rdpsnd_winmm_close(device);
freerdp_dsp_context_free(winmm->dsp_context);
CloseHandle(winmm->event);
free(winmm);
}
static BOOL rdpsnd_winmm_format_supported(rdpsndDevicePlugin* device, rdpsndFormat* format)
{
MMRESULT result;
WAVEFORMATEX out;
if (rdpsnd_winmm_convert_format(format, &out))
{
result = waveOutOpen(NULL, WAVE_MAPPER, &out, 0, 0, WAVE_FORMAT_QUERY);
if (result == MMSYSERR_NOERROR)
return TRUE;
}
return FALSE;
}
static void rdpsnd_winmm_set_volume(rdpsndDevicePlugin* device, UINT32 value)
{
rdpsndWinmmPlugin* winmm = (rdpsndWinmmPlugin*) device;
if (winmm->out_handle == NULL)
return;
waveOutSetVolume(winmm->out_handle, value);
}
static void rdpsnd_winmm_play(rdpsndDevicePlugin* device, BYTE* data, int size)
{
BYTE* src;
MMRESULT result;
rdpsndWinmmDatablock* last;
rdpsndWinmmDatablock* datablock;
rdpsndWinmmPlugin* winmm = (rdpsndWinmmPlugin*) device;
if (winmm->out_handle == NULL)
return;
if (winmm->wformat == 2)
{
winmm->dsp_context->decode_ms_adpcm(winmm->dsp_context,
data, size, winmm->format.nChannels, winmm->block_size);
size = winmm->dsp_context->adpcm_size;
src = winmm->dsp_context->adpcm_buffer;
}
else if (winmm->wformat == 0x11)
{
winmm->dsp_context->decode_ima_adpcm(winmm->dsp_context,
data, size, winmm->format.nChannels, winmm->block_size);
size = winmm->dsp_context->adpcm_size;
src = winmm->dsp_context->adpcm_buffer;
}
else
{
src = data;
}
rdpsnd_winmm_clear_datablocks(winmm, FALSE);
for (last = winmm->datablock_head; last && last->next; last = last->next)
{
}
datablock = (rdpsndWinmmDatablock*) malloc(sizeof(rdpsndWinmmDatablock));
ZeroMemory(datablock, sizeof(rdpsndWinmmDatablock));
if (last)
last->next = datablock;
else
winmm->datablock_head = datablock;
datablock->header.dwBufferLength = size;
datablock->header.lpData = (LPSTR) malloc(size);
CopyMemory(datablock->header.lpData, src, size);
result = waveOutPrepareHeader(winmm->out_handle, &datablock->header, sizeof(datablock->header));
if (result != MMSYSERR_NOERROR)
{
DEBUG_WARN("waveOutPrepareHeader: %d", result);
return;
}
ResetEvent(winmm->event);
waveOutWrite(winmm->out_handle, &datablock->header, sizeof(datablock->header));
}
static void rdpsnd_winmm_start(rdpsndDevicePlugin* device)
{
rdpsndWinmmPlugin* winmm = (rdpsndWinmmPlugin*) device;
rdpsnd_winmm_clear_datablocks(winmm, FALSE);
}
static void rdpsnd_winmm_parse_addin_args(rdpsndDevicePlugin* device, ADDIN_ARGV* args)
{
}
#ifdef STATIC_CHANNELS
#define freerdp_rdpsnd_client_subsystem_entry winmm_freerdp_rdpsnd_client_subsystem_entry
#endif
int freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints)
{
ADDIN_ARGV* args;
rdpsndWinmmPlugin* winmm;
winmm = (rdpsndWinmmPlugin*) malloc(sizeof(rdpsndWinmmPlugin));
ZeroMemory(winmm, sizeof(rdpsndWinmmPlugin));
winmm->device.Open = rdpsnd_winmm_open;
winmm->device.FormatSupported = rdpsnd_winmm_format_supported;
winmm->device.SetFormat = rdpsnd_winmm_set_format;
winmm->device.SetVolume = rdpsnd_winmm_set_volume;
winmm->device.Play = rdpsnd_winmm_play;
winmm->device.Start = rdpsnd_winmm_start;
winmm->device.Close = rdpsnd_winmm_close;
winmm->device.Free = rdpsnd_winmm_free;
args = pEntryPoints->args;
rdpsnd_winmm_parse_addin_args((rdpsndDevicePlugin*) winmm, args);
winmm->dsp_context = freerdp_dsp_context_new();
winmm->event = CreateEvent(NULL, TRUE, FALSE, NULL);
pEntryPoints->pRegisterRdpsndDevice(pEntryPoints->rdpsnd, (rdpsndDevicePlugin*) winmm);
return 0;
}

View File

@@ -27,11 +27,9 @@
#include <winpr/crt.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/dsp.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/thread.h>
#include <freerdp/utils/wait_obj.h>
#include <freerdp/channels/wtsvc.h>
#include <freerdp/server/rdpsnd.h>
@@ -109,6 +107,8 @@ static BOOL rdpsnd_server_send_formats(rdpsnd_server* rdpsnd, STREAM* s)
}
RDPSND_PDU_FINISH(s);
return TRUE;
}
static BOOL rdpsnd_server_recv_formats(rdpsnd_server* rdpsnd, STREAM* s)
@@ -172,9 +172,10 @@ static void* rdpsnd_server_thread_func(void* arg)
if (WTSVirtualChannelQuery(rdpsnd->rdpsnd_channel, WTSVirtualFileHandle, &buffer, &bytes_returned) == TRUE)
{
fd = *((void**)buffer);
fd = *((void**) buffer);
WTSFreeMemory(buffer);
thread->signals[thread->num_signals++] = wait_obj_new_with_fd(fd);
thread->signals[thread->num_signals++] = CreateWaitObjectEvent(NULL, TRUE, FALSE, fd);
}
s = stream_new(4096);
@@ -451,7 +452,9 @@ rdpsnd_server_context* rdpsnd_server_context_new(WTSVirtualChannelManager* vcm)
{
rdpsnd_server* rdpsnd;
rdpsnd = xnew(rdpsnd_server);
rdpsnd = (rdpsnd_server*) malloc(sizeof(rdpsnd_server));
ZeroMemory(rdpsnd, sizeof(rdpsnd_server));
rdpsnd->context.vcm = vcm;
rdpsnd->context.selected_client_format = -1;
rdpsnd->context.Initialize = rdpsnd_server_initialize;

View File

@@ -8,10 +8,6 @@ if(WITH_SAMPLE)
set(OPTION_SERVER_DEFAULT OFF)
endif()
if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT})
set(OPTION_DEFAULT ON)
endif()
define_channel_options(NAME "sample" TYPE "static"
DESCRIPTION "Sample Virtual Channel Extension"
SPECIFICATIONS ""

View File

@@ -34,10 +34,8 @@
#include <freerdp/types.h>
#include <freerdp/constants.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/list.h>
#include <freerdp/utils/load_plugin.h>
#include <freerdp/utils/svc_plugin.h>
#include "sample_main.h"

View File

@@ -13,10 +13,6 @@ if(ANDROID)
set(OPTION_SERVER_DEFAULT OFF)
endif()
if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT})
set(OPTION_DEFAULT ON)
endif()
define_channel_options(NAME "serial" TYPE "device"
DESCRIPTION "Serial Port Virtual Channel Extension"
SPECIFICATIONS "[MS-RDPESP]"

View File

@@ -43,11 +43,11 @@
#include "serial_tty.h"
#include "serial_constants.h"
#include <winpr/crt.h>
#include <freerdp/freerdp.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/thread.h>
#include <freerdp/utils/unicode.h>
#include <freerdp/utils/wait_obj.h>
#include <freerdp/channels/rdpdr.h>
typedef struct _SERIAL_DEVICE SERIAL_DEVICE;
@@ -62,7 +62,7 @@ struct _SERIAL_DEVICE
LIST* irp_list;
LIST* pending_irps;
freerdp_thread* thread;
struct wait_obj* in_event;
HANDLE in_event;
fd_set read_fds;
fd_set write_fds;
@@ -80,6 +80,7 @@ static BOOL serial_check_fds(SERIAL_DEVICE* serial);
static void serial_process_irp_create(SERIAL_DEVICE* serial, IRP* irp)
{
char* path;
int status;
SERIAL_TTY* tty;
UINT32 PathLength;
UINT32 FileId;
@@ -88,7 +89,11 @@ static void serial_process_irp_create(SERIAL_DEVICE* serial, IRP* irp)
/* SharedAccess(4) CreateDisposition(4), CreateOptions(4) */
stream_read_UINT32(irp->input, PathLength);
freerdp_UnicodeToAsciiAlloc((WCHAR*) stream_get_tail(irp->input), &path, PathLength / 2);
status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(irp->input),
PathLength / 2, &path, 0, NULL, NULL);
if (status < 1)
path = (char*) calloc(1, 1);
FileId = irp->devman->id_sequence++;
@@ -351,10 +356,10 @@ static void* serial_thread_func(void* arg)
freerdp_thread_reset(serial->thread);
serial_process_irp_list(serial);
if (wait_obj_is_set(serial->in_event))
if (WaitForSingleObject(serial->in_event, 0) == WAIT_OBJECT_0)
{
if (serial_check_fds(serial))
wait_obj_clear(serial->in_event);
ResetEvent(serial->in_event);
}
}
@@ -442,7 +447,7 @@ static void serial_abort_single_io(SERIAL_DEVICE* serial, UINT32 file_id, UINT32
stream_write_UINT32(irp->output, 0);
irp->Complete(irp);
wait_obj_set(serial->in_event);
SetEvent(serial->in_event);
break;
}
@@ -480,7 +485,7 @@ static void serial_check_for_events(SERIAL_DEVICE* serial)
irp = (IRP*) list_next(serial->pending_irps, irp);
list_remove(serial->pending_irps, prev);
wait_obj_set(serial->in_event);
SetEvent(serial->in_event);
}
}
@@ -556,7 +561,7 @@ static void serial_handle_async_irp(SERIAL_DEVICE* serial, IRP* irp)
irp->IoStatus = STATUS_PENDING;
list_enqueue(serial->pending_irps, irp);
wait_obj_set(serial->in_event);
SetEvent(serial->in_event);
}
static void __serial_check_fds(SERIAL_DEVICE* serial)
@@ -616,7 +621,7 @@ static void __serial_check_fds(SERIAL_DEVICE* serial)
if (prev->IoStatus == STATUS_SUCCESS)
{
list_remove(serial->pending_irps, prev);
wait_obj_set(serial->in_event);
SetEvent(serial->in_event);
}
}
}
@@ -708,7 +713,8 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
if (name[0] && path[0])
{
serial = xnew(SERIAL_DEVICE);
serial = (SERIAL_DEVICE*) malloc(sizeof(SERIAL_DEVICE));
ZeroMemory(serial, sizeof(SERIAL_DEVICE));
serial->device.type = RDPDR_DTYP_SERIAL;
serial->device.name = name;
@@ -725,9 +731,9 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
serial->irp_list = list_new();
serial->pending_irps = list_new();
serial->thread = freerdp_thread_new();
serial->in_event = wait_obj_new();
serial->in_event = CreateEvent(NULL, TRUE, FALSE, NULL);
pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*)serial);
pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) serial);
freerdp_thread_start(serial->thread, serial_thread_func, serial);
}

View File

@@ -26,13 +26,13 @@
#include <stdlib.h>
#include <string.h>
#include <freerdp/utils/memory.h>
#include <winpr/crt.h>
#include <winpr/print.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/unicode.h>
#include <freerdp/utils/list.h>
#include <freerdp/utils/thread.h>
#include <freerdp/utils/svc_plugin.h>
#include <freerdp/utils/hexdump.h>
#include <freerdp/channels/rdpdr.h>
#ifndef _WIN32
@@ -467,31 +467,40 @@ SERIAL_TTY* serial_tty_new(const char* path, UINT32 id)
{
SERIAL_TTY* tty;
tty = xnew(SERIAL_TTY);
tty = (SERIAL_TTY*) malloc(sizeof(SERIAL_TTY));
ZeroMemory(tty, sizeof(SERIAL_TTY));
tty->id = id;
tty->fd = open(path, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (tty->fd < 0)
{
perror("open");
DEBUG_WARN("failed to open device %s", path);
serial_tty_free(tty) ;
serial_tty_free(tty);
return NULL;
}
else
{
DEBUG_SVC("tty fd %d successfully opened", tty->fd);
}
tty->ptermios = (struct termios*) malloc(sizeof(struct termios));
ZeroMemory(tty->ptermios, sizeof(struct termios));
tty->ptermios = (struct termios*) xzalloc(sizeof(struct termios));
if (tty->ptermios == NULL)
{
serial_tty_free(tty) ;
serial_tty_free(tty);
return NULL ;
}
tty->pold_termios = (struct termios*) xzalloc(sizeof(struct termios));
tty->pold_termios = (struct termios*) malloc(sizeof(struct termios));
ZeroMemory(tty->pold_termios, sizeof(struct termios));
if (tty->pold_termios == NULL)
{
serial_tty_free(tty) ;
return NULL ;
serial_tty_free(tty);
return NULL;
}
tcgetattr(tty->fd, tty->pold_termios);
@@ -499,7 +508,7 @@ SERIAL_TTY* serial_tty_new(const char* path, UINT32 id)
{
DEBUG_WARN("%s access denied", path);
fflush(stdout);
serial_tty_free(tty) ;
serial_tty_free(tty);
return NULL;
}
@@ -976,6 +985,7 @@ static UINT32 tty_write_data(SERIAL_TTY* tty, BYTE* data, int len)
DEBUG_SVC("in");
r = write(tty->fd, data, len);
if (r < 0)
return tty_get_error_status();

View File

@@ -30,7 +30,7 @@ endforeach()
add_library(${MODULE_NAME} STATIC ${${MODULE_PREFIX}_SRCS})
set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib")
set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION} SOVERSION ${FREERDP_API_VERSION} PREFIX "lib")
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
MONOLITHIC ${MONOLITHIC_BUILD}

View File

@@ -27,9 +27,9 @@
#include <string.h>
#include <freerdp/constants.h>
#include <freerdp/utils/memory.h>
#include <freerdp/server/channels.h>
#include <winpr/crt.h>
#include <winpr/synch.h>
#include "channels.h"
@@ -99,7 +99,9 @@ static void wts_queue_receive_data(rdpPeerChannel* channel, const BYTE* buffer,
{
wts_data_item* item;
item = xnew(wts_data_item);
item = (wts_data_item*) malloc(sizeof(wts_data_item));
ZeroMemory(item, sizeof(wts_data_item));
item->length = length;
item->buffer = malloc(length);
memcpy(item->buffer, buffer, length);
@@ -108,7 +110,7 @@ static void wts_queue_receive_data(rdpPeerChannel* channel, const BYTE* buffer,
list_enqueue(channel->receive_queue, item);
ReleaseMutex(channel->mutex);
wait_obj_set(channel->receive_event);
SetEvent(channel->receive_event);
}
static void wts_queue_send_item(rdpPeerChannel* channel, wts_data_item* item)
@@ -123,7 +125,7 @@ static void wts_queue_send_item(rdpPeerChannel* channel, wts_data_item* item)
list_enqueue(vcm->send_queue, item);
ReleaseMutex(vcm->mutex);
wait_obj_set(vcm->send_event);
SetEvent(vcm->send_event);
}
static int wts_read_variable_uint(STREAM* s, int cbLen, UINT32 *val)
@@ -174,15 +176,16 @@ static void wts_read_drdynvc_create_response(rdpPeerChannel* channel, STREAM* s,
if ((INT32) CreationStatus < 0)
{
DEBUG_DVC("ChannelId %d creation failed (%d)", channel->ChannelId, (INT32)CreationStatus);
DEBUG_DVC("ChannelId %d creation failed (%d)", channel->channel_id, (INT32) CreationStatus);
channel->dvc_open_state = DVC_OPEN_STATE_FAILED;
}
else
{
DEBUG_DVC("ChannelId %d creation succeeded", channel->ChannelId);
DEBUG_DVC("ChannelId %d creation succeeded", channel->channel_id);
channel->dvc_open_state = DVC_OPEN_STATE_SUCCEEDED;
}
wait_obj_set(channel->receive_event);
SetEvent(channel->receive_event);
}
static void wts_read_drdynvc_data_first(rdpPeerChannel* channel, STREAM* s, int cbLen, UINT32 length)
@@ -231,7 +234,7 @@ static void wts_read_drdynvc_data(rdpPeerChannel* channel, STREAM* s, UINT32 len
static void wts_read_drdynvc_close_response(rdpPeerChannel* channel)
{
DEBUG_DVC("ChannelId %d close response", channel->ChannelId);
DEBUG_DVC("ChannelId %d close response", channel->channel_id);
channel->dvc_open_state = DVC_OPEN_STATE_CLOSED;
}
@@ -411,12 +414,14 @@ WTSVirtualChannelManager* WTSCreateVirtualChannelManager(freerdp_peer* client)
{
WTSVirtualChannelManager* vcm;
vcm = xnew(WTSVirtualChannelManager);
vcm = (WTSVirtualChannelManager*) malloc(sizeof(WTSVirtualChannelManager));
if (vcm != NULL)
{
ZeroMemory(vcm, sizeof(WTSVirtualChannelManager));
vcm->client = client;
vcm->send_event = wait_obj_new();
vcm->send_event = CreateEvent(NULL, TRUE, FALSE, NULL);
vcm->send_queue = list_new();
vcm->mutex = CreateMutex(NULL, FALSE, NULL);
vcm->dvc_channel_id_seq = 1;
@@ -448,7 +453,7 @@ void WTSDestroyVirtualChannelManager(WTSVirtualChannelManager* vcm)
vcm->drdynvc_channel = NULL;
}
wait_obj_free(vcm->send_event);
CloseHandle(vcm->send_event);
while ((item = (wts_data_item*) list_dequeue(vcm->send_queue)) != NULL)
{
@@ -464,11 +469,25 @@ void WTSDestroyVirtualChannelManager(WTSVirtualChannelManager* vcm)
void WTSVirtualChannelManagerGetFileDescriptor(WTSVirtualChannelManager* vcm,
void** fds, int* fds_count)
{
wait_obj_get_fds(vcm->send_event, fds, fds_count);
void* fd;
fd = GetEventWaitObject(vcm->send_event);
if (fd)
{
fds[*fds_count] = fd;
(*fds_count)++;
}
if (vcm->drdynvc_channel)
{
wait_obj_get_fds(vcm->drdynvc_channel->receive_event, fds, fds_count);
fd = GetEventWaitObject(vcm->drdynvc_channel->receive_event);
if (fd)
{
fds[*fds_count] = fd;
(*fds_count)++;
}
}
}
@@ -494,7 +513,7 @@ BOOL WTSVirtualChannelManagerCheckFileDescriptor(WTSVirtualChannelManager* vcm)
}
}
wait_obj_clear(vcm->send_event);
ResetEvent(vcm->send_event);
WaitForSingleObject(vcm->mutex, INFINITE);
@@ -535,12 +554,14 @@ void* WTSVirtualChannelOpenEx(
return NULL;
}
channel = xnew(rdpPeerChannel);
channel = (rdpPeerChannel*) malloc(sizeof(rdpPeerChannel));
ZeroMemory(channel, sizeof(rdpPeerChannel));
channel->vcm = vcm;
channel->client = client;
channel->channel_type = RDP_PEER_CHANNEL_TYPE_DVC;
channel->receive_data = stream_new(client->settings->VirtualChannelChunkSize);
channel->receive_event = wait_obj_new();
channel->receive_event = CreateEvent(NULL, TRUE, FALSE, NULL);
channel->receive_queue = list_new();
channel->mutex = CreateMutex(NULL, FALSE, NULL);
@@ -554,7 +575,7 @@ void* WTSVirtualChannelOpenEx(
WTSVirtualChannelWrite(vcm->drdynvc_channel, stream_get_head(s), stream_get_length(s), NULL);
stream_free(s);
DEBUG_DVC("ChannelId %d.%s (total %d)", channel->ChannelId, pVirtualName, list_size(vcm->dvc_channel_list));
DEBUG_DVC("ChannelId %d.%s (total %d)", channel->channel_id, pVirtualName, list_size(vcm->dvc_channel_list));
}
else
{
@@ -579,14 +600,16 @@ void* WTSVirtualChannelOpenEx(
if (channel == NULL)
{
channel = xnew(rdpPeerChannel);
channel = (rdpPeerChannel*) malloc(sizeof(rdpPeerChannel));
ZeroMemory(channel, sizeof(rdpPeerChannel));
channel->vcm = vcm;
channel->client = client;
channel->channel_id = client->settings->ChannelDefArray[i].ChannelId;
channel->index = i;
channel->channel_type = RDP_PEER_CHANNEL_TYPE_SVC;
channel->receive_data = stream_new(client->settings->VirtualChannelChunkSize);
channel->receive_event = wait_obj_new();
channel->receive_event = CreateEvent(NULL, TRUE, FALSE, NULL);
channel->receive_queue = list_new();
channel->mutex = CreateMutex(NULL, FALSE, NULL);
@@ -603,6 +626,7 @@ BOOL WTSVirtualChannelQuery(
/* __out */ void** ppBuffer,
/* __out */ UINT32* pBytesReturned)
{
void* pfd;
BOOL bval;
void* fds[10];
int fds_count = 0;
@@ -612,7 +636,15 @@ BOOL WTSVirtualChannelQuery(
switch (WtsVirtualClass)
{
case WTSVirtualFileHandle:
wait_obj_get_fds(channel->receive_event, fds, &fds_count);
pfd = GetEventWaitObject(channel->receive_event);
if (pfd)
{
fds[fds_count] = pfd;
(fds_count)++;
}
*ppBuffer = malloc(sizeof(void*));
memcpy(*ppBuffer, &fds[0], sizeof(void*));
*pBytesReturned = sizeof(void*);
@@ -674,7 +706,7 @@ BOOL WTSVirtualChannelRead(
if (item == NULL)
{
wait_obj_clear(channel->receive_event);
ResetEvent(channel->receive_event);
*pBytesRead = 0;
return TRUE;
}
@@ -689,7 +721,7 @@ BOOL WTSVirtualChannelRead(
list_dequeue(channel->receive_queue);
if (list_size(channel->receive_queue) == 0)
wait_obj_clear(channel->receive_event);
ResetEvent(channel->receive_event);
ReleaseMutex(channel->mutex);
@@ -718,7 +750,9 @@ BOOL WTSVirtualChannelWrite(
if (channel->channel_type == RDP_PEER_CHANNEL_TYPE_SVC)
{
item = xnew(wts_data_item);
item = (wts_data_item*) malloc(sizeof(wts_data_item));
ZeroMemory(item, sizeof(wts_data_item));
item->buffer = malloc(Length);
item->length = Length;
memcpy(item->buffer, Buffer, Length);
@@ -737,7 +771,9 @@ BOOL WTSVirtualChannelWrite(
while (Length > 0)
{
item = xnew(wts_data_item);
item = (wts_data_item*) malloc(sizeof(wts_data_item));
ZeroMemory(item, sizeof(wts_data_item));
item->buffer = malloc(channel->client->settings->VirtualChannelChunkSize);
stream_attach(s, item->buffer, channel->client->settings->VirtualChannelChunkSize);
@@ -813,7 +849,7 @@ BOOL WTSVirtualChannelClose(
stream_free(channel->receive_data);
if (channel->receive_event)
wait_obj_free(channel->receive_event);
CloseHandle(channel->receive_event);
if (channel->receive_queue)
{

View File

@@ -25,7 +25,6 @@
#include <freerdp/utils/stream.h>
#include <freerdp/utils/list.h>
#include <freerdp/utils/debug.h>
#include <freerdp/utils/wait_obj.h>
#include <freerdp/channels/wtsvc.h>
#include <winpr/synch.h>
@@ -58,6 +57,7 @@ enum
};
typedef struct rdp_peer_channel rdpPeerChannel;
struct rdp_peer_channel
{
WTSVirtualChannelManager* vcm;
@@ -67,7 +67,7 @@ struct rdp_peer_channel
UINT16 index;
STREAM* receive_data;
struct wait_obj* receive_event;
HANDLE receive_event;
LIST* receive_queue;
HANDLE mutex;
@@ -78,7 +78,7 @@ struct rdp_peer_channel
struct WTSVirtualChannelManager
{
freerdp_peer* client;
struct wait_obj* send_event;
HANDLE send_event;
LIST* send_queue;
HANDLE mutex;

View File

@@ -8,10 +8,6 @@ if(WITH_PCSC)
set(OPTION_SERVER_DEFAULT OFF)
endif()
if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT})
set(OPTION_DEFAULT ON)
endif()
define_channel_options(NAME "smartcard" TYPE "device"
DESCRIPTION "Smart Card Virtual Channel Extension"
SPECIFICATIONS "[MS-RDPESC]"

View File

@@ -18,8 +18,9 @@
define_channel_client("smartcard")
set(${MODULE_PREFIX}_SRCS
scard_main.c
scard_operations.c)
smartcard_main.c
smartcard_main.h
smartcard_operations.c)
include_directories(${PCSC_INCLUDE_DIR})
@@ -46,3 +47,4 @@ if(NOT STATIC_CHANNELS)
endif()
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")

View File

@@ -27,47 +27,49 @@
#include <stdlib.h>
#include <string.h>
#include <winpr/crt.h>
#include <freerdp/utils/list.h>
#include <freerdp/utils/thread.h>
#include <freerdp/utils/svc_plugin.h>
#include <freerdp/utils/debug.h>
#include <freerdp/utils/svc_plugin.h>
#include <freerdp/channels/rdpdr.h>
#include "scard_main.h"
#include "smartcard_main.h"
static void scard_free(DEVICE* dev)
static void smartcard_free(DEVICE* dev)
{
IRP* irp;
COMPLETIONIDINFO* CompletionIdInfo;
SCARD_DEVICE* scard = (SCARD_DEVICE*) dev;
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) dev;
freerdp_thread_stop(scard->thread);
freerdp_thread_free(scard->thread);
SetEvent(smartcard->stopEvent);
CloseHandle(smartcard->thread);
CloseHandle(smartcard->irpEvent);
while ((irp = (IRP*) InterlockedPopEntrySList(scard->pIrpList)) != NULL)
while ((irp = (IRP*) InterlockedPopEntrySList(smartcard->pIrpList)) != NULL)
irp->Discard(irp);
_aligned_free(scard->pIrpList);
_aligned_free(smartcard->pIrpList);
/* Begin TS Client defect workaround. */
while ((CompletionIdInfo = (COMPLETIONIDINFO*) list_dequeue(scard->CompletionIds)) != NULL)
while ((CompletionIdInfo = (COMPLETIONIDINFO*) list_dequeue(smartcard->CompletionIds)) != NULL)
free(CompletionIdInfo);
list_free(scard->CompletionIds);
list_free(smartcard->CompletionIds);
/* End TS Client defect workaround. */
free(dev);
return;
}
static void scard_process_irp(SCARD_DEVICE* scard, IRP* irp)
static void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
{
switch (irp->MajorFunction)
{
case IRP_MJ_DEVICE_CONTROL:
scard_device_control(scard, irp);
smartcard_device_control(smartcard, irp);
break;
default:
@@ -79,77 +81,83 @@ static void scard_process_irp(SCARD_DEVICE* scard, IRP* irp)
}
}
static void scard_process_irp_list(SCARD_DEVICE* scard)
static void smartcard_process_irp_list(SMARTCARD_DEVICE* smartcard)
{
IRP* irp;
while (!freerdp_thread_is_stopped(scard->thread))
while (1)
{
irp = (IRP*) InterlockedPopEntrySList(scard->pIrpList);
if (WaitForSingleObject(smartcard->stopEvent, 0) == WAIT_OBJECT_0)
break;
irp = (IRP*) InterlockedPopEntrySList(smartcard->pIrpList);
if (irp == NULL)
break;
scard_process_irp(scard, irp);
smartcard_process_irp(smartcard, irp);
}
}
struct scard_irp_thread_args
struct _SMARTCARD_IRP_WORKER
{
SCARD_DEVICE* scard;
SMARTCARD_DEVICE* smartcard;
IRP* irp;
freerdp_thread* thread;
HANDLE thread;
};
typedef struct _SMARTCARD_IRP_WORKER SMARTCARD_IRP_WORKER;
static void scard_process_irp_thread_func(struct scard_irp_thread_args* args)
static void smartcard_process_irp_thread_func(SMARTCARD_IRP_WORKER* irpWorker)
{
scard_process_irp(args->scard, args->irp);
smartcard_process_irp(irpWorker->smartcard, irpWorker->irp);
freerdp_thread_free(args->thread);
free(args);
CloseHandle(irpWorker->thread);
free(irpWorker);
}
static void* scard_thread_func(void* arg)
static void* smartcard_thread_func(void* arg)
{
SCARD_DEVICE* scard = (SCARD_DEVICE*) arg;
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) arg;
while (1)
{
freerdp_thread_wait(scard->thread);
WaitForSingleObject(smartcard->irpEvent, INFINITE);
if (freerdp_thread_is_stopped(scard->thread))
if (WaitForSingleObject(smartcard->stopEvent, 0) == WAIT_OBJECT_0)
break;
freerdp_thread_reset(scard->thread);
scard_process_irp_list(scard);
ResetEvent(smartcard->irpEvent);
smartcard_process_irp_list(smartcard);
}
freerdp_thread_quit(scard->thread);
return NULL;
}
/* Begin TS Client defect workaround. */
static COMPLETIONIDINFO* scard_mark_duplicate_id(SCARD_DEVICE* scard, UINT32 CompletionId)
static COMPLETIONIDINFO* smartcard_mark_duplicate_id(SMARTCARD_DEVICE* smartcard, UINT32 CompletionId)
{
LIST_ITEM* item;
COMPLETIONIDINFO* CompletionIdInfo;
/*
* Search from the beginning of the LIST for one outstanding "CompletionID"
* that matches the one passed in. If there is one, mark it as a duplicate
* if it is not already marked.
*/
LIST_ITEM* item;
COMPLETIONIDINFO* CompletionIdInfo;
for (item = scard->CompletionIds->head; item; item = item->next)
for (item = smartcard->CompletionIds->head; item; item = item->next)
{
CompletionIdInfo = (COMPLETIONIDINFO*)item->data;
CompletionIdInfo = (COMPLETIONIDINFO*) item->data;
if (CompletionIdInfo->ID == CompletionId)
{
if (FALSE == CompletionIdInfo->duplicate)
if (!CompletionIdInfo->duplicate)
{
CompletionIdInfo->duplicate = TRUE;
DEBUG_WARN("CompletionID number %u is now marked as a duplicate.", CompletionId);
}
return CompletionIdInfo;
}
}
@@ -157,30 +165,35 @@ static COMPLETIONIDINFO* scard_mark_duplicate_id(SCARD_DEVICE* scard, UINT32 Com
return NULL; /* Either no items in the list or no match. */
}
static BOOL scard_check_for_duplicate_id(SCARD_DEVICE* scard, UINT32 CompletionId)
static BOOL smartcard_check_for_duplicate_id(SMARTCARD_DEVICE* smartcard, UINT32 CompletionId)
{
BOOL duplicate;
LIST_ITEM* item;
COMPLETIONIDINFO* CompletionIdInfo;
/*
* Search from the end of the LIST for one outstanding "CompletionID"
* that matches the one passed in. Remove it from the list and free the
* memory associated with it. Return whether or not it was marked
* as a duplicate.
*/
LIST_ITEM* item;
COMPLETIONIDINFO* CompletionIdInfo;
BOOL duplicate;
for (item = scard->CompletionIds->tail; item; item = item->prev)
for (item = smartcard->CompletionIds->tail; item; item = item->prev)
{
CompletionIdInfo = (COMPLETIONIDINFO*)item->data;
CompletionIdInfo = (COMPLETIONIDINFO*) item->data;
if (CompletionIdInfo->ID == CompletionId)
{
duplicate = CompletionIdInfo->duplicate;
if (TRUE == duplicate)
if (duplicate)
{
DEBUG_WARN("CompletionID number %u was previously marked as a duplicate. The response to the command is removed.", CompletionId);
DEBUG_WARN("CompletionID number %u was previously marked as a duplicate.", CompletionId);
}
list_remove(scard->CompletionIds, CompletionIdInfo);
list_remove(smartcard->CompletionIds, CompletionIdInfo);
free(CompletionIdInfo);
return duplicate;
}
}
@@ -193,16 +206,17 @@ static BOOL scard_check_for_duplicate_id(SCARD_DEVICE* scard, UINT32 Completion
return FALSE;
}
static void scard_irp_complete(IRP* irp)
static void smartcard_irp_complete(IRP* irp)
{
int pos;
BOOL duplicate;
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) irp->device;
/* This function is (mostly) a copy of the statically-declared "irp_complete()"
* function except that this function adds extra operations for the
* smart card's handling of duplicate "CompletionID"s. This function needs
* to be in this file so that "scard_irp_request()" can reference it.
* to be in this file so that "smartcard_irp_request()" can reference it.
*/
int pos;
BOOL duplicate;
SCARD_DEVICE* scard = (SCARD_DEVICE*)irp->device;
DEBUG_SVC("DeviceId %d FileId %d CompletionId %d", irp->device->id, irp->FileId, irp->CompletionId);
@@ -212,18 +226,19 @@ static void scard_irp_complete(IRP* irp)
stream_set_pos(irp->output, pos);
/* Begin TS Client defect workaround. */
WaitForSingleObject(scard->CompletionIdsMutex, INFINITE);
WaitForSingleObject(smartcard->CompletionIdsMutex, INFINITE);
/* Remove from the list the item identified by the CompletionID.
* The function returns whether or not it was a duplicate CompletionID.
*/
duplicate = scard_check_for_duplicate_id(scard, irp->CompletionId);
ReleaseMutex(scard->CompletionIdsMutex);
duplicate = smartcard_check_for_duplicate_id(smartcard, irp->CompletionId);
ReleaseMutex(smartcard->CompletionIdsMutex);
if (FALSE == duplicate)
if (!duplicate)
{
svc_plugin_send(irp->devman->plugin, irp->output);
irp->output = NULL;
}
/* End TS Client defect workaround. */
/* irp_free(irp); The "irp_free()" function is statically-declared
@@ -237,49 +252,48 @@ static void scard_irp_complete(IRP* irp)
}
/* End TS Client defect workaround. */
static void scard_irp_request(DEVICE* device, IRP* irp)
static void smartcard_irp_request(DEVICE* device, IRP* irp)
{
COMPLETIONIDINFO* CompletionIdInfo;
SCARD_DEVICE* scard = (SCARD_DEVICE*) device;
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device;
/* Begin TS Client defect workaround. */
CompletionIdInfo= xnew(COMPLETIONIDINFO);
CompletionIdInfo->ID = irp->CompletionId;/* "duplicate" member is set
* to FALSE by "xnew()"
*/
WaitForSingleObject(scard->CompletionIdsMutex, INFINITE);
scard_mark_duplicate_id(scard, irp->CompletionId);
list_enqueue(scard->CompletionIds, CompletionIdInfo);
ReleaseMutex(scard->CompletionIdsMutex);
irp->Complete = scard_irp_complete; /* Overwrite the previous
* assignment made in
* "irp_new()".
*/
CompletionIdInfo = (COMPLETIONIDINFO*) malloc(sizeof(COMPLETIONIDINFO));
ZeroMemory(CompletionIdInfo, sizeof(COMPLETIONIDINFO));
CompletionIdInfo->ID = irp->CompletionId;
WaitForSingleObject(smartcard->CompletionIdsMutex, INFINITE);
smartcard_mark_duplicate_id(smartcard, irp->CompletionId);
list_enqueue(smartcard->CompletionIds, CompletionIdInfo);
ReleaseMutex(smartcard->CompletionIdsMutex);
/* Overwrite the previous assignment made in irp_new() */
irp->Complete = smartcard_irp_complete;
/* End TS Client defect workaround. */
if (irp->MajorFunction == IRP_MJ_DEVICE_CONTROL &&
scard_async_op(irp))
if ((irp->MajorFunction == IRP_MJ_DEVICE_CONTROL) && smartcard_async_op(irp))
{
/*
* certain potentially long running operations
* get their own thread
* TODO: revise this mechanism.. maybe worker pool
*/
struct scard_irp_thread_args *args = malloc(sizeof(struct scard_irp_thread_args));
/* certain potentially long running operations get their own thread */
SMARTCARD_IRP_WORKER* irpWorker = malloc(sizeof(SMARTCARD_IRP_WORKER));
irpWorker->thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) smartcard_process_irp_thread_func,
irpWorker, CREATE_SUSPENDED, NULL);
args->thread = freerdp_thread_new();
args->scard = scard;
args->irp = irp;
freerdp_thread_start(args->thread, scard_process_irp_thread_func, args);
irpWorker->smartcard = smartcard;
irpWorker->irp = irp;
ResumeThread(irpWorker->thread);
return;
}
InterlockedPushEntrySList(scard->pIrpList, &(irp->ItemEntry));
InterlockedPushEntrySList(smartcard->pIrpList, &(irp->ItemEntry));
freerdp_thread_signal(scard->thread);
SetEvent(smartcard->irpEvent);
}
#ifdef STATIC_CHANNELS
@@ -292,7 +306,7 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
char* path;
int i, length;
RDPDR_SMARTCARD* device;
SCARD_DEVICE* scard;
SMARTCARD_DEVICE* smartcard;
device = (RDPDR_SMARTCARD*) pEntryPoints->device;
name = device->Name;
@@ -302,33 +316,38 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
{
/* TODO: check if server supports sc redirect (version 5.1) */
scard = xnew(SCARD_DEVICE);
smartcard = (SMARTCARD_DEVICE*) malloc(sizeof(SMARTCARD_DEVICE));
ZeroMemory(smartcard, sizeof(SMARTCARD_DEVICE));
scard->device.type = RDPDR_DTYP_SMARTCARD;
scard->device.name = "SCARD";
scard->device.IRPRequest = scard_irp_request;
scard->device.Free = scard_free;
smartcard->device.type = RDPDR_DTYP_SMARTCARD;
smartcard->device.name = "SCARD";
smartcard->device.IRPRequest = smartcard_irp_request;
smartcard->device.Free = smartcard_free;
length = strlen(scard->device.name);
scard->device.data = stream_new(length + 1);
length = strlen(smartcard->device.name);
smartcard->device.data = stream_new(length + 1);
for (i = 0; i <= length; i++)
stream_write_BYTE(scard->device.data, name[i] < 0 ? '_' : name[i]);
stream_write_BYTE(smartcard->device.data, name[i] < 0 ? '_' : name[i]);
scard->path = path;
smartcard->path = path;
scard->pIrpList = (PSLIST_HEADER) _aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT);
InitializeSListHead(scard->pIrpList);
smartcard->pIrpList = (PSLIST_HEADER) _aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT);
InitializeSListHead(smartcard->pIrpList);
scard->thread = freerdp_thread_new();
smartcard->irpEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
smartcard->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
smartcard->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) smartcard_thread_func,
smartcard, CREATE_SUSPENDED, NULL);
scard->CompletionIds = list_new();
scard->CompletionIdsMutex = CreateMutex(NULL, FALSE, NULL);
smartcard->CompletionIds = list_new();
smartcard->CompletionIdsMutex = CreateMutex(NULL, FALSE, NULL);
pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE *)scard);
pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) smartcard);
freerdp_thread_start(scard->thread, scard_thread_func, scard);
ResumeThread(smartcard->thread);
}
return 0;
}

View File

@@ -18,8 +18,8 @@
* limitations under the License.
*/
#ifndef __SCARD_MAIN_H
#define __SCARD_MAIN_H
#ifndef FREERDP_CHANNEL_SMARTCARD_CLIENT_MAIN_H
#define FREERDP_CHANNEL_SMARTCARD_CLIENT_MAIN_H
#include <inttypes.h>
@@ -27,6 +27,7 @@
#include <freerdp/utils/debug.h>
#include <freerdp/channels/rdpdr.h>
#include <winpr/crt.h>
#include <winpr/synch.h>
/*
@@ -81,6 +82,7 @@
* This structure tracks outstanding Terminal Services server "CompletionIDs"
* used by the redirected smart card device.
*/
struct _COMPLETIONIDINFO
{
UINT32 ID; /* CompletionID */
@@ -89,11 +91,9 @@ struct _COMPLETIONIDINFO
* earlier, outstanding, CompletionID.
*/
};
typedef struct _COMPLETIONIDINFO COMPLETIONIDINFO;
struct _SCARD_DEVICE
struct _SMARTCARD_DEVICE
{
DEVICE device;
@@ -102,12 +102,14 @@ struct _SCARD_DEVICE
PSLIST_HEADER pIrpList;
freerdp_thread* thread;
HANDLE thread;
HANDLE irpEvent;
HANDLE stopEvent;
LIST* CompletionIds;
HANDLE CompletionIdsMutex;
};
typedef struct _SCARD_DEVICE SCARD_DEVICE;
typedef struct _SMARTCARD_DEVICE SMARTCARD_DEVICE;
#ifdef WITH_DEBUG_SCARD
#define DEBUG_SCARD(fmt, ...) DEBUG_CLASS(SCARD, fmt, ## __VA_ARGS__)
@@ -115,7 +117,7 @@ typedef struct _SCARD_DEVICE SCARD_DEVICE;
#define DEBUG_SCARD(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
#endif
BOOL scard_async_op(IRP*);
void scard_device_control(SCARD_DEVICE*, IRP*);
BOOL smartcard_async_op(IRP*);
void smartcard_device_control(SMARTCARD_DEVICE*, IRP*);
#endif
#endif /* FREERDP_CHANNEL_SMARTCARD_CLIENT_MAIN_H */

View File

@@ -20,5 +20,3 @@ define_channel("tsmf")
if(WITH_CLIENT_CHANNELS)
add_channel_client(${MODULE_PREFIX} ${CHANNEL_NAME})
endif()

View File

@@ -13,10 +13,6 @@ if(ANDROID)
set(OPTION_SERVER_DEFAULT OFF)
endif()
if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT})
set(OPTION_DEFAULT ON)
endif()
define_channel_options(NAME "tsmf" TYPE "dynamic"
DESCRIPTION "Video Redirection Virtual Channel Extension"
SPECIFICATIONS "[MS-RDPEV]"

View File

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

View File

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

View File

@@ -26,9 +26,12 @@
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <winpr/crt.h>
#include <alsa/asoundlib.h>
#include <freerdp/types.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/dsp.h>
#include "tsmf_audio.h"
@@ -46,13 +49,14 @@ typedef struct _TSMFALSAAudioDevice
UINT32 bytes_per_sample;
FREERDP_DSP_CONTEXT* dsp_context;
} TSMFALSAAudioDevice;
} TSMFAlsaAudioDevice;
static BOOL tsmf_alsa_open_device(TSMFALSAAudioDevice* alsa)
static BOOL tsmf_alsa_open_device(TSMFAlsaAudioDevice* alsa)
{
int error;
error = snd_pcm_open(&alsa->out_handle, alsa->device, SND_PCM_STREAM_PLAYBACK, 0);
if (error < 0)
{
DEBUG_WARN("failed to open device %s", alsa->device);
@@ -65,7 +69,7 @@ static BOOL tsmf_alsa_open_device(TSMFALSAAudioDevice* alsa)
static BOOL tsmf_alsa_open(ITSMFAudioDevice* audio, const char* device)
{
TSMFALSAAudioDevice* alsa = (TSMFALSAAudioDevice*) audio;
TSMFAlsaAudioDevice* alsa = (TSMFAlsaAudioDevice*) audio;
if (!device)
{
@@ -87,7 +91,7 @@ static BOOL tsmf_alsa_set_format(ITSMFAudioDevice* audio,
snd_pcm_uframes_t frames;
snd_pcm_hw_params_t* hw_params;
snd_pcm_sw_params_t* sw_params;
TSMFALSAAudioDevice* alsa = (TSMFALSAAudioDevice*) audio;
TSMFAlsaAudioDevice* alsa = (TSMFAlsaAudioDevice*) audio;
if (!alsa->out_handle)
return FALSE;
@@ -99,11 +103,13 @@ static BOOL tsmf_alsa_set_format(ITSMFAudioDevice* audio,
alsa->bytes_per_sample = bits_per_sample / 8;
error = snd_pcm_hw_params_malloc(&hw_params);
if (error < 0)
{
DEBUG_WARN("snd_pcm_hw_params_malloc failed");
return FALSE;
}
snd_pcm_hw_params_any(alsa->out_handle, hw_params);
snd_pcm_hw_params_set_access(alsa->out_handle, hw_params,
SND_PCM_ACCESS_RW_INTERLEAVED);
@@ -120,11 +126,13 @@ static BOOL tsmf_alsa_set_format(ITSMFAudioDevice* audio,
snd_pcm_hw_params_free(hw_params);
error = snd_pcm_sw_params_malloc(&sw_params);
if (error < 0)
{
DEBUG_WARN("snd_pcm_sw_params_malloc");
return FALSE;
}
snd_pcm_sw_params_current(alsa->out_handle, sw_params);
snd_pcm_sw_params_set_start_threshold(alsa->out_handle, sw_params,
frames / 2);
@@ -136,6 +144,7 @@ static BOOL tsmf_alsa_set_format(ITSMFAudioDevice* audio,
DEBUG_DVC("sample_rate %d channels %d bits_per_sample %d",
sample_rate, channels, bits_per_sample);
DEBUG_DVC("hardware buffer %d frames", (int)frames);
if ((alsa->actual_rate != alsa->source_rate) ||
(alsa->actual_channels != alsa->source_channels))
{
@@ -144,6 +153,7 @@ static BOOL tsmf_alsa_set_format(ITSMFAudioDevice* audio,
alsa->actual_rate, alsa->actual_channels,
alsa->source_rate, alsa->source_channels);
}
return TRUE;
}
@@ -157,7 +167,7 @@ static BOOL tsmf_alsa_play(ITSMFAudioDevice* audio, BYTE* data, UINT32 data_size
BYTE* pindex;
int rbytes_per_frame;
int sbytes_per_frame;
TSMFALSAAudioDevice* alsa = (TSMFALSAAudioDevice*) audio;
TSMFAlsaAudioDevice* alsa = (TSMFAlsaAudioDevice*) audio;
DEBUG_DVC("data_size %d", data_size);
@@ -190,6 +200,7 @@ static BOOL tsmf_alsa_play(ITSMFAudioDevice* audio, BYTE* data, UINT32 data_size
len = end - pindex;
frames = len / rbytes_per_frame;
error = snd_pcm_writei(alsa->out_handle, pindex, frames);
if (error == -EPIPE)
{
snd_pcm_recover(alsa->out_handle, error, 0);
@@ -203,9 +214,12 @@ static BOOL tsmf_alsa_play(ITSMFAudioDevice* audio, BYTE* data, UINT32 data_size
tsmf_alsa_open_device(alsa);
break;
}
DEBUG_DVC("%d frames played.", error);
if (error == 0)
break;
pindex += error * rbytes_per_frame;
}
}
@@ -218,14 +232,15 @@ static UINT64 tsmf_alsa_get_latency(ITSMFAudioDevice* audio)
{
UINT64 latency = 0;
snd_pcm_sframes_t frames = 0;
TSMFALSAAudioDevice* alsa = (TSMFALSAAudioDevice*) audio;
TSMFAlsaAudioDevice* alsa = (TSMFAlsaAudioDevice*) audio;
if (alsa->out_handle && alsa->actual_rate > 0 &&
snd_pcm_delay(alsa->out_handle, &frames) == 0 &&
frames > 0)
{
latency = ((UINT64)frames) * 10000000LL / (UINT64)alsa->actual_rate;
latency = ((UINT64)frames) * 10000000LL / (UINT64) alsa->actual_rate;
}
return latency;
}
@@ -235,7 +250,7 @@ static void tsmf_alsa_flush(ITSMFAudioDevice* audio)
static void tsmf_alsa_free(ITSMFAudioDevice* audio)
{
TSMFALSAAudioDevice* alsa = (TSMFALSAAudioDevice*) audio;
TSMFAlsaAudioDevice* alsa = (TSMFAlsaAudioDevice*) audio;
DEBUG_DVC("");
@@ -244,15 +259,21 @@ static void tsmf_alsa_free(ITSMFAudioDevice* audio)
snd_pcm_drain(alsa->out_handle);
snd_pcm_close(alsa->out_handle);
}
freerdp_dsp_context_free(alsa->dsp_context);
free(alsa);
}
ITSMFAudioDevice* TSMFAudioDeviceEntry(void)
{
TSMFALSAAudioDevice* alsa;
#ifdef STATIC_CHANNELS
#define freerdp_tsmf_client_audio_subsystem_entry alsa_freerdp_tsmf_client_audio_subsystem_entry
#endif
alsa = xnew(TSMFALSAAudioDevice);
ITSMFAudioDevice* freerdp_tsmf_client_audio_subsystem_entry(void)
{
TSMFAlsaAudioDevice* alsa;
alsa = (TSMFAlsaAudioDevice*) malloc(sizeof(TSMFAlsaAudioDevice));
ZeroMemory(alsa, sizeof(TSMFAlsaAudioDevice));
alsa->iface.Open = tsmf_alsa_open;
alsa->iface.SetFormat = tsmf_alsa_set_format;
@@ -265,4 +286,3 @@ ITSMFAudioDevice* TSMFAudioDeviceEntry(void)
return (ITSMFAudioDevice*) alsa;
}

View File

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

View File

@@ -25,7 +25,8 @@
#include <stdlib.h>
#include <string.h>
#include <freerdp/utils/memory.h>
#include <winpr/crt.h>
#include <freerdp/utils/event.h>
#include <freerdp/client/tsmf.h>
#include <libavcodec/avcodec.h>
@@ -60,6 +61,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 +110,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.");
@@ -142,7 +145,8 @@ static BOOL tsmf_ffmpeg_init_stream(ITSMFDecoder* decoder, const TS_AM_MEDIA_TYP
/* The extradata format that FFmpeg uses is following CodecPrivate in Matroska.
See http://haali.su/mkv/codecs.pdf */
mdecoder->codec_context->extradata_size = media_type->ExtraDataSize + 8;
mdecoder->codec_context->extradata = xzalloc(mdecoder->codec_context->extradata_size);
mdecoder->codec_context->extradata = malloc(mdecoder->codec_context->extradata_size);
ZeroMemory(mdecoder->codec_context->extradata, mdecoder->codec_context->extradata_size);
p = mdecoder->codec_context->extradata;
*p++ = 1; /* Reserved? */
*p++ = media_type->ExtraData[8]; /* Profile */
@@ -163,7 +167,8 @@ static BOOL tsmf_ffmpeg_init_stream(ITSMFDecoder* decoder, const TS_AM_MEDIA_TYP
{
/* Add a padding to avoid invalid memory read in some codec */
mdecoder->codec_context->extradata_size = media_type->ExtraDataSize + 8;
mdecoder->codec_context->extradata = xzalloc(mdecoder->codec_context->extradata_size);
mdecoder->codec_context->extradata = malloc(mdecoder->codec_context->extradata_size);
ZeroMemory(mdecoder->codec_context->extradata, mdecoder->codec_context->extradata_size);
memcpy(mdecoder->codec_context->extradata, media_type->ExtraData, media_type->ExtraDataSize);
memset(mdecoder->codec_context->extradata + media_type->ExtraDataSize, 0, 8);
}
@@ -303,13 +308,14 @@ static BOOL tsmf_ffmpeg_decode_video(ITSMFDecoder* decoder, const BYTE* data, UI
mdecoder->decoded_size = avpicture_get_size(mdecoder->codec_context->pix_fmt,
mdecoder->codec_context->width, mdecoder->codec_context->height);
mdecoder->decoded_data = xzalloc(mdecoder->decoded_size);
mdecoder->decoded_data = malloc(mdecoder->decoded_size);
ZeroMemory(mdecoder->decoded_data, mdecoder->decoded_size);
frame = avcodec_alloc_frame();
avpicture_fill((AVPicture *) frame, mdecoder->decoded_data,
avpicture_fill((AVPicture*) frame, mdecoder->decoded_data,
mdecoder->codec_context->pix_fmt,
mdecoder->codec_context->width, mdecoder->codec_context->height);
av_picture_copy((AVPicture *) frame, (AVPicture *) mdecoder->frame,
av_picture_copy((AVPicture*) frame, (AVPicture*) mdecoder->frame,
mdecoder->codec_context->pix_fmt,
mdecoder->codec_context->width, mdecoder->codec_context->height);
@@ -343,9 +349,10 @@ static BOOL tsmf_ffmpeg_decode_audio(ITSMFDecoder* decoder, const BYTE* data, UI
if (mdecoder->decoded_size_max == 0)
mdecoder->decoded_size_max = AVCODEC_MAX_AUDIO_FRAME_SIZE + 16;
mdecoder->decoded_data = xzalloc(mdecoder->decoded_size_max);
mdecoder->decoded_data = malloc(mdecoder->decoded_size_max);
ZeroMemory(mdecoder->decoded_data, 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 +380,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 +390,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 +403,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 +452,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 +501,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,15 +513,19 @@ 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;
TSMFFFmpegDecoder* decoder;
if (!initialized)
{
@@ -518,7 +533,10 @@ 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;
@@ -529,4 +547,3 @@ TSMFDecoderEntry(void)
return (ITSMFDecoder*) decoder;
}

View File

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

View File

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

View File

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

View File

@@ -26,8 +26,9 @@
#include <string.h>
#include <unistd.h>
#include <winpr/crt.h>
#include <pulse/pulseaudio.h>
#include <freerdp/utils/memory.h>
#include "tsmf_audio.h"
@@ -389,11 +390,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;

View File

@@ -25,43 +25,32 @@
#include <stdlib.h>
#include <string.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/load_plugin.h>
#include "tsmf_audio.h"
static ITSMFAudioDevice* tsmf_load_audio_device_by_name(const char* name, const char* device)
{
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 +65,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);
}

View File

@@ -27,7 +27,7 @@
#include <string.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/hexdump.h>
#include <winpr/print.h>
#include "tsmf_constants.h"
#include "tsmf_types.h"
@@ -425,7 +425,7 @@ BOOL tsmf_codec_parse_media_type(TS_AM_MEDIA_TYPE* mediatype, STREAM* s)
DEBUG_DVC("cbFormat %d", cbFormat);
#ifdef WITH_DEBUG_DVC
freerdp_hexdump(stream_get_tail(s), cbFormat);
winpr_HexDump(stream_get_tail(s), cbFormat);
#endif
switch (mediatype->FormatType)
@@ -526,4 +526,3 @@ BOOL tsmf_codec_check_media_type(STREAM* s)
return ret;
}

View File

@@ -25,8 +25,8 @@
#include <stdlib.h>
#include <string.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/load_plugin.h>
#include <freerdp/addin.h>
#include <freerdp/client/channels.h>
#include "tsmf_types.h"
#include "tsmf_constants.h"
@@ -36,34 +36,26 @@ static ITSMFDecoder* tsmf_load_decoder_by_name(const char* name, TS_AM_MEDIA_TYP
{
ITSMFDecoder* decoder;
TSMF_DECODER_ENTRY entry;
char* fullname;
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;
}
decoder = entry();
if (decoder == NULL)
{
DEBUG_WARN("failed to call export function in %s", name);
return NULL;
}
if (!decoder->SetFormat(decoder, media_type))
{
decoder->Free(decoder);
decoder = NULL;
}
return decoder;
}
@@ -82,4 +74,3 @@ ITSMFDecoder* tsmf_load_decoder(const char* name, TS_AM_MEDIA_TYPE* media_type)
return decoder;
}

View File

@@ -26,7 +26,8 @@
#include <stdlib.h>
#include <string.h>
#include <freerdp/utils/memory.h>
#include <winpr/crt.h>
#include <freerdp/utils/stream.h>
#include "tsmf_types.h"
@@ -65,11 +66,13 @@ int tsmf_ifman_exchange_capability_request(TSMF_IFMAN* ifman)
stream_set_pos(ifman->output, pos);
stream_read_UINT32(ifman->output, numHostCapabilities);
for (i = 0; i < numHostCapabilities; i++)
{
stream_read_UINT32(ifman->output, CapabilityType);
stream_read_UINT32(ifman->output, cbCapabilityLength);
pos = stream_get_pos(ifman->output);
switch (CapabilityType)
{
case 1: /* Protocol version request */
@@ -128,10 +131,11 @@ static TSMF_PRESENTATION* pexisted = 0;
int tsmf_ifman_on_new_presentation(TSMF_IFMAN* ifman)
{
int error = 0;
int status = 0;
TSMF_PRESENTATION* presentation;
DEBUG_DVC("");
if (pexisted)
{
ifman->output_pending = FALSE;
@@ -141,18 +145,21 @@ int tsmf_ifman_on_new_presentation(TSMF_IFMAN* ifman)
presentation = tsmf_presentation_new(stream_get_tail(ifman->input), ifman->channel_callback);
pexisted = presentation;
if (presentation == NULL)
error = 1;
status = 1;
else
tsmf_presentation_set_audio_device(presentation, ifman->audio_name, ifman->audio_device);
ifman->output_pending = TRUE;
return error;
return status;
}
int tsmf_ifman_add_stream(TSMF_IFMAN* ifman)
{
UINT32 StreamId;
int error = 0;
int status = 0;
TSMF_STREAM* stream;
TSMF_PRESENTATION* presentation;
@@ -162,17 +169,22 @@ int tsmf_ifman_add_stream(TSMF_IFMAN* ifman)
stream_seek(ifman->input, 16);
if (presentation == NULL)
error = 1;
{
status = 1;
}
else
{
stream_read_UINT32(ifman->input, StreamId);
stream_seek_UINT32(ifman->input); /* numMediaType */
stream = tsmf_stream_new(presentation, StreamId);
if (stream)
tsmf_stream_set_format(stream, ifman->decoder_name, ifman->input);
}
ifman->output_pending = TRUE;
return error;
return status;
}
int tsmf_ifman_set_topology_request(TSMF_IFMAN* ifman)
@@ -183,12 +195,13 @@ int tsmf_ifman_set_topology_request(TSMF_IFMAN* ifman)
stream_write_UINT32(ifman->output, 1); /* TopologyReady */
stream_write_UINT32(ifman->output, 0); /* Result */
ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB;
return 0;
}
int tsmf_ifman_remove_stream(TSMF_IFMAN* ifman)
{
int error = 0;
int status = 0;
UINT32 StreamId;
TSMF_STREAM* stream;
TSMF_PRESENTATION* presentation;
@@ -199,7 +212,9 @@ int tsmf_ifman_remove_stream(TSMF_IFMAN* ifman)
stream_seek(ifman->input, 16);
if (presentation == NULL)
error = 1;
{
status = 1;
}
else
{
stream_read_UINT32(ifman->input, StreamId);
@@ -207,10 +222,12 @@ int tsmf_ifman_remove_stream(TSMF_IFMAN* ifman)
if (stream)
tsmf_stream_free(stream);
else
error = 1;
status = 1;
}
ifman->output_pending = TRUE;
return error;
return status;
}
int tsmf_ifman_shutdown_presentation(TSMF_IFMAN* ifman)
@@ -220,6 +237,7 @@ int tsmf_ifman_shutdown_presentation(TSMF_IFMAN* ifman)
DEBUG_DVC("");
presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input));
if (presentation)
tsmf_presentation_free(presentation);
@@ -228,6 +246,7 @@ int tsmf_ifman_shutdown_presentation(TSMF_IFMAN* ifman)
stream_check_size(ifman->output, 4);
stream_write_UINT32(ifman->output, 0); /* Result */
ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB;
return 0;
}
@@ -335,7 +354,9 @@ int tsmf_ifman_update_geometry_info(TSMF_IFMAN* ifman)
{
if (num_rects > 0)
{
rects = (RDP_RECT*) xzalloc(sizeof(RDP_RECT) * num_rects);
rects = (RDP_RECT*) malloc(sizeof(RDP_RECT) * num_rects);
ZeroMemory(rects, sizeof(RDP_RECT) * num_rects);
for (i = 0; i < num_rects; i++)
{
stream_read_UINT16(ifman->input, rects[i].y); /* Top */
@@ -402,35 +423,41 @@ int tsmf_ifman_on_sample(TSMF_IFMAN* ifman)
(int)ThrottleDuration, SampleExtensions, cbData);
presentation = tsmf_presentation_find_by_id(ifman->presentation_id);
if (presentation == NULL)
{
DEBUG_WARN("unknown presentation id");
return 1;
}
stream = tsmf_stream_find_by_id(presentation, StreamId);
if (stream == NULL)
{
DEBUG_WARN("unknown stream id");
return 1;
}
tsmf_stream_push_sample(stream, ifman->channel_callback,
ifman->message_id, SampleStartTime, SampleEndTime, ThrottleDuration, SampleExtensions,
cbData, stream_get_tail(ifman->input));
ifman->output_pending = TRUE;
return 0;
}
int tsmf_ifman_on_flush(TSMF_IFMAN* ifman)
{
TSMF_PRESENTATION* presentation;
UINT32 StreamId;
TSMF_PRESENTATION* presentation;
stream_seek(ifman->input, 16);
stream_read_UINT32(ifman->input, StreamId);
DEBUG_DVC("StreamId %d", StreamId);
presentation = tsmf_presentation_find_by_id(ifman->presentation_id);
if (presentation == NULL)
{
DEBUG_WARN("unknown presentation id");
@@ -440,18 +467,20 @@ int tsmf_ifman_on_flush(TSMF_IFMAN* ifman)
tsmf_presentation_flush(presentation);
ifman->output_pending = TRUE;
return 0;
}
int tsmf_ifman_on_end_of_stream(TSMF_IFMAN* ifman)
{
TSMF_PRESENTATION* presentation;
TSMF_STREAM* stream;
UINT32 StreamId;
TSMF_STREAM* stream;
TSMF_PRESENTATION* presentation;
presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input));
stream_seek(ifman->input, 16);
stream_read_UINT32(ifman->input, StreamId);
if (presentation)
{
stream = tsmf_stream_find_by_id(presentation, StreamId);
@@ -477,6 +506,7 @@ int tsmf_ifman_on_playback_started(TSMF_IFMAN* ifman)
DEBUG_DVC("");
presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input));
if (presentation)
tsmf_presentation_start(presentation);
else
@@ -502,10 +532,12 @@ int tsmf_ifman_on_playback_paused(TSMF_IFMAN* ifman)
/* Added pause control so gstreamer pipeline can be paused accordingly */
presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input));
if (presentation)
tsmf_presentation_paused(presentation);
else
DEBUG_WARN("unknown presentation id");
return 0;
}
@@ -564,4 +596,3 @@ int tsmf_ifman_on_playback_rate_changed(TSMF_IFMAN * ifman)
return 0;
}

View File

@@ -25,7 +25,9 @@
#include <stdlib.h>
#include <string.h>
#include <freerdp/utils/memory.h>
#include <winpr/crt.h>
#include <winpr/cmdline.h>
#include <freerdp/utils/stream.h>
#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, "<subsystem>", NULL, NULL, -1, NULL, "audio subsystem" },
{ "audio-dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "audio device name" },
{ "decoder", COMMAND_LINE_VALUE_REQUIRED, "<subsystem>", 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;
}

View File

@@ -35,14 +35,15 @@
#include <sys/time.h>
#endif
#include <freerdp/utils/memory.h>
#include <winpr/crt.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/list.h>
#include <freerdp/utils/thread.h>
#include <freerdp/utils/event.h>
#include <freerdp/utils/sleep.h>
#include <freerdp/client/tsmf.h>
#include <winpr/crt.h>
#include <winpr/synch.h>
#include "tsmf_constants.h"
@@ -271,7 +272,8 @@ TSMF_PRESENTATION* tsmf_presentation_new(const BYTE* guid, IWTSVirtualChannelCal
return NULL;
}
presentation = xnew(TSMF_PRESENTATION);
presentation = (TSMF_PRESENTATION*) malloc(sizeof(TSMF_PRESENTATION));
ZeroMemory(presentation, sizeof(TSMF_PRESENTATION));
memcpy(presentation->presentation_id, guid, GUID_SIZE);
presentation->channel_callback = pChannelCallback;
@@ -339,7 +341,7 @@ static void tsmf_sample_playback_video(TSMF_SAMPLE* sample)
(sample->end_time >= presentation->audio_start_time ||
sample->end_time < stream->last_end_time))
{
freerdp_usleep((stream->next_start_time - t) / 10);
USleep((stream->next_start_time - t) / 10);
}
stream->next_start_time = t + sample->duration - 50000;
@@ -364,10 +366,14 @@ static void tsmf_sample_playback_video(TSMF_SAMPLE* sample)
free(presentation->last_rects);
presentation->last_rects = NULL;
}
presentation->last_num_rects = presentation->output_num_rects;
if (presentation->last_num_rects > 0)
{
presentation->last_rects = xzalloc(presentation->last_num_rects * sizeof(RDP_RECT));
presentation->last_rects = malloc(presentation->last_num_rects * sizeof(RDP_RECT));
ZeroMemory(presentation->last_rects, presentation->last_num_rects * sizeof(RDP_RECT));
memcpy(presentation->last_rects, presentation->output_rects,
presentation->last_num_rects * sizeof(RDP_RECT));
}
@@ -384,10 +390,14 @@ static void tsmf_sample_playback_video(TSMF_SAMPLE* sample)
vevent->y = presentation->output_y;
vevent->width = presentation->output_width;
vevent->height = presentation->output_height;
if (presentation->output_num_rects > 0)
{
vevent->num_visible_rects = presentation->output_num_rects;
vevent->visible_rects = (RDP_RECT*) xzalloc(presentation->output_num_rects * sizeof(RDP_RECT));
vevent->visible_rects = (RDP_RECT*) malloc(presentation->output_num_rects * sizeof(RDP_RECT));
ZeroMemory(vevent->visible_rects, presentation->output_num_rects * sizeof(RDP_RECT));
memcpy(vevent->visible_rects, presentation->output_rects,
presentation->output_num_rects * sizeof(RDP_RECT));
}
@@ -567,10 +577,13 @@ static void tsmf_sample_playback(TSMF_SAMPLE* sample)
free(presentation->last_rects);
presentation->last_rects = NULL;
}
presentation->last_num_rects = presentation->output_num_rects;
if (presentation->last_num_rects > 0)
{
presentation->last_rects = xzalloc(presentation->last_num_rects * sizeof(RDP_RECT));
presentation->last_rects = malloc(presentation->last_num_rects * sizeof(RDP_RECT));
ZeroMemory(presentation->last_rects, presentation->last_num_rects * sizeof(RDP_RECT));
memcpy(presentation->last_rects, presentation->output_rects, presentation->last_num_rects * sizeof(RDP_RECT));
}
if(stream->decoder->UpdateRenderingArea)
@@ -661,10 +674,11 @@ static void* tsmf_stream_playback_func(void* arg)
{
tsmf_stream_process_ack(stream);
sample = tsmf_stream_pop_sample(stream, 1);
if (sample)
tsmf_sample_playback(sample);
else
freerdp_usleep(5000);
USleep(5000);
}
if (stream->eos || presentation->eos)
{
@@ -921,7 +935,8 @@ TSMF_STREAM* tsmf_stream_new(TSMF_PRESENTATION* presentation, UINT32 stream_id)
return NULL;
}
stream = xnew(TSMF_STREAM);
stream = (TSMF_STREAM*) malloc(sizeof(TSMF_STREAM));
ZeroMemory(stream, sizeof(TSMF_STREAM));
stream->stream_id = stream_id;
stream->presentation = presentation;
@@ -1035,7 +1050,8 @@ void tsmf_stream_push_sample(TSMF_STREAM* stream, IWTSVirtualChannelCallback* pC
ReleaseMutex(tsmf_mutex);
sample = xnew(TSMF_SAMPLE);
sample = (TSMF_SAMPLE*) malloc(sizeof(TSMF_SAMPLE));
ZeroMemory(sample, sizeof(TSMF_SAMPLE));
sample->sample_id = sample_id;
sample->start_time = start_time;
@@ -1045,7 +1061,8 @@ void tsmf_stream_push_sample(TSMF_STREAM* stream, IWTSVirtualChannelCallback* pC
sample->stream = stream;
sample->channel_callback = pChannelCallback;
sample->data_size = data_size;
sample->data = xzalloc(data_size + TSMF_BUFFER_PADDING_SIZE);
sample->data = malloc(data_size + TSMF_BUFFER_PADDING_SIZE);
ZeroMemory(sample->data, data_size + TSMF_BUFFER_PADDING_SIZE);
memcpy(sample->data, data, data_size);
freerdp_thread_lock(stream->thread);

View File

@@ -17,8 +17,6 @@
define_channel("urbdrc")
add_subdirectory(libusb)
if(WITH_CLIENT_CHANNELS)
add_channel_client(${MODULE_PREFIX} ${CHANNEL_NAME})
endif()

View File

@@ -3,15 +3,10 @@ set(OPTION_DEFAULT OFF)
set(OPTION_CLIENT_DEFAULT OFF)
set(OPTION_SERVER_DEFAULT OFF)
if(${OPTION_CLIENT_DEFAULT} OR ${OPTION_SERVER_DEFAULT})
set(OPTION_DEFAULT ON)
endif()
define_channel_options(NAME "urbdrc" TYPE "dynamic"
DESCRIPTION "USB Devices Virtual Channel Extension"
SPECIFICATIONS "[MS-RDPEUSB]"
DEFAULT ${OPTION_DEFAULT})
define_channel_client_options(${OPTION_CLIENT_DEFAULT})
#define_channel_server_options(${OPTION_SERVER_DEFAULT})
define_channel_server_options(${OPTION_SERVER_DEFAULT})

View File

@@ -35,17 +35,22 @@ add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} libusb-devman)
#set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} libusb-devman)
set(${MODULE_PREFIX}_LIBS
dbus-glib-1
udev
uuid)
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
MONOLITHIC ${MONOLITHIC_BUILD}
MODULE winpr
MODULES winpr-utils)
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
MONOLITHIC ${MONOLITHIC_BUILD}
MODULE freerdp
MODULES freerdp-utils)
MODULES freerdp-common freerdp-utils)
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
@@ -55,3 +60,5 @@ endif()
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")
# libusb subsystem
add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "libusb" "")

View File

@@ -715,18 +715,19 @@ static int urb_control_transfer(URBDRC_CHANNEL_CALLBACK* callback, BYTE* data,
static int urb_bulk_or_interrupt_transfer(URBDRC_CHANNEL_CALLBACK* callback, BYTE* data,
UINT32 data_sizem, UINT32 MessageId, IUDEVMAN* udevman, UINT32 UsbDevice, int transferDir)
{
IUDEVICE * pdev;
UINT32 out_size, RequestId, InterfaceId, EndpointAddress, PipeHandle;
UINT32 TransferFlags, OutputBufferSize, usbd_status = 0;
BYTE * Buffer;
BYTE * out_data;
int offset;
int offset;
BYTE* Buffer;
IUDEVICE* pdev;
BYTE* out_data;
UINT32 out_size, RequestId, InterfaceId, EndpointAddress, PipeHandle;
UINT32 TransferFlags, OutputBufferSize, usbd_status = 0;
pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
if (pdev == NULL)
return 0;
InterfaceId = ((STREAM_ID_PROXY<<30) | pdev->get_ReqCompletion(pdev));
InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
data_read_UINT32(data + 0, RequestId);
data_read_UINT32(data + 4, PipeHandle);
@@ -740,7 +741,8 @@ static int urb_bulk_or_interrupt_transfer(URBDRC_CHANNEL_CALLBACK* callback, BYT
else
out_size = 36 + OutputBufferSize;
out_data = (BYTE *) malloc(out_size);
Buffer = NULL;
out_data = (BYTE*) malloc(out_size);
memset(out_data, 0, out_size);
switch (transferDir)
@@ -748,10 +750,12 @@ static int urb_bulk_or_interrupt_transfer(URBDRC_CHANNEL_CALLBACK* callback, BYT
case USBD_TRANSFER_DIRECTION_OUT:
Buffer = data + offset;
break;
case USBD_TRANSFER_DIRECTION_IN:
Buffer = out_data + 36;
break;
}
/** process URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER */
pdev->bulk_or_interrupt_transfer(
pdev, RequestId, EndpointAddress,
@@ -794,8 +798,7 @@ static int urb_bulk_or_interrupt_transfer(URBDRC_CHANNEL_CALLBACK* callback, BYT
}
static int
urb_isoch_transfer(URBDRC_CHANNEL_CALLBACK * callback, BYTE * data,
static int urb_isoch_transfer(URBDRC_CHANNEL_CALLBACK * callback, BYTE * data,
UINT32 data_sizem,
UINT32 MessageId,
IUDEVMAN * udevman,
@@ -959,8 +962,7 @@ urb_isoch_transfer(URBDRC_CHANNEL_CALLBACK * callback, BYTE * data,
return 0;
}
static int
urb_control_descriptor_request(URBDRC_CHANNEL_CALLBACK * callback,
static int urb_control_descriptor_request(URBDRC_CHANNEL_CALLBACK* callback,
BYTE * data,
UINT32 data_sizem,
UINT32 MessageId,
@@ -969,17 +971,19 @@ urb_control_descriptor_request(URBDRC_CHANNEL_CALLBACK * callback,
BYTE func_recipient,
int transferDir)
{
IUDEVICE * pdev;
UINT32 out_size, InterfaceId, RequestId, OutputBufferSize, usbd_status;
BYTE bmRequestType, desc_index, desc_type;
UINT16 langId;
BYTE * buffer;
BYTE * out_data;
int ret, offset;
IUDEVICE* pdev;
UINT32 out_size, InterfaceId, RequestId, OutputBufferSize, usbd_status;
BYTE bmRequestType, desc_index, desc_type;
UINT16 langId;
BYTE* buffer;
BYTE* out_data;
int ret, offset;
pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
if (pdev == NULL)
return 0;
InterfaceId = ((STREAM_ID_PROXY<<30) | pdev->get_ReqCompletion(pdev));
data_read_UINT32(data + 0, RequestId);
data_read_BYTE(data + 4, desc_index);
@@ -1051,11 +1055,7 @@ urb_control_descriptor_request(URBDRC_CHANNEL_CALLBACK * callback,
return 0;
}
static int
urb_control_get_status_request(URBDRC_CHANNEL_CALLBACK * callback, BYTE * data,
static int urb_control_get_status_request(URBDRC_CHANNEL_CALLBACK * callback, BYTE * data,
UINT32 data_sizem,
UINT32 MessageId,
IUDEVMAN * udevman,
@@ -1063,13 +1063,13 @@ urb_control_get_status_request(URBDRC_CHANNEL_CALLBACK * callback, BYTE * data,
BYTE func_recipient,
int transferDir)
{
IUDEVICE * pdev;
UINT32 out_size, RequestId, InterfaceId, OutputBufferSize, usbd_status;
UINT16 Index;
BYTE bmRequestType;
BYTE * buffer;
BYTE * out_data;
int offset, ret;
IUDEVICE* pdev;
UINT32 out_size, RequestId, InterfaceId, OutputBufferSize, usbd_status;
UINT16 Index;
BYTE bmRequestType;
BYTE* buffer;
BYTE* out_data;
int offset, ret;
if (transferDir == 0){
LLOGLN(urbdrc_debug, ("urb_control_get_status_request: not support transfer out\n"));
@@ -1146,8 +1146,7 @@ urb_control_get_status_request(URBDRC_CHANNEL_CALLBACK * callback, BYTE * data,
return 0;
}
static int
urb_control_vendor_or_class_request(URBDRC_CHANNEL_CALLBACK * callback,
static int urb_control_vendor_or_class_request(URBDRC_CHANNEL_CALLBACK * callback,
BYTE * data,
UINT32 data_sizem,
UINT32 MessageId,
@@ -1157,14 +1156,14 @@ urb_control_vendor_or_class_request(URBDRC_CHANNEL_CALLBACK * callback,
BYTE func_recipient,
int transferDir)
{
IUDEVICE * pdev;
UINT32 out_size, RequestId, InterfaceId, TransferFlags, usbd_status;
UINT32 OutputBufferSize;
BYTE ReqTypeReservedBits, Request, bmRequestType;
UINT16 Value, Index, Padding;
BYTE * buffer;
BYTE * out_data;
int offset, ret;
IUDEVICE* pdev;
UINT32 out_size, RequestId, InterfaceId, TransferFlags, usbd_status;
UINT32 OutputBufferSize;
BYTE ReqTypeReservedBits, Request, bmRequestType;
UINT16 Value, Index, Padding;
BYTE* buffer;
BYTE* out_data;
int offset, ret;
/** control by vendor command */
pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
@@ -1256,8 +1255,7 @@ urb_control_vendor_or_class_request(URBDRC_CHANNEL_CALLBACK * callback,
static int
urb_os_feature_descriptor_request(URBDRC_CHANNEL_CALLBACK * callback,
static int urb_os_feature_descriptor_request(URBDRC_CHANNEL_CALLBACK * callback,
BYTE * data,
UINT32 data_sizem,
UINT32 MessageId,
@@ -1265,17 +1263,19 @@ urb_os_feature_descriptor_request(URBDRC_CHANNEL_CALLBACK * callback,
UINT32 UsbDevice,
int transferDir)
{
IUDEVICE * pdev;
UINT32 out_size, RequestId, InterfaceId, OutputBufferSize, usbd_status;
BYTE Recipient, InterfaceNumber, Ms_PageIndex;
UINT16 Ms_featureDescIndex;
BYTE * out_data;
BYTE * buffer;
int offset, ret;
IUDEVICE* pdev;
UINT32 out_size, RequestId, InterfaceId, OutputBufferSize, usbd_status;
BYTE Recipient, InterfaceNumber, Ms_PageIndex;
UINT16 Ms_featureDescIndex;
BYTE* out_data;
BYTE* buffer;
int offset, ret;
pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
if (pdev == NULL)
return 0;
InterfaceId = ((STREAM_ID_PROXY<<30) | pdev->get_ReqCompletion(pdev));
data_read_UINT32(data + 0, RequestId);
@@ -1347,14 +1347,11 @@ urb_os_feature_descriptor_request(URBDRC_CHANNEL_CALLBACK * callback,
callback->channel->Write(callback->channel, out_size, out_data, NULL);
zfree(out_data);
return 0;
}
static int
urb_pipe_request(URBDRC_CHANNEL_CALLBACK * callback, BYTE * data,
static int urb_pipe_request(URBDRC_CHANNEL_CALLBACK * callback, BYTE * data,
UINT32 data_sizem,
UINT32 MessageId,
IUDEVMAN * udevman,
@@ -1362,11 +1359,11 @@ urb_pipe_request(URBDRC_CHANNEL_CALLBACK * callback, BYTE * data,
int transferDir,
int action)
{
IUDEVICE * pdev;
UINT32 out_size, RequestId, InterfaceId, PipeHandle, EndpointAddress;
UINT32 OutputBufferSize, usbd_status = 0;
BYTE * out_data;
int out_offset, ret;
IUDEVICE* pdev;
UINT32 out_size, RequestId, InterfaceId, PipeHandle, EndpointAddress;
UINT32 OutputBufferSize, usbd_status = 0;
BYTE* out_data;
int out_offset, ret;
if (transferDir == 0){
LLOGLN(urbdrc_debug, ("urb_pipe_request: not support transfer out\n"));
@@ -1374,8 +1371,10 @@ urb_pipe_request(URBDRC_CHANNEL_CALLBACK * callback, BYTE * data,
}
pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
if (pdev == NULL)
return 0;
InterfaceId = ((STREAM_ID_PROXY<<30) | pdev->get_ReqCompletion(pdev));
data_read_UINT32(data + 0, RequestId);
@@ -1441,14 +1440,11 @@ urb_pipe_request(URBDRC_CHANNEL_CALLBACK * callback, BYTE * data,
if (!pdev->isSigToEnd(pdev))
callback->channel->Write(callback->channel, out_size, out_data, NULL);
zfree(out_data);
return 0;
}
static int
urb_get_current_frame_number(URBDRC_CHANNEL_CALLBACK * callback,
static int urb_get_current_frame_number(URBDRC_CHANNEL_CALLBACK* callback,
BYTE * data,
UINT32 data_sizem,
UINT32 MessageId,
@@ -1456,10 +1452,10 @@ urb_get_current_frame_number(URBDRC_CHANNEL_CALLBACK * callback,
UINT32 UsbDevice,
int transferDir)
{
IUDEVICE * pdev;
UINT32 out_size, RequestId, InterfaceId, OutputBufferSize;
UINT32 dummy_frames;
BYTE * out_data;
IUDEVICE* pdev;
UINT32 out_size, RequestId, InterfaceId, OutputBufferSize;
UINT32 dummy_frames;
BYTE* out_data;
if (transferDir == 0){
LLOGLN(urbdrc_debug, ("urb_get_current_frame_number: not support transfer out\n"));
@@ -1506,8 +1502,7 @@ urb_get_current_frame_number(URBDRC_CHANNEL_CALLBACK * callback,
/* Unused function for current server */
static int
urb_control_get_configuration_request(URBDRC_CHANNEL_CALLBACK * callback,
static int urb_control_get_configuration_request(URBDRC_CHANNEL_CALLBACK* callback,
BYTE * data,
UINT32 data_sizem,
UINT32 MessageId,
@@ -1515,21 +1510,24 @@ urb_control_get_configuration_request(URBDRC_CHANNEL_CALLBACK * callback,
UINT32 UsbDevice,
int transferDir)
{
IUDEVICE * pdev;
UINT32 out_size, RequestId, InterfaceId, OutputBufferSize, usbd_status;
BYTE * buffer;
BYTE * out_data;
int ret, offset;
IUDEVICE* pdev;
UINT32 out_size, RequestId, InterfaceId, OutputBufferSize, usbd_status;
BYTE* buffer;
BYTE* out_data;
int ret, offset;
if (transferDir == 0){
if (transferDir == 0)
{
LLOGLN(urbdrc_debug, ("urb_control_get_configuration_request:"
" not support transfer out\n"));
return -1;
}
pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
if (pdev == NULL)
return 0;
InterfaceId = ((STREAM_ID_PROXY<<30) | pdev->get_ReqCompletion(pdev));
data_read_UINT32(data + 0, RequestId);
@@ -1585,8 +1583,7 @@ urb_control_get_configuration_request(URBDRC_CHANNEL_CALLBACK * callback,
}
/* Unused function for current server */
static int
urb_control_get_interface_request(URBDRC_CHANNEL_CALLBACK * callback,
static int urb_control_get_interface_request(URBDRC_CHANNEL_CALLBACK* callback,
BYTE * data,
UINT32 data_sizem,
UINT32 MessageId,
@@ -1594,12 +1591,12 @@ urb_control_get_interface_request(URBDRC_CHANNEL_CALLBACK * callback,
UINT32 UsbDevice,
int transferDir)
{
IUDEVICE * pdev;
UINT32 out_size, RequestId, InterfaceId, OutputBufferSize, usbd_status;
UINT16 interface;
BYTE * buffer;
BYTE * out_data;
int ret, offset;
IUDEVICE* pdev;
UINT32 out_size, RequestId, InterfaceId, OutputBufferSize, usbd_status;
UINT16 interface;
BYTE* buffer;
BYTE* out_data;
int ret, offset;
if (transferDir == 0){
LLOGLN(urbdrc_debug, ("urb_control_get_interface_request: not support transfer out\n"));
@@ -1662,8 +1659,7 @@ urb_control_get_interface_request(URBDRC_CHANNEL_CALLBACK * callback,
return 0;
}
static int
urb_control_feature_request(URBDRC_CHANNEL_CALLBACK * callback, BYTE * data,
static int urb_control_feature_request(URBDRC_CHANNEL_CALLBACK * callback, BYTE * data,
UINT32 data_sizem,
UINT32 MessageId,
IUDEVMAN * udevman,
@@ -1672,17 +1668,19 @@ urb_control_feature_request(URBDRC_CHANNEL_CALLBACK * callback, BYTE * data,
BYTE command,
int transferDir)
{
IUDEVICE * pdev;
UINT32 out_size, RequestId, InterfaceId, OutputBufferSize, usbd_status;
UINT16 FeatureSelector, Index;
BYTE bmRequestType, bmRequest;
BYTE * buffer;
BYTE * out_data;
int ret, offset;
IUDEVICE* pdev;
UINT32 out_size, RequestId, InterfaceId, OutputBufferSize, usbd_status;
UINT16 FeatureSelector, Index;
BYTE bmRequestType, bmRequest;
BYTE* buffer;
BYTE* out_data;
int ret, offset;
pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
if (pdev == NULL)
return 0;
InterfaceId = ((STREAM_ID_PROXY<<30) | pdev->get_ReqCompletion(pdev));
data_read_UINT32(data + 0, RequestId);
@@ -1765,8 +1763,7 @@ urb_control_feature_request(URBDRC_CHANNEL_CALLBACK * callback, BYTE * data,
return 0;
}
static int
urbdrc_process_transfer_request(URBDRC_CHANNEL_CALLBACK * callback, BYTE * data,
static int urbdrc_process_transfer_request(URBDRC_CHANNEL_CALLBACK * callback, BYTE * data,
UINT32 data_sizem,
UINT32 MessageId,
IUDEVMAN * udevman,
@@ -2292,13 +2289,13 @@ urbdrc_process_transfer_request(URBDRC_CHANNEL_CALLBACK * callback, BYTE * data,
break;
default:
LLOGLN(urbdrc_debug, ("URB_Func: %x is not found!", URB_Function));
break;
}
return error;
}
void*
urbdrc_process_udev_data_transfer(void* arg)
void* urbdrc_process_udev_data_transfer(void* arg)
{
TRANSFER_DATA* transfer_data = (TRANSFER_DATA*) arg;
URBDRC_CHANNEL_CALLBACK * callback = transfer_data->callback;
@@ -2446,5 +2443,3 @@ urbdrc_process_udev_data_transfer(void* arg)
udevman->push_urb(udevman);
return 0;
}

View File

@@ -149,9 +149,11 @@ void isoch_queue_free(ISOCH_CALLBACK_QUEUE* queue)
while (queue->has_next(queue))
{
isoch = queue->get_next(queue);
if (isoch != NULL)
queue->unregister_data(queue, isoch);
}
pthread_mutex_unlock(&queue->isoch_loading);
pthread_mutex_destroy(&queue->isoch_loading);

View File

@@ -16,8 +16,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
set(MODULE_NAME "libusb-devman")
set(MODULE_PREFIX "CHANNEL_URBDRC_LIBUSB_DEVMAN")
define_channel_client_subsystem("urbdrc" "libusb" "")
set(${MODULE_PREFIX}_SRCS
libusb_udevman.c
@@ -26,25 +25,27 @@ set(${MODULE_PREFIX}_SRCS
request_queue.c
request_queue.h)
include_directories(../client)
include_directories(..)
if(STATIC_CHANNELS)
add_library(${MODULE_NAME} STATIC ${${MODULE_PREFIX}_SRCS})
else()
add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
endif()
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "")
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
set(${MODULE_PREFIX}_LIBS
${CMAKE_THREAD_LIBS_INIT})
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS}
dbus-glib-1
usb-1.0
pthread
udev)
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
MONOLITHIC ${MONOLITHIC_BUILD}
MODULE winpr
MODULES winpr-utils)
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
if(NOT STATIC_CHANNELS)
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH})
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH})
endif()

View File

@@ -22,6 +22,11 @@
#include <stdlib.h>
#include <string.h>
#include <winpr/crt.h>
#include <winpr/cmdline.h>
#include <freerdp/addin.h>
#include "urbdrc_types.h"
#include "urbdrc_main.h"
@@ -61,19 +66,20 @@ struct _UDEVMAN
int sem_timeout;
pthread_mutex_t devman_loading;
sem_t sem_urb_lock;
sem_t sem_urb_lock;
};
typedef UDEVMAN * PUDEVMAN;
typedef UDEVMAN* PUDEVMAN;
static void udevman_rewind(IUDEVMAN* idevman)
{
UDEVMAN * udevman = (UDEVMAN *) idevman;
UDEVMAN* udevman = (UDEVMAN*) idevman;
udevman->idev = udevman->head;
}
static int udevman_has_next(IUDEVMAN* idevman)
{
UDEVMAN * udevman = (UDEVMAN *) idevman;
UDEVMAN* udevman = (UDEVMAN*) idevman;
if (udevman->idev == NULL)
return 0;
else
@@ -82,60 +88,63 @@ static int udevman_has_next(IUDEVMAN* idevman)
static IUDEVICE* udevman_get_next(IUDEVMAN* idevman)
{
UDEVMAN * udevman = (UDEVMAN*) idevman;
UDEVMAN* udevman = (UDEVMAN*) idevman;
IUDEVICE* pdev;
pdev = udevman->idev;
udevman->idev = (IUDEVICE*) ((UDEVICE*)udevman->idev)->next;
udevman->idev = (IUDEVICE*) ((UDEVICE*) udevman->idev)->next;
return pdev;
}
static IUDEVICE* udevman_get_udevice_by_addr(IUDEVMAN* idevman, int bus_number, int dev_number)
{
IUDEVICE * pdev;
IUDEVICE* pdev;
idevman->loading_lock(idevman);
idevman->rewind (idevman);
while (idevman->has_next (idevman))
idevman->rewind(idevman);
while (idevman->has_next(idevman))
{
pdev = idevman->get_next (idevman);
if (pdev->get_bus_number(pdev) == bus_number &&
pdev->get_dev_number(pdev) == dev_number)
pdev = idevman->get_next(idevman);
if ((pdev->get_bus_number(pdev) == bus_number) && (pdev->get_dev_number(pdev) == dev_number))
{
idevman->loading_unlock(idevman);
return pdev;
}
}
idevman->loading_unlock(idevman);
LLOGLN(libusb_debug, ("%s: bus:%d dev:%d not exist in udevman",
__func__, bus_number, dev_number));
return NULL;
}
static int udevman_register_udevice(IUDEVMAN* idevman, int bus_number, int dev_number,
int UsbDevice,
UINT16 idVendor,
UINT16 idProduct,
int flag)
int UsbDevice, UINT16 idVendor, UINT16 idProduct, int flag)
{
UDEVMAN * udevman = (UDEVMAN *) idevman;
IUDEVICE * pdev = NULL;
IUDEVICE ** devArray;
UDEVMAN* udevman = (UDEVMAN*) idevman;
IUDEVICE* pdev = NULL;
IUDEVICE** devArray;
int i, num, addnum = 0;
pdev = (IUDEVICE *)udevman_get_udevice_by_addr(idevman, bus_number, dev_number);
pdev = (IUDEVICE*) udevman_get_udevice_by_addr(idevman, bus_number, dev_number);
if (pdev != NULL)
return 0;
if (flag == UDEVMAN_FLAG_ADD_BY_ADDR)
{
pdev = udev_new_by_addr(bus_number, dev_number);
if (pdev == NULL)
return 0;
pdev->set_UsbDevice(pdev, UsbDevice);
idevman->loading_lock(idevman);
if (udevman->head == NULL)
{
/* linked list is empty */
@@ -149,6 +158,7 @@ static int udevman_register_udevice(IUDEVMAN* idevman, int bus_number, int dev_n
pdev->set_p_prev(pdev, udevman->tail);
udevman->tail = pdev;
}
udevman->device_num += 1;
idevman->loading_unlock(idevman);
}
@@ -157,13 +167,13 @@ static int udevman_register_udevice(IUDEVMAN* idevman, int bus_number, int dev_n
addnum = 0;
/* register all device that match pid vid */
num = udev_new_by_id(idVendor, idProduct, &devArray);
for (i = 0; i < num; i++)
{
pdev = devArray[i];
if (udevman_get_udevice_by_addr(idevman,
pdev->get_bus_number(pdev),
pdev->get_dev_number(pdev))
!= NULL)
pdev->get_bus_number(pdev), pdev->get_dev_number(pdev)) != NULL)
{
zfree(pdev);
continue;
@@ -171,6 +181,7 @@ static int udevman_register_udevice(IUDEVMAN* idevman, int bus_number, int dev_n
pdev->set_UsbDevice(pdev, UsbDevice);
idevman->loading_lock(idevman);
if (udevman->head == NULL)
{
/* linked list is empty */
@@ -184,10 +195,12 @@ static int udevman_register_udevice(IUDEVMAN* idevman, int bus_number, int dev_n
pdev->set_p_prev(pdev, udevman->tail);
udevman->tail = pdev;
}
udevman->device_num += 1;
idevman->loading_unlock(idevman);
addnum++;
}
zfree(devArray);
return addnum;
}
@@ -196,23 +209,24 @@ static int udevman_register_udevice(IUDEVMAN* idevman, int bus_number, int dev_n
printf("udevman_register_udevice: function error!!");
return 0;
}
return 1;
}
static int udevman_unregister_udevice(IUDEVMAN* idevman, int bus_number, int dev_number)
{
UDEVMAN * udevman = (UDEVMAN *) idevman;
UDEVMAN* udevman = (UDEVMAN*) idevman;
UDEVICE * pdev, * dev;
int ret = 0, err = 0;
dev = (UDEVICE *)udevman_get_udevice_by_addr(idevman, bus_number, dev_number);
dev = (UDEVICE*) udevman_get_udevice_by_addr(idevman, bus_number, dev_number);
idevman->loading_lock(idevman);
idevman->rewind(idevman);
while (idevman->has_next(idevman) != 0)
{
pdev = (UDEVICE *)idevman->get_next(idevman);
pdev = (UDEVICE*) idevman->get_next(idevman);
if (pdev == dev) /* device exists */
{
@@ -280,30 +294,33 @@ static int udevman_unregister_udevice(IUDEVMAN* idevman, int bus_number, int dev
return 1; /* unregistration successful */
}
/* if we reach this point, the device wasn't found */
return 0;
}
static void udevman_parse_device_addr (char *str, int *id1, int *id2, char sign)
static void udevman_parse_device_addr(char* str, int* id1, int* id2, char sign)
{
char s1[8], *s2;
memset(s1, 0, sizeof(s1));
char s1[8];
char* s2;
ZeroMemory(s1, sizeof(s1));
s2 = (strchr(str, sign)) + 1;
strncpy(s1, str, strlen(str) - (strlen(s2)+1));
strncpy(s1, str, strlen(str) - (strlen(s2) + 1));
*id1 = atoi(s1);
*id2 = atoi(s2);
}
static void udevman_parse_device_pid_vid (char *str, int *id1, int *id2, char sign)
static void udevman_parse_device_pid_vid(char* str, int* id1, int* id2, char sign)
{
char s1[8], *s2;
memset(s1, 0, sizeof(s1));
char s1[8];
char* s2;
ZeroMemory(s1, sizeof(s1));
s2 = (strchr(str, sign)) + 1;
strncpy(s1, str, strlen(str) - (strlen(s2)+1));
strncpy(s1, str, strlen(str) - (strlen(s2) + 1));
*id1 = (int) strtol(s1, NULL, 16);
*id2 = (int) strtol(s2, NULL, 16);
@@ -311,7 +328,7 @@ static void udevman_parse_device_pid_vid (char *str, int *id1, int *id2, char si
static int udevman_check_device_exist_by_id(IUDEVMAN* idevman, UINT16 idVendor, UINT16 idProduct)
{
if (libusb_open_device_with_vid_pid (NULL, idVendor, idProduct))
if (libusb_open_device_with_vid_pid(NULL, idVendor, idProduct))
return 1;
return 0;
@@ -319,106 +336,113 @@ static int udevman_check_device_exist_by_id(IUDEVMAN* idevman, UINT16 idVendor,
static int udevman_is_auto_add(IUDEVMAN* idevman)
{
UDEVMAN * udevman = (UDEVMAN *) idevman;
UDEVMAN* udevman = (UDEVMAN*) idevman;
return (udevman->flags & UDEVMAN_FLAG_ADD_BY_AUTO) ? 1 : 0;
}
static IUDEVICE* udevman_get_udevice_by_UsbDevice_try_again(IUDEVMAN* idevman, UINT32 UsbDevice)
{
UDEVICE * pdev;
UDEVICE* pdev;
idevman->loading_lock(idevman);
idevman->rewind (idevman);
while (idevman->has_next (idevman))
idevman->rewind(idevman);
while (idevman->has_next(idevman))
{
pdev = (UDEVICE *)idevman->get_next (idevman);
pdev = (UDEVICE*) idevman->get_next(idevman);
if (pdev->UsbDevice == UsbDevice)
{
idevman->loading_unlock(idevman);
return (IUDEVICE *)pdev;
return (IUDEVICE*) pdev;
}
}
idevman->loading_unlock(idevman);
return NULL;
}
static IUDEVICE* udevman_get_udevice_by_UsbDevice(IUDEVMAN* idevman, UINT32 UsbDevice)
{
UDEVICE * pdev;
UDEVICE* pdev;
idevman->loading_lock(idevman);
idevman->rewind (idevman);
while (idevman->has_next (idevman))
idevman->rewind(idevman);
while (idevman->has_next(idevman))
{
pdev = (UDEVICE *)idevman->get_next (idevman);
pdev = (UDEVICE*) idevman->get_next(idevman);
if (pdev->UsbDevice == UsbDevice)
{
idevman->loading_unlock(idevman);
return (IUDEVICE *)pdev;
return (IUDEVICE*) pdev;
}
}
idevman->loading_unlock(idevman);
/* try again */
pdev = (UDEVICE *)idevman->get_udevice_by_UsbDevice_try_again(idevman, UsbDevice);
pdev = (UDEVICE*) idevman->get_udevice_by_UsbDevice_try_again(idevman, UsbDevice);
if (pdev)
{
return (IUDEVICE *)pdev;
return (IUDEVICE*) pdev;
}
LLOGLN(libusb_debug, ("udevman_get_udevice_by_UsbDevice: 0x%x ERROR!!\n",
UsbDevice));
LLOGLN(libusb_debug, ("udevman_get_udevice_by_UsbDevice: 0x%x ERROR!!\n", UsbDevice));
return NULL;
}
static void udevman_loading_lock(IUDEVMAN* idevman)
{
UDEVMAN * udevman = (UDEVMAN *) idevman;
UDEVMAN* udevman = (UDEVMAN*) idevman;
pthread_mutex_lock(&udevman->devman_loading);
}
static void udevman_loading_unlock(IUDEVMAN* idevman)
{
UDEVMAN * udevman = (UDEVMAN *) idevman;
UDEVMAN* udevman = (UDEVMAN*) idevman;
pthread_mutex_unlock(&udevman->devman_loading);
}
static void udevman_wait_urb(IUDEVMAN* idevman)
{
UDEVMAN * udevman = (UDEVMAN *) idevman;
UDEVMAN* udevman = (UDEVMAN*) idevman;
sem_wait(&udevman->sem_urb_lock);
}
static void udevman_push_urb(IUDEVMAN* idevman)
{
UDEVMAN * udevman = (UDEVMAN *) idevman;
UDEVMAN* udevman = (UDEVMAN*) idevman;
sem_post(&udevman->sem_urb_lock);
}
BASIC_STATE_FUNC_DEFINED(defUsbDevice, UINT32)
BASIC_STATE_FUNC_DEFINED(device_num, int)
BASIC_STATE_FUNC_DEFINED(sem_timeout, int)
static void udevman_free(IUDEVMAN* idevman)
{
UDEVMAN * udevman = (UDEVMAN *) idevman;
UDEVMAN* udevman = (UDEVMAN*) idevman;
pthread_mutex_destroy(&udevman->devman_loading);
sem_destroy(&udevman->sem_urb_lock);
libusb_exit(NULL);
/* free udevman */
if (udevman)
zfree(udevman);
}
static void udevman_load_interface(UDEVMAN * udevman)
{
/* standard */
udevman->iface.free = udevman_free;
/* manage devices */
udevman->iface.rewind = udevman_rewind;
udevman->iface.get_next = udevman_get_next;
@@ -428,13 +452,16 @@ static void udevman_load_interface(UDEVMAN * udevman)
udevman->iface.get_udevice_by_UsbDevice = udevman_get_udevice_by_UsbDevice;
udevman->iface.get_udevice_by_UsbDevice_try_again =
udevman_get_udevice_by_UsbDevice_try_again;
/* Extension */
udevman->iface.check_device_exist_by_id = udevman_check_device_exist_by_id;
udevman->iface.isAutoAdd = udevman_is_auto_add;
/* Basic state */
BASIC_STATE_FUNC_REGISTER(defUsbDevice, udevman);
BASIC_STATE_FUNC_REGISTER(device_num, udevman);
BASIC_STATE_FUNC_REGISTER(sem_timeout, udevman);
/* control semaphore or mutex lock */
udevman->iface.loading_lock = udevman_loading_lock;
udevman->iface.loading_unlock = udevman_loading_unlock;
@@ -442,25 +469,127 @@ static void udevman_load_interface(UDEVMAN * udevman)
udevman->iface.wait_urb = udevman_wait_urb;
}
int FreeRDPUDEVMANEntry(PFREERDP_URBDRC_SERVICE_ENTRY_POINTS pEntryPoints)
COMMAND_LINE_ARGUMENT_A urbdrc_udevman_args[] =
{
UDEVMAN* udevman;
RDP_PLUGIN_DATA * plugin_data = pEntryPoints->plugin_data;
UINT32 UsbDevice = BASE_USBDEVICE_NUM;
char * token;
char * message = "id";
char hardware_id[16];
{ "dbg", COMMAND_LINE_VALUE_FLAG, "", NULL, BoolValueFalse, -1, NULL, "debug" },
{ "dev", COMMAND_LINE_VALUE_REQUIRED, "<devices>", NULL, NULL, -1, NULL, "device list" },
{ "id", COMMAND_LINE_VALUE_FLAG, "", NULL, BoolValueFalse, -1, NULL, "FLAG_ADD_BY_VID_PID" },
{ "addr", COMMAND_LINE_VALUE_FLAG, "", NULL, BoolValueFalse, -1, NULL, "FLAG_ADD_BY_ADDR" },
{ "auto", COMMAND_LINE_VALUE_FLAG, "", NULL, BoolValueFalse, -1, NULL, "FLAG_ADD_BY_AUTO" },
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
};
static void urbdrc_udevman_register_devices(UDEVMAN* udevman, char* devices)
{
char* token;
int idVendor;
int idProduct;
int bus_number;
int dev_number;
int bus_number;
int dev_number;
int success = 0;
char hardware_id[16];
char* default_devices = "id";
UINT32 UsbDevice = BASE_USBDEVICE_NUM;
if (!devices)
devices = default_devices;
/* register all usb devices */
token = strtok(devices, "#");
while (token)
{
bus_number = 0;
dev_number = 0;
idVendor = 0;
idProduct = 0;
strcpy(hardware_id, token);
token = strtok(NULL, "#");
if (udevman->flags & UDEVMAN_FLAG_ADD_BY_VID_PID)
{
udevman_parse_device_pid_vid(hardware_id, &idVendor, &idProduct, ':');
success = udevman->iface.register_udevice((IUDEVMAN*) udevman,
0, 0, UsbDevice, (UINT16) idVendor, (UINT16) idProduct, UDEVMAN_FLAG_ADD_BY_VID_PID);
}
else if (udevman->flags & UDEVMAN_FLAG_ADD_BY_ADDR)
{
udevman_parse_device_addr(hardware_id, &bus_number, &dev_number, ':');
success = udevman->iface.register_udevice((IUDEVMAN*) udevman,
bus_number, dev_number, UsbDevice, 0, 0, UDEVMAN_FLAG_ADD_BY_ADDR);
}
if (success)
UsbDevice++;
}
udevman->defUsbDevice = UsbDevice;
}
static void urbdrc_udevman_parse_addin_args(UDEVMAN* udevman, ADDIN_ARGV* args)
{
int status;
DWORD flags;
COMMAND_LINE_ARGUMENT_A* arg;
flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON;
status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv,
urbdrc_udevman_args, flags, udevman, NULL, NULL);
arg = urbdrc_udevman_args;
do
{
if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT))
continue;
CommandLineSwitchStart(arg)
CommandLineSwitchCase(arg, "dbg")
{
urbdrc_debug = 0;
}
CommandLineSwitchCase(arg, "dev")
{
urbdrc_udevman_register_devices(udevman, arg->Value);
}
CommandLineSwitchCase(arg, "id")
{
udevman->flags = UDEVMAN_FLAG_ADD_BY_VID_PID;
}
CommandLineSwitchCase(arg, "addr")
{
udevman->flags = UDEVMAN_FLAG_ADD_BY_ADDR;
}
CommandLineSwitchCase(arg, "auto")
{
udevman->flags |= UDEVMAN_FLAG_ADD_BY_AUTO;
}
CommandLineSwitchDefault(arg)
{
}
CommandLineSwitchEnd(arg)
}
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
}
#ifdef STATIC_CHANNELS
#define freerdp_urbdrc_client_subsystem_entry libusb_freerdp_urbdrc_client_subsystem_entry
#endif
int freerdp_urbdrc_client_subsystem_entry(PFREERDP_URBDRC_SERVICE_ENTRY_POINTS pEntryPoints)
{
UDEVMAN* udevman;
ADDIN_ARGV* args = pEntryPoints->args;
libusb_init(NULL);
udevman = (PUDEVMAN)malloc(sizeof(UDEVMAN));
udevman = (PUDEVMAN) malloc(sizeof(UDEVMAN));
udevman->device_num = 0;
udevman->idev = NULL;
udevman->head = NULL;
@@ -474,66 +603,11 @@ int FreeRDPUDEVMANEntry(PFREERDP_URBDRC_SERVICE_ENTRY_POINTS pEntryPoints)
/* load usb device service management */
udevman_load_interface(udevman);
/* set debug flag, to enable Debug message for usb data transfer*/
if (plugin_data->data[2])
message = (char *)plugin_data->data[2];
/* set debug flag, to enable Debug message for usb data transfer */
if (strstr(message, "id"))
udevman->flags = UDEVMAN_FLAG_ADD_BY_VID_PID;
else if (strstr(message, "addr"))
udevman->flags = UDEVMAN_FLAG_ADD_BY_ADDR;
if (strstr(message, "auto"))
udevman->flags |= UDEVMAN_FLAG_ADD_BY_AUTO;
libusb_debug = 10;
if (strstr(message, "debug"))
{
libusb_debug = 0;
udevman->flags |= UDEVMAN_FLAG_DEBUG;
}
/* register all usb device */
token = strtok((char *)plugin_data->data[1], "#");
while (token)
{
bus_number = 0;
dev_number = 0;
idVendor = 0;
idProduct = 0;
strcpy(hardware_id, token);
token = strtok(NULL, "#");
if (udevman->flags & UDEVMAN_FLAG_ADD_BY_VID_PID)
{
udevman_parse_device_pid_vid(hardware_id, &idVendor,
&idProduct,
'_');
success = udevman->iface.register_udevice((IUDEVMAN *)udevman,
0,
0,
UsbDevice,
(UINT16) idVendor,
(UINT16) idProduct,
UDEVMAN_FLAG_ADD_BY_VID_PID);
}
else if (udevman->flags & UDEVMAN_FLAG_ADD_BY_ADDR)
{
udevman_parse_device_addr(hardware_id, &bus_number,
&dev_number,
'_');
success = udevman->iface.register_udevice((IUDEVMAN *)udevman,
bus_number,
dev_number,
UsbDevice,
0,
0,
UDEVMAN_FLAG_ADD_BY_ADDR);
}
if (success)
UsbDevice++;
}
udevman->defUsbDevice = UsbDevice;
urbdrc_udevman_parse_addin_args(udevman, args);
pEntryPoints->pRegisterUDEVMAN(pEntryPoints->plugin, (IUDEVMAN*) udevman);

View File

@@ -43,12 +43,11 @@ int request_queue_has_next(REQUEST_QUEUE* queue)
}
TRANSFER_REQUEST* request_queue_register_request(REQUEST_QUEUE* queue, UINT32 RequestId,
struct libusb_transfer * transfer,
BYTE endpoint)
struct libusb_transfer* transfer, BYTE endpoint)
{
TRANSFER_REQUEST* request;
TRANSFER_REQUEST* request;
request = (TRANSFER_REQUEST*)malloc(sizeof(TRANSFER_REQUEST));
request = (TRANSFER_REQUEST*) malloc(sizeof(TRANSFER_REQUEST));
request->prev = NULL;
request->next = NULL;
@@ -57,7 +56,9 @@ TRANSFER_REQUEST* request_queue_register_request(REQUEST_QUEUE* queue, UINT32 Re
request->transfer = transfer;
request->endpoint = endpoint;
request->submit = 0;
pthread_mutex_lock(&queue->request_loading);
if (queue->head == NULL)
{
/* linked queue is empty */
@@ -67,22 +68,24 @@ TRANSFER_REQUEST* request_queue_register_request(REQUEST_QUEUE* queue, UINT32 Re
else
{
/* append data to the end of the linked queue */
queue->tail->next = (void*)request;
request->prev = (void*)queue->tail;
queue->tail->next = (void*) request;
request->prev = (void*) queue->tail;
queue->tail = request;
}
queue->request_num += 1;
pthread_mutex_unlock(&queue->request_loading);
return request;
}
void request_queue_rewind(REQUEST_QUEUE *queue)
void request_queue_rewind(REQUEST_QUEUE* queue)
{
queue->ireq = queue->head;
}
/* Get first*/
TRANSFER_REQUEST* request_queue_get_request_by_endpoint(REQUEST_QUEUE *queue, BYTE ep)
TRANSFER_REQUEST* request_queue_get_request_by_endpoint(REQUEST_QUEUE* queue, BYTE ep)
{
TRANSFER_REQUEST * request;
pthread_mutex_lock(&queue->request_loading);
@@ -101,7 +104,7 @@ TRANSFER_REQUEST* request_queue_get_request_by_endpoint(REQUEST_QUEUE *queue, BY
return NULL;
}
int request_queue_unregister_request(REQUEST_QUEUE *queue, UINT32 RequestId)
int request_queue_unregister_request(REQUEST_QUEUE* queue, UINT32 RequestId)
{
TRANSFER_REQUEST *request, *request_temp;
pthread_mutex_lock(&queue->request_loading);
@@ -110,27 +113,28 @@ int request_queue_unregister_request(REQUEST_QUEUE *queue, UINT32 RequestId)
while (queue->has_next(queue) != 0)
{
request = queue->get_next(queue);
if (request->RequestId == RequestId)
{
if (request->prev != NULL)
{
request_temp = (TRANSFER_REQUEST*)request->prev;
request_temp->next = (TRANSFER_REQUEST*)request->next;
request_temp = (TRANSFER_REQUEST*) request->prev;
request_temp->next = (TRANSFER_REQUEST*) request->next;
}
else
{
queue->head = (TRANSFER_REQUEST*)request->next;
queue->head = (TRANSFER_REQUEST*) request->next;
}
if (request->next != NULL)
{
request_temp = (TRANSFER_REQUEST*)request->next;
request_temp->prev = (TRANSFER_REQUEST*)request->prev;
request_temp = (TRANSFER_REQUEST*) request->next;
request_temp->prev = (TRANSFER_REQUEST*) request->prev;
}
else
{
queue->tail = (TRANSFER_REQUEST*)request->prev;
queue->tail = (TRANSFER_REQUEST*) request->prev;
}
@@ -156,7 +160,7 @@ REQUEST_QUEUE* request_queue_new()
{
REQUEST_QUEUE* queue;
queue = (REQUEST_QUEUE*)malloc(sizeof(REQUEST_QUEUE));
queue = (REQUEST_QUEUE*) malloc(sizeof(REQUEST_QUEUE));
queue->request_num = 0;
queue->ireq = NULL;
queue->head = NULL;

View File

@@ -23,6 +23,10 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <winpr/crt.h>
#include <winpr/synch.h>
#include "searchman.h"
static void searchman_rewind(USB_SEARCHMAN* searchman)
@@ -144,7 +148,7 @@ static void searchman_start(USB_SEARCHMAN* self, void* func)
/* close thread */
static void searchman_close(USB_SEARCHMAN* self)
{
wait_obj_set(self->term_event);
SetEvent(self->term_event);
}
static void searchman_list_show(USB_SEARCHMAN* self)
@@ -176,7 +180,7 @@ void searchman_free(USB_SEARCHMAN* self)
/* free searchman */
sem_destroy(&self->sem_term);
wait_obj_free(self->term_event);
CloseHandle(self->term_event);
free(self);
}
@@ -214,7 +218,7 @@ USB_SEARCHMAN* searchman_new(void * urbdrc, UINT32 UsbDevice)
searchman->free = searchman_free;
searchman->strated = 0;
searchman->term_event = wait_obj_new();
searchman->term_event = CreateEvent(NULL, TRUE, FALSE, NULL);
sem_init(&searchman->sem_term, 0, 0);
return searchman;

View File

@@ -22,34 +22,35 @@
#define __SEACH_MAN_H
#include "urbdrc_types.h"
#include <freerdp/utils/wait_obj.h>
typedef struct _USB_SEARCHDEV USB_SEARCHDEV;
struct _USB_SEARCHDEV
{
void * inode;
void * prev;
void * next;
void* inode;
void* prev;
void* next;
UINT16 idVendor;
UINT16 idProduct;
};
typedef struct _USB_SEARCHMAN USB_SEARCHMAN;
struct _USB_SEARCHMAN
{
int usb_numbers;
UINT32 UsbDevice;
USB_SEARCHDEV * idev; /* iterator device */
USB_SEARCHDEV * head; /* head device in linked list */
USB_SEARCHDEV * tail; /* tail device in linked list */
int usb_numbers;
UINT32 UsbDevice;
USB_SEARCHDEV* idev; /* iterator device */
USB_SEARCHDEV* head; /* head device in linked list */
USB_SEARCHDEV* tail; /* tail device in linked list */
pthread_mutex_t mutex;
struct wait_obj * term_event;
HANDLE term_event;
sem_t sem_term;
int strated;
/* for urbdrc channel call back */
void * urbdrc;
void* urbdrc;
/* load service */
void (*rewind) (USB_SEARCHMAN* seachman);
@@ -71,7 +72,7 @@ struct _USB_SEARCHMAN
void (*free) (USB_SEARCHMAN* searchman);
};
USB_SEARCHMAN * searchman_new(void * urbdrc, UINT32 UsbDevice);
USB_SEARCHMAN* searchman_new(void* urbdrc, UINT32 UsbDevice);
#endif

View File

@@ -25,8 +25,12 @@
#include <time.h>
#include <libudev.h>
#include <winpr/crt.h>
#include <winpr/synch.h>
#include <winpr/cmdline.h>
#include <freerdp/dvc.h>
#include <freerdp/utils/load_plugin.h>
#include <freerdp/addin.h>
#include "urbdrc_types.h"
#include "urbdrc_main.h"
@@ -54,7 +58,7 @@ static int func_hardware_id_format(IUDEVICE* pdev, char (*HardwareIds)[DEVICE_HA
return 0;
}
static int func_compat_id_format(IUDEVICE *pdev, char (*CompatibilityIds)[DEVICE_COMPATIBILITY_ID_SIZE])
static int func_compat_id_format(IUDEVICE* pdev, char (*CompatibilityIds)[DEVICE_COMPATIBILITY_ID_SIZE])
{
char str[DEVICE_COMPATIBILITY_ID_SIZE];
int bDeviceClass, bDeviceSubClass, bDeviceProtocol;
@@ -260,8 +264,9 @@ static int urbdrc_process_channel_create(URBDRC_CHANNEL_CALLBACK* callback, char
InterfaceId = ((STREAM_ID_PROXY<<30) | CLIENT_CHANNEL_NOTIFICATION);
out_size = 24;
out_data = (char *) malloc(out_size);
out_data = (char*) malloc(out_size);
memset(out_data, 0, out_size);
data_write_UINT32(out_data + 0, InterfaceId); /* interface id */
data_write_UINT32(out_data + 4, MessageId); /* message id */
data_write_UINT32(out_data + 8, CHANNEL_CREATED); /* function id */
@@ -285,8 +290,9 @@ static int urdbrc_send_virtual_channel_add(IWTSVirtualChannel* channel, UINT32 M
InterfaceId = ((STREAM_ID_PROXY<<30) | CLIENT_DEVICE_SINK);
out_size = 12;
out_data = (char *) malloc(out_size);
out_data = (char*) malloc(out_size);
memset(out_data, 0, out_size);
data_write_UINT32(out_data + 0, InterfaceId); /* interface */
data_write_UINT32(out_data + 4, MessageId); /* message id */
data_write_UINT32(out_data + 8, ADD_VIRTUAL_CHANNEL); /* function id */
@@ -439,8 +445,8 @@ static void* urbdrc_search_usb_device(void* arg)
IWTSVirtualChannel* dvc_channel;
USB_SEARCHDEV* sdev;
IUDEVICE* pdev = NULL;
struct wait_obj* listobj[2];
struct wait_obj* mon_fd;
HANDLE listobj[2];
HANDLE mon_fd;
int numobj, timeout;
int busnum, devnum;
int success = 0, error, on_close = 0, found = 0;
@@ -469,7 +475,7 @@ static void* urbdrc_search_usb_device(void* arg)
/* Get the file descriptor (fd) for the monitor.
This fd will get passed to select() */
mon_fd = wait_obj_new_with_fd((void*) (size_t) udev_monitor_get_fd(mon));
mon_fd = CreateFileDescriptorEvent(NULL, TRUE, FALSE, udev_monitor_get_fd(mon));
while (1)
{
@@ -483,15 +489,16 @@ static void* urbdrc_search_usb_device(void* arg)
listobj[0] = searchman->term_event;
listobj[1] = mon_fd;
numobj = 2;
wait_obj_select(listobj, numobj, -1);
if (wait_obj_is_set(searchman->term_event))
WaitForMultipleObjects(numobj, listobj, FALSE, INFINITE);
if (WaitForSingleObject(searchman->term_event, 0) == WAIT_OBJECT_0)
{
sem_post(&searchman->sem_term);
return 0;
}
if (wait_obj_is_set(mon_fd))
if (WaitForSingleObject(mon_fd, 0) == WAIT_OBJECT_0)
{
dev = udev_monitor_receive_device(mon);
@@ -565,11 +572,11 @@ static void* urbdrc_search_usb_device(void* arg)
numobj = 1;
timeout = 4000; /* milliseconds */
wait_obj_select(listobj, numobj, timeout);
WaitForMultipleObjects(numobj, listobj, FALSE, timeout);
if (wait_obj_is_set(searchman->term_event))
if (WaitForSingleObject(searchman->term_event, 0) == WAIT_OBJECT_0)
{
wait_obj_free(mon_fd);
CloseHandle(mon_fd);
sem_post(&searchman->sem_term);
return 0;
}
@@ -621,16 +628,16 @@ static void* urbdrc_search_usb_device(void* arg)
numobj = 1;
timeout = 3000; /* milliseconds */
wait_obj_select(listobj, numobj, timeout);
WaitForMultipleObjects(numobj, listobj, FALSE, timeout);
if (wait_obj_is_set(searchman->term_event))
if (WaitForSingleObject(searchman->term_event, 0) == WAIT_OBJECT_0)
{
wait_obj_free(mon_fd);
CloseHandle(mon_fd);
sem_post(&searchman->sem_term);
return 0;
}
if(pdev && on_close && dvc_channel && pdev->isSigToEnd(pdev) && !(pdev->isChannelClosed(pdev)))
if (pdev && on_close && dvc_channel && pdev->isSigToEnd(pdev) && !(pdev->isChannelClosed(pdev)))
{
on_close = 0;
dvc_channel->Close(dvc_channel);
@@ -639,21 +646,22 @@ static void* urbdrc_search_usb_device(void* arg)
udev_device_unref(dev);
}
else {
else
{
printf("No Device from receive_device(). An error occured.\n");
}
}
}
wait_obj_free(mon_fd);
CloseHandle(mon_fd);
sem_post(&searchman->sem_term);
return 0;
}
void* urbdrc_new_device_create(void * arg)
void* urbdrc_new_device_create(void* arg)
{
TRANSFER_DATA* transfer_data = (TRANSFER_DATA*) arg;
TRANSFER_DATA* transfer_data = (TRANSFER_DATA*) arg;
URBDRC_CHANNEL_CALLBACK* callback = transfer_data->callback;
IWTSVirtualChannelManager* channel_mgr;
URBDRC_PLUGIN* urbdrc = transfer_data->urbdrc;
@@ -756,7 +764,7 @@ static int urbdrc_process_channel_notification(URBDRC_CHANNEL_CALLBACK* callback
transfer_data->udevman = urbdrc->udevman;
transfer_data->urbdrc = urbdrc;
transfer_data->cbSize = cbSize;
transfer_data->pBuffer = (BYTE *)malloc((cbSize));
transfer_data->pBuffer = (BYTE*) malloc((cbSize));
for (i = 0; i < (cbSize); i++)
{
@@ -919,7 +927,7 @@ static int urbdrc_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManag
{
URBDRC_PLUGIN* urbdrc = (URBDRC_PLUGIN*) pPlugin;
IUDEVMAN* udevman = NULL;
USB_SEARCHMAN * searchman = NULL;
USB_SEARCHMAN* searchman = NULL;
LLOGLN(10, ("urbdrc_plugin_initialize:"));
urbdrc->listener_callback = (URBDRC_LISTENER_CALLBACK*) malloc(sizeof(URBDRC_LISTENER_CALLBACK));
@@ -935,7 +943,7 @@ static int urbdrc_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManag
urbdrc->searchman = searchman;
return pChannelMgr->CreateListener(pChannelMgr, "URBDRC", 0,
(IWTSListenerCallback *) urbdrc->listener_callback, NULL);
(IWTSListenerCallback*) urbdrc->listener_callback, NULL);
}
static int urbdrc_plugin_terminated(IWTSPlugin* pPlugin)
@@ -979,7 +987,7 @@ static int urbdrc_plugin_terminated(IWTSPlugin* pPlugin)
return 0;
}
static void urbdrc_register_udevman_plugin(IWTSPlugin* pPlugin, IUDEVMAN* udevman)
static void urbdrc_register_udevman_addin(IWTSPlugin* pPlugin, IUDEVMAN* udevman)
{
URBDRC_PLUGIN* urbdrc = (URBDRC_PLUGIN*) pPlugin;
@@ -994,31 +1002,19 @@ static void urbdrc_register_udevman_plugin(IWTSPlugin* pPlugin, IUDEVMAN* udevma
urbdrc->udevman = udevman;
}
static int urbdrc_load_udevman_plugin(IWTSPlugin* pPlugin, const char* name, RDP_PLUGIN_DATA* data)
static int urbdrc_load_udevman_addin(IWTSPlugin* pPlugin, const char* name, ADDIN_ARGV* args)
{
char* fullname;
PFREERDP_URBDRC_DEVICE_ENTRY entry;
FREERDP_URBDRC_SERVICE_ENTRY_POINTS entryPoints;
if (strrchr(name, '.') != NULL)
{
entry = (PFREERDP_URBDRC_DEVICE_ENTRY) freerdp_load_plugin(name, URBDRC_UDEVMAN_EXPORT_FUNC_NAME);
}
else
{
fullname = xzalloc(strlen(name) + 8);
strcpy(fullname, name);
strcat(fullname, "_udevman");
entry = (PFREERDP_URBDRC_DEVICE_ENTRY) freerdp_load_plugin(fullname, URBDRC_UDEVMAN_EXPORT_FUNC_NAME);
free(fullname);
}
entry = (PFREERDP_URBDRC_DEVICE_ENTRY) freerdp_load_channel_addin_entry("urbdrc", (LPSTR) name, NULL, 0);
if (entry == NULL)
return FALSE;
entryPoints.plugin = pPlugin;
entryPoints.pRegisterUDEVMAN = urbdrc_register_udevman_plugin;
entryPoints.plugin_data = data;
entryPoints.pRegisterUDEVMAN = urbdrc_register_udevman_addin;
entryPoints.args = args;
if (entry(&entryPoints) != 0)
{
@@ -1029,17 +1025,57 @@ static int urbdrc_load_udevman_plugin(IWTSPlugin* pPlugin, const char* name, RDP
return TRUE;
}
static int urbdrc_process_plugin_data(IWTSPlugin* pPlugin, RDP_PLUGIN_DATA* data)
void urbdrc_set_subsystem(URBDRC_PLUGIN* urbdrc, char* subsystem)
{
BOOL ret;
if (urbdrc->subsystem)
free(urbdrc->subsystem);
if (data->data[0] && (strcmp((char*)data->data[0], "urbdrc") == 0 || strstr((char*) data->data[0], "/urbdrc.") != NULL))
urbdrc->subsystem = _strdup(subsystem);
}
COMMAND_LINE_ARGUMENT_A urbdrc_args[] =
{
{ "dbg", COMMAND_LINE_VALUE_FLAG, "", NULL, BoolValueFalse, -1, NULL, "debug" },
{ "sys", COMMAND_LINE_VALUE_REQUIRED, "<subsystem>", NULL, NULL, -1, NULL, "subsystem" },
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
};
static void urbdrc_process_addin_args(URBDRC_PLUGIN* urbdrc, ADDIN_ARGV* args)
{
int status;
DWORD flags;
COMMAND_LINE_ARGUMENT_A* arg;
flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON;
status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv,
urbdrc_args, flags, urbdrc, NULL, NULL);
arg = urbdrc_args;
do
{
ret = urbdrc_load_udevman_plugin(pPlugin, "libusb", data);
return ret;
}
if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT))
continue;
return TRUE;
CommandLineSwitchStart(arg)
CommandLineSwitchCase(arg, "dbg")
{
urbdrc_debug = 0;
}
CommandLineSwitchCase(arg, "sys")
{
urbdrc_set_subsystem(urbdrc, arg->Value);
}
CommandLineSwitchDefault(arg)
{
}
CommandLineSwitchEnd(arg)
}
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
}
#ifdef STATIC_CHANNELS
@@ -1048,16 +1084,17 @@ static int urbdrc_process_plugin_data(IWTSPlugin* pPlugin, RDP_PLUGIN_DATA* data
int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
{
int error = 0;
int status = 0;
ADDIN_ARGV* args;
URBDRC_PLUGIN* urbdrc;
RDP_PLUGIN_DATA* data;
urbdrc = (URBDRC_PLUGIN*) pEntryPoints->GetPlugin(pEntryPoints, "urbdrc");
data = pEntryPoints->GetPluginData(pEntryPoints);
args = pEntryPoints->GetPluginData(pEntryPoints);
if (urbdrc == NULL)
{
urbdrc = xnew(URBDRC_PLUGIN);
urbdrc = (URBDRC_PLUGIN*) malloc(sizeof(URBDRC_PLUGIN));
ZeroMemory(urbdrc, sizeof(URBDRC_PLUGIN));
urbdrc->iface.Initialize = urbdrc_plugin_initialize;
urbdrc->iface.Connected = NULL;
@@ -1068,14 +1105,16 @@ int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
urbdrc_debug = 10;
if (data->data[2] && strstr((char *)data->data[2], "debug"))
urbdrc_debug = 0;
error = pEntryPoints->RegisterPlugin(pEntryPoints, "urbdrc", (IWTSPlugin *) urbdrc);
status = pEntryPoints->RegisterPlugin(pEntryPoints, "urbdrc", (IWTSPlugin*) urbdrc);
}
if (error == 0)
urbdrc_process_plugin_data((IWTSPlugin*) urbdrc, data);
if (status == 0)
urbdrc_process_addin_args(urbdrc, args);
return error;
if (!urbdrc->subsystem)
urbdrc_set_subsystem(urbdrc, "libusb");
urbdrc_load_udevman_addin((IWTSPlugin*) urbdrc, urbdrc->subsystem, args);
return status;
}

View File

@@ -35,11 +35,12 @@ typedef struct _IUDEVICE IUDEVICE;
typedef struct _IUDEVMAN IUDEVMAN;
#define BASIC_DEV_STATE_DEFINED(_arg, _type) \
_type (*get_##_arg) (IUDEVICE *pdev); \
void (*set_##_arg) (IUDEVICE *pdev, _type _arg)
_type (*get_##_arg) (IUDEVICE* pdev); \
void (*set_##_arg) (IUDEVICE* pdev, _type _arg)
#define BASIC_DEVMAN_STATE_DEFINED(_arg, _type) \
_type (*get_##_arg) (IUDEVMAN *udevman); \
void (*set_##_arg) (IUDEVMAN *udevman, _type _arg)
_type (*get_##_arg) (IUDEVMAN* udevman); \
void (*set_##_arg) (IUDEVMAN* udevman, _type _arg)
typedef struct _URBDRC_LISTENER_CALLBACK URBDRC_LISTENER_CALLBACK;
@@ -74,17 +75,16 @@ struct _URBDRC_PLUGIN
USB_SEARCHMAN* searchman;
UINT32 first_channel_id;
UINT32 vchannel_status;
char* subsystem;
};
#define URBDRC_UDEVMAN_EXPORT_FUNC_NAME "FreeRDPUDEVMANEntry"
typedef void (*PREGISTERURBDRCSERVICE)(IWTSPlugin* plugin, IUDEVMAN* udevman);
struct _FREERDP_URBDRC_SERVICE_ENTRY_POINTS
{
IWTSPlugin* plugin;
PREGISTERURBDRCSERVICE pRegisterUDEVMAN;
RDP_PLUGIN_DATA* plugin_data;
ADDIN_ARGV* args;
};
typedef struct _FREERDP_URBDRC_SERVICE_ENTRY_POINTS FREERDP_URBDRC_SERVICE_ENTRY_POINTS;
typedef FREERDP_URBDRC_SERVICE_ENTRY_POINTS* PFREERDP_URBDRC_SERVICE_ENTRY_POINTS;
@@ -106,107 +106,75 @@ struct _TRANSFER_DATA
struct _IUDEVICE
{
/* Transfer */
int (*isoch_transfer) (IUDEVICE * idev, UINT32 RequestId,
UINT32 EndpointAddress,
UINT32 TransferFlags,
int NoAck,
UINT32 *ErrorCount,
UINT32 *UrbdStatus,
UINT32 *StartFrame,
UINT32 NumberOfPackets,
BYTE *IsoPacket,
UINT32 *BufferSize,
BYTE *Buffer,
int Timeout);
int (*isoch_transfer) (IUDEVICE* idev, UINT32 RequestId,
UINT32 EndpointAddress, UINT32 TransferFlags, int NoAck, UINT32* ErrorCount,
UINT32* UrbdStatus, UINT32* StartFrame, UINT32 NumberOfPackets,
BYTE* IsoPacket, UINT32* BufferSize, BYTE* Buffer, int Timeout);
int (*control_transfer) (IUDEVICE * idev, UINT32 RequestId,
UINT32 EndpointAddress,
UINT32 TransferFlags,
BYTE bmRequestType,
BYTE Request,
UINT16 Value,
UINT16 Index,
UINT32 *UrbdStatus,
UINT32 *BufferSize,
BYTE *Buffer,
UINT32 Timeout);
int (*control_transfer) (IUDEVICE* idev, UINT32 RequestId,
UINT32 EndpointAddress, UINT32 TransferFlags, BYTE bmRequestType, BYTE Request, UINT16 Value,
UINT16 Index, UINT32* UrbdStatus, UINT32* BufferSize, BYTE* Buffer, UINT32 Timeout);
int (*bulk_or_interrupt_transfer) (IUDEVICE * idev, UINT32 RequestId,
UINT32 EndpointAddress,
UINT32 TransferFlags,
UINT32 *UsbdStatus,
UINT32 *BufferSize,
BYTE *Buffer,
UINT32 Timeout);
int (*bulk_or_interrupt_transfer) (IUDEVICE* idev, UINT32 RequestId, UINT32 EndpointAddress,
UINT32 TransferFlags, UINT32* UsbdStatus, UINT32* BufferSize, BYTE* Buffer, UINT32 Timeout);
int (*select_configuration) (IUDEVICE* idev, UINT32 bConfigurationValue);
int (*select_configuration) (IUDEVICE * idev, UINT32 bConfigurationValue);
int (*select_interface) (IUDEVICE * idev, BYTE InterfaceNumber,
int (*select_interface) (IUDEVICE* idev, BYTE InterfaceNumber,
BYTE AlternateSetting);
int (*control_pipe_request) (IUDEVICE * idev, UINT32 RequestId,
UINT32 EndpointAddress,
UINT32 *UsbdStatus,
int command);
int (*control_pipe_request) (IUDEVICE* idev, UINT32 RequestId,
UINT32 EndpointAddress, UINT32* UsbdStatus, int command);
int (*control_query_device_text) (IUDEVICE * idev, UINT32 TextType,
UINT32 LocaleId,
UINT32 *BufferSize,
BYTE * Buffer);
int (*control_query_device_text) (IUDEVICE* idev, UINT32 TextType,
UINT32 LocaleId, UINT32*BufferSize, BYTE* Buffer);
int (*os_feature_descriptor_request) (IUDEVICE * idev, UINT32 RequestId,
BYTE Recipient,
BYTE InterfaceNumber,
BYTE Ms_PageIndex,
UINT16 Ms_featureDescIndex,
UINT32 * UsbdStatus,
UINT32 * BufferSize,
BYTE* Buffer,
int Timeout);
int (*os_feature_descriptor_request) (IUDEVICE* idev, UINT32 RequestId, BYTE Recipient,
BYTE InterfaceNumber, BYTE Ms_PageIndex, UINT16 Ms_featureDescIndex, UINT32* UsbdStatus,
UINT32* BufferSize, BYTE* Buffer, int Timeout);
void (*cancel_all_transfer_request) (IUDEVICE * idev);
void (*cancel_all_transfer_request) (IUDEVICE* idev);
int (*cancel_transfer_request) (IUDEVICE * idev, UINT32 RequestId);
int (*cancel_transfer_request) (IUDEVICE* idev, UINT32 RequestId);
int (*query_device_descriptor) (IUDEVICE * idev, int offset);
int (*query_device_descriptor) (IUDEVICE* idev, int offset);
void (*detach_kernel_driver) (IUDEVICE * idev);
void (*detach_kernel_driver) (IUDEVICE* idev);
void (*attach_kernel_driver) (IUDEVICE * idev);
void (*attach_kernel_driver) (IUDEVICE* idev);
int (*wait_action_completion) (IUDEVICE * idev);
int (*wait_action_completion) (IUDEVICE* idev);
void (*push_action) (IUDEVICE * idev);
void (*push_action) (IUDEVICE* idev);
void (*complete_action) (IUDEVICE * idev);
void (*complete_action) (IUDEVICE* idev);
/* Wait for 5 sec */
int (*wait_for_detach) (IUDEVICE * idev);
int (*wait_for_detach) (IUDEVICE* idev);
/* FIXME: Currently this is a way of stupid, SHOULD to improve it.
* Isochronous transfer must to FIFO */
void (*lock_fifo_isoch) (IUDEVICE * idev);
void (*unlock_fifo_isoch) (IUDEVICE * idev);
void (*lock_fifo_isoch) (IUDEVICE* idev);
void (*unlock_fifo_isoch) (IUDEVICE* idev);
int (*query_device_port_status) (IUDEVICE * idev, UINT32 *UsbdStatus,
UINT32 * BufferSize,
BYTE * Buffer);
int (*query_device_port_status) (IUDEVICE* idev, UINT32 *UsbdStatus,
UINT32* BufferSize,
BYTE* Buffer);
int (*request_queue_is_none) (IUDEVICE * idev);
int (*request_queue_is_none) (IUDEVICE* idev);
MSUSB_CONFIG_DESCRIPTOR * (*complete_msconfig_setup) (IUDEVICE * idev,
MSUSB_CONFIG_DESCRIPTOR * MsConfig);
MSUSB_CONFIG_DESCRIPTOR* (*complete_msconfig_setup) (IUDEVICE* idev,
MSUSB_CONFIG_DESCRIPTOR* MsConfig);
/* Basic state */
int (*isCompositeDevice) (IUDEVICE * idev);
int (*isSigToEnd) (IUDEVICE * idev);
int (*isExist) (IUDEVICE * idev);
int (*isAlreadySend) (IUDEVICE * idev);
int (*isChannelClosed) (IUDEVICE * idev);
void (*SigToEnd) (IUDEVICE * idev);
void (*setAlreadySend) (IUDEVICE * idev);
void (*setChannelClosed) (IUDEVICE * idev);
char *(*getPath) (IUDEVICE * idev);
int (*isCompositeDevice) (IUDEVICE* idev);
int (*isSigToEnd) (IUDEVICE* idev);
int (*isExist) (IUDEVICE* idev);
int (*isAlreadySend) (IUDEVICE* idev);
int (*isChannelClosed) (IUDEVICE* idev);
void (*SigToEnd) (IUDEVICE* idev);
void (*setAlreadySend) (IUDEVICE* idev);
void (*setChannelClosed) (IUDEVICE* idev);
char *(*getPath) (IUDEVICE* idev);
BASIC_DEV_STATE_DEFINED(channel_id, UINT32);
BASIC_DEV_STATE_DEFINED(UsbDevice, UINT32);
@@ -214,12 +182,12 @@ struct _IUDEVICE
BASIC_DEV_STATE_DEFINED(bus_number, UINT16);
BASIC_DEV_STATE_DEFINED(dev_number, UINT16);
BASIC_DEV_STATE_DEFINED(port_number, int);
BASIC_DEV_STATE_DEFINED(isoch_queue, void *);
BASIC_DEV_STATE_DEFINED(MsConfig, MSUSB_CONFIG_DESCRIPTOR *);
BASIC_DEV_STATE_DEFINED(isoch_queue, void*);
BASIC_DEV_STATE_DEFINED(MsConfig, MSUSB_CONFIG_DESCRIPTOR*);
BASIC_DEV_STATE_DEFINED(p_udev, void *);
BASIC_DEV_STATE_DEFINED(p_prev, void *);
BASIC_DEV_STATE_DEFINED(p_next, void *);
BASIC_DEV_STATE_DEFINED(p_udev, void*);
BASIC_DEV_STATE_DEFINED(p_prev, void*);
BASIC_DEV_STATE_DEFINED(p_next, void*);
/* Control semaphore or mutex lock */
@@ -228,36 +196,32 @@ struct _IUDEVICE
struct _IUDEVMAN
{
/* Standard */
void (*free) (IUDEVMAN *idevman);
void (*free) (IUDEVMAN* idevman);
/* Manage devices */
void (*rewind) (IUDEVMAN *idevman);
int (*has_next) (IUDEVMAN *idevman);
int (*unregister_udevice) (IUDEVMAN* idevman, int bus_number,
int dev_number);
int (*register_udevice) (IUDEVMAN* idevman, int bus_number,
int dev_number,
int UsbDevice,
UINT16 idVendor,
UINT16 idProduct,
int flag);
IUDEVICE *(*get_next) (IUDEVMAN *idevman);
IUDEVICE *(*get_udevice_by_UsbDevice) (IUDEVMAN * idevman,
UINT32 UsbDevice);
IUDEVICE *(*get_udevice_by_UsbDevice_try_again) (IUDEVMAN * idevman,
UINT32 UsbDevice);
void (*rewind) (IUDEVMAN* idevman);
int (*has_next) (IUDEVMAN* idevman);
int (*unregister_udevice) (IUDEVMAN* idevman, int bus_number, int dev_number);
int (*register_udevice) (IUDEVMAN* idevman, int bus_number,
int dev_number, int UsbDevice, UINT16 idVendor, UINT16 idProduct, int flag);
IUDEVICE *(*get_next) (IUDEVMAN* idevman);
IUDEVICE *(*get_udevice_by_UsbDevice) (IUDEVMAN* idevman, UINT32 UsbDevice);
IUDEVICE *(*get_udevice_by_UsbDevice_try_again) (IUDEVMAN* idevman, UINT32 UsbDevice);
/* Extension */
int (*check_device_exist_by_id) (IUDEVMAN * idevman, UINT16 idVendor,
UINT16 idProduct);
int (*isAutoAdd) (IUDEVMAN * idevman);
int (*check_device_exist_by_id) (IUDEVMAN* idevman, UINT16 idVendor, UINT16 idProduct);
int (*isAutoAdd) (IUDEVMAN* idevman);
/* Basic state */
BASIC_DEVMAN_STATE_DEFINED(defUsbDevice, UINT32);
BASIC_DEVMAN_STATE_DEFINED(device_num, int);
BASIC_DEVMAN_STATE_DEFINED(sem_timeout, int);
/* control semaphore or mutex lock */
void (*loading_lock) (IUDEVMAN * idevman);
void (*loading_unlock) (IUDEVMAN * idevman);
void (*push_urb) (IUDEVMAN * idevman);
void (*wait_urb) (IUDEVMAN * idevman);
void (*loading_lock) (IUDEVMAN* idevman);
void (*loading_unlock) (IUDEVMAN* idevman);
void (*push_urb) (IUDEVMAN* idevman);
void (*wait_urb) (IUDEVMAN* idevman);
};
#endif /* __URBDRC_MAIN_H */

View File

@@ -17,7 +17,7 @@
* limitations under the License.
*/
#include <freerdp/utils/memory.h>
#include <winpr/crt.h>
#include "df_graphics.h"
@@ -123,7 +123,8 @@ void df_register_graphics(rdpGraphics* graphics)
{
rdpPointer* pointer;
pointer = xnew(rdpPointer);
pointer = (rdpPointer*) malloc(sizeof(rdpPointer));
ZeroMemory(pointer, sizeof(rdpPointer));
pointer->size = sizeof(dfPointer);
pointer->New = df_Pointer_New;

View File

@@ -22,13 +22,14 @@
#include <locale.h>
#include <freerdp/freerdp.h>
#include <freerdp/utils/args.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/event.h>
#include <freerdp/constants.h>
#include <freerdp/utils/event.h>
#include <freerdp/client/file.h>
#include <freerdp/client/cmdline.h>
#include <freerdp/client/channels.h>
#include <freerdp/client/cliprdr.h>
#include <winpr/crt.h>
#include <winpr/synch.h>
#include "df_event.h"
@@ -120,7 +121,9 @@ BOOL df_pre_connect(freerdp* instance)
dfContext* context;
rdpSettings* settings;
dfi = (dfInfo*) xzalloc(sizeof(dfInfo));
dfi = (dfInfo*) malloc(sizeof(dfInfo));
ZeroMemory(dfi, sizeof(dfInfo));
context = ((dfContext*) instance->context);
context->dfi = dfi;
@@ -152,11 +155,15 @@ BOOL df_pre_connect(freerdp* instance)
settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE;
settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE;
dfi->clrconv = xnew(CLRCONV);
dfi->clrconv = (CLRCONV*) malloc(sizeof(CLRCONV));
ZeroMemory(dfi->clrconv, sizeof(CLRCONV));
dfi->clrconv->alpha = 1;
dfi->clrconv->invert = 0;
dfi->clrconv->rgb555 = 0;
dfi->clrconv->palette = xnew(rdpPalette);
dfi->clrconv->palette = (rdpPalette*) malloc(sizeof(rdpPalette));
ZeroMemory(dfi->clrconv->palette, sizeof(rdpPalette));
freerdp_channels_pre_connect(instance->context->channels, instance);
@@ -221,31 +228,10 @@ BOOL df_post_connect(freerdp* instance)
return TRUE;
}
static int df_process_plugin_args(rdpSettings* settings, const char* name,
RDP_PLUGIN_DATA* plugin_data, void* user_data)
{
void* entry = NULL;
rdpChannels* channels = (rdpChannels*) user_data;
entry = freerdp_channels_client_find_static_entry("VirtualChannelEntry", name);
if (entry)
{
if (freerdp_channels_client_load(channels, settings, entry, plugin_data) == 0)
{
printf("loading channel %s (static)\n", name);
return 1;
}
}
printf("loading channel %s (plugin)\n", name);
freerdp_channels_load_plugin(channels, settings, name, plugin_data);
return 1;
}
BOOL df_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint)
{
char answer;
printf("Certificate details:\n");
printf("\tSubject: %s\n", subject);
printf("\tIssuer: %s\n", issuer);
@@ -254,7 +240,6 @@ BOOL df_verify_certificate(freerdp* instance, char* subject, char* issuer, char*
"the CA certificate in your certificate store, or the certificate has expired. "
"Please look at the documentation on how to create local certificate store for a private CA.\n");
char answer;
while (1)
{
printf("Do you trust the above certificate? (Y/N) ");
@@ -445,6 +430,7 @@ void* thread_func(void* param)
int main(int argc, char* argv[])
{
int status;
pthread_t thread;
freerdp* instance;
dfContext* context;
@@ -472,9 +458,20 @@ int main(int argc, char* argv[])
channels = instance->context->channels;
DirectFBInit(&argc, &argv);
freerdp_parse_args(instance->settings, argc, argv, df_process_plugin_args, channels, NULL, NULL);
data = (struct thread_data*) xzalloc(sizeof(struct thread_data));
instance->context->argc = argc;
instance->context->argv = argv;
status = freerdp_client_parse_command_line_arguments(argc, argv, instance->settings);
if (status < 0)
exit(0);
freerdp_client_load_addins(instance->context->channels, instance->settings);
data = (struct thread_data*) malloc(sizeof(struct thread_data));
ZeroMemory(data, sizeof(sizeof(struct thread_data)));
data->instance = instance;
g_thread_count++;

View File

@@ -16,7 +16,8 @@
#import "freerdp/graphics.h"
#import "freerdp/utils/event.h"
#import "freerdp/client/cliprdr.h"
#import "freerdp/utils/args.h"
#import "freerdp/client/file.h"
#import "freerdp/client/cmdline.h"
#import "freerdp/rail/rail.h"
#import "freerdp/rail.h"
#import "freerdp/utils/rail.h"

View File

@@ -1016,6 +1016,7 @@ int rdp_connect()
BOOL mac_pre_connect(freerdp *inst)
{
int status;
char *cptr;
int len;
int i;
@@ -1213,12 +1214,19 @@ BOOL mac_pre_connect(freerdp *inst)
}
}
#endif
freerdp_parse_args(inst->settings, g_mrdpview->argc, g_mrdpview->argv, process_plugin_args, inst->context->channels, NULL, NULL);
if ((strcmp(g_mrdpview->argv[1], "-h") == 0) || (strcmp(g_mrdpview->argv[1], "--help") == 0)) {
[NSApp terminate:nil];
return TRUE;
}
inst->context->argc = g_mrdpview->argc;
inst->context->argv = g_mrdpview->argv;
status = freerdp_client_parse_command_line_arguments(inst->context->argc, inst->context->argv, inst->settings);
if (status < 0)
{
[NSApp terminate:nil];
return TRUE;
}
freerdp_client_load_addins(inst->context->channels, inst->settings);
[g_mrdpview setViewSize:inst->settings->DesktopWidth :inst->settings->DesktopHeight];

Some files were not shown because too many files have changed in this diff Show More