Merge pull request #816 from awakecoding/master

Refactoring, Channels, CMake, Settings, TSG, Command-Line Interface, .rdp File Support,
This commit is contained in:
Marc-André Moreau 2012-11-22 06:42:38 -08:00
commit f0c5a0fdb9
349 changed files with 16617 additions and 7665 deletions

View File

@ -38,10 +38,11 @@ set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/)
# Check for cmake compatibility (enable/disable features)
include(CheckCmakeCompat)
include(FindFeature)
include(AutoVersioning)
include(ConfigOptions)
include(ComplexLibrary)
include(FindOptionalPackage)
include(FeatureSummary)
include(CheckCCompilerFlag)
include(GNUInstallDirsWrapper)
@ -77,7 +78,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
@ -136,14 +137,13 @@ if(MSVC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MT")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /O2")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Ob2")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W2")
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_AMD64_")
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_X86_")
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_UNICODE")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWINPR_EXPORTS")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFREERDP_EXPORTS")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_WIN32_WINNT=0x0501")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_CRT_SECURE_NO_WARNINGS")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWIN32_LEAN_AND_MEAN")
@ -151,6 +151,9 @@ if(MSVC)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR})
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWINPR_EXPORTS")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFREERDP_EXPORTS")
# Include files
check_include_files(fcntl.h HAVE_FCNTL_H)
check_include_files(unistd.h HAVE_UNISTD_H)
@ -168,52 +171,118 @@ if(APPLE)
include_directories(/opt/local/include)
link_directories(/opt/local/lib)
endif()
if(WITH_CLANG)
set(CMAKE_C_COMPILER "clang")
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmacosx-version-min=10.4")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl-framework,CoreFoundation")
endif()
# Android
if(ANDROID)
set(WITH_X11 OFF)
set(WITH_CUPS OFF)
set(WITH_ALSA OFF)
set(WITH_PULSE OFF)
set(WITH_FFMPEG OFF)
set(WITH_GSTREAMER OFF)
set(WITH_PCSC OFF)
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
find_package(Threads REQUIRED)
if(UNIX OR CYGWIN)
set(X11_FEATURE_TYPE "RECOMMENDED")
else()
set(X11_FEATURE_TYPE "DISABLED")
endif()
if(NOT WIN32)
find_required_package(ZLIB)
find_optional_package(PCSC)
find_optional_package(PulseAudio)
set(X11_FEATURE_PURPOSE "X11")
set(X11_FEATURE_DESCRIPTION "X11 client and server")
if(NOT ANDROID)
find_suggested_package(Cups)
endif()
set(DIRECTFB_FEATURE_TYPE "OPTIONAL")
set(DIRECTFB_FEATURE_PURPOSE "DirectFB")
set(DIRECTFB_FEATURE_DESCRIPTION "DirectFB client")
if(NOT APPLE)
find_suggested_package(XRandR)
find_suggested_package(Gstreamer)
if(NOT ANDROID)
find_suggested_package(ALSA)
endif()
endif()
set(ZLIB_FEATURE_TYPE "REQUIRED")
set(ZLIB_FEATURE_PURPOSE "compression")
set(ZLIB_FEATURE_DESCRIPTION "data compression")
if((NOT ANDROID) AND (NOT APPLE))
find_suggested_package(FFmpeg)
endif()
endif()
set(OPENSSL_FEATURE_TYPE "REQUIRED")
set(OPENSSL_FEATURE_PURPOSE "cryptography")
set(OPENSSL_FEATURE_DESCRIPTION "encryption, certificate validation, hashing functions")
set(ALSA_FEATURE_TYPE "RECOMMENDED")
set(ALSA_FEATURE_PURPOSE "sound")
set(ALSA_FEATURE_DESCRIPTION "audio input, audio output and multimedia redirection")
set(PULSE_FEATURE_TYPE "OPTIONAL")
set(PULSE_FEATURE_PURPOSE "sound")
set(PULSE_FEATURE_DESCRIPTION "audio input, audio output and multimedia redirection")
set(CUPS_FEATURE_TYPE "OPTIONAL")
set(CUPS_FEATURE_PURPOSE "printing")
set(CUPS_FEATURE_DESCRIPTION "printer device redirection")
set(PCSC_FEATURE_TYPE "OPTIONAL")
set(PCSC_FEATURE_PURPOSE "smart card")
set(PCSC_FEATURE_DESCRIPTION "smart card device redirection")
set(FFMPEG_FEATURE_TYPE "RECOMMENDED")
set(FFMPEG_FEATURE_PURPOSE "multimedia")
set(FFMPEG_FEATURE_DESCRIPTION "multimedia redirection, audio and video playback")
set(GSTREAMER_FEATURE_TYPE "RECOMMENDED")
set(GSTREAMER_FEATURE_PURPOSE "multimedia")
set(GSTREAMER_FEATURE_DESCRIPTION "multimedia redirection, audio and video playback")
if(WIN32)
set(CMAKE_INSTALL_BINDIR ${CMAKE_INSTALL_PREFIX})
set(CMAKE_INSTALL_LIBDIR ${CMAKE_INSTALL_PREFIX})
set(CMAKE_INSTALL_FULL_LIBDIR ${CMAKE_INSTALL_PREFIX})
set(X11_FEATURE_TYPE "DISABLED")
set(ZLIB_FEATURE_TYPE "DISABLED")
set(DIRECTFB_FEATURE_TYPE "DISABLED")
set(ALSA_FEATURE_TYPE "DISABLED")
set(PULSE_FEATURE_TYPE "DISABLED")
set(CUPS_FEATURE_TYPE "DISABLED")
set(PCSC_FEATURE_TYPE "DISABLED")
set(FFMPEG_FEATURE_TYPE "DISABLED")
set(GSTREAMER_FEATURE_TYPE "DISABLED")
endif()
if(APPLE)
set(DIRECTFB_FEATURE_TYPE "DISABLED")
set(FFMPEG_FEATURE_TYPE "OPTIONAL")
endif()
if(ANDROID)
set(X11_FEATURE_TYPE "DISABLED")
set(DIRECTFB_FEATURE_TYPE "DISABLED")
set(ALSA_FEATURE_TYPE "DISABLED")
set(PULSE_FEATURE_TYPE "DISABLED")
set(CUPS_FEATURE_TYPE "DISABLED")
set(PCSC_FEATURE_TYPE "DISABLED")
set(FFMPEG_FEATURE_TYPE "DISABLED")
set(GSTREAMER_FEATURE_TYPE "DISABLED")
endif()
if(IOS)
set(X11_FEATURE_TYPE "DISABLED")
set(DIRECTFB_FEATURE_TYPE "DISABLED")
set(ALSA_FEATURE_TYPE "DISABLED")
set(PULSE_FEATURE_TYPE "DISABLED")
set(CUPS_FEATURE_TYPE "DISABLED")
set(PCSC_FEATURE_TYPE "DISABLED")
set(FFMPEG_FEATURE_TYPE "DISABLED")
set(GSTREAMER_FEATURE_TYPE "DISABLED")
endif()
find_feature(X11 ${X11_FEATURE_TYPE} ${X11_FEATURE_PURPOSE} ${X11_FEATURE_DESCRIPTION})
find_feature(DirectFB ${DIRECTFB_FEATURE_TYPE} ${DIRECTFB_FEATURE_PURPOSE} ${DIRECTFB_FEATURE_DESCRIPTION})
find_feature(ZLIB ${ZLIB_FEATURE_TYPE} ${ZLIB_FEATURE_PURPOSE} ${ZLIB_FEATURE_DESCRIPTION})
find_feature(OpenSSL ${OPENSSL_FEATURE_TYPE} ${OPENSSL_FEATURE_PURPOSE} ${OPENSSL_FEATURE_DESCRIPTION})
find_feature(ALSA ${ALSA_FEATURE_TYPE} ${ALSA_FEATURE_PURPOSE} ${ALSA_FEATURE_DESCRIPTION})
find_feature(Pulse ${PULSE_FEATURE_TYPE} ${PULSE_FEATURE_PURPOSE} ${PULSE_FEATURE_DESCRIPTION})
find_feature(Cups ${CUPS_FEATURE_TYPE} ${CUPS_FEATURE_PURPOSE} ${CUPS_FEATURE_DESCRIPTION})
find_feature(PCSC ${PCSC_FEATURE_TYPE} ${PCSC_FEATURE_PURPOSE} ${PCSC_FEATURE_DESCRIPTION})
find_feature(FFmpeg ${FFMPEG_FEATURE_TYPE} ${FFMPEG_FEATURE_PURPOSE} ${FFMPEG_FEATURE_DESCRIPTION})
find_feature(Gstreamer ${GSTREAMER_FEATURE_TYPE} ${GSTREAMER_FEATURE_PURPOSE} ${GSTREAMER_FEATURE_DESCRIPTION})
# Installation Paths
if(WIN32)
set(CMAKE_INSTALL_BINDIR ".")
set(CMAKE_INSTALL_LIBDIR ".")
endif()
# Path to put FreeRDP data
@ -222,14 +291,10 @@ set(FREERDP_KEYMAP_PATH "${FREERDP_DATA_PATH}/keymaps")
# Path to put plugins
if(WIN32)
set(FREERDP_PLUGIN_PATH "${CMAKE_INSTALL_LIBDIR}")
else()
set(FREERDP_PLUGIN_PATH "${CMAKE_INSTALL_LIBDIR}/freerdp")
endif()
set(FREERDP_LIBRARY_PATH "${CMAKE_INSTALL_LIBDIR}")
set(FREERDP_CLIENT_PLUGIN_PATH "${FREERDP_PLUGIN_PATH}/client")
set(FREERDP_SERVER_PLUGIN_PATH "${FREERDP_PLUGIN_PATH}/server")
set(FREERDP_PLUGIN_PATH "${CMAKE_INSTALL_LIBDIR}/freerdp")
set(FREERDP_ADDIN_PATH "${FREERDP_PLUGIN_PATH}")
# Path to put extensions
set(FREERDP_EXTENSION_PATH "${CMAKE_INSTALL_FULL_LIBDIR}/freerdp/extensions")
@ -246,14 +311,19 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_SOURCE_DI
set(CMAKE_SKIP_BUILD_RPATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CMAKE_INSTALL_RPATH "\$ORIGIN/../${CMAKE_INSTALL_LIBDIR}")
set(CMAKE_INSTALL_RPATH "\$ORIGIN/../${CMAKE_INSTALL_LIBDIR}:\$ORIGIN/..")
# Unit Tests
INCLUDE(CTest)
include(CTest)
if(BUILD_TESTING)
find_package(Cmockery)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFREERDP_TEST_EXPORTS")
enable_testing()
if(MSVC)
set(TESTING_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
else()
@ -273,9 +343,6 @@ if(NOT MSVC)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/freerdp.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
endif()
# Intel Performance Primitives
#find_optional_package(IPP)
if(WITH_CUNIT)
message(FATAL_ERROR "cunit (WITH_CUNIT) is deprecated please use BUILD_TESTING to build ctest tests.
The cunit directory contains the old tests and is kept until all tests are converted.")
@ -311,14 +378,13 @@ endif()
set(CPACK_SOURCE_IGNORE_FILES "/\\\\.git/;/\\\\.gitignore;/CMakeCache.txt")
set(CPACK_PACKAGE_EXECUTABLES "xfreerdp")
if(WITH_SERVER)
set(CPACK_PACKAGE_EXECUTABLES ${CPACK_PACKAGE_EXECUTABLES} "xfreerdp-server")
if(NOT WIN32)
set(CPACK_PACKAGE_EXECUTABLES "xfreerdp")
if(WITH_SERVER)
set(CPACK_PACKAGE_EXECUTABLES ${CPACK_PACKAGE_EXECUTABLES} "xfreerdp-server")
endif()
endif()
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "FreeRDP: A Remote Desktop Protocol Implementation")
set(CPACK_SYSTEM_NAME "${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}")
set(CPACK_TOPLEVEL_TAG "${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}")
@ -332,9 +398,7 @@ set(CPACK_PACKAGE_VERSION ${FREERDP_VERSION_FULL})
set(CPACK_PACKAGE_VERSION_MAJOR ${FREERDP_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${FREERDP_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${FREERDP_VERSION_REVISION})
set(CPACK_SET_DESTDIR "on")
set(CPACK_PACKAGING_INSTALL_PREFIX "/tmp")
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "FreeRDP: A Remote Desktop Protocol Implementation")
set(CPACK_PACKAGE_CONTACT "Marc-Andre Moreau")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "marcandre.moreau@gmail.com")
@ -351,15 +415,30 @@ set(CPACK_NSIS_MUI_UNICON "${CMAKE_SOURCE_DIR}/resource\\\\FreeRDP_Icon_96px.ico
if(MSVC)
if(MSVC_RUNTIME STREQUAL "dynamic")
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE)
include(InstallRequiredSystemLibraries)
install(PROGRAMS ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS}
DESTINATION ${CMAKE_INSTALL_BINDIR}
COMPONENT libraries)
endif()
endif()
set(CPACK_COMPONENTS_ALL client server libraries headers)
set(CPACK_COMPONENT_CLIENT_DISPLAY_NAME "Client")
set(CPACK_COMPONENT_CLIENT_GROUP "Applications")
set(CPACK_COMPONENT_SERVER_DISPLAY_NAME "Server")
set(CPACK_COMPONENT_SERVER_GROUP "Applications")
set(CPACK_COMPONENT_LIBRARIES_DISPLAY_NAME "Libraries")
set(CPACK_COMPONENT_LIBRARIES_GROUP "Runtime")
set(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "Headers")
set(CPACK_COMPONENT_HEADERS_GROUP "Development")
set(CPACK_COMPONENT_GROUP_RUNTIME_DESCRIPTION "Runtime")
set(CPACK_COMPONENT_GROUP_APPLICATIONS_DESCRIPTION "Applications")
set(CPACK_COMPONENT_GROUP_DEVELOPMENT_DESCRIPTION "Development")
include(CPack)
cpack_add_component(headers DISPLAY_NAME "Headers")
cpack_add_component(libraries DISPLAY_NAME "Libraries")
cpack_add_component(clients DISPLAY_NAME "Clients")
set(CPACK_COMPONENTS_ALL clients libraries headers)

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})
@ -73,10 +94,11 @@ macro(define_channel_client_subsystem _channel_name _subsystem _type)
set(CHANNEL_NAME ${_channel_name})
set(CHANNEL_SUBSYSTEM ${_subsystem})
string(LENGTH "${_type}" _type_length)
string(TOUPPER "CHANNEL_${CHANNEL_NAME}_CLIENT" CHANNEL_PREFIX)
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)
@ -112,13 +134,31 @@ macro(add_channel_server _channel_prefix _channel_name)
endif()
endmacro(add_channel_server)
macro(add_channel_client_library _module_prefix _module_name _channel_name _plugin _entry)
macro(add_channel_client_subsystem _channel_prefix _channel_name _subsystem _type)
add_subdirectory(${_subsystem})
set(_channel_module_name "${_channel_name}-client")
string(LENGTH "${_type}" _type_length)
if(_type_length GREATER 0)
string(TOUPPER "CHANNEL_${_channel_name}_CLIENT_${_subsystem}_${_type}" _subsystem_prefix)
else()
string(TOUPPER "CHANNEL_${_channel_name}_CLIENT_${_subsystem}" _subsystem_prefix)
endif()
if(${${_subsystem_prefix}_STATIC})
get_target_property(CHANNEL_SUBSYSTEMS ${_channel_module_name} SUBSYSTEMS)
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)
if(${_plugin} AND MSVC AND (NOT STATIC_CHANNELS))
macro(add_channel_client_library _module_prefix _module_name _channel_name _dynamic _entry)
if(${_dynamic} AND MSVC AND (NOT STATIC_CHANNELS))
set(${_module_prefix}_SRCS ${${_module_prefix}_SRCS} module.def)
endif()
if(${_plugin} AND (NOT STATIC_CHANNELS))
if(${_dynamic} AND (NOT STATIC_CHANNELS))
add_library(${_module_name} ${${_module_prefix}_SRCS})
else()
set(${_module_prefix}_STATIC ON PARENT_SCOPE)
@ -127,16 +167,27 @@ macro(add_channel_client_library _module_prefix _module_name _channel_name _plug
set(${_module_prefix}_ENTRY ${_entry} PARENT_SCOPE)
add_library(${_module_name} STATIC ${${_module_prefix}_SRCS})
endif()
endmacro(add_channel_client_library)
macro(add_channel_server_library _module_prefix _module_name _channel_name _plugin _entry)
if(${_plugin} AND MSVC AND (NOT STATIC_CHANNELS))
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()
if(${_plugin} AND (NOT STATIC_CHANNELS))
if(${_dynamic} AND (NOT STATIC_CHANNELS))
add_library(${_module_name} ${${_module_prefix}_SRCS})
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)
macro(add_channel_server_library _module_prefix _module_name _channel_name _dynamic _entry)
if(${_dynamic} AND MSVC AND (NOT STATIC_CHANNELS))
set(${_module_prefix}_SRCS ${${_module_prefix}_SRCS} module.def)
endif()
if(${_dynamic} AND (NOT STATIC_CHANNELS))
add_library(${_module_name} ${${_module_prefix}_SRCS})
else()
set(${_module_prefix}_STATIC ON PARENT_SCOPE)
@ -145,7 +196,6 @@ macro(add_channel_server_library _module_prefix _module_name _channel_name _plug
set(${_module_prefix}_ENTRY ${_entry} PARENT_SCOPE)
add_library(${_module_name} STATIC ${${_module_prefix}_SRCS})
endif()
endmacro(add_channel_server_library)
set(FILENAME "ChannelOptions.cmake")

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})
@ -41,9 +41,9 @@ endif()
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")
if(WITH_ALSA)
add_subdirectory(alsa)
add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "alsa" "")
endif()
if(WITH_PULSE)
add_subdirectory(pulse)
add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "pulse" "")
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,4 +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

@ -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,36 +338,66 @@ static void audin_alsa_close(IAudinDevice* device)
alsa->user_data = NULL;
}
int FreeRDPAudinDeviceEntry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints)
COMMAND_LINE_ARGUMENT_A audin_alsa_args[] =
{
AudinALSADevice* alsa;
RDP_PLUGIN_DATA* data;
{ "audio-dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "audio device name" },
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
};
alsa = xnew(AudinALSADevice);
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;
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;
@ -374,4 +414,3 @@ int FreeRDPAudinDeviceEntry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints)
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
@ -58,7 +59,7 @@ struct _IAudinDevice
void (*Free) (IAudinDevice* devplugin);
};
#define AUDIN_DEVICE_EXPORT_FUNC_NAME "FreeRDPAudinDeviceEntry"
#define AUDIN_DEVICE_EXPORT_FUNC_NAME "freerdp_audin_client_subsystem_entry"
typedef void (*PREGISTERAUDINDEVICE)(IWTSPlugin* plugin, IAudinDevice* device);
@ -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_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} ${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

@ -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,12 +435,53 @@ static void audin_pulse_open(IAudinDevice* device, AudinReceive receive, void* u
}
}
int FreeRDPAudinDeviceEntry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints)
COMMAND_LINE_ARGUMENT_A audin_pulse_args[] =
{
AudinPulseDevice* pulse;
RDP_PLUGIN_DATA * data;
{ "audio-dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "audio device name" },
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
};
pulse = xnew(AudinPulseDevice);
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;
pulse = (AudinPulseDevice*) malloc(sizeof(AudinPulseDevice));
ZeroMemory(pulse, sizeof(AudinPulseDevice));
pulse->iface.Open = audin_pulse_open;
pulse->iface.FormatSupported = audin_pulse_format_supported;
@ -443,30 +489,35 @@ int FreeRDPAudinDeviceEntry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints)
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);
@ -477,4 +528,3 @@ int FreeRDPAudinDeviceEntry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints)
return 0;
}

View File

@ -25,10 +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/stream.h>
#include <freerdp/utils/wait_obj.h>
#include <freerdp/channels/wtsvc.h>
#include <freerdp/server/audin.h>
@ -134,7 +135,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)
@ -410,7 +413,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 +433,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

@ -26,9 +26,7 @@ set(${MODULE_PREFIX}_SRCS
list(REMOVE_DUPLICATES CHANNEL_STATIC_CLIENT_ENTRIES)
foreach(STATIC_ENTRY ${CHANNEL_STATIC_CLIENT_ENTRIES})
foreach(STATIC_MODULE ${CHANNEL_STATIC_CLIENT_MODULES})
if(${${STATIC_MODULE}_CLIENT_ENTRY} STREQUAL ${STATIC_ENTRY})
set(STATIC_MODULE_NAME ${${STATIC_MODULE}_CLIENT_NAME})
set(STATIC_MODULE_CHANNEL ${${STATIC_MODULE}_CLIENT_CHANNEL})
@ -39,26 +37,59 @@ foreach(STATIC_ENTRY ${CHANNEL_STATIC_CLIENT_ENTRIES})
set(${STATIC_ENTRY}_IMPORTS "${${STATIC_ENTRY}_IMPORTS}\n${ENTRY_POINT_IMPORT}")
set(${STATIC_ENTRY}_TABLE "${${STATIC_ENTRY}_TABLE}\n\t{ \"${STATIC_MODULE_CHANNEL}\", ${ENTRY_POINT_NAME} },")
endif()
endforeach()
endforeach()
set(CLIENT_STATIC_ENTRY_TABLES_LIST "${CLIENT_STATIC_ENTRY_TABLES_LIST}\nconst STATIC_ENTRY_TABLE CLIENT_STATIC_ENTRY_TABLES[] =\n{")
foreach(STATIC_ENTRY ${CHANNEL_STATIC_CLIENT_ENTRIES})
set(CLIENT_STATIC_ENTRY_IMPORTS "${CLIENT_STATIC_ENTRY_IMPORTS}\n${${STATIC_ENTRY}_IMPORTS}")
set(CLIENT_STATIC_ENTRY_TABLES "${CLIENT_STATIC_ENTRY_TABLES}\nconst STATIC_ENTRY CLIENT_${STATIC_ENTRY}_TABLE[] =\n{")
set(CLIENT_STATIC_ENTRY_TABLES "${CLIENT_STATIC_ENTRY_TABLES}\n${${STATIC_ENTRY}_TABLE}")
set(CLIENT_STATIC_ENTRY_TABLES "${CLIENT_STATIC_ENTRY_TABLES}\n\t{ \"\", NULL }\n};")
set(CLIENT_STATIC_ENTRY_TABLES_LIST "${CLIENT_STATIC_ENTRY_TABLES_LIST}\n\t{ \"${STATIC_ENTRY}\", CLIENT_${STATIC_ENTRY}_TABLE },")
endforeach()
set(CLIENT_STATIC_ENTRY_TABLES_LIST "${CLIENT_STATIC_ENTRY_TABLES_LIST}\n\t{ \"\", NULL }\n};")
set(CLIENT_STATIC_ADDIN_TABLE "const STATIC_ADDIN_TABLE CLIENT_STATIC_ADDIN_TABLE[] =\n{")
foreach(STATIC_MODULE ${CHANNEL_STATIC_CLIENT_MODULES})
set(STATIC_MODULE_NAME ${${STATIC_MODULE}_CLIENT_NAME})
set(STATIC_MODULE_CHANNEL ${${STATIC_MODULE}_CLIENT_CHANNEL})
string(TOUPPER "CLIENT_${STATIC_MODULE_CHANNEL}_SUBSYSTEM_TABLE" SUBSYSTEM_TABLE_NAME)
set(SUBSYSTEM_TABLE "const STATIC_SUBSYSTEM_ENTRY ${SUBSYSTEM_TABLE_NAME}[] =\n{")
get_target_property(CHANNEL_SUBSYSTEMS ${STATIC_MODULE_NAME} SUBSYSTEMS)
if(CHANNEL_SUBSYSTEMS MATCHES "NOTFOUND")
set(CHANNEL_SUBSYSTEMS "")
endif()
message(STATUS "Channel: ${STATIC_MODULE_CHANNEL} Subsystems: ${CHANNEL_SUBSYSTEMS}")
foreach(STATIC_SUBSYSTEM ${CHANNEL_SUBSYSTEMS})
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})
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()
set(SUBSYSTEM_TABLE "${SUBSYSTEM_TABLE}\n\t{ NULL, NULL, NULL }\n};")
set(CLIENT_STATIC_SUBSYSTEM_TABLES "${CLIENT_STATIC_SUBSYSTEM_TABLES}\n${SUBSYSTEM_TABLE}")
set(ENTRY_POINT_NAME "${STATIC_MODULE_CHANNEL}_${${STATIC_MODULE}_CLIENT_ENTRY}")
set(CLIENT_STATIC_ADDIN_TABLE "${CLIENT_STATIC_ADDIN_TABLE}\n\t{ \"${STATIC_MODULE_CHANNEL}\", ${ENTRY_POINT_NAME}, ${SUBSYSTEM_TABLE_NAME} },")
endforeach()
set(CLIENT_STATIC_ADDIN_TABLE "${CLIENT_STATIC_ADDIN_TABLE}\n\t{ NULL, NULL, NULL }\n};")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tables.c.in ${CMAKE_CURRENT_SOURCE_DIR}/tables.c)
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
@ -69,7 +100,7 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
MONOLITHIC ${MONOLITHIC_BUILD}
MODULE winpr
MODULES winpr-crt winpr-synch winpr-interlocked)
MODULES winpr-crt winpr-path winpr-file winpr-synch winpr-library winpr-interlocked)
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} PARENT_SCOPE)
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE)

View File

@ -34,15 +34,17 @@
#include <freerdp/client/channels.h>
#include <freerdp/channels/channels.h>
#include <freerdp/svc.h>
#include <freerdp/utils/memory.h>
#include <freerdp/addin.h>
#include <freerdp/utils/wait_obj.h>
#include <freerdp/utils/load_plugin.h>
#include <freerdp/utils/file.h>
#include <freerdp/utils/event.h>
#include <freerdp/utils/debug.h>
#include <winpr/crt.h>
#include <winpr/path.h>
#include <winpr/file.h>
#include <winpr/synch.h>
#include <winpr/library.h>
#include <winpr/interlocked.h>
#ifdef WITH_DEBUG_CHANNELS
@ -109,35 +111,262 @@ 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)
extern const STATIC_ADDIN_TABLE CLIENT_STATIC_ADDIN_TABLE[];
FREERDP_ADDIN** freerdp_channels_list_client_static_addins(LPSTR pszName, LPSTR pszSubsystem, LPSTR pszType, DWORD dwFlags)
{
char* path;
void* entry;
char* module;
int i, j;
DWORD nAddins;
FREERDP_ADDIN* pAddin;
FREERDP_ADDIN** ppAddins = NULL;
STATIC_SUBSYSTEM_ENTRY* subsystems;
module = freerdp_append_shared_library_suffix((char*) identifier);
path = freerdp_construct_path(FREERDP_CLIENT_PLUGIN_PATH, module);
nAddins = 0;
ppAddins = (FREERDP_ADDIN**) malloc(sizeof(FREERDP_ADDIN*) * 128);
ppAddins[nAddins] = NULL;
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)
for (i = 0; CLIENT_STATIC_ADDIN_TABLE[i].name != NULL; i++)
{
pChannelEntry = freerdp_channels_client_find_dynamic_entry(name, identifier);
pAddin = (FREERDP_ADDIN*) malloc(sizeof(FREERDP_ADDIN));
ZeroMemory(pAddin, sizeof(FREERDP_ADDIN));
strcpy(pAddin->cName, CLIENT_STATIC_ADDIN_TABLE[i].name);
pAddin->dwFlags = FREERDP_ADDIN_CLIENT;
pAddin->dwFlags |= FREERDP_ADDIN_STATIC;
pAddin->dwFlags |= FREERDP_ADDIN_NAME;
ppAddins[nAddins++] = pAddin;
subsystems = (STATIC_SUBSYSTEM_ENTRY*) CLIENT_STATIC_ADDIN_TABLE[i].table;
for (j = 0; subsystems[j].name != NULL; j++)
{
pAddin = (FREERDP_ADDIN*) malloc(sizeof(FREERDP_ADDIN));
ZeroMemory(pAddin, sizeof(FREERDP_ADDIN));
strcpy(pAddin->cName, CLIENT_STATIC_ADDIN_TABLE[i].name);
strcpy(pAddin->cSubsystem, subsystems[j].name);
pAddin->dwFlags = FREERDP_ADDIN_CLIENT;
pAddin->dwFlags |= FREERDP_ADDIN_STATIC;
pAddin->dwFlags |= FREERDP_ADDIN_NAME;
pAddin->dwFlags |= FREERDP_ADDIN_SUBSYSTEM;
ppAddins[nAddins++] = pAddin;
}
}
return pChannelEntry;
ppAddins[nAddins] = NULL;
return ppAddins;
}
LPCSTR gAddinPath = FREERDP_ADDIN_PATH;
LPCSTR gInstallPrefix = FREERDP_INSTALL_PREFIX;
FREERDP_ADDIN** freerdp_channels_list_dynamic_addins(LPSTR pszName, LPSTR pszSubsystem, LPSTR pszType, DWORD dwFlags)
{
int index;
int nDashes;
HANDLE hFind;
DWORD nAddins;
LPSTR pszPattern;
size_t cchPattern;
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);
pszExtension = PathGetSharedLibraryExtensionA(0);
cchPattern = 128 + strlen(pszExtension) + 2;
pszPattern = (LPSTR) malloc(cchPattern + 1);
if (pszName && pszSubsystem && pszType)
{
sprintf_s(pszPattern, cchPattern, "%s-client-%s-%s.%s", pszName, pszSubsystem, pszType, pszExtension);
}
else if (pszName && pszType)
{
sprintf_s(pszPattern, cchPattern, "%s-client-?-%s.%s", pszName, pszType, pszExtension);
}
else if (pszName)
{
sprintf_s(pszPattern, cchPattern, "%s-client*.%s", pszName, pszExtension);
}
else
{
sprintf_s(pszPattern, cchPattern, "?-client*.%s", pszExtension);
}
cchPattern = strlen(pszPattern);
cchSearchPath = cchInstallPrefix + cchAddinPath + cchPattern + 3;
pszSearchPath = (LPSTR) malloc(cchSearchPath + 1);
CopyMemory(pszSearchPath, gInstallPrefix, cchInstallPrefix);
pszSearchPath[cchInstallPrefix] = '\0';
NativePathCchAppendA(pszSearchPath, cchSearchPath + 1, gAddinPath);
NativePathCchAppendA(pszSearchPath, cchSearchPath + 1, pszPattern);
cchSearchPath = strlen(pszSearchPath);
hFind = FindFirstFileA(pszSearchPath, &FindData);
nAddins = 0;
ppAddins = (FREERDP_ADDIN**) malloc(sizeof(FREERDP_ADDIN*) * 128);
ppAddins[nAddins] = NULL;
if (hFind == INVALID_HANDLE_VALUE)
return ppAddins;
do
{
char* p[5];
FREERDP_ADDIN* pAddin;
nDashes = 0;
pAddin = (FREERDP_ADDIN*) malloc(sizeof(FREERDP_ADDIN));
ZeroMemory(pAddin, sizeof(FREERDP_ADDIN));
for (index = 0; FindData.cFileName[index]; index++)
nDashes += (FindData.cFileName[index] == '-') ? 1 : 0;
if (nDashes == 1)
{
/* <name>-client.<extension> */
p[0] = FindData.cFileName;
p[1] = strchr(p[0], '-') + 1;
strncpy(pAddin->cName, p[0], (p[1] - p[0]) - 1);
pAddin->dwFlags = FREERDP_ADDIN_CLIENT;
pAddin->dwFlags |= FREERDP_ADDIN_DYNAMIC;
pAddin->dwFlags |= FREERDP_ADDIN_NAME;
ppAddins[nAddins++] = pAddin;
}
else if (nDashes == 2)
{
/* <name>-client-<subsystem>.<extension> */
p[0] = FindData.cFileName;
p[1] = strchr(p[0], '-') + 1;
p[2] = strchr(p[1], '-') + 1;
p[3] = strchr(p[2], '.') + 1;
strncpy(pAddin->cName, p[0], (p[1] - p[0]) - 1);
strncpy(pAddin->cSubsystem, p[2], (p[3] - p[2]) - 1);
pAddin->dwFlags = FREERDP_ADDIN_CLIENT;
pAddin->dwFlags |= FREERDP_ADDIN_DYNAMIC;
pAddin->dwFlags |= FREERDP_ADDIN_NAME;
pAddin->dwFlags |= FREERDP_ADDIN_SUBSYSTEM;
ppAddins[nAddins++] = pAddin;
}
else if (nDashes == 3)
{
/* <name>-client-<subsystem>-<type>.<extension> */
p[0] = FindData.cFileName;
p[1] = strchr(p[0], '-') + 1;
p[2] = strchr(p[1], '-') + 1;
p[3] = strchr(p[2], '-') + 1;
p[4] = strchr(p[3], '.') + 1;
strncpy(pAddin->cName, p[0], (p[1] - p[0]) - 1);
strncpy(pAddin->cSubsystem, p[2], (p[3] - p[2]) - 1);
strncpy(pAddin->cType, p[3], (p[4] - p[3]) - 1);
pAddin->dwFlags = FREERDP_ADDIN_CLIENT;
pAddin->dwFlags |= FREERDP_ADDIN_DYNAMIC;
pAddin->dwFlags |= FREERDP_ADDIN_NAME;
pAddin->dwFlags |= FREERDP_ADDIN_SUBSYSTEM;
pAddin->dwFlags |= FREERDP_ADDIN_TYPE;
ppAddins[nAddins++] = pAddin;
}
else
{
free(pAddin);
}
}
while (FindNextFileA(hFind, &FindData));
FindClose(hFind);
ppAddins[nAddins] = NULL;
return ppAddins;
}
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(pszName, pszSubsystem, pszType, dwFlags);
else if (dwFlags & FREERDP_ADDIN_DYNAMIC)
return freerdp_channels_list_dynamic_addins(pszName, pszSubsystem, pszType, dwFlags);
return NULL;
}
void freerdp_channels_addin_list_free(FREERDP_ADDIN** ppAddins)
{
int index;
for (index = 0; ppAddins[index] != NULL; index++)
free(ppAddins[index]);
free(ppAddins);
}
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 (pszSubsystem != NULL)
{
subsystems = (STATIC_SUBSYSTEM_ENTRY*) CLIENT_STATIC_ADDIN_TABLE[i].table;
for (j = 0; subsystems[j].name != NULL; j++)
{
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
{
if (strcmp(CLIENT_STATIC_ADDIN_TABLE[i].name, pszName) == 0)
{
return (void*) CLIENT_STATIC_ADDIN_TABLE[i].entry;
}
}
}
return NULL;
}
struct lib_data
@ -319,13 +548,13 @@ static rdpChannel* freerdp_channels_find_channel_by_id(rdpChannels* channels, rd
int lcount;
rdpChannel* lrdp_channel;
lcount = settings->num_channels;
lcount = settings->ChannelCount;
for (lindex = 0; lindex < lcount; lindex++)
{
lrdp_channel = settings->channels + lindex;
lrdp_channel = settings->ChannelDefArray + lindex;
if (lrdp_channel->channel_id == channel_id)
if (lrdp_channel->ChannelId == channel_id)
{
if (pindex != 0)
*pindex = lindex;
@ -345,13 +574,13 @@ static rdpChannel* freerdp_channels_find_channel_by_name(rdpChannels* channels,
int lcount;
rdpChannel* lrdp_channel;
lcount = settings->num_channels;
lcount = settings->ChannelCount;
for (lindex = 0; lindex < lcount; lindex++)
{
lrdp_channel = settings->channels + lindex;
lrdp_channel = settings->ChannelDefArray + lindex;
if (strcmp(channel_name, lrdp_channel->name) == 0)
if (strcmp(channel_name, lrdp_channel->Name) == 0)
{
if (pindex != 0)
*pindex = lindex;
@ -449,12 +678,12 @@ static UINT32 FREERDP_CC MyVirtualChannelInit(void** ppInitHandle, PCHANNEL_DEF
strncpy(lchannel_data->name, lchannel_def->name, CHANNEL_NAME_LEN);
lchannel_data->options = lchannel_def->options;
if (channels->settings->num_channels < 16)
if (channels->settings->ChannelCount < 16)
{
lrdp_channel = channels->settings->channels + channels->settings->num_channels;
strncpy(lrdp_channel->name, lchannel_def->name, 7);
lrdp_channel = channels->settings->ChannelDefArray + channels->settings->ChannelCount;
strncpy(lrdp_channel->Name, lchannel_def->name, 7);
lrdp_channel->options = lchannel_def->options;
channels->settings->num_channels++;
channels->settings->ChannelCount++;
}
else
{
@ -699,7 +928,8 @@ 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);
@ -708,7 +938,8 @@ rdpChannels* freerdp_channels_new(void)
channels->signal = wait_obj_new();
/* 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);
@ -762,7 +993,7 @@ int freerdp_channels_client_load(rdpChannels* channels, rdpSettings* settings, v
if (channels->num_libs_data + 1 >= CHANNEL_MAX_COUNT)
{
DEBUG_CHANNELS("too many channels");
printf("error: too many channels\n");
return 1;
}
@ -796,7 +1027,7 @@ int freerdp_channels_client_load(rdpChannels* channels, rdpSettings* settings, v
if (!status)
{
DEBUG_CHANNELS("export function call failed");
printf("error: channel export function call failed\n");
return 1;
}
@ -813,7 +1044,7 @@ int freerdp_channels_load_plugin(rdpChannels* channels, rdpSettings* settings, c
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)
{
@ -886,7 +1117,7 @@ int freerdp_channels_post_connect(rdpChannels* channels, freerdp* instance)
struct lib_data* llib;
channels->is_connected = 1;
hostname = instance->settings->hostname;
hostname = instance->settings->ServerHostname;
hostname_len = strlen(hostname);
DEBUG_CHANNELS("hostname [%s] channels->num_libs [%d]", hostname, channels->num_libs_data);
@ -929,7 +1160,7 @@ int freerdp_channels_data(freerdp* instance, int channel_id, void* data, int dat
return 1;
}
lchannel_data = freerdp_channels_find_channel_data_by_name(channels, lrdp_channel->name, &index);
lchannel_data = freerdp_channels_find_channel_data_by_name(channels, lrdp_channel->Name, &index);
if (lchannel_data == 0)
{
@ -1017,7 +1248,7 @@ static void freerdp_channels_process_sync(rdpChannels* channels, freerdp* instan
lchannel_data->name, &item->Index);
if (lrdp_channel != NULL)
instance->SendChannelData(instance, lrdp_channel->channel_id, item->Data, item->DataLength);
instance->SendChannelData(instance, lrdp_channel->ChannelId, item->Data, item->DataLength);
if (lchannel_data->open_event_proc != 0)
{

View File

@ -25,4 +25,9 @@ ${CLIENT_STATIC_ENTRY_TABLES}
${CLIENT_STATIC_ENTRY_TABLES_LIST}
${CLIENT_STATIC_SUBSYSTEM_IMPORTS}
${CLIENT_STATIC_SUBSYSTEM_TABLES}
${CLIENT_STATIC_ADDIN_TABLE}

View File

@ -32,3 +32,19 @@ struct _STATIC_ENTRY_TABLE
const STATIC_ENTRY* table;
};
typedef struct _STATIC_ENTRY_TABLE STATIC_ENTRY_TABLE;
struct _STATIC_SUBSYSTEM_ENTRY
{
const char* name;
const char* type;
const void* entry;
};
typedef struct _STATIC_SUBSYSTEM_ENTRY STATIC_SUBSYSTEM_ENTRY;
struct _STATIC_ADDIN_TABLE
{
const char* name;
const void* entry;
const STATIC_SUBSYSTEM_ENTRY* table;
};
typedef struct _STATIC_ADDIN_TABLE STATIC_ADDIN_TABLE;

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

@ -31,7 +31,6 @@
#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>

View File

@ -30,7 +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>
@ -274,7 +273,7 @@ static void cliprdr_process_terminate(rdpSvcPlugin* plugin)
/* cliprdr is always built-in */
#define VirtualChannelEntry cliprdr_VirtualChannelEntry
const int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
{
cliprdrPlugin* _p;
@ -298,5 +297,3 @@ const int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
return 1;
}

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,19 @@
#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 <freerdp/utils/svc_plugin.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 +75,7 @@ static int drdynvc_write_variable_uint(STREAM* stream, UINT32 val)
cb = 2;
stream_write_UINT32(stream, val);
}
return cb;
}
@ -97,13 +97,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 +112,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 +126,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 +148,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 +163,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 +182,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 +190,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 +216,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 +258,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 +312,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 +352,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 +380,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");
@ -368,7 +393,7 @@ static void drdynvc_process_terminate(rdpSvcPlugin* plugin)
/* drdynvc is always built-in */
#define VirtualChannelEntry drdynvc_VirtualChannelEntry
const int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
{
drdynvcPlugin* _p;
@ -391,4 +416,3 @@ const 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

@ -15,8 +15,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
define_channel("disk")
define_channel("drive")
if(WITH_CLIENT_CHANNELS)
add_channel_client(${MODULE_PREFIX} ${CHANNEL_NAME})
endif()

View File

@ -8,12 +8,8 @@ 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 "disk" TYPE "device"
DESCRIPTION "Disk Redirection Virtual Channel Extension"
define_channel_options(NAME "drive" TYPE "device"
DESCRIPTION "Drive Redirection Virtual Channel Extension"
SPECIFICATIONS "[MS-RDPEFS]"
DEFAULT ${OPTION_DEFAULT})

View File

@ -15,13 +15,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
define_channel_client("disk")
define_channel_client("drive")
set(${MODULE_PREFIX}_SRCS
disk_file.c
disk_file.h
disk_main.c)
drive_file.c
drive_file.h
drive_main.c)
if(WIN32)
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS}
statvfs.c
@ -41,14 +41,12 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
MONOLITHIC ${MONOLITHIC_BUILD}
MODULE winpr
MODULES winpr-crt winpr-synch winpr-thread winpr-interlocked)
MODULES winpr-crt winpr-file winpr-synch winpr-thread winpr-interlocked)
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()
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")

View File

@ -39,8 +39,8 @@
#include <sys/stat.h>
#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>
@ -49,47 +49,19 @@
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include "disk_file.h"
#include "drive_file.h"
#ifdef _WIN32
#pragma warning(push)
#pragma warning(disable: 4244)
#endif
static BOOL disk_file_wildcard_match(const char* pattern, const char* filename)
{
const char *p = pattern, *f = filename;
char c;
/*
* TODO: proper wildcard rules per msft's File System Behavior Overview
* Simple cases for now.
*/
f = filename;
while ((c = *p++))
{
if (c == '*')
{
c = *p++;
if (!c) /* shortcut */
return TRUE;
/* TODO: skip to tail comparison */
}
if (c != *f++)
return FALSE;
}
if (!*f)
return TRUE;
return FALSE;
}
static void disk_file_fix_path(char* path)
static void drive_file_fix_path(char* path)
{
int i;
int length;
@ -114,19 +86,19 @@ static void disk_file_fix_path(char* path)
path[length - 1] = '\0';
}
static char* disk_file_combine_fullpath(const char* base_path, const char* path)
static char* drive_file_combine_fullpath(const char* base_path, const char* path)
{
char* fullpath;
fullpath = (char*) malloc(strlen(base_path) + strlen(path) + 1);
strcpy(fullpath, base_path);
strcat(fullpath, path);
disk_file_fix_path(fullpath);
drive_file_fix_path(fullpath);
return fullpath;
}
static BOOL disk_file_remove_dir(const char* path)
static BOOL drive_file_remove_dir(const char* path)
{
DIR* dir;
char* p;
@ -159,7 +131,7 @@ static BOOL disk_file_remove_dir(const char* path)
}
else if (S_ISDIR(st.st_mode))
{
ret = disk_file_remove_dir(p);
ret = drive_file_remove_dir(p);
}
else if (unlink(p) < 0)
{
@ -193,7 +165,7 @@ static BOOL disk_file_remove_dir(const char* path)
return ret;
}
static void disk_file_set_fullpath(DISK_FILE* file, char* fullpath)
static void drive_file_set_fullpath(DRIVE_FILE* file, char* fullpath)
{
free(file->fullpath);
file->fullpath = fullpath;
@ -205,7 +177,7 @@ static void disk_file_set_fullpath(DISK_FILE* file, char* fullpath)
file->filename += 1;
}
static BOOL disk_file_init(DISK_FILE* file, UINT32 DesiredAccess, UINT32 CreateDisposition, UINT32 CreateOptions)
static BOOL drive_file_init(DRIVE_FILE* file, UINT32 DesiredAccess, UINT32 CreateDisposition, UINT32 CreateOptions)
{
struct STAT st;
BOOL exists;
@ -221,8 +193,8 @@ static BOOL disk_file_init(DISK_FILE* file, UINT32 DesiredAccess, UINT32 CreateD
{
file->is_dir = (S_ISDIR(st.st_mode) ? TRUE : FALSE);
#ifndef WIN32
if (st.st_size > (unsigned long)0x07fffffff)
largeFile = TRUE;
if (st.st_size > (unsigned long) 0x07FFFFFFF)
largeFile = TRUE;
#endif
exists = TRUE;
}
@ -231,14 +203,14 @@ static BOOL disk_file_init(DISK_FILE* file, UINT32 DesiredAccess, UINT32 CreateD
file->is_dir = ((CreateOptions & FILE_DIRECTORY_FILE) ? TRUE : FALSE);
if (file->is_dir)
{
//Should only create the directory if the disposition allows for it
/* Should only create the directory if the disposition allows for it */
if ((CreateDisposition == FILE_OPEN_IF) || (CreateDisposition == FILE_CREATE))
{
if (mkdir(file->fullpath, mode) != 0)
{
file->err = errno;
return TRUE;
}
if (mkdir(file->fullpath, mode) != 0)
{
file->err = errno;
return TRUE;
}
}
}
exists = FALSE;
@ -247,6 +219,7 @@ static BOOL disk_file_init(DISK_FILE* file, UINT32 DesiredAccess, UINT32 CreateD
if (file->is_dir)
{
file->dir = opendir(file->fullpath);
if (file->dir == NULL)
{
file->err = errno;
@ -278,7 +251,7 @@ static BOOL disk_file_init(DISK_FILE* file, UINT32 DesiredAccess, UINT32 CreateD
break;
}
if (CreateOptions & FILE_DELETE_ON_CLOSE && DesiredAccess & DELETE)
if ((CreateOptions & FILE_DELETE_ON_CLOSE) && (DesiredAccess & DELETE))
{
file->delete_pending = TRUE;
}
@ -301,6 +274,7 @@ static BOOL disk_file_init(DISK_FILE* file, UINT32 DesiredAccess, UINT32 CreateD
}
#endif
file->fd = OPEN(file->fullpath, oflag, mode);
if (file->fd == -1)
{
file->err = errno;
@ -311,37 +285,40 @@ static BOOL disk_file_init(DISK_FILE* file, UINT32 DesiredAccess, UINT32 CreateD
return TRUE;
}
DISK_FILE* disk_file_new(const char* base_path, const char* path, UINT32 id,
DRIVE_FILE* drive_file_new(const char* base_path, const char* path, UINT32 id,
UINT32 DesiredAccess, UINT32 CreateDisposition, UINT32 CreateOptions)
{
DISK_FILE* file;
DRIVE_FILE* file;
file = (DRIVE_FILE*) malloc(sizeof(DRIVE_FILE));
ZeroMemory(file, sizeof(DRIVE_FILE));
file = xnew(DISK_FILE);
file->id = id;
file->basepath = (char*) base_path;
disk_file_set_fullpath(file, disk_file_combine_fullpath(base_path, path));
drive_file_set_fullpath(file, drive_file_combine_fullpath(base_path, path));
file->fd = -1;
if (!disk_file_init(file, DesiredAccess, CreateDisposition, CreateOptions))
if (!drive_file_init(file, DesiredAccess, CreateDisposition, CreateOptions))
{
disk_file_free(file);
drive_file_free(file);
return NULL;
}
return file;
}
void disk_file_free(DISK_FILE* file)
void drive_file_free(DRIVE_FILE* file)
{
if (file->fd != -1)
close(file->fd);
if (file->dir != NULL)
closedir(file->dir);
if (file->delete_pending)
{
if (file->is_dir)
disk_file_remove_dir(file->fullpath);
drive_file_remove_dir(file->fullpath);
else
unlink(file->fullpath);
}
@ -351,7 +328,7 @@ void disk_file_free(DISK_FILE* file)
free(file);
}
BOOL disk_file_seek(DISK_FILE* file, UINT64 Offset)
BOOL drive_file_seek(DRIVE_FILE* file, UINT64 Offset)
{
if (file->is_dir || file->fd == -1)
return FALSE;
@ -362,7 +339,7 @@ BOOL disk_file_seek(DISK_FILE* file, UINT64 Offset)
return TRUE;
}
BOOL disk_file_read(DISK_FILE* file, BYTE* buffer, UINT32* Length)
BOOL drive_file_read(DRIVE_FILE* file, BYTE* buffer, UINT32* Length)
{
ssize_t r;
@ -370,14 +347,16 @@ BOOL disk_file_read(DISK_FILE* file, BYTE* buffer, UINT32* Length)
return FALSE;
r = read(file->fd, buffer, *Length);
if (r < 0)
return FALSE;
*Length = (UINT32)r;
*Length = (UINT32) r;
return TRUE;
}
BOOL disk_file_write(DISK_FILE* file, BYTE* buffer, UINT32 Length)
BOOL drive_file_write(DRIVE_FILE* file, BYTE* buffer, UINT32 Length)
{
ssize_t r;
@ -387,8 +366,10 @@ BOOL disk_file_write(DISK_FILE* file, BYTE* buffer, UINT32 Length)
while (Length > 0)
{
r = write(file->fd, buffer, Length);
if (r == -1)
return FALSE;
Length -= r;
buffer += r;
}
@ -396,7 +377,7 @@ BOOL disk_file_write(DISK_FILE* file, BYTE* buffer, UINT32 Length)
return TRUE;
}
BOOL disk_file_query_information(DISK_FILE* file, UINT32 FsInformationClass, STREAM* output)
BOOL drive_file_query_information(DRIVE_FILE* file, UINT32 FsInformationClass, STREAM* output)
{
struct STAT st;
@ -405,6 +386,7 @@ BOOL disk_file_query_information(DISK_FILE* file, UINT32 FsInformationClass, STR
stream_write_UINT32(output, 0); /* Length */
return FALSE;
}
switch (FsInformationClass)
{
case FileBasicInformation:
@ -447,7 +429,7 @@ BOOL disk_file_query_information(DISK_FILE* file, UINT32 FsInformationClass, STR
return TRUE;
}
BOOL disk_file_set_information(DISK_FILE* file, UINT32 FsInformationClass, UINT32 Length, STREAM* input)
BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UINT32 Length, STREAM* input)
{
char* s;
@ -522,14 +504,14 @@ BOOL disk_file_set_information(DISK_FILE* file, UINT32 FsInformationClass, UINT3
freerdp_UnicodeToAsciiAlloc((WCHAR*) stream_get_tail(input), &s, FileNameLength / 2);
fullpath = disk_file_combine_fullpath(file->basepath, s);
fullpath = drive_file_combine_fullpath(file->basepath, s);
free(s);
/* TODO rename does not work on win32 */
if (rename(file->fullpath, fullpath) == 0)
{
DEBUG_SVC("renamed %s to %s", file->fullpath, fullpath);
disk_file_set_fullpath(file, fullpath);
drive_file_set_fullpath(file, fullpath);
}
else
{
@ -548,7 +530,7 @@ BOOL disk_file_set_information(DISK_FILE* file, UINT32 FsInformationClass, UINT3
return TRUE;
}
BOOL disk_file_query_directory(DISK_FILE* file, UINT32 FsInformationClass, BYTE InitialQuery,
BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYTE InitialQuery,
const char* path, STREAM* output)
{
int length;
@ -586,9 +568,11 @@ BOOL disk_file_query_directory(DISK_FILE* file, UINT32 FsInformationClass, BYTE
if (ent == NULL)
continue;
if (disk_file_wildcard_match(file->pattern, ent->d_name))
if (FilePatternMatchA(ent->d_name, file->pattern))
break;
} while (ent);
}
while (ent);
}
else
{

View File

@ -19,8 +19,8 @@
* limitations under the License.
*/
#ifndef __DISK_FILE_H
#define __DISK_FILE_H
#ifndef FREERDP_CHANNEL_DRIVE_FILE_H
#define FREERDP_CHANNEL_DRIVE_FILE_H
#include <sys/types.h>
#include <sys/stat.h>
@ -84,8 +84,9 @@ typedef UINT32 mode_t;
(_f->delete_pending ? FILE_ATTRIBUTE_TEMPORARY : 0) | \
(st.st_mode & S_IWUSR ? 0 : FILE_ATTRIBUTE_READONLY))
typedef struct _DISK_FILE DISK_FILE;
struct _DISK_FILE
typedef struct _DRIVE_FILE DRIVE_FILE;
struct _DRIVE_FILE
{
UINT32 id;
BOOL is_dir;
@ -99,16 +100,16 @@ struct _DISK_FILE
BOOL delete_pending;
};
DISK_FILE* disk_file_new(const char* base_path, const char* path, UINT32 id,
DRIVE_FILE* drive_file_new(const char* base_path, const char* path, UINT32 id,
UINT32 DesiredAccess, UINT32 CreateDisposition, UINT32 CreateOptions);
void disk_file_free(DISK_FILE* file);
void drive_file_free(DRIVE_FILE* file);
BOOL disk_file_seek(DISK_FILE* file, UINT64 Offset);
BOOL disk_file_read(DISK_FILE* file, BYTE* buffer, UINT32* Length);
BOOL disk_file_write(DISK_FILE* file, BYTE* buffer, UINT32 Length);
BOOL disk_file_query_information(DISK_FILE* file, UINT32 FsInformationClass, STREAM* output);
BOOL disk_file_set_information(DISK_FILE* file, UINT32 FsInformationClass, UINT32 Length, STREAM* input);
BOOL disk_file_query_directory(DISK_FILE* file, UINT32 FsInformationClass, BYTE InitialQuery,
BOOL drive_file_seek(DRIVE_FILE* file, UINT64 Offset);
BOOL drive_file_read(DRIVE_FILE* file, BYTE* buffer, UINT32* Length);
BOOL drive_file_write(DRIVE_FILE* file, BYTE* buffer, UINT32 Length);
BOOL drive_file_query_information(DRIVE_FILE* file, UINT32 FsInformationClass, STREAM* output);
BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UINT32 Length, STREAM* input);
BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYTE InitialQuery,
const char* path, STREAM* output);
#endif /* __DISK_FILE_H */
#endif /* FREERDP_CHANNEL_DRIVE_FILE_H */

View File

@ -35,7 +35,6 @@
#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>
@ -47,11 +46,11 @@
#include <winpr/thread.h>
#include <winpr/interlocked.h>
#include "disk_file.h"
#include "drive_file.h"
typedef struct _DISK_DEVICE DISK_DEVICE;
typedef struct _DRIVE_DEVICE DRIVE_DEVICE;
struct _DISK_DEVICE
struct _DRIVE_DEVICE
{
DEVICE device;
@ -66,7 +65,7 @@ struct _DISK_DEVICE
DEVMAN* devman;
};
static UINT32 disk_map_posix_err(int fs_errno)
static UINT32 drive_map_posix_err(int fs_errno)
{
UINT32 rc;
@ -101,14 +100,14 @@ static UINT32 disk_map_posix_err(int fs_errno)
return rc;
}
static DISK_FILE* disk_get_file_by_id(DISK_DEVICE* disk, UINT32 id)
static DRIVE_FILE* drive_get_file_by_id(DRIVE_DEVICE* disk, UINT32 id)
{
LIST_ITEM* item;
DISK_FILE* file;
DRIVE_FILE* file;
for (item = disk->files->head; item; item = item->next)
{
file = (DISK_FILE*) item->data;
file = (DRIVE_FILE*) item->data;
if (file->id == id)
return file;
@ -117,11 +116,11 @@ static DISK_FILE* disk_get_file_by_id(DISK_DEVICE* disk, UINT32 id)
return NULL;
}
static void disk_process_irp_create(DISK_DEVICE* disk, IRP* irp)
static void drive_process_irp_create(DRIVE_DEVICE* disk, IRP* irp)
{
char* path;
UINT32 FileId;
DISK_FILE* file;
DRIVE_FILE* file;
BYTE Information;
UINT32 DesiredAccess;
UINT32 CreateDisposition;
@ -138,7 +137,7 @@ static void disk_process_irp_create(DISK_DEVICE* disk, IRP* irp)
FileId = irp->devman->id_sequence++;
file = disk_file_new(disk->path, path, FileId,
file = drive_file_new(disk->path, path, FileId,
DesiredAccess, CreateDisposition, CreateOptions);
if (file == NULL)
@ -155,8 +154,8 @@ static void disk_process_irp_create(DISK_DEVICE* disk, IRP* irp)
Information = 0;
/* map errno to windows result */
irp->IoStatus = disk_map_posix_err(file->err);
disk_file_free(file);
irp->IoStatus = drive_map_posix_err(file->err);
drive_file_free(file);
}
else
{
@ -191,11 +190,11 @@ static void disk_process_irp_create(DISK_DEVICE* disk, IRP* irp)
irp->Complete(irp);
}
static void disk_process_irp_close(DISK_DEVICE* disk, IRP* irp)
static void drive_process_irp_close(DRIVE_DEVICE* disk, IRP* irp)
{
DISK_FILE* file;
DRIVE_FILE* file;
file = disk_get_file_by_id(disk, irp->FileId);
file = drive_get_file_by_id(disk, irp->FileId);
if (file == NULL)
{
@ -208,7 +207,7 @@ static void disk_process_irp_close(DISK_DEVICE* disk, IRP* irp)
DEBUG_SVC("%s(%d) closed.", file->fullpath, file->id);
list_remove(disk->files, file);
disk_file_free(file);
drive_file_free(file);
}
stream_write_zero(irp->output, 5); /* Padding(5) */
@ -216,9 +215,9 @@ static void disk_process_irp_close(DISK_DEVICE* disk, IRP* irp)
irp->Complete(irp);
}
static void disk_process_irp_read(DISK_DEVICE* disk, IRP* irp)
static void drive_process_irp_read(DRIVE_DEVICE* disk, IRP* irp)
{
DISK_FILE* file;
DRIVE_FILE* file;
UINT32 Length;
UINT64 Offset;
BYTE* buffer = NULL;
@ -226,7 +225,7 @@ static void disk_process_irp_read(DISK_DEVICE* disk, IRP* irp)
stream_read_UINT32(irp->input, Length);
stream_read_UINT64(irp->input, Offset);
file = disk_get_file_by_id(disk, irp->FileId);
file = drive_get_file_by_id(disk, irp->FileId);
if (file == NULL)
{
@ -235,7 +234,7 @@ static void disk_process_irp_read(DISK_DEVICE* disk, IRP* irp)
DEBUG_WARN("FileId %d not valid.", irp->FileId);
}
else if (!disk_file_seek(file, Offset))
else if (!drive_file_seek(file, Offset))
{
irp->IoStatus = STATUS_UNSUCCESSFUL;
Length = 0;
@ -245,7 +244,7 @@ static void disk_process_irp_read(DISK_DEVICE* disk, IRP* irp)
else
{
buffer = (BYTE*) malloc(Length);
if (!disk_file_read(file, buffer, &Length))
if (!drive_file_read(file, buffer, &Length))
{
irp->IoStatus = STATUS_UNSUCCESSFUL;
free(buffer);
@ -273,9 +272,9 @@ static void disk_process_irp_read(DISK_DEVICE* disk, IRP* irp)
irp->Complete(irp);
}
static void disk_process_irp_write(DISK_DEVICE* disk, IRP* irp)
static void drive_process_irp_write(DRIVE_DEVICE* disk, IRP* irp)
{
DISK_FILE* file;
DRIVE_FILE* file;
UINT32 Length;
UINT64 Offset;
@ -283,7 +282,7 @@ static void disk_process_irp_write(DISK_DEVICE* disk, IRP* irp)
stream_read_UINT64(irp->input, Offset);
stream_seek(irp->input, 20); /* Padding */
file = disk_get_file_by_id(disk, irp->FileId);
file = drive_get_file_by_id(disk, irp->FileId);
if (file == NULL)
{
@ -292,14 +291,14 @@ static void disk_process_irp_write(DISK_DEVICE* disk, IRP* irp)
DEBUG_WARN("FileId %d not valid.", irp->FileId);
}
else if (!disk_file_seek(file, Offset))
else if (!drive_file_seek(file, Offset))
{
irp->IoStatus = STATUS_UNSUCCESSFUL;
Length = 0;
DEBUG_WARN("seek %s(%d) failed.", file->fullpath, file->id);
}
else if (!disk_file_write(file, stream_get_tail(irp->input), Length))
else if (!drive_file_write(file, stream_get_tail(irp->input), Length))
{
irp->IoStatus = STATUS_UNSUCCESSFUL;
Length = 0;
@ -317,14 +316,14 @@ static void disk_process_irp_write(DISK_DEVICE* disk, IRP* irp)
irp->Complete(irp);
}
static void disk_process_irp_query_information(DISK_DEVICE* disk, IRP* irp)
static void drive_process_irp_query_information(DRIVE_DEVICE* disk, IRP* irp)
{
DISK_FILE* file;
DRIVE_FILE* file;
UINT32 FsInformationClass;
stream_read_UINT32(irp->input, FsInformationClass);
file = disk_get_file_by_id(disk, irp->FileId);
file = drive_get_file_by_id(disk, irp->FileId);
if (file == NULL)
{
@ -332,7 +331,7 @@ static void disk_process_irp_query_information(DISK_DEVICE* disk, IRP* irp)
DEBUG_WARN("FileId %d not valid.", irp->FileId);
}
else if (!disk_file_query_information(file, FsInformationClass, irp->output))
else if (!drive_file_query_information(file, FsInformationClass, irp->output))
{
irp->IoStatus = STATUS_UNSUCCESSFUL;
@ -346,9 +345,9 @@ static void disk_process_irp_query_information(DISK_DEVICE* disk, IRP* irp)
irp->Complete(irp);
}
static void disk_process_irp_set_information(DISK_DEVICE* disk, IRP* irp)
static void drive_process_irp_set_information(DRIVE_DEVICE* disk, IRP* irp)
{
DISK_FILE* file;
DRIVE_FILE* file;
UINT32 FsInformationClass;
UINT32 Length;
@ -356,7 +355,7 @@ static void disk_process_irp_set_information(DISK_DEVICE* disk, IRP* irp)
stream_read_UINT32(irp->input, Length);
stream_seek(irp->input, 24); /* Padding */
file = disk_get_file_by_id(disk, irp->FileId);
file = drive_get_file_by_id(disk, irp->FileId);
if (file == NULL)
{
@ -364,7 +363,7 @@ static void disk_process_irp_set_information(DISK_DEVICE* disk, IRP* irp)
DEBUG_WARN("FileId %d not valid.", irp->FileId);
}
else if (!disk_file_set_information(file, FsInformationClass, Length, irp->input))
else if (!drive_file_set_information(file, FsInformationClass, Length, irp->input))
{
irp->IoStatus = STATUS_UNSUCCESSFUL;
@ -380,7 +379,7 @@ static void disk_process_irp_set_information(DISK_DEVICE* disk, IRP* irp)
irp->Complete(irp);
}
static void disk_process_irp_query_volume_information(DISK_DEVICE* disk, IRP* irp)
static void drive_process_irp_query_volume_information(DRIVE_DEVICE* disk, IRP* irp)
{
UINT32 FsInformationClass;
STREAM* output = irp->output;
@ -466,10 +465,10 @@ static void disk_process_irp_query_volume_information(DISK_DEVICE* disk, IRP* ir
irp->Complete(irp);
}
static void disk_process_irp_query_directory(DISK_DEVICE* disk, IRP* irp)
static void drive_process_irp_query_directory(DRIVE_DEVICE* disk, IRP* irp)
{
char* path;
DISK_FILE* file;
DRIVE_FILE* file;
BYTE InitialQuery;
UINT32 PathLength;
UINT32 FsInformationClass;
@ -481,7 +480,7 @@ static void disk_process_irp_query_directory(DISK_DEVICE* disk, IRP* irp)
freerdp_UnicodeToAsciiAlloc((WCHAR*) stream_get_tail(irp->input), &path, PathLength / 2);
file = disk_get_file_by_id(disk, irp->FileId);
file = drive_get_file_by_id(disk, irp->FileId);
if (file == NULL)
{
@ -489,7 +488,7 @@ static void disk_process_irp_query_directory(DISK_DEVICE* disk, IRP* irp)
stream_write_UINT32(irp->output, 0); /* Length */
DEBUG_WARN("FileId %d not valid.", irp->FileId);
}
else if (!disk_file_query_directory(file, FsInformationClass, InitialQuery, path, irp->output))
else if (!drive_file_query_directory(file, FsInformationClass, InitialQuery, path, irp->output))
{
irp->IoStatus = STATUS_NO_MORE_FILES;
}
@ -499,12 +498,12 @@ static void disk_process_irp_query_directory(DISK_DEVICE* disk, IRP* irp)
irp->Complete(irp);
}
static void disk_process_irp_directory_control(DISK_DEVICE* disk, IRP* irp)
static void drive_process_irp_directory_control(DRIVE_DEVICE* disk, IRP* irp)
{
switch (irp->MinorFunction)
{
case IRP_MN_QUERY_DIRECTORY:
disk_process_irp_query_directory(disk, irp);
drive_process_irp_query_directory(disk, irp);
break;
case IRP_MN_NOTIFY_CHANGE_DIRECTORY: /* TODO */
@ -520,52 +519,52 @@ static void disk_process_irp_directory_control(DISK_DEVICE* disk, IRP* irp)
}
}
static void disk_process_irp_device_control(DISK_DEVICE* disk, IRP* irp)
static void drive_process_irp_device_control(DRIVE_DEVICE* disk, IRP* irp)
{
stream_write_UINT32(irp->output, 0); /* OutputBufferLength */
irp->Complete(irp);
}
static void disk_process_irp(DISK_DEVICE* disk, IRP* irp)
static void drive_process_irp(DRIVE_DEVICE* disk, IRP* irp)
{
irp->IoStatus = STATUS_SUCCESS;
switch (irp->MajorFunction)
{
case IRP_MJ_CREATE:
disk_process_irp_create(disk, irp);
drive_process_irp_create(disk, irp);
break;
case IRP_MJ_CLOSE:
disk_process_irp_close(disk, irp);
drive_process_irp_close(disk, irp);
break;
case IRP_MJ_READ:
disk_process_irp_read(disk, irp);
drive_process_irp_read(disk, irp);
break;
case IRP_MJ_WRITE:
disk_process_irp_write(disk, irp);
drive_process_irp_write(disk, irp);
break;
case IRP_MJ_QUERY_INFORMATION:
disk_process_irp_query_information(disk, irp);
drive_process_irp_query_information(disk, irp);
break;
case IRP_MJ_SET_INFORMATION:
disk_process_irp_set_information(disk, irp);
drive_process_irp_set_information(disk, irp);
break;
case IRP_MJ_QUERY_VOLUME_INFORMATION:
disk_process_irp_query_volume_information(disk, irp);
drive_process_irp_query_volume_information(disk, irp);
break;
case IRP_MJ_DIRECTORY_CONTROL:
disk_process_irp_directory_control(disk, irp);
drive_process_irp_directory_control(disk, irp);
break;
case IRP_MJ_DEVICE_CONTROL:
disk_process_irp_device_control(disk, irp);
drive_process_irp_device_control(disk, irp);
break;
default:
@ -576,7 +575,7 @@ static void disk_process_irp(DISK_DEVICE* disk, IRP* irp)
}
}
static void disk_process_irp_list(DISK_DEVICE* disk)
static void drive_process_irp_list(DRIVE_DEVICE* disk)
{
IRP* irp;
@ -590,13 +589,13 @@ static void disk_process_irp_list(DISK_DEVICE* disk)
if (irp == NULL)
break;
disk_process_irp(disk, irp);
drive_process_irp(disk, irp);
}
}
static void* disk_thread_func(void* arg)
static void* drive_thread_func(void* arg)
{
DISK_DEVICE* disk = (DISK_DEVICE*) arg;
DRIVE_DEVICE* disk = (DRIVE_DEVICE*) arg;
while (1)
{
@ -606,26 +605,26 @@ static void* disk_thread_func(void* arg)
break;
ResetEvent(disk->irpEvent);
disk_process_irp_list(disk);
drive_process_irp_list(disk);
}
return NULL;
}
static void disk_irp_request(DEVICE* device, IRP* irp)
static void drive_irp_request(DEVICE* device, IRP* irp)
{
DISK_DEVICE* disk = (DISK_DEVICE*) device;
DRIVE_DEVICE* disk = (DRIVE_DEVICE*) device;
InterlockedPushEntrySList(disk->pIrpList, &(irp->ItemEntry));
SetEvent(disk->irpEvent);
}
static void disk_free(DEVICE* device)
static void drive_free(DEVICE* device)
{
IRP* irp;
DISK_FILE* file;
DISK_DEVICE* disk = (DISK_DEVICE*) device;
DRIVE_FILE* file;
DRIVE_DEVICE* disk = (DRIVE_DEVICE*) device;
SetEvent(disk->stopEvent);
CloseHandle(disk->thread);
@ -636,17 +635,18 @@ static void disk_free(DEVICE* device)
_aligned_free(disk->pIrpList);
while ((file = (DISK_FILE*) list_dequeue(disk->files)) != NULL)
disk_file_free(file);
while ((file = (DRIVE_FILE*) list_dequeue(disk->files)) != NULL)
drive_file_free(file);
list_free(disk->files);
free(disk);
}
void disk_register_disk_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char* name, char* path)
void drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char* name, char* path)
{
int i, length;
DISK_DEVICE* disk;
DRIVE_DEVICE* disk;
#ifdef WIN32
/*
@ -664,12 +664,13 @@ void disk_register_disk_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char* na
if (name[0] && path[0])
{
disk = xnew(DISK_DEVICE);
disk = (DRIVE_DEVICE*) malloc(sizeof(DRIVE_DEVICE));
ZeroMemory(disk, sizeof(DRIVE_DEVICE));
disk->device.type = RDPDR_DTYP_FILESYSTEM;
disk->device.name = name;
disk->device.IRPRequest = disk_irp_request;
disk->device.Free = disk_free;
disk->device.IRPRequest = drive_irp_request;
disk->device.Free = drive_free;
length = strlen(name);
disk->device.data = stream_new(length + 1);
@ -685,7 +686,7 @@ void disk_register_disk_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char* na
disk->irpEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
disk->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
disk->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) disk_thread_func, disk, CREATE_SUSPENDED, NULL);
disk->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) drive_thread_func, disk, CREATE_SUSPENDED, NULL);
pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) disk);
@ -694,31 +695,33 @@ void disk_register_disk_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char* na
}
#ifdef STATIC_CHANNELS
#define DeviceServiceEntry disk_DeviceServiceEntry
#define DeviceServiceEntry drive_DeviceServiceEntry
#endif
const int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
{
char* name;
char* path;
RDPDR_DRIVE* drive;
#ifdef WIN32
char* dev;
int len;
char devlist[512], buf[512];
#endif
name = (char*) pEntryPoints->plugin_data->data[1];
path = (char*) pEntryPoints->plugin_data->data[2];
drive = (RDPDR_DRIVE*) pEntryPoints->device;
name = drive->Name;
path = drive->Path;
#ifndef WIN32
disk_register_disk_path(pEntryPoints, name, path);
drive_register_drive_path(pEntryPoints, name, path);
#else
/* Special case: path[0] == '*' -> export all drives */
/* Special case: path[0] == '%' -> user home dir */
if( path[0] == '%' )
{
_snprintf(buf, sizeof(buf), "%s\\", getenv("USERPROFILE"));
disk_register_disk_path(pEntryPoints, name, _strdup(buf));
drive_register_drive_path(pEntryPoints, name, _strdup(buf));
}
else if( path[0] == '*' )
{
@ -738,13 +741,13 @@ const int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
buf[len + 1] = dev[0];
buf[len + 2] = 0;
buf[len + 3] = 0;
disk_register_disk_path(pEntryPoints, _strdup(buf), _strdup(dev));
drive_register_drive_path(pEntryPoints, _strdup(buf), _strdup(dev));
}
}
}
else
{
disk_register_disk_path(pEntryPoints, name, path);
drive_register_drive_path(pEntryPoints, name, path);
}
#endif

View File

@ -1,3 +1,3 @@
LIBRARY "disk"
LIBRARY "drive"
EXPORTS
DeviceServiceEntry @1

View File

@ -1,6 +1,6 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* statvfs emulation für windows
* statvfs emulation for Windows
*
* Copyright 2012 Gerald Richter
*

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,7 +53,6 @@
#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>
@ -316,14 +315,17 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
char* name;
char* path;
int i, length;
RDPDR_PARALLEL* device;
PARALLEL_DEVICE* parallel;
name = (char*) pEntryPoints->plugin_data->data[1];
path = (char*) pEntryPoints->plugin_data->data[2];
device = (RDPDR_PARALLEL*) pEntryPoints->device;
name = device->Name;
path = device->Path;
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

@ -32,7 +32,6 @@
#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>
@ -247,7 +246,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;
@ -311,6 +311,7 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
char* driver_name;
rdpPrinter* printer;
rdpPrinter** printers;
RDPDR_PRINTER* device;
rdpPrinterDriver* driver = NULL;
#ifdef WITH_CUPS
@ -326,8 +327,9 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
return 1;
}
name = (char*) pEntryPoints->plugin_data->data[1];
driver_name = (char*) pEntryPoints->plugin_data->data[2];
device = (RDPDR_PRINTER*) pEntryPoints->device;
name = device->Name;
driver_name = device->DriverName;
if (name && name[0])
{

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)
@ -255,7 +252,7 @@ static void rail_process_event(rdpSvcPlugin* plugin, RDP_EVENT* event)
/* rail is always built-in */
#define VirtualChannelEntry rail_VirtualChannelEntry
const int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
{
railPlugin* _p;
@ -279,4 +276,3 @@ const 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

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

@ -26,22 +26,26 @@
#include <stdlib.h>
#include <string.h>
#include <winpr/crt.h>
#include <freerdp/types.h>
#include <freerdp/utils/memory.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"
#include "devman.h"
DEVMAN* devman_new(rdpSvcPlugin* plugin)
{
DEVMAN* devman;
devman = xnew(DEVMAN);
devman = (DEVMAN*) malloc(sizeof(DEVMAN));
ZeroMemory(devman, sizeof(DEVMAN));
devman->plugin = plugin;
devman->id_sequence = 1;
devman->devices = list_new();
@ -69,31 +73,41 @@ static void devman_register_device(DEVMAN* devman, DEVICE* device)
DEBUG_SVC("device %d.%s registered", device->id, device->name);
}
BOOL devman_load_device_service(DEVMAN* devman, RDP_PLUGIN_DATA* plugin_data)
static char DRIVE_SERVICE_NAME[] = "drive";
static char PRINTER_SERVICE_NAME[] = "printer";
static char SMARTCARD_SERVICE_NAME[] = "smartcard";
static char SERIAL_SERVICE_NAME[] = "serial";
static char PARALLEL_SERVICE_NAME[] = "parallel";
BOOL devman_load_device_service(DEVMAN* devman, RDPDR_DEVICE* device)
{
char* name;
char* ServiceName = NULL;
DEVICE_SERVICE_ENTRY_POINTS ep;
PDEVICE_SERVICE_ENTRY entry = NULL;
name = (char*) plugin_data->data[0];
entry = (PDEVICE_SERVICE_ENTRY) freerdp_channels_client_find_static_entry("DeviceServiceEntry", name);
if (device->Type == RDPDR_DTYP_FILESYSTEM)
ServiceName = DRIVE_SERVICE_NAME;
else if (device->Type == RDPDR_DTYP_PRINT)
ServiceName = PRINTER_SERVICE_NAME;
else if (device->Type == RDPDR_DTYP_SMARTCARD)
ServiceName = SMARTCARD_SERVICE_NAME;
else if (device->Type == RDPDR_DTYP_SERIAL)
ServiceName = SERIAL_SERVICE_NAME;
else if (device->Type == RDPDR_DTYP_PARALLEL)
ServiceName = PARALLEL_SERVICE_NAME;
if (!entry)
{
printf("loading device service %s (plugin)\n", name);
entry = freerdp_load_plugin(name, "DeviceServiceEntry");
}
else
{
printf("loading device service %s (static)\n", name);
}
if (!ServiceName)
return FALSE;
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;
ep.devman = devman;
ep.RegisterDevice = devman_register_device;
ep.plugin_data = plugin_data;
ep.device = device;
entry(&ep);

View File

@ -21,9 +21,10 @@
#ifndef FREERDP_CHANNEL_RDPDR_CLIENT_DEVMAN_H
#define FREERDP_CHANNEL_RDPDR_CLIENT_DEVMAN_H
DEVMAN* devman_new(rdpSvcPlugin* plugin);
void devman_free(DEVMAN* devman);
BOOL devman_load_device_service(DEVMAN* devman, RDP_PLUGIN_DATA* plugin_data);
BOOL devman_load_device_service(DEVMAN* devman, RDPDR_DEVICE* device);
DEVICE* devman_get_device_by_id(DEVMAN* devman, UINT32 id);
DEVMAN* devman_new(rdpSvcPlugin* plugin);
void devman_free(DEVMAN* devman);
#endif /* FREERDP_CHANNEL_RDPDR_CLIENT_DEVMAN_H */

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,7 +30,6 @@
#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>
@ -49,25 +48,20 @@
static void rdpdr_process_connect(rdpSvcPlugin* plugin)
{
int index;
RDPDR_DEVICE* device;
rdpSettings* settings;
rdpdrPlugin* rdpdr = (rdpdrPlugin*) plugin;
RDP_PLUGIN_DATA* data;
rdpdr->devman = devman_new(plugin);
data = (RDP_PLUGIN_DATA*) plugin->channel_entry_points.pExtendedData;
settings = (rdpSettings*) plugin->channel_entry_points.pExtendedData;
while (data && data->size > 0)
strncpy(rdpdr->computerName, settings->ComputerName, sizeof(rdpdr->computerName) - 1);
for (index = 0; index < settings->DeviceCount; index++)
{
if (strcmp((char*) data->data[0], "clientname") == 0)
{
strncpy(rdpdr->computerName, (char*) data->data[1], sizeof(rdpdr->computerName) - 1);
DEBUG_SVC("computerName %s", rdpdr->computerName);
}
else
{
devman_load_device_service(rdpdr->devman, data);
}
data = (RDP_PLUGIN_DATA*) (((BYTE*) data) + data->size);
device = settings->DeviceArray[index];
devman_load_device_service(rdpdr->devman, device);
}
}
@ -178,8 +172,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);
@ -319,7 +314,7 @@ static void rdpdr_process_terminate(rdpSvcPlugin* plugin)
/* rdpdr is always built-in */
#define VirtualChannelEntry rdpdr_VirtualChannelEntry
const int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
{
rdpdrPlugin* _p;

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,20 +29,24 @@ 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})
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")
if(WITH_ALSA)
add_subdirectory(alsa)
add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "alsa" "")
endif()
if(WITH_PULSE)
add_subdirectory(pulse)
add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "pulse" "")
endif()
if(WITH_MACAUDIO)
add_subdirectory(mac)
add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "mac" "")
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 "")
@ -32,8 +32,15 @@ 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})
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH})
if(NOT STATIC_CHANNELS)
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH})
endif()

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,12 +417,53 @@ static void rdpsnd_alsa_start(rdpsndDevicePlugin* device)
snd_pcm_start(alsa->out_handle);
}
int FreeRDPRdpsndDeviceEntry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints)
COMMAND_LINE_ARGUMENT_A rdpsnd_alsa_args[] =
{
rdpsndAlsaPlugin* alsa;
RDP_PLUGIN_DATA* data;
{ "dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "device" },
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
};
alsa = xnew(rdpsndAlsaPlugin);
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;
alsa = (rdpsndAlsaPlugin*) malloc(sizeof(rdpsndAlsaPlugin));
ZeroMemory(alsa, sizeof(rdpsndAlsaPlugin));
alsa->device.Open = rdpsnd_alsa_open;
alsa->device.FormatSupported = rdpsnd_alsa_format_supported;
@ -432,17 +474,8 @@ int FreeRDPRdpsndDeviceEntry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints)
alsa->device.Close = rdpsnd_alsa_close;
alsa->device.Free = rdpsnd_alsa_free;
data = pEntryPoints->plugin_data;
if (data && strcmp((char*) data->data[0], "alsa") == 0)
{
alsa->device_name = _strdup((char*) data->data[1]);
}
if (alsa->device_name == NULL)
{
alsa->device_name = _strdup("default");
}
args = pEntryPoints->args;
rdpsnd_alsa_parse_addin_args((rdpsndDevicePlugin*) alsa, args);
alsa->out_handle = 0;
alsa->source_rate = 22050;
@ -458,4 +491,3 @@ int FreeRDPRdpsndDeviceEntry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints)
return 0;
}

View File

@ -24,7 +24,7 @@ set(${MODULE_PREFIX}_SRCS
include_directories(..)
include_directories(${MACAUDIO_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 "")
@ -38,5 +38,6 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${MAC_COREFOUNDATION_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

@ -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>
@ -192,19 +193,22 @@ static void rdpsnd_audio_start(rdpsndDevicePlugin* device)
* our job here is to fill aq_buf_ref with audio data and enqueue it
*/
static void aq_playback_cb(void *user_data,
AudioQueueRef aq_ref,
AudioQueueBufferRef aq_buf_ref
)
static void aq_playback_cb(void* user_data, AudioQueueRef aq_ref, AudioQueueBufferRef aq_buf_ref)
{
}
int FreeRDPRdpsndDeviceEntry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints)
#ifdef STATIC_CHANNELS
#define freerdp_rdpsnd_client_subsystem_entry mac_freerdp_rdpsnd_client_subsystem_entry
#endif
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;
@ -215,15 +219,14 @@ int FreeRDPRdpsndDeviceEntry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints)
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(strlen((char *)data->data[1]) > 0)
aqPlugin->device_name = strdup((char *)data->data[1]);
else
aqPlugin->device_name = NULL;
if (args->argc > 2)
{
/* TODO: parse device name */
}
pEntryPoints->pRegisterRdpsndDevice(pEntryPoints->rdpsnd, (rdpsndDevicePlugin*)aqPlugin);
pEntryPoints->pRegisterRdpsndDevice(pEntryPoints->rdpsnd, (rdpsndDevicePlugin*) aqPlugin);
return 0;
}

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,6 @@ 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,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,12 +523,54 @@ static void rdpsnd_pulse_start(rdpsndDevicePlugin* device)
pa_stream_trigger(pulse->stream, NULL, NULL);
}
int FreeRDPRdpsndDeviceEntry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints)
COMMAND_LINE_ARGUMENT_A rdpsnd_pulse_args[] =
{
rdpsndPulsePlugin* pulse;
RDP_PLUGIN_DATA* data;
{ "dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "device" },
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
};
pulse = xnew(rdpsndPulsePlugin);
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;
pulse = (rdpsndPulsePlugin*) malloc(sizeof(rdpsndPulsePlugin));
ZeroMemory(pulse, sizeof(rdpsndPulsePlugin));
pulse->device.Open = rdpsnd_pulse_open;
pulse->device.FormatSupported = rdpsnd_pulse_format_supported;
@ -539,15 +581,8 @@ int FreeRDPRdpsndDeviceEntry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints)
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);
@ -357,7 +361,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);
@ -444,67 +450,114 @@ 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_");
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)
{
DEBUG_WARN("%s entry returns error.", name);
return FALSE;
}
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");
@ -513,42 +566,40 @@ 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 == NULL)
{
DEBUG_WARN("no sound device.");
@ -575,6 +626,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);
@ -583,7 +640,7 @@ static void rdpsnd_process_terminate(rdpSvcPlugin* plugin)
/* rdpsnd is always built-in */
#define VirtualChannelEntry rdpsnd_VirtualChannelEntry
const int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
{
rdpsndPlugin* _p;

View File

@ -47,7 +47,7 @@ struct rdpsnd_device_plugin
pcFree Free;
};
#define RDPSND_DEVICE_EXPORT_FUNC_NAME "FreeRDPRdpsndDeviceEntry"
#define RDPSND_DEVICE_EXPORT_FUNC_NAME "freerdp_rdpsnd_client_subsystem_entry"
typedef void (*PREGISTERRDPSNDDEVICE)(rdpsndPlugin* rdpsnd, rdpsndDevicePlugin* device);
@ -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;
@ -63,4 +63,3 @@ typedef FREERDP_RDPSND_DEVICE_ENTRY_POINTS* PFREERDP_RDPSND_DEVICE_ENTRY_POINTS;
typedef int (*PFREERDP_RDPSND_DEVICE_ENTRY)(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints);
#endif /* __RDPSND_MAIN_H */

View File

@ -27,9 +27,8 @@
#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>
@ -109,6 +108,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)
@ -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"
@ -136,7 +134,7 @@ static void sample_process_terminate(rdpSvcPlugin* plugin)
#define VirtualChannelEntry sample_VirtualChannelEntry
const int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
{
samplePlugin* _p;

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

@ -397,49 +397,6 @@ static void serial_free(DEVICE* device)
free(serial);
}
#ifdef STATIC_CHANNELS
#define DeviceServiceEntry serial_DeviceServiceEntry
#endif
int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
{
int i, len;
char* name;
char* path;
SERIAL_DEVICE* serial;
name = (char*) pEntryPoints->plugin_data->data[1];
path = (char*) pEntryPoints->plugin_data->data[2];
if (name[0] && path[0])
{
serial = xnew(SERIAL_DEVICE);
serial->device.type = RDPDR_DTYP_SERIAL;
serial->device.name = name;
serial->device.IRPRequest = serial_irp_request;
serial->device.Free = serial_free;
len = strlen(name);
serial->device.data = stream_new(len + 1);
for (i = 0; i <= len; i++)
stream_write_BYTE(serial->device.data, name[i] < 0 ? '_' : name[i]);
serial->path = path;
serial->irp_list = list_new();
serial->pending_irps = list_new();
serial->thread = freerdp_thread_new();
serial->in_event = wait_obj_new();
pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*)serial);
freerdp_thread_start(serial->thread, serial_thread_func, serial);
}
return 0;
}
static void serial_abort_single_io(SERIAL_DEVICE* serial, UINT32 file_id, UINT32 abort_io, UINT32 io_status)
{
IRP* irp = NULL;
@ -732,3 +689,49 @@ static BOOL serial_check_fds(SERIAL_DEVICE* serial)
return 1;
}
#ifdef STATIC_CHANNELS
#define DeviceServiceEntry serial_DeviceServiceEntry
#endif
int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
{
int i, len;
char* name;
char* path;
RDPDR_SERIAL* device;
SERIAL_DEVICE* serial;
device = (RDPDR_SERIAL*) pEntryPoints->device;
name = device->Name;
path = device->Path;
if (name[0] && path[0])
{
serial = (SERIAL_DEVICE*) malloc(sizeof(SERIAL_DEVICE));
ZeroMemory(serial, sizeof(SERIAL_DEVICE));
serial->device.type = RDPDR_DTYP_SERIAL;
serial->device.name = name;
serial->device.IRPRequest = serial_irp_request;
serial->device.Free = serial_free;
len = strlen(name);
serial->device.data = stream_new(len + 1);
for (i = 0; i <= len; i++)
stream_write_BYTE(serial->device.data, name[i] < 0 ? '_' : name[i]);
serial->path = path;
serial->irp_list = list_new();
serial->pending_irps = list_new();
serial->thread = freerdp_thread_new();
serial->in_event = wait_obj_new();
pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*)serial);
freerdp_thread_start(serial->thread, serial_thread_func, serial);
}
return 0;
}

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 <freerdp/utils/unicode.h>
#include <freerdp/utils/list.h>
@ -467,31 +468,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 +509,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 +986,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

@ -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);
@ -174,7 +176,7 @@ static void wts_read_drdynvc_create_response(rdpPeerChannel* channel, STREAM* s,
if ((INT32) CreationStatus < 0)
{
DEBUG_DVC("ChannelId %d creation failed (%d)", channel->channel_id, (INT32)CreationStatus);
DEBUG_DVC("ChannelId %d creation failed (%d)", channel->channel_id, (INT32) CreationStatus);
channel->dvc_open_state = DVC_OPEN_STATE_FAILED;
}
else
@ -388,14 +390,14 @@ static int WTSReceiveChannelData(freerdp_peer* client, int channelId, BYTE* data
BOOL result = FALSE;
rdpPeerChannel* channel;
for (i = 0; i < client->settings->num_channels; i++)
for (i = 0; i < client->settings->ChannelCount; i++)
{
if (client->settings->channels[i].channel_id == channelId)
if (client->settings->ChannelDefArray[i].ChannelId == channelId)
break;
}
if (i < client->settings->num_channels)
if (i < client->settings->ChannelCount)
{
channel = (rdpPeerChannel*) client->settings->channels[i].handle;
channel = (rdpPeerChannel*) client->settings->ChannelDefArray[i].handle;
if (channel != NULL)
{
@ -411,10 +413,12 @@ 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_queue = list_new();
@ -535,11 +539,13 @@ 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->vc_chunk_size);
channel->receive_data = stream_new(client->settings->VirtualChannelChunkSize);
channel->receive_event = wait_obj_new();
channel->receive_queue = list_new();
channel->mutex = CreateMutex(NULL, FALSE, NULL);
@ -563,34 +569,36 @@ void* WTSVirtualChannelOpenEx(
if (len > 8)
return NULL;
for (i = 0; i < client->settings->num_channels; i++)
for (i = 0; i < client->settings->ChannelCount; i++)
{
if (client->settings->channels[i].joined &&
strncmp(client->settings->channels[i].name, pVirtualName, len) == 0)
if (client->settings->ChannelDefArray[i].joined &&
strncmp(client->settings->ChannelDefArray[i].Name, pVirtualName, len) == 0)
{
break;
}
}
if (i >= client->settings->num_channels)
if (i >= client->settings->ChannelCount)
return NULL;
channel = (rdpPeerChannel*) client->settings->channels[i].handle;
channel = (rdpPeerChannel*) client->settings->ChannelDefArray[i].handle;
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->channels[i].channel_id;
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->vc_chunk_size);
channel->receive_data = stream_new(client->settings->VirtualChannelChunkSize);
channel->receive_event = wait_obj_new();
channel->receive_queue = list_new();
channel->mutex = CreateMutex(NULL, FALSE, NULL);
client->settings->channels[i].handle = channel;
client->settings->ChannelDefArray[i].handle = channel;
}
}
@ -718,7 +726,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,9 +747,11 @@ BOOL WTSVirtualChannelWrite(
while (Length > 0)
{
item = xnew(wts_data_item);
item->buffer = malloc(channel->client->settings->vc_chunk_size);
stream_attach(s, item->buffer, channel->client->settings->vc_chunk_size);
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);
stream_seek_BYTE(s);
cbChId = wts_write_variable_uint(s, channel->channel_id);
@ -791,8 +803,8 @@ BOOL WTSVirtualChannelClose(
if (channel->channel_type == RDP_PEER_CHANNEL_TYPE_SVC)
{
if (channel->index < channel->client->settings->num_channels)
channel->client->settings->channels[channel->index].handle = NULL;
if (channel->index < channel->client->settings->ChannelCount)
channel->client->settings->ChannelDefArray[channel->index].handle = NULL;
}
else
{

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

@ -1,332 +0,0 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Smartcard Device Service Virtual Channel
*
* Copyright 2011 O.S. Systems Software Ltda.
* Copyright 2011 Eduardo Fiss Beloni <beloni@ossystems.com.br>
* Copyright 2011 Anthony Tong <atong@trustedcs.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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <freerdp/utils/list.h>
#include <freerdp/utils/thread.h>
#include <freerdp/utils/svc_plugin.h>
#include <freerdp/utils/debug.h>
#include <freerdp/channels/rdpdr.h>
#include "scard_main.h"
static void scard_free(DEVICE* dev)
{
IRP* irp;
COMPLETIONIDINFO* CompletionIdInfo;
SCARD_DEVICE* scard = (SCARD_DEVICE*) dev;
freerdp_thread_stop(scard->thread);
freerdp_thread_free(scard->thread);
while ((irp = (IRP*) InterlockedPopEntrySList(scard->pIrpList)) != NULL)
irp->Discard(irp);
_aligned_free(scard->pIrpList);
/* Begin TS Client defect workaround. */
while ((CompletionIdInfo = (COMPLETIONIDINFO*) list_dequeue(scard->CompletionIds)) != NULL)
free(CompletionIdInfo);
list_free(scard->CompletionIds);
/* End TS Client defect workaround. */
free(dev);
return;
}
static void scard_process_irp(SCARD_DEVICE* scard, IRP* irp)
{
switch (irp->MajorFunction)
{
case IRP_MJ_DEVICE_CONTROL:
scard_device_control(scard, irp);
break;
default:
printf("MajorFunction 0x%X unexpected for smartcards.", irp->MajorFunction);
DEBUG_WARN("Smartcard MajorFunction 0x%X not supported.", irp->MajorFunction);
irp->IoStatus = STATUS_NOT_SUPPORTED;
irp->Complete(irp);
break;
}
}
static void scard_process_irp_list(SCARD_DEVICE* scard)
{
IRP* irp;
while (!freerdp_thread_is_stopped(scard->thread))
{
irp = (IRP*) InterlockedPopEntrySList(scard->pIrpList);
if (irp == NULL)
break;
scard_process_irp(scard, irp);
}
}
struct scard_irp_thread_args
{
SCARD_DEVICE* scard;
IRP* irp;
freerdp_thread* thread;
};
static void scard_process_irp_thread_func(struct scard_irp_thread_args* args)
{
scard_process_irp(args->scard, args->irp);
freerdp_thread_free(args->thread);
free(args);
}
static void* scard_thread_func(void* arg)
{
SCARD_DEVICE* scard = (SCARD_DEVICE*) arg;
while (1)
{
freerdp_thread_wait(scard->thread);
if (freerdp_thread_is_stopped(scard->thread))
break;
freerdp_thread_reset(scard->thread);
scard_process_irp_list(scard);
}
freerdp_thread_quit(scard->thread);
return NULL;
}
/* Begin TS Client defect workaround. */
static COMPLETIONIDINFO* scard_mark_duplicate_id(SCARD_DEVICE* scard, UINT32 CompletionId)
{
/*
* 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)
{
CompletionIdInfo = (COMPLETIONIDINFO*)item->data;
if (CompletionIdInfo->ID == CompletionId)
{
if (FALSE == CompletionIdInfo->duplicate)
{
CompletionIdInfo->duplicate = TRUE;
DEBUG_WARN("CompletionID number %u is now marked as a duplicate.", CompletionId);
}
return CompletionIdInfo;
}
}
return NULL; /* Either no items in the list or no match. */
}
static BOOL scard_check_for_duplicate_id(SCARD_DEVICE* scard, UINT32 CompletionId)
{
/*
* 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)
{
CompletionIdInfo = (COMPLETIONIDINFO*)item->data;
if (CompletionIdInfo->ID == CompletionId)
{
duplicate = CompletionIdInfo->duplicate;
if (TRUE == duplicate)
{
DEBUG_WARN("CompletionID number %u was previously marked as a duplicate. The response to the command is removed.", CompletionId);
}
list_remove(scard->CompletionIds, CompletionIdInfo);
free(CompletionIdInfo);
return duplicate;
}
}
/* This function should only be called when there is
* at least one outstanding CompletionID item in the list.
*/
DEBUG_WARN("Error!!! No CompletionIDs (or no matching IDs) in the list!");
return FALSE;
}
static void scard_irp_complete(IRP* irp)
{
/* 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.
*/
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);
pos = stream_get_pos(irp->output);
stream_set_pos(irp->output, 12);
stream_write_UINT32(irp->output, irp->IoStatus);
stream_set_pos(irp->output, pos);
/* Begin TS Client defect workaround. */
WaitForSingleObject(scard->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);
if (FALSE == 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
* and so is not available to be called
* here. Instead, call it indirectly by calling
* the IRP's "Discard()" function,
* which has already been assigned
* to point to "irp_free()" in "irp_new()".
*/
irp->Discard(irp);
}
/* End TS Client defect workaround. */
static void scard_irp_request(DEVICE* device, IRP* irp)
{
COMPLETIONIDINFO* CompletionIdInfo;
SCARD_DEVICE* scard = (SCARD_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()".
*/
/* End TS Client defect workaround. */
if (irp->MajorFunction == IRP_MJ_DEVICE_CONTROL &&
scard_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));
args->thread = freerdp_thread_new();
args->scard = scard;
args->irp = irp;
freerdp_thread_start(args->thread, scard_process_irp_thread_func, args);
return;
}
InterlockedPushEntrySList(scard->pIrpList, &(irp->ItemEntry));
freerdp_thread_signal(scard->thread);
}
#ifdef STATIC_CHANNELS
#define DeviceServiceEntry smartcard_DeviceServiceEntry
#endif
int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
{
char* name;
char* path;
int i, length;
SCARD_DEVICE* scard;
name = (char*) pEntryPoints->plugin_data->data[1];
path = (char*) pEntryPoints->plugin_data->data[2];
if (name)
{
/* TODO: check if server supports sc redirect (version 5.1) */
scard = xnew(SCARD_DEVICE);
scard->device.type = RDPDR_DTYP_SMARTCARD;
scard->device.name = "SCARD";
scard->device.IRPRequest = scard_irp_request;
scard->device.Free = scard_free;
length = strlen(scard->device.name);
scard->device.data = stream_new(length + 1);
for (i = 0; i <= length; i++)
stream_write_BYTE(scard->device.data, name[i] < 0 ? '_' : name[i]);
scard->path = path;
scard->pIrpList = (PSLIST_HEADER) _aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT);
InitializeSListHead(scard->pIrpList);
scard->thread = freerdp_thread_new();
scard->CompletionIds = list_new();
scard->CompletionIdsMutex = CreateMutex(NULL, FALSE, NULL);
pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE *)scard);
freerdp_thread_start(scard->thread, scard_thread_func, scard);
}
return 0;
}

View File

@ -0,0 +1,353 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Smartcard Device Service Virtual Channel
*
* Copyright 2011 O.S. Systems Software Ltda.
* Copyright 2011 Eduardo Fiss Beloni <beloni@ossystems.com.br>
* Copyright 2011 Anthony Tong <atong@trustedcs.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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winpr/crt.h>
#include <freerdp/utils/list.h>
#include <freerdp/utils/debug.h>
#include <freerdp/utils/svc_plugin.h>
#include <freerdp/channels/rdpdr.h>
#include "smartcard_main.h"
static void smartcard_free(DEVICE* dev)
{
IRP* irp;
COMPLETIONIDINFO* CompletionIdInfo;
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) dev;
SetEvent(smartcard->stopEvent);
CloseHandle(smartcard->thread);
CloseHandle(smartcard->irpEvent);
while ((irp = (IRP*) InterlockedPopEntrySList(smartcard->pIrpList)) != NULL)
irp->Discard(irp);
_aligned_free(smartcard->pIrpList);
/* Begin TS Client defect workaround. */
while ((CompletionIdInfo = (COMPLETIONIDINFO*) list_dequeue(smartcard->CompletionIds)) != NULL)
free(CompletionIdInfo);
list_free(smartcard->CompletionIds);
/* End TS Client defect workaround. */
free(dev);
}
static void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
{
switch (irp->MajorFunction)
{
case IRP_MJ_DEVICE_CONTROL:
smartcard_device_control(smartcard, irp);
break;
default:
printf("MajorFunction 0x%X unexpected for smartcards.", irp->MajorFunction);
DEBUG_WARN("Smartcard MajorFunction 0x%X not supported.", irp->MajorFunction);
irp->IoStatus = STATUS_NOT_SUPPORTED;
irp->Complete(irp);
break;
}
}
static void smartcard_process_irp_list(SMARTCARD_DEVICE* smartcard)
{
IRP* irp;
while (1)
{
if (WaitForSingleObject(smartcard->stopEvent, 0) == WAIT_OBJECT_0)
break;
irp = (IRP*) InterlockedPopEntrySList(smartcard->pIrpList);
if (irp == NULL)
break;
smartcard_process_irp(smartcard, irp);
}
}
struct _SMARTCARD_IRP_WORKER
{
SMARTCARD_DEVICE* smartcard;
IRP* irp;
HANDLE thread;
};
typedef struct _SMARTCARD_IRP_WORKER SMARTCARD_IRP_WORKER;
static void smartcard_process_irp_thread_func(SMARTCARD_IRP_WORKER* irpWorker)
{
smartcard_process_irp(irpWorker->smartcard, irpWorker->irp);
CloseHandle(irpWorker->thread);
free(irpWorker);
}
static void* smartcard_thread_func(void* arg)
{
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) arg;
while (1)
{
WaitForSingleObject(smartcard->irpEvent, INFINITE);
if (WaitForSingleObject(smartcard->stopEvent, 0) == WAIT_OBJECT_0)
break;
ResetEvent(smartcard->irpEvent);
smartcard_process_irp_list(smartcard);
}
return NULL;
}
/* Begin TS Client defect workaround. */
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.
*/
for (item = smartcard->CompletionIds->head; item; item = item->next)
{
CompletionIdInfo = (COMPLETIONIDINFO*) item->data;
if (CompletionIdInfo->ID == CompletionId)
{
if (!CompletionIdInfo->duplicate)
{
CompletionIdInfo->duplicate = TRUE;
DEBUG_WARN("CompletionID number %u is now marked as a duplicate.", CompletionId);
}
return CompletionIdInfo;
}
}
return NULL; /* Either no items in the list or no match. */
}
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.
*/
for (item = smartcard->CompletionIds->tail; item; item = item->prev)
{
CompletionIdInfo = (COMPLETIONIDINFO*) item->data;
if (CompletionIdInfo->ID == CompletionId)
{
duplicate = CompletionIdInfo->duplicate;
if (duplicate)
{
DEBUG_WARN("CompletionID number %u was previously marked as a duplicate.", CompletionId);
}
list_remove(smartcard->CompletionIds, CompletionIdInfo);
free(CompletionIdInfo);
return duplicate;
}
}
/* This function should only be called when there is
* at least one outstanding CompletionID item in the list.
*/
DEBUG_WARN("Error!!! No CompletionIDs (or no matching IDs) in the list!");
return FALSE;
}
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 "smartcard_irp_request()" can reference it.
*/
DEBUG_SVC("DeviceId %d FileId %d CompletionId %d", irp->device->id, irp->FileId, irp->CompletionId);
pos = stream_get_pos(irp->output);
stream_set_pos(irp->output, 12);
stream_write_UINT32(irp->output, irp->IoStatus);
stream_set_pos(irp->output, pos);
/* Begin TS Client defect workaround. */
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 = smartcard_check_for_duplicate_id(smartcard, irp->CompletionId);
ReleaseMutex(smartcard->CompletionIdsMutex);
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
* and so is not available to be called
* here. Instead, call it indirectly by calling
* the IRP's "Discard()" function,
* which has already been assigned
* to point to "irp_free()" in "irp_new()".
*/
irp->Discard(irp);
}
/* End TS Client defect workaround. */
static void smartcard_irp_request(DEVICE* device, IRP* irp)
{
COMPLETIONIDINFO* CompletionIdInfo;
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device;
/* Begin TS Client defect workaround. */
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) && smartcard_async_op(irp))
{
/* 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);
irpWorker->smartcard = smartcard;
irpWorker->irp = irp;
ResumeThread(irpWorker->thread);
return;
}
InterlockedPushEntrySList(smartcard->pIrpList, &(irp->ItemEntry));
SetEvent(smartcard->irpEvent);
}
#ifdef STATIC_CHANNELS
#define DeviceServiceEntry smartcard_DeviceServiceEntry
#endif
int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
{
char* name;
char* path;
int i, length;
RDPDR_SMARTCARD* device;
SMARTCARD_DEVICE* smartcard;
device = (RDPDR_SMARTCARD*) pEntryPoints->device;
name = device->Name;
path = device->Path;
if (name)
{
/* TODO: check if server supports sc redirect (version 5.1) */
smartcard = (SMARTCARD_DEVICE*) malloc(sizeof(SMARTCARD_DEVICE));
ZeroMemory(smartcard, sizeof(SMARTCARD_DEVICE));
smartcard->device.type = RDPDR_DTYP_SMARTCARD;
smartcard->device.name = "SCARD";
smartcard->device.IRPRequest = smartcard_irp_request;
smartcard->device.Free = smartcard_free;
length = strlen(smartcard->device.name);
smartcard->device.data = stream_new(length + 1);
for (i = 0; i <= length; i++)
stream_write_BYTE(smartcard->device.data, name[i] < 0 ? '_' : name[i]);
smartcard->path = path;
smartcard->pIrpList = (PSLIST_HEADER) _aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT);
InitializeSListHead(smartcard->pIrpList);
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);
smartcard->CompletionIds = list_new();
smartcard->CompletionIdsMutex = CreateMutex(NULL, FALSE, NULL);
pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) smartcard);
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"
@ -248,11 +251,16 @@ static void tsmf_alsa_free(ITSMFAudioDevice* audio)
free(alsa);
}
ITSMFAudioDevice* TSMFAudioDeviceEntry(void)
#ifdef STATIC_CHANNELS
#define freerdp_tsmf_client_audio_subsystem_entry alsa_freerdp_tsmf_client_audio_subsystem_entry
#endif
ITSMFAudioDevice* freerdp_tsmf_client_audio_subsystem_entry(void)
{
TSMFALSAAudioDevice* alsa;
alsa = xnew(TSMFALSAAudioDevice);
alsa = (TSMFALSAAudioDevice*) malloc(sizeof(TSMFALSAAudioDevice));
ZeroMemory(alsa, sizeof(TSMFALSAAudioDevice));
alsa->iface.Open = tsmf_alsa_open;
alsa->iface.SetFormat = tsmf_alsa_set_format;
@ -265,4 +273,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

@ -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,7 +35,8 @@
#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>
@ -259,7 +260,7 @@ TSMF_PRESENTATION* tsmf_presentation_new(const BYTE* guid, IWTSVirtualChannelCal
if (fout)
{
fprintf(fout, "%d\n", (int) thid);
fprintf(fout, "%d\n", (int) (size_t) thid);
fclose(fout);
}
@ -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;
@ -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)
@ -921,7 +934,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 +1049,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 +1060,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

@ -798,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,
@ -963,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,
@ -973,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);
@ -1055,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,
@ -1067,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"));
@ -1150,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,
@ -1161,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);
@ -1260,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,
@ -1269,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);
@ -1351,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,
@ -1366,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"));
@ -1378,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);
@ -1445,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,
@ -1460,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"));
@ -1510,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,
@ -1519,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);
@ -1589,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,
@ -1598,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"));
@ -1666,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,
@ -1676,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);
@ -1769,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,
@ -2296,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;
@ -2450,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

@ -25,8 +25,11 @@
#include <time.h>
#include <libudev.h>
#include <winpr/crt.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 +57,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 +263,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 +289,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 */
@ -651,9 +656,9 @@ static void* urbdrc_search_usb_device(void* arg)
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 +761,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 +924,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 +940,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 +984,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 +999,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 +1022,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 +1081,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 +1102,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

@ -26,20 +26,16 @@ else()
add_subdirectory(Sample)
endif()
find_optional_package(DirectFB)
if(WITH_DIRECTFB)
add_subdirectory(DirectFB)
endif()
endif()
if(NOT WIN32 AND (NOT ANDROID))
find_suggested_package(X11)
if(WITH_X11)
add_subdirectory(X11)
endif()
if(WITH_X11)
add_subdirectory(X11)
endif()
if(APPLE)
if(APPLE AND (NOT IOS))
add_subdirectory(Mac)
endif()

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