New upstream version 2.0.0~gite60d0d5

This commit is contained in:
Bernhard Miklautz 2016-11-30 10:07:58 +00:00
parent 9aa47e3624
commit 4e8ad76edb
642 changed files with 45074 additions and 44090 deletions

View File

@ -41,6 +41,12 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# Include our extra modules
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/)
if((CMAKE_SYSTEM_NAME MATCHES "WindowsStore") AND (CMAKE_SYSTEM_VERSION MATCHES "10.0"))
set(UWP 1)
add_definitions("-D_UWP")
set(CMAKE_WINDOWS_VERSION "WIN10")
endif()
# Check for cmake compatibility (enable/disable features)
include(CheckCmakeCompat)
@ -65,7 +71,7 @@ include(CMakePackageConfigHelpers)
# Soname versioning
set(BUILD_NUMBER 0)
if ($ENV{BUILD_NUMBER})
set(BUILD_NUMBER $ENV{BUILD_NUMBER})
set(BUILD_NUMBER $ENV{BUILD_NUMBER})
endif()
set(WITH_LIBRARY_VERSIONING "ON")
set(FREERDP_VERSION_MAJOR "2")
@ -81,6 +87,12 @@ else()
endif()
set(FREERDP_INCLUDE_DIR "include/freerdp${FREERDP_VERSION_MAJOR}/")
# Compatibility options
if(DEFINED STATIC_CHANNELS)
message(WARNING "STATIC_CHANNELS is obsolete, please use BUILTIN_CHANNELS instead")
set(BUILTIN_CHANNELS ${STATIC_CHANNELS} CACHE BOOL "" FORCE)
endif()
# Make paths absolute
if (CMAKE_INSTALL_PREFIX)
get_filename_component(CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" ABSOLUTE)
@ -90,9 +102,9 @@ if (FREERDP_EXTERNAL_PATH)
endif()
# Allow to search the host machine for git
if(ANDROID OR IOS)
if(CMAKE_CROSSCOMPILING)
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH)
endif(ANDROID OR IOS)
endif(CMAKE_CROSSCOMPILING)
include(GetGitRevisionDescription)
git_get_exact_tag(GIT_REVISION --tags --always)
@ -100,9 +112,9 @@ git_get_exact_tag(GIT_REVISION --tags --always)
if (${GIT_REVISION} STREQUAL "n/a")
git_rev_parse (GIT_REVISION --short)
endif()
if(ANDROID OR IOS)
if(CMAKE_CROSSCOMPILING)
SET (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)
endif(ANDROID OR IOS)
endif(CMAKE_CROSSCOMPILING)
message(STATUS "Git Revision ${GIT_REVISION}")
@ -123,11 +135,16 @@ if(NOT DEFINED BUILD_SHARED_LIBS)
endif()
if(BUILD_TESTING)
set(EXPORT_ALL_SYMBOLS TRUE)
set(EXPORT_ALL_SYMBOLS TRUE)
elseif(NOT DEFINED EXPORT_ALL_SYMBOLS)
set(EXPORT_ALL_SYMBOLS FALSE)
set(EXPORT_ALL_SYMBOLS FALSE)
endif()
if (EXPORT_ALL_SYMBOLS)
# set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
add_definitions(-DFREERDP_TEST_EXPORTS -DBUILD_TESTING)
endif(EXPORT_ALL_SYMBOLS)
# BSD
if(${CMAKE_SYSTEM_NAME} MATCHES "BSD")
set(BSD TRUE)
@ -145,7 +162,10 @@ if(MSVC)
if(NOT DEFINED MSVC_RUNTIME)
set(MSVC_RUNTIME "dynamic")
endif()
if(${MSVC_RUNTIME} STREQUAL "static")
if(MSVC_RUNTIME STREQUAL "static")
if(BUILD_SHARED_LIBS)
message(FATAL_ERROR "Static CRT is only supported in a fully static build")
endif()
message(STATUS "Use the MSVC static runtime option carefully!")
message(STATUS "OpenSSL uses /MD by default, and is very picky")
message(STATUS "Random freeing errors are a common sign of runtime issues")
@ -215,20 +235,7 @@ if(CMAKE_COMPILER_IS_GNUCC)
endif()
endif()
if(CMAKE_BUILD_TYPE STREQUAL "Release")
set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG")
CHECK_C_COMPILER_FLAG (-Wno-builtin-macro-redefined Wno-builtin-macro-redefined)
if(Wno-builtin-macro-redefined)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Wno-builtin-macro-redefined")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -D__FILE__='\"$(subst ${CMAKE_BINARY_DIR}/,,$(subst ${CMAKE_SOURCE_DIR}/,,$(abspath $<)))\"'")
endif()
CHECK_CXX_COMPILER_FLAG (-Wno-builtin-macro-redefined Wno-builtin-macro-redefinedCXX)
if(Wno-builtin-macro-redefinedCXX)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wno-builtin-macro-redefined")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -D__FILE__='\"$(subst ${CMAKE_BINARY_DIR}/,,$(subst ${CMAKE_SOURCE_DIR}/,,$(abspath $<)))\"'")
endif()
add_definitions(-DNDEBUG)
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")
@ -238,6 +245,23 @@ if(CMAKE_COMPILER_IS_GNUCC)
endif()
endif()
# When building with Unix Makefiles and doing any release builds
# try to set __FILE__ to relative paths via a make specific macro
if (CMAKE_GENERATOR MATCHES "Unix Makefile*")
if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
string(TOUPPER ${CMAKE_BUILD_TYPE} UPPER_BUILD_TYPE)
CHECK_C_COMPILER_FLAG (-Wno-builtin-macro-redefined Wno-builtin-macro-redefined)
if(Wno-builtin-macro-redefined)
set(CMAKE_C_FLAGS_${UPPER_BUILD_TYPE} "${CMAKE_C_FLAGS_${UPPER_BUILD_TYPE}} -Wno-builtin-macro-redefined -D__FILE__='\"$(subst ${CMAKE_BINARY_DIR}/,,$(subst ${CMAKE_SOURCE_DIR}/,,$(abspath $<)))\"'")
endif()
CHECK_CXX_COMPILER_FLAG (-Wno-builtin-macro-redefined Wno-builtin-macro-redefinedCXX)
if(Wno-builtin-macro-redefinedCXX)
set(CMAKE_CXX_FLAGS_${UPPER_BUILD_TYPE} "${CMAKE_CXX_FLAGS_${UPPER_BUILD_TYPE}} -Wno-builtin-macro-redefined -D__FILE__='\"$(subst ${CMAKE_BINARY_DIR}/,,$(subst ${CMAKE_SOURCE_DIR}/,,$(abspath $<)))\"'")
endif()
endif()
endif()
if(${CMAKE_C_COMPILER_ID} STREQUAL "Clang")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-parameter")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-macros -Wno-padded")
@ -272,11 +296,31 @@ if(${CMAKE_C_COMPILER_ID} STREQUAL "Clang" OR CMAKE_COMPILER_IS_GNUCC)
unset(CMAKE_REQUIRED_FLAGS)
endif()
CHECK_C_COMPILER_FLAG ("-fno-omit-frame-pointer" fno-omit-frame-pointer)
if(fno-omit-frame-pointer)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer")
endif()
elseif(WITH_SANITIZE_LEAK)
if (DEFINED CMAKE_REQUIRED_FLAGS)
set(SAVE_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
endif()
set(CMAKE_REQUIRED_FLAGS "-fsanitize=leak")
CHECK_C_COMPILER_FLAG ("-fsanitize=leak" fsanitize-leak)
if(fsanitize-leak)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=leak")
endif()
if (DEFINED SAVE_CMAKE_REQUIRED_FLAGS)
set(CMAKE_REQUIRED_FLAGS ${SAVE_CMAKE_REQUIRED_FLAGS})
else()
unset(CMAKE_REQUIRED_FLAGS)
endif()
CHECK_C_COMPILER_FLAG ("-fno-omit-frame-pointer" fno-omit-frame-pointer)
if(fno-omit-frame-pointer)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer")
endif()
endif()
if (WITH_NO_UNDEFINED)
if (DEFINED CMAKE_REQUIRED_FLAGS)
set(SAVE_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
@ -315,9 +359,9 @@ if(MSVC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3")
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_AMD64_")
add_definitions(-D_AMD64_)
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_X86_")
add_definitions(-D_X86_)
endif()
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR})
@ -332,9 +376,10 @@ if(MSVC)
endif()
if(WIN32)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUNICODE -D_UNICODE")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_CRT_SECURE_NO_WARNINGS")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWIN32_LEAN_AND_MEAN")
add_definitions(-DUNICODE -D_UNICODE)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
add_definitions(-DWIN32_LEAN_AND_MEAN)
add_definitions(-D_WINSOCK_DEPRECATED_NO_WARNINGS)
set(CMAKE_USE_RELATIVE_PATH ON)
if (${CMAKE_GENERATOR} MATCHES "NMake Makefile*")
@ -358,14 +403,13 @@ if(WIN32)
endif()
if(CMAKE_WINDOWS_VERSION STREQUAL "WINXP")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWINVER=0x0501 -DWIN32_WINNT=0x0501")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWINVER=0x0501 -DWIN32_WINNT=0x0501")
add_definitions(-DWINVER=0x0501 -D_WIN32_WINNT=0x0501)
elseif(CMAKE_WINDOWS_VERSION STREQUAL "WIN7")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWINVER=0x0601 -DWIN32_WINNT=0x0601")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWINVER=0x0601 -DWIN32_WINNT=0x0601")
add_definitions(-DWINVER=0x0601 -D_WIN32_WINNT=0x0601)
elseif(CMAKE_WINDOWS_VERSION STREQUAL "WIN8")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWINVER=0x0602 -DWIN32_WINNT=0x0602")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWINVER=0x0602 -DWIN32_WINNT=0x0602")
add_definitions(-DWINVER=0x0602 -D_WIN32_WINNT=0x0602)
elseif(CMAKE_WINDOWS_VERSION STREQUAL "WIN10")
add_definitions(-DWINVER=0x0A00 -D_WIN32_WINNT=0x0A00)
endif()
if (FREERDP_EXTERNAL_SSL_PATH)
@ -377,8 +421,7 @@ if(IOS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -isysroot ${CMAKE_IOS_SDK_ROOT} -g")
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWINPR_EXPORTS -DFREERDP_EXPORTS")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWINPR_EXPORTS -DFREERDP_EXPORTS")
add_definitions(-DWINPR_EXPORTS -DFREERDP_EXPORTS)
# Include files
if(NOT IOS)
@ -449,6 +492,8 @@ endif()
if(ANDROID)
set(WITH_LIBRARY_VERSIONING "OFF")
set_property( GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS ${ANDROID_LIBRARY_USE_LIB64_PATHS} )
if (${ANDROID_ABI} STREQUAL "armeabi")
set (WITH_NEON OFF)
endif()
@ -484,12 +529,22 @@ endif()
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
if(NOT IOS AND NOT ANDROID)
if(NOT IOS)
find_package(Threads REQUIRED)
endif()
if(NOT WIN32)
check_library_exists(pthread pthread_mutex_timedlock "" HAVE_PTHREAD_MUTEX_TIMEDLOCK)
CHECK_SYMBOL_EXISTS(pthread_mutex_timedlock pthread.h HAVE_PTHREAD_MUTEX_TIMEDLOCK_SYMBOL)
if (NOT HAVE_PTHREAD_MUTEX_TIMEDLOCK_SYMBOL)
CHECK_LIBRARY_EXISTS(pthread pthread_mutex_timedlock "" HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIB)
endif (NOT HAVE_PTHREAD_MUTEX_TIMEDLOCK_SYMBOL)
if (NOT HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIB)
CHECK_LIBRARY_EXISTS(pthreads pthread_mutex_timedlock "" HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIBS)
endif (NOT HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIB)
if (HAVE_PTHREAD_MUTEX_TIMEDLOCK_SYMBOL OR HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIB OR HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIBS)
set(HAVE_PTHREAD_MUTEX_TIMEDLOCK ON)
endif (HAVE_PTHREAD_MUTEX_TIMEDLOCK_SYMBOL OR HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIB OR HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIBS)
endif()
if(WITH_VALGRIND_MEMCHECK)
@ -701,6 +756,7 @@ endif()
if(OPENSSL_FOUND)
add_definitions("-DWITH_OPENSSL")
message(STATUS "Using OpenSSL Version: ${OPENSSL_VERSION}")
endif()
if(MBEDTLS_FOUND)
@ -711,15 +767,21 @@ if (TARGET_ARCH MATCHES "sparc")
set(HAVE_ALIGNED_REQUIRED 1)
endif()
# Path to put FreeRDP data
set(FREERDP_DATA_PATH "${CMAKE_INSTALL_PREFIX}/share/freerdp${FREERDP_VERSION_MAJOR}")
# Path to put plugins
set(FREERDP_LIBRARY_PATH "${CMAKE_INSTALL_LIBDIR}")
set(FREERDP_PLUGIN_PATH "${CMAKE_INSTALL_LIBDIR}/freerdp${FREERDP_VERSION_MAJOR}")
set(FREERDP_ADDIN_PATH "${FREERDP_PLUGIN_PATH}")
# Android expects all libraries to be loadable
# without paths.
if (ANDROID)
set(FREERDP_DATA_PATH "share")
set(FREERDP_INSTALL_PREFIX ".")
set(FREERDP_LIBRARY_PATH ".")
set(FREERDP_PLUGIN_PATH ".")
set(FREERDP_ADDIN_PATH ".")
else (ANDROID)
set(FREERDP_DATA_PATH "${CMAKE_INSTALL_PREFIX}/share/freerdp${FREERDP_VERSION_MAJOR}")
set(FREERDP_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
set(FREERDP_LIBRARY_PATH "${CMAKE_INSTALL_LIBDIR}")
set(FREERDP_PLUGIN_PATH "${CMAKE_INSTALL_LIBDIR}/freerdp${FREERDP_VERSION_MAJOR}")
set(FREERDP_ADDIN_PATH "${FREERDP_PLUGIN_PATH}")
endif(ANDROID)
# Path to put extensions
set(FREERDP_EXTENSION_PATH "${CMAKE_INSTALL_FULL_LIBDIR}/freerdp${FREERDP_VERSION_MAJOR}/extensions")
@ -758,8 +820,6 @@ endif()
include(CTest)
if(BUILD_TESTING)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFREERDP_TEST_EXPORTS")
enable_testing()
if(MSVC)
@ -812,7 +872,7 @@ include_directories("${CMAKE_BINARY_DIR}/rdtk/include")
add_subdirectory(rdtk)
if(WAYLAND_FOUND)
add_subdirectory(uwac)
add_subdirectory(uwac)
endif()
if(BSD)
@ -858,9 +918,9 @@ include(${CMAKE_CPACK_INCLUDE_FILE})
set(FREERDP_BUILD_CONFIG_LIST "")
GET_CMAKE_PROPERTY(res VARIABLES)
FOREACH(var ${res})
IF (var MATCHES "^WITH_*|^BUILD_TESTING|^STATIC_CHANNELS|^HAVE_*")
LIST(APPEND FREERDP_BUILD_CONFIG_LIST "${var}=${${var}}")
ENDIF()
IF (var MATCHES "^WITH_*|^BUILD_TESTING|^BUILTIN_CHANNELS|^HAVE_*")
LIST(APPEND FREERDP_BUILD_CONFIG_LIST "${var}=${${var}}")
ENDIF()
ENDFOREACH()
string(REPLACE ";" " " FREERDP_BUILD_CONFIG "${FREERDP_BUILD_CONFIG_LIST}")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/buildflags.h.in ${CMAKE_CURRENT_BINARY_DIR}/buildflags.h)

2438
ChangeLog

File diff suppressed because it is too large Load Diff

View File

@ -167,7 +167,7 @@ macro(client_channel_install _targets _destination)
endmacro(client_channel_install)
macro(add_channel_client_library _module_prefix _module_name _channel_name _dynamic _entry)
if(${_dynamic} AND (NOT STATIC_CHANNELS))
if(${_dynamic} AND (NOT BUILTIN_CHANNELS))
# On windows create dll version information.
# Vendor, product and year are already set in top level CMakeLists.txt
if (WIN32)
@ -193,14 +193,14 @@ macro(add_channel_client_library _module_prefix _module_name _channel_name _dyna
set(${_module_prefix}_CHANNEL ${_channel_name} PARENT_SCOPE)
set(${_module_prefix}_ENTRY ${_entry} PARENT_SCOPE)
add_library(${_module_name} STATIC ${${_module_prefix}_SRCS})
if (${CMAKE_VERSION} VERSION_LESS 2.8.12)
if (${CMAKE_VERSION} VERSION_LESS 2.8.12 OR NOT BUILD_SHARED_LIBS)
client_channel_install(${_module_name} ${FREERDP_ADDIN_PATH})
endif()
endif()
endmacro(add_channel_client_library)
macro(add_channel_client_subsystem_library _module_prefix _module_name _channel_name _type _dynamic _entry)
if(${_dynamic} AND (NOT STATIC_CHANNELS))
if(${_dynamic} AND (NOT BUILTIN_CHANNELS))
# On windows create dll version information.
# Vendor, product and year are already set in top level CMakeLists.txt
if (WIN32)
@ -225,14 +225,14 @@ macro(add_channel_client_subsystem_library _module_prefix _module_name _channel_
set(${_module_prefix}_NAME ${_module_name} PARENT_SCOPE)
set(${_module_prefix}_TYPE ${_type} PARENT_SCOPE)
add_library(${_module_name} STATIC ${${_module_prefix}_SRCS})
if (${CMAKE_VERSION} VERSION_LESS 2.8.12)
if (${CMAKE_VERSION} VERSION_LESS 2.8.12 OR NOT BUILD_SHARED_LIBS)
client_channel_install(${_module_name} ${FREERDP_ADDIN_PATH})
endif()
endif()
endmacro(add_channel_client_subsystem_library)
macro(add_channel_server_library _module_prefix _module_name _channel_name _dynamic _entry)
if(${_dynamic} AND (NOT STATIC_CHANNELS))
if(${_dynamic} AND (NOT BUILTIN_CHANNELS))
# On windows create dll version information.
# Vendor, product and year are already set in top level CMakeLists.txt
if (WIN32)
@ -257,7 +257,7 @@ macro(add_channel_server_library _module_prefix _module_name _channel_name _dyna
set(${_module_prefix}_CHANNEL ${_channel_name} PARENT_SCOPE)
set(${_module_prefix}_ENTRY ${_entry} PARENT_SCOPE)
add_library(${_module_name} STATIC ${${_module_prefix}_SRCS})
if (${CMAKE_VERSION} VERSION_LESS 2.8.12)
if (${CMAKE_VERSION} VERSION_LESS 2.8.12 OR NOT BUILD_SHARED_LIBS)
server_channel_install(${_module_name} ${FREERDP_ADDIN_PATH})
endif()
endif()

View File

@ -27,7 +27,7 @@ add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE
target_link_libraries(${MODULE_NAME} freerdp winpr)
if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS)
if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS)
install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols)
endif()

View File

@ -69,7 +69,8 @@ typedef struct _AudinALSADevice
rdpContext* rdpcontext;
} AudinALSADevice;
static BOOL audin_alsa_set_params(AudinALSADevice* alsa, snd_pcm_t* capture_handle)
static BOOL audin_alsa_set_params(AudinALSADevice* alsa,
snd_pcm_t* capture_handle)
{
int error;
snd_pcm_hw_params_t* hw_params;
@ -77,26 +78,29 @@ static BOOL audin_alsa_set_params(AudinALSADevice* alsa, snd_pcm_t* capture_hand
if ((error = snd_pcm_hw_params_malloc(&hw_params)) < 0)
{
WLog_ERR(TAG, "snd_pcm_hw_params_malloc (%s)",
snd_strerror(error));
snd_strerror(error));
return FALSE;
}
snd_pcm_hw_params_any(capture_handle, hw_params);
snd_pcm_hw_params_set_access(capture_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
snd_pcm_hw_params_set_access(capture_handle, hw_params,
SND_PCM_ACCESS_RW_INTERLEAVED);
snd_pcm_hw_params_set_format(capture_handle, hw_params, alsa->format);
snd_pcm_hw_params_set_rate_near(capture_handle, hw_params, &alsa->actual_rate, NULL);
snd_pcm_hw_params_set_channels_near(capture_handle, hw_params, &alsa->actual_channels);
snd_pcm_hw_params_set_rate_near(capture_handle, hw_params, &alsa->actual_rate,
NULL);
snd_pcm_hw_params_set_channels_near(capture_handle, hw_params,
&alsa->actual_channels);
snd_pcm_hw_params(capture_handle, hw_params);
snd_pcm_hw_params_free(hw_params);
snd_pcm_prepare(capture_handle);
if ((alsa->actual_rate != alsa->target_rate) ||
(alsa->actual_channels != alsa->target_channels))
(alsa->actual_channels != alsa->target_channels))
{
DEBUG_DVC("actual rate %d / channel %d is "
"different from target rate %d / channel %d, resampling required.",
alsa->actual_rate, alsa->actual_channels,
alsa->target_rate, alsa->target_channels);
"different from target rate %d / channel %d, resampling required.",
alsa->actual_rate, alsa->actual_channels,
alsa->target_rate, alsa->target_channels);
}
return TRUE;
@ -107,7 +111,8 @@ static BOOL audin_alsa_set_params(AudinALSADevice* alsa, snd_pcm_t* capture_hand
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT audin_alsa_thread_receive(AudinALSADevice* alsa, BYTE* src, int size)
static UINT audin_alsa_thread_receive(AudinALSADevice* alsa, BYTE* src,
int size)
{
int frames;
int cframes;
@ -116,38 +121,37 @@ static UINT audin_alsa_thread_receive(AudinALSADevice* alsa, BYTE* src, int size
BYTE* encoded_data;
int rbytes_per_frame;
int tbytes_per_frame;
int status;
int status;
rbytes_per_frame = alsa->actual_channels * alsa->bytes_per_channel;
tbytes_per_frame = alsa->target_channels * alsa->bytes_per_channel;
if ((alsa->target_rate == alsa->actual_rate) &&
(alsa->target_channels == alsa->actual_channels))
(alsa->target_channels == alsa->actual_channels))
{
frames = size / rbytes_per_frame;
}
else
{
alsa->dsp_context->resample(alsa->dsp_context, src, alsa->bytes_per_channel,
alsa->actual_channels, alsa->actual_rate, size / rbytes_per_frame,
alsa->target_channels, alsa->target_rate);
alsa->actual_channels, alsa->actual_rate, size / rbytes_per_frame,
alsa->target_channels, alsa->target_rate);
frames = alsa->dsp_context->resampled_frames;
DEBUG_DVC("resampled %d frames at %d to %d frames at %d",
size / rbytes_per_frame, alsa->actual_rate, frames, alsa->target_rate);
size / rbytes_per_frame, alsa->actual_rate, frames, alsa->target_rate);
size = frames * tbytes_per_frame;
src = alsa->dsp_context->resampled_buffer;
}
while (frames > 0)
{
status = WaitForSingleObject(alsa->stopEvent, 0);
status = WaitForSingleObject(alsa->stopEvent, 0);
if (status == WAIT_FAILED)
{
ret = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", ret);
break;
}
if (status == WAIT_FAILED)
{
ret = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", ret);
break;
}
if (status == WAIT_OBJECT_0)
break;
@ -157,8 +161,8 @@ static UINT audin_alsa_thread_receive(AudinALSADevice* alsa, BYTE* src, int size
if (cframes > frames)
cframes = frames;
CopyMemory(alsa->buffer + alsa->buffer_frames * tbytes_per_frame, src, cframes * tbytes_per_frame);
CopyMemory(alsa->buffer + alsa->buffer_frames * tbytes_per_frame, src,
cframes * tbytes_per_frame);
alsa->buffer_frames += cframes;
if (alsa->buffer_frames >= alsa->frames_per_packet)
@ -166,8 +170,8 @@ static UINT audin_alsa_thread_receive(AudinALSADevice* alsa, BYTE* src, int size
if (alsa->wformat == WAVE_FORMAT_DVI_ADPCM)
{
if (!alsa->dsp_context->encode_ima_adpcm(alsa->dsp_context,
alsa->buffer, alsa->buffer_frames * tbytes_per_frame,
alsa->target_channels, alsa->block_size))
alsa->buffer, alsa->buffer_frames * tbytes_per_frame,
alsa->target_channels, alsa->block_size))
{
ret = ERROR_INTERNAL_ERROR;
break;
@ -175,9 +179,8 @@ static UINT audin_alsa_thread_receive(AudinALSADevice* alsa, BYTE* src, int size
encoded_data = alsa->dsp_context->adpcm_buffer;
encoded_size = alsa->dsp_context->adpcm_size;
DEBUG_DVC("encoded %d to %d",
alsa->buffer_frames * tbytes_per_frame, encoded_size);
alsa->buffer_frames * tbytes_per_frame, encoded_size);
}
else
{
@ -185,22 +188,22 @@ static UINT audin_alsa_thread_receive(AudinALSADevice* alsa, BYTE* src, int size
encoded_size = alsa->buffer_frames * tbytes_per_frame;
}
status = WaitForSingleObject(alsa->stopEvent, 0);
status = WaitForSingleObject(alsa->stopEvent, 0);
if (status == WAIT_FAILED)
{
ret = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", ret);
break;
}
if (status == WAIT_FAILED)
{
ret = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", ret);
break;
}
if (status == WAIT_OBJECT_0)
if (status == WAIT_OBJECT_0)
break;
else
{
DEBUG_DVC("encoded %d [%d] to %d [%X]", alsa->buffer_frames,
tbytes_per_frame, encoded_size,
alsa->wformat);
tbytes_per_frame, encoded_size,
alsa->wformat);
ret = alsa->receive(encoded_data, encoded_size, alsa->user_data);
}
@ -225,81 +228,83 @@ static void* audin_alsa_thread_func(void* arg)
int tbytes_per_frame;
snd_pcm_t* capture_handle = NULL;
AudinALSADevice* alsa = (AudinALSADevice*) arg;
DWORD status;
DWORD status;
DEBUG_DVC("in");
rbytes_per_frame = alsa->actual_channels * alsa->bytes_per_channel;
tbytes_per_frame = alsa->target_channels * alsa->bytes_per_channel;
buffer = (BYTE*) calloc(1, rbytes_per_frame * alsa->frames_per_packet);
if (!buffer)
{
WLog_ERR(TAG, "calloc failed!");
error = CHANNEL_RC_NO_MEMORY;
if (alsa->rdpcontext)
setChannelError(alsa->rdpcontext, error, "calloc failed!");
goto out;
error = CHANNEL_RC_NO_MEMORY;
goto out;
}
freerdp_dsp_context_reset_adpcm(alsa->dsp_context);
if ((error = snd_pcm_open(&capture_handle, alsa->device_name, SND_PCM_STREAM_CAPTURE, 0)) < 0)
{
WLog_ERR(TAG, "snd_pcm_open (%s)", snd_strerror(error));
goto out;
}
if ((error = snd_pcm_open(&capture_handle, alsa->device_name,
SND_PCM_STREAM_CAPTURE, 0)) < 0)
{
WLog_ERR(TAG, "snd_pcm_open (%s)", snd_strerror(error));
error = CHANNEL_RC_INITIALIZATION_ERROR;
goto out;
}
if (!audin_alsa_set_params(alsa, capture_handle))
{
WLog_ERR(TAG, "audin_alsa_set_params failed");
goto out;
}
if (!audin_alsa_set_params(alsa, capture_handle))
{
WLog_ERR(TAG, "audin_alsa_set_params failed");
goto out;
}
while(1)
{
status = WaitForSingleObject(alsa->stopEvent, 0);
while (1)
{
status = WaitForSingleObject(alsa->stopEvent, 0);
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
break;
}
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %ld!", error);
break;
}
if (status == WAIT_OBJECT_0)
break;
if (status == WAIT_OBJECT_0)
break;
error = snd_pcm_readi(capture_handle, buffer, alsa->frames_per_packet);
error = snd_pcm_readi(capture_handle, buffer, alsa->frames_per_packet);
if (error == -EPIPE)
{
snd_pcm_recover(capture_handle, error, 0);
continue;
}
else if (error < 0)
{
WLog_ERR(TAG, "snd_pcm_readi (%s)", snd_strerror(error));
break;
}
if (error == -EPIPE)
{
snd_pcm_recover(capture_handle, error, 0);
continue;
}
else if (error < 0)
{
WLog_ERR(TAG, "snd_pcm_readi (%s)", snd_strerror(error));
break;
}
if ((error = audin_alsa_thread_receive(alsa, buffer, error * rbytes_per_frame)))
{
WLog_ERR(TAG, "audin_alsa_thread_receive failed with error %lu", error);
break;
}
}
if ((error = audin_alsa_thread_receive(alsa, buffer, error * rbytes_per_frame)))
{
WLog_ERR(TAG, "audin_alsa_thread_receive failed with error %ld", error);
break;
}
}
free(buffer);
if (capture_handle)
snd_pcm_close(capture_handle);
out:
DEBUG_DVC("out");
if (error && alsa->rdpcontext)
setChannelError(alsa->rdpcontext, error, "audin_alsa_thread_func reported an error");
ExitThread((DWORD)error);
if (error && alsa->rdpcontext)
setChannelError(alsa->rdpcontext, error,
"audin_alsa_thread_func reported an error");
ExitThread((DWORD)error);
return NULL;
}
@ -311,36 +316,36 @@ out:
static UINT audin_alsa_free(IAudinDevice* device)
{
AudinALSADevice* alsa = (AudinALSADevice*) device;
freerdp_dsp_context_free(alsa->dsp_context);
free(alsa->device_name);
free(alsa);
return CHANNEL_RC_OK;
}
static BOOL audin_alsa_format_supported(IAudinDevice* device, audinFormat* format)
static BOOL audin_alsa_format_supported(IAudinDevice* device,
audinFormat* format)
{
switch (format->wFormatTag)
{
case WAVE_FORMAT_PCM:
if (format->cbSize == 0 &&
(format->nSamplesPerSec <= 48000) &&
(format->wBitsPerSample == 8 || format->wBitsPerSample == 16) &&
(format->nChannels == 1 || format->nChannels == 2))
(format->nSamplesPerSec <= 48000) &&
(format->wBitsPerSample == 8 || format->wBitsPerSample == 16) &&
(format->nChannels == 1 || format->nChannels == 2))
{
return TRUE;
}
break;
case WAVE_FORMAT_DVI_ADPCM:
if ((format->nSamplesPerSec <= 48000) &&
(format->wBitsPerSample == 4) &&
(format->nChannels == 1 || format->nChannels == 2))
(format->wBitsPerSample == 4) &&
(format->nChannels == 1 || format->nChannels == 2))
{
return TRUE;
}
break;
}
@ -352,11 +357,11 @@ static BOOL audin_alsa_format_supported(IAudinDevice* device, audinFormat* forma
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT audin_alsa_set_format(IAudinDevice* device, audinFormat* format, UINT32 FramesPerPacket)
static UINT audin_alsa_set_format(IAudinDevice* device, audinFormat* format,
UINT32 FramesPerPacket)
{
int bs;
AudinALSADevice* alsa = (AudinALSADevice*) device;
alsa->target_rate = format->nSamplesPerSec;
alsa->actual_rate = format->nSamplesPerSec;
alsa->target_channels = format->nChannels;
@ -371,11 +376,13 @@ static UINT audin_alsa_set_format(IAudinDevice* device, audinFormat* format, UIN
alsa->format = SND_PCM_FORMAT_S8;
alsa->bytes_per_channel = 1;
break;
case 16:
alsa->format = SND_PCM_FORMAT_S16_LE;
alsa->bytes_per_channel = 2;
break;
}
break;
case WAVE_FORMAT_DVI_ADPCM:
@ -383,9 +390,9 @@ static UINT audin_alsa_set_format(IAudinDevice* device, audinFormat* format, UIN
alsa->bytes_per_channel = 2;
bs = (format->nBlockAlign - 4 * format->nChannels) * 4;
alsa->frames_per_packet = (alsa->frames_per_packet * format->nChannels * 2 /
bs + 1) * bs / (format->nChannels * 2);
bs + 1) * bs / (format->nChannels * 2);
DEBUG_DVC("aligned FramesPerPacket=%d",
alsa->frames_per_packet);
alsa->frames_per_packet);
break;
}
@ -399,34 +406,37 @@ static UINT audin_alsa_set_format(IAudinDevice* device, audinFormat* format, UIN
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT audin_alsa_open(IAudinDevice* device, AudinReceive receive, void* user_data)
static UINT audin_alsa_open(IAudinDevice* device, AudinReceive receive,
void* user_data)
{
int tbytes_per_frame;
AudinALSADevice* alsa = (AudinALSADevice*) device;
alsa->receive = receive;
alsa->user_data = user_data;
tbytes_per_frame = alsa->target_channels * alsa->bytes_per_channel;
alsa->buffer = (BYTE*) calloc(1, tbytes_per_frame * alsa->frames_per_packet);
if (!alsa->buffer)
{
WLog_ERR(TAG, "calloc failed!");
return ERROR_NOT_ENOUGH_MEMORY;
}
alsa->buffer_frames = 0;
if (!(alsa->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
{
WLog_ERR(TAG, "CreateEvent failed!");
goto error_out;
}
if (!(alsa->thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) audin_alsa_thread_func, alsa, 0, NULL)))
(LPTHREAD_START_ROUTINE) audin_alsa_thread_func, alsa, 0, NULL)))
{
WLog_ERR(TAG, "CreateThread failed!");
goto error_out;
}
return CHANNEL_RC_OK;
error_out:
free(alsa->buffer);
@ -443,32 +453,30 @@ error_out:
*/
static UINT audin_alsa_close(IAudinDevice* device)
{
UINT error = CHANNEL_RC_OK;
UINT error = CHANNEL_RC_OK;
AudinALSADevice* alsa = (AudinALSADevice*) device;
if (alsa->stopEvent)
{
SetEvent(alsa->stopEvent);
if (WaitForSingleObject(alsa->thread, INFINITE) == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error);
return error;
}
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error);
return error;
}
CloseHandle(alsa->stopEvent);
alsa->stopEvent = NULL;
CloseHandle(alsa->thread);
alsa->thread = NULL;
}
free(alsa->buffer);
alsa->buffer = NULL;
alsa->receive = NULL;
alsa->user_data = NULL;
return error;
}
@ -483,17 +491,17 @@ COMMAND_LINE_ARGUMENT_A audin_alsa_args[] =
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT audin_alsa_parse_addin_args(AudinALSADevice* device, ADDIN_ARGV* args)
static UINT 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 | COMMAND_LINE_IGN_UNKNOWN_KEYWORD;
status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv, audin_alsa_args, flags, alsa, NULL, NULL);
flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON |
COMMAND_LINE_IGN_UNKNOWN_KEYWORD;
status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv,
audin_alsa_args, flags, alsa, NULL, NULL);
arg = audin_alsa_args;
do
@ -502,17 +510,16 @@ static UINT audin_alsa_parse_addin_args(AudinALSADevice* device, ADDIN_ARGV* arg
continue;
CommandLineSwitchStart(arg)
CommandLineSwitchCase(arg, "dev")
{
alsa->device_name = _strdup(arg->Value);
if(!alsa->device_name)
if (!alsa->device_name)
{
WLog_ERR(TAG, "_strdup failed!");
return CHANNEL_RC_NO_MEMORY;
}
}
CommandLineSwitchEnd(arg)
}
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
@ -520,7 +527,7 @@ static UINT audin_alsa_parse_addin_args(AudinALSADevice* device, ADDIN_ARGV* arg
return CHANNEL_RC_OK;
}
#ifdef STATIC_CHANNELS
#ifdef BUILTIN_CHANNELS
#define freerdp_audin_client_subsystem_entry alsa_freerdp_audin_client_subsystem_entry
#else
#define freerdp_audin_client_subsystem_entry FREERDP_API freerdp_audin_client_subsystem_entry
@ -531,13 +538,14 @@ static UINT audin_alsa_parse_addin_args(AudinALSADevice* device, ADDIN_ARGV* arg
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints)
UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS
pEntryPoints)
{
ADDIN_ARGV* args;
AudinALSADevice* alsa;
UINT error;
alsa = (AudinALSADevice*) calloc(1, sizeof(AudinALSADevice));
if (!alsa)
{
WLog_ERR(TAG, "calloc failed!");
@ -550,18 +558,18 @@ UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEn
alsa->iface.Close = audin_alsa_close;
alsa->iface.Free = audin_alsa_free;
alsa->rdpcontext = pEntryPoints->rdpcontext;
args = pEntryPoints->args;
if ((error = audin_alsa_parse_addin_args(alsa, args)))
{
WLog_ERR(TAG, "audin_alsa_parse_addin_args failed with errorcode %lu!", error);
WLog_ERR(TAG, "audin_alsa_parse_addin_args failed with errorcode %u!", error);
goto error_out;
}
if (!alsa->device_name)
{
alsa->device_name = _strdup("default");
if (!alsa->device_name)
{
WLog_ERR(TAG, "_strdup failed!");
@ -577,8 +585,8 @@ UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEn
alsa->target_channels = 2;
alsa->actual_channels = 2;
alsa->bytes_per_channel = 2;
alsa->dsp_context = freerdp_dsp_context_new();
if (!alsa->dsp_context)
{
WLog_ERR(TAG, "freerdp_dsp_context_new failed!");
@ -586,9 +594,10 @@ UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEn
goto error_out;
}
if ((error = pEntryPoints->pRegisterAudinDevice(pEntryPoints->plugin, (IAudinDevice*) alsa)))
if ((error = pEntryPoints->pRegisterAudinDevice(pEntryPoints->plugin,
(IAudinDevice*) alsa)))
{
WLog_ERR(TAG, "RegisterAudinDevice failed with error %lu!", error);
WLog_ERR(TAG, "RegisterAudinDevice failed with error %u!", error);
goto error_out;
}

View File

@ -374,13 +374,13 @@ static UINT audin_process_open(IWTSVirtualChannelCallback* pChannelCallback, wSt
IFCALLRET(audin->device->SetFormat, error, audin->device, format, FramesPerPacket);
if (error != CHANNEL_RC_OK)
{
WLog_ERR(TAG, "SetFormat failed with errorcode %lu", error);
WLog_ERR(TAG, "SetFormat failed with errorcode %u", error);
return error;
}
IFCALLRET(audin->device->Open, error, audin->device, audin_receive_wave_data, callback);
if (error != CHANNEL_RC_OK)
{
WLog_ERR(TAG, "Open failed with errorcode %lu", error);
WLog_ERR(TAG, "Open failed with errorcode %u", error);
return error;
}
}
@ -428,19 +428,19 @@ static UINT audin_process_format_change(IWTSVirtualChannelCallback* pChannelCall
IFCALLRET(audin->device->Close, error, audin->device);
if (error != CHANNEL_RC_OK)
{
WLog_ERR(TAG, "Close failed with errorcode %lu", error);
WLog_ERR(TAG, "Close failed with errorcode %u", error);
return error;
}
IFCALLRET(audin->device->SetFormat, error, audin->device, format, 0);
if (error != CHANNEL_RC_OK)
{
WLog_ERR(TAG, "SetFormat failed with errorcode %lu", error);
WLog_ERR(TAG, "SetFormat failed with errorcode %u", error);
return error;
}
IFCALLRET(audin->device->Open, error, audin->device, audin_receive_wave_data, callback);
if (error != CHANNEL_RC_OK)
{
WLog_ERR(TAG, "Open failed with errorcode %lu", error);
WLog_ERR(TAG, "Open failed with errorcode %u", error);
return error;
}
}
@ -509,7 +509,7 @@ static UINT audin_on_close(IWTSVirtualChannelCallback* pChannelCallback)
{
IFCALLRET(audin->device->Close, error, audin->device);
if (error != CHANNEL_RC_OK)
WLog_ERR(TAG, "Close failed with errorcode %lu", error);
WLog_ERR(TAG, "Close failed with errorcode %u", error);
}
free(callback->formats);
@ -593,7 +593,7 @@ static UINT audin_plugin_terminated(IWTSPlugin* pPlugin)
IFCALLRET(audin->device->Free, error, audin->device);
if (error != CHANNEL_RC_OK)
{
WLog_ERR(TAG, "Free failed with errorcode %lu", error);
WLog_ERR(TAG, "Free failed with errorcode %u", error);
// dont stop on error
}
audin->device = NULL;
@ -662,7 +662,7 @@ static UINT audin_load_device_plugin(IWTSPlugin* pPlugin, const char* name, ADDI
if ((error = entry(&entryPoints)))
{
WLog_ERR(TAG, "%s entry returned error %lu.", name, error);
WLog_ERR(TAG, "%s entry returned error %u.", name, error);
return error;
}
@ -721,10 +721,8 @@ BOOL audin_process_addin_args(AUDIN_PLUGIN* audin, ADDIN_ARGV* args)
COMMAND_LINE_ARGUMENT_A* arg;
UINT error;
if (args->argc == 1)
{
if (!args || args->argc == 1)
return TRUE;
}
flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON | COMMAND_LINE_IGN_UNKNOWN_KEYWORD;
@ -746,7 +744,7 @@ BOOL audin_process_addin_args(AUDIN_PLUGIN* audin, ADDIN_ARGV* args)
{
if ((error = audin_set_subsystem(audin, arg->Value)))
{
WLog_ERR(TAG, "audin_set_subsystem failed with error %lu!", error);
WLog_ERR(TAG, "audin_set_subsystem failed with error %u!", error);
return FALSE;
}
}
@ -754,7 +752,7 @@ BOOL audin_process_addin_args(AUDIN_PLUGIN* audin, ADDIN_ARGV* args)
{
if ((error = audin_set_device_name(audin, arg->Value)))
{
WLog_ERR(TAG, "audin_set_device_name failed with error %lu!", error);
WLog_ERR(TAG, "audin_set_device_name failed with error %u!", error);
return FALSE;
}
}
@ -782,7 +780,7 @@ BOOL audin_process_addin_args(AUDIN_PLUGIN* audin, ADDIN_ARGV* args)
return TRUE;
}
#ifdef STATIC_CHANNELS
#ifdef BUILTIN_CHANNELS
#define DVCPluginEntry audin_DVCPluginEntry
#else
#define DVCPluginEntry FREERDP_API DVCPluginEntry
@ -860,7 +858,7 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
{
if ((error = audin_load_device_plugin((IWTSPlugin*) audin, audin->subsystem, args)))
{
WLog_ERR(TAG, "audin_load_device_plugin %s failed with error %lu!",
WLog_ERR(TAG, "audin_load_device_plugin %s failed with error %u!",
audin->subsystem, error);
goto out;
}
@ -871,17 +869,17 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
{
if ((error = audin_set_subsystem(audin, entry->subsystem)))
{
WLog_ERR(TAG, "audin_set_subsystem for %s failed with error %lu!",
WLog_ERR(TAG, "audin_set_subsystem for %s failed with error %u!",
entry->subsystem, error);
}
else if ((error = audin_set_device_name(audin, entry->device)))
{
WLog_ERR(TAG, "audin_set_device_name for %s failed with error %lu!",
WLog_ERR(TAG, "audin_set_device_name for %s failed with error %u!",
entry->subsystem, error);
}
else if ((error = audin_load_device_plugin((IWTSPlugin*) audin, audin->subsystem, args)))
{
WLog_ERR(TAG, "audin_load_device_plugin %s failed with error %lu!",
WLog_ERR(TAG, "audin_load_device_plugin %s failed with error %u!",
entry->subsystem, error);
}

View File

@ -33,9 +33,9 @@
#define TAG CHANNELS_TAG("audin.client")
#ifdef WITH_DEBUG_DVC
#define DEBUG_DVC(fmt, ...) WLog_DBG(TAG, fmt, ## __VA_ARGS__)
#define DEBUG_DVC(...) WLog_DBG(TAG, __VA_ARGS__)
#else
#define DEBUG_DVC(fmt, ...) do { } while (0)
#define DEBUG_DVC(...) do { } while (0)
#endif
#endif /* FREERDP_AUDIN_CLIENT_MAIN_H */

View File

@ -33,6 +33,9 @@
#include <winpr/debug.h>
#include <winpr/cmdline.h>
#define __COREFOUNDATION_CFPLUGINCOM__ 1
#define IUNKNOWN_C_GUTS void *_reserved; void* QueryInterface; void* AddRef; void* Release
#include <CoreAudio/CoreAudioTypes.h>
#include <CoreAudio/CoreAudio.h>
#include <AudioToolbox/AudioToolbox.h>
@ -171,7 +174,7 @@ static void mac_audio_queue_input_cb(void *aqData,
{
AudinMacDevice* mac = (AudinMacDevice*)aqData;
UINT error;
int encoded_size;
int encoded_size = 0;
const BYTE *encoded_data;
BYTE *buffer = inBuffer->mAudioData;
int buffer_size = inBuffer->mAudioDataByteSize;
@ -212,7 +215,7 @@ static void mac_audio_queue_input_cb(void *aqData,
if ((error = mac->receive(encoded_data, encoded_size, mac->user_data)))
{
WLog_ERR(TAG, "mac->receive failed with error %lu", error);
WLog_ERR(TAG, "mac->receive failed with error %u", error);
SetLastError(ERROR_INTERNAL_ERROR);
return;
}
@ -400,7 +403,7 @@ static UINT audin_mac_parse_addin_args(AudinMacDevice *device, ADDIN_ARGV *args)
return CHANNEL_RC_OK;
}
#ifdef STATIC_CHANNELS
#ifdef BUILTIN_CHANNELS
#define freerdp_audin_client_subsystem_entry mac_freerdp_audin_client_subsystem_entry
#else
#define freerdp_audin_client_subsystem_entry FREERDP_API freerdp_audin_client_subsystem_entry
@ -435,7 +438,7 @@ UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEn
if ((error = audin_mac_parse_addin_args(mac, args)))
{
WLog_ERR(TAG, "audin_mac_parse_addin_args failed with %lu!", error);
WLog_ERR(TAG, "audin_mac_parse_addin_args failed with %u!", error);
goto error_out;
}
@ -449,7 +452,7 @@ UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEn
if ((error = pEntryPoints->pRegisterAudinDevice(pEntryPoints->plugin, (IAudinDevice*) mac)))
{
WLog_ERR(TAG, "RegisterAudinDevice failed with error %lu!", error);
WLog_ERR(TAG, "RegisterAudinDevice failed with error %u!", error);
goto error_out;
}

View File

@ -112,7 +112,7 @@ static void* audin_opensles_thread_func(void* arg)
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error);
break;
}
@ -125,7 +125,7 @@ static void* audin_opensles_thread_func(void* arg)
rc = android_RecIn(opensles->stream, buffer.s, raw_size);
if (rc < 0)
{
WLog_ERR(TAG, "android_RecIn %lu", rc);
WLog_ERR(TAG, "android_RecIn %d", rc);
continue;
}
@ -401,7 +401,7 @@ static UINT audin_opensles_close(IAudinDevice* device)
if (WaitForSingleObject(opensles->thread, INFINITE) == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error);
WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error);
return error;
}
CloseHandle(opensles->stopEvent);
@ -473,7 +473,7 @@ static UINT audin_opensles_parse_addin_args(AudinOpenSLESDevice* device,
return CHANNEL_RC_OK;
}
#ifdef STATIC_CHANNELS
#ifdef BUILTIN_CHANNELS
#define freerdp_audin_client_subsystem_entry \
opensles_freerdp_audin_client_subsystem_entry
#else

View File

@ -6,14 +6,14 @@ All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@ -34,114 +34,132 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define CONV16BIT 32768
#define CONVMYFLT (1./32768.)
static void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context);
static void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void* context);
// creates the OpenSL ES audio engine
static SLresult openSLCreateEngine(OPENSL_STREAM *p)
static SLresult openSLCreateEngine(OPENSL_STREAM* p)
{
SLresult result;
// create engine
result = slCreateEngine(&(p->engineObject), 0, NULL, 0, NULL, NULL);
SLresult result;
// create engine
result = slCreateEngine(&(p->engineObject), 0, NULL, 0, NULL, NULL);
DEBUG_DVC("engineObject=%p", p->engineObject);
if(result != SL_RESULT_SUCCESS) goto engine_end;
// realize the engine
result = (*p->engineObject)->Realize(p->engineObject, SL_BOOLEAN_FALSE);
if (result != SL_RESULT_SUCCESS) goto engine_end;
// realize the engine
result = (*p->engineObject)->Realize(p->engineObject, SL_BOOLEAN_FALSE);
DEBUG_DVC("Realize=%d", result);
if(result != SL_RESULT_SUCCESS) goto engine_end;
// get the engine interface, which is needed in order to create other objects
result = (*p->engineObject)->GetInterface(p->engineObject, SL_IID_ENGINE, &(p->engineEngine));
if (result != SL_RESULT_SUCCESS) goto engine_end;
// get the engine interface, which is needed in order to create other objects
result = (*p->engineObject)->GetInterface(p->engineObject, SL_IID_ENGINE,
&(p->engineEngine));
DEBUG_DVC("engineEngine=%p", p->engineEngine);
if(result != SL_RESULT_SUCCESS) goto engine_end;
// get the volume interface - important, this is optional!
result = (*p->engineObject)->GetInterface(p->engineObject, SL_IID_DEVICEVOLUME, &(p->deviceVolume));
if (result != SL_RESULT_SUCCESS) goto engine_end;
// get the volume interface - important, this is optional!
result = (*p->engineObject)->GetInterface(p->engineObject, SL_IID_DEVICEVOLUME,
&(p->deviceVolume));
DEBUG_DVC("deviceVolume=%p", p->deviceVolume);
if(result != SL_RESULT_SUCCESS)
if (result != SL_RESULT_SUCCESS)
{
p->deviceVolume = NULL;
result = SL_RESULT_SUCCESS;
}
engine_end:
engine_end:
assert(SL_RESULT_SUCCESS == result);
return result;
return result;
}
// Open the OpenSL ES device for input
static SLresult openSLRecOpen(OPENSL_STREAM *p){
SLresult result;
SLuint32 sr = p->sr;
SLuint32 channels = p->inchannels;
static SLresult openSLRecOpen(OPENSL_STREAM* p)
{
SLresult result;
SLuint32 sr = p->sr;
SLuint32 channels = p->inchannels;
assert(!p->recorderObject);
if(channels){
if (channels)
{
switch (sr)
{
case 8000:
sr = SL_SAMPLINGRATE_8;
break;
switch(sr){
case 11025:
sr = SL_SAMPLINGRATE_11_025;
break;
case 8000:
sr = SL_SAMPLINGRATE_8;
break;
case 11025:
sr = SL_SAMPLINGRATE_11_025;
break;
case 16000:
sr = SL_SAMPLINGRATE_16;
break;
case 22050:
sr = SL_SAMPLINGRATE_22_05;
break;
case 24000:
sr = SL_SAMPLINGRATE_24;
break;
case 32000:
sr = SL_SAMPLINGRATE_32;
break;
case 44100:
sr = SL_SAMPLINGRATE_44_1;
break;
case 48000:
sr = SL_SAMPLINGRATE_48;
break;
case 64000:
sr = SL_SAMPLINGRATE_64;
break;
case 88200:
sr = SL_SAMPLINGRATE_88_2;
break;
case 96000:
sr = SL_SAMPLINGRATE_96;
break;
case 192000:
sr = SL_SAMPLINGRATE_192;
break;
default:
return -1;
}
// configure audio source
SLDataLocator_IODevice loc_dev = {SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT,
SL_DEFAULTDEVICEID_AUDIOINPUT, NULL};
SLDataSource audioSrc = {&loc_dev, NULL};
case 16000:
sr = SL_SAMPLINGRATE_16;
break;
// configure audio sink
int speakers;
if(channels > 1)
speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
else
case 22050:
sr = SL_SAMPLINGRATE_22_05;
break;
case 24000:
sr = SL_SAMPLINGRATE_24;
break;
case 32000:
sr = SL_SAMPLINGRATE_32;
break;
case 44100:
sr = SL_SAMPLINGRATE_44_1;
break;
case 48000:
sr = SL_SAMPLINGRATE_48;
break;
case 64000:
sr = SL_SAMPLINGRATE_64;
break;
case 88200:
sr = SL_SAMPLINGRATE_88_2;
break;
case 96000:
sr = SL_SAMPLINGRATE_96;
break;
case 192000:
sr = SL_SAMPLINGRATE_192;
break;
default:
return -1;
}
// configure audio source
SLDataLocator_IODevice loc_dev = {SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT,
SL_DEFAULTDEVICEID_AUDIOINPUT, NULL
};
SLDataSource audioSrc = {&loc_dev, NULL};
// configure audio sink
int speakers;
if (channels > 1)
speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
else
speakers = SL_SPEAKER_FRONT_CENTER;
SLDataLocator_AndroidSimpleBufferQueue loc_bq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
SLDataFormat_PCM format_pcm;
SLDataLocator_AndroidSimpleBufferQueue loc_bq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
SLDataFormat_PCM format_pcm;
format_pcm.formatType = SL_DATAFORMAT_PCM;
format_pcm.numChannels = channels;
format_pcm.samplesPerSec = sr;
format_pcm.channelMask = speakers;
format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
if (16 == p->bits_per_sample)
{
format_pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
@ -155,131 +173,135 @@ static SLresult openSLRecOpen(OPENSL_STREAM *p){
else
assert(0);
SLDataSink audioSnk = {&loc_bq, &format_pcm};
// create audio recorder
// (requires the RECORD_AUDIO permission)
const SLInterfaceID id[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE};
const SLboolean req[] = {SL_BOOLEAN_TRUE};
result = (*p->engineEngine)->CreateAudioRecorder(p->engineEngine,
&(p->recorderObject), &audioSrc, &audioSnk, 1, id, req);
SLDataSink audioSnk = {&loc_bq, &format_pcm};
// create audio recorder
// (requires the RECORD_AUDIO permission)
const SLInterfaceID id[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE};
const SLboolean req[] = {SL_BOOLEAN_TRUE};
result = (*p->engineEngine)->CreateAudioRecorder(p->engineEngine,
&(p->recorderObject), &audioSrc, &audioSnk, 1, id, req);
DEBUG_DVC("p->recorderObject=%p", p->recorderObject);
assert(!result);
if (SL_RESULT_SUCCESS != result) goto end_recopen;
// realize the audio recorder
result = (*p->recorderObject)->Realize(p->recorderObject, SL_BOOLEAN_FALSE);
if (SL_RESULT_SUCCESS != result) goto end_recopen;
// realize the audio recorder
result = (*p->recorderObject)->Realize(p->recorderObject, SL_BOOLEAN_FALSE);
DEBUG_DVC("Realize=%d", result);
assert(!result);
if (SL_RESULT_SUCCESS != result) goto end_recopen;
// get the record interface
result = (*p->recorderObject)->GetInterface(p->recorderObject,
SL_IID_RECORD, &(p->recorderRecord));
if (SL_RESULT_SUCCESS != result) goto end_recopen;
// get the record interface
result = (*p->recorderObject)->GetInterface(p->recorderObject,
SL_IID_RECORD, &(p->recorderRecord));
DEBUG_DVC("p->recorderRecord=%p", p->recorderRecord);
assert(!result);
if (SL_RESULT_SUCCESS != result) goto end_recopen;
// get the buffer queue interface
result = (*p->recorderObject)->GetInterface(p->recorderObject,
SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
&(p->recorderBufferQueue));
DEBUG_DVC("p->recorderBufferQueue=%p", p->recorderBufferQueue);
assert(!result);
if (SL_RESULT_SUCCESS != result) goto end_recopen;
// register callback on the buffer queue
result = (*p->recorderBufferQueue)->RegisterCallback(p->recorderBufferQueue,
bqRecorderCallback, p);
if (SL_RESULT_SUCCESS != result) goto end_recopen;
// get the buffer queue interface
result = (*p->recorderObject)->GetInterface(p->recorderObject,
SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
&(p->recorderBufferQueue));
DEBUG_DVC("p->recorderBufferQueue=%p", p->recorderBufferQueue);
assert(!result);
if (SL_RESULT_SUCCESS != result)
if (SL_RESULT_SUCCESS != result) goto end_recopen;
// register callback on the buffer queue
result = (*p->recorderBufferQueue)->RegisterCallback(p->recorderBufferQueue,
bqRecorderCallback, p);
DEBUG_DVC("p->recorderBufferQueue=%p", p->recorderBufferQueue);
assert(!result);
if (SL_RESULT_SUCCESS != result)
goto end_recopen;
end_recopen:
return result;
}
else return SL_RESULT_SUCCESS;
end_recopen:
return result;
}
else return SL_RESULT_SUCCESS;
}
// close the OpenSL IO and destroy the audio engine
static void openSLDestroyEngine(OPENSL_STREAM *p)
static void openSLDestroyEngine(OPENSL_STREAM* p)
{
DEBUG_DVC("p=%p", p);
// destroy audio recorder object, and invalidate all associated interfaces
if (p->recorderObject != NULL) {
(*p->recorderObject)->Destroy(p->recorderObject);
p->recorderObject = NULL;
p->recorderRecord = NULL;
p->recorderBufferQueue = NULL;
}
// destroy engine object, and invalidate all associated interfaces
if (p->engineObject != NULL) {
(*p->engineObject)->Destroy(p->engineObject);
p->engineObject = NULL;
p->engineEngine = NULL;
}
// destroy audio recorder object, and invalidate all associated interfaces
if (p->recorderObject != NULL)
{
(*p->recorderObject)->Destroy(p->recorderObject);
p->recorderObject = NULL;
p->recorderRecord = NULL;
p->recorderBufferQueue = NULL;
}
// destroy engine object, and invalidate all associated interfaces
if (p->engineObject != NULL)
{
(*p->engineObject)->Destroy(p->engineObject);
p->engineObject = NULL;
p->engineEngine = NULL;
}
}
// open the android audio device for input
OPENSL_STREAM *android_OpenRecDevice(char *name, int sr, int inchannels,
int bufferframes, int bits_per_sample)
// open the android audio device for input
OPENSL_STREAM* android_OpenRecDevice(char* name, int sr, int inchannels,
int bufferframes, int bits_per_sample)
{
OPENSL_STREAM *p;
p = (OPENSL_STREAM *) calloc(sizeof(OPENSL_STREAM),1);
if (!p)
return NULL;
OPENSL_STREAM* p;
p = (OPENSL_STREAM*) calloc(sizeof(OPENSL_STREAM), 1);
p->inchannels = inchannels;
p->sr = sr;
if (!p)
return NULL;
p->inchannels = inchannels;
p->sr = sr;
p->queue = Queue_New(TRUE, -1, -1);
p->buffersize = bufferframes;
p->bits_per_sample = bits_per_sample;
if ((p->bits_per_sample != 8) && (p->bits_per_sample != 16))
{
android_CloseRecDevice(p);
android_CloseRecDevice(p);
return NULL;
}
if(openSLCreateEngine(p) != SL_RESULT_SUCCESS)
{
android_CloseRecDevice(p);
return NULL;
}
if(openSLRecOpen(p) != SL_RESULT_SUCCESS)
if (openSLCreateEngine(p) != SL_RESULT_SUCCESS)
{
android_CloseRecDevice(p);
return NULL;
}
android_CloseRecDevice(p);
return NULL;
}
return p;
if (openSLRecOpen(p) != SL_RESULT_SUCCESS)
{
android_CloseRecDevice(p);
return NULL;
}
return p;
}
// close the android audio device
void android_CloseRecDevice(OPENSL_STREAM *p)
void android_CloseRecDevice(OPENSL_STREAM* p)
{
DEBUG_DVC("p=%p", p);
if (p == NULL)
return;
if (p == NULL)
return;
if (p->queue)
{
while (Queue_Count(p->queue) > 0)
{
queue_element *e = Queue_Dequeue(p->queue);
queue_element* e = Queue_Dequeue(p->queue);
free(e->data);
free(e);
}
Queue_Free(p->queue);
}
@ -295,52 +317,47 @@ void android_CloseRecDevice(OPENSL_STREAM *p)
free(p->prep);
}
openSLDestroyEngine(p);
free(p);
openSLDestroyEngine(p);
free(p);
}
// this callback handler is called every time a buffer finishes recording
void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context)
static void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void* context)
{
queue_element *e;
OPENSL_STREAM *p = (OPENSL_STREAM *) context;
queue_element* e;
OPENSL_STREAM* p = (OPENSL_STREAM*) context;
DEBUG_DVC("p=%p", p);
assert(p);
assert(p->next);
assert(p->prep);
assert(p->queue);
e = calloc(1, sizeof(queue_element));
if (!e)
return;
e->data = calloc(p->buffersize, p->bits_per_sample / 8);
if (!e->data)
{
free(e);
return;
}
e->size = p->buffersize * p->bits_per_sample / 8;
e->size = p->buffersize * p->bits_per_sample / 8;
Queue_Enqueue(p->queue, p->next);
p->next = p->prep;
p->prep = e;
(*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue,
e->data, e->size);
(*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue,
e->data, e->size);
}
// gets a buffer of size samples from the device
int android_RecIn(OPENSL_STREAM *p,short *buffer,int size)
{
queue_element *e;
int rc;
DWORD status;
// gets a buffer of size samples from the device
int android_RecIn(OPENSL_STREAM* p, short* buffer, int size)
{
queue_element* e;
int rc;
DWORD status;
assert(p);
assert(buffer);
assert(size > 0);
@ -349,35 +366,33 @@ int android_RecIn(OPENSL_STREAM *p,short *buffer,int size)
if (!p->prep)
{
p->prep = calloc(1, sizeof(queue_element));
p->prep->data = calloc(p->buffersize, p->bits_per_sample / 8);
p->prep->size = p->buffersize * p->bits_per_sample / 8;
p->next = calloc(1, sizeof(queue_element));
p->next->data = calloc(p->buffersize, p->bits_per_sample / 8);
p->next->size = p->buffersize * p->bits_per_sample / 8;
(*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue,
p->next->data, p->next->size);
(*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue,
p->prep->data, p->prep->size);
(*p->recorderRecord)->SetRecordState(p->recorderRecord, SL_RECORDSTATE_RECORDING);
(*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue,
p->next->data, p->next->size);
(*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue,
p->prep->data, p->prep->size);
(*p->recorderRecord)->SetRecordState(p->recorderRecord,
SL_RECORDSTATE_RECORDING);
}
/* Wait for queue to be filled... */
if (!Queue_Count(p->queue))
{
status = WaitForSingleObject(p->queue->event, INFINITE);
if (status == WAIT_FAILED)
{
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", GetLastError());
return -1;
}
}
{
status = WaitForSingleObject(p->queue->event, INFINITE);
if (status == WAIT_FAILED)
{
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", (unsigned long)GetLastError());
return -1;
}
}
e = Queue_Dequeue(p->queue);
if (!e)
{
WLog_ERR(TAG, "[ERROR] got e=%p from queue", e);
@ -387,11 +402,9 @@ int android_RecIn(OPENSL_STREAM *p,short *buffer,int size)
rc = (e->size < size) ? e->size : size;
assert(size == e->size);
assert(p->buffersize * p->bits_per_sample / 8 == size);
memcpy(buffer, e->data, rc);
free(e->data);
free(e);
return rc;
return rc;
}

View File

@ -6,14 +6,14 @@ All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@ -36,6 +36,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <winpr/synch.h>
#include <winpr/collections.h>
#include <freerdp/api.h>
#include <stdlib.h>
#ifdef __cplusplus
@ -45,46 +47,48 @@ extern "C" {
typedef struct
{
size_t size;
void *data;
void* data;
} queue_element;
typedef struct opensl_stream {
// engine interfaces
SLObjectItf engineObject;
SLEngineItf engineEngine;
typedef struct opensl_stream
{
// engine interfaces
SLObjectItf engineObject;
SLEngineItf engineEngine;
// device interfaces
SLDeviceVolumeItf deviceVolume;
// recorder interfaces
SLObjectItf recorderObject;
SLRecordItf recorderRecord;
SLAndroidSimpleBufferQueueItf recorderBufferQueue;
// recorder interfaces
SLObjectItf recorderObject;
SLRecordItf recorderRecord;
SLAndroidSimpleBufferQueueItf recorderBufferQueue;
unsigned int inchannels;
unsigned int sr;
unsigned int inchannels;
unsigned int sr;
unsigned int buffersize;
unsigned int bits_per_sample;
wQueue *queue;
queue_element *prep;
queue_element *next;
wQueue* queue;
queue_element* prep;
queue_element* next;
} OPENSL_STREAM;
/*
Open the audio device with a given sampling rate (sr), input and output channels and IO buffer size
in frames. Returns a handle to the OpenSL stream
*/
OPENSL_STREAM* android_OpenRecDevice(char *name, int sr, int inchannels,
int bufferframes, int bits_per_sample);
/*
Close the audio device
*/
void android_CloseRecDevice(OPENSL_STREAM *p);
/*
Read a buffer from the OpenSL stream *p, of size samples. Returns the number of samples read.
*/
int android_RecIn(OPENSL_STREAM *p, short *buffer,int size);
/*
Open the audio device with a given sampling rate (sr), input and output channels and IO buffer size
in frames. Returns a handle to the OpenSL stream
*/
FREERDP_LOCAL OPENSL_STREAM* android_OpenRecDevice(char* name, int sr,
int inchannels,
int bufferframes, int bits_per_sample);
/*
Close the audio device
*/
FREERDP_LOCAL void android_CloseRecDevice(OPENSL_STREAM* p);
/*
Read a buffer from the OpenSL stream *p, of size samples. Returns the number of samples read.
*/
FREERDP_LOCAL int android_RecIn(OPENSL_STREAM* p, short* buffer, int size);
#ifdef __cplusplus
};
#endif

View File

@ -81,22 +81,25 @@ static int audin_oss_get_format(audinFormat* format)
switch (format->wFormatTag)
{
case WAVE_FORMAT_PCM:
switch (format->wBitsPerSample)
{
case 8:
return AFMT_S8;
case 16:
return AFMT_S16_LE;
}
break;
case WAVE_FORMAT_ALAW:
return AFMT_A_LAW;
#if 0 /* This does not work on my desktop. */
case WAVE_FORMAT_MULAW:
return AFMT_MU_LAW;
#endif
case WAVE_FORMAT_ADPCM:
case WAVE_FORMAT_DVI_ADPCM:
return AFMT_S16_LE;
@ -105,7 +108,8 @@ static int audin_oss_get_format(audinFormat* format)
return 0;
}
static BOOL audin_oss_format_supported(IAudinDevice* device, audinFormat* format)
static BOOL audin_oss_format_supported(IAudinDevice* device,
audinFormat* format)
{
int req_fmt = 0;
@ -115,20 +119,19 @@ static BOOL audin_oss_format_supported(IAudinDevice* device, audinFormat* format
switch (format->wFormatTag)
{
case WAVE_FORMAT_PCM:
if (format->cbSize != 0 ||
format->nSamplesPerSec > 48000 ||
(format->wBitsPerSample != 8 && format->wBitsPerSample != 16) ||
(format->nChannels != 1 && format->nChannels != 2))
format->nSamplesPerSec > 48000 ||
(format->wBitsPerSample != 8 && format->wBitsPerSample != 16) ||
(format->nChannels != 1 && format->nChannels != 2))
return FALSE;
break;
case WAVE_FORMAT_ADPCM:
case WAVE_FORMAT_DVI_ADPCM:
if (format->nSamplesPerSec > 48000 ||
format->wBitsPerSample != 4 ||
(format->nChannels != 1 && format->nChannels != 2))
format->wBitsPerSample != 4 ||
(format->nChannels != 1 && format->nChannels != 2))
return FALSE;
break;
@ -147,7 +150,8 @@ static BOOL audin_oss_format_supported(IAudinDevice* device, audinFormat* format
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT audin_oss_set_format(IAudinDevice* device, audinFormat* format, UINT32 FramesPerPacket)
static UINT audin_oss_set_format(IAudinDevice* device, audinFormat* format,
UINT32 FramesPerPacket)
{
AudinOSSDevice* oss = (AudinOSSDevice*)device;
@ -165,6 +169,7 @@ static UINT audin_oss_set_format(IAudinDevice* device, audinFormat* format, UINT
oss->format.wBitsPerSample *= 4;
break;
}
return CHANNEL_RC_OK;
}
@ -255,7 +260,8 @@ static void* audin_oss_thread_func(void* arg)
if (ioctl(pcm_handle, SNDCTL_DSP_SETFRAGMENT, &tmp) == -1)
OSS_LOG_ERR("SNDCTL_DSP_SETFRAGMENT failed", errno);
buffer_size = (oss->FramesPerPacket * oss->format.nChannels * (oss->format.wBitsPerSample / 8));
buffer_size = (oss->FramesPerPacket * oss->format.nChannels *
(oss->format.wBitsPerSample / 8));
buffer = (BYTE*)calloc((buffer_size + sizeof(void*)), sizeof(BYTE));
if (NULL == buffer)
@ -274,7 +280,7 @@ static void* audin_oss_thread_func(void* arg)
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error);
WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error);
goto err_out;
}
@ -294,44 +300,50 @@ static void* audin_oss_thread_func(void* arg)
continue;
/* Process. */
switch (oss->format.wFormatTag) {
case WAVE_FORMAT_ADPCM:
if (!oss->dsp_context->encode_ms_adpcm(oss->dsp_context,
buffer, buffer_size, oss->format.nChannels, oss->format.nBlockAlign))
{
error = ERROR_INTERNAL_ERROR;
goto err_out;
}
encoded_data = oss->dsp_context->adpcm_buffer;
encoded_size = oss->dsp_context->adpcm_size;
break;
case WAVE_FORMAT_DVI_ADPCM:
if (!oss->dsp_context->encode_ima_adpcm(oss->dsp_context,
buffer, buffer_size, oss->format.nChannels, oss->format.nBlockAlign))
{
error = ERROR_INTERNAL_ERROR;
goto err_out;
}
encoded_data = oss->dsp_context->adpcm_buffer;
encoded_size = oss->dsp_context->adpcm_size;
break;
default:
encoded_data = buffer;
encoded_size = buffer_size;
break;
}
if ((error = oss->receive(encoded_data, encoded_size, oss->user_data)))
switch (oss->format.wFormatTag)
{
WLog_ERR(TAG, "oss->receive failed with error %lu", error);
break;
case WAVE_FORMAT_ADPCM:
if (!oss->dsp_context->encode_ms_adpcm(oss->dsp_context,
buffer, buffer_size, oss->format.nChannels, oss->format.nBlockAlign))
{
error = ERROR_INTERNAL_ERROR;
goto err_out;
}
encoded_data = oss->dsp_context->adpcm_buffer;
encoded_size = oss->dsp_context->adpcm_size;
break;
case WAVE_FORMAT_DVI_ADPCM:
if (!oss->dsp_context->encode_ima_adpcm(oss->dsp_context,
buffer, buffer_size, oss->format.nChannels, oss->format.nBlockAlign))
{
error = ERROR_INTERNAL_ERROR;
goto err_out;
}
encoded_data = oss->dsp_context->adpcm_buffer;
encoded_size = oss->dsp_context->adpcm_size;
break;
default:
encoded_data = buffer;
encoded_size = buffer_size;
break;
}
if ((error = oss->receive(encoded_data, encoded_size, oss->user_data)))
{
WLog_ERR(TAG, "oss->receive failed with error %u", error);
break;
}
}
err_out:
if (error && oss->rdpcontext)
setChannelError(oss->rdpcontext, error, "audin_oss_thread_func reported an error");
setChannelError(oss->rdpcontext, error,
"audin_oss_thread_func reported an error");
if (pcm_handle != -1)
{
@ -349,9 +361,10 @@ err_out:
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT audin_oss_open(IAudinDevice *device, AudinReceive receive, void *user_data) {
AudinOSSDevice *oss = (AudinOSSDevice*)device;
static UINT audin_oss_open(IAudinDevice* device, AudinReceive receive,
void* user_data)
{
AudinOSSDevice* oss = (AudinOSSDevice*)device;
oss->receive = receive;
oss->user_data = user_data;
@ -360,8 +373,9 @@ static UINT audin_oss_open(IAudinDevice *device, AudinReceive receive, void *use
WLog_ERR(TAG, "CreateEvent failed!");
return ERROR_INTERNAL_ERROR;
}
if (!(oss->thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)audin_oss_thread_func, oss, 0, NULL)))
(LPTHREAD_START_ROUTINE)audin_oss_thread_func, oss, 0, NULL)))
{
WLog_ERR(TAG, "CreateThread failed!");
CloseHandle(oss->stopEvent);
@ -377,10 +391,10 @@ static UINT audin_oss_open(IAudinDevice *device, AudinReceive receive, void *use
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT audin_oss_close(IAudinDevice *device)
static UINT audin_oss_close(IAudinDevice* device)
{
UINT error;
AudinOSSDevice *oss = (AudinOSSDevice*)device;
AudinOSSDevice* oss = (AudinOSSDevice*)device;
if (device == NULL)
return ERROR_INVALID_PARAMETER;
@ -388,12 +402,14 @@ static UINT audin_oss_close(IAudinDevice *device)
if (oss->stopEvent != NULL)
{
SetEvent(oss->stopEvent);
if (WaitForSingleObject(oss->thread, INFINITE) == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error);
WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error);
return error;
}
CloseHandle(oss->stopEvent);
oss->stopEvent = NULL;
CloseHandle(oss->thread);
@ -402,7 +418,6 @@ static UINT audin_oss_close(IAudinDevice *device)
oss->receive = NULL;
oss->user_data = NULL;
return CHANNEL_RC_OK;
}
@ -413,8 +428,7 @@ static UINT audin_oss_close(IAudinDevice *device)
*/
static UINT audin_oss_free(IAudinDevice* device)
{
AudinOSSDevice *oss = (AudinOSSDevice*)device;
AudinOSSDevice* oss = (AudinOSSDevice*)device;
int error;
if (device == NULL)
@ -424,9 +438,9 @@ static UINT audin_oss_free(IAudinDevice* device)
{
WLog_ERR(TAG, "audin_oss_close failed with error code %d!", error);
}
freerdp_dsp_context_free(oss->dsp_context);
free(oss);
return CHANNEL_RC_OK;
}
@ -441,15 +455,17 @@ COMMAND_LINE_ARGUMENT_A audin_oss_args[] =
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT audin_oss_parse_addin_args(AudinOSSDevice *device, ADDIN_ARGV *args)
static UINT audin_oss_parse_addin_args(AudinOSSDevice* device, ADDIN_ARGV* args)
{
int status;
char* str_num, *eptr;
DWORD flags;
COMMAND_LINE_ARGUMENT_A* arg;
AudinOSSDevice* oss = (AudinOSSDevice*)device;
flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON | COMMAND_LINE_IGN_UNKNOWN_KEYWORD;
status = CommandLineParseArgumentsA(args->argc, (const char**)args->argv, audin_oss_args, flags, oss, NULL, NULL);
flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON |
COMMAND_LINE_IGN_UNKNOWN_KEYWORD;
status = CommandLineParseArgumentsA(args->argc, (const char**)args->argv,
audin_oss_args, flags, oss, NULL, NULL);
if (status < 0)
return ERROR_INVALID_PARAMETER;
@ -465,11 +481,13 @@ static UINT audin_oss_parse_addin_args(AudinOSSDevice *device, ADDIN_ARGV *args)
CommandLineSwitchCase(arg, "dev")
{
str_num = _strdup(arg->Value);
if (!str_num)
{
WLog_ERR(TAG, "_strdup failed!");
return CHANNEL_RC_NO_MEMORY;
}
oss->dev_unit = strtol(str_num, &eptr, 10);
if (oss->dev_unit < 0 || *eptr != '\0')
@ -480,10 +498,11 @@ static UINT audin_oss_parse_addin_args(AudinOSSDevice *device, ADDIN_ARGV *args)
CommandLineSwitchEnd(arg)
}
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
return CHANNEL_RC_OK;
}
#ifdef STATIC_CHANNELS
#ifdef BUILTIN_CHANNELS
#define freerdp_audin_client_subsystem_entry oss_freerdp_audin_client_subsystem_entry
#else
#define freerdp_audin_client_subsystem_entry FREERDP_API freerdp_audin_client_subsystem_entry
@ -494,13 +513,14 @@ static UINT audin_oss_parse_addin_args(AudinOSSDevice *device, ADDIN_ARGV *args)
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints)
UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS
pEntryPoints)
{
ADDIN_ARGV *args;
AudinOSSDevice *oss;
ADDIN_ARGV* args;
AudinOSSDevice* oss;
UINT error;
oss = (AudinOSSDevice*)calloc(1, sizeof(AudinOSSDevice));
if (!oss)
{
WLog_ERR(TAG, "calloc failed!");
@ -513,17 +533,17 @@ UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEn
oss->iface.Close = audin_oss_close;
oss->iface.Free = audin_oss_free;
oss->rdpcontext = pEntryPoints->rdpcontext;
oss->dev_unit = -1;
args = pEntryPoints->args;
if ((error = audin_oss_parse_addin_args(oss, args)))
{
WLog_ERR(TAG, "audin_oss_parse_addin_args failed with errorcode %lu!", error);
WLog_ERR(TAG, "audin_oss_parse_addin_args failed with errorcode %u!", error);
goto error_out;
}
oss->dsp_context = freerdp_dsp_context_new();
if (!oss->dsp_context)
{
WLog_ERR(TAG, "freerdp_dsp_context_new failed!");
@ -531,9 +551,10 @@ UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEn
goto error_out;
}
if ((error = pEntryPoints->pRegisterAudinDevice(pEntryPoints->plugin, (IAudinDevice*) oss)))
if ((error = pEntryPoints->pRegisterAudinDevice(pEntryPoints->plugin,
(IAudinDevice*) oss)))
{
WLog_ERR(TAG, "RegisterAudinDevice failed with error %lu!", error);
WLog_ERR(TAG, "RegisterAudinDevice failed with error %u!", error);
goto error_out;
}
@ -542,5 +563,4 @@ error_out:
freerdp_dsp_context_free(oss->dsp_context);
free(oss);
return error;
}

View File

@ -523,7 +523,7 @@ static UINT audin_pulse_parse_addin_args(AudinPulseDevice* device, ADDIN_ARGV* a
return CHANNEL_RC_OK;
}
#ifdef STATIC_CHANNELS
#ifdef BUILTIN_CHANNELS
#define freerdp_audin_client_subsystem_entry pulse_freerdp_audin_client_subsystem_entry
#else
#define freerdp_audin_client_subsystem_entry FREERDP_API freerdp_audin_client_subsystem_entry
@ -558,7 +558,7 @@ UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEn
if ((error = audin_pulse_parse_addin_args(pulse, args)))
{
WLog_ERR(TAG, "audin_pulse_parse_addin_args failed with error %lu!", error);
WLog_ERR(TAG, "audin_pulse_parse_addin_args failed with error %u!", error);
goto error_out;
}
@ -598,7 +598,7 @@ UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEn
if ((error = pEntryPoints->pRegisterAudinDevice(pEntryPoints->plugin, (IAudinDevice*) pulse)))
{
WLog_ERR(TAG, "RegisterAudinDevice failed with error %lu!", error);
WLog_ERR(TAG, "RegisterAudinDevice failed with error %u!", error);
goto error_out;
}

View File

@ -26,12 +26,12 @@ add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_N
set(${MODULE_PREFIX}_LIBS freerdp winmm.lib)
set(${MODULE_PREFIX}_LIBS freerdp winpr winmm.lib)
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS)
if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS)
install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols)
endif()

View File

@ -230,7 +230,7 @@ static UINT audin_winmm_close(IAudinDevice* device)
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error);
return error;
}
@ -391,7 +391,7 @@ static UINT audin_winmm_parse_addin_args(AudinWinmmDevice* device, ADDIN_ARGV* a
return CHANNEL_RC_OK;
}
#ifdef STATIC_CHANNELS
#ifdef BUILTIN_CHANNELS
#define freerdp_audin_client_subsystem_entry winmm_freerdp_audin_client_subsystem_entry
#else
#define freerdp_audin_client_subsystem_entry FREERDP_API freerdp_audin_client_subsystem_entry

View File

@ -69,13 +69,15 @@ typedef struct _audin_server
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT audin_server_select_format(audin_server_context* context, int client_format_index)
static UINT audin_server_select_format(audin_server_context* context,
int client_format_index)
{
audin_server* audin = (audin_server*) context;
if (client_format_index >= context->num_client_formats)
{
WLog_ERR(TAG, "error in protocol: client_format_index >= context->num_client_formats!");
WLog_ERR(TAG,
"error in protocol: client_format_index >= context->num_client_formats!");
return ERROR_INVALID_DATA;
}
@ -85,6 +87,7 @@ static UINT audin_server_select_format(audin_server_context* context, int client
{
/* TODO: send MSG_SNDIN_FORMATCHANGE */
}
return CHANNEL_RC_OK;
}
@ -96,14 +99,16 @@ static UINT audin_server_select_format(audin_server_context* context, int client
static UINT audin_server_send_version(audin_server* audin, wStream* s)
{
ULONG written;
Stream_Write_UINT8(s, MSG_SNDIN_VERSION);
Stream_Write_UINT32(s, 1); /* Version (4 bytes) */
if (!WTSVirtualChannelWrite(audin->audin_channel, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written))
if (!WTSVirtualChannelWrite(audin->audin_channel, (PCHAR) Stream_Buffer(s),
Stream_GetPosition(s), &written))
{
WLog_ERR(TAG, "WTSVirtualChannelWrite failed!");
return ERROR_INTERNAL_ERROR;
}
return CHANNEL_RC_OK;
}
@ -112,13 +117,15 @@ static UINT audin_server_send_version(audin_server* audin, wStream* s)
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT audin_server_recv_version(audin_server* audin, wStream* s, UINT32 length)
static UINT audin_server_recv_version(audin_server* audin, wStream* s,
UINT32 length)
{
UINT32 Version;
if (length < 4)
{
WLog_ERR(TAG, "error parsing version info: expected at least 4 bytes, got %d", length);
WLog_ERR(TAG, "error parsing version info: expected at least 4 bytes, got %d",
length);
return ERROR_INVALID_DATA;
}
@ -143,17 +150,18 @@ static UINT audin_server_send_formats(audin_server* audin, wStream* s)
int i;
UINT32 nAvgBytesPerSec;
ULONG written;
Stream_SetPosition(s, 0);
Stream_Write_UINT8(s, MSG_SNDIN_FORMATS);
Stream_Write_UINT32(s, audin->context.num_server_formats); /* NumFormats (4 bytes) */
Stream_Write_UINT32(s, 0); /* cbSizeFormatsPacket (4 bytes), client-to-server only */
Stream_Write_UINT32(s,
audin->context.num_server_formats); /* NumFormats (4 bytes) */
Stream_Write_UINT32(s,
0); /* cbSizeFormatsPacket (4 bytes), client-to-server only */
for (i = 0; i < audin->context.num_server_formats; i++)
{
nAvgBytesPerSec = audin->context.server_formats[i].nSamplesPerSec *
audin->context.server_formats[i].nChannels *
audin->context.server_formats[i].wBitsPerSample / 8;
audin->context.server_formats[i].nChannels *
audin->context.server_formats[i].wBitsPerSample / 8;
if (!Stream_EnsureRemainingCapacity(s, 18))
{
@ -178,11 +186,12 @@ static UINT audin_server_send_formats(audin_server* audin, wStream* s)
}
Stream_Write(s, audin->context.server_formats[i].data,
audin->context.server_formats[i].cbSize);
audin->context.server_formats[i].cbSize);
}
}
return WTSVirtualChannelWrite(audin->audin_channel, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written) ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR;
return WTSVirtualChannelWrite(audin->audin_channel, (PCHAR) Stream_Buffer(s),
Stream_GetPosition(s), &written) ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR;
}
/**
@ -190,29 +199,36 @@ static UINT audin_server_send_formats(audin_server* audin, wStream* s)
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT audin_server_recv_formats(audin_server* audin, wStream* s, UINT32 length)
static UINT audin_server_recv_formats(audin_server* audin, wStream* s,
UINT32 length)
{
int i;
UINT success = CHANNEL_RC_OK;
if (length < 8)
{
WLog_ERR(TAG, "error parsing rec formats: expected at least 8 bytes, got %d", length);
WLog_ERR(TAG, "error parsing rec formats: expected at least 8 bytes, got %d",
length);
return ERROR_INVALID_DATA;
}
Stream_Read_UINT32(s, audin->context.num_client_formats); /* NumFormats (4 bytes) */
Stream_Read_UINT32(s,
audin->context.num_client_formats); /* NumFormats (4 bytes) */
Stream_Seek_UINT32(s); /* cbSizeFormatsPacket (4 bytes) */
length -= 8;
if (audin->context.num_client_formats <= 0)
{
WLog_ERR(TAG, "num_client_formats expected > 0 but got %d", audin->context.num_client_formats);
WLog_ERR(TAG, "num_client_formats expected > 0 but got %d",
audin->context.num_client_formats);
return ERROR_INVALID_DATA;
}
audin->context.client_formats = malloc(audin->context.num_client_formats * sizeof(AUDIO_FORMAT));
ZeroMemory(audin->context.client_formats, audin->context.num_client_formats * sizeof(AUDIO_FORMAT));
audin->context.client_formats = calloc(audin->context.num_client_formats,
sizeof(AUDIO_FORMAT));
if (!audin->context.client_formats)
return ERROR_NOT_ENOUGH_MEMORY;
for (i = 0; i < audin->context.num_client_formats; i++)
{
@ -239,8 +255,10 @@ static UINT audin_server_recv_formats(audin_server* audin, wStream* s, UINT32 le
}
IFCALLRET(audin->context.Opening, success, &audin->context);
if (success)
WLog_ERR(TAG, "context.Opening failed with error %lu", success);
if (success)
WLog_ERR(TAG, "context.Opening failed with error %u", success);
return success;
}
@ -256,16 +274,17 @@ static UINT audin_server_send_open(audin_server* audin, wStream* s)
if (audin->context.selected_client_format < 0)
{
WLog_ERR(TAG, "audin->context.selected_client_format = %d",
audin->context.selected_client_format);
audin->context.selected_client_format);
return ERROR_INVALID_DATA;
}
audin->opened = TRUE;
Stream_SetPosition(s, 0);
Stream_Write_UINT8(s, MSG_SNDIN_OPEN);
Stream_Write_UINT32(s, audin->context.frames_per_packet); /* FramesPerPacket (4 bytes) */
Stream_Write_UINT32(s, audin->context.selected_client_format); /* initialFormat (4 bytes) */
Stream_Write_UINT32(s,
audin->context.frames_per_packet); /* FramesPerPacket (4 bytes) */
Stream_Write_UINT32(s,
audin->context.selected_client_format); /* initialFormat (4 bytes) */
/*
* [MS-RDPEAI] 3.2.5.1.6
* The second format specify the format that SHOULD be used to capture data from
@ -278,8 +297,8 @@ static UINT audin_server_send_open(audin_server* audin, wStream* s)
Stream_Write_UINT16(s, 4); /* nBlockAlign */
Stream_Write_UINT16(s, 16); /* wBitsPerSample */
Stream_Write_UINT16(s, 0); /* cbSize */
return WTSVirtualChannelWrite(audin->audin_channel, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written) ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR;
return WTSVirtualChannelWrite(audin->audin_channel, (PCHAR) Stream_Buffer(s),
Stream_GetPosition(s), &written) ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR;
}
/**
@ -287,24 +306,24 @@ static UINT audin_server_send_open(audin_server* audin, wStream* s)
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT audin_server_recv_open_reply(audin_server* audin, wStream* s, UINT32 length)
static UINT audin_server_recv_open_reply(audin_server* audin, wStream* s,
UINT32 length)
{
UINT32 Result;
UINT success = CHANNEL_RC_OK;
if (length < 4)
{
WLog_ERR(TAG, "error parsing version info: expected at least 4 bytes, got %d", length);
WLog_ERR(TAG, "error parsing version info: expected at least 4 bytes, got %d",
length);
return ERROR_INVALID_DATA;
}
Stream_Read_UINT32(s, Result);
IFCALLRET(audin->context.OpenResult, success, &audin->context, Result);
if (success)
WLog_ERR(TAG, "context.OpenResult failed with error %lu", success);
if (success)
WLog_ERR(TAG, "context.OpenResult failed with error %u", success);
return success;
}
@ -314,7 +333,8 @@ static UINT audin_server_recv_open_reply(audin_server* audin, wStream* s, UINT32
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT audin_server_recv_data(audin_server* audin, wStream* s, UINT32 length)
static UINT audin_server_recv_data(audin_server* audin, wStream* s,
UINT32 length)
{
AUDIO_FORMAT* format;
int sbytes_per_sample;
@ -327,7 +347,7 @@ static UINT audin_server_recv_data(audin_server* audin, wStream* s, UINT32 lengt
if (audin->context.selected_client_format < 0)
{
WLog_ERR(TAG, "audin->context.selected_client_format = %d",
audin->context.selected_client_format);
audin->context.selected_client_format);
return ERROR_INVALID_DATA;
}
@ -336,7 +356,7 @@ static UINT audin_server_recv_data(audin_server* audin, wStream* s, UINT32 lengt
if (format->wFormatTag == WAVE_FORMAT_ADPCM)
{
audin->dsp_context->decode_ms_adpcm(audin->dsp_context,
Stream_Pointer(s), length, format->nChannels, format->nBlockAlign);
Stream_Pointer(s), length, format->nChannels, format->nBlockAlign);
size = audin->dsp_context->adpcm_size;
src = audin->dsp_context->adpcm_buffer;
sbytes_per_sample = 2;
@ -345,7 +365,7 @@ static UINT audin_server_recv_data(audin_server* audin, wStream* s, UINT32 lengt
else if (format->wFormatTag == WAVE_FORMAT_DVI_ADPCM)
{
audin->dsp_context->decode_ima_adpcm(audin->dsp_context,
Stream_Pointer(s), length, format->nChannels, format->nBlockAlign);
Stream_Pointer(s), length, format->nChannels, format->nBlockAlign);
size = audin->dsp_context->adpcm_size;
src = audin->dsp_context->adpcm_buffer;
sbytes_per_sample = 2;
@ -359,25 +379,26 @@ static UINT audin_server_recv_data(audin_server* audin, wStream* s, UINT32 lengt
sbytes_per_frame = format->nChannels * sbytes_per_sample;
}
if (format->nSamplesPerSec == audin->context.dst_format.nSamplesPerSec && format->nChannels == audin->context.dst_format.nChannels)
if (format->nSamplesPerSec == audin->context.dst_format.nSamplesPerSec
&& format->nChannels == audin->context.dst_format.nChannels)
{
frames = size / sbytes_per_frame;
}
else
{
audin->dsp_context->resample(audin->dsp_context, src, sbytes_per_sample,
format->nChannels, format->nSamplesPerSec, size / sbytes_per_frame,
audin->context.dst_format.nChannels, audin->context.dst_format.nSamplesPerSec);
format->nChannels, format->nSamplesPerSec, size / sbytes_per_frame,
audin->context.dst_format.nChannels, audin->context.dst_format.nSamplesPerSec);
frames = audin->dsp_context->resampled_frames;
src = audin->dsp_context->resampled_buffer;
}
IFCALLRET(audin->context.ReceiveSamples, success, &audin->context, src, frames);
if (success)
WLog_ERR(TAG, "context.ReceiveSamples failed with error %lu", success);
if (success)
WLog_ERR(TAG, "context.ReceiveSamples failed with error %u", success);
return success;
return success;
}
static void* audin_server_thread_func(void* arg)
@ -393,12 +414,12 @@ static void* audin_server_thread_func(void* arg)
audin_server* audin = (audin_server*) arg;
UINT error = CHANNEL_RC_OK;
DWORD status;
buffer = NULL;
BytesReturned = 0;
ChannelEvent = NULL;
if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE)
if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualEventHandle, &buffer,
&BytesReturned) == TRUE)
{
if (BytesReturned == sizeof(HANDLE))
CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE));
@ -420,17 +441,19 @@ static void* audin_server_thread_func(void* arg)
while (1)
{
if ((status = WaitForMultipleObjects(nCount, events, FALSE, 100)) == WAIT_OBJECT_0)
if ((status = WaitForMultipleObjects(nCount, events, FALSE,
100)) == WAIT_OBJECT_0)
goto out;
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error);
error = GetLastError();
WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u", error);
goto out;
}
if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualChannelReady, &buffer, &BytesReturned) == FALSE)
if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualChannelReady,
&buffer, &BytesReturned) == FALSE)
{
WLog_ERR(TAG, "WTSVirtualChannelQuery failed");
error = ERROR_INTERNAL_ERROR;
@ -438,7 +461,6 @@ static void* audin_server_thread_func(void* arg)
}
ready = *((BOOL*) buffer);
WTSFreeMemory(buffer);
if (ready)
@ -446,6 +468,7 @@ static void* audin_server_thread_func(void* arg)
}
s = Stream_New(NULL, 4096);
if (!s)
{
WLog_ERR(TAG, "Stream_New failed!");
@ -453,26 +476,26 @@ static void* audin_server_thread_func(void* arg)
goto out;
}
if (ready)
{
if ((error = audin_server_send_version(audin, s)))
{
WLog_ERR(TAG, "audin_server_send_version failed with error %lu!", error);
WLog_ERR(TAG, "audin_server_send_version failed with error %u!", error);
goto out_capacity;
}
}
while (ready)
{
if ((status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE)) == WAIT_OBJECT_0)
if ((status = WaitForMultipleObjects(nCount, events, FALSE,
INFINITE)) == WAIT_OBJECT_0)
break;
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error);
goto out;
error = GetLastError();
WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u", error);
goto out;
}
Stream_SetPosition(s, 0);
@ -483,12 +506,15 @@ static void* audin_server_thread_func(void* arg)
error = ERROR_INTERNAL_ERROR;
break;
}
if (BytesReturned < 1)
continue;
if (!Stream_EnsureRemainingCapacity(s, BytesReturned))
break;
if (WTSVirtualChannelRead(audin->audin_channel, 0, (PCHAR) Stream_Buffer(s),
Stream_Capacity(s), &BytesReturned) == FALSE)
Stream_Capacity(s), &BytesReturned) == FALSE)
{
WLog_ERR(TAG, "WTSVirtualChannelRead failed!");
error = ERROR_INTERNAL_ERROR;
@ -503,35 +529,40 @@ static void* audin_server_thread_func(void* arg)
case MSG_SNDIN_VERSION:
if ((error = audin_server_recv_version(audin, s, BytesReturned)))
{
WLog_ERR(TAG, "audin_server_recv_version failed with error %lu!", error);
goto out_capacity;
}
if ((error = audin_server_send_formats(audin, s)))
{
WLog_ERR(TAG, "audin_server_send_formats failed with error %lu!", error);
WLog_ERR(TAG, "audin_server_recv_version failed with error %u!", error);
goto out_capacity;
}
if ((error = audin_server_send_formats(audin, s)))
{
WLog_ERR(TAG, "audin_server_send_formats failed with error %u!", error);
goto out_capacity;
}
break;
case MSG_SNDIN_FORMATS:
if ((error = audin_server_recv_formats(audin, s, BytesReturned)))
{
WLog_ERR(TAG, "audin_server_recv_formats failed with error %lu!", error);
WLog_ERR(TAG, "audin_server_recv_formats failed with error %u!", error);
goto out_capacity;
}
if ((error = audin_server_send_open(audin, s)))
{
WLog_ERR(TAG, "audin_server_send_open failed with error %lu!", error);
WLog_ERR(TAG, "audin_server_send_open failed with error %u!", error);
goto out_capacity;
}
break;
case MSG_SNDIN_OPEN_REPLY:
if ((error = audin_server_recv_open_reply(audin, s, BytesReturned)))
{
WLog_ERR(TAG, "audin_server_recv_open_reply failed with error %lu!", error);
WLog_ERR(TAG, "audin_server_recv_open_reply failed with error %u!", error);
goto out_capacity;
}
break;
case MSG_SNDIN_DATA_INCOMING:
@ -540,9 +571,10 @@ static void* audin_server_thread_func(void* arg)
case MSG_SNDIN_DATA:
if ((error = audin_server_recv_data(audin, s, BytesReturned)))
{
WLog_ERR(TAG, "audin_server_recv_data failed with error %lu!", error);
WLog_ERR(TAG, "audin_server_recv_data failed with error %u!", error);
goto out_capacity;
};
break;
case MSG_SNDIN_FORMATCHANGE:
@ -559,8 +591,10 @@ out_capacity:
out:
WTSVirtualChannelClose(audin->audin_channel);
audin->audin_channel = NULL;
if (error && audin->context.rdpcontext)
setChannelError(audin->context.rdpcontext, error, "audin_server_thread_func reported an error");
setChannelError(audin->context.rdpcontext, error,
"audin_server_thread_func reported an error");
ExitThread((DWORD)error);
return NULL;
@ -574,18 +608,17 @@ static BOOL audin_server_open(audin_server_context* context)
{
PULONG pSessionId = NULL;
DWORD BytesReturned = 0;
audin->SessionId = WTS_CURRENT_SESSION;
if (WTSQuerySessionInformationA(context->vcm, WTS_CURRENT_SESSION,
WTSSessionId, (LPSTR*) &pSessionId, &BytesReturned))
WTSSessionId, (LPSTR*) &pSessionId, &BytesReturned))
{
audin->SessionId = (DWORD) *pSessionId;
audin->SessionId = (DWORD) * pSessionId;
WTSFreeMemory(pSessionId);
}
audin->audin_channel = WTSVirtualChannelOpenEx(audin->SessionId,
"AUDIO_INPUT", WTS_CHANNEL_OPTION_DYNAMIC);
"AUDIO_INPUT", WTS_CHANNEL_OPTION_DYNAMIC);
if (!audin->audin_channel)
{
@ -600,7 +633,7 @@ static BOOL audin_server_open(audin_server_context* context)
}
if (!(audin->thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) audin_server_thread_func, (void*) audin, 0, NULL)))
(LPTHREAD_START_ROUTINE) audin_server_thread_func, (void*) audin, 0, NULL)))
{
WLog_ERR(TAG, "CreateThread failed!");
CloseHandle(audin->stopEvent);
@ -610,6 +643,7 @@ static BOOL audin_server_open(audin_server_context* context)
return TRUE;
}
WLog_ERR(TAG, "thread already running!");
return FALSE;
}
@ -621,11 +655,12 @@ static BOOL audin_server_close(audin_server_context* context)
if (audin->thread)
{
SetEvent(audin->stopEvent);
if (WaitForSingleObject(audin->thread, INFINITE) == WAIT_FAILED)
{
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", GetLastError());
return FALSE;
}
{
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", (unsigned long)GetLastError());
return FALSE;
}
CloseHandle(audin->thread);
CloseHandle(audin->stopEvent);
@ -640,15 +675,14 @@ static BOOL audin_server_close(audin_server_context* context)
}
audin->context.selected_client_format = -1;
return TRUE;
}
audin_server_context* audin_server_context_new(HANDLE vcm)
{
audin_server* audin;
audin = (audin_server*)calloc(1, sizeof(audin_server));
audin = (audin_server *)calloc(1, sizeof(audin_server));
if (!audin)
{
WLog_ERR(TAG, "calloc failed!");
@ -661,7 +695,6 @@ audin_server_context* audin_server_context_new(HANDLE vcm)
audin->context.SelectFormat = audin_server_select_format;
audin->context.Open = audin_server_open;
audin->context.Close = audin_server_close;
audin->dsp_context = freerdp_dsp_context_new();
if (!audin->dsp_context)
@ -677,7 +710,6 @@ audin_server_context* audin_server_context_new(HANDLE vcm)
void audin_server_context_free(audin_server_context* context)
{
audin_server* audin = (audin_server*) context;
audin_server_close(context);
if (audin->dsp_context)

View File

@ -25,7 +25,7 @@ set(${MODULE_PREFIX}_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/addin.h)
if(CHANNEL_STATIC_CLIENT_ENTRIES)
list(REMOVE_DUPLICATES CHANNEL_STATIC_CLIENT_ENTRIES)
list(REMOVE_DUPLICATES CHANNEL_STATIC_CLIENT_ENTRIES)
endif()
foreach(STATIC_ENTRY ${CHANNEL_STATIC_CLIENT_ENTRIES})
@ -38,6 +38,8 @@ foreach(STATIC_ENTRY ${CHANNEL_STATIC_CLIENT_ENTRIES})
set(ENTRY_POINT_NAME "${STATIC_MODULE_CHANNEL}_${${STATIC_MODULE}_CLIENT_ENTRY}")
if(${${STATIC_MODULE}_CLIENT_ENTRY} STREQUAL "VirtualChannelEntry")
set(ENTRY_POINT_IMPORT "extern BOOL VCAPITYPE ${ENTRY_POINT_NAME}(PCHANNEL_ENTRY_POINTS);")
elseif(${${STATIC_MODULE}_CLIENT_ENTRY} STREQUAL "VirtualChannelEntryEx")
set(ENTRY_POINT_IMPORT "extern BOOL VCAPITYPE ${ENTRY_POINT_NAME}(PCHANNEL_ENTRY_POINTS,PVOID);")
else()
set(ENTRY_POINT_IMPORT "extern UINT ${ENTRY_POINT_NAME}();")
endif()

View File

@ -349,6 +349,24 @@ void freerdp_channels_addin_list_free(FREERDP_ADDIN** ppAddins)
free(ppAddins);
}
extern const STATIC_ENTRY CLIENT_VirtualChannelEntryEx_TABLE[];
BOOL freerdp_channels_is_virtual_channel_entry_ex(LPCSTR pszName)
{
int i;
STATIC_ENTRY* entry;
for (i = 0; CLIENT_VirtualChannelEntryEx_TABLE[i].name != NULL; i++)
{
entry = (STATIC_ENTRY*) &CLIENT_VirtualChannelEntryEx_TABLE[i];
if (!strcmp(entry->name, pszName))
return TRUE;
}
return FALSE;
}
void* freerdp_channels_load_static_addin_entry(LPCSTR pszName, LPSTR pszSubsystem, LPSTR pszType, DWORD dwFlags)
{
int i, j;
@ -380,6 +398,12 @@ void* freerdp_channels_load_static_addin_entry(LPCSTR pszName, LPSTR pszSubsyste
}
else
{
if (dwFlags & FREERDP_ADDIN_CHANNEL_ENTRYEX)
{
if (!freerdp_channels_is_virtual_channel_entry_ex(pszName))
return NULL;
}
return (void*) CLIENT_STATIC_ADDIN_TABLE[i].entry;
}
}

View File

@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS
cliprdr_main.c
cliprdr_main.h)
add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntry")
add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntryEx")
set(${MODULE_PREFIX}_LIBS freerdp winpr)

View File

@ -265,7 +265,7 @@ UINT cliprdr_process_format_list_response(cliprdrPlugin* cliprdr, wStream* s, UI
IFCALLRET(context->ServerFormatListResponse, error, context, &formatListResponse);
if (error)
WLog_ERR(TAG, "ServerFormatListResponse failed with error %lu!", error);
WLog_ERR(TAG, "ServerFormatListResponse failed with error %u!", error);
return error;
}
@ -298,7 +298,7 @@ UINT cliprdr_process_format_data_request(cliprdrPlugin* cliprdr, wStream* s, UIN
IFCALLRET(context->ServerFormatDataRequest, error, context, &formatDataRequest);
if (error)
WLog_ERR(TAG, "ServerFormatDataRequest failed with error %lu!", error);
WLog_ERR(TAG, "ServerFormatDataRequest failed with error %u!", error);
return error;
}
@ -332,7 +332,7 @@ UINT cliprdr_process_format_data_response(cliprdrPlugin* cliprdr, wStream* s, UI
IFCALLRET(context->ServerFormatDataResponse, error, context, &formatDataResponse);
if (error)
WLog_ERR(TAG, "ServerFormatDataResponse failed with error %lu!", error);
WLog_ERR(TAG, "ServerFormatDataResponse failed with error %u!", error);
return error;
}

File diff suppressed because it is too large Load Diff

View File

@ -33,7 +33,7 @@
struct cliprdr_plugin
{
CHANNEL_DEF channelDef;
CHANNEL_ENTRY_POINTS_FREERDP channelEntryPoints;
CHANNEL_ENTRY_POINTS_FREERDP_EX channelEntryPoints;
CliprdrClientContext* context;
@ -52,15 +52,12 @@ struct cliprdr_plugin
};
typedef struct cliprdr_plugin cliprdrPlugin;
wStream* cliprdr_packet_new(UINT16 msgType, UINT16 msgFlags, UINT32 dataLen);
UINT cliprdr_packet_send(cliprdrPlugin* cliprdr, wStream* data_out);
CliprdrClientContext* cliprdr_get_client_interface(cliprdrPlugin* cliprdr);
#ifdef WITH_DEBUG_CLIPRDR
#define DEBUG_CLIPRDR(fmt, ...) WLog_DBG(TAG, fmt, ## __VA_ARGS__)
#define DEBUG_CLIPRDR(...) WLog_DBG(TAG, __VA_ARGS__)
#else
#define DEBUG_CLIPRDR(fmt, ...) do { } while (0)
#define DEBUG_CLIPRDR(...) do { } while (0)
#endif
#endif /* __CLIPRDR_MAIN_H */

File diff suppressed because it is too large Load Diff

View File

@ -32,7 +32,7 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} winpr)
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS)
if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS)
install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols)
endif()

6
channels/disp/client/disp_main.c Normal file → Executable file
View File

@ -5,6 +5,7 @@
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2015 Thincast Technologies GmbH
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
* Copyright 2016 David PHAM-VAN <d.phamvan@inuvika.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -317,6 +318,9 @@ static UINT disp_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManage
*/
static UINT disp_plugin_terminated(IWTSPlugin* pPlugin)
{
DISP_PLUGIN* disp = (DISP_PLUGIN*) pPlugin;
free(disp->listener_callback);
free(disp->iface.pInterface);
free(pPlugin);
return CHANNEL_RC_OK;
}
@ -338,7 +342,7 @@ UINT disp_send_monitor_layout(DispClientContext* context, UINT32 NumMonitors, DI
return disp_send_display_control_monitor_layout_pdu(callback, NumMonitors, Monitors);
}
#ifdef STATIC_CHANNELS
#ifdef BUILTIN_CHANNELS
#define DVCPluginEntry disp_DVCPluginEntry
#else
#define DVCPluginEntry FREERDP_API DVCPluginEntry

View File

@ -21,7 +21,7 @@ set(${MODULE_PREFIX}_SRCS
drdynvc_main.c
drdynvc_main.h)
add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntry")
add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntryEx")
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")

File diff suppressed because it is too large Load Diff

View File

@ -115,7 +115,7 @@ typedef enum _DRDYNVC_STATE DRDYNVC_STATE;
struct drdynvc_plugin
{
CHANNEL_DEF channelDef;
CHANNEL_ENTRY_POINTS_FREERDP channelEntryPoints;
CHANNEL_ENTRY_POINTS_FREERDP_EX channelEntryPoints;
wLog* log;
HANDLE thread;
@ -134,7 +134,6 @@ struct drdynvc_plugin
int PriorityCharge3;
rdpContext* rdpcontext;
IWTSVirtualChannelManager* channel_mgr;
};

View File

@ -45,14 +45,13 @@ static void* drdynvc_server_thread(void* arg)
DWORD BytesReturned;
DrdynvcServerContext* context;
UINT error = ERROR_INTERNAL_ERROR;
context = (DrdynvcServerContext*) arg;
buffer = NULL;
BytesReturned = 0;
ChannelEvent = NULL;
s = Stream_New(NULL, 4096);
if (!s)
{
WLog_ERR(TAG, "Stream_New failed!");
@ -60,7 +59,8 @@ static void* drdynvc_server_thread(void* arg)
return NULL;
}
if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE)
if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle,
&buffer, &BytesReturned) == TRUE)
{
if (BytesReturned == sizeof(HANDLE))
CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE));
@ -82,13 +82,16 @@ static void* drdynvc_server_thread(void* arg)
break;
}
if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0, NULL, 0, &BytesReturned))
if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0, NULL, 0,
&BytesReturned))
{
WLog_ERR(TAG, "WTSVirtualChannelRead failed!");
break;
}
if (BytesReturned < 1)
continue;
if (!Stream_EnsureRemainingCapacity(s, BytesReturned))
{
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
@ -96,7 +99,7 @@ static void* drdynvc_server_thread(void* arg)
}
if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0,
(PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned))
(PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned))
{
WLog_ERR(TAG, "WTSVirtualChannelRead failed!");
break;
@ -118,7 +121,8 @@ static void* drdynvc_server_thread(void* arg)
*/
static UINT drdynvc_server_start(DrdynvcServerContext* context)
{
context->priv->ChannelHandle = WTSVirtualChannelOpen(context->vcm, WTS_CURRENT_SESSION, "drdynvc");
context->priv->ChannelHandle = WTSVirtualChannelOpen(context->vcm,
WTS_CURRENT_SESSION, "drdynvc");
if (!context->priv->ChannelHandle)
{
@ -131,8 +135,9 @@ static UINT drdynvc_server_start(DrdynvcServerContext* context)
WLog_ERR(TAG, "CreateEvent failed!");
return ERROR_INTERNAL_ERROR;
}
if (!(context->priv->Thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) drdynvc_server_thread, (void*) context, 0, NULL)))
(LPTHREAD_START_ROUTINE) drdynvc_server_thread, (void*) context, 0, NULL)))
{
WLog_ERR(TAG, "CreateThread failed!");
CloseHandle(context->priv->StopEvent);
@ -150,34 +155,32 @@ static UINT drdynvc_server_start(DrdynvcServerContext* context)
*/
static UINT drdynvc_server_stop(DrdynvcServerContext* context)
{
UINT error;
UINT error;
SetEvent(context->priv->StopEvent);
if (WaitForSingleObject(context->priv->Thread, INFINITE) == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
return error;
}
CloseHandle(context->priv->Thread);
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error);
return error;
}
CloseHandle(context->priv->Thread);
return CHANNEL_RC_OK;
}
DrdynvcServerContext* drdynvc_server_context_new(HANDLE vcm)
{
DrdynvcServerContext* context;
context = (DrdynvcServerContext*) calloc(1, sizeof(DrdynvcServerContext));
if (context)
{
context->vcm = vcm;
context->Start = drdynvc_server_start;
context->Stop = drdynvc_server_stop;
context->priv = (DrdynvcServerPrivate*) calloc(1, sizeof(DrdynvcServerPrivate));
if (!context->priv)
{
WLog_ERR(TAG, "calloc failed!");

View File

@ -36,7 +36,7 @@ add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE
target_link_libraries(${MODULE_NAME} winpr freerdp)
if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS)
if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS)
install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols)
endif()

View File

@ -222,7 +222,7 @@ static DIR *opendir(const char *dirname)
* allows rewinddir() to function correctly when the current working
* directory is changed between opendir() and rewinddir().
*/
if (GetFullPathNameA (dirname, MAX_PATH, dirp->patt, NULL)) {
if (GetFullPathNameA(dirname, MAX_PATH, dirp->patt, NULL)) {
char *p;
/* append the search pattern "\\*\0" to the directory name */
@ -234,7 +234,7 @@ static DIR *opendir(const char *dirname)
*p = '\0';
/* open directory stream and retrieve the first entry */
dirp->search_handle = FindFirstFileA (dirp->patt, &dirp->find_data);
dirp->search_handle = FindFirstFileA(dirp->patt, &dirp->find_data);
if (dirp->search_handle != INVALID_HANDLE_VALUE) {
/* a directory entry is now waiting in memory */
dirp->cached = 1;

View File

@ -43,6 +43,7 @@
#include <sys/stat.h>
#include <winpr/crt.h>
#include <winpr/path.h>
#include <winpr/file.h>
#include <winpr/stream.h>
@ -546,7 +547,7 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
hFd = CreateFileA(file->fullpath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFd == INVALID_HANDLE_VALUE)
{
WLog_ERR(TAG, "Unable to set file time %s to %d", file->fullpath);
WLog_ERR(TAG, "Unable to create file %s", file->fullpath);
return FALSE;
}
if (liCreationTime.QuadPart != 0)
@ -575,7 +576,7 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
}
if (!SetFileTime(hFd, pftCreationTime, pftLastAccessTime, pftLastWriteTime))
{
WLog_ERR(TAG, "Unable to set file time %s to %d", file->fullpath);
WLog_ERR(TAG, "Unable to set file time on %s", file->fullpath);
CloseHandle(hFd);
return FALSE;
}
@ -591,13 +592,13 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
hFd = CreateFileA(file->fullpath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFd == INVALID_HANDLE_VALUE)
{
WLog_ERR(TAG, "Unable to truncate %s to %d", file->fullpath, size);
WLog_ERR(TAG, "Unable to truncate %s to %lld", file->fullpath, (long long) size);
return FALSE;
}
liSize.QuadPart = size;
if (SetFilePointer(hFd, liSize.LowPart, &liSize.HighPart, FILE_BEGIN) == 0)
{
WLog_ERR(TAG, "Unable to truncate %s to %d", file->fullpath, size);
WLog_ERR(TAG, "Unable to truncate %s to %lld", file->fullpath, (long long) size);
CloseHandle(hFd);
return FALSE;
}

View File

@ -38,10 +38,12 @@
#include <string.h>
#include <winpr/crt.h>
#include <winpr/path.h>
#include <winpr/string.h>
#include <winpr/synch.h>
#include <winpr/thread.h>
#include <winpr/stream.h>
#include <winpr/environment.h>
#include <winpr/interlocked.h>
#include <winpr/collections.h>
@ -78,15 +80,19 @@ static UINT32 drive_map_posix_err(int fs_errno)
case EACCES:
rc = STATUS_ACCESS_DENIED;
break;
case ENOENT:
rc = STATUS_NO_SUCH_FILE;
break;
case EBUSY:
rc = STATUS_DEVICE_BUSY;
break;
case EEXIST:
rc = STATUS_OBJECT_NAME_COLLISION;
break;
case EISDIR:
rc = STATUS_FILE_IS_A_DIRECTORY;
break;
@ -102,10 +108,8 @@ static UINT32 drive_map_posix_err(int fs_errno)
static DRIVE_FILE* drive_get_file_by_id(DRIVE_DEVICE* drive, UINT32 id)
{
DRIVE_FILE* file = NULL;
void* key = (void*) (size_t) id;
void* key = (void*)(size_t) id;
file = (DRIVE_FILE*) ListDictionary_GetItemValue(drive->files, key);
return file;
}
@ -126,19 +130,19 @@ static UINT drive_process_irp_create(DRIVE_DEVICE* drive, IRP* irp)
UINT32 CreateOptions;
UINT32 PathLength;
char* path = NULL;
Stream_Read_UINT32(irp->input, DesiredAccess);
Stream_Seek(irp->input, 16); /* AllocationSize(8), FileAttributes(4), SharedAccess(4) */
Stream_Seek(irp->input,
16); /* AllocationSize(8), FileAttributes(4), SharedAccess(4) */
Stream_Read_UINT32(irp->input, CreateDisposition);
Stream_Read_UINT32(irp->input, CreateOptions);
Stream_Read_UINT32(irp->input, PathLength);
status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(irp->input),
PathLength / 2, &path, 0, NULL, NULL);
PathLength / 2, &path, 0, NULL, NULL);
if (status < 1)
{
path = (char*) calloc(1, 1);
if (!path)
{
WLog_ERR(TAG, "calloc failed!");
@ -146,11 +150,9 @@ static UINT drive_process_irp_create(DRIVE_DEVICE* drive, IRP* irp)
}
}
FileId = irp->devman->id_sequence++;
file = drive_file_new(drive->path, path, FileId,
DesiredAccess, CreateDisposition, CreateOptions);
DesiredAccess, CreateDisposition, CreateOptions);
if (!file)
{
@ -162,14 +164,14 @@ static UINT drive_process_irp_create(DRIVE_DEVICE* drive, IRP* irp)
{
FileId = 0;
Information = 0;
/* map errno to windows result */
irp->IoStatus = drive_map_posix_err(file->err);
drive_file_free(file);
}
else
{
key = (void*) (size_t) file->id;
key = (void*)(size_t) file->id;
if (!ListDictionary_Add(drive->files, key, file))
{
WLog_ERR(TAG, "ListDictionary_Add failed!");
@ -185,12 +187,15 @@ static UINT drive_process_irp_create(DRIVE_DEVICE* drive, IRP* irp)
case FILE_OVERWRITE:
Information = FILE_SUPERSEDED;
break;
case FILE_OPEN_IF:
Information = FILE_OPENED;
break;
case FILE_OVERWRITE_IF:
Information = FILE_OVERWRITTEN;
break;
default:
Information = 0;
break;
@ -199,9 +204,7 @@ static UINT drive_process_irp_create(DRIVE_DEVICE* drive, IRP* irp)
Stream_Write_UINT32(irp->output, FileId);
Stream_Write_UINT8(irp->output, Information);
free(path);
return irp->Complete(irp);
}
@ -214,10 +217,8 @@ static UINT drive_process_irp_close(DRIVE_DEVICE* drive, IRP* irp)
{
void* key;
DRIVE_FILE* file;
file = drive_get_file_by_id(drive, irp->FileId);
key = (void*) (size_t) irp->FileId;
key = (void*)(size_t) irp->FileId;
if (!file)
{
@ -230,7 +231,6 @@ static UINT drive_process_irp_close(DRIVE_DEVICE* drive, IRP* irp)
}
Stream_Zero(irp->output, 5); /* Padding(5) */
return irp->Complete(irp);
}
@ -245,10 +245,8 @@ static UINT drive_process_irp_read(DRIVE_DEVICE* drive, IRP* irp)
UINT32 Length;
UINT64 Offset;
BYTE* buffer = NULL;
Stream_Read_UINT32(irp->input, Length);
Stream_Read_UINT64(irp->input, Offset);
file = drive_get_file_by_id(drive, irp->FileId);
if (!file)
@ -264,6 +262,7 @@ static UINT drive_process_irp_read(DRIVE_DEVICE* drive, IRP* irp)
else
{
buffer = (BYTE*) malloc(Length);
if (!buffer)
{
WLog_ERR(TAG, "malloc failed!");
@ -288,11 +287,11 @@ static UINT drive_process_irp_read(DRIVE_DEVICE* drive, IRP* irp)
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
return ERROR_INTERNAL_ERROR;
}
Stream_Write(irp->output, buffer, Length);
}
free(buffer);
return irp->Complete(irp);
}
@ -306,11 +305,9 @@ static UINT drive_process_irp_write(DRIVE_DEVICE* drive, IRP* irp)
DRIVE_FILE* file;
UINT32 Length;
UINT64 Offset;
Stream_Read_UINT32(irp->input, Length);
Stream_Read_UINT64(irp->input, Offset);
Stream_Seek(irp->input, 20); /* Padding */
file = drive_get_file_by_id(drive, irp->FileId);
if (!file)
@ -331,7 +328,6 @@ static UINT drive_process_irp_write(DRIVE_DEVICE* drive, IRP* irp)
Stream_Write_UINT32(irp->output, Length);
Stream_Write_UINT8(irp->output, 0); /* Padding */
return irp->Complete(irp);
}
@ -344,9 +340,7 @@ static UINT drive_process_irp_query_information(DRIVE_DEVICE* drive, IRP* irp)
{
DRIVE_FILE* file;
UINT32 FsInformationClass;
Stream_Read_UINT32(irp->input, FsInformationClass);
file = drive_get_file_by_id(drive, irp->FileId);
if (!file)
@ -371,18 +365,17 @@ static UINT drive_process_irp_set_information(DRIVE_DEVICE* drive, IRP* irp)
DRIVE_FILE* file;
UINT32 FsInformationClass;
UINT32 Length;
Stream_Read_UINT32(irp->input, FsInformationClass);
Stream_Read_UINT32(irp->input, Length);
Stream_Seek(irp->input, 24); /* Padding */
file = drive_get_file_by_id(drive, irp->FileId);
if (!file)
{
irp->IoStatus = STATUS_UNSUCCESSFUL;
}
else if (!drive_file_set_information(file, FsInformationClass, Length, irp->input))
else if (!drive_file_set_information(file, FsInformationClass, Length,
irp->input))
{
irp->IoStatus = STATUS_UNSUCCESSFUL;
}
@ -391,7 +384,6 @@ static UINT drive_process_irp_set_information(DRIVE_DEVICE* drive, IRP* irp)
irp->IoStatus = STATUS_DIRECTORY_NOT_EMPTY;
Stream_Write_UINT32(irp->output, Length);
return irp->Complete(irp);
}
@ -400,7 +392,8 @@ static UINT drive_process_irp_set_information(DRIVE_DEVICE* drive, IRP* irp)
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT drive_process_irp_query_volume_information(DRIVE_DEVICE* drive, IRP* irp)
static UINT drive_process_irp_query_volume_information(DRIVE_DEVICE* drive,
IRP* irp)
{
UINT32 FsInformationClass;
wStream* output = irp->output;
@ -410,9 +403,7 @@ static UINT drive_process_irp_query_volume_information(DRIVE_DEVICE* drive, IRP*
char* diskType = {"FAT32"};
WCHAR* outStr = NULL;
int length;
Stream_Read_UINT32(irp->input, FsInformationClass);
STATVFS(drive->path, &svfst);
STAT(drive->path, &st);
@ -422,6 +413,7 @@ static UINT drive_process_irp_query_volume_information(DRIVE_DEVICE* drive, IRP*
/* http://msdn.microsoft.com/en-us/library/cc232108.aspx */
length = ConvertToUnicode(sys_code_page, 0, volumeLabel, -1, &outStr, 0) * 2;
Stream_Write_UINT32(output, 17 + length); /* Length */
if (!Stream_EnsureRemainingCapacity(output, 17 + length))
{
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
@ -429,7 +421,8 @@ static UINT drive_process_irp_query_volume_information(DRIVE_DEVICE* drive, IRP*
return CHANNEL_RC_NO_MEMORY;
}
Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* VolumeCreationTime */
Stream_Write_UINT64(output,
FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* VolumeCreationTime */
#ifdef ANDROID
Stream_Write_UINT32(output, svfst.f_fsid.__val[0]); /* VolumeSerialNumber */
#else
@ -445,11 +438,13 @@ static UINT drive_process_irp_query_volume_information(DRIVE_DEVICE* drive, IRP*
case FileFsSizeInformation:
/* http://msdn.microsoft.com/en-us/library/cc232107.aspx */
Stream_Write_UINT32(output, 24); /* Length */
if (!Stream_EnsureRemainingCapacity(output, 24))
{
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
return CHANNEL_RC_NO_MEMORY;
}
Stream_Write_UINT64(output, svfst.f_blocks); /* TotalAllocationUnits */
Stream_Write_UINT64(output, svfst.f_bavail); /* AvailableAllocationUnits */
Stream_Write_UINT32(output, 1); /* SectorsPerAllocationUnit */
@ -460,19 +455,22 @@ static UINT drive_process_irp_query_volume_information(DRIVE_DEVICE* drive, IRP*
/* http://msdn.microsoft.com/en-us/library/cc232101.aspx */
length = ConvertToUnicode(sys_code_page, 0, diskType, -1, &outStr, 0) * 2;
Stream_Write_UINT32(output, 12 + length); /* Length */
if (!Stream_EnsureRemainingCapacity(output, 12 + length))
{
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
return CHANNEL_RC_NO_MEMORY;
}
Stream_Write_UINT32(output,
FILE_CASE_SENSITIVE_SEARCH |
FILE_CASE_PRESERVED_NAMES |
FILE_UNICODE_ON_DISK); /* FileSystemAttributes */
FILE_CASE_SENSITIVE_SEARCH |
FILE_CASE_PRESERVED_NAMES |
FILE_UNICODE_ON_DISK); /* FileSystemAttributes */
#ifdef ANDROID
Stream_Write_UINT32(output, 255); /* MaximumComponentNameLength */
#else
Stream_Write_UINT32(output, svfst.f_namemax/*510*/); /* MaximumComponentNameLength */
Stream_Write_UINT32(output,
svfst.f_namemax/*510*/); /* MaximumComponentNameLength */
#endif
Stream_Write_UINT32(output, length); /* FileSystemNameLength */
Stream_Write(output, outStr, length); /* FileSystemName (Unicode) */
@ -482,13 +480,16 @@ static UINT drive_process_irp_query_volume_information(DRIVE_DEVICE* drive, IRP*
case FileFsFullSizeInformation:
/* http://msdn.microsoft.com/en-us/library/cc232104.aspx */
Stream_Write_UINT32(output, 32); /* Length */
if (!Stream_EnsureRemainingCapacity(output, 32))
{
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
return CHANNEL_RC_NO_MEMORY;
}
Stream_Write_UINT64(output, svfst.f_blocks); /* TotalAllocationUnits */
Stream_Write_UINT64(output, svfst.f_bavail); /* CallerAvailableAllocationUnits */
Stream_Write_UINT64(output,
svfst.f_bavail); /* CallerAvailableAllocationUnits */
Stream_Write_UINT64(output, svfst.f_bfree); /* AvailableAllocationUnits */
Stream_Write_UINT32(output, 1); /* SectorsPerAllocationUnit */
Stream_Write_UINT32(output, svfst.f_bsize); /* BytesPerSector */
@ -497,11 +498,13 @@ static UINT drive_process_irp_query_volume_information(DRIVE_DEVICE* drive, IRP*
case FileFsDeviceInformation:
/* http://msdn.microsoft.com/en-us/library/cc232109.aspx */
Stream_Write_UINT32(output, 8); /* Length */
if (!Stream_EnsureRemainingCapacity(output, 8))
{
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
return CHANNEL_RC_NO_MEMORY;
}
Stream_Write_UINT32(output, FILE_DEVICE_DISK); /* DeviceType */
Stream_Write_UINT32(output, 0); /* Characteristics */
break;
@ -526,11 +529,8 @@ static UINT drive_process_irp_silent_ignore(DRIVE_DEVICE* drive, IRP* irp)
{
UINT32 FsInformationClass;
wStream* output = irp->output;
Stream_Read_UINT32(irp->input, FsInformationClass);
Stream_Write_UINT32(output, 0); /* Length */
return irp->Complete(irp);
}
@ -547,14 +547,12 @@ static UINT drive_process_irp_query_directory(DRIVE_DEVICE* drive, IRP* irp)
BYTE InitialQuery;
UINT32 PathLength;
UINT32 FsInformationClass;
Stream_Read_UINT32(irp->input, FsInformationClass);
Stream_Read_UINT8(irp->input, InitialQuery);
Stream_Read_UINT32(irp->input, PathLength);
Stream_Seek(irp->input, 23); /* Padding */
status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(irp->input),
PathLength / 2, &path, 0, NULL, NULL);
PathLength / 2, &path, 0, NULL, NULL);
if (status < 1)
if (!(path = (char*) calloc(1, 1)))
@ -570,13 +568,13 @@ static UINT drive_process_irp_query_directory(DRIVE_DEVICE* drive, IRP* irp)
irp->IoStatus = STATUS_UNSUCCESSFUL;
Stream_Write_UINT32(irp->output, 0); /* Length */
}
else if (!drive_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;
}
free(path);
return irp->Complete(irp);
}
@ -603,6 +601,7 @@ static UINT drive_process_irp_directory_control(DRIVE_DEVICE* drive, IRP* irp)
return irp->Complete(irp);
break;
}
return CHANNEL_RC_OK;
}
@ -625,7 +624,6 @@ static UINT drive_process_irp_device_control(DRIVE_DEVICE* drive, IRP* irp)
static UINT drive_process_irp(DRIVE_DEVICE* drive, IRP* irp)
{
UINT error;
irp->IoStatus = STATUS_SUCCESS;
switch (irp->MajorFunction)
@ -675,6 +673,7 @@ static UINT drive_process_irp(DRIVE_DEVICE* drive, IRP* irp)
error = irp->Complete(irp);
break;
}
return error;
}
@ -709,13 +708,15 @@ static void* drive_thread_func(void* arg)
if (irp)
if ((error = drive_process_irp(drive, irp)))
{
WLog_ERR(TAG, "drive_process_irp failed with error %lu!", error);
WLog_ERR(TAG, "drive_process_irp failed with error %u!", error);
break;
}
}
if (error && drive->rdpcontext)
setChannelError(drive->rdpcontext, error, "drive_thread_func reported an error");
setChannelError(drive->rdpcontext, error,
"drive_thread_func reported an error");
ExitThread((DWORD)error);
return NULL;
}
@ -728,11 +729,13 @@ static void* drive_thread_func(void* arg)
static UINT drive_irp_request(DEVICE* device, IRP* irp)
{
DRIVE_DEVICE* drive = (DRIVE_DEVICE*) device;
if (!MessageQueue_Post(drive->IrpQueue, NULL, 0, (void*) irp, NULL))
{
WLog_ERR(TAG, "MessageQueue_Post failed!");
return ERROR_INTERNAL_ERROR;
}
return CHANNEL_RC_OK;
}
@ -744,24 +747,22 @@ static UINT drive_irp_request(DEVICE* device, IRP* irp)
static UINT drive_free(DEVICE* device)
{
DRIVE_DEVICE* drive = (DRIVE_DEVICE*) device;
UINT error = CHANNEL_RC_OK;
UINT error = CHANNEL_RC_OK;
if (MessageQueue_PostQuit(drive->IrpQueue, 0) && (WaitForSingleObject(drive->thread, INFINITE) == WAIT_FAILED))
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error);
return error;
}
if (MessageQueue_PostQuit(drive->IrpQueue, 0)
&& (WaitForSingleObject(drive->thread, INFINITE) == WAIT_FAILED))
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error);
return error;
}
CloseHandle(drive->thread);
ListDictionary_Free(drive->files);
MessageQueue_Free(drive->IrpQueue);
Stream_Free(drive->device.data, TRUE);
free(drive);
return error;
return error;
}
/**
@ -769,29 +770,32 @@ static UINT drive_free(DEVICE* device)
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char* name, char* path)
UINT drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints,
char* name, char* path)
{
int i, length;
DRIVE_DEVICE* drive;
UINT error;
#ifdef WIN32
/*
* We cannot enter paths like c:\ because : is an arg separator
* thus, paths are entered as c+\ and the + is substituted here
*/
if (path[1] == '+')
{
if ((path[0]>='a' && path[0]<='z') || (path[0]>='A' && path[0]<='Z'))
if ((path[0] >= 'a' && path[0] <= 'z') || (path[0] >= 'A' && path[0] <= 'Z'))
{
path[1] = ':';
}
}
#endif
if (name[0] && path[0])
{
drive = (DRIVE_DEVICE*) calloc(1, sizeof(DRIVE_DEVICE));
if (!drive)
{
WLog_ERR(TAG, "calloc failed!");
@ -803,9 +807,9 @@ UINT drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char*
drive->device.IRPRequest = drive_irp_request;
drive->device.Free = drive_free;
drive->rdpcontext = pEntryPoints->rdpcontext;
length = (int) strlen(name);
drive->device.data = Stream_New(NULL, length + 1);
if (!drive->device.data)
{
WLog_ERR(TAG, "Stream_New failed!");
@ -817,17 +821,19 @@ UINT drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char*
Stream_Write_UINT8(drive->device.data, name[i] < 0 ? '_' : name[i]);
drive->path = path;
drive->files = ListDictionary_New(TRUE);
if (!drive->files)
{
WLog_ERR(TAG, "ListDictionary_New failed!");
error = CHANNEL_RC_NO_MEMORY;
goto out_error;
}
ListDictionary_ValueObject(drive->files)->fnObjectFree = (OBJECT_FREE_FN) drive_file_free;
ListDictionary_ValueObject(drive->files)->fnObjectFree =
(OBJECT_FREE_FN) drive_file_free;
drive->IrpQueue = MessageQueue_New(NULL);
if (!drive->IrpQueue)
{
WLog_ERR(TAG, "ListDictionary_New failed!");
@ -835,13 +841,15 @@ UINT drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char*
goto out_error;
}
if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) drive)))
if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman,
(DEVICE*) drive)))
{
WLog_ERR(TAG, "RegisterDevice failed with error %lu!", error);
WLog_ERR(TAG, "RegisterDevice failed with error %u!", error);
goto out_error;
}
if (!(drive->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) drive_thread_func, drive, CREATE_SUSPENDED, NULL)))
if (!(drive->thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) drive_thread_func, drive, CREATE_SUSPENDED, NULL)))
{
WLog_ERR(TAG, "CreateThread failed!");
goto out_error;
@ -849,6 +857,7 @@ UINT drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char*
ResumeThread(drive->thread);
}
return CHANNEL_RC_OK;
out_error:
MessageQueue_Free(drive->IrpQueue);
@ -857,7 +866,7 @@ out_error:
return error;
}
#ifdef STATIC_CHANNELS
#ifdef BUILTIN_CHANNELS
#define DeviceServiceEntry drive_DeviceServiceEntry
#else
#define DeviceServiceEntry FREERDP_API DeviceServiceEntry
@ -878,21 +887,19 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
char* dev;
int len;
char devlist[512], buf[512];
char *bufdup;
char *devdup;
char* bufdup;
char* devdup;
#endif
drive = (RDPDR_DRIVE*) pEntryPoints->device;
#ifndef WIN32
sys_code_page = CP_UTF8;
if (strcmp(drive->Path, "*") == 0)
{
/* all drives */
free(drive->Path);
drive->Path = _strdup("/");
if (!drive->Path)
{
WLog_ERR(TAG, "_strdup failed!");
@ -902,15 +909,14 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
else if (strcmp(drive->Path, "%") == 0)
{
char* home_env = NULL;
/* home directory */
home_env = getenv("HOME");
free(drive->Path);
if (home_env)
{
drive->Path = _strdup(home_env);
if (!drive->Path)
{
WLog_ERR(TAG, "_strdup failed!");
@ -920,6 +926,7 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
else
{
drive->Path = _strdup("/");
if (!drive->Path)
{
WLog_ERR(TAG, "_strdup failed!");
@ -929,27 +936,29 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
}
error = drive_register_drive_path(pEntryPoints, drive->Name, drive->Path);
#else
sys_code_page = GetACP();
/* Special case: path[0] == '*' -> export all drives */
/* Special case: path[0] == '%' -> user home dir */
if (strcmp(drive->Path, "%") == 0)
{
sprintf_s(buf, sizeof(buf), "%s\\", getenv("USERPROFILE"));
GetEnvironmentVariableA("USERPROFILE", buf, sizeof(buf));
PathCchAddBackslashA(buf, sizeof(buf));
free(drive->Path);
drive->Path = _strdup(buf);
if (!drive->Path)
{
WLog_ERR(TAG, "_strdup failed!");
return CHANNEL_RC_NO_MEMORY;
}
error = drive_register_drive_path(pEntryPoints, drive->Name, drive->Path);
}
else if (strcmp(drive->Path, "*") == 0)
{
int i;
/* Enumerate all devices: */
GetLogicalDriveStringsA(sizeof(devlist) - 1, devlist);
@ -963,11 +972,13 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
buf[len + 1] = dev[0];
buf[len + 2] = 0;
buf[len + 3] = 0;
if (!(bufdup = _strdup(buf)))
{
WLog_ERR(TAG, "_strdup failed!");
return CHANNEL_RC_NO_MEMORY;
}
if (!(devdup = _strdup(dev)))
{
WLog_ERR(TAG, "_strdup failed!");
@ -985,7 +996,7 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
{
error = drive_register_drive_path(pEntryPoints, drive->Name, drive->Path);
}
#endif
#endif
return error;
}

View File

@ -25,7 +25,7 @@ include_directories(..)
add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "DVCPluginEntry")
if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS)
if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS)
install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols)
endif()

View File

@ -160,7 +160,7 @@ static UINT echo_plugin_terminated(IWTSPlugin* pPlugin)
return CHANNEL_RC_OK;
}
#ifdef STATIC_CHANNELS
#ifdef BUILTIN_CHANNELS
#define DVCPluginEntry echo_DVCPluginEntry
#else
#define DVCPluginEntry FREERDP_API DVCPluginEntry

View File

@ -31,9 +31,9 @@
#define DVC_TAG CHANNELS_TAG("echo.client")
#ifdef WITH_DEBUG_DVC
#define DEBUG_DVC(fmt, ...) WLog_DBG(DVC_TAG, fmt, ## __VA_ARGS__)
#define DEBUG_DVC(...) WLog_DBG(DVC_TAG, __VA_ARGS__)
#else
#define DEBUG_DVC(fmt, ...) do { } while (0)
#define DEBUG_DVC(...) do { } while (0)
#endif
#endif /* __ECHO_MAIN_H */

View File

@ -67,34 +67,34 @@ static UINT echo_server_open_channel(echo_server* echo)
PULONG pSessionId = NULL;
if (WTSQuerySessionInformationA(echo->context.vcm, WTS_CURRENT_SESSION,
WTSSessionId, (LPSTR*) &pSessionId, &BytesReturned) == FALSE)
WTSSessionId, (LPSTR*) &pSessionId, &BytesReturned) == FALSE)
{
WLog_ERR(TAG, "WTSQuerySessionInformationA failed!");
return ERROR_INTERNAL_ERROR;
}
echo->SessionId = (DWORD) *pSessionId;
echo->SessionId = (DWORD) * pSessionId;
WTSFreeMemory(pSessionId);
hEvent = WTSVirtualChannelManagerGetEventHandle(echo->context.vcm);
StartTick = GetTickCount();
while (echo->echo_channel == NULL)
{
if (WaitForSingleObject(hEvent, 1000) == WAIT_FAILED)
{
Error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", Error);
return Error;
}
{
Error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", (unsigned long)Error);
return Error;
}
echo->echo_channel = WTSVirtualChannelOpenEx(echo->SessionId,
"ECHO", WTS_CHANNEL_OPTION_DYNAMIC);
"ECHO", WTS_CHANNEL_OPTION_DYNAMIC);
if (echo->echo_channel)
break;
Error = GetLastError();
if (Error == ERROR_NOT_FOUND)
break;
@ -121,10 +121,14 @@ static void* echo_server_thread_func(void* arg)
if ((error = echo_server_open_channel(echo)))
{
UINT error2 = 0;
WLog_ERR(TAG, "echo_server_open_channel failed with error %lu!", error);
IFCALLRET(echo->context.OpenResult, error2, &echo->context, ECHO_SERVER_OPEN_RESULT_NOTSUPPORTED);
WLog_ERR(TAG, "echo_server_open_channel failed with error %u!", error);
IFCALLRET(echo->context.OpenResult, error2, &echo->context,
ECHO_SERVER_OPEN_RESULT_NOTSUPPORTED);
if (error2)
WLog_ERR(TAG, "echo server's OpenResult callback failed with error %lu", error2);
WLog_ERR(TAG, "echo server's OpenResult callback failed with error %u",
error2);
goto out;
}
@ -132,7 +136,8 @@ static void* echo_server_thread_func(void* arg)
BytesReturned = 0;
ChannelEvent = NULL;
if (WTSVirtualChannelQuery(echo->echo_channel, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE)
if (WTSVirtualChannelQuery(echo->echo_channel, WTSVirtualEventHandle, &buffer,
&BytesReturned) == TRUE)
{
if (BytesReturned == sizeof(HANDLE))
CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE));
@ -153,40 +158,50 @@ static void* echo_server_thread_func(void* arg)
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error);
WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u", error);
break;
}
if (status == WAIT_OBJECT_0)
{
IFCALLRET(echo->context.OpenResult, error, &echo->context, ECHO_SERVER_OPEN_RESULT_CLOSED);
IFCALLRET(echo->context.OpenResult, error, &echo->context,
ECHO_SERVER_OPEN_RESULT_CLOSED);
if (error)
WLog_ERR(TAG, "OpenResult failed with error %lu!", error);
WLog_ERR(TAG, "OpenResult failed with error %u!", error);
break;
}
if (WTSVirtualChannelQuery(echo->echo_channel, WTSVirtualChannelReady, &buffer, &BytesReturned) == FALSE)
if (WTSVirtualChannelQuery(echo->echo_channel, WTSVirtualChannelReady, &buffer,
&BytesReturned) == FALSE)
{
IFCALLRET(echo->context.OpenResult, error, &echo->context, ECHO_SERVER_OPEN_RESULT_ERROR);
IFCALLRET(echo->context.OpenResult, error, &echo->context,
ECHO_SERVER_OPEN_RESULT_ERROR);
if (error)
WLog_ERR(TAG, "OpenResult failed with error %lu!", error);
WLog_ERR(TAG, "OpenResult failed with error %u!", error);
break;
}
ready = *((BOOL*) buffer);
WTSFreeMemory(buffer);
if (ready)
{
IFCALLRET(echo->context.OpenResult, error, &echo->context, ECHO_SERVER_OPEN_RESULT_OK);
IFCALLRET(echo->context.OpenResult, error, &echo->context,
ECHO_SERVER_OPEN_RESULT_OK);
if (error)
WLog_ERR(TAG, "OpenResult failed with error %lu!", error);
WLog_ERR(TAG, "OpenResult failed with error %u!", error);
break;
}
}
s = Stream_New(NULL, 4096);
if (!s)
{
WLog_ERR(TAG, "Stream_New failed!");
@ -197,23 +212,24 @@ static void* echo_server_thread_func(void* arg)
while (ready)
{
status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error);
break;
}
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u", error);
break;
}
if (status == WAIT_OBJECT_0)
if (status == WAIT_OBJECT_0)
break;
Stream_SetPosition(s, 0);
WTSVirtualChannelRead(echo->echo_channel, 0, NULL, 0, &BytesReturned);
if (BytesReturned < 1)
continue;
if (!Stream_EnsureRemainingCapacity(s, BytesReturned))
{
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
@ -222,26 +238,31 @@ static void* echo_server_thread_func(void* arg)
}
if (WTSVirtualChannelRead(echo->echo_channel, 0, (PCHAR) Stream_Buffer(s),
(ULONG) Stream_Capacity(s), &BytesReturned) == FALSE)
(ULONG) Stream_Capacity(s), &BytesReturned) == FALSE)
{
WLog_ERR(TAG, "WTSVirtualChannelRead failed!");
error = ERROR_INTERNAL_ERROR;
break;
}
IFCALLRET(echo->context.Response, error, &echo->context, (BYTE *) Stream_Buffer(s), BytesReturned);
IFCALLRET(echo->context.Response, error, &echo->context,
(BYTE*) Stream_Buffer(s), BytesReturned);
if (error)
{
WLog_ERR(TAG, "Response failed with error %lu!", error);
WLog_ERR(TAG, "Response failed with error %u!", error);
break;
}
}
Stream_Free(s, TRUE);
WTSVirtualChannelClose(echo->echo_channel);
echo->echo_channel = NULL;
out:
if (error && echo->context.rdpcontext)
setChannelError(echo->context.rdpcontext, error, "echo_server_thread_func reported an error");
setChannelError(echo->context.rdpcontext, error,
"echo_server_thread_func reported an error");
ExitThread((DWORD)error);
return NULL;
@ -264,7 +285,8 @@ static UINT echo_server_open(echo_server_context* context)
return ERROR_INTERNAL_ERROR;
}
if (!(echo->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) echo_server_thread_func, (void*) echo, 0, NULL)))
if (!(echo->thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) echo_server_thread_func, (void*) echo, 0, NULL)))
{
WLog_ERR(TAG, "CreateEvent failed!");
CloseHandle(echo->stopEvent);
@ -272,6 +294,7 @@ static UINT echo_server_open(echo_server_context* context)
return ERROR_INTERNAL_ERROR;
}
}
return CHANNEL_RC_OK;
}
@ -282,7 +305,7 @@ static UINT echo_server_open(echo_server_context* context)
*/
static UINT echo_server_close(echo_server_context* context)
{
UINT error = CHANNEL_RC_OK;
UINT error = CHANNEL_RC_OK;
echo_server* echo = (echo_server*) context;
if (echo->thread)
@ -290,31 +313,31 @@ static UINT echo_server_close(echo_server_context* context)
SetEvent(echo->stopEvent);
if (WaitForSingleObject(echo->thread, INFINITE) == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error);
return error;
}
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error);
return error;
}
CloseHandle(echo->thread);
CloseHandle(echo->stopEvent);
echo->thread = NULL;
echo->stopEvent = NULL;
}
return error;
}
static BOOL echo_server_request(echo_server_context* context, const BYTE* buffer, UINT32 length)
static BOOL echo_server_request(echo_server_context* context,
const BYTE* buffer, UINT32 length)
{
echo_server* echo = (echo_server*) context;
return WTSVirtualChannelWrite(echo->echo_channel, (PCHAR) buffer, length, NULL);
}
echo_server_context* echo_server_context_new(HANDLE vcm)
{
echo_server* echo;
echo = (echo_server*) calloc(1, sizeof(echo_server));
if (echo)
@ -333,8 +356,6 @@ echo_server_context* echo_server_context_new(HANDLE vcm)
void echo_server_context_free(echo_server_context* context)
{
echo_server* echo = (echo_server*) context;
echo_server_close(context);
free(echo);
}

View File

@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS
encomsp_main.c
encomsp_main.h)
add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntry")
add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntryEx")
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")

File diff suppressed because it is too large Load Diff

View File

@ -40,7 +40,7 @@
struct encomsp_plugin
{
CHANNEL_DEF channelDef;
CHANNEL_ENTRY_POINTS_FREERDP channelEntryPoints;
CHANNEL_ENTRY_POINTS_FREERDP_EX channelEntryPoints;
EncomspClientContext* context;

View File

@ -45,7 +45,6 @@ static UINT encomsp_read_header(wStream* s, ENCOMSP_ORDER_HEADER* header)
Stream_Read_UINT16(s, header->Type); /* Type (2 bytes) */
Stream_Read_UINT16(s, header->Length); /* Length (2 bytes) */
return CHANNEL_RC_OK;
}
@ -55,7 +54,6 @@ static int encomsp_write_header(wStream* s, ENCOMSP_ORDER_HEADER* header)
{
Stream_Write_UINT16(s, header->Type); /* Type (2 bytes) */
Stream_Write_UINT16(s, header->Length); /* Length (2 bytes) */
return 1;
}
@ -75,7 +73,6 @@ static int encomsp_read_unicode_string(wStream* s, ENCOMSP_UNICODE_STRING* str)
return -1;
Stream_Read(s, &(str->wString), (str->cchString * 2)); /* String (variable) */
return 1;
}
@ -86,14 +83,13 @@ static int encomsp_read_unicode_string(wStream* s, ENCOMSP_UNICODE_STRING* str)
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT encomsp_recv_change_participant_control_level_pdu(EncomspServerContext* context, wStream* s, ENCOMSP_ORDER_HEADER* header)
static UINT encomsp_recv_change_participant_control_level_pdu(
EncomspServerContext* context, wStream* s, ENCOMSP_ORDER_HEADER* header)
{
int beg, end;
ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU pdu;
UINT error = CHANNEL_RC_OK;
beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE;
CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER));
if (Stream_GetRemainingLength(s) < 6)
@ -104,7 +100,6 @@ static UINT encomsp_recv_change_participant_control_level_pdu(EncomspServerConte
Stream_Read_UINT16(s, pdu.Flags); /* Flags (2 bytes) */
Stream_Read_UINT32(s, pdu.ParticipantId); /* ParticipantId (4 bytes) */
end = (int) Stream_GetPosition(s);
if ((beg + header->Length) < end)
@ -125,8 +120,10 @@ static UINT encomsp_recv_change_participant_control_level_pdu(EncomspServerConte
}
IFCALLRET(context->ChangeParticipantControlLevel, error, context, &pdu);
if (error)
WLog_ERR(TAG, "context->ChangeParticipantControlLevel failed with error %lu", error);
WLog_ERR(TAG, "context->ChangeParticipantControlLevel failed with error %u",
error);
return error;
}
@ -136,7 +133,8 @@ static UINT encomsp_recv_change_participant_control_level_pdu(EncomspServerConte
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT encomsp_server_receive_pdu(EncomspServerContext* context, wStream* s)
static UINT encomsp_server_receive_pdu(EncomspServerContext* context,
wStream* s)
{
UINT error = CHANNEL_RC_OK;
ENCOMSP_ORDER_HEADER header;
@ -145,18 +143,22 @@ static UINT encomsp_server_receive_pdu(EncomspServerContext* context, wStream* s
{
if ((error = encomsp_read_header(s, &header)))
{
WLog_ERR(TAG, "encomsp_read_header failed with error %lu!", error);
WLog_ERR(TAG, "encomsp_read_header failed with error %u!", error);
return error;
}
WLog_INFO(TAG, "EncomspReceive: Type: %d Length: %d", header.Type, header.Length);
WLog_INFO(TAG, "EncomspReceive: Type: %d Length: %d", header.Type,
header.Length);
switch (header.Type)
{
case ODTYPE_PARTICIPANT_CTRL_CHANGED:
if ((error = encomsp_recv_change_participant_control_level_pdu(context, s, &header)))
if ((error = encomsp_recv_change_participant_control_level_pdu(context, s,
&header)))
{
WLog_ERR(TAG, "encomsp_recv_change_participant_control_level_pdu failed with error %lu!", error);
WLog_ERR(TAG,
"encomsp_recv_change_participant_control_level_pdu failed with error %u!",
error);
return error;
}
@ -183,15 +185,14 @@ static void* encomsp_server_thread(void* arg)
ENCOMSP_ORDER_HEADER* header;
EncomspServerContext* context;
UINT error = CHANNEL_RC_OK;
DWORD status;
DWORD status;
context = (EncomspServerContext*) arg;
buffer = NULL;
BytesReturned = 0;
ChannelEvent = NULL;
s = Stream_New(NULL, 4096);
if (!s)
{
WLog_ERR(TAG, "Stream_New failed!");
@ -199,7 +200,8 @@ static void* encomsp_server_thread(void* arg)
goto out;
}
if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE)
if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle,
&buffer, &BytesReturned) == TRUE)
{
if (BytesReturned == sizeof(HANDLE))
CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE));
@ -213,23 +215,23 @@ static void* encomsp_server_thread(void* arg)
while (1)
{
status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error);
break;
}
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u", error);
break;
}
status = WaitForSingleObject(context->priv->StopEvent, 0);
status = WaitForSingleObject(context->priv->StopEvent, 0);
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error);
break;
}
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error);
break;
}
if (status == WAIT_OBJECT_0)
{
@ -237,16 +239,19 @@ static void* encomsp_server_thread(void* arg)
}
WTSVirtualChannelRead(context->priv->ChannelHandle, 0, NULL, 0, &BytesReturned);
if (BytesReturned < 1)
continue;
if (!Stream_EnsureRemainingCapacity(s, BytesReturned))
{
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
error = CHANNEL_RC_NO_MEMORY;
break;
}
if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0,
(PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned))
(PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned))
{
WLog_ERR(TAG, "WTSVirtualChannelRead failed!");
error = ERROR_INTERNAL_ERROR;
@ -261,11 +266,13 @@ static void* encomsp_server_thread(void* arg)
{
Stream_SealLength(s);
Stream_SetPosition(s, 0);
if ((error = encomsp_server_receive_pdu(context, s)))
{
WLog_ERR(TAG, "encomsp_server_receive_pdu failed with error %lu!", error);
WLog_ERR(TAG, "encomsp_server_receive_pdu failed with error %u!", error);
break;
}
Stream_SetPosition(s, 0);
}
}
@ -273,8 +280,10 @@ static void* encomsp_server_thread(void* arg)
Stream_Free(s, TRUE);
out:
if (error && context->rdpcontext)
setChannelError(context->rdpcontext, error, "encomsp_server_thread reported an error");
setChannelError(context->rdpcontext, error,
"encomsp_server_thread reported an error");
ExitThread((DWORD)error);
return NULL;
@ -287,7 +296,8 @@ out:
*/
static UINT encomsp_server_start(EncomspServerContext* context)
{
context->priv->ChannelHandle = WTSVirtualChannelOpen(context->vcm, WTS_CURRENT_SESSION, "encomsp");
context->priv->ChannelHandle = WTSVirtualChannelOpen(context->vcm,
WTS_CURRENT_SESSION, "encomsp");
if (!context->priv->ChannelHandle)
return CHANNEL_RC_BAD_CHANNEL;
@ -299,7 +309,7 @@ static UINT encomsp_server_start(EncomspServerContext* context)
}
if (!(context->priv->Thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) encomsp_server_thread, (void*) context, 0, NULL)))
(LPTHREAD_START_ROUTINE) encomsp_server_thread, (void*) context, 0, NULL)))
{
WLog_ERR(TAG, "CreateThread failed!");
CloseHandle(context->priv->StopEvent);
@ -317,33 +327,30 @@ static UINT encomsp_server_start(EncomspServerContext* context)
*/
static UINT encomsp_server_stop(EncomspServerContext* context)
{
UINT error = CHANNEL_RC_OK;
UINT error = CHANNEL_RC_OK;
SetEvent(context->priv->StopEvent);
if (WaitForSingleObject(context->priv->Thread, INFINITE) == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error);
return error;
}
CloseHandle(context->priv->Thread);
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error);
return error;
}
CloseHandle(context->priv->Thread);
return error;
}
EncomspServerContext* encomsp_server_context_new(HANDLE vcm)
{
EncomspServerContext* context;
context = (EncomspServerContext*) calloc(1, sizeof(EncomspServerContext));
if (context)
{
context->vcm = vcm;
context->Start = encomsp_server_start;
context->Stop = encomsp_server_stop;
context->priv = (EncomspServerPrivate*) calloc(1, sizeof(EncomspServerPrivate));
if (!context->priv)

View File

@ -27,7 +27,7 @@ add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE
target_link_libraries(${MODULE_NAME} freerdp winpr)
if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS)
if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS)
install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols)
endif()

View File

@ -84,14 +84,12 @@ static UINT parallel_process_irp_create(PARALLEL_DEVICE* parallel, IRP* irp)
char* path = NULL;
int status;
UINT32 PathLength;
Stream_Seek(irp->input, 28);
/* DesiredAccess(4) AllocationSize(8), FileAttributes(4) */
/* SharedAccess(4) CreateDisposition(4), CreateOptions(4) */
Stream_Read_UINT32(irp->input, PathLength);
status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(irp->input),
PathLength / 2, &path, 0, NULL, NULL);
PathLength / 2, &path, 0, NULL, NULL);
if (status < 1)
if (!(path = (char*) calloc(1, 1)))
@ -113,15 +111,12 @@ static UINT parallel_process_irp_create(PARALLEL_DEVICE* parallel, IRP* irp)
/* all read and write operations should be non-blocking */
if (fcntl(parallel->file, F_SETFL, O_NONBLOCK) == -1)
{
}
}
Stream_Write_UINT32(irp->output, parallel->id);
Stream_Write_UINT8(irp->output, 0);
free(path);
return irp->Complete(irp);
}
@ -134,15 +129,12 @@ static UINT parallel_process_irp_close(PARALLEL_DEVICE* parallel, IRP* irp)
{
if (close(parallel->file) < 0)
{
}
else
{
}
Stream_Zero(irp->output, 5); /* Padding(5) */
return irp->Complete(irp);
}
@ -157,11 +149,10 @@ static UINT parallel_process_irp_read(PARALLEL_DEVICE* parallel, IRP* irp)
UINT64 Offset;
ssize_t status;
BYTE* buffer = NULL;
Stream_Read_UINT32(irp->input, Length);
Stream_Read_UINT64(irp->input, Offset);
buffer = (BYTE*) malloc(Length);
if (!buffer)
{
WLog_ERR(TAG, "malloc failed!");
@ -179,7 +170,6 @@ static UINT parallel_process_irp_read(PARALLEL_DEVICE* parallel, IRP* irp)
}
else
{
}
Stream_Write_UINT32(irp->output, Length);
@ -192,11 +182,11 @@ static UINT parallel_process_irp_read(PARALLEL_DEVICE* parallel, IRP* irp)
free(buffer);
return CHANNEL_RC_NO_MEMORY;
}
Stream_Write(irp->output, buffer, Length);
}
free(buffer);
return irp->Complete(irp);
}
@ -211,11 +201,9 @@ static UINT parallel_process_irp_write(PARALLEL_DEVICE* parallel, IRP* irp)
UINT32 Length;
UINT64 Offset;
ssize_t status;
Stream_Read_UINT32(irp->input, Length);
Stream_Read_UINT64(irp->input, Offset);
Stream_Seek(irp->input, 20); /* Padding */
len = Length;
while (len > 0)
@ -235,7 +223,6 @@ static UINT parallel_process_irp_write(PARALLEL_DEVICE* parallel, IRP* irp)
Stream_Write_UINT32(irp->output, Length);
Stream_Write_UINT8(irp->output, 0); /* Padding */
return irp->Complete(irp);
}
@ -244,7 +231,8 @@ static UINT parallel_process_irp_write(PARALLEL_DEVICE* parallel, IRP* irp)
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT parallel_process_irp_device_control(PARALLEL_DEVICE* parallel, IRP* irp)
static UINT parallel_process_irp_device_control(PARALLEL_DEVICE* parallel,
IRP* irp)
{
Stream_Write_UINT32(irp->output, 0); /* OutputBufferLength */
return irp->Complete(irp);
@ -267,6 +255,7 @@ static UINT parallel_process_irp(PARALLEL_DEVICE* parallel, IRP* irp)
WLog_ERR(TAG, "parallel_process_irp_create failed with error %d!", error);
return error;
}
break;
case IRP_MJ_CLOSE:
@ -275,6 +264,7 @@ static UINT parallel_process_irp(PARALLEL_DEVICE* parallel, IRP* irp)
WLog_ERR(TAG, "parallel_process_irp_close failed with error %d!", error);
return error;
}
break;
case IRP_MJ_READ:
@ -283,6 +273,7 @@ static UINT parallel_process_irp(PARALLEL_DEVICE* parallel, IRP* irp)
WLog_ERR(TAG, "parallel_process_irp_read failed with error %d!", error);
return error;
}
break;
case IRP_MJ_WRITE:
@ -291,14 +282,17 @@ static UINT parallel_process_irp(PARALLEL_DEVICE* parallel, IRP* irp)
WLog_ERR(TAG, "parallel_process_irp_write failed with error %d!", error);
return error;
}
break;
case IRP_MJ_DEVICE_CONTROL:
if ((error = parallel_process_irp_device_control(parallel, irp)))
{
WLog_ERR(TAG, "parallel_process_irp_device_control failed with error %d!", error);
WLog_ERR(TAG, "parallel_process_irp_device_control failed with error %d!",
error);
return error;
}
break;
default:
@ -306,6 +300,7 @@ static UINT parallel_process_irp(PARALLEL_DEVICE* parallel, IRP* irp)
return irp->Complete(irp);
break;
}
return CHANNEL_RC_OK;
}
@ -343,8 +338,10 @@ static void* parallel_thread_func(void* arg)
break;
}
}
if (error && parallel->rdpcontext)
setChannelError(parallel->rdpcontext, error, "parallel_thread_func reported an error");
setChannelError(parallel->rdpcontext, error,
"parallel_thread_func reported an error");
ExitThread((DWORD)error);
return NULL;
@ -364,6 +361,7 @@ static UINT parallel_irp_request(DEVICE* device, IRP* irp)
WLog_ERR(TAG, "MessageQueue_Post failed!");
return ERROR_INTERNAL_ERROR;
}
return CHANNEL_RC_OK;
}
@ -374,25 +372,25 @@ static UINT parallel_irp_request(DEVICE* device, IRP* irp)
*/
static UINT parallel_free(DEVICE* device)
{
UINT error;
UINT error;
PARALLEL_DEVICE* parallel = (PARALLEL_DEVICE*) device;
if (MessageQueue_PostQuit(parallel->queue, 0) && (WaitForSingleObject(parallel->thread, INFINITE) == WAIT_FAILED))
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
return error;
}
CloseHandle(parallel->thread);
if (MessageQueue_PostQuit(parallel->queue, 0)
&& (WaitForSingleObject(parallel->thread, INFINITE) == WAIT_FAILED))
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error);
return error;
}
CloseHandle(parallel->thread);
Stream_Free(parallel->device.data, TRUE);
MessageQueue_Free(parallel->queue);
free(parallel);
return CHANNEL_RC_OK;
return CHANNEL_RC_OK;
}
#ifdef STATIC_CHANNELS
#ifdef BUILTIN_CHANNELS
#define DeviceServiceEntry parallel_DeviceServiceEntry
#else
#define DeviceServiceEntry FREERDP_API DeviceServiceEntry
@ -412,7 +410,6 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
RDPDR_PARALLEL* device;
PARALLEL_DEVICE* parallel;
UINT error;
device = (RDPDR_PARALLEL*) pEntryPoints->device;
name = device->Name;
path = device->Path;
@ -426,6 +423,7 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
if (name[0] && path[0])
{
parallel = (PARALLEL_DEVICE*) calloc(1, sizeof(PARALLEL_DEVICE));
if (!parallel)
{
WLog_ERR(TAG, "calloc failed!");
@ -437,9 +435,9 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
parallel->device.IRPRequest = parallel_irp_request;
parallel->device.Free = parallel_free;
parallel->rdpcontext = pEntryPoints->rdpcontext;
length = strlen(name);
parallel->device.data = Stream_New(NULL, length + 1);
if (!parallel->device.data)
{
WLog_ERR(TAG, "Stream_New failed!");
@ -451,8 +449,8 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
Stream_Write_UINT8(parallel->device.data, name[i] < 0 ? '_' : name[i]);
parallel->path = path;
parallel->queue = MessageQueue_New(NULL);
if (!parallel->queue)
{
WLog_ERR(TAG, "MessageQueue_New failed!");
@ -460,14 +458,15 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
goto error_out;
}
if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) parallel)))
if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman,
(DEVICE*) parallel)))
{
WLog_ERR(TAG, "RegisterDevice failed with error %lu!", error);
WLog_ERR(TAG, "RegisterDevice failed with error %u!", error);
goto error_out;
}
if (!(parallel->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) parallel_thread_func, (void*) parallel, 0, NULL)))
if (!(parallel->thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) parallel_thread_func, (void*) parallel, 0, NULL)))
{
WLog_ERR(TAG, "CreateThread failed!");
error = ERROR_INTERNAL_ERROR;

View File

@ -30,7 +30,7 @@ if(WITH_CUPS)
add_definitions(-DWITH_CUPS)
endif()
if(WIN32)
if(WIN32 AND NOT UWP)
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS}
printer_win.c
printer_win.h)
@ -49,7 +49,7 @@ endif()
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS)
if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS)
install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols)
endif()

View File

@ -6,6 +6,7 @@
* Copyright 2015 Thincast Technologies GmbH
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
* Copyright 2016 Armin Novak <armin.novak@gmail.com>
* Copyright 2016 David PHAM-VAN <d.phamvan@inuvika.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -45,7 +46,7 @@
#include "printer_main.h"
#ifdef WIN32
#if defined(_WIN32) && !defined(_UWP)
#include "printer_win.h"
#endif
@ -60,7 +61,7 @@ struct _PRINTER_DEVICE
rdpPrinter* printer;
PSLIST_HEADER pIrpList;
WINPR_PSLIST_HEADER pIrpList;
HANDLE event;
HANDLE stopEvent;
@ -79,7 +80,8 @@ static UINT printer_process_irp_create(PRINTER_DEVICE* printer_dev, IRP* irp)
rdpPrintJob* printjob = NULL;
if (printer_dev->printer)
printjob = printer_dev->printer->CreatePrintJob(printer_dev->printer, irp->devman->id_sequence++);
printjob = printer_dev->printer->CreatePrintJob(printer_dev->printer,
irp->devman->id_sequence++);
if (printjob)
{
@ -104,7 +106,8 @@ static UINT printer_process_irp_close(PRINTER_DEVICE* printer_dev, IRP* irp)
rdpPrintJob* printjob = NULL;
if (printer_dev->printer)
printjob = printer_dev->printer->FindPrintJob(printer_dev->printer, irp->FileId);
printjob = printer_dev->printer->FindPrintJob(printer_dev->printer,
irp->FileId);
if (!printjob)
{
@ -116,7 +119,6 @@ static UINT printer_process_irp_close(PRINTER_DEVICE* printer_dev, IRP* irp)
}
Stream_Zero(irp->output, 4); /* Padding(4) */
return irp->Complete(irp);
}
@ -131,13 +133,13 @@ static UINT printer_process_irp_write(PRINTER_DEVICE* printer_dev, IRP* irp)
UINT64 Offset;
rdpPrintJob* printjob = NULL;
UINT error = CHANNEL_RC_OK;
Stream_Read_UINT32(irp->input, Length);
Stream_Read_UINT64(irp->input, Offset);
Stream_Seek(irp->input, 20); /* Padding */
if (printer_dev->printer)
printjob = printer_dev->printer->FindPrintJob(printer_dev->printer, irp->FileId);
printjob = printer_dev->printer->FindPrintJob(printer_dev->printer,
irp->FileId);
if (!printjob)
{
@ -151,13 +153,12 @@ static UINT printer_process_irp_write(PRINTER_DEVICE* printer_dev, IRP* irp)
if (error)
{
WLog_ERR(TAG, "printjob->Write failed with error %lu!", error);
WLog_ERR(TAG, "printjob->Write failed with error %u!", error);
return error;
}
Stream_Write_UINT32(irp->output, Length);
Stream_Write_UINT8(irp->output, 0); /* Padding */
return irp->Complete(irp);
}
@ -166,7 +167,8 @@ static UINT printer_process_irp_write(PRINTER_DEVICE* printer_dev, IRP* irp)
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT printer_process_irp_device_control(PRINTER_DEVICE* printer_dev, IRP* irp)
static UINT printer_process_irp_device_control(PRINTER_DEVICE* printer_dev,
IRP* irp)
{
Stream_Write_UINT32(irp->output, 0); /* OutputBufferLength */
return irp->Complete(irp);
@ -180,38 +182,44 @@ static UINT printer_process_irp_device_control(PRINTER_DEVICE* printer_dev, IRP*
static UINT printer_process_irp(PRINTER_DEVICE* printer_dev, IRP* irp)
{
UINT error;
switch (irp->MajorFunction)
{
case IRP_MJ_CREATE:
if ((error = printer_process_irp_create(printer_dev, irp)))
{
WLog_ERR(TAG, "printer_process_irp_create failed with error %lu!", error);
WLog_ERR(TAG, "printer_process_irp_create failed with error %u!", error);
return error;
}
break;
case IRP_MJ_CLOSE:
if ((error = printer_process_irp_close(printer_dev, irp)))
{
WLog_ERR(TAG, "printer_process_irp_close failed with error %lu!", error);
WLog_ERR(TAG, "printer_process_irp_close failed with error %u!", error);
return error;
}
break;
case IRP_MJ_WRITE:
if ((error = printer_process_irp_write(printer_dev, irp)))
{
WLog_ERR(TAG, "printer_process_irp_write failed with error %lu!", error);
WLog_ERR(TAG, "printer_process_irp_write failed with error %u!", error);
return error;
}
break;
case IRP_MJ_DEVICE_CONTROL:
if ((error = printer_process_irp_device_control(printer_dev, irp)))
{
WLog_ERR(TAG, "printer_process_irp_device_control failed with error %lu!", error);
WLog_ERR(TAG, "printer_process_irp_device_control failed with error %u!",
error);
return error;
}
break;
default:
@ -219,6 +227,7 @@ static UINT printer_process_irp(PRINTER_DEVICE* printer_dev, IRP* irp)
return irp->Complete(irp);
break;
}
return CHANNEL_RC_OK;
}
@ -232,20 +241,20 @@ static void* printer_thread_func(void* arg)
while (1)
{
DWORD rc = WaitForMultipleObjects(2, obj, FALSE, INFINITE);
if (rc == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error);
break;
}
if (rc == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u!", error);
break;
}
if (rc == WAIT_OBJECT_0 + 1)
break;
else if( rc != WAIT_OBJECT_0 )
else if (rc != WAIT_OBJECT_0)
continue;
ResetEvent(printer_dev->event);
irp = (IRP*) InterlockedPopEntrySList(printer_dev->pIrpList);
if (irp == NULL)
@ -261,11 +270,12 @@ static void* printer_thread_func(void* arg)
break;
}
}
if (error && printer_dev->rdpcontext)
setChannelError(printer_dev->rdpcontext, error, "printer_thread_func reported an error");
setChannelError(printer_dev->rdpcontext, error,
"printer_thread_func reported an error");
ExitThread((DWORD) error);
return NULL;
}
@ -277,9 +287,7 @@ static void* printer_thread_func(void* arg)
static UINT printer_irp_request(DEVICE* device, IRP* irp)
{
PRINTER_DEVICE* printer_dev = (PRINTER_DEVICE*) device;
InterlockedPushEntrySList(printer_dev->pIrpList, &(irp->ItemEntry));
SetEvent(printer_dev->event);
return CHANNEL_RC_OK;
}
@ -293,15 +301,15 @@ static UINT printer_free(DEVICE* device)
{
IRP* irp;
PRINTER_DEVICE* printer_dev = (PRINTER_DEVICE*) device;
UINT error;
UINT error;
SetEvent(printer_dev->stopEvent);
if (WaitForSingleObject(printer_dev->thread, INFINITE) == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error);
return error;
}
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error);
return error;
}
while ((irp = (IRP*) InterlockedPopEntrySList(printer_dev->pIrpList)) != NULL)
irp->Discard(irp);
@ -309,16 +317,15 @@ static UINT printer_free(DEVICE* device)
CloseHandle(printer_dev->thread);
CloseHandle(printer_dev->stopEvent);
CloseHandle(printer_dev->event);
_aligned_free(printer_dev->pIrpList);
if (printer_dev->printer)
printer_dev->printer->Free(printer_dev->printer);
free(printer_dev->device.name);
Stream_Free(printer_dev->device.data, TRUE);
free(printer_dev);
return CHANNEL_RC_OK;
return CHANNEL_RC_OK;
}
/**
@ -326,7 +333,8 @@ static UINT printer_free(DEVICE* device)
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* printer)
UINT printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints,
rdpPrinter* printer)
{
char* port;
UINT32 Flags;
@ -338,16 +346,17 @@ UINT printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* pri
BYTE* CachedPrinterConfigData;
PRINTER_DEVICE* printer_dev;
UINT error;
port = malloc(10);
if (!port)
{
WLog_ERR(TAG, "malloc failed!");
return CHANNEL_RC_NO_MEMORY;
}
sprintf_s(port, 10, "PRN%d", printer->id);
sprintf_s(port, 10, "PRN%d", printer->id);
printer_dev = (PRINTER_DEVICE*) calloc(1, sizeof(PRINTER_DEVICE));
if (!printer_dev)
{
WLog_ERR(TAG, "calloc failed!");
@ -360,21 +369,21 @@ UINT printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* pri
printer_dev->device.IRPRequest = printer_irp_request;
printer_dev->device.Free = printer_free;
printer_dev->rdpcontext = pEntryPoints->rdpcontext;
printer_dev->printer = printer;
CachedFieldsLen = 0;
CachedPrinterConfigData = NULL;
Flags = 0;
if (printer->is_default)
Flags |= RDPDR_PRINTER_ANNOUNCE_FLAG_DEFAULTPRINTER;
DriverNameLen = ConvertToUnicode(CP_UTF8, 0, printer->driver, -1, &DriverName, 0) * 2;
PrintNameLen = ConvertToUnicode(CP_UTF8, 0, printer->name, -1, &PrintName, 0) * 2;
DriverNameLen = ConvertToUnicode(CP_UTF8, 0, printer->driver, -1, &DriverName,
0) * 2;
PrintNameLen = ConvertToUnicode(CP_UTF8, 0, printer->name, -1, &PrintName,
0) * 2;
printer_dev->device.data = Stream_New(NULL,
28 + DriverNameLen + PrintNameLen + CachedFieldsLen);
printer_dev->device.data = Stream_New(NULL, 28 + DriverNameLen + PrintNameLen + CachedFieldsLen);
if (!printer_dev->device.data)
{
WLog_ERR(TAG, "calloc failed!");
@ -397,19 +406,22 @@ UINT printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* pri
if (CachedFieldsLen > 0)
{
Stream_Write(printer_dev->device.data, CachedPrinterConfigData, CachedFieldsLen);
Stream_Write(printer_dev->device.data, CachedPrinterConfigData,
CachedFieldsLen);
}
free(DriverName);
free(PrintName);
printer_dev->pIrpList = (WINPR_PSLIST_HEADER) _aligned_malloc(sizeof(
WINPR_SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT);
printer_dev->pIrpList = (PSLIST_HEADER) _aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT);
if (!printer_dev->pIrpList)
{
WLog_ERR(TAG, "_aligned_malloc failed!");
error = CHANNEL_RC_NO_MEMORY;
goto error_out;
}
InitializeSListHead(printer_dev->pIrpList);
if (!(printer_dev->event = CreateEvent(NULL, TRUE, FALSE, NULL)))
@ -418,6 +430,7 @@ UINT printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* pri
error = ERROR_INTERNAL_ERROR;
goto error_out;
}
if (!(printer_dev->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
{
WLog_ERR(TAG, "CreateEvent failed!");
@ -425,14 +438,15 @@ UINT printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* pri
goto error_out;
}
if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) printer_dev)))
if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman,
(DEVICE*) printer_dev)))
{
WLog_ERR(TAG, "RegisterDevice failed with error %d!", error);
goto error_out;
}
if (!(printer_dev->thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) printer_thread_func, (void*) printer_dev, 0, NULL)))
(LPTHREAD_START_ROUTINE) printer_thread_func, (void*) printer_dev, 0, NULL)))
{
WLog_ERR(TAG, "CreateThread failed!");
error = ERROR_INTERNAL_ERROR;
@ -450,7 +464,7 @@ error_out:
return error;
}
#ifdef STATIC_CHANNELS
#ifdef BUILTIN_CHANNELS
#define DeviceServiceEntry printer_DeviceServiceEntry
#else
#define DeviceServiceEntry FREERDP_API DeviceServiceEntry
@ -471,12 +485,10 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
RDPDR_PRINTER* device;
rdpPrinterDriver* driver = NULL;
UINT error;
#ifdef WITH_CUPS
driver = printer_cups_get_driver();
#endif
#ifdef WIN32
#if defined(_WIN32) && !defined(_UWP)
driver = printer_win_get_driver();
#endif
@ -502,7 +514,7 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
if ((error = printer_register(pEntryPoints, printer)))
{
WLog_ERR(TAG, "printer_register failed with error %lu!", error);
WLog_ERR(TAG, "printer_register failed with error %u!", error);
return error;
}
}
@ -513,12 +525,12 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
for (i = 0; printers[i]; i++)
{
printer = printers[i];
if ((error = printer_register(pEntryPoints, printer)))
{
WLog_ERR(TAG, "printer_register failed with error %lu!", error);
WLog_ERR(TAG, "printer_register failed with error %u!", error);
free(printers);
return error;
}
}

View File

@ -26,9 +26,9 @@ rdpPrinterDriver* printer_win_get_driver(void);
#define PRINTER_TAG CHANNELS_TAG("printer.client")
#ifdef WITH_DEBUG_WINPR
#define DEBUG_WINPR(fmt, ...) WLog_DBG(PRINTER_TAG, fmt, ## __VA_ARGS__)
#define DEBUG_WINPR(...) WLog_DBG(PRINTER_TAG, __VA_ARGS__)
#else
#define DEBUG_WINPR(fmt, ...) do { } while (0)
#define DEBUG_WINPR(...) do { } while (0)
#endif
#endif

View File

@ -25,7 +25,7 @@ set(${MODULE_PREFIX}_SRCS
rail_orders.c
rail_orders.h)
add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntry")
add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntryEx")

View File

@ -45,7 +45,7 @@ RailClientContext* rail_get_client_interface(railPlugin* rail)
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rail_send(railPlugin* rail, wStream* s)
static UINT rail_send(railPlugin* rail, wStream* s)
{
UINT status;
@ -55,15 +55,15 @@ UINT rail_send(railPlugin* rail, wStream* s)
}
else
{
status = rail->channelEntryPoints.pVirtualChannelWrite(rail->OpenHandle,
Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s);
status = rail->channelEntryPoints.pVirtualChannelWriteEx(rail->InitHandle, rail->OpenHandle,
Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s);
}
if (status != CHANNEL_RC_OK)
{
Stream_Free(s, TRUE);
WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]",
WTSErrorToString(status), status);
WLog_ERR(TAG, "pVirtualChannelWriteEx failed with %s [%08X]",
WTSErrorToString(status), status);
}
return status;
@ -77,15 +77,15 @@ UINT rail_send(railPlugin* rail, wStream* s)
UINT rail_send_channel_data(railPlugin* rail, void* data, size_t length)
{
wStream* s = NULL;
s = Stream_New(NULL, length);
if (!s)
{
WLog_ERR(TAG, "Stream_New failed!");
return CHANNEL_RC_NO_MEMORY;
}
Stream_Write(s, data, length);
Stream_Write(s, data, length);
return rail_send(rail, s);
}
@ -98,11 +98,11 @@ UINT rail_send_channel_data(railPlugin* rail, void* data, size_t length)
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rail_client_execute(RailClientContext* context, RAIL_EXEC_ORDER* exec)
static UINT rail_client_execute(RailClientContext* context,
RAIL_EXEC_ORDER* exec)
{
char* exeOrFile;
railPlugin* rail = (railPlugin*) context->handle;
exeOrFile = exec->RemoteApplicationProgram;
if (!exeOrFile)
@ -114,10 +114,12 @@ UINT rail_client_execute(RailClientContext* context, RAIL_EXEC_ORDER* exec)
exec->flags |= RAIL_EXEC_FLAG_FILE;
}
rail_string_to_unicode_string(exec->RemoteApplicationProgram, &exec->exeOrFile); /* RemoteApplicationProgram */
rail_string_to_unicode_string(exec->RemoteApplicationWorkingDir, &exec->workingDir); /* ShellWorkingDirectory */
rail_string_to_unicode_string(exec->RemoteApplicationArguments, &exec->arguments); /* RemoteApplicationCmdLine */
rail_string_to_unicode_string(exec->RemoteApplicationProgram,
&exec->exeOrFile); /* RemoteApplicationProgram */
rail_string_to_unicode_string(exec->RemoteApplicationWorkingDir,
&exec->workingDir); /* ShellWorkingDirectory */
rail_string_to_unicode_string(exec->RemoteApplicationArguments,
&exec->arguments); /* RemoteApplicationCmdLine */
return rail_send_client_exec_order(rail, exec);
}
@ -126,10 +128,10 @@ UINT rail_client_execute(RailClientContext* context, RAIL_EXEC_ORDER* exec)
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rail_client_activate(RailClientContext* context, RAIL_ACTIVATE_ORDER* activate)
static UINT rail_client_activate(RailClientContext* context,
RAIL_ACTIVATE_ORDER* activate)
{
railPlugin* rail = (railPlugin*) context->handle;
return rail_send_client_activate_order(rail, activate);
}
@ -138,13 +140,13 @@ UINT rail_client_activate(RailClientContext* context, RAIL_ACTIVATE_ORDER* activ
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rail_send_client_sysparam(RailClientContext* context, RAIL_SYSPARAM_ORDER* sysparam)
static UINT rail_send_client_sysparam(RailClientContext* context,
RAIL_SYSPARAM_ORDER* sysparam)
{
wStream* s;
int length;
railPlugin* rail = (railPlugin*) context->handle;
UINT error;
length = RAIL_SYSPARAM_ORDER_LENGTH;
switch (sysparam->param)
@ -168,6 +170,7 @@ UINT rail_send_client_sysparam(RailClientContext* context, RAIL_SYSPARAM_ORDER*
}
s = rail_pdu_init(RAIL_SYSPARAM_ORDER_LENGTH + 8);
if (!s)
{
WLog_ERR(TAG, "rail_pdu_init failed!");
@ -176,14 +179,14 @@ UINT rail_send_client_sysparam(RailClientContext* context, RAIL_SYSPARAM_ORDER*
if ((error = rail_write_client_sysparam_order(s, sysparam)))
{
WLog_ERR(TAG, "rail_write_client_sysparam_order failed with error %lu!", error);
WLog_ERR(TAG, "rail_write_client_sysparam_order failed with error %u!", error);
Stream_Free(s, TRUE);
return error;
}
if ((error = rail_send_pdu(rail, s, RDP_RAIL_ORDER_SYSPARAM)))
{
WLog_ERR(TAG, "rail_send_pdu failed with error %lu!", error);
WLog_ERR(TAG, "rail_send_pdu failed with error %u!", error);
}
Stream_Free(s, TRUE);
@ -195,16 +198,18 @@ UINT rail_send_client_sysparam(RailClientContext* context, RAIL_SYSPARAM_ORDER*
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* sysparam)
static UINT rail_client_system_param(RailClientContext* context,
RAIL_SYSPARAM_ORDER* sysparam)
{
UINT error = CHANNEL_RC_OK;
if (sysparam->params & SPI_MASK_SET_HIGH_CONTRAST)
{
sysparam->param = SPI_SET_HIGH_CONTRAST;
if ((error = rail_send_client_sysparam(context, sysparam)))
{
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error);
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %u!", error);
return error;
}
}
@ -212,9 +217,10 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s
if (sysparam->params & SPI_MASK_TASKBAR_POS)
{
sysparam->param = SPI_TASKBAR_POS;
if ((error = rail_send_client_sysparam(context, sysparam)))
{
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error);
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %u!", error);
return error;
}
}
@ -222,9 +228,10 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s
if (sysparam->params & SPI_MASK_SET_MOUSE_BUTTON_SWAP)
{
sysparam->param = SPI_SET_MOUSE_BUTTON_SWAP;
if ((error = rail_send_client_sysparam(context, sysparam)))
{
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error);
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %u!", error);
return error;
}
}
@ -232,9 +239,10 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s
if (sysparam->params & SPI_MASK_SET_KEYBOARD_PREF)
{
sysparam->param = SPI_SET_KEYBOARD_PREF;
if ((error = rail_send_client_sysparam(context, sysparam)))
{
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error);
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %u!", error);
return error;
}
}
@ -242,9 +250,10 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s
if (sysparam->params & SPI_MASK_SET_DRAG_FULL_WINDOWS)
{
sysparam->param = SPI_SET_DRAG_FULL_WINDOWS;
if ((error = rail_send_client_sysparam(context, sysparam)))
{
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error);
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %u!", error);
return error;
}
}
@ -252,9 +261,10 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s
if (sysparam->params & SPI_MASK_SET_KEYBOARD_CUES)
{
sysparam->param = SPI_SET_KEYBOARD_CUES;
if ((error = rail_send_client_sysparam(context, sysparam)))
{
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error);
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %u!", error);
return error;
}
}
@ -262,9 +272,10 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s
if (sysparam->params & SPI_MASK_SET_WORK_AREA)
{
sysparam->param = SPI_SET_WORK_AREA;
if ((error = rail_send_client_sysparam(context, sysparam)))
{
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error);
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %u!", error);
return error;
}
}
@ -277,7 +288,8 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rail_server_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* sysparam)
static UINT rail_server_system_param(RailClientContext* context,
RAIL_SYSPARAM_ORDER* sysparam)
{
return CHANNEL_RC_OK; /* stub - should be registered by client */
}
@ -287,10 +299,10 @@ UINT rail_server_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rail_client_system_command(RailClientContext* context, RAIL_SYSCOMMAND_ORDER* syscommand)
static UINT rail_client_system_command(RailClientContext* context,
RAIL_SYSCOMMAND_ORDER* syscommand)
{
railPlugin* rail = (railPlugin*) context->handle;
return rail_send_client_syscommand_order(rail, syscommand);
}
@ -299,10 +311,10 @@ UINT rail_client_system_command(RailClientContext* context, RAIL_SYSCOMMAND_ORDE
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rail_client_handshake(RailClientContext* context, RAIL_HANDSHAKE_ORDER* handshake)
static UINT rail_client_handshake(RailClientContext* context,
RAIL_HANDSHAKE_ORDER* handshake)
{
railPlugin* rail = (railPlugin*) context->handle;
return rail_send_handshake_order(rail, handshake);
}
@ -311,7 +323,8 @@ UINT rail_client_handshake(RailClientContext* context, RAIL_HANDSHAKE_ORDER* han
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rail_server_handshake(RailClientContext* context, RAIL_HANDSHAKE_ORDER* handshake)
static UINT rail_server_handshake(RailClientContext* context,
RAIL_HANDSHAKE_ORDER* handshake)
{
return CHANNEL_RC_OK; /* stub - should be registered by client */
}
@ -321,10 +334,10 @@ UINT rail_server_handshake(RailClientContext* context, RAIL_HANDSHAKE_ORDER* han
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rail_client_handshake_ex(RailClientContext* context, RAIL_HANDSHAKE_EX_ORDER* handshakeEx)
static UINT rail_client_handshake_ex(RailClientContext* context,
RAIL_HANDSHAKE_EX_ORDER* handshakeEx)
{
railPlugin* rail = (railPlugin*) context->handle;
return rail_send_handshake_ex_order(rail, handshakeEx);
}
@ -333,7 +346,8 @@ UINT rail_client_handshake_ex(RailClientContext* context, RAIL_HANDSHAKE_EX_ORDE
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rail_server_handshake_ex(RailClientContext* context, RAIL_HANDSHAKE_EX_ORDER* handshakeEx)
static UINT rail_server_handshake_ex(RailClientContext* context,
RAIL_HANDSHAKE_EX_ORDER* handshakeEx)
{
return CHANNEL_RC_OK; /* stub - should be registered by client */
}
@ -343,10 +357,10 @@ UINT rail_server_handshake_ex(RailClientContext* context, RAIL_HANDSHAKE_EX_ORDE
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rail_client_notify_event(RailClientContext* context, RAIL_NOTIFY_EVENT_ORDER* notifyEvent)
static UINT rail_client_notify_event(RailClientContext* context,
RAIL_NOTIFY_EVENT_ORDER* notifyEvent)
{
railPlugin* rail = (railPlugin*) context->handle;
return rail_send_client_notify_event_order(rail, notifyEvent);
}
@ -355,10 +369,10 @@ UINT rail_client_notify_event(RailClientContext* context, RAIL_NOTIFY_EVENT_ORDE
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rail_client_window_move(RailClientContext* context, RAIL_WINDOW_MOVE_ORDER* windowMove)
static UINT rail_client_window_move(RailClientContext* context,
RAIL_WINDOW_MOVE_ORDER* windowMove)
{
railPlugin* rail = (railPlugin*) context->handle;
return rail_send_client_window_move_order(rail, windowMove);
}
@ -367,7 +381,8 @@ UINT rail_client_window_move(RailClientContext* context, RAIL_WINDOW_MOVE_ORDER*
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rail_server_local_move_size(RailClientContext* context, RAIL_LOCALMOVESIZE_ORDER* localMoveSize)
static UINT rail_server_local_move_size(RailClientContext* context,
RAIL_LOCALMOVESIZE_ORDER* localMoveSize)
{
return CHANNEL_RC_OK; /* stub - should be registered by client */
}
@ -377,7 +392,8 @@ UINT rail_server_local_move_size(RailClientContext* context, RAIL_LOCALMOVESIZE_
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rail_server_min_max_info(RailClientContext* context, RAIL_MINMAXINFO_ORDER* minMaxInfo)
static UINT rail_server_min_max_info(RailClientContext* context,
RAIL_MINMAXINFO_ORDER* minMaxInfo)
{
return CHANNEL_RC_OK; /* stub - should be registered by client */
}
@ -387,10 +403,10 @@ UINT rail_server_min_max_info(RailClientContext* context, RAIL_MINMAXINFO_ORDER*
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rail_client_information(RailClientContext* context, RAIL_CLIENT_STATUS_ORDER* clientStatus)
static UINT rail_client_information(RailClientContext* context,
RAIL_CLIENT_STATUS_ORDER* clientStatus)
{
railPlugin* rail = (railPlugin*) context->handle;
return rail_send_client_status_order(rail, clientStatus);
}
@ -399,10 +415,10 @@ UINT rail_client_information(RailClientContext* context, RAIL_CLIENT_STATUS_ORDE
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rail_client_system_menu(RailClientContext* context, RAIL_SYSMENU_ORDER* sysmenu)
static UINT rail_client_system_menu(RailClientContext* context,
RAIL_SYSMENU_ORDER* sysmenu)
{
railPlugin* rail = (railPlugin*) context->handle;
return rail_send_client_sysmenu_order(rail, sysmenu);
}
@ -411,10 +427,10 @@ UINT rail_client_system_menu(RailClientContext* context, RAIL_SYSMENU_ORDER* sys
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rail_client_language_bar_info(RailClientContext* context, RAIL_LANGBAR_INFO_ORDER* langBarInfo)
static UINT rail_client_language_bar_info(RailClientContext* context,
RAIL_LANGBAR_INFO_ORDER* langBarInfo)
{
railPlugin* rail = (railPlugin*) context->handle;
return rail_send_client_langbar_info_order(rail, langBarInfo);
}
@ -423,7 +439,8 @@ UINT rail_client_language_bar_info(RailClientContext* context, RAIL_LANGBAR_INFO
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rail_server_language_bar_info(RailClientContext* context, RAIL_LANGBAR_INFO_ORDER* langBarInfo)
static UINT rail_server_language_bar_info(RailClientContext* context,
RAIL_LANGBAR_INFO_ORDER* langBarInfo)
{
return CHANNEL_RC_OK; /* stub - should be registered by client */
}
@ -433,7 +450,8 @@ UINT rail_server_language_bar_info(RailClientContext* context, RAIL_LANGBAR_INFO
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rail_server_execute_result(RailClientContext* context, RAIL_EXEC_RESULT_ORDER* execResult)
static UINT rail_server_execute_result(RailClientContext* context,
RAIL_EXEC_RESULT_ORDER* execResult)
{
return CHANNEL_RC_OK; /* stub - should be registered by client */
}
@ -443,10 +461,10 @@ UINT rail_server_execute_result(RailClientContext* context, RAIL_EXEC_RESULT_ORD
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rail_client_get_appid_request(RailClientContext* context, RAIL_GET_APPID_REQ_ORDER* getAppIdReq)
static UINT rail_client_get_appid_request(RailClientContext* context,
RAIL_GET_APPID_REQ_ORDER* getAppIdReq)
{
railPlugin* rail = (railPlugin*) context->handle;
return rail_send_client_get_appid_req_order(rail, getAppIdReq);
}
@ -455,111 +473,19 @@ UINT rail_client_get_appid_request(RailClientContext* context, RAIL_GET_APPID_RE
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rail_server_get_appid_response(RailClientContext* context, RAIL_GET_APPID_RESP_ORDER* getAppIdResp)
static UINT rail_server_get_appid_response(RailClientContext* context,
RAIL_GET_APPID_RESP_ORDER* getAppIdResp)
{
return CHANNEL_RC_OK; /* stub - should be registered by client */
}
/****************************************************************************************/
static wListDictionary* g_InitHandles = NULL;
static wListDictionary* g_OpenHandles = NULL;
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rail_add_init_handle_data(void* pInitHandle, void* pUserData)
{
if (!g_InitHandles)
{
g_InitHandles = ListDictionary_New(TRUE);
}
if (!g_InitHandles)
{
WLog_ERR(TAG, "ListDictionary_New failed!");
return CHANNEL_RC_NO_MEMORY;
}
if (!ListDictionary_Add(g_InitHandles, pInitHandle, pUserData))
{
WLog_ERR(TAG, "ListDictionary_Add failed!");
return ERROR_INTERNAL_ERROR;
}
return CHANNEL_RC_OK;
}
void* rail_get_init_handle_data(void* pInitHandle)
{
void* pUserData = NULL;
pUserData = ListDictionary_GetItemValue(g_InitHandles, pInitHandle);
return pUserData;
}
void rail_remove_init_handle_data(void* pInitHandle)
{
ListDictionary_Remove(g_InitHandles, pInitHandle);
if (ListDictionary_Count(g_InitHandles) < 1)
{
ListDictionary_Free(g_InitHandles);
g_InitHandles = NULL;
}
}
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rail_add_open_handle_data(DWORD openHandle, void* pUserData)
{
void* pOpenHandle = (void*) (size_t) openHandle;
if (!g_OpenHandles)
{
g_OpenHandles = ListDictionary_New(TRUE);
}
if (!g_OpenHandles)
{
WLog_ERR(TAG, "ListDictionary_New failed!");
return CHANNEL_RC_NO_MEMORY;
}
if (!ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData))
{
WLog_ERR(TAG, "ListDictionary_Add failed!");
return ERROR_INTERNAL_ERROR;
}
return CHANNEL_RC_OK;
}
void* rail_get_open_handle_data(DWORD openHandle)
{
void* pUserData = NULL;
void* pOpenHandle = (void*) (size_t) openHandle;
pUserData = ListDictionary_GetItemValue(g_OpenHandles, pOpenHandle);
return pUserData;
}
void rail_remove_open_handle_data(DWORD openHandle)
{
void* pOpenHandle = (void*) (size_t) openHandle;
ListDictionary_Remove(g_OpenHandles, pOpenHandle);
if (ListDictionary_Count(g_OpenHandles) < 1)
{
ListDictionary_Free(g_OpenHandles);
g_OpenHandles = NULL;
}
}
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT rail_virtual_channel_event_data_received(railPlugin* rail,
void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
{
wStream* data_in;
@ -574,6 +500,7 @@ static UINT rail_virtual_channel_event_data_received(railPlugin* rail,
Stream_Free(rail->data_in, TRUE);
rail->data_in = Stream_New(NULL, totalLength);
if (!rail->data_in)
{
WLog_ERR(TAG, "Stream_New failed!");
@ -582,11 +509,13 @@ static UINT rail_virtual_channel_event_data_received(railPlugin* rail,
}
data_in = rail->data_in;
if (!Stream_EnsureRemainingCapacity(data_in, (int) dataLength))
{
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
return CHANNEL_RC_NO_MEMORY;
}
Stream_Write(data_in, pData, dataLength);
if (dataFlags & CHANNEL_FLAG_LAST)
@ -607,28 +536,31 @@ static UINT rail_virtual_channel_event_data_received(railPlugin* rail,
return ERROR_INTERNAL_ERROR;
}
}
return CHANNEL_RC_OK;
}
static VOID VCAPITYPE rail_virtual_channel_open_event(DWORD openHandle, UINT event,
LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
static VOID VCAPITYPE rail_virtual_channel_open_event_ex(LPVOID lpUserParam, DWORD openHandle,
UINT event,
LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
{
railPlugin* rail;
UINT error = CHANNEL_RC_OK;
railPlugin* rail = (railPlugin*) lpUserParam;
rail = (railPlugin*) rail_get_open_handle_data(openHandle);
if (!rail)
if (!rail || (rail->OpenHandle != openHandle))
{
WLog_ERR(TAG, "rail_virtual_channel_open_event: error no match");
WLog_ERR(TAG, "error no match");
return;
}
switch (event)
{
case CHANNEL_EVENT_DATA_RECEIVED:
if ((error = rail_virtual_channel_event_data_received(rail, pData, dataLength, totalLength, dataFlags)))
WLog_ERR(TAG, "rail_virtual_channel_event_data_received failed with error %lu!", error);
if ((error = rail_virtual_channel_event_data_received(rail, pData, dataLength,
totalLength, dataFlags)))
WLog_ERR(TAG, "rail_virtual_channel_event_data_received failed with error %u!",
error);
break;
case CHANNEL_EVENT_WRITE_COMPLETE:
@ -640,7 +572,8 @@ static VOID VCAPITYPE rail_virtual_channel_open_event(DWORD openHandle, UINT eve
}
if (error && rail->rdpcontext)
setChannelError(rail->rdpcontext, error, "rail_virtual_channel_open_event reported an error");
setChannelError(rail->rdpcontext, error,
"rail_virtual_channel_open_event reported an error");
return;
}
@ -667,12 +600,14 @@ static void* rail_virtual_channel_client_thread(void* arg)
error = ERROR_INTERNAL_ERROR;
break;
}
if (message.id == WMQ_QUIT)
break;
if (message.id == 0)
{
data = (wStream*) message.wParam;
if ((error = rail_order_recv(rail, data)))
{
WLog_ERR(TAG, "rail_order_recv failed with error %d!", error);
@ -682,7 +617,8 @@ static void* rail_virtual_channel_client_thread(void* arg)
}
if (error && rail->rdpcontext)
setChannelError(rail->rdpcontext, error, "rail_virtual_channel_client_thread reported an error");
setChannelError(rail->rdpcontext, error,
"rail_virtual_channel_client_thread reported an error");
ExitThread((DWORD)error);
return NULL;
@ -693,27 +629,22 @@ static void* rail_virtual_channel_client_thread(void* arg)
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT rail_virtual_channel_event_connected(railPlugin* rail, LPVOID pData, UINT32 dataLength)
static UINT rail_virtual_channel_event_connected(railPlugin* rail, LPVOID pData,
UINT32 dataLength)
{
UINT status;
status = rail->channelEntryPoints.pVirtualChannelOpen(rail->InitHandle,
&rail->OpenHandle, rail->channelDef.name, rail_virtual_channel_open_event);
status = rail->channelEntryPoints.pVirtualChannelOpenEx(rail->InitHandle,
&rail->OpenHandle, rail->channelDef.name, rail_virtual_channel_open_event_ex);
if (status != CHANNEL_RC_OK)
{
WLog_ERR(TAG, "pVirtualChannelOpen failed with %s [%08X]",
WTSErrorToString(status), status);
return status;
}
if ((status = rail_add_open_handle_data(rail->OpenHandle, rail)))
{
WLog_ERR(TAG, "rail_add_open_handle_data failed with error %lu!", status);
WTSErrorToString(status), status);
return status;
}
rail->queue = MessageQueue_New(NULL);
if (!rail->queue)
{
WLog_ERR(TAG, "MessageQueue_New failed!");
@ -721,13 +652,15 @@ static UINT rail_virtual_channel_event_connected(railPlugin* rail, LPVOID pData,
}
if (!(rail->thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) rail_virtual_channel_client_thread, (void*) rail, 0, NULL)))
(LPTHREAD_START_ROUTINE) rail_virtual_channel_client_thread, (void*) rail, 0,
NULL)))
{
WLog_ERR(TAG, "CreateThread failed!");
MessageQueue_Free(rail->queue);
rail->queue = NULL;
return ERROR_INTERNAL_ERROR;
}
return CHANNEL_RC_OK;
}
@ -739,53 +672,54 @@ static UINT rail_virtual_channel_event_connected(railPlugin* rail, LPVOID pData,
static UINT rail_virtual_channel_event_disconnected(railPlugin* rail)
{
UINT rc;
if (MessageQueue_PostQuit(rail->queue, 0) && (WaitForSingleObject(rail->thread, INFINITE) == WAIT_FAILED))
{
rc = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", rc);
return rc;
}
if (MessageQueue_PostQuit(rail->queue, 0)
&& (WaitForSingleObject(rail->thread, INFINITE) == WAIT_FAILED))
{
rc = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %u", rc);
return rc;
}
MessageQueue_Free(rail->queue);
CloseHandle(rail->thread);
rail->queue = NULL;
rail->thread = NULL;
rc = rail->channelEntryPoints.pVirtualChannelCloseEx(rail->InitHandle, rail->OpenHandle);
rc = rail->channelEntryPoints.pVirtualChannelClose(rail->OpenHandle);
if (CHANNEL_RC_OK != rc)
{
WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08X]",
WTSErrorToString(rc), rc);
return rc;
WLog_ERR(TAG, "pVirtualChannelCloseEx failed with %s [%08X]",
WTSErrorToString(rc), rc);
return rc;
}
rail->OpenHandle = 0;
if (rail->data_in)
{
Stream_Free(rail->data_in, TRUE);
rail->data_in = NULL;
}
rail_remove_open_handle_data(rail->OpenHandle);
return CHANNEL_RC_OK;
return CHANNEL_RC_OK;
}
static void rail_virtual_channel_event_terminated(railPlugin* rail)
{
rail_remove_init_handle_data(rail->InitHandle);
rail->InitHandle = 0;
free(rail);
}
static VOID VCAPITYPE rail_virtual_channel_init_event(LPVOID pInitHandle, UINT event, LPVOID pData, UINT dataLength)
static VOID VCAPITYPE rail_virtual_channel_init_event_ex(LPVOID lpUserParam, LPVOID pInitHandle,
UINT event, LPVOID pData, UINT dataLength)
{
railPlugin* rail;
UINT error = CHANNEL_RC_OK;
railPlugin* rail = (railPlugin*) lpUserParam;
rail = (railPlugin*) rail_get_init_handle_data(pInitHandle);
if (!rail)
if (!rail || (rail->InitHandle != pInitHandle))
{
WLog_ERR(TAG, "rail_virtual_channel_init_event: error no match");
WLog_ERR(TAG, "error no match");
return;
}
@ -793,12 +727,16 @@ static VOID VCAPITYPE rail_virtual_channel_init_event(LPVOID pInitHandle, UINT e
{
case CHANNEL_EVENT_CONNECTED:
if ((error = rail_virtual_channel_event_connected(rail, pData, dataLength)))
WLog_ERR(TAG, "rail_virtual_channel_event_connected failed with error %lu!", error);
WLog_ERR(TAG, "rail_virtual_channel_event_connected failed with error %u!",
error);
break;
case CHANNEL_EVENT_DISCONNECTED:
if ((error = rail_virtual_channel_event_disconnected(rail)))
WLog_ERR(TAG, "rail_virtual_channel_event_disconnected failed with error %lu!", error);
WLog_ERR(TAG, "rail_virtual_channel_event_disconnected failed with error %u!",
error);
break;
case CHANNEL_EVENT_TERMINATED:
@ -806,23 +744,22 @@ static VOID VCAPITYPE rail_virtual_channel_init_event(LPVOID pInitHandle, UINT e
break;
}
if(error && rail->rdpcontext)
setChannelError(rail->rdpcontext, error, "rail_virtual_channel_init_event reported an error");
if (error && rail->rdpcontext)
setChannelError(rail->rdpcontext, error, "rail_virtual_channel_init_event_ex reported an error");
}
/* rail is always built-in */
#define VirtualChannelEntry rail_VirtualChannelEntry
#define VirtualChannelEntryEx rail_VirtualChannelEntryEx
BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID pInitHandle)
{
UINT rc;
railPlugin* rail;
RailClientContext* context;
CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx;
RailClientContext* context = NULL;
CHANNEL_ENTRY_POINTS_FREERDP_EX* pEntryPointsEx;
BOOL isFreerdp = FALSE;
UINT error;
rail = (railPlugin*) calloc(1, sizeof(railPlugin));
if (!rail)
{
WLog_ERR(TAG, "calloc failed!");
@ -830,19 +767,18 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
}
rail->channelDef.options =
CHANNEL_OPTION_INITIALIZED |
CHANNEL_OPTION_ENCRYPT_RDP |
CHANNEL_OPTION_COMPRESS_RDP |
CHANNEL_OPTION_SHOW_PROTOCOL;
CHANNEL_OPTION_INITIALIZED |
CHANNEL_OPTION_ENCRYPT_RDP |
CHANNEL_OPTION_COMPRESS_RDP |
CHANNEL_OPTION_SHOW_PROTOCOL;
strcpy(rail->channelDef.name, "rail");
pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP_EX*) pEntryPoints;
pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints;
if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP)) &&
(pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER))
if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)) &&
(pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER))
{
context = (RailClientContext*) calloc(1, sizeof(RailClientContext));
if (!context)
{
WLog_ERR(TAG, "calloc failed!");
@ -852,7 +788,6 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
context->handle = (void*) rail;
context->custom = NULL;
context->ClientExecute = rail_client_execute;
context->ClientActivate = rail_client_activate;
context->ClientSystemParam = rail_client_system_param;
@ -874,42 +809,34 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
context->ClientGetAppIdRequest = rail_client_get_appid_request;
context->ServerGetAppIdResponse = rail_server_get_appid_response;
rail->rdpcontext = pEntryPointsEx->context;
*(pEntryPointsEx->ppInterface) = (void*) context;
rail->context = context;
isFreerdp = TRUE;
}
WLog_Init();
rail->log = WLog_Get("com.freerdp.channels.rail.client");
WLog_Print(rail->log, WLOG_DEBUG, "VirtualChannelEntry");
CopyMemory(&(rail->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP));
rc = rail->channelEntryPoints.pVirtualChannelInit(&rail->InitHandle,
&rail->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, rail_virtual_channel_init_event);
WLog_Print(rail->log, WLOG_DEBUG, "VirtualChannelEntryEx");
CopyMemory(&(rail->channelEntryPoints), pEntryPoints,
sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX));
rail->InitHandle = pInitHandle;
rc = rail->channelEntryPoints.pVirtualChannelInitEx(rail, context, pInitHandle,
&rail->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000,
rail_virtual_channel_init_event_ex);
if (CHANNEL_RC_OK != rc)
{
WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]",
WTSErrorToString(rc), rc);
goto error_out;
}
rail->channelEntryPoints.pInterface = *(rail->channelEntryPoints.ppInterface);
rail->channelEntryPoints.ppInterface = &(rail->channelEntryPoints.pInterface);
if ((error = rail_add_init_handle_data(rail->InitHandle, (void*) rail)))
{
WLog_ERR(TAG, "rail_add_init_handle_data failed with error %lu!", error);
WLog_ERR(TAG, "failed with %s [%08X]",
WTSErrorToString(rc), rc);
goto error_out;
}
rail->channelEntryPoints.pInterface = context;
return TRUE;
error_out:
if (isFreerdp)
free(rail->context);
free(rail);
return FALSE;
}

View File

@ -39,7 +39,7 @@
struct rail_plugin
{
CHANNEL_DEF channelDef;
CHANNEL_ENTRY_POINTS_FREERDP channelEntryPoints;
CHANNEL_ENTRY_POINTS_FREERDP_EX channelEntryPoints;
RailClientContext* context;

View File

@ -268,17 +268,17 @@ UINT rail_write_client_exec_order(wStream* s, RAIL_EXEC_ORDER* exec)
Stream_Write_UINT16(s, exec->arguments.length); /* argumentsLength (2 bytes) */
if ((error = rail_write_unicode_string_value(s, &exec->exeOrFile)))
{
WLog_ERR(TAG, "rail_write_unicode_string_value failed with error %lu", error);
WLog_ERR(TAG, "rail_write_unicode_string_value failed with error %u", error);
return error;
}
if ((error = rail_write_unicode_string_value(s, &exec->workingDir)))
{
WLog_ERR(TAG, "rail_write_unicode_string_value failed with error %lu", error);
WLog_ERR(TAG, "rail_write_unicode_string_value failed with error %u", error);
return error;
}
if ((error = rail_write_unicode_string_value(s, &exec->arguments)))
{
WLog_ERR(TAG, "rail_write_unicode_string_value failed with error %lu", error);
WLog_ERR(TAG, "rail_write_unicode_string_value failed with error %u", error);
return error;
}
return error;
@ -408,7 +408,7 @@ UINT rail_recv_handshake_order(railPlugin* rail, RAIL_HANDSHAKE_ORDER* handshake
if ((error = rail_read_handshake_order(s, handshake)))
{
WLog_ERR(TAG, "rail_read_handshake_order failed with error %lu!", error);
WLog_ERR(TAG, "rail_read_handshake_order failed with error %u!", error);
return error;
}
@ -416,7 +416,7 @@ UINT rail_recv_handshake_order(railPlugin* rail, RAIL_HANDSHAKE_ORDER* handshake
{
IFCALLRET(context->ServerHandshake, error, context, handshake);
if (error)
WLog_ERR(TAG, "context.ServerHandshake failed with error %lu", error);
WLog_ERR(TAG, "context.ServerHandshake failed with error %u", error);
}
return error;
@ -434,7 +434,7 @@ UINT rail_recv_handshake_ex_order(railPlugin* rail, RAIL_HANDSHAKE_EX_ORDER* han
if ((error = rail_read_handshake_ex_order(s, handshakeEx)))
{
WLog_ERR(TAG, "rail_read_handshake_ex_order failed with error %lu!", error);
WLog_ERR(TAG, "rail_read_handshake_ex_order failed with error %u!", error);
return error;
}
@ -442,7 +442,7 @@ UINT rail_recv_handshake_ex_order(railPlugin* rail, RAIL_HANDSHAKE_EX_ORDER* han
{
IFCALLRET(context->ClientHandshakeEx, error, context, handshakeEx);
if (error)
WLog_ERR(TAG, "context.ClientHandshakeEx failed with error %lu", error);
WLog_ERR(TAG, "context.ClientHandshakeEx failed with error %u", error);
}
@ -463,7 +463,7 @@ UINT rail_recv_exec_result_order(railPlugin* rail, RAIL_EXEC_RESULT_ORDER* execR
if ((error = rail_read_server_exec_result_order(s, execResult)))
{
WLog_ERR(TAG, "rail_read_server_exec_result_order failed with error %lu!", error);
WLog_ERR(TAG, "rail_read_server_exec_result_order failed with error %u!", error);
return error;
}
@ -471,7 +471,7 @@ UINT rail_recv_exec_result_order(railPlugin* rail, RAIL_EXEC_RESULT_ORDER* execR
{
IFCALLRET(context->ServerExecuteResult, error, context, execResult);
if (error)
WLog_ERR(TAG, "context.ServerExecuteResult failed with error %lu", error);
WLog_ERR(TAG, "context.ServerExecuteResult failed with error %u", error);
}
@ -490,7 +490,7 @@ UINT rail_recv_server_sysparam_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sysp
if ((error = rail_read_server_sysparam_order(s, sysparam)))
{
WLog_ERR(TAG, "rail_read_server_sysparam_order failed with error %lu!", error);
WLog_ERR(TAG, "rail_read_server_sysparam_order failed with error %u!", error);
return error;
}
@ -498,7 +498,7 @@ UINT rail_recv_server_sysparam_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sysp
{
IFCALLRET(context->ServerSystemParam, error, context, sysparam);
if (error)
WLog_ERR(TAG, "context.ServerSystemParam failed with error %lu", error);
WLog_ERR(TAG, "context.ServerSystemParam failed with error %u", error);
}
return error;
@ -516,7 +516,7 @@ UINT rail_recv_server_minmaxinfo_order(railPlugin* rail, RAIL_MINMAXINFO_ORDER*
if ((error = rail_read_server_minmaxinfo_order(s, minMaxInfo)))
{
WLog_ERR(TAG, "rail_read_server_minmaxinfo_order failed with error %lu!", error);
WLog_ERR(TAG, "rail_read_server_minmaxinfo_order failed with error %u!", error);
return error;
}
@ -524,7 +524,7 @@ UINT rail_recv_server_minmaxinfo_order(railPlugin* rail, RAIL_MINMAXINFO_ORDER*
{
IFCALLRET(context->ServerMinMaxInfo, error, context, minMaxInfo);
if (error)
WLog_ERR(TAG, "context.ServerMinMaxInfo failed with error %lu", error);
WLog_ERR(TAG, "context.ServerMinMaxInfo failed with error %u", error);
}
return error;
@ -542,7 +542,7 @@ UINT rail_recv_server_localmovesize_order(railPlugin* rail, RAIL_LOCALMOVESIZE_O
if ((error = rail_read_server_localmovesize_order(s, localMoveSize)))
{
WLog_ERR(TAG, "rail_read_server_localmovesize_order failed with error %lu!", error);
WLog_ERR(TAG, "rail_read_server_localmovesize_order failed with error %u!", error);
return error;
}
@ -550,7 +550,7 @@ UINT rail_recv_server_localmovesize_order(railPlugin* rail, RAIL_LOCALMOVESIZE_O
{
IFCALLRET(context->ServerLocalMoveSize, error, context, localMoveSize);
if (error)
WLog_ERR(TAG, "context.ServerLocalMoveSize failed with error %lu", error);
WLog_ERR(TAG, "context.ServerLocalMoveSize failed with error %u", error);
}
return error;
@ -568,7 +568,7 @@ UINT rail_recv_server_get_appid_resp_order(railPlugin* rail, RAIL_GET_APPID_RESP
if ((error = rail_read_server_get_appid_resp_order(s, getAppIdResp)))
{
WLog_ERR(TAG, "rail_read_server_get_appid_resp_order failed with error %lu!", error);
WLog_ERR(TAG, "rail_read_server_get_appid_resp_order failed with error %u!", error);
return error;
}
@ -576,7 +576,7 @@ UINT rail_recv_server_get_appid_resp_order(railPlugin* rail, RAIL_GET_APPID_RESP
{
IFCALLRET(context->ServerGetAppIdResponse, error, context, getAppIdResp);
if (error)
WLog_ERR(TAG, "context.ServerGetAppIdResponse failed with error %lu", error);
WLog_ERR(TAG, "context.ServerGetAppIdResponse failed with error %u", error);
}
return error;
@ -594,7 +594,7 @@ UINT rail_recv_langbar_info_order(railPlugin* rail, RAIL_LANGBAR_INFO_ORDER* lan
if ((error = rail_read_langbar_info_order(s, langBarInfo)))
{
WLog_ERR(TAG, "rail_read_langbar_info_order failed with error %lu!", error);
WLog_ERR(TAG, "rail_read_langbar_info_order failed with error %u!", error);
return error;
}
@ -602,7 +602,7 @@ UINT rail_recv_langbar_info_order(railPlugin* rail, RAIL_LANGBAR_INFO_ORDER* lan
{
IFCALLRET(context->ServerLanguageBarInfo, error, context, langBarInfo);
if (error)
WLog_ERR(TAG, "context.ServerLanguageBarInfo failed with error %lu", error);
WLog_ERR(TAG, "context.ServerLanguageBarInfo failed with error %u", error);
}
return error;
@ -621,12 +621,12 @@ UINT rail_order_recv(railPlugin* rail, wStream* s)
if ((error = rail_read_pdu_header(s, &orderType, &orderLength)))
{
WLog_ERR(TAG, "rail_read_pdu_header failed with error %lu!", error);
WLog_ERR(TAG, "rail_read_pdu_header failed with error %u!", error);
return error;
}
WLog_Print(rail->log, WLOG_DEBUG, "Received %s PDU, length:%lu",
RAIL_ORDER_TYPE_STRINGS[((orderType & 0xF0) >> 3) + (orderType & 0x0F)], orderLength);
WLog_Print(rail->log, WLOG_DEBUG, "Received %s PDU, length:%u",
RAIL_ORDER_TYPE_STRINGS[((orderType & 0xF0) >> 3) + (orderType & 0x0F)], (unsigned)orderLength);
switch (orderType)
{
@ -780,12 +780,12 @@ UINT rail_send_client_exec_order(railPlugin* rail, RAIL_EXEC_ORDER* exec)
if ((error = rail_write_client_exec_order(s, exec)))
{
WLog_ERR(TAG, "rail_write_client_exec_order failed with error %lu!", error);
WLog_ERR(TAG, "rail_write_client_exec_order failed with error %u!", error);
return error;
}
if ((error = rail_send_pdu(rail, s, RDP_RAIL_ORDER_EXEC)))
{
WLog_ERR(TAG, "rail_send_pdu failed with error %lu!", error);
WLog_ERR(TAG, "rail_send_pdu failed with error %u!", error);
return error;
}
Stream_Free(s, TRUE);
@ -834,13 +834,13 @@ UINT rail_send_client_sysparam_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sysp
if ((error = rail_write_client_sysparam_order(s, sysparam)))
{
WLog_ERR(TAG, "rail_write_client_sysparam_order failed with error %lu!", error);
WLog_ERR(TAG, "rail_write_client_sysparam_order failed with error %u!", error);
return error;
}
if ((error = rail_send_pdu(rail, s, RDP_RAIL_ORDER_SYSPARAM)))
{
WLog_ERR(TAG, "rail_send_pdu failed with error %lu!", error);
WLog_ERR(TAG, "rail_send_pdu failed with error %u!", error);
return error;
}
@ -862,7 +862,7 @@ UINT rail_send_client_sysparams_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sys
sysparam->param = SPI_SET_HIGH_CONTRAST;
if ((error = rail_send_client_sysparam_order(rail, sysparam)))
{
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %lu!", error);
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %u!", error);
return error;
}
}
@ -872,7 +872,7 @@ UINT rail_send_client_sysparams_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sys
sysparam->param = SPI_TASKBAR_POS;
if ((error = rail_send_client_sysparam_order(rail, sysparam)))
{
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %lu!", error);
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %u!", error);
return error;
}
}
@ -882,7 +882,7 @@ UINT rail_send_client_sysparams_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sys
sysparam->param = SPI_SET_MOUSE_BUTTON_SWAP;
if ((error = rail_send_client_sysparam_order(rail, sysparam)))
{
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %lu!", error);
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %u!", error);
return error;
}
}
@ -892,7 +892,7 @@ UINT rail_send_client_sysparams_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sys
sysparam->param = SPI_SET_KEYBOARD_PREF;
if ((error = rail_send_client_sysparam_order(rail, sysparam)))
{
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %lu!", error);
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %u!", error);
return error;
}
}
@ -902,7 +902,7 @@ UINT rail_send_client_sysparams_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sys
sysparam->param = SPI_SET_DRAG_FULL_WINDOWS;
if ((error = rail_send_client_sysparam_order(rail, sysparam)))
{
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %lu!", error);
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %u!", error);
return error;
}
}
@ -912,7 +912,7 @@ UINT rail_send_client_sysparams_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sys
sysparam->param = SPI_SET_KEYBOARD_CUES;
if ((error = rail_send_client_sysparam_order(rail, sysparam)))
{
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %lu!", error);
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %u!", error);
return error;
}
}
@ -922,7 +922,7 @@ UINT rail_send_client_sysparams_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sys
sysparam->param = SPI_SET_WORK_AREA;
if ((error = rail_send_client_sysparam_order(rail, sysparam)))
{
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %lu!", error);
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %u!", error);
return error;
}
}

View File

@ -29,7 +29,7 @@ set(${MODULE_PREFIX}_SRCS
rdpdr_capabilities.c
rdpdr_capabilities.h)
add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntry")
add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntryEx")

File diff suppressed because it is too large Load Diff

View File

@ -49,7 +49,7 @@ typedef struct rdpdr_plugin rdpdrPlugin;
struct rdpdr_plugin
{
CHANNEL_DEF channelDef;
CHANNEL_ENTRY_POINTS_FREERDP channelEntryPoints;
CHANNEL_ENTRY_POINTS_FREERDP_EX channelEntryPoints;
HANDLE thread;
wStream* data_in;

File diff suppressed because it is too large Load Diff

View File

@ -31,7 +31,7 @@ add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE
target_link_libraries(${MODULE_NAME} winpr freerdp)
if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS)
if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS)
install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols)
endif()

View File

@ -138,16 +138,16 @@ UINT rdpei_add_frame(RdpeiClientContext* context)
int i;
RDPINPUT_CONTACT_DATA* contact;
RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle;
rdpei->frame.contactCount = 0;
for (i = 0; i < rdpei->maxTouchContacts; i++)
{
contact = (RDPINPUT_CONTACT_DATA*) &(rdpei->contactPoints[i].data);
contact = (RDPINPUT_CONTACT_DATA*) & (rdpei->contactPoints[i].data);
if (rdpei->contactPoints[i].dirty)
{
CopyMemory(&(rdpei->contacts[rdpei->frame.contactCount]), contact, sizeof(RDPINPUT_CONTACT_DATA));
CopyMemory(&(rdpei->contacts[rdpei->frame.contactCount]), contact,
sizeof(RDPINPUT_CONTACT_DATA));
rdpei->contactPoints[i].dirty = FALSE;
rdpei->frame.contactCount++;
}
@ -160,7 +160,8 @@ UINT rdpei_add_frame(RdpeiClientContext* context)
contact->contactFlags |= CONTACT_FLAG_INCONTACT;
}
CopyMemory(&(rdpei->contacts[rdpei->frame.contactCount]), contact, sizeof(RDPINPUT_CONTACT_DATA));
CopyMemory(&(rdpei->contacts[rdpei->frame.contactCount]), contact,
sizeof(RDPINPUT_CONTACT_DATA));
rdpei->frame.contactCount++;
}
}
@ -182,7 +183,6 @@ static void* rdpei_schedule_thread(void* arg)
goto out;
}
if (!context)
{
error = ERROR_INVALID_PARAMETER;
@ -193,12 +193,12 @@ static void* rdpei_schedule_thread(void* arg)
{
status = WaitForMultipleObjects(2, hdl, FALSE, 20);
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error);
break;
}
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u!", error);
break;
}
if (status == WAIT_OBJECT_0 + 1)
break;
@ -207,7 +207,7 @@ static void* rdpei_schedule_thread(void* arg)
if ((error = rdpei_add_frame(context)))
{
WLog_ERR(TAG, "rdpei_add_frame failed with error %lu!", error);
WLog_ERR(TAG, "rdpei_add_frame failed with error %u!", error);
break;
}
@ -215,7 +215,7 @@ static void* rdpei_schedule_thread(void* arg)
{
if ((error = rdpei_send_frame(context)))
{
WLog_ERR(TAG, "rdpei_send_frame failed with error %lu!", error);
WLog_ERR(TAG, "rdpei_send_frame failed with error %u!", error);
break;
}
}
@ -227,11 +227,12 @@ static void* rdpei_schedule_thread(void* arg)
}
out:
if (error && rdpei->rdpcontext)
setChannelError(rdpei->rdpcontext, error, "rdpei_schedule_thread reported an error");
setChannelError(rdpei->rdpcontext, error,
"rdpei_schedule_thread reported an error");
ExitThread(0);
return NULL;
}
@ -240,22 +241,20 @@ out:
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rdpei_send_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s, UINT16 eventId, UINT32 pduLength)
UINT rdpei_send_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s,
UINT16 eventId, UINT32 pduLength)
{
UINT status;
Stream_SetPosition(s, 0);
Stream_Write_UINT16(s, eventId); /* eventId (2 bytes) */
Stream_Write_UINT32(s, pduLength); /* pduLength (4 bytes) */
Stream_SetPosition(s, Stream_Length(s));
status = callback->channel->Write(callback->channel, (UINT32) Stream_Length(s), Stream_Buffer(s), NULL);
status = callback->channel->Write(callback->channel, (UINT32) Stream_Length(s),
Stream_Buffer(s), NULL);
#ifdef WITH_DEBUG_RDPEI
WLog_DBG(TAG, "rdpei_send_pdu: eventId: %d (%s) length: %d status: %d",
eventId, RDPEI_EVENTID_STRINGS[eventId], pduLength, status);
eventId, RDPEI_EVENTID_STRINGS[eventId], pduLength, status);
#endif
return status;
}
@ -271,29 +270,26 @@ UINT rdpei_send_cs_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback)
UINT32 flags;
UINT32 pduLength;
RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) callback->plugin;
flags = 0;
flags |= READY_FLAGS_SHOW_TOUCH_VISUALS;
//flags |= READY_FLAGS_DISABLE_TIMESTAMP_INJECTION;
pduLength = RDPINPUT_HEADER_LENGTH + 10;
s = Stream_New(NULL, pduLength);
if (!s)
{
WLog_ERR(TAG, "Stream_New failed!");
return CHANNEL_RC_NO_MEMORY;
}
Stream_Seek(s, RDPINPUT_HEADER_LENGTH);
Stream_Seek(s, RDPINPUT_HEADER_LENGTH);
Stream_Write_UINT32(s, flags); /* flags (4 bytes) */
Stream_Write_UINT32(s, RDPINPUT_PROTOCOL_V10); /* protocolVersion (4 bytes) */
Stream_Write_UINT16(s, rdpei->maxTouchContacts); /* maxTouchContacts (2 bytes) */
Stream_Write_UINT16(s,
rdpei->maxTouchContacts); /* maxTouchContacts (2 bytes) */
Stream_SealLength(s);
status = rdpei_send_pdu(callback, s, EVENTID_CS_READY, pduLength);
Stream_Free(s, TRUE);
return status;
}
@ -328,19 +324,18 @@ UINT rdpei_write_touch_frame(wStream* s, RDPINPUT_TOUCH_FRAME* frame)
UINT32 index;
int rectSize = 2;
RDPINPUT_CONTACT_DATA* contact;
#ifdef WITH_DEBUG_RDPEI
WLog_DBG(TAG, "contactCount: %d", frame->contactCount);
WLog_DBG(TAG, "frameOffset: 0x%08X", (UINT32) frame->frameOffset);
#endif
rdpei_write_2byte_unsigned(s, frame->contactCount); /* contactCount (TWO_BYTE_UNSIGNED_INTEGER) */
rdpei_write_2byte_unsigned(s,
frame->contactCount); /* contactCount (TWO_BYTE_UNSIGNED_INTEGER) */
/**
* the time offset from the previous frame (in microseconds).
* If this is the first frame being transmitted then this field MUST be set to zero.
*/
rdpei_write_8byte_unsigned(s, frame->frameOffset * 1000); /* frameOffset (EIGHT_BYTE_UNSIGNED_INTEGER) */
rdpei_write_8byte_unsigned(s,
frame->frameOffset * 1000); /* frameOffset (EIGHT_BYTE_UNSIGNED_INTEGER) */
if (!Stream_EnsureRemainingCapacity(s, (size_t) frame->contactCount * 64))
{
@ -351,13 +346,11 @@ UINT rdpei_write_touch_frame(wStream* s, RDPINPUT_TOUCH_FRAME* frame)
for (index = 0; index < frame->contactCount; index++)
{
contact = &frame->contacts[index];
contact->fieldsPresent |= CONTACT_DATA_CONTACTRECT_PRESENT;
contact->contactRectLeft = contact->x - rectSize;
contact->contactRectTop = contact->y - rectSize;
contact->contactRectRight = contact->x + rectSize;
contact->contactRectBottom = contact->y + rectSize;
#ifdef WITH_DEBUG_RDPEI
WLog_DBG(TAG, "contact[%d].contactId: %d", index, contact->contactId);
WLog_DBG(TAG, "contact[%d].fieldsPresent: %d", index, contact->fieldsPresent);
@ -366,15 +359,11 @@ UINT rdpei_write_touch_frame(wStream* s, RDPINPUT_TOUCH_FRAME* frame)
WLog_DBG(TAG, "contact[%d].contactFlags: 0x%04X", index, contact->contactFlags);
rdpei_print_contact_flags(contact->contactFlags);
#endif
Stream_Write_UINT8(s, contact->contactId); /* contactId (1 byte) */
/* fieldsPresent (TWO_BYTE_UNSIGNED_INTEGER) */
rdpei_write_2byte_unsigned(s, contact->fieldsPresent);
rdpei_write_4byte_signed(s, contact->x); /* x (FOUR_BYTE_SIGNED_INTEGER) */
rdpei_write_4byte_signed(s, contact->y); /* y (FOUR_BYTE_SIGNED_INTEGER) */
/* contactFlags (FOUR_BYTE_UNSIGNED_INTEGER) */
rdpei_write_4byte_unsigned(s, contact->contactFlags);
@ -411,43 +400,41 @@ UINT rdpei_write_touch_frame(wStream* s, RDPINPUT_TOUCH_FRAME* frame)
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rdpei_send_touch_event_pdu(RDPEI_CHANNEL_CALLBACK* callback, RDPINPUT_TOUCH_FRAME* frame)
UINT rdpei_send_touch_event_pdu(RDPEI_CHANNEL_CALLBACK* callback,
RDPINPUT_TOUCH_FRAME* frame)
{
UINT status;
wStream* s;
UINT32 pduLength;
pduLength = 64 + (frame->contactCount * 64);
s = Stream_New(NULL, pduLength);
if (!s)
{
WLog_ERR(TAG, "Stream_New failed!");
return CHANNEL_RC_NO_MEMORY;
}
Stream_Seek(s, RDPINPUT_HEADER_LENGTH);
Stream_Seek(s, RDPINPUT_HEADER_LENGTH);
/**
* the time that has elapsed (in milliseconds) from when the oldest touch frame
* was generated to when it was encoded for transmission by the client.
*/
rdpei_write_4byte_unsigned(s, (UINT32) frame->frameOffset); /* encodeTime (FOUR_BYTE_UNSIGNED_INTEGER) */
rdpei_write_4byte_unsigned(s,
(UINT32) frame->frameOffset); /* encodeTime (FOUR_BYTE_UNSIGNED_INTEGER) */
rdpei_write_2byte_unsigned(s, 1); /* (frameCount) TWO_BYTE_UNSIGNED_INTEGER */
if ((status = rdpei_write_touch_frame(s, frame)))
{
WLog_ERR(TAG, "rdpei_write_touch_frame failed with error %lu!", status);
WLog_ERR(TAG, "rdpei_write_touch_frame failed with error %u!", status);
Stream_Free(s, TRUE);
return status;
}
Stream_SealLength(s);
pduLength = Stream_Length(s);
status = rdpei_send_pdu(callback, s, EVENTID_TOUCH, pduLength);
Stream_Free(s, TRUE);
return status;
}
@ -459,17 +446,16 @@ UINT rdpei_send_touch_event_pdu(RDPEI_CHANNEL_CALLBACK* callback, RDPINPUT_TOUCH
UINT rdpei_recv_sc_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s)
{
UINT32 protocolVersion;
Stream_Read_UINT32(s, protocolVersion); /* protocolVersion (4 bytes) */
#if 0
if (protocolVersion != RDPINPUT_PROTOCOL_V10)
{
WLog_ERR(TAG, "Unknown [MS-RDPEI] protocolVersion: 0x%08X", protocolVersion);
return -1;
}
#endif
#endif
return CHANNEL_RC_OK;
}
@ -482,10 +468,10 @@ UINT rdpei_recv_suspend_touch_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s)
{
RdpeiClientContext* rdpei = (RdpeiClientContext*) callback->plugin->pInterface;
UINT error = CHANNEL_RC_OK;
IFCALLRET(rdpei->SuspendTouch, error, rdpei);
if (error)
WLog_ERR(TAG, "rdpei->SuspendTouch failed with error %lu!", error);
WLog_ERR(TAG, "rdpei->SuspendTouch failed with error %u!", error);
return error;
}
@ -499,10 +485,10 @@ UINT rdpei_recv_resume_touch_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s)
{
RdpeiClientContext* rdpei = (RdpeiClientContext*) callback->plugin->pInterface;
UINT error = CHANNEL_RC_OK;
IFCALLRET(rdpei->ResumeTouch, error, rdpei);
if (error)
WLog_ERR(TAG, "rdpei->ResumeTouch failed with error %lu!", error);
WLog_ERR(TAG, "rdpei->ResumeTouch failed with error %u!", error);
return error;
}
@ -517,13 +503,11 @@ UINT rdpei_recv_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s)
UINT16 eventId;
UINT32 pduLength;
UINT error;
Stream_Read_UINT16(s, eventId); /* eventId (2 bytes) */
Stream_Read_UINT32(s, pduLength); /* pduLength (4 bytes) */
#ifdef WITH_DEBUG_RDPEI
WLog_DBG(TAG, "rdpei_recv_pdu: eventId: %d (%s) length: %d",
eventId, RDPEI_EVENTID_STRINGS[eventId], pduLength);
eventId, RDPEI_EVENTID_STRINGS[eventId], pduLength);
#endif
switch (eventId)
@ -531,30 +515,34 @@ UINT rdpei_recv_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s)
case EVENTID_SC_READY:
if ((error = rdpei_recv_sc_ready_pdu(callback, s)))
{
WLog_ERR(TAG, "rdpei_recv_sc_ready_pdu failed with error %lu!", error);
WLog_ERR(TAG, "rdpei_recv_sc_ready_pdu failed with error %u!", error);
return error;
}
if ((error = rdpei_send_cs_ready_pdu(callback)))
{
WLog_ERR(TAG, "rdpei_send_cs_ready_pdu failed with error %lu!", error);
WLog_ERR(TAG, "rdpei_send_cs_ready_pdu failed with error %u!", error);
return error;
}
break;
case EVENTID_SUSPEND_TOUCH:
if ((error = rdpei_recv_suspend_touch_pdu(callback, s)))
{
WLog_ERR(TAG, "rdpei_recv_suspend_touch_pdu failed with error %lu!", error);
WLog_ERR(TAG, "rdpei_recv_suspend_touch_pdu failed with error %u!", error);
return error;
}
break;
case EVENTID_RESUME_TOUCH:
if ((error = rdpei_recv_resume_touch_pdu(callback, s)))
{
WLog_ERR(TAG, "rdpei_recv_resume_touch_pdu failed with error %lu!", error);
WLog_ERR(TAG, "rdpei_recv_resume_touch_pdu failed with error %u!", error);
return error;
}
break;
default:
@ -569,10 +557,10 @@ UINT rdpei_recv_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s)
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT rdpei_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, wStream *data)
static UINT rdpei_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
wStream* data)
{
RDPEI_CHANNEL_CALLBACK* callback = (RDPEI_CHANNEL_CALLBACK*) pChannelCallback;
return rdpei_recv_pdu(callback, data);
}
@ -584,9 +572,7 @@ static UINT rdpei_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
static UINT rdpei_on_close(IWTSVirtualChannelCallback* pChannelCallback)
{
RDPEI_CHANNEL_CALLBACK* callback = (RDPEI_CHANNEL_CALLBACK*) pChannelCallback;
free(callback);
return CHANNEL_RC_OK;
}
@ -595,17 +581,19 @@ static UINT rdpei_on_close(IWTSVirtualChannelCallback* pChannelCallback)
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT rdpei_on_new_channel_connection(IWTSListenerCallback* pListenerCallback,
IWTSVirtualChannel* pChannel, BYTE* Data, BOOL* pbAccept,
IWTSVirtualChannelCallback** ppCallback)
static UINT rdpei_on_new_channel_connection(IWTSListenerCallback*
pListenerCallback,
IWTSVirtualChannel* pChannel, BYTE* Data, BOOL* pbAccept,
IWTSVirtualChannelCallback** ppCallback)
{
RDPEI_CHANNEL_CALLBACK* callback;
RDPEI_LISTENER_CALLBACK* listener_callback = (RDPEI_LISTENER_CALLBACK*) pListenerCallback;
RDPEI_LISTENER_CALLBACK* listener_callback = (RDPEI_LISTENER_CALLBACK*)
pListenerCallback;
callback = (RDPEI_CHANNEL_CALLBACK*) calloc(1, sizeof(RDPEI_CHANNEL_CALLBACK));
if (!callback)
{
WLog_ERR(TAG,"calloc failed!");
WLog_ERR(TAG, "calloc failed!");
return CHANNEL_RC_NO_MEMORY;
}
@ -615,9 +603,7 @@ static UINT rdpei_on_new_channel_connection(IWTSListenerCallback* pListenerCallb
callback->channel_mgr = listener_callback->channel_mgr;
callback->channel = pChannel;
listener_callback->channel_callback = callback;
*ppCallback = (IWTSVirtualChannelCallback*) callback;
return CHANNEL_RC_OK;
}
@ -626,52 +612,52 @@ static UINT rdpei_on_new_channel_connection(IWTSListenerCallback* pListenerCallb
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT rdpei_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager* pChannelMgr)
static UINT rdpei_plugin_initialize(IWTSPlugin* pPlugin,
IWTSVirtualChannelManager* pChannelMgr)
{
UINT error;
RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) pPlugin;
rdpei->listener_callback = (RDPEI_LISTENER_CALLBACK*) calloc(1 ,
sizeof(RDPEI_LISTENER_CALLBACK));
rdpei->listener_callback = (RDPEI_LISTENER_CALLBACK*) calloc(1 ,sizeof(RDPEI_LISTENER_CALLBACK));
if (!rdpei->listener_callback)
{
WLog_ERR(TAG, "calloc failed!");
return CHANNEL_RC_NO_MEMORY;
}
rdpei->listener_callback->iface.OnNewChannelConnection = rdpei_on_new_channel_connection;
rdpei->listener_callback->iface.OnNewChannelConnection =
rdpei_on_new_channel_connection;
rdpei->listener_callback->plugin = pPlugin;
rdpei->listener_callback->channel_mgr = pChannelMgr;
if ((error = pChannelMgr->CreateListener(pChannelMgr, RDPEI_DVC_CHANNEL_NAME, 0,
(IWTSListenerCallback*) rdpei->listener_callback, &(rdpei->listener))))
(IWTSListenerCallback*) rdpei->listener_callback, &(rdpei->listener))))
{
WLog_ERR(TAG, "ChannelMgr->CreateListener failed with error %lu!", error);
WLog_ERR(TAG, "ChannelMgr->CreateListener failed with error %u!", error);
goto error_out;
}
rdpei->listener->pInterface = rdpei->iface.pInterface;
InitializeCriticalSection(&rdpei->lock);
if (!(rdpei->event = CreateEvent(NULL, TRUE, FALSE, NULL)))
{
WLog_ERR(TAG, "CreateEvent failed!");
goto error_out;
}
if (!(rdpei->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
{
WLog_ERR(TAG, "CreateEvent failed!");
goto error_out;
}
if (!(rdpei->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)
rdpei_schedule_thread, (void*) rdpei, 0, NULL)))
rdpei_schedule_thread, (void*) rdpei, 0, NULL)))
{
WLog_ERR(TAG, "CreateThread failed!");
goto error_out;
}
return error;
@ -690,7 +676,7 @@ error_out:
static UINT rdpei_plugin_terminated(IWTSPlugin* pPlugin)
{
RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) pPlugin;
UINT error;
UINT error;
if (!pPlugin)
return ERROR_INVALID_PARAMETER;
@ -699,22 +685,19 @@ static UINT rdpei_plugin_terminated(IWTSPlugin* pPlugin)
EnterCriticalSection(&rdpei->lock);
if (WaitForSingleObject(rdpei->thread, INFINITE) == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
return error;
}
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error);
return error;
}
CloseHandle(rdpei->stopEvent);
CloseHandle(rdpei->event);
CloseHandle(rdpei->thread);
DeleteCriticalSection(&rdpei->lock);
free(rdpei->listener_callback);
free(rdpei->context);
free(rdpei);
return CHANNEL_RC_OK;
}
@ -739,7 +722,6 @@ UINT rdpei_send_frame(RdpeiClientContext* context)
RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle;
RDPEI_CHANNEL_CALLBACK* callback = rdpei->listener_callback->channel_callback;
UINT error;
currentTime = GetTickCount64();
if (!rdpei->previousFrameTime && !rdpei->currentFrameTime)
@ -755,12 +737,12 @@ UINT rdpei_send_frame(RdpeiClientContext* context)
if ((error = rdpei_send_touch_event_pdu(callback, &rdpei->frame)))
{
WLog_ERR(TAG, "rdpei_send_touch_event_pdu failed with error %lu!", error);
WLog_ERR(TAG, "rdpei_send_touch_event_pdu failed with error %u!", error);
return error;
}
rdpei->previousFrameTime = rdpei->currentFrameTime;
rdpei->frame.contactCount = 0;
return error;
}
@ -769,21 +751,18 @@ UINT rdpei_send_frame(RdpeiClientContext* context)
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rdpei_add_contact(RdpeiClientContext* context, RDPINPUT_CONTACT_DATA* contact)
UINT rdpei_add_contact(RdpeiClientContext* context,
RDPINPUT_CONTACT_DATA* contact)
{
RDPINPUT_CONTACT_POINT* contactPoint;
RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle;
EnterCriticalSection(&rdpei->lock);
contactPoint = (RDPINPUT_CONTACT_POINT*) &rdpei->contactPoints[contact->contactId];
contactPoint = (RDPINPUT_CONTACT_POINT*)
&rdpei->contactPoints[contact->contactId];
CopyMemory(&(contactPoint->data), contact, sizeof(RDPINPUT_CONTACT_DATA));
contactPoint->dirty = TRUE;
SetEvent(rdpei->event);
LeaveCriticalSection(&rdpei->lock);
return CHANNEL_RC_OK;
}
@ -792,7 +771,8 @@ UINT rdpei_add_contact(RdpeiClientContext* context, RDPINPUT_CONTACT_DATA* conta
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rdpei_touch_begin(RdpeiClientContext* context, int externalId, int x, int y, int* contactId)
UINT rdpei_touch_begin(RdpeiClientContext* context, int externalId, int x,
int y, int* contactId)
{
unsigned int i;
int contactIdlocal = -1;
@ -821,20 +801,17 @@ UINT rdpei_touch_begin(RdpeiClientContext* context, int externalId, int x, int y
if (contactIdlocal >= 0)
{
ZeroMemory(&contact, sizeof(RDPINPUT_CONTACT_DATA));
contactPoint->lastX = x;
contactPoint->lastY = y;
contact.x = x;
contact.y = y;
contact.contactId = (UINT32) contactIdlocal;
contact.contactFlags |= CONTACT_FLAG_DOWN;
contact.contactFlags |= CONTACT_FLAG_INRANGE;
contact.contactFlags |= CONTACT_FLAG_INCONTACT;
error = context->AddContact(context, &contact);
}
*contactId = contactIdlocal;
return error;
}
@ -844,7 +821,8 @@ UINT rdpei_touch_begin(RdpeiClientContext* context, int externalId, int x, int y
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rdpei_touch_update(RdpeiClientContext* context, int externalId, int x, int y, int* contactId)
UINT rdpei_touch_update(RdpeiClientContext* context, int externalId, int x,
int y, int* contactId)
{
unsigned int i;
int contactIdlocal = -1;
@ -870,23 +848,18 @@ UINT rdpei_touch_update(RdpeiClientContext* context, int externalId, int x, int
if (contactIdlocal >= 0)
{
ZeroMemory(&contact, sizeof(RDPINPUT_CONTACT_DATA));
contactPoint->lastX = x;
contactPoint->lastY = y;
contact.x = x;
contact.y = y;
contact.contactId = (UINT32) contactIdlocal;
contact.contactFlags |= CONTACT_FLAG_UPDATE;
contact.contactFlags |= CONTACT_FLAG_INRANGE;
contact.contactFlags |= CONTACT_FLAG_INCONTACT;
error = context->AddContact(context, &contact);
}
*contactId = contactIdlocal;
return error;
}
@ -895,7 +868,8 @@ UINT rdpei_touch_update(RdpeiClientContext* context, int externalId, int x, int
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rdpei_touch_end(RdpeiClientContext* context, int externalId, int x, int y, int* contactId)
UINT rdpei_touch_end(RdpeiClientContext* context, int externalId, int x, int y,
int* contactId)
{
unsigned int i;
int contactIdlocal = -1;
@ -927,7 +901,7 @@ UINT rdpei_touch_end(RdpeiClientContext* context, int externalId, int x, int y,
{
if ((error = context->TouchUpdate(context, externalId, x, y, &tempvalue)))
{
WLog_ERR(TAG, "context->TouchUpdate failed with error %lu!", error);
WLog_ERR(TAG, "context->TouchUpdate failed with error %u!", error);
return error;
}
}
@ -935,12 +909,11 @@ UINT rdpei_touch_end(RdpeiClientContext* context, int externalId, int x, int y,
contact.x = x;
contact.y = y;
contact.contactId = (UINT32) contactIdlocal;
contact.contactFlags |= CONTACT_FLAG_UP;
if ((error = context->AddContact(context, &contact)))
{
WLog_ERR(TAG, "context->AddContact failed with error %lu!", error);
WLog_ERR(TAG, "context->AddContact failed with error %u!", error);
return error;
}
@ -950,12 +923,12 @@ UINT rdpei_touch_end(RdpeiClientContext* context, int externalId, int x, int y,
contactPoint->contactId = 0;
contactPoint->state = RDPINPUT_CONTACT_STATE_OUT_OF_RANGE;
}
*contactId = contactIdlocal;
*contactId = contactIdlocal;
return CHANNEL_RC_OK;
}
#ifdef STATIC_CHANNELS
#ifdef BUILTIN_CHANNELS
#define DVCPluginEntry rdpei_DVCPluginEntry
#else
#define DVCPluginEntry FREERDP_API DVCPluginEntry
@ -971,15 +944,14 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
UINT error;
RDPEI_PLUGIN* rdpei = NULL;
RdpeiClientContext* context = NULL;
rdpei = (RDPEI_PLUGIN*) pEntryPoints->GetPlugin(pEntryPoints, "rdpei");
if (!rdpei)
{
size_t size;
rdpei = (RDPEI_PLUGIN*) calloc(1, sizeof(RDPEI_PLUGIN));
if(!rdpei)
if (!rdpei)
{
WLog_ERR(TAG, "calloc failed!");
return CHANNEL_RC_NO_MEMORY;
@ -989,18 +961,15 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
rdpei->iface.Connected = NULL;
rdpei->iface.Disconnected = NULL;
rdpei->iface.Terminated = rdpei_plugin_terminated;
rdpei->version = 1;
rdpei->currentFrameTime = 0;
rdpei->previousFrameTime = 0;
rdpei->frame.contacts = (RDPINPUT_CONTACT_DATA*) rdpei->contacts;
rdpei->maxTouchContacts = 10;
size = rdpei->maxTouchContacts * sizeof(RDPINPUT_CONTACT_POINT);
rdpei->contactPoints = (RDPINPUT_CONTACT_POINT*) calloc(1, size);
rdpei->rdpcontext = ((freerdp*)((rdpSettings*) pEntryPoints->GetRdpSettings(pEntryPoints))->instance)->context;
rdpei->rdpcontext = ((freerdp*)((rdpSettings*) pEntryPoints->GetRdpSettings(
pEntryPoints))->instance)->context;
if (!rdpei->contactPoints)
{
@ -1010,6 +979,7 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
}
context = (RdpeiClientContext*) calloc(1, sizeof(RdpeiClientContext));
if (!context)
{
WLog_ERR(TAG, "calloc failed!");
@ -1020,16 +990,15 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
context->handle = (void*) rdpei;
context->GetVersion = rdpei_get_version;
context->AddContact = rdpei_add_contact;
context->TouchBegin = rdpei_touch_begin;
context->TouchUpdate = rdpei_touch_update;
context->TouchEnd = rdpei_touch_end;
rdpei->iface.pInterface = (void*) context;
if ((error = pEntryPoints->RegisterPlugin(pEntryPoints, "rdpei", (IWTSPlugin*) rdpei)))
if ((error = pEntryPoints->RegisterPlugin(pEntryPoints, "rdpei",
(IWTSPlugin*) rdpei)))
{
WLog_ERR(TAG, "EntryPoints->RegisterPlugin failed with error %lu!", error);
WLog_ERR(TAG, "EntryPoints->RegisterPlugin failed with error %u!", error);
error = CHANNEL_RC_NO_MEMORY;
goto error_out;
}

View File

@ -82,9 +82,9 @@ struct _RDPINPUT_CONTACT_POINT
typedef struct _RDPINPUT_CONTACT_POINT RDPINPUT_CONTACT_POINT;
#ifdef WITH_DEBUG_DVC
#define DEBUG_DVC(fmt, ...) WLog_DBG(TAG, fmt, ## __VA_ARGS__)
#define DEBUG_DVC(...) WLog_DBG(TAG, __VA_ARGS__)
#else
#define DEBUG_DVC(fmt, ...) do { } while (0)
#define DEBUG_DVC(...) do { } while (0)
#endif
#endif /* FREERDP_CHANNEL_RDPEI_CLIENT_MAIN_H */

View File

@ -185,7 +185,7 @@ static UINT read_cs_ready_message(RdpeiServerContext *context, wStream *s)
IFCALLRET(context->onClientReady, error, context);
if (error)
WLog_ERR(TAG, "context->onClientReady failed with error %lu", error);
WLog_ERR(TAG, "context->onClientReady failed with error %u", error);
return error;
}
@ -271,7 +271,7 @@ static UINT read_touch_frame(RdpeiServerContext *context, wStream *s, RDPINPUT_T
{
if ((error = read_touch_contact_data(context, s, contact)))
{
WLog_ERR(TAG, "read_touch_contact_data failed with error %lu!", error);
WLog_ERR(TAG, "read_touch_contact_data failed with error %u!", error);
frame->contactCount = i;
touch_frame_reset(frame);
return error;
@ -311,7 +311,7 @@ static UINT read_touch_event(RdpeiServerContext *context, wStream *s)
{
if ((error = read_touch_frame(context, s, frame)))
{
WLog_ERR(TAG, "read_touch_contact_data failed with error %lu!", error);
WLog_ERR(TAG, "read_touch_contact_data failed with error %u!", error);
event->frameCount = i;
goto out_cleanup;
}
@ -320,7 +320,7 @@ static UINT read_touch_event(RdpeiServerContext *context, wStream *s)
IFCALLRET(context->onTouchEvent, error, context, event);
if (error)
WLog_ERR(TAG, "context->onTouchEvent failed with error %lu", error);
WLog_ERR(TAG, "context->onTouchEvent failed with error %u", error);
out_cleanup:
touch_event_reset(event);
@ -347,7 +347,7 @@ static UINT read_dismiss_hovering_contact(RdpeiServerContext *context, wStream *
IFCALLRET(context->onTouchReleased, error, context, contactId);
if (error)
WLog_ERR(TAG, "context->onTouchReleased failed with error %lu", error);
WLog_ERR(TAG, "context->onTouchReleased failed with error %u", error);
return error;
}
@ -420,7 +420,7 @@ UINT rdpei_server_handle_messages(RdpeiServerContext *context) {
if ((error = read_cs_ready_message(context, s)))
{
WLog_ERR(TAG, "read_cs_ready_message failed with error %lu", error);
WLog_ERR(TAG, "read_cs_ready_message failed with error %u", error);
return error;
}
break;
@ -428,14 +428,14 @@ UINT rdpei_server_handle_messages(RdpeiServerContext *context) {
case EVENTID_TOUCH:
if ((error = read_touch_event(context, s)))
{
WLog_ERR(TAG, "read_touch_event failed with error %lu", error);
WLog_ERR(TAG, "read_touch_event failed with error %u", error);
return error;
}
break;
case EVENTID_DISMISS_HOVERING_CONTACT:
if ((error = read_dismiss_hovering_contact(context, s)))
{
WLog_ERR(TAG, "read_dismiss_hovering_contact failed with error %lu", error);
WLog_ERR(TAG, "read_dismiss_hovering_contact failed with error %u", error);
return error;
}
break;

View File

@ -21,3 +21,6 @@ if(WITH_CLIENT_CHANNELS)
add_channel_client(${MODULE_PREFIX} ${CHANNEL_NAME})
endif()
if(WITH_SERVER_CHANNELS)
add_channel_server(${MODULE_PREFIX} ${CHANNEL_NAME})
endif()

View File

@ -22,8 +22,8 @@ set(${MODULE_PREFIX}_SRCS
rdpgfx_main.h
rdpgfx_codec.c
rdpgfx_codec.h
rdpgfx_common.c
rdpgfx_common.h)
../rdpgfx_common.c
../rdpgfx_common.h)
include_directories(..)
@ -33,7 +33,7 @@ add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE
target_link_libraries(${MODULE_NAME} winpr freerdp)
if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS)
if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS)
install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols)
endif()

View File

@ -57,7 +57,7 @@ static UINT rdpgfx_read_h264_metablock(RDPGFX_PLUGIN* gfx, wStream* s,
Stream_Read_UINT32(s, meta->numRegionRects); /* numRegionRects (4 bytes) */
if (Stream_GetRemainingLength(s) < (meta->numRegionRects * sizeof(RECTANGLE_16)))
if (Stream_GetRemainingLength(s) < (meta->numRegionRects * 8))
{
WLog_ERR(TAG, "not enough data!");
goto error_out;
@ -88,7 +88,7 @@ static UINT rdpgfx_read_h264_metablock(RDPGFX_PLUGIN* gfx, wStream* s,
regionRect = &(meta->regionRects[index]);
if ((error = rdpgfx_read_rect16(s, regionRect)))
{
WLog_ERR(TAG, "rdpgfx_read_rect16 failed with error %lu!", error);
WLog_ERR(TAG, "rdpgfx_read_rect16 failed with error %u!", error);
goto error_out;
}
WLog_DBG(TAG, "regionRects[%d]: left: %d top: %d right: %d bottom: %d",
@ -146,7 +146,7 @@ static UINT rdpgfx_decode_AVC420(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd
if ((error = rdpgfx_read_h264_metablock(gfx, s, &(h264.meta))))
{
WLog_ERR(TAG, "rdpgfx_read_h264_metablock failed with error %lu!", error);
WLog_ERR(TAG, "rdpgfx_read_h264_metablock failed with error %u!", error);
return error;
}
@ -161,7 +161,7 @@ static UINT rdpgfx_decode_AVC420(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd
{
IFCALLRET(context->SurfaceCommand, error, context, cmd);
if (error)
WLog_ERR(TAG, "context->SurfaceCommand failed with error %lu", error);
WLog_ERR(TAG, "context->SurfaceCommand failed with error %u", error);
}
free(h264.meta.regionRects);
@ -205,7 +205,7 @@ static UINT rdpgfx_decode_AVC444(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd
pos1 = Stream_GetPosition(s);
if ((error = rdpgfx_read_h264_metablock(gfx, s, &(h264.bitstream[0].meta))))
{
WLog_ERR(TAG, "rdpgfx_read_h264_metablock failed with error %lu!", error);
WLog_ERR(TAG, "rdpgfx_read_h264_metablock failed with error %u!", error);
return error;
}
pos2 = Stream_GetPosition(s);
@ -223,7 +223,7 @@ static UINT rdpgfx_decode_AVC444(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd
if ((error = rdpgfx_read_h264_metablock(gfx, s, &(h264.bitstream[1].meta))))
{
WLog_ERR(TAG, "rdpgfx_read_h264_metablock failed with error %lu!", error);
WLog_ERR(TAG, "rdpgfx_read_h264_metablock failed with error %u!", error);
return error;
}
@ -244,7 +244,7 @@ static UINT rdpgfx_decode_AVC444(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd
{
IFCALLRET(context->SurfaceCommand, error, context, cmd);
if (error)
WLog_ERR(TAG, "context->SurfaceCommand failed with error %lu", error);
WLog_ERR(TAG, "context->SurfaceCommand failed with error %u", error);
}
free(h264.bitstream[0].meta.regionRects);
@ -270,7 +270,7 @@ UINT rdpgfx_decode(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd)
case RDPGFX_CODECID_AVC420:
if ((error = rdpgfx_decode_AVC420(gfx, cmd)))
{
WLog_ERR(TAG, "rdpgfx_decode_AVC420 failed with error %lu", error);
WLog_ERR(TAG, "rdpgfx_decode_AVC420 failed with error %u", error);
return error;
}
break;
@ -278,7 +278,7 @@ UINT rdpgfx_decode(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd)
case RDPGFX_CODECID_AVC444:
if ((error = rdpgfx_decode_AVC444(gfx, cmd)))
{
WLog_ERR(TAG, "rdpgfx_decode_AVC444 failed with error %lu", error);
WLog_ERR(TAG, "rdpgfx_decode_AVC444 failed with error %u", error);
return error;
}
break;
@ -288,7 +288,7 @@ UINT rdpgfx_decode(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd)
{
IFCALLRET(context->SurfaceCommand, error, context, cmd);
if (error)
WLog_ERR(TAG, "context->SurfaceCommand failed with error %lu", error);
WLog_ERR(TAG, "context->SurfaceCommand failed with error %u", error);
}
break;
}

View File

@ -26,9 +26,10 @@
#include <winpr/stream.h>
#include <freerdp/channels/rdpgfx.h>
#include <freerdp/api.h>
#include "rdpgfx_main.h"
UINT rdpgfx_decode(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd);
FREERDP_LOCAL UINT rdpgfx_decode(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd);
#endif /* FREERDP_CHANNEL_RDPGFX_CLIENT_CODEC_H */

File diff suppressed because it is too large Load Diff

View File

@ -31,7 +31,7 @@
#include "rdpgfx_common.h"
const char* RDPGFX_CMDID_STRINGS[] =
static const char* RDPGFX_CMDID_STRINGS[] =
{
"RDPGFX_CMDID_UNUSED_0000",
"RDPGFX_CMDID_WIRETOSURFACE_1",
@ -54,7 +54,8 @@ const char* RDPGFX_CMDID_STRINGS[] =
"RDPGFX_CMDID_CAPSADVERTISE",
"RDPGFX_CMDID_CAPSCONFIRM",
"RDPGFX_CMDID_UNUSED_0014",
"RDPGFX_CMDID_MAPSURFACETOWINDOW"
"RDPGFX_CMDID_MAPSURFACETOWINDOW",
"RDPGFX_CMDID_QOEFRAMEACKNOWLEDGE"
};
const char* rdpgfx_get_cmd_id_string(UINT16 cmdId)
@ -71,20 +72,28 @@ const char* rdpgfx_get_codec_id_string(UINT16 codecId)
{
case RDPGFX_CODECID_UNCOMPRESSED:
return "RDPGFX_CODECID_UNCOMPRESSED";
case RDPGFX_CODECID_CAVIDEO:
return "RDPGFX_CODECID_CAVIDEO";
case RDPGFX_CODECID_CLEARCODEC:
return "RDPGFX_CODECID_CLEARCODEC";
case RDPGFX_CODECID_PLANAR:
return "RDPGFX_CODECID_PLANAR";
case RDPGFX_CODECID_AVC420:
return "RDPGFX_CODECID_AVC420";
case RDPGFX_CODECID_AVC444:
return "RDPGFX_CODECID_AVC444";
case RDPGFX_CODECID_ALPHA:
return "RDPGFX_CODECID_ALPHA";
case RDPGFX_CODECID_CAPROGRESSIVE:
return "RDPGFX_CODECID_CAPROGRESSIVE";
case RDPGFX_CODECID_CAPROGRESSIVE_V2:
return "RDPGFX_CODECID_CAPROGRESSIVE_V2";
}
@ -108,7 +117,6 @@ UINT rdpgfx_read_header(wStream* s, RDPGFX_HEADER* header)
Stream_Read_UINT16(s, header->cmdId); /* cmdId (2 bytes) */
Stream_Read_UINT16(s, header->flags); /* flags (2 bytes) */
Stream_Read_UINT32(s, header->pduLength); /* pduLength (4 bytes) */
return CHANNEL_RC_OK;
}
@ -122,7 +130,6 @@ UINT rdpgfx_write_header(wStream* s, RDPGFX_HEADER* header)
Stream_Write_UINT16(s, header->cmdId); /* cmdId (2 bytes) */
Stream_Write_UINT16(s, header->flags); /* flags (2 bytes) */
Stream_Write_UINT32(s, header->pduLength); /* pduLength (4 bytes) */
return CHANNEL_RC_OK;
}
@ -141,7 +148,6 @@ UINT rdpgfx_read_point16(wStream* s, RDPGFX_POINT16* pt16)
Stream_Read_UINT16(s, pt16->x); /* x (2 bytes) */
Stream_Read_UINT16(s, pt16->y); /* y (2 bytes) */
return CHANNEL_RC_OK;
}
@ -154,7 +160,6 @@ UINT rdpgfx_write_point16(wStream* s, RDPGFX_POINT16* point16)
{
Stream_Write_UINT16(s, point16->x); /* x (2 bytes) */
Stream_Write_UINT16(s, point16->y); /* y (2 bytes) */
return CHANNEL_RC_OK;
}
@ -175,7 +180,6 @@ UINT rdpgfx_read_rect16(wStream* s, RECTANGLE_16* rect16)
Stream_Read_UINT16(s, rect16->top); /* top (2 bytes) */
Stream_Read_UINT16(s, rect16->right); /* right (2 bytes) */
Stream_Read_UINT16(s, rect16->bottom); /* bottom (2 bytes) */
return CHANNEL_RC_OK;
}
@ -190,7 +194,6 @@ UINT rdpgfx_write_rect16(wStream* s, RECTANGLE_16* rect16)
Stream_Write_UINT16(s, rect16->top); /* top (2 bytes) */
Stream_Write_UINT16(s, rect16->right); /* right (2 bytes) */
Stream_Write_UINT16(s, rect16->bottom); /* bottom (2 bytes) */
return CHANNEL_RC_OK;
}
@ -211,7 +214,6 @@ UINT rdpgfx_read_color32(wStream* s, RDPGFX_COLOR32* color32)
Stream_Read_UINT8(s, color32->G); /* G (1 byte) */
Stream_Read_UINT8(s, color32->R); /* R (1 byte) */
Stream_Read_UINT8(s, color32->XA); /* XA (1 byte) */
return CHANNEL_RC_OK;
}
@ -226,6 +228,5 @@ UINT rdpgfx_write_color32(wStream* s, RDPGFX_COLOR32* color32)
Stream_Write_UINT8(s, color32->G); /* G (1 byte) */
Stream_Write_UINT8(s, color32->R); /* R (1 byte) */
Stream_Write_UINT8(s, color32->XA); /* XA (1 byte) */
return CHANNEL_RC_OK;
}

View File

@ -26,21 +26,22 @@
#include <winpr/stream.h>
#include <freerdp/channels/rdpgfx.h>
#include <freerdp/api.h>
const char* rdpgfx_get_cmd_id_string(UINT16 cmdId);
const char* rdpgfx_get_codec_id_string(UINT16 codecId);
FREERDP_LOCAL const char* rdpgfx_get_cmd_id_string(UINT16 cmdId);
FREERDP_LOCAL const char* rdpgfx_get_codec_id_string(UINT16 codecId);
UINT rdpgfx_read_header(wStream* s, RDPGFX_HEADER* header);
UINT rdpgfx_write_header(wStream* s, RDPGFX_HEADER* header);
FREERDP_LOCAL UINT rdpgfx_read_header(wStream* s, RDPGFX_HEADER* header);
FREERDP_LOCAL UINT rdpgfx_write_header(wStream* s, RDPGFX_HEADER* header);
UINT rdpgfx_read_point16(wStream* s, RDPGFX_POINT16* pt16);
UINT rdpgfx_write_point16(wStream* s, RDPGFX_POINT16* point16);
FREERDP_LOCAL UINT rdpgfx_read_point16(wStream* s, RDPGFX_POINT16* pt16);
FREERDP_LOCAL UINT rdpgfx_write_point16(wStream* s, RDPGFX_POINT16* point16);
UINT rdpgfx_read_rect16(wStream* s, RECTANGLE_16* rect16);
UINT rdpgfx_write_rect16(wStream* s, RECTANGLE_16* rect16);
FREERDP_LOCAL UINT rdpgfx_read_rect16(wStream* s, RECTANGLE_16* rect16);
FREERDP_LOCAL UINT rdpgfx_write_rect16(wStream* s, RECTANGLE_16* rect16);
UINT rdpgfx_read_color32(wStream* s, RDPGFX_COLOR32* color32);
UINT rdpgfx_write_color32(wStream* s, RDPGFX_COLOR32* color32);
FREERDP_LOCAL UINT rdpgfx_read_color32(wStream* s, RDPGFX_COLOR32* color32);
FREERDP_LOCAL UINT rdpgfx_write_color32(wStream* s, RDPGFX_COLOR32* color32);
#endif /* FREERDP_CHANNEL_RDPGFX_CLIENT_COMMON_H */

View File

@ -0,0 +1,34 @@
# FreeRDP: A Remote Desktop Protocol Implementation
# FreeRDP cmake build script
#
# Copyright 2016 Jiang Zihao <zihao.jiang@yahoo.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
define_channel_server("rdpgfx")
set(${MODULE_PREFIX}_SRCS
rdpgfx_main.c
rdpgfx_main.h
../rdpgfx_common.c
../rdpgfx_common.h)
include_directories(..)
add_channel_server_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "DVCPluginEntry")
target_link_libraries(${MODULE_NAME} freerdp)
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Server")

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,40 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Graphics Pipeline Extension
*
* Copyright 2016 Jiang Zihao <zihao.jiang@yahoo.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.
*/
#ifndef FREERDP_CHANNEL_RDPGFX_SERVER_MAIN_H
#define FREERDP_CHANNEL_RDPGFX_SERVER_MAIN_H
#include <freerdp/server/rdpgfx.h>
#include <freerdp/codec/zgfx.h>
struct _rdpgfx_server_private
{
ZGFX_CONTEXT* zgfx;
BOOL ownThread;
HANDLE thread;
HANDLE stopEvent;
HANDLE channelEvent;
void* rdpgfx_channel;
DWORD SessionId;
wStream* input_stream;
BOOL isOpened;
BOOL isReady;
};
#endif /* FREERDP_CHANNEL_RDPGFX_SERVER_MAIN_H */

View File

@ -21,7 +21,7 @@ set(${MODULE_PREFIX}_SRCS
rdpsnd_main.c
rdpsnd_main.h)
add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntry")
add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntryEx")

View File

@ -647,7 +647,7 @@ static UINT rdpsnd_alsa_parse_addin_args(rdpsndDevicePlugin* device, ADDIN_ARGV*
return CHANNEL_RC_OK;
}
#ifdef STATIC_CHANNELS
#ifdef BUILTIN_CHANNELS
#define freerdp_rdpsnd_client_subsystem_entry alsa_freerdp_rdpsnd_client_subsystem_entry
#else
#define freerdp_rdpsnd_client_subsystem_entry FREERDP_API freerdp_rdpsnd_client_subsystem_entry
@ -686,7 +686,7 @@ UINT freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS p
{
if ((error = rdpsnd_alsa_parse_addin_args((rdpsndDevicePlugin *) alsa, args)))
{
WLog_ERR(TAG, "rdpsnd_alsa_parse_addin_args failed with error %lu", error);
WLog_ERR(TAG, "rdpsnd_alsa_parse_addin_args failed with error %u", error);
goto error_parse_args;
}
}

View File

@ -279,7 +279,7 @@ static void rdpsnd_ios_free(rdpsndDevicePlugin* device)
free(p);
}
#ifdef STATIC_CHANNELS
#ifdef BUILTIN_CHANNELS
#define freerdp_rdpsnd_client_subsystem_entry ios_freerdp_rdpsnd_client_subsystem_entry
#else
#define freerdp_rdpsnd_client_subsystem_entry FREERDP_API freerdp_rdpsnd_client_subsystem_entry

View File

@ -34,6 +34,9 @@
#include <freerdp/types.h>
#include <freerdp/codec/dsp.h>
#define __COREFOUNDATION_CFPLUGINCOM__ 1
#define IUNKNOWN_C_GUTS void *_reserved; void* QueryInterface; void* AddRef; void* Release
#include <AudioToolbox/AudioToolbox.h>
#include <AudioToolbox/AudioQueue.h>
@ -324,6 +327,8 @@ static void rdpsnd_mac_waveplay(rdpsndDevicePlugin* device, RDPSND_WAVE* wave)
length = wave->length > audioBuffer->mAudioDataBytesCapacity ? audioBuffer->mAudioDataBytesCapacity : wave->length;
CopyMemory(audioBuffer->mAudioData, wave->data, length);
free(wave->data);
wave->data = NULL;
audioBuffer->mAudioDataByteSize = length;
audioBuffer->mUserData = wave;
@ -343,7 +348,7 @@ static void rdpsnd_mac_waveplay(rdpsndDevicePlugin* device, RDPSND_WAVE* wave)
device->Start(device);
}
#ifdef STATIC_CHANNELS
#ifdef BUILTIN_CHANNELS
#define freerdp_rdpsnd_client_subsystem_entry mac_freerdp_rdpsnd_client_subsystem_entry
#else
#define freerdp_rdpsnd_client_subsystem_entry FREERDP_API freerdp_rdpsnd_client_subsystem_entry

View File

@ -6,14 +6,14 @@ All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@ -34,203 +34,238 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define CONV16BIT 32768
#define CONVMYFLT (1./32768.)
static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context);
static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void* context);
// creates the OpenSL ES audio engine
static SLresult openSLCreateEngine(OPENSL_STREAM *p)
static SLresult openSLCreateEngine(OPENSL_STREAM* p)
{
SLresult result;
// create engine
result = slCreateEngine(&(p->engineObject), 0, NULL, 0, NULL, NULL);
SLresult result;
// create engine
result = slCreateEngine(&(p->engineObject), 0, NULL, 0, NULL, NULL);
DEBUG_SND("engineObject=%p", p->engineObject);
if(result != SL_RESULT_SUCCESS) goto engine_end;
// realize the engine
result = (*p->engineObject)->Realize(p->engineObject, SL_BOOLEAN_FALSE);
if (result != SL_RESULT_SUCCESS) goto engine_end;
// realize the engine
result = (*p->engineObject)->Realize(p->engineObject, SL_BOOLEAN_FALSE);
DEBUG_SND("Realize=%d", result);
if(result != SL_RESULT_SUCCESS) goto engine_end;
// get the engine interface, which is needed in order to create other objects
result = (*p->engineObject)->GetInterface(p->engineObject, SL_IID_ENGINE, &(p->engineEngine));
if (result != SL_RESULT_SUCCESS) goto engine_end;
// get the engine interface, which is needed in order to create other objects
result = (*p->engineObject)->GetInterface(p->engineObject, SL_IID_ENGINE,
&(p->engineEngine));
DEBUG_SND("engineEngine=%p", p->engineEngine);
if(result != SL_RESULT_SUCCESS) goto engine_end;
engine_end:
return result;
if (result != SL_RESULT_SUCCESS) goto engine_end;
engine_end:
return result;
}
// opens the OpenSL ES device for output
static SLresult openSLPlayOpen(OPENSL_STREAM *p)
static SLresult openSLPlayOpen(OPENSL_STREAM* p)
{
SLresult result;
SLuint32 sr = p->sr;
SLuint32 channels = p->outchannels;
SLresult result;
SLuint32 sr = p->sr;
SLuint32 channels = p->outchannels;
assert(p->engineObject);
assert(p->engineEngine);
if(channels){
// configure audio source
SLDataLocator_AndroidSimpleBufferQueue loc_bufq =
if (channels)
{
// configure audio source
SLDataLocator_AndroidSimpleBufferQueue loc_bufq =
{
SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
p->queuesize
};
switch(sr){
switch (sr)
{
case 8000:
sr = SL_SAMPLINGRATE_8;
break;
case 8000:
sr = SL_SAMPLINGRATE_8;
break;
case 11025:
sr = SL_SAMPLINGRATE_11_025;
break;
case 16000:
sr = SL_SAMPLINGRATE_16;
break;
case 22050:
sr = SL_SAMPLINGRATE_22_05;
break;
case 24000:
sr = SL_SAMPLINGRATE_24;
break;
case 32000:
sr = SL_SAMPLINGRATE_32;
break;
case 44100:
sr = SL_SAMPLINGRATE_44_1;
break;
case 48000:
sr = SL_SAMPLINGRATE_48;
break;
case 64000:
sr = SL_SAMPLINGRATE_64;
break;
case 88200:
sr = SL_SAMPLINGRATE_88_2;
break;
case 96000:
sr = SL_SAMPLINGRATE_96;
break;
case 192000:
sr = SL_SAMPLINGRATE_192;
break;
default:
return -1;
}
const SLInterfaceID ids[] = {SL_IID_VOLUME};
const SLboolean req[] = {SL_BOOLEAN_FALSE};
result = (*p->engineEngine)->CreateOutputMix(p->engineEngine, &(p->outputMixObject), 1, ids, req);
case 11025:
sr = SL_SAMPLINGRATE_11_025;
break;
case 16000:
sr = SL_SAMPLINGRATE_16;
break;
case 22050:
sr = SL_SAMPLINGRATE_22_05;
break;
case 24000:
sr = SL_SAMPLINGRATE_24;
break;
case 32000:
sr = SL_SAMPLINGRATE_32;
break;
case 44100:
sr = SL_SAMPLINGRATE_44_1;
break;
case 48000:
sr = SL_SAMPLINGRATE_48;
break;
case 64000:
sr = SL_SAMPLINGRATE_64;
break;
case 88200:
sr = SL_SAMPLINGRATE_88_2;
break;
case 96000:
sr = SL_SAMPLINGRATE_96;
break;
case 192000:
sr = SL_SAMPLINGRATE_192;
break;
default:
return -1;
}
const SLInterfaceID ids[] = {SL_IID_VOLUME};
const SLboolean req[] = {SL_BOOLEAN_FALSE};
result = (*p->engineEngine)->CreateOutputMix(p->engineEngine,
&(p->outputMixObject), 1, ids, req);
DEBUG_SND("engineEngine=%p", p->engineEngine);
assert(!result);
if(result != SL_RESULT_SUCCESS) goto end_openaudio;
// realize the output mix
result = (*p->outputMixObject)->Realize(p->outputMixObject, SL_BOOLEAN_FALSE);
if (result != SL_RESULT_SUCCESS) goto end_openaudio;
// realize the output mix
result = (*p->outputMixObject)->Realize(p->outputMixObject, SL_BOOLEAN_FALSE);
DEBUG_SND("Realize=%d", result);
assert(!result);
if(result != SL_RESULT_SUCCESS) goto end_openaudio;
int speakers;
if(channels > 1)
speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
else speakers = SL_SPEAKER_FRONT_CENTER;
SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM,channels, sr,
SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
speakers, SL_BYTEORDER_LITTLEENDIAN};
SLDataSource audioSrc = {&loc_bufq, &format_pcm};
if (result != SL_RESULT_SUCCESS) goto end_openaudio;
// configure audio sink
SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, p->outputMixObject};
SLDataSink audioSnk = {&loc_outmix, NULL};
int speakers;
// create audio player
const SLInterfaceID ids1[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_VOLUME};
const SLboolean req1[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
result = (*p->engineEngine)->CreateAudioPlayer(p->engineEngine,
&(p->bqPlayerObject), &audioSrc, &audioSnk, 2, ids1, req1);
if (channels > 1)
speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
else speakers = SL_SPEAKER_FRONT_CENTER;
SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM, channels, sr,
SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
speakers, SL_BYTEORDER_LITTLEENDIAN
};
SLDataSource audioSrc = {&loc_bufq, &format_pcm};
// configure audio sink
SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, p->outputMixObject};
SLDataSink audioSnk = {&loc_outmix, NULL};
// create audio player
const SLInterfaceID ids1[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_VOLUME};
const SLboolean req1[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
result = (*p->engineEngine)->CreateAudioPlayer(p->engineEngine,
&(p->bqPlayerObject), &audioSrc, &audioSnk, 2, ids1, req1);
DEBUG_SND("bqPlayerObject=%p", p->bqPlayerObject);
assert(!result);
if(result != SL_RESULT_SUCCESS) goto end_openaudio;
// realize the player
result = (*p->bqPlayerObject)->Realize(p->bqPlayerObject, SL_BOOLEAN_FALSE);
if (result != SL_RESULT_SUCCESS) goto end_openaudio;
// realize the player
result = (*p->bqPlayerObject)->Realize(p->bqPlayerObject, SL_BOOLEAN_FALSE);
DEBUG_SND("Realize=%d", result);
assert(!result);
if(result != SL_RESULT_SUCCESS) goto end_openaudio;
// get the play interface
result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, SL_IID_PLAY, &(p->bqPlayerPlay));
if (result != SL_RESULT_SUCCESS) goto end_openaudio;
// get the play interface
result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, SL_IID_PLAY,
&(p->bqPlayerPlay));
DEBUG_SND("bqPlayerPlay=%p", p->bqPlayerPlay);
assert(!result);
if(result != SL_RESULT_SUCCESS) goto end_openaudio;
// get the volume interface
result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, SL_IID_VOLUME, &(p->bqPlayerVolume));
if (result != SL_RESULT_SUCCESS) goto end_openaudio;
// get the volume interface
result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, SL_IID_VOLUME,
&(p->bqPlayerVolume));
DEBUG_SND("bqPlayerVolume=%p", p->bqPlayerVolume);
assert(!result);
if(result != SL_RESULT_SUCCESS) goto end_openaudio;
// get the buffer queue interface
result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
&(p->bqPlayerBufferQueue));
if (result != SL_RESULT_SUCCESS) goto end_openaudio;
// get the buffer queue interface
result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject,
SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
&(p->bqPlayerBufferQueue));
DEBUG_SND("bqPlayerBufferQueue=%p", p->bqPlayerBufferQueue);
assert(!result);
if(result != SL_RESULT_SUCCESS) goto end_openaudio;
// register callback on the buffer queue
result = (*p->bqPlayerBufferQueue)->RegisterCallback(p->bqPlayerBufferQueue, bqPlayerCallback, p);
if (result != SL_RESULT_SUCCESS) goto end_openaudio;
// register callback on the buffer queue
result = (*p->bqPlayerBufferQueue)->RegisterCallback(p->bqPlayerBufferQueue,
bqPlayerCallback, p);
DEBUG_SND("bqPlayerCallback=%p", p->bqPlayerCallback);
assert(!result);
if(result != SL_RESULT_SUCCESS) goto end_openaudio;
// set the player's state to playing
result = (*p->bqPlayerPlay)->SetPlayState(p->bqPlayerPlay, SL_PLAYSTATE_PLAYING);
if (result != SL_RESULT_SUCCESS) goto end_openaudio;
// set the player's state to playing
result = (*p->bqPlayerPlay)->SetPlayState(p->bqPlayerPlay,
SL_PLAYSTATE_PLAYING);
DEBUG_SND("SetPlayState=%d", result);
assert(!result);
end_openaudio:
end_openaudio:
assert(!result);
return result;
}
return SL_RESULT_SUCCESS;
return result;
}
return SL_RESULT_SUCCESS;
}
// close the OpenSL IO and destroy the audio engine
static void openSLDestroyEngine(OPENSL_STREAM *p){
static void openSLDestroyEngine(OPENSL_STREAM* p)
{
// destroy buffer queue audio player object, and invalidate all associated interfaces
if (p->bqPlayerObject != NULL)
{
(*p->bqPlayerObject)->Destroy(p->bqPlayerObject);
p->bqPlayerObject = NULL;
p->bqPlayerVolume = NULL;
p->bqPlayerPlay = NULL;
p->bqPlayerBufferQueue = NULL;
p->bqPlayerEffectSend = NULL;
}
// destroy buffer queue audio player object, and invalidate all associated interfaces
if (p->bqPlayerObject != NULL) {
(*p->bqPlayerObject)->Destroy(p->bqPlayerObject);
p->bqPlayerObject = NULL;
p->bqPlayerVolume = NULL;
p->bqPlayerPlay = NULL;
p->bqPlayerBufferQueue = NULL;
p->bqPlayerEffectSend = NULL;
}
// destroy output mix object, and invalidate all associated interfaces
if (p->outputMixObject != NULL) {
(*p->outputMixObject)->Destroy(p->outputMixObject);
p->outputMixObject = NULL;
}
// destroy engine object, and invalidate all associated interfaces
if (p->engineObject != NULL) {
(*p->engineObject)->Destroy(p->engineObject);
p->engineObject = NULL;
p->engineEngine = NULL;
}
// destroy output mix object, and invalidate all associated interfaces
if (p->outputMixObject != NULL)
{
(*p->outputMixObject)->Destroy(p->outputMixObject);
p->outputMixObject = NULL;
}
// destroy engine object, and invalidate all associated interfaces
if (p->engineObject != NULL)
{
(*p->engineObject)->Destroy(p->engineObject);
p->engineObject = NULL;
p->engineEngine = NULL;
}
}
// open the android audio device for and/or output
OPENSL_STREAM *android_OpenAudioDevice(int sr, int outchannels, int bufferframes){
OPENSL_STREAM *p;
p = (OPENSL_STREAM *) calloc(sizeof(OPENSL_STREAM), 1);
OPENSL_STREAM* android_OpenAudioDevice(int sr, int outchannels,
int bufferframes)
{
OPENSL_STREAM* p;
p = (OPENSL_STREAM*) calloc(sizeof(OPENSL_STREAM), 1);
if (!p)
return NULL;
@ -238,19 +273,20 @@ OPENSL_STREAM *android_OpenAudioDevice(int sr, int outchannels, int bufferframes
p->outchannels = outchannels;
p->sr = sr;
if(openSLCreateEngine(p) != SL_RESULT_SUCCESS)
if (openSLCreateEngine(p) != SL_RESULT_SUCCESS)
{
android_CloseAudioDevice(p);
return NULL;
}
if(openSLPlayOpen(p) != SL_RESULT_SUCCESS)
if (openSLPlayOpen(p) != SL_RESULT_SUCCESS)
{
android_CloseAudioDevice(p);
return NULL;
}
p->queue = Queue_New(TRUE, -1, -1);
if (!p->queue)
{
android_CloseAudioDevice(p);
@ -261,107 +297,120 @@ OPENSL_STREAM *android_OpenAudioDevice(int sr, int outchannels, int bufferframes
}
// close the android audio device
void android_CloseAudioDevice(OPENSL_STREAM *p){
void android_CloseAudioDevice(OPENSL_STREAM* p)
{
if (p == NULL)
return;
if (p == NULL)
return;
openSLDestroyEngine(p);
openSLDestroyEngine(p);
if (p->queue)
Queue_Free(p->queue);
free(p);
free(p);
}
// this callback handler is called every time a buffer finishes playing
void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context)
static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void* context)
{
OPENSL_STREAM *p = (OPENSL_STREAM *) context;
OPENSL_STREAM* p = (OPENSL_STREAM*) context;
assert(p);
assert(p->queue);
void *data = Queue_Dequeue(p->queue);
void* data = Queue_Dequeue(p->queue);
free(data);
}
// puts a buffer of size samples to the device
int android_AudioOut(OPENSL_STREAM *p, const short *buffer,int size)
int android_AudioOut(OPENSL_STREAM* p, const short* buffer, int size)
{
assert(p);
assert(buffer);
assert(size > 0);
/* Assure, that the queue is not full. */
if (p->queuesize <= Queue_Count(p->queue) && WaitForSingleObject(p->queue->event, INFINITE) == WAIT_FAILED)
{
DEBUG_SND("WaitForSingleObject failed!");
return -1;
}
if (p->queuesize <= Queue_Count(p->queue)
&& WaitForSingleObject(p->queue->event, INFINITE) == WAIT_FAILED)
{
DEBUG_SND("WaitForSingleObject failed!");
return -1;
}
void* data = calloc(size, sizeof(short));
void *data = calloc(size, sizeof(short));
if (!data)
{
DEBUG_SND("unable to allocate a buffer");
return -1;
}
memcpy(data, buffer, size * sizeof(short));
Queue_Enqueue(p->queue, data);
(*p->bqPlayerBufferQueue)->Enqueue(p->bqPlayerBufferQueue,
data, sizeof(short) * size);
(*p->bqPlayerBufferQueue)->Enqueue(p->bqPlayerBufferQueue,
data, sizeof(short) * size);
return size;
}
int android_GetOutputMute(OPENSL_STREAM *p) {
int android_GetOutputMute(OPENSL_STREAM* p)
{
SLboolean mute;
assert(p);
assert(p->bqPlayerVolume);
SLresult rc = (*p->bqPlayerVolume)->GetMute(p->bqPlayerVolume, &mute);
assert(SL_RESULT_SUCCESS == rc);
if (SL_RESULT_SUCCESS != rc)
return SL_BOOLEAN_FALSE;
return mute;
}
void android_SetOutputMute(OPENSL_STREAM *p, BOOL _mute) {
BOOL android_SetOutputMute(OPENSL_STREAM* p, BOOL _mute)
{
SLboolean mute = _mute;
assert(p);
assert(p->bqPlayerVolume);
SLresult rc = (*p->bqPlayerVolume)->SetMute(p->bqPlayerVolume, mute);
assert(SL_RESULT_SUCCESS == rc);
if (SL_RESULT_SUCCESS != rc)
return FALSE;
return TRUE;
}
int android_GetOutputVolume(OPENSL_STREAM *p){
int android_GetOutputVolume(OPENSL_STREAM* p)
{
SLmillibel level;
assert(p);
assert(p->bqPlayerVolume);
SLresult rc = (*p->bqPlayerVolume)->GetVolumeLevel(p->bqPlayerVolume, &level);
assert(SL_RESULT_SUCCESS == rc);
if (SL_RESULT_SUCCESS != rc)
return 0;
return level;
}
int android_GetOutputVolumeMax(OPENSL_STREAM *p){
int android_GetOutputVolumeMax(OPENSL_STREAM* p)
{
SLmillibel level;
assert(p);
assert(p->bqPlayerVolume);
SLresult rc = (*p->bqPlayerVolume)->GetMaxVolumeLevel(p->bqPlayerVolume,
&level);
SLresult rc = (*p->bqPlayerVolume)->GetMaxVolumeLevel(p->bqPlayerVolume, &level);
assert(SL_RESULT_SUCCESS == rc);
if (SL_RESULT_SUCCESS != rc)
return 0;
return level;
}
void android_SetOutputVolume(OPENSL_STREAM *p, int level){
BOOL android_SetOutputVolume(OPENSL_STREAM* p, int level)
{
SLresult rc = (*p->bqPlayerVolume)->SetVolumeLevel(p->bqPlayerVolume, level);
assert(SL_RESULT_SUCCESS == rc);
if (SL_RESULT_SUCCESS != rc)
return FALSE;
return TRUE;
}

View File

@ -6,14 +6,14 @@ All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@ -35,70 +35,75 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdlib.h>
#include <winpr/synch.h>
#include <freerdp/api.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct opensl_stream {
// engine interfaces
SLObjectItf engineObject;
SLEngineItf engineEngine;
typedef struct opensl_stream
{
// engine interfaces
SLObjectItf engineObject;
SLEngineItf engineEngine;
// output mix interfaces
SLObjectItf outputMixObject;
// output mix interfaces
SLObjectItf outputMixObject;
// buffer queue player interfaces
SLObjectItf bqPlayerObject;
SLPlayItf bqPlayerPlay;
// buffer queue player interfaces
SLObjectItf bqPlayerObject;
SLPlayItf bqPlayerPlay;
SLVolumeItf bqPlayerVolume;
SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
SLEffectSendItf bqPlayerEffectSend;
SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
SLEffectSendItf bqPlayerEffectSend;
unsigned int outchannels;
unsigned int sr;
unsigned int outchannels;
unsigned int sr;
unsigned int queuesize;
wQueue *queue;
wQueue* queue;
} OPENSL_STREAM;
/*
Open the audio device with a given sampling rate (sr), output channels and IO buffer size
in frames. Returns a handle to the OpenSL stream
*/
OPENSL_STREAM* android_OpenAudioDevice(int sr, int outchannels, int bufferframes);
/*
Close the audio device
*/
void android_CloseAudioDevice(OPENSL_STREAM *p);
/*
Write a buffer to the OpenSL stream *p, of size samples. Returns the number of samples written.
*/
int android_AudioOut(OPENSL_STREAM *p, const short *buffer, int size);
/*
* Set the volume input level.
*/
void android_SetInputVolume(OPENSL_STREAM *p, int level);
/*
* Get the current output mute setting.
*/
int android_GetOutputMute(OPENSL_STREAM *p);
/*
* Change the current output mute setting.
*/
void android_SetOutputMute(OPENSL_STREAM *p, BOOL mute);
/*
* Get the current output volume level.
*/
int android_GetOutputVolume(OPENSL_STREAM *p);
/*
* Get the maximum output volume level.
*/
int android_GetOutputVolumeMax(OPENSL_STREAM *p);
/*
Open the audio device with a given sampling rate (sr), output channels and IO buffer size
in frames. Returns a handle to the OpenSL stream
*/
FREERDP_LOCAL OPENSL_STREAM* android_OpenAudioDevice(int sr, int outchannels,
int bufferframes);
/*
Close the audio device
*/
FREERDP_LOCAL void android_CloseAudioDevice(OPENSL_STREAM* p);
/*
Write a buffer to the OpenSL stream *p, of size samples. Returns the number of samples written.
*/
FREERDP_LOCAL int android_AudioOut(OPENSL_STREAM* p, const short* buffer,
int size);
/*
* Set the volume input level.
*/
FREERDP_LOCAL void android_SetInputVolume(OPENSL_STREAM* p, int level);
/*
* Get the current output mute setting.
*/
FREERDP_LOCAL int android_GetOutputMute(OPENSL_STREAM* p);
/*
* Change the current output mute setting.
*/
FREERDP_LOCAL BOOL android_SetOutputMute(OPENSL_STREAM* p, BOOL mute);
/*
* Get the current output volume level.
*/
FREERDP_LOCAL int android_GetOutputVolume(OPENSL_STREAM* p);
/*
* Get the maximum output volume level.
*/
FREERDP_LOCAL int android_GetOutputVolumeMax(OPENSL_STREAM* p);
/*
* Set the volume output level.
*/
void android_SetOutputVolume(OPENSL_STREAM *p, int level);
/*
* Set the volume output level.
*/
FREERDP_LOCAL BOOL android_SetOutputVolume(OPENSL_STREAM* p, int level);
#ifdef __cplusplus
};
#endif

View File

@ -53,7 +53,7 @@ struct rdpsnd_opensles_plugin
int block_size;
char* device_name;
OPENSL_STREAM *stream;
OPENSL_STREAM* stream;
UINT32 volume;
@ -68,10 +68,8 @@ static int rdpsnd_opensles_volume_to_millibel(unsigned short level, int max)
const int min = SL_MILLIBEL_MIN;
const int step = max - min;
const int rc = (level * step / 0xFFFF) + min;
DEBUG_SND("level=%d, min=%d, max=%d, step=%d, result=%d",
level, min, max, step, rc);
level, min, max, step, rc);
return rc;
}
@ -80,14 +78,12 @@ static unsigned short rdpsnd_opensles_millibel_to_volume(int millibel, int max)
const int min = SL_MILLIBEL_MIN;
const int range = max - min;
const int rc = ((millibel - min) * 0xFFFF + range / 2 + 1) / range;
DEBUG_SND("millibel=%d, min=%d, max=%d, range=%d, result=%d",
millibel, min, max, range, rc);
millibel, min, max, range, rc);
return rc;
}
static bool rdpsnd_opensles_check_handle(const rdpsndopenslesPlugin *hdl)
static bool rdpsnd_opensles_check_handle(const rdpsndopenslesPlugin* hdl)
{
bool rc = true;
@ -97,6 +93,7 @@ static bool rdpsnd_opensles_check_handle(const rdpsndopenslesPlugin *hdl)
{
if (!hdl->dsp_context)
rc = false;
if (!hdl->stream)
rc = false;
}
@ -105,11 +102,12 @@ static bool rdpsnd_opensles_check_handle(const rdpsndopenslesPlugin *hdl)
}
static BOOL rdpsnd_opensles_set_volume(rdpsndDevicePlugin* device,
UINT32 volume);
UINT32 volume);
static int rdpsnd_opensles_set_params(rdpsndopenslesPlugin* opensles)
{
DEBUG_SND("opensles=%p", opensles);
if (!rdpsnd_opensles_check_handle(opensles))
return 0;
@ -117,25 +115,22 @@ static int rdpsnd_opensles_set_params(rdpsndopenslesPlugin* opensles)
android_CloseAudioDevice(opensles->stream);
opensles->stream = android_OpenAudioDevice(
opensles->rate, opensles->channels, 20);
opensles->rate, opensles->channels, 20);
return 0;
}
static BOOL rdpsnd_opensles_set_format(rdpsndDevicePlugin* device,
AUDIO_FORMAT* format, int latency)
AUDIO_FORMAT* format, int latency)
{
rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device;
rdpsnd_opensles_check_handle(opensles);
DEBUG_SND("opensles=%p format=%p, latency=%d", opensles, format, latency);
if (format)
{
DEBUG_SND("format=%d, cbsize=%d, samples=%d, bits=%d, channels=%d, align=%d",
format->wFormatTag, format->cbSize, format->nSamplesPerSec,
format->wBitsPerSample, format->nChannels, format->nBlockAlign);
format->wFormatTag, format->cbSize, format->nSamplesPerSec,
format->wBitsPerSample, format->nChannels, format->nBlockAlign);
opensles->rate = format->nSamplesPerSec;
opensles->channels = format->nChannels;
opensles->format = format->wFormatTag;
@ -144,22 +139,21 @@ static BOOL rdpsnd_opensles_set_format(rdpsndDevicePlugin* device,
}
opensles->latency = latency;
return (rdpsnd_opensles_set_params(opensles) == 0);
}
static BOOL rdpsnd_opensles_open(rdpsndDevicePlugin* device,
AUDIO_FORMAT* format, int latency)
AUDIO_FORMAT* format, int latency)
{
rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device;
DEBUG_SND("opensles=%p format=%p, latency=%d, rate=%d",
opensles, format, latency, opensles->rate);
opensles, format, latency, opensles->rate);
if (rdpsnd_opensles_check_handle(opensles))
return TRUE;
opensles->stream = android_OpenAudioDevice(opensles->rate, opensles->channels, 20);
opensles->stream = android_OpenAudioDevice(opensles->rate, opensles->channels,
20);
assert(opensles->stream);
if (!opensles->stream)
@ -174,9 +168,9 @@ static BOOL rdpsnd_opensles_open(rdpsndDevicePlugin* device,
static void rdpsnd_opensles_close(rdpsndDevicePlugin* device)
{
rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device;
DEBUG_SND("opensles=%p", opensles);
if( !rdpsnd_opensles_check_handle(opensles))
if (!rdpsnd_opensles_check_handle(opensles))
return;
android_CloseAudioDevice(opensles->stream);
@ -186,51 +180,46 @@ static void rdpsnd_opensles_close(rdpsndDevicePlugin* device)
static void rdpsnd_opensles_free(rdpsndDevicePlugin* device)
{
rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device;
DEBUG_SND("opensles=%p", opensles);
assert(opensles);
assert(opensles->device_name);
free(opensles->device_name);
assert(opensles->dsp_context);
freerdp_dsp_context_free(opensles->dsp_context);
free(opensles);
}
static BOOL rdpsnd_opensles_format_supported(rdpsndDevicePlugin* device,
AUDIO_FORMAT* format)
AUDIO_FORMAT* format)
{
rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device;
DEBUG_SND("format=%d, cbsize=%d, samples=%d, bits=%d, channels=%d, align=%d",
format->wFormatTag, format->cbSize, format->nSamplesPerSec,
format->wBitsPerSample, format->nChannels, format->nBlockAlign);
assert(opensles);
format->wFormatTag, format->cbSize, format->nSamplesPerSec,
format->wBitsPerSample, format->nChannels, format->nBlockAlign);
assert(device);
assert(format);
switch (format->wFormatTag)
{
case WAVE_FORMAT_PCM:
if (format->cbSize == 0 &&
format->nSamplesPerSec <= 48000 &&
(format->wBitsPerSample == 8 || format->wBitsPerSample == 16) &&
(format->nChannels == 1 || format->nChannels == 2))
format->nSamplesPerSec <= 48000 &&
(format->wBitsPerSample == 8 || format->wBitsPerSample == 16) &&
(format->nChannels == 1 || format->nChannels == 2))
{
return TRUE;
}
break;
case WAVE_FORMAT_ADPCM:
case WAVE_FORMAT_DVI_ADPCM:
if (format->nSamplesPerSec <= 48000 &&
format->wBitsPerSample == 4 &&
(format->nChannels == 1 || format->nChannels == 2))
format->wBitsPerSample == 4 &&
(format->nChannels == 1 || format->nChannels == 2))
{
return TRUE;
}
break;
case WAVE_FORMAT_ALAW:
@ -246,7 +235,6 @@ static BOOL rdpsnd_opensles_format_supported(rdpsndDevicePlugin* device,
static UINT32 rdpsnd_opensles_get_volume(rdpsndDevicePlugin* device)
{
rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device;
DEBUG_SND("opensles=%p", opensles);
assert(opensles);
@ -263,31 +251,32 @@ static UINT32 rdpsnd_opensles_get_volume(rdpsndDevicePlugin* device)
opensles->volume = (vol << 16) | (vol & 0xFFFF);
}
}
return opensles->volume;
}
static BOOL rdpsnd_opensles_set_volume(rdpsndDevicePlugin* device,
UINT32 value)
UINT32 value)
{
rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device;
DEBUG_SND("opensles=%p, value=%d", opensles, value);
assert(opensles);
opensles->volume = value;
if (opensles->stream)
{
if (0 == opensles->volume)
android_SetOutputMute(opensles->stream, true);
return android_SetOutputMute(opensles->stream, true);
else
{
const int max = android_GetOutputVolumeMax(opensles->stream);
const int vol = rdpsnd_opensles_volume_to_millibel(value & 0xFFFF, max);
android_SetOutputMute(opensles->stream, false);
android_SetOutputVolume(opensles->stream, vol);
if (!android_SetOutputMute(opensles->stream, false))
return FALSE;
if (!android_SetOutputVolume(opensles->stream, vol))
return FALSE;
}
}
@ -295,53 +284,49 @@ static BOOL rdpsnd_opensles_set_volume(rdpsndDevicePlugin* device,
}
static void rdpsnd_opensles_play(rdpsndDevicePlugin* device,
BYTE *data, int size)
BYTE* data, int size)
{
union
{
BYTE *b;
short *s;
BYTE* b;
short* s;
} src;
int ret;
rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device;
DEBUG_SND("opensles=%p, data=%p, size=%d", opensles, data, size);
if (!rdpsnd_opensles_check_handle(opensles))
return;
if (opensles->format == WAVE_FORMAT_ADPCM)
{
DEBUG_SND("dsp_context=%p, channels=%d, block_size=%d",
opensles->dsp_context, opensles->channels, opensles->block_size);
opensles->dsp_context, opensles->channels, opensles->block_size);
opensles->dsp_context->decode_ms_adpcm(opensles->dsp_context,
data, size, opensles->channels, opensles->block_size);
data, size, opensles->channels, opensles->block_size);
size = opensles->dsp_context->adpcm_size;
src.b = opensles->dsp_context->adpcm_buffer;
}
else if (opensles->format == WAVE_FORMAT_DVI_ADPCM)
{
DEBUG_SND("dsp_context=%p, channels=%d, block_size=%d",
opensles->dsp_context, opensles->channels, opensles->block_size);
opensles->dsp_context, opensles->channels, opensles->block_size);
opensles->dsp_context->decode_ima_adpcm(opensles->dsp_context,
data, size, opensles->channels, opensles->block_size);
data, size, opensles->channels, opensles->block_size);
size = opensles->dsp_context->adpcm_size;
src.b = opensles->dsp_context->adpcm_buffer;
}
else
{
{
src.b = data;
}
}
DEBUG_SND("size=%d, src=%p", size, src.b);
assert(0 == size % 2);
assert(size > 0);
assert(src.b);
ret = android_AudioOut(opensles->stream, src.s, size / 2);
if (ret < 0)
WLog_ERR(TAG, "android_AudioOut failed (%d)", ret);
}
@ -350,34 +335,33 @@ static void rdpsnd_opensles_start(rdpsndDevicePlugin* device)
{
rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device;
rdpsnd_opensles_check_handle(opensles);
DEBUG_SND("opensles=%p", opensles);
}
static COMMAND_LINE_ARGUMENT_A rdpsnd_opensles_args[] =
{
{ "dev", COMMAND_LINE_VALUE_REQUIRED, "<device>",
NULL, NULL, -1, NULL, "device" },
{
"dev", COMMAND_LINE_VALUE_REQUIRED, "<device>",
NULL, NULL, -1, NULL, "device"
},
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
};
static int rdpsnd_opensles_parse_addin_args(rdpsndDevicePlugin* device,
ADDIN_ARGV* args)
ADDIN_ARGV* args)
{
int status;
DWORD flags;
COMMAND_LINE_ARGUMENT_A* arg;
rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device;
assert(opensles);
assert(args);
DEBUG_SND("opensles=%p, args=%p", opensles, args);
flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON | COMMAND_LINE_IGN_UNKNOWN_KEYWORD;
flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON |
COMMAND_LINE_IGN_UNKNOWN_KEYWORD;
status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv,
rdpsnd_opensles_args, flags, opensles, NULL, NULL);
rdpsnd_opensles_args, flags, opensles, NULL, NULL);
if (status < 0)
return status;
@ -389,14 +373,13 @@ static int rdpsnd_opensles_parse_addin_args(rdpsndDevicePlugin* device,
continue;
CommandLineSwitchStart(arg)
CommandLineSwitchCase(arg, "dev")
{
opensles->device_name = _strdup(arg->Value);
if (!opensles->device_name)
return ERROR_OUTOFMEMORY;
}
CommandLineSwitchEnd(arg)
}
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
@ -404,7 +387,7 @@ static int rdpsnd_opensles_parse_addin_args(rdpsndDevicePlugin* device,
return status;
}
#ifdef STATIC_CHANNELS
#ifdef BUILTIN_CHANNELS
#define freerdp_rdpsnd_client_subsystem_entry \
opensles_freerdp_rdpsnd_client_subsystem_entry
#else
@ -418,15 +401,14 @@ static int rdpsnd_opensles_parse_addin_args(rdpsndDevicePlugin* device,
* @return 0 on success, otherwise a Win32 error code
*/
UINT freerdp_rdpsnd_client_subsystem_entry(
PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints)
PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints)
{
ADDIN_ARGV* args;
rdpsndopenslesPlugin* opensles;
UINT error;
DEBUG_SND("pEntryPoints=%p", pEntryPoints);
opensles = (rdpsndopenslesPlugin*) calloc(1, sizeof(rdpsndopenslesPlugin));
if (!opensles)
return CHANNEL_RC_NO_MEMORY;
@ -439,13 +421,13 @@ UINT freerdp_rdpsnd_client_subsystem_entry(
opensles->device.Play = rdpsnd_opensles_play;
opensles->device.Close = rdpsnd_opensles_close;
opensles->device.Free = rdpsnd_opensles_free;
args = pEntryPoints->args;
rdpsnd_opensles_parse_addin_args((rdpsndDevicePlugin*) opensles, args);
if (!opensles->device_name)
{
opensles->device_name = _strdup("default");
if (!opensles->device_name)
{
error = CHANNEL_RC_NO_MEMORY;
@ -456,8 +438,8 @@ UINT freerdp_rdpsnd_client_subsystem_entry(
opensles->rate = 44100;
opensles->channels = 2;
opensles->format = WAVE_FORMAT_ADPCM;
opensles->dsp_context = freerdp_dsp_context_new();
if (!opensles->dsp_context)
{
error = CHANNEL_RC_NO_MEMORY;
@ -465,8 +447,7 @@ UINT freerdp_rdpsnd_client_subsystem_entry(
}
pEntryPoints->pRegisterRdpsndDevice(pEntryPoints->rdpsnd,
(rdpsndDevicePlugin*) opensles);
(rdpsndDevicePlugin*) opensles);
DEBUG_SND("success");
return CHANNEL_RC_OK;
out_dsp_new:

View File

@ -475,7 +475,7 @@ static int rdpsnd_oss_parse_addin_args(rdpsndDevicePlugin* device, ADDIN_ARGV* a
return status;
}
#ifdef STATIC_CHANNELS
#ifdef BUILTIN_CHANNELS
#define freerdp_rdpsnd_client_subsystem_entry oss_freerdp_rdpsnd_client_subsystem_entry
#else
#define freerdp_rdpsnd_client_subsystem_entry FREERDP_API freerdp_rdpsnd_client_subsystem_entry

View File

@ -584,7 +584,9 @@ static void rdpsnd_pulse_start(rdpsndDevicePlugin* device)
if (!pulse->stream)
return;
pa_threaded_mainloop_lock(pulse->mainloop);
pa_stream_trigger(pulse->stream, NULL, NULL);
pa_threaded_mainloop_unlock(pulse->mainloop);
}
COMMAND_LINE_ARGUMENT_A rdpsnd_pulse_args[] =
@ -634,7 +636,7 @@ static UINT rdpsnd_pulse_parse_addin_args(rdpsndDevicePlugin* device, ADDIN_ARGV
return CHANNEL_RC_OK;
}
#ifdef STATIC_CHANNELS
#ifdef BUILTIN_CHANNELS
#define freerdp_rdpsnd_client_subsystem_entry pulse_freerdp_rdpsnd_client_subsystem_entry
#else
#define freerdp_rdpsnd_client_subsystem_entry FREERDP_API freerdp_rdpsnd_client_subsystem_entry

File diff suppressed because it is too large Load Diff

View File

@ -30,9 +30,9 @@
#define TAG CHANNELS_TAG("rdpsnd.client")
#if defined(WITH_DEBUG_SND)
#define DEBUG_SND(fmt, ...) WLog_DBG(TAG, fmt, ## __VA_ARGS__)
#define DEBUG_SND(...) WLog_DBG(TAG, __VA_ARGS__)
#else
#define DEBUG_SND(fmt, ...) do { } while (0)
#define DEBUG_SND(...) do { } while (0)
#endif
UINT rdpsnd_virtual_channel_write(rdpsndPlugin* rdpsnd, wStream* s);

View File

@ -32,7 +32,7 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp)
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS)
if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS)
install(FILES ${CMAKE_PDB_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols)
endif()

View File

@ -6,6 +6,7 @@
* Copyright 2010-2012 Vic Lee
* Copyright 2015 Thincast Technologies GmbH
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
* Copyright 2016 David PHAM-VAN <d.phamvan@inuvika.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -136,6 +137,7 @@ static void CALLBACK rdpsnd_winmm_callback_function(HWAVEOUT hwo, UINT uMsg, DWO
winmm->device.WaveConfirm(&(winmm->device), wave);
free(lpWaveHdr->lpData);
free(lpWaveHdr);
free(wave);
}
@ -330,6 +332,7 @@ void rdpsnd_winmm_wave_play(rdpsndDevicePlugin* device, RDPSND_WAVE* wave)
{
WLog_ERR(TAG, "waveOutWrite failure: %d", mmResult);
waveOutUnprepareHeader(winmm->hWaveOut, lpWaveHdr, sizeof(WAVEHDR));
free(lpWaveHdr);
return;
}
}
@ -344,7 +347,7 @@ static void rdpsnd_winmm_parse_addin_args(rdpsndDevicePlugin* device, ADDIN_ARGV
}
#ifdef STATIC_CHANNELS
#ifdef BUILTIN_CHANNELS
#define freerdp_rdpsnd_client_subsystem_entry winmm_freerdp_rdpsnd_client_subsystem_entry
#else
#define freerdp_rdpsnd_client_subsystem_entry FREERDP_API freerdp_rdpsnd_client_subsystem_entry

View File

@ -46,11 +46,9 @@ UINT rdpsnd_server_send_formats(RdpsndServerContext* context, wStream* s)
UINT16 i;
BOOL status;
ULONG written;
Stream_Write_UINT8(s, SNDC_FORMATS);
Stream_Write_UINT8(s, 0);
Stream_Seek_UINT16(s);
Stream_Write_UINT32(s, 0); /* dwFlags */
Stream_Write_UINT32(s, 0); /* dwVolume */
Stream_Write_UINT32(s, 0); /* dwPitch */
@ -59,24 +57,27 @@ UINT rdpsnd_server_send_formats(RdpsndServerContext* context, wStream* s)
Stream_Write_UINT8(s, context->block_no); /* cLastBlockConfirmed */
Stream_Write_UINT16(s, 0x06); /* wVersion */
Stream_Write_UINT8(s, 0); /* bPad */
for (i = 0; i < context->num_server_formats; i++)
{
Stream_Write_UINT16(s, context->server_formats[i].wFormatTag); /* wFormatTag (WAVE_FORMAT_PCM) */
Stream_Write_UINT16(s,
context->server_formats[i].wFormatTag); /* wFormatTag (WAVE_FORMAT_PCM) */
Stream_Write_UINT16(s, context->server_formats[i].nChannels); /* nChannels */
Stream_Write_UINT32(s, context->server_formats[i].nSamplesPerSec); /* nSamplesPerSec */
Stream_Write_UINT32(s,
context->server_formats[i].nSamplesPerSec); /* nSamplesPerSec */
Stream_Write_UINT32(s, context->server_formats[i].nSamplesPerSec *
context->server_formats[i].nChannels *
context->server_formats[i].wBitsPerSample / 8); /* nAvgBytesPerSec */
Stream_Write_UINT16(s, context->server_formats[i].nBlockAlign); /* nBlockAlign */
Stream_Write_UINT16(s, context->server_formats[i].wBitsPerSample); /* wBitsPerSample */
context->server_formats[i].nChannels *
context->server_formats[i].wBitsPerSample / 8); /* nAvgBytesPerSec */
Stream_Write_UINT16(s,
context->server_formats[i].nBlockAlign); /* nBlockAlign */
Stream_Write_UINT16(s,
context->server_formats[i].wBitsPerSample); /* wBitsPerSample */
Stream_Write_UINT16(s, context->server_formats[i].cbSize); /* cbSize */
if (context->server_formats[i].cbSize > 0)
{
Stream_Write(s, context->server_formats[i].data, context->server_formats[i].cbSize);
Stream_Write(s, context->server_formats[i].data,
context->server_formats[i].cbSize);
}
}
@ -84,10 +85,10 @@ UINT rdpsnd_server_send_formats(RdpsndServerContext* context, wStream* s)
Stream_SetPosition(s, 2);
Stream_Write_UINT16(s, pos - 4);
Stream_SetPosition(s, pos);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle,
(PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written);
Stream_SetPosition(s, 0);
return status ? CHANNEL_RC_OK: ERROR_INTERNAL_ERROR;
return status ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR;
}
/**
@ -95,7 +96,8 @@ UINT rdpsnd_server_send_formats(RdpsndServerContext* context, wStream* s)
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT rdpsnd_server_recv_waveconfirm(RdpsndServerContext* context, wStream* s)
static UINT rdpsnd_server_recv_waveconfirm(RdpsndServerContext* context,
wStream* s)
{
UINT16 timestamp;
BYTE confirmBlockNum;
@ -110,10 +112,10 @@ static UINT rdpsnd_server_recv_waveconfirm(RdpsndServerContext* context, wStream
Stream_Read_UINT16(s, timestamp);
Stream_Read_UINT8(s, confirmBlockNum);
Stream_Seek_UINT8(s);
IFCALLRET(context->ConfirmBlock, error, context, confirmBlockNum, timestamp);
if (error)
WLog_ERR(TAG, "context->ConfirmBlock failed with error %lu", error);
WLog_ERR(TAG, "context->ConfirmBlock failed with error %u", error);
return error;
}
@ -123,10 +125,11 @@ static UINT rdpsnd_server_recv_waveconfirm(RdpsndServerContext* context, wStream
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT rdpsnd_server_recv_quality_mode(RdpsndServerContext* context, wStream* s)
static UINT rdpsnd_server_recv_quality_mode(RdpsndServerContext* context,
wStream* s)
{
UINT16 quality;
if (Stream_GetRemainingLength(s) < 4)
{
WLog_ERR(TAG, "not enought data in stream!");
@ -180,7 +183,9 @@ static UINT rdpsnd_server_recv_formats(RdpsndServerContext* context, wStream* s)
return ERROR_INTERNAL_ERROR;
}
context->client_formats = (AUDIO_FORMAT *)calloc(context->num_client_formats, sizeof(AUDIO_FORMAT));
context->client_formats = (AUDIO_FORMAT*)calloc(context->num_client_formats,
sizeof(AUDIO_FORMAT));
if (!context->client_formats)
{
WLog_ERR(TAG, "calloc failed!");
@ -196,7 +201,6 @@ static UINT rdpsnd_server_recv_formats(RdpsndServerContext* context, wStream* s)
goto out_free;
}
Stream_Read_UINT16(s, context->client_formats[i].wFormatTag);
Stream_Read_UINT16(s, context->client_formats[i].nChannels);
Stream_Read_UINT32(s, context->client_formats[i].nSamplesPerSec);
@ -213,7 +217,6 @@ static UINT rdpsnd_server_recv_formats(RdpsndServerContext* context, wStream* s)
error = ERROR_INTERNAL_ERROR;
goto out_free;
}
}
if (context->client_formats[i].wFormatTag != 0)
@ -231,7 +234,6 @@ static UINT rdpsnd_server_recv_formats(RdpsndServerContext* context, wStream* s)
}
return CHANNEL_RC_OK;
out_free:
free(context->client_formats);
return error;
@ -243,15 +245,15 @@ static void* rdpsnd_server_thread(void* arg)
HANDLE events[8];
RdpsndServerContext* context;
UINT error = CHANNEL_RC_OK;
context = (RdpsndServerContext*)arg;
context = (RdpsndServerContext *)arg;
nCount = 0;
events[nCount++] = context->priv->channelEvent;
events[nCount++] = context->priv->StopEvent;
if ((error = rdpsnd_server_send_formats(context, context->priv->rdpsnd_pdu)))
{
WLog_ERR(TAG, "rdpsnd_server_send_formats failed with error %lu", error);
WLog_ERR(TAG, "rdpsnd_server_send_formats failed with error %u", error);
goto out;
}
@ -259,36 +261,38 @@ static void* rdpsnd_server_thread(void* arg)
{
status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error);
break;
}
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u!", error);
break;
}
status = WaitForSingleObject(context->priv->StopEvent, 0);
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
break;
}
status = WaitForSingleObject(context->priv->StopEvent, 0);
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error);
break;
}
if (status == WAIT_OBJECT_0)
break;
if ((error = rdpsnd_server_handle_messages(context)))
{
WLog_ERR(TAG, "rdpsnd_server_handle_messages failed with error %lu", error);
WLog_ERR(TAG, "rdpsnd_server_handle_messages failed with error %u", error);
break;
}
}
out:
if (error && context->rdpcontext)
setChannelError(context->rdpcontext, error, "rdpsnd_server_thread reported an error");
setChannelError(context->rdpcontext, error,
"rdpsnd_server_thread reported an error");
ExitThread((DWORD)error);
return NULL;
}
@ -298,7 +302,8 @@ out:
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT rdpsnd_server_initialize(RdpsndServerContext* context, BOOL ownThread)
static UINT rdpsnd_server_initialize(RdpsndServerContext* context,
BOOL ownThread)
{
context->priv->ownThread = ownThread;
return context->Start(context);
@ -309,63 +314,79 @@ static UINT rdpsnd_server_initialize(RdpsndServerContext* context, BOOL ownThrea
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT rdpsnd_server_select_format(RdpsndServerContext* context, int client_format_index)
static UINT rdpsnd_server_select_format(RdpsndServerContext* context,
int client_format_index)
{
int bs;
int out_buffer_size;
AUDIO_FORMAT *format;
AUDIO_FORMAT* format;
UINT error = CHANNEL_RC_OK;
if (client_format_index < 0 || client_format_index >= context->num_client_formats)
if (client_format_index < 0
|| client_format_index >= context->num_client_formats)
{
WLog_ERR(TAG, "index %d is not correct.", client_format_index);
return ERROR_INVALID_DATA;
}
context->priv->src_bytes_per_sample = context->src_format.wBitsPerSample / 8;
context->priv->src_bytes_per_frame = context->priv->src_bytes_per_sample * context->src_format.nChannels;
EnterCriticalSection(&context->priv->lock);
context->priv->src_bytes_per_sample = context->src_format.wBitsPerSample / 8;
context->priv->src_bytes_per_frame = context->priv->src_bytes_per_sample *
context->src_format.nChannels;
context->selected_client_format = client_format_index;
format = &context->client_formats[client_format_index];
if (format->nSamplesPerSec == 0)
{
WLog_ERR(TAG, "invalid Client Sound Format!!");
return ERROR_INVALID_DATA;
error = ERROR_INVALID_DATA;
goto out;
}
switch(format->wFormatTag)
if (context->latency <= 0)
context->latency = 50;
context->priv->out_frames = context->src_format.nSamplesPerSec *
context->latency / 1000;
if (context->priv->out_frames < 1)
context->priv->out_frames = 1;
switch (format->wFormatTag)
{
case WAVE_FORMAT_DVI_ADPCM:
bs = (format->nBlockAlign - 4 * format->nChannels) * 4;
context->priv->out_frames = (format->nBlockAlign * 4 * format->nChannels * 2 / bs + 1) * bs / (format->nChannels * 2);
context->priv->out_frames -= context->priv->out_frames % bs;
if (context->priv->out_frames < bs)
context->priv->out_frames = bs;
break;
case WAVE_FORMAT_ADPCM:
bs = (format->nBlockAlign - 7 * format->nChannels) * 2 / format->nChannels + 2;
context->priv->out_frames = bs * 4;
break;
default:
context->priv->out_frames = 0x4000 / context->priv->src_bytes_per_frame;
context->priv->out_frames -= context->priv->out_frames % bs;
if (context->priv->out_frames < bs)
context->priv->out_frames = bs;
break;
}
if (format->nSamplesPerSec != context->src_format.nSamplesPerSec)
{
context->priv->out_frames = (context->priv->out_frames * context->src_format.nSamplesPerSec + format->nSamplesPerSec - 100) / format->nSamplesPerSec;
}
context->priv->out_pending_frames = 0;
out_buffer_size = context->priv->out_frames *
context->priv->src_bytes_per_frame;
out_buffer_size = context->priv->out_frames * context->priv->src_bytes_per_frame;
if (context->priv->out_buffer_size < out_buffer_size)
{
BYTE *newBuffer;
BYTE* newBuffer;
newBuffer = (BYTE*)realloc(context->priv->out_buffer, out_buffer_size);
newBuffer = (BYTE *)realloc(context->priv->out_buffer, out_buffer_size);
if (!newBuffer)
{
WLog_ERR(TAG, "realloc failed!");
return CHANNEL_RC_NO_MEMORY;
error = CHANNEL_RC_NO_MEMORY;
goto out;
}
context->priv->out_buffer = newBuffer;
@ -373,15 +394,19 @@ static UINT rdpsnd_server_select_format(RdpsndServerContext* context, int client
}
freerdp_dsp_context_reset_adpcm(context->priv->dsp_context);
return CHANNEL_RC_OK;
out:
LeaveCriticalSection(&context->priv->lock);
return error;
}
/**
* Function description
* context->priv->lock should be obtained before calling this function
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT rdpsnd_server_send_audio_pdu(RdpsndServerContext* context, UINT16 wTimestamp)
static UINT rdpsnd_server_send_audio_pdu(RdpsndServerContext* context,
UINT16 wTimestamp)
{
int size;
BYTE* src;
@ -393,50 +418,51 @@ static UINT rdpsnd_server_send_audio_pdu(RdpsndServerContext* context, UINT16 wT
ULONG written;
wStream* s = context->priv->rdpsnd_pdu;
UINT error = CHANNEL_RC_OK;
format = &context->client_formats[context->selected_client_format];
tbytes_per_frame = format->nChannels * context->priv->src_bytes_per_sample;
if ((format->nSamplesPerSec == context->src_format.nSamplesPerSec) &&
(format->nChannels == context->src_format.nChannels))
(format->nChannels == context->src_format.nChannels))
{
src = context->priv->out_buffer;
frames = context->priv->out_pending_frames;
}
else
{
context->priv->dsp_context->resample(context->priv->dsp_context, context->priv->out_buffer,
context->priv->src_bytes_per_sample, context->src_format.nChannels,
context->src_format.nSamplesPerSec, context->priv->out_pending_frames,
format->nChannels, format->nSamplesPerSec);
context->priv->dsp_context->resample(context->priv->dsp_context,
context->priv->out_buffer,
context->priv->src_bytes_per_sample, context->src_format.nChannels,
context->src_format.nSamplesPerSec, context->priv->out_pending_frames,
format->nChannels, format->nSamplesPerSec);
frames = context->priv->dsp_context->resampled_frames;
src = context->priv->dsp_context->resampled_buffer;
}
size = frames * tbytes_per_frame;
if (format->wFormatTag == WAVE_FORMAT_DVI_ADPCM)
{
context->priv->dsp_context->encode_ima_adpcm(context->priv->dsp_context,
src, size, format->nChannels, format->nBlockAlign);
src, size, format->nChannels, format->nBlockAlign);
src = context->priv->dsp_context->adpcm_buffer;
size = context->priv->dsp_context->adpcm_size;
}
else if (format->wFormatTag == WAVE_FORMAT_ADPCM)
{
context->priv->dsp_context->encode_ms_adpcm(context->priv->dsp_context,
src, size, format->nChannels, format->nBlockAlign);
src, size, format->nChannels, format->nBlockAlign);
src = context->priv->dsp_context->adpcm_buffer;
size = context->priv->dsp_context->adpcm_size;
}
context->block_no = (context->block_no + 1) % 256;
/* Fill to nBlockAlign for the last audio packet */
fill_size = 0;
if ((format->wFormatTag == WAVE_FORMAT_DVI_ADPCM || format->wFormatTag == WAVE_FORMAT_ADPCM) &&
(context->priv->out_pending_frames < context->priv->out_frames) && ((size % format->nBlockAlign) != 0))
if ((format->wFormatTag == WAVE_FORMAT_DVI_ADPCM
|| format->wFormatTag == WAVE_FORMAT_ADPCM) &&
(context->priv->out_pending_frames < context->priv->out_frames)
&& ((size % format->nBlockAlign) != 0))
{
fill_size = format->nBlockAlign - (size % format->nBlockAlign);
}
@ -446,14 +472,14 @@ static UINT rdpsnd_server_send_audio_pdu(RdpsndServerContext* context, UINT16 wT
Stream_Write_UINT8(s, SNDC_WAVE); /* msgType */
Stream_Write_UINT8(s, 0); /* bPad */
Stream_Write_UINT16(s, size + fill_size + 8); /* BodySize */
Stream_Write_UINT16(s, wTimestamp); /* wTimeStamp */
Stream_Write_UINT16(s, context->selected_client_format); /* wFormatNo */
Stream_Write_UINT8(s, context->block_no); /* cBlockNo */
Stream_Seek(s, 3); /* bPad */
Stream_Write(s, src, 4);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle,
(PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written);
if (!status)
{
WLog_ERR(TAG, "WTSVirtualChannelWrite failed!");
@ -470,13 +496,15 @@ static UINT rdpsnd_server_send_audio_pdu(RdpsndServerContext* context, UINT16 wT
error = CHANNEL_RC_NO_MEMORY;
goto out;
}
Stream_Write_UINT32(s, 0); /* bPad */
Stream_Write(s, src + 4, size - 4);
if (fill_size > 0)
Stream_Zero(s, fill_size);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle,
(PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written);
if (!status)
{
@ -495,22 +523,30 @@ out:
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT rdpsnd_server_send_samples(RdpsndServerContext* context, const void* buf, int nframes, UINT16 wTimestamp)
static UINT rdpsnd_server_send_samples(RdpsndServerContext* context,
const void* buf, int nframes, UINT16 wTimestamp)
{
int cframes;
int cframesize;
UINT error = CHANNEL_RC_OK;
EnterCriticalSection(&context->priv->lock);
if (context->selected_client_format < 0)
return ERROR_INVALID_DATA;
{
/* It's possible while format negotiation has not been done */
WLog_WARN(TAG, "Drop samples because client format has not been negotiated.");
error = ERROR_NOT_READY;
goto out;
}
while (nframes > 0)
{
cframes = MIN(nframes, context->priv->out_frames - context->priv->out_pending_frames);
cframes = MIN(nframes, context->priv->out_frames -
context->priv->out_pending_frames);
cframesize = cframes * context->priv->src_bytes_per_frame;
CopyMemory(context->priv->out_buffer +
(context->priv->out_pending_frames * context->priv->src_bytes_per_frame), buf, cframesize);
(context->priv->out_pending_frames * context->priv->src_bytes_per_frame), buf,
cframesize);
buf = (BYTE*) buf + cframesize;
nframes -= cframes;
context->priv->out_pending_frames += cframes;
@ -518,11 +554,15 @@ static UINT rdpsnd_server_send_samples(RdpsndServerContext* context, const void*
if (context->priv->out_pending_frames >= context->priv->out_frames)
{
if ((error = rdpsnd_server_send_audio_pdu(context, wTimestamp)))
WLog_ERR(TAG, "rdpsnd_server_send_audio_pdu failed with error %lu", error);
{
WLog_ERR(TAG, "rdpsnd_server_send_audio_pdu failed with error %u", error);
break;
}
}
}
out:
LeaveCriticalSection(&context->priv->lock);
return error;
}
@ -531,27 +571,25 @@ static UINT rdpsnd_server_send_samples(RdpsndServerContext* context, const void*
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT rdpsnd_server_set_volume(RdpsndServerContext* context, int left, int right)
static UINT rdpsnd_server_set_volume(RdpsndServerContext* context, int left,
int right)
{
int pos;
BOOL status;
ULONG written;
wStream* s = context->priv->rdpsnd_pdu;
Stream_Write_UINT8(s, SNDC_SETVOLUME);
Stream_Write_UINT8(s, 0);
Stream_Seek_UINT16(s);
Stream_Write_UINT16(s, left);
Stream_Write_UINT16(s, right);
pos = Stream_GetPosition(s);
Stream_SetPosition(s, 2);
Stream_Write_UINT16(s, pos - 4);
Stream_SetPosition(s, pos);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle,
(PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written);
Stream_SetPosition(s, 0);
return status ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR;
}
@ -567,32 +605,37 @@ static UINT rdpsnd_server_close(RdpsndServerContext* context)
ULONG written;
wStream* s = context->priv->rdpsnd_pdu;
UINT error = CHANNEL_RC_OK;
if (context->selected_client_format < 0)
return ERROR_INVALID_DATA;
EnterCriticalSection(&context->priv->lock);
if (context->priv->out_pending_frames > 0)
{
if ((error = rdpsnd_server_send_audio_pdu(context, 0)))
if (context->selected_client_format < 0)
{
WLog_ERR(TAG, "rdpsnd_server_send_audio_pdu failed with error %lu", error);
return error;
WLog_ERR(TAG, "Pending audio frame exists while no format selected.");
error = ERROR_INVALID_DATA;
}
else if ((error = rdpsnd_server_send_audio_pdu(context, 0)))
{
WLog_ERR(TAG, "rdpsnd_server_send_audio_pdu failed with error %u", error);
}
}
context->selected_client_format = -1;
LeaveCriticalSection(&context->priv->lock);
if (error)
return error;
context->selected_client_format = -1;
Stream_Write_UINT8(s, SNDC_CLOSE);
Stream_Write_UINT8(s, 0);
Stream_Seek_UINT16(s);
pos = Stream_GetPosition(s);
Stream_SetPosition(s, 2);
Stream_Write_UINT16(s, pos - 4);
Stream_SetPosition(s, pos);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle,
(PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written);
Stream_SetPosition(s, 0);
return status ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR;
}
@ -603,31 +646,36 @@ static UINT rdpsnd_server_close(RdpsndServerContext* context)
*/
static UINT rdpsnd_server_start(RdpsndServerContext* context)
{
void *buffer = NULL;
void* buffer = NULL;
DWORD bytesReturned;
RdpsndServerPrivate *priv = context->priv;
RdpsndServerPrivate* priv = context->priv;
UINT error = ERROR_INTERNAL_ERROR;
priv->ChannelHandle = WTSVirtualChannelOpen(context->vcm, WTS_CURRENT_SESSION,
"rdpsnd");
priv->ChannelHandle = WTSVirtualChannelOpen(context->vcm, WTS_CURRENT_SESSION, "rdpsnd");
if (!priv->ChannelHandle)
{
WLog_ERR(TAG, "WTSVirtualChannelOpen failed!");
return ERROR_INTERNAL_ERROR;
}
if (!WTSVirtualChannelQuery(priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &bytesReturned) || (bytesReturned != sizeof(HANDLE)))
if (!WTSVirtualChannelQuery(priv->ChannelHandle, WTSVirtualEventHandle, &buffer,
&bytesReturned) || (bytesReturned != sizeof(HANDLE)))
{
WLog_ERR(TAG, "error during WTSVirtualChannelQuery(WTSVirtualEventHandle) or invalid returned size(%d)",
bytesReturned);
WLog_ERR(TAG,
"error during WTSVirtualChannelQuery(WTSVirtualEventHandle) or invalid returned size(%d)",
bytesReturned);
if (buffer)
WTSFreeMemory(buffer);
goto out_close;
}
CopyMemory(&priv->channelEvent, buffer, sizeof(HANDLE));
WTSFreeMemory(buffer);
priv->rdpsnd_pdu = Stream_New(NULL, 4096);
if (!priv->rdpsnd_pdu)
{
WLog_ERR(TAG, "Stream_New failed!");
@ -635,30 +683,38 @@ static UINT rdpsnd_server_start(RdpsndServerContext* context)
goto out_close;
}
if (!InitializeCriticalSectionEx(&context->priv->lock, 0, 0))
{
WLog_ERR(TAG, "InitializeCriticalSectionEx failed!");
goto out_pdu;
}
if (priv->ownThread)
{
context->priv->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!context->priv->StopEvent)
{
WLog_ERR(TAG, "CreateEvent failed!");
goto out_pdu;
goto out_lock;
}
context->priv->Thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) rdpsnd_server_thread, (void*) context, 0, NULL);
(LPTHREAD_START_ROUTINE) rdpsnd_server_thread, (void*) context, 0, NULL);
if (!context->priv->Thread)
{
WLog_ERR(TAG, "CreateThread failed!");
goto out_stopEvent;
}
}
return CHANNEL_RC_OK;
out_stopEvent:
CloseHandle(context->priv->StopEvent);
context->priv->StopEvent = NULL;
out_lock:
DeleteCriticalSection(&context->priv->lock);
out_pdu:
Stream_Free(context->priv->rdpsnd_pdu, TRUE);
context->priv->rdpsnd_pdu = NULL;
@ -675,7 +731,8 @@ out_close:
*/
static UINT rdpsnd_server_stop(RdpsndServerContext* context)
{
UINT error = CHANNEL_RC_OK;
UINT error = CHANNEL_RC_OK;
if (context->priv->ownThread)
{
if (context->priv->StopEvent)
@ -683,16 +740,19 @@ static UINT rdpsnd_server_stop(RdpsndServerContext* context)
SetEvent(context->priv->StopEvent);
if (WaitForSingleObject(context->priv->Thread, INFINITE) == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
return error;
}
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error);
return error;
}
CloseHandle(context->priv->Thread);
CloseHandle(context->priv->StopEvent);
}
}
DeleteCriticalSection(&context->priv->lock);
if (context->priv->rdpsnd_pdu)
Stream_Free(context->priv->rdpsnd_pdu, TRUE);
@ -702,9 +762,9 @@ static UINT rdpsnd_server_stop(RdpsndServerContext* context)
RdpsndServerContext* rdpsnd_server_context_new(HANDLE vcm)
{
RdpsndServerContext* context;
RdpsndServerPrivate *priv;
RdpsndServerPrivate* priv;
context = (RdpsndServerContext*)calloc(1, sizeof(RdpsndServerContext));
context = (RdpsndServerContext *)calloc(1, sizeof(RdpsndServerContext));
if (!context)
{
WLog_ERR(TAG, "calloc failed!");
@ -712,18 +772,17 @@ RdpsndServerContext* rdpsnd_server_context_new(HANDLE vcm)
}
context->vcm = vcm;
context->Start = rdpsnd_server_start;
context->Stop = rdpsnd_server_stop;
context->selected_client_format = -1;
context->Initialize = rdpsnd_server_initialize;
context->SelectFormat = rdpsnd_server_select_format;
context->SendSamples = rdpsnd_server_send_samples;
context->SetVolume = rdpsnd_server_set_volume;
context->Close = rdpsnd_server_close;
context->priv = priv = (RdpsndServerPrivate*)calloc(1,
sizeof(RdpsndServerPrivate));
context->priv = priv = (RdpsndServerPrivate *)calloc(1, sizeof(RdpsndServerPrivate));
if (!priv)
{
WLog_ERR(TAG, "calloc failed!");
@ -731,6 +790,7 @@ RdpsndServerContext* rdpsnd_server_context_new(HANDLE vcm)
}
priv->dsp_context = freerdp_dsp_context_new();
if (!priv->dsp_context)
{
WLog_ERR(TAG, "freerdp_dsp_context_new failed!");
@ -738,6 +798,7 @@ RdpsndServerContext* rdpsnd_server_context_new(HANDLE vcm)
}
priv->input_stream = Stream_New(NULL, 4);
if (!priv->input_stream)
{
WLog_ERR(TAG, "Stream_New failed!");
@ -748,7 +809,6 @@ RdpsndServerContext* rdpsnd_server_context_new(HANDLE vcm)
priv->waitingHeader = TRUE;
priv->ownThread = TRUE;
return context;
out_free_dsp:
freerdp_dsp_context_free(priv->dsp_context);
out_free_priv:
@ -759,11 +819,10 @@ out_free:
}
void rdpsnd_server_context_reset(RdpsndServerContext *context)
void rdpsnd_server_context_reset(RdpsndServerContext* context)
{
context->priv->expectedBytes = 4;
context->priv->waitingHeader = TRUE;
Stream_SetPosition(context->priv->input_stream, 0);
}
@ -781,13 +840,11 @@ void rdpsnd_server_context_free(RdpsndServerContext* context)
Stream_Free(context->priv->input_stream, TRUE);
free(context->client_formats);
free(context->priv);
free(context);
}
HANDLE rdpsnd_server_get_event_handle(RdpsndServerContext *context)
HANDLE rdpsnd_server_get_event_handle(RdpsndServerContext* context)
{
return context->priv->channelEvent;
}
@ -806,15 +863,15 @@ HANDLE rdpsnd_server_get_event_handle(RdpsndServerContext *context)
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rdpsnd_server_handle_messages(RdpsndServerContext *context)
UINT rdpsnd_server_handle_messages(RdpsndServerContext* context)
{
DWORD bytesReturned;
UINT ret = CHANNEL_RC_OK;
RdpsndServerPrivate* priv = context->priv;
wStream* s = priv->input_stream;
RdpsndServerPrivate *priv = context->priv;
wStream *s = priv->input_stream;
if (!WTSVirtualChannelRead(priv->ChannelHandle, 0, (PCHAR)Stream_Pointer(s), priv->expectedBytes, &bytesReturned))
if (!WTSVirtualChannelRead(priv->ChannelHandle, 0, (PCHAR)Stream_Pointer(s),
priv->expectedBytes, &bytesReturned))
{
if (GetLastError() == ERROR_NO_DATA)
return ERROR_NO_DATA;
@ -822,6 +879,7 @@ UINT rdpsnd_server_handle_messages(RdpsndServerContext *context)
WLog_ERR(TAG, "channel connection closed");
return ERROR_INTERNAL_ERROR;
}
priv->expectedBytes -= bytesReturned;
Stream_Seek(s, bytesReturned);
@ -830,15 +888,16 @@ UINT rdpsnd_server_handle_messages(RdpsndServerContext *context)
Stream_SealLength(s);
Stream_SetPosition(s, 0);
if (priv->waitingHeader)
{
/* header case */
Stream_Read_UINT8(s, priv->msgType);
Stream_Seek_UINT8(s); /* bPad */
Stream_Read_UINT16(s, priv->expectedBytes);
priv->waitingHeader = FALSE;
Stream_SetPosition(s, 0);
if (priv->expectedBytes)
{
if (!Stream_EnsureCapacity(s, priv->expectedBytes))
@ -846,6 +905,7 @@ UINT rdpsnd_server_handle_messages(RdpsndServerContext *context)
WLog_ERR(TAG, "Stream_EnsureCapacity failed!");
return CHANNEL_RC_NO_MEMORY;
}
return CHANNEL_RC_OK;
}
}
@ -873,10 +933,12 @@ UINT rdpsnd_server_handle_messages(RdpsndServerContext *context)
case SNDC_QUALITYMODE:
ret = rdpsnd_server_recv_quality_mode(context, s);
Stream_SetPosition(s, 0); /* in case the Activated callback tries to treat some messages */
Stream_SetPosition(s,
0); /* in case the Activated callback tries to treat some messages */
if ((ret == CHANNEL_RC_OK) && (context->clientVersion >= 6))
IFCALL(context->Activated, context);
break;
default:
@ -884,7 +946,7 @@ UINT rdpsnd_server_handle_messages(RdpsndServerContext *context)
ret = ERROR_INVALID_DATA;
break;
}
Stream_SetPosition(s, 0);
Stream_SetPosition(s, 0);
return ret;
}

View File

@ -52,6 +52,7 @@ struct _rdpsnd_server_private
UINT32 src_bytes_per_sample;
UINT32 src_bytes_per_frame;
FREERDP_DSP_CONTEXT* dsp_context;
CRITICAL_SECTION lock; /* Protect out_buffer and related parameters */
};
#endif /* FREERDP_CHANNEL_SERVER_RDPSND_MAIN_H */

View File

@ -21,7 +21,7 @@ set(${MODULE_PREFIX}_SRCS
remdesk_main.c
remdesk_main.h)
add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntry")
add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntryEx")

View File

@ -33,7 +33,8 @@
#include "remdesk_main.h"
RemdeskClientContext* remdesk_get_client_interface(remdeskPlugin* remdesk)
static RemdeskClientContext* remdesk_get_client_interface(
remdeskPlugin* remdesk)
{
RemdeskClientContext* pInterface;
pInterface = (RemdeskClientContext*) remdesk->channelEntryPoints.pInterface;
@ -55,12 +56,13 @@ static UINT remdesk_virtual_channel_write(remdeskPlugin* remdesk, wStream* s)
return CHANNEL_RC_INVALID_INSTANCE;
}
status = remdesk->channelEntryPoints.pVirtualChannelWrite(remdesk->OpenHandle,
Stream_Buffer(s), (UINT32) Stream_Length(s), s);
status = remdesk->channelEntryPoints.pVirtualChannelWriteEx(remdesk->InitHandle,
remdesk->OpenHandle,
Stream_Buffer(s), (UINT32) Stream_Length(s), s);
if (status != CHANNEL_RC_OK)
WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]",
WTSErrorToString(status), status);
WLog_ERR(TAG, "pVirtualChannelWriteEx failed with %s [%08X]",
WTSErrorToString(status), status);
return status;
}
@ -70,7 +72,7 @@ static UINT remdesk_virtual_channel_write(remdeskPlugin* remdesk, wStream* s)
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT remdesk_generate_expert_blob(remdeskPlugin* remdesk)
static UINT remdesk_generate_expert_blob(remdeskPlugin* remdesk)
{
char* name;
char* pass;
@ -97,7 +99,7 @@ UINT remdesk_generate_expert_blob(remdeskPlugin* remdesk)
name = "Expert";
remdesk->EncryptedPassStub = freerdp_assistance_encrypt_pass_stub(password,
settings->RemoteAssistancePassStub, &(remdesk->EncryptedPassStubSize));
settings->RemoteAssistancePassStub, &(remdesk->EncryptedPassStubSize));
if (!remdesk->EncryptedPassStub)
{
@ -105,7 +107,8 @@ UINT remdesk_generate_expert_blob(remdeskPlugin* remdesk)
return ERROR_INTERNAL_ERROR;
}
pass = freerdp_assistance_bin_to_hex_string(remdesk->EncryptedPassStub, remdesk->EncryptedPassStubSize);
pass = freerdp_assistance_bin_to_hex_string(remdesk->EncryptedPassStub,
remdesk->EncryptedPassStubSize);
if (!pass)
{
@ -129,7 +132,8 @@ UINT remdesk_generate_expert_blob(remdeskPlugin* remdesk)
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header)
static UINT remdesk_read_channel_header(wStream* s,
REMDESK_CHANNEL_HEADER* header)
{
int status;
UINT32 ChannelNameLen;
@ -152,7 +156,7 @@ static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* head
if ((ChannelNameLen % 2) != 0)
{
WLog_ERR(TAG, "ChannelNameLen % 2) != 0 ");
WLog_ERR(TAG, "ChannelNameLen %% 2) != 0 ");
return ERROR_INVALID_DATA;
}
@ -163,11 +167,9 @@ static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* head
}
ZeroMemory(header->ChannelName, sizeof(header->ChannelName));
pChannelName = (char*) header->ChannelName;
status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s),
ChannelNameLen / 2, &pChannelName, 32, NULL, NULL);
ChannelNameLen / 2, &pChannelName, 32, NULL, NULL);
Stream_Seek(s, ChannelNameLen);
if (status <= 0)
@ -184,12 +186,12 @@ static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* head
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT remdesk_write_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header)
static UINT remdesk_write_channel_header(wStream* s,
REMDESK_CHANNEL_HEADER* header)
{
int index;
UINT32 ChannelNameLen;
WCHAR ChannelNameW[32];
ZeroMemory(ChannelNameW, sizeof(ChannelNameW));
for (index = 0; index < 32; index++)
@ -198,12 +200,9 @@ static UINT remdesk_write_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* hea
}
ChannelNameLen = (strlen(header->ChannelName) + 1) * 2;
Stream_Write_UINT32(s, ChannelNameLen); /* ChannelNameLen (4 bytes) */
Stream_Write_UINT32(s, header->DataLength); /* DataLen (4 bytes) */
Stream_Write(s, ChannelNameW, ChannelNameLen); /* ChannelName (variable) */
return CHANNEL_RC_OK;
}
@ -224,7 +223,8 @@ static UINT remdesk_write_ctl_header(wStream* s, REMDESK_CTL_HEADER* ctlHeader)
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, UINT32 msgType, UINT32 msgSize)
static UINT remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader,
UINT32 msgType, UINT32 msgSize)
{
ctlHeader->msgType = msgType;
strcpy(ctlHeader->ChannelName, REMDESK_CHANNEL_CTL_NAME);
@ -237,7 +237,8 @@ static UINT remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, UINT32 msg
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT remdesk_recv_ctl_server_announce_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header)
static UINT remdesk_recv_ctl_server_announce_pdu(remdeskPlugin* remdesk,
wStream* s, REMDESK_CHANNEL_HEADER* header)
{
return CHANNEL_RC_OK;
}
@ -247,7 +248,8 @@ static UINT remdesk_recv_ctl_server_announce_pdu(remdeskPlugin* remdesk, wStream
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT remdesk_recv_ctl_version_info_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header)
static UINT remdesk_recv_ctl_version_info_pdu(remdeskPlugin* remdesk,
wStream* s, REMDESK_CHANNEL_HEADER* header)
{
UINT32 versionMajor;
UINT32 versionMinor;
@ -260,9 +262,7 @@ static UINT remdesk_recv_ctl_version_info_pdu(remdeskPlugin* remdesk, wStream* s
Stream_Read_UINT32(s, versionMajor); /* versionMajor (4 bytes) */
Stream_Read_UINT32(s, versionMinor); /* versionMinor (4 bytes) */
remdesk->Version = versionMajor;
return CHANNEL_RC_OK;
}
@ -276,13 +276,11 @@ static UINT remdesk_send_ctl_version_info_pdu(remdeskPlugin* remdesk)
wStream* s;
REMDESK_CTL_VERSION_INFO_PDU pdu;
UINT error;
remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_VERSIONINFO, 8);
pdu.versionMajor = 1;
pdu.versionMinor = 2;
s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength);
if (!s)
{
WLog_ERR(TAG, "Stream_New failed!");
@ -290,17 +288,16 @@ static UINT remdesk_send_ctl_version_info_pdu(remdeskPlugin* remdesk)
}
remdesk_write_ctl_header(s, &(pdu.ctlHeader));
Stream_Write_UINT32(s, pdu.versionMajor); /* versionMajor (4 bytes) */
Stream_Write_UINT32(s, pdu.versionMinor); /* versionMinor (4 bytes) */
Stream_SealLength(s);
if ((error = remdesk_virtual_channel_write(remdesk, s)))
WLog_ERR(TAG, "remdesk_virtual_channel_write failed with error %lu!", error);
WLog_ERR(TAG, "remdesk_virtual_channel_write failed with error %u!", error);
if (error != CHANNEL_RC_OK)
Stream_Free(s, TRUE);
return error;
}
@ -309,7 +306,8 @@ static UINT remdesk_send_ctl_version_info_pdu(remdeskPlugin* remdesk)
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT remdesk_recv_ctl_result_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header, UINT32 *pResult)
static UINT remdesk_recv_ctl_result_pdu(remdeskPlugin* remdesk, wStream* s,
REMDESK_CHANNEL_HEADER* header, UINT32* pResult)
{
UINT32 result;
@ -320,7 +318,6 @@ static UINT remdesk_recv_ctl_result_pdu(remdeskPlugin* remdesk, wStream* s, REMD
}
Stream_Read_UINT32(s, result); /* result (4 bytes) */
*pResult = result;
//WLog_DBG(TAG, "RemdeskRecvResult: 0x%04X", result);
return CHANNEL_RC_OK;
@ -344,14 +341,14 @@ static UINT remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk)
if ((error = remdesk_generate_expert_blob(remdesk)))
{
WLog_ERR(TAG, "remdesk_generate_expert_blob failed with error %lu", error);
WLog_ERR(TAG, "remdesk_generate_expert_blob failed with error %u", error);
return error;
}
pdu.expertBlob = remdesk->ExpertBlob;
pdu.raConnectionString = remdesk->settings->RemoteAssistanceRCTicket;
status = ConvertToUnicode(CP_UTF8, 0, pdu.raConnectionString, -1, &raConnectionStringW, 0);
status = ConvertToUnicode(CP_UTF8, 0, pdu.raConnectionString, -1,
&raConnectionStringW, 0);
if (status <= 0)
{
@ -360,7 +357,6 @@ static UINT remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk)
}
cbRaConnectionStringW = status * 2;
status = ConvertToUnicode(CP_UTF8, 0, pdu.expertBlob, -1, &expertBlobW, 0);
if (status <= 0)
@ -371,11 +367,10 @@ static UINT remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk)
}
cbExpertBlobW = status * 2;
remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_AUTHENTICATE,
cbRaConnectionStringW + cbExpertBlobW);
cbRaConnectionStringW + cbExpertBlobW);
s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength);
if (!s)
{
WLog_ERR(TAG, "Stream_New failed!");
@ -384,18 +379,17 @@ static UINT remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk)
}
remdesk_write_ctl_header(s, &(pdu.ctlHeader));
Stream_Write(s, (BYTE*) raConnectionStringW, cbRaConnectionStringW);
Stream_Write(s, (BYTE*) expertBlobW, cbExpertBlobW);
Stream_SealLength(s);
if ((error = remdesk_virtual_channel_write(remdesk, s)))
WLog_ERR(TAG, "remdesk_virtual_channel_write failed with error %lu!", error);
WLog_ERR(TAG, "remdesk_virtual_channel_write failed with error %u!", error);
out:
free(raConnectionStringW);
free(expertBlobW);
if (error != CHANNEL_RC_OK)
Stream_Free(s, TRUE);
@ -415,10 +409,9 @@ static UINT remdesk_send_ctl_remote_control_desktop_pdu(remdeskPlugin* remdesk)
int cbRaConnectionStringW = 0;
WCHAR* raConnectionStringW = NULL;
REMDESK_CTL_REMOTE_CONTROL_DESKTOP_PDU pdu;
pdu.raConnectionString = remdesk->settings->RemoteAssistanceRCTicket;
status = ConvertToUnicode(CP_UTF8, 0, pdu.raConnectionString, -1, &raConnectionStringW, 0);
status = ConvertToUnicode(CP_UTF8, 0, pdu.raConnectionString, -1,
&raConnectionStringW, 0);
if (status <= 0)
{
@ -427,10 +420,10 @@ static UINT remdesk_send_ctl_remote_control_desktop_pdu(remdeskPlugin* remdesk)
}
cbRaConnectionStringW = status * 2;
remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_REMOTE_CONTROL_DESKTOP, cbRaConnectionStringW);
remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_REMOTE_CONTROL_DESKTOP,
cbRaConnectionStringW);
s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength);
if (!s)
{
WLog_ERR(TAG, "Stream_New failed!");
@ -439,16 +432,15 @@ static UINT remdesk_send_ctl_remote_control_desktop_pdu(remdeskPlugin* remdesk)
}
remdesk_write_ctl_header(s, &(pdu.ctlHeader));
Stream_Write(s, (BYTE*) raConnectionStringW, cbRaConnectionStringW);
Stream_SealLength(s);
if ((error = remdesk_virtual_channel_write(remdesk, s)))
WLog_ERR(TAG, "remdesk_virtual_channel_write failed with error %lu!", error);
WLog_ERR(TAG, "remdesk_virtual_channel_write failed with error %u!", error);
out:
free(raConnectionStringW);
if (error != CHANNEL_RC_OK)
Stream_Free(s, TRUE);
@ -471,12 +463,11 @@ static UINT remdesk_send_ctl_verify_password_pdu(remdeskPlugin* remdesk)
if ((error = remdesk_generate_expert_blob(remdesk)))
{
WLog_ERR(TAG, "remdesk_generate_expert_blob failed with error %lu!", error);
WLog_ERR(TAG, "remdesk_generate_expert_blob failed with error %u!", error);
return error;
}
pdu.expertBlob = remdesk->ExpertBlob;
status = ConvertToUnicode(CP_UTF8, 0, pdu.expertBlob, -1, &expertBlobW, 0);
if (status <= 0)
@ -486,10 +477,10 @@ static UINT remdesk_send_ctl_verify_password_pdu(remdeskPlugin* remdesk)
}
cbExpertBlobW = status * 2;
remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_VERIFY_PASSWORD, cbExpertBlobW);
remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_VERIFY_PASSWORD,
cbExpertBlobW);
s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength);
if (!s)
{
WLog_ERR(TAG, "Stream_New failed!");
@ -498,16 +489,15 @@ static UINT remdesk_send_ctl_verify_password_pdu(remdeskPlugin* remdesk)
}
remdesk_write_ctl_header(s, &(pdu.ctlHeader));
Stream_Write(s, (BYTE*) expertBlobW, cbExpertBlobW);
Stream_SealLength(s);
if ((error = remdesk_virtual_channel_write(remdesk, s)))
WLog_ERR(TAG, "remdesk_virtual_channel_write failed with error %lu!", error);
WLog_ERR(TAG, "remdesk_virtual_channel_write failed with error %u!", error);
out:
free(expertBlobW);
if (error != CHANNEL_RC_OK)
Stream_Free(s, TRUE);
@ -527,17 +517,16 @@ static UINT remdesk_send_ctl_expert_on_vista_pdu(remdeskPlugin* remdesk)
if ((error = remdesk_generate_expert_blob(remdesk)))
{
WLog_ERR(TAG, "remdesk_generate_expert_blob failed with error %lu!", error);
WLog_ERR(TAG, "remdesk_generate_expert_blob failed with error %u!", error);
return error;
}
pdu.EncryptedPasswordLength = remdesk->EncryptedPassStubSize;
pdu.EncryptedPassword = remdesk->EncryptedPassStub;
remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_EXPERT_ON_VISTA,
pdu.EncryptedPasswordLength);
pdu.EncryptedPasswordLength);
s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength);
if (!s)
{
WLog_ERR(TAG, "Stream_New failed!");
@ -545,11 +534,8 @@ static UINT remdesk_send_ctl_expert_on_vista_pdu(remdeskPlugin* remdesk)
}
remdesk_write_ctl_header(s, &(pdu.ctlHeader));
Stream_Write(s, pdu.EncryptedPassword, pdu.EncryptedPasswordLength);
Stream_SealLength(s);
return remdesk_virtual_channel_write(remdesk, s);
}
@ -558,7 +544,8 @@ static UINT remdesk_send_ctl_expert_on_vista_pdu(remdeskPlugin* remdesk)
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header)
static UINT remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s,
REMDESK_CHANNEL_HEADER* header)
{
UINT error = CHANNEL_RC_OK;
UINT32 msgType = 0;
@ -581,7 +568,8 @@ static UINT remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHA
case REMDESK_CTL_RESULT:
if ((error = remdesk_recv_ctl_result_pdu(remdesk, s, header, &result)))
WLog_ERR(TAG, "remdesk_recv_ctl_result_pdu failed with error %lu", error);
WLog_ERR(TAG, "remdesk_recv_ctl_result_pdu failed with error %u", error);
break;
case REMDESK_CTL_AUTHENTICATE:
@ -589,7 +577,9 @@ static UINT remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHA
case REMDESK_CTL_SERVER_ANNOUNCE:
if ((error = remdesk_recv_ctl_server_announce_pdu(remdesk, s, header)))
WLog_ERR(TAG, "remdesk_recv_ctl_server_announce_pdu failed with error %lu", error);
WLog_ERR(TAG, "remdesk_recv_ctl_server_announce_pdu failed with error %u",
error);
break;
case REMDESK_CTL_DISCONNECT:
@ -598,7 +588,7 @@ static UINT remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHA
case REMDESK_CTL_VERSIONINFO:
if ((error = remdesk_recv_ctl_version_info_pdu(remdesk, s, header)))
{
WLog_ERR(TAG, "remdesk_recv_ctl_version_info_pdu failed with error %lu", error);
WLog_ERR(TAG, "remdesk_recv_ctl_version_info_pdu failed with error %u", error);
break;
}
@ -606,19 +596,20 @@ static UINT remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHA
{
if ((error = remdesk_send_ctl_version_info_pdu(remdesk)))
{
WLog_ERR(TAG, "remdesk_send_ctl_version_info_pdu failed with error %lu", error);
WLog_ERR(TAG, "remdesk_send_ctl_version_info_pdu failed with error %u", error);
break;
}
if ((error = remdesk_send_ctl_authenticate_pdu(remdesk)))
{
WLog_ERR(TAG, "remdesk_send_ctl_authenticate_pdu failed with error %lu", error);
WLog_ERR(TAG, "remdesk_send_ctl_authenticate_pdu failed with error %u", error);
break;
}
if ((error = remdesk_send_ctl_remote_control_desktop_pdu(remdesk)))
{
WLog_ERR(TAG, "remdesk_send_ctl_remote_control_desktop_pdu failed with error %lu", error);
WLog_ERR(TAG,
"remdesk_send_ctl_remote_control_desktop_pdu failed with error %u", error);
break;
}
}
@ -626,13 +617,15 @@ static UINT remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHA
{
if ((error = remdesk_send_ctl_expert_on_vista_pdu(remdesk)))
{
WLog_ERR(TAG, "remdesk_send_ctl_expert_on_vista_pdu failed with error %lu", error);
WLog_ERR(TAG, "remdesk_send_ctl_expert_on_vista_pdu failed with error %u",
error);
break;
}
if ((error = remdesk_send_ctl_verify_password_pdu(remdesk)))
{
WLog_ERR(TAG, "remdesk_send_ctl_verify_password_pdu failed with error %lu", error);
WLog_ERR(TAG, "remdesk_send_ctl_verify_password_pdu failed with error %u",
error);
break;
}
}
@ -675,7 +668,6 @@ static UINT remdesk_process_receive(remdeskPlugin* remdesk, wStream* s)
{
UINT status;
REMDESK_CHANNEL_HEADER header;
#if 0
WLog_DBG(TAG, "RemdeskReceive: %d", Stream_GetRemainingLength(s));
winpr_HexDump(Stream_Pointer(s), Stream_GetRemainingLength(s));
@ -683,7 +675,7 @@ static UINT remdesk_process_receive(remdeskPlugin* remdesk, wStream* s)
if ((status = remdesk_read_channel_header(s, &header)))
{
WLog_ERR(TAG, "remdesk_read_channel_header failed with error %lu", status);
WLog_ERR(TAG, "remdesk_read_channel_header failed with error %u", status);
return status;
}
@ -693,27 +685,21 @@ static UINT remdesk_process_receive(remdeskPlugin* remdesk, wStream* s)
}
else if (strcmp(header.ChannelName, "70") == 0)
{
}
else if (strcmp(header.ChannelName, "71") == 0)
{
}
else if (strcmp(header.ChannelName, ".") == 0)
{
}
else if (strcmp(header.ChannelName, "1000.") == 0)
{
}
else if (strcmp(header.ChannelName, "RA_FX") == 0)
{
}
else
{
}
return status;
@ -724,89 +710,12 @@ static void remdesk_process_connect(remdeskPlugin* remdesk)
remdesk->settings = (rdpSettings*) remdesk->channelEntryPoints.pExtendedData;
}
/****************************************************************************************/
static wListDictionary* g_InitHandles = NULL;
static wListDictionary* g_OpenHandles = NULL;
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT remdesk_add_init_handle_data(void* pInitHandle, void* pUserData)
{
if (!g_InitHandles)
{
g_InitHandles = ListDictionary_New(TRUE);
if (!g_InitHandles)
return CHANNEL_RC_NO_MEMORY;
}
return ListDictionary_Add(g_InitHandles, pInitHandle, pUserData) ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR;
}
void* remdesk_get_init_handle_data(void* pInitHandle)
{
void* pUserData = NULL;
pUserData = ListDictionary_GetItemValue(g_InitHandles, pInitHandle);
return pUserData;
}
void remdesk_remove_init_handle_data(void* pInitHandle)
{
ListDictionary_Remove(g_InitHandles, pInitHandle);
if (ListDictionary_Count(g_InitHandles) < 1)
{
ListDictionary_Free(g_InitHandles);
g_InitHandles = NULL;
}
}
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT remdesk_add_open_handle_data(DWORD openHandle, void* pUserData)
{
void* pOpenHandle = (void*) (size_t) openHandle;
if (!g_OpenHandles)
{
g_OpenHandles = ListDictionary_New(TRUE);
if (!g_OpenHandles)
return CHANNEL_RC_NO_MEMORY;
}
return ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData) ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR;
}
void* remdesk_get_open_handle_data(DWORD openHandle)
{
void* pUserData = NULL;
void* pOpenHandle = (void*) (size_t) openHandle;
pUserData = ListDictionary_GetItemValue(g_OpenHandles, pOpenHandle);
return pUserData;
}
void remdesk_remove_open_handle_data(DWORD openHandle)
{
void* pOpenHandle = (void*) (size_t) openHandle;
ListDictionary_Remove(g_OpenHandles, pOpenHandle);
if (ListDictionary_Count(g_OpenHandles) < 1)
{
ListDictionary_Free(g_OpenHandles);
g_OpenHandles = NULL;
}
}
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT remdesk_send(remdeskPlugin* remdesk, wStream* s)
static UINT remdesk_send(remdeskPlugin* remdesk, wStream* s)
{
UINT status = 0;
remdeskPlugin* plugin = (remdeskPlugin*) remdesk;
@ -817,15 +726,15 @@ UINT remdesk_send(remdeskPlugin* remdesk, wStream* s)
}
else
{
status = plugin->channelEntryPoints.pVirtualChannelWrite(plugin->OpenHandle,
Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s);
status = plugin->channelEntryPoints.pVirtualChannelWriteEx(plugin->InitHandle, plugin->OpenHandle,
Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s);
}
if (status != CHANNEL_RC_OK)
{
Stream_Free(s, TRUE);
WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]",
WTSErrorToString(status), status);
WLog_ERR(TAG, "pVirtualChannelWriteEx failed with %s [%08X]",
WTSErrorToString(status), status);
}
return status;
@ -837,7 +746,7 @@ UINT remdesk_send(remdeskPlugin* remdesk, wStream* s)
* @return 0 on success, otherwise a Win32 error code
*/
static UINT remdesk_virtual_channel_event_data_received(remdeskPlugin* remdesk,
void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
{
wStream* data_in;
@ -852,6 +761,7 @@ static UINT remdesk_virtual_channel_event_data_received(remdeskPlugin* remdesk,
Stream_Free(remdesk->data_in, TRUE);
remdesk->data_in = Stream_New(NULL, totalLength);
if (!remdesk->data_in)
{
WLog_ERR(TAG, "Stream_New failed!");
@ -860,11 +770,13 @@ static UINT remdesk_virtual_channel_event_data_received(remdeskPlugin* remdesk,
}
data_in = remdesk->data_in;
if (!Stream_EnsureRemainingCapacity(data_in, (int) dataLength))
{
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
return CHANNEL_RC_NO_MEMORY;
}
Stream_Write(data_in, pData, dataLength);
if (dataFlags & CHANNEL_FLAG_LAST)
@ -885,18 +797,18 @@ static UINT remdesk_virtual_channel_event_data_received(remdeskPlugin* remdesk,
return ERROR_INTERNAL_ERROR;
}
}
return CHANNEL_RC_OK;
}
static VOID VCAPITYPE remdesk_virtual_channel_open_event(DWORD openHandle, UINT event,
LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
static VOID VCAPITYPE remdesk_virtual_channel_open_event_ex(LPVOID lpUserParam, DWORD openHandle,
UINT event,
LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
{
remdeskPlugin* remdesk;
UINT error = CHANNEL_RC_OK;
remdeskPlugin* remdesk = (remdeskPlugin*) lpUserParam;
remdesk = (remdeskPlugin*) remdesk_get_open_handle_data(openHandle);
if (!remdesk)
if (!remdesk || (remdesk->OpenHandle != openHandle))
{
WLog_ERR(TAG, "error no match");
return;
@ -905,8 +817,11 @@ static VOID VCAPITYPE remdesk_virtual_channel_open_event(DWORD openHandle, UINT
switch (event)
{
case CHANNEL_EVENT_DATA_RECEIVED:
if ((error = remdesk_virtual_channel_event_data_received(remdesk, pData, dataLength, totalLength, dataFlags)))
WLog_ERR(TAG, "remdesk_virtual_channel_event_data_received failed with error %lu!", error);
if ((error = remdesk_virtual_channel_event_data_received(remdesk, pData,
dataLength, totalLength, dataFlags)))
WLog_ERR(TAG,
"remdesk_virtual_channel_event_data_received failed with error %u!", error);
break;
case CHANNEL_EVENT_WRITE_COMPLETE:
@ -917,13 +832,13 @@ static VOID VCAPITYPE remdesk_virtual_channel_open_event(DWORD openHandle, UINT
break;
default:
WLog_ERR(TAG, "unhandled event %lu!", event);
WLog_ERR(TAG, "unhandled event %u!", event);
error = ERROR_INTERNAL_ERROR;
}
if (error && remdesk->rdpcontext)
setChannelError(remdesk->rdpcontext, error, "remdesk_virtual_channel_open_event reported an error");
if (error && remdesk->rdpcontext)
setChannelError(remdesk->rdpcontext, error,
"remdesk_virtual_channel_open_event_ex reported an error");
}
static void* remdesk_virtual_channel_client_thread(void* arg)
@ -932,7 +847,6 @@ static void* remdesk_virtual_channel_client_thread(void* arg)
wMessage message;
remdeskPlugin* remdesk = (remdeskPlugin*) arg;
UINT error = CHANNEL_RC_OK;
remdesk_process_connect(remdesk);
while (1)
@ -944,27 +858,31 @@ static void* remdesk_virtual_channel_client_thread(void* arg)
break;
}
if (!MessageQueue_Peek(remdesk->queue, &message, TRUE)) {
if (!MessageQueue_Peek(remdesk->queue, &message, TRUE))
{
WLog_ERR(TAG, "MessageQueue_Peek failed!");
error = ERROR_INTERNAL_ERROR;
break;
}
if (message.id == WMQ_QUIT)
break;
if (message.id == 0)
{
data = (wStream*) message.wParam;
if ((error = remdesk_process_receive(remdesk, data)))
{
WLog_ERR(TAG, "remdesk_process_receive failed with error %lu!", error);
WLog_ERR(TAG, "remdesk_process_receive failed with error %u!", error);
break;
}
}
}
if (error && remdesk->rdpcontext)
setChannelError(remdesk->rdpcontext, error, "remdesk_virtual_channel_client_thread reported an error");
setChannelError(remdesk->rdpcontext, error,
"remdesk_virtual_channel_client_thread reported an error");
ExitThread((DWORD)error);
return NULL;
@ -975,28 +893,24 @@ static void* remdesk_virtual_channel_client_thread(void* arg)
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT remdesk_virtual_channel_event_connected(remdeskPlugin* remdesk, LPVOID pData, UINT32 dataLength)
static UINT remdesk_virtual_channel_event_connected(remdeskPlugin* remdesk,
LPVOID pData, UINT32 dataLength)
{
UINT32 status;
UINT error;
status = remdesk->channelEntryPoints.pVirtualChannelOpen(remdesk->InitHandle,
&remdesk->OpenHandle, remdesk->channelDef.name, remdesk_virtual_channel_open_event);
status = remdesk->channelEntryPoints.pVirtualChannelOpenEx(remdesk->InitHandle,
&remdesk->OpenHandle, remdesk->channelDef.name,
remdesk_virtual_channel_open_event_ex);
if (status != CHANNEL_RC_OK)
{
WLog_ERR(TAG, "pVirtualChannelOpen failed with %s [%08X]",
WTSErrorToString(status), status);
WLog_ERR(TAG, "pVirtualChannelOpenEx failed with %s [%08X]",
WTSErrorToString(status), status);
return status;
}
if ((error = remdesk_add_open_handle_data(remdesk->OpenHandle, remdesk)))
{
WLog_ERR(TAG, "remdesk_add_open_handle_data failed with error %lu", error);
return error;
}
remdesk->queue = MessageQueue_New(NULL);
if (!remdesk->queue)
{
WLog_ERR(TAG, "MessageQueue_New failed!");
@ -1005,16 +919,18 @@ static UINT remdesk_virtual_channel_event_connected(remdeskPlugin* remdesk, LPVO
}
remdesk->thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) remdesk_virtual_channel_client_thread, (void*) remdesk, 0, NULL);
(LPTHREAD_START_ROUTINE) remdesk_virtual_channel_client_thread, (void*) remdesk,
0, NULL);
if (!remdesk->thread)
{
WLog_ERR(TAG, "CreateThread failed");
error = ERROR_INTERNAL_ERROR;
goto error_out;
}
return CHANNEL_RC_OK;
error_out:
remdesk_remove_open_handle_data(remdesk->OpenHandle);
MessageQueue_Free(remdesk->queue);
remdesk->queue = NULL;
return error;
@ -1029,53 +945,51 @@ static UINT remdesk_virtual_channel_event_disconnected(remdeskPlugin* remdesk)
{
UINT rc;
if (MessageQueue_PostQuit(remdesk->queue, 0) && (WaitForSingleObject(remdesk->thread, INFINITE) == WAIT_FAILED))
if (MessageQueue_PostQuit(remdesk->queue, 0)
&& (WaitForSingleObject(remdesk->thread, INFINITE) == WAIT_FAILED))
{
rc = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", rc);
WLog_ERR(TAG, "WaitForSingleObject failed with error %u", rc);
return rc;
}
MessageQueue_Free(remdesk->queue);
CloseHandle(remdesk->thread);
remdesk->queue = NULL;
remdesk->thread = NULL;
rc = remdesk->channelEntryPoints.pVirtualChannelCloseEx(remdesk->InitHandle, remdesk->OpenHandle);
rc = remdesk->channelEntryPoints.pVirtualChannelClose(remdesk->OpenHandle);
if (CHANNEL_RC_OK != rc)
{
WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08X]",
WTSErrorToString(rc), rc);
WLog_ERR(TAG, "pVirtualChannelCloseEx failed with %s [%08X]",
WTSErrorToString(rc), rc);
}
remdesk->OpenHandle = 0;
if (remdesk->data_in)
{
Stream_Free(remdesk->data_in, TRUE);
remdesk->data_in = NULL;
}
remdesk_remove_open_handle_data(remdesk->OpenHandle);
return rc;
}
static void remdesk_virtual_channel_event_terminated(remdeskPlugin* remdesk)
{
remdesk_remove_init_handle_data(remdesk->InitHandle);
remdesk->InitHandle = 0;
free(remdesk);
}
static VOID VCAPITYPE remdesk_virtual_channel_init_event(LPVOID pInitHandle,
UINT event, LPVOID pData,
UINT dataLength)
static VOID VCAPITYPE remdesk_virtual_channel_init_event_ex(LPVOID lpUserParam, LPVOID pInitHandle,
UINT event, LPVOID pData,
UINT dataLength)
{
remdeskPlugin* remdesk;
UINT error = CHANNEL_RC_OK;
remdeskPlugin* remdesk = (remdeskPlugin*) lpUserParam;
remdesk = (remdeskPlugin*) remdesk_get_init_handle_data(pInitHandle);
if (!remdesk)
if (!remdesk || (remdesk->InitHandle != pInitHandle))
{
WLog_ERR(TAG, "error no match");
return;
@ -1084,34 +998,44 @@ static VOID VCAPITYPE remdesk_virtual_channel_init_event(LPVOID pInitHandle,
switch (event)
{
case CHANNEL_EVENT_CONNECTED:
if ((error = remdesk_virtual_channel_event_connected(remdesk, pData, dataLength)))
WLog_ERR(TAG, "remdesk_virtual_channel_event_connected failed with error %lu", error);
if ((error = remdesk_virtual_channel_event_connected(remdesk, pData,
dataLength)))
WLog_ERR(TAG, "remdesk_virtual_channel_event_connected failed with error %u",
error);
break;
case CHANNEL_EVENT_DISCONNECTED:
if ((error = remdesk_virtual_channel_event_disconnected(remdesk)))
WLog_ERR(TAG, "remdesk_virtual_channel_event_disconnected failed with error %lu", error);
WLog_ERR(TAG,
"remdesk_virtual_channel_event_disconnected failed with error %u", error);
break;
case CHANNEL_EVENT_TERMINATED:
remdesk_virtual_channel_event_terminated(remdesk);
break;
}
if (error && remdesk->rdpcontext)
setChannelError(remdesk->rdpcontext, error, "remdesk_virtual_channel_init_event reported an error");
setChannelError(remdesk->rdpcontext, error,
"remdesk_virtual_channel_init_event reported an error");
}
/* remdesk is always built-in */
#define VirtualChannelEntry remdesk_VirtualChannelEntry
#define VirtualChannelEntryEx remdesk_VirtualChannelEntryEx
BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID pInitHandle)
{
UINT rc;
UINT error;
remdeskPlugin* remdesk;
RemdeskClientContext* context = NULL;
CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx;
CHANNEL_ENTRY_POINTS_FREERDP_EX* pEntryPointsEx;
if (!pEntryPoints)
{
return FALSE;
}
remdesk = (remdeskPlugin*) calloc(1, sizeof(remdeskPlugin));
@ -1122,21 +1046,19 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
}
remdesk->channelDef.options =
CHANNEL_OPTION_INITIALIZED |
CHANNEL_OPTION_ENCRYPT_RDP |
CHANNEL_OPTION_COMPRESS_RDP |
CHANNEL_OPTION_SHOW_PROTOCOL;
CHANNEL_OPTION_INITIALIZED |
CHANNEL_OPTION_ENCRYPT_RDP |
CHANNEL_OPTION_COMPRESS_RDP |
CHANNEL_OPTION_SHOW_PROTOCOL;
strcpy(remdesk->channelDef.name, "remdesk");
remdesk->Version = 2;
pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP_EX*) pEntryPoints;
pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints;
if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP)) &&
(pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER))
if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)) &&
(pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER))
{
context = (RemdeskClientContext*) calloc(1, sizeof(RemdeskClientContext));
if (!context)
{
WLog_ERR(TAG, "calloc failed!");
@ -1144,31 +1066,25 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
}
context->handle = (void*) remdesk;
*(pEntryPointsEx->ppInterface) = (void*) context;
remdesk->context = context;
remdesk->rdpcontext = pEntryPointsEx->context;
}
CopyMemory(&(remdesk->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP));
CopyMemory(&(remdesk->channelEntryPoints), pEntryPoints,
sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX));
remdesk->InitHandle = pInitHandle;
rc = remdesk->channelEntryPoints.pVirtualChannelInitEx(remdesk, context, pInitHandle,
&remdesk->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000,
remdesk_virtual_channel_init_event_ex);
rc = remdesk->channelEntryPoints.pVirtualChannelInit(&remdesk->InitHandle,
&remdesk->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, remdesk_virtual_channel_init_event);
if (CHANNEL_RC_OK != rc)
{
WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]",
WTSErrorToString(rc), rc);
WLog_ERR(TAG, "pVirtualChannelInitEx failed with %s [%08X]",
WTSErrorToString(rc), rc);
goto error_out;
}
remdesk->channelEntryPoints.pInterface = *(remdesk->channelEntryPoints.ppInterface);
remdesk->channelEntryPoints.ppInterface = &(remdesk->channelEntryPoints.pInterface);
if ((error = remdesk_add_init_handle_data(remdesk->InitHandle, (void*) remdesk)))
{
WLog_ERR(TAG, "remdesk_add_init_handle_data failed with error %lu!", error);
goto error_out;
}
remdesk->channelEntryPoints.pInterface = context;
return TRUE;
error_out:
free(remdesk);

View File

@ -41,7 +41,7 @@
struct remdesk_plugin
{
CHANNEL_DEF channelDef;
CHANNEL_ENTRY_POINTS_FREERDP channelEntryPoints;
CHANNEL_ENTRY_POINTS_FREERDP_EX channelEntryPoints;
RemdeskClientContext* context;

View File

@ -34,14 +34,13 @@
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT remdesk_virtual_channel_write(RemdeskServerContext* context, wStream* s)
static UINT remdesk_virtual_channel_write(RemdeskServerContext* context,
wStream* s)
{
BOOL status;
ULONG BytesWritten = 0;
status = WTSVirtualChannelWrite(context->priv->ChannelHandle,
(PCHAR) Stream_Buffer(s), Stream_Length(s), &BytesWritten);
(PCHAR) Stream_Buffer(s), Stream_Length(s), &BytesWritten);
return (status) ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR;
}
@ -50,7 +49,8 @@ static UINT remdesk_virtual_channel_write(RemdeskServerContext* context, wStream
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header)
static UINT remdesk_read_channel_header(wStream* s,
REMDESK_CHANNEL_HEADER* header)
{
int status;
UINT32 ChannelNameLen;
@ -73,7 +73,7 @@ static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* head
if ((ChannelNameLen % 2) != 0)
{
WLog_ERR(TAG, "(ChannelNameLen % 2) != 0!");
WLog_ERR(TAG, "(ChannelNameLen %% 2) != 0!");
return ERROR_INVALID_DATA;
}
@ -84,11 +84,9 @@ static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* head
}
ZeroMemory(header->ChannelName, sizeof(header->ChannelName));
pChannelName = (char*) header->ChannelName;
status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s),
ChannelNameLen / 2, &pChannelName, 32, NULL, NULL);
ChannelNameLen / 2, &pChannelName, 32, NULL, NULL);
Stream_Seek(s, ChannelNameLen);
if (status <= 0)
@ -105,12 +103,12 @@ static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* head
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT remdesk_write_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header)
static UINT remdesk_write_channel_header(wStream* s,
REMDESK_CHANNEL_HEADER* header)
{
int index;
UINT32 ChannelNameLen;
WCHAR ChannelNameW[32];
ZeroMemory(ChannelNameW, sizeof(ChannelNameW));
for (index = 0; index < 32; index++)
@ -119,12 +117,9 @@ static UINT remdesk_write_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* hea
}
ChannelNameLen = (strlen(header->ChannelName) + 1) * 2;
Stream_Write_UINT32(s, ChannelNameLen); /* ChannelNameLen (4 bytes) */
Stream_Write_UINT32(s, header->DataLength); /* DataLen (4 bytes) */
Stream_Write(s, ChannelNameW, ChannelNameLen); /* ChannelName (variable) */
return CHANNEL_RC_OK;
}
@ -136,11 +131,14 @@ static UINT remdesk_write_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* hea
static UINT remdesk_write_ctl_header(wStream* s, REMDESK_CTL_HEADER* ctlHeader)
{
UINT error;
if ((error = remdesk_write_channel_header(s, (REMDESK_CHANNEL_HEADER*) ctlHeader)))
if ((error = remdesk_write_channel_header(s,
(REMDESK_CHANNEL_HEADER*) ctlHeader)))
{
WLog_ERR(TAG, "remdesk_write_channel_header failed with error %lu!", error);
WLog_ERR(TAG, "remdesk_write_channel_header failed with error %u!", error);
return error;
}
Stream_Write_UINT32(s, ctlHeader->msgType); /* msgType (4 bytes) */
return CHANNEL_RC_OK;
}
@ -150,7 +148,8 @@ static UINT remdesk_write_ctl_header(wStream* s, REMDESK_CTL_HEADER* ctlHeader)
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, UINT32 msgType, UINT32 msgSize)
static UINT remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader,
UINT32 msgType, UINT32 msgSize)
{
ctlHeader->msgType = msgType;
strcpy(ctlHeader->ChannelName, REMDESK_CHANNEL_CTL_NAME);
@ -163,21 +162,23 @@ static UINT remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, UINT32 msg
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT remdesk_send_ctl_result_pdu(RemdeskServerContext* context, UINT32 result)
static UINT remdesk_send_ctl_result_pdu(RemdeskServerContext* context,
UINT32 result)
{
wStream* s;
REMDESK_CTL_RESULT_PDU pdu;
UINT error;
pdu.result = result;
if ((error = remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_RESULT, 4)))
if ((error = remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_RESULT,
4)))
{
WLog_ERR(TAG, "remdesk_prepare_ctl_header failed with error %lu!", error);
WLog_ERR(TAG, "remdesk_prepare_ctl_header failed with error %u!", error);
return error;
}
s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength);
if (!s)
{
WLog_ERR(TAG, "Stream_New failed!");
@ -186,20 +187,18 @@ static UINT remdesk_send_ctl_result_pdu(RemdeskServerContext* context, UINT32 re
if ((error = remdesk_write_ctl_header(s, &(pdu.ctlHeader))))
{
WLog_ERR(TAG, "remdesk_write_ctl_header failed with error %lu!", error);
WLog_ERR(TAG, "remdesk_write_ctl_header failed with error %u!", error);
goto out;
}
Stream_Write_UINT32(s, pdu.result); /* result (4 bytes) */
Stream_SealLength(s);
if ((error = remdesk_virtual_channel_write(context, s)))
WLog_ERR(TAG, "remdesk_virtual_channel_write failed with error %lu!", error);
WLog_ERR(TAG, "remdesk_virtual_channel_write failed with error %u!", error);
out:
Stream_Free(s, TRUE);
return error;
}
@ -214,16 +213,17 @@ static UINT remdesk_send_ctl_version_info_pdu(RemdeskServerContext* context)
REMDESK_CTL_VERSION_INFO_PDU pdu;
UINT error;
if ((error = remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_VERSIONINFO, 8)))
if ((error = remdesk_prepare_ctl_header(&(pdu.ctlHeader),
REMDESK_CTL_VERSIONINFO, 8)))
{
WLog_ERR(TAG, "remdesk_prepare_ctl_header failed with error %lu!", error);
WLog_ERR(TAG, "remdesk_prepare_ctl_header failed with error %u!", error);
return error;
}
pdu.versionMajor = 1;
pdu.versionMinor = 2;
s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength);
if (!s)
{
WLog_ERR(TAG, "Stream_New failed!");
@ -232,20 +232,19 @@ static UINT remdesk_send_ctl_version_info_pdu(RemdeskServerContext* context)
if ((error = remdesk_write_ctl_header(s, &(pdu.ctlHeader))))
{
WLog_ERR(TAG, "remdesk_write_ctl_header failed with error %lu!", error);
WLog_ERR(TAG, "remdesk_write_ctl_header failed with error %u!", error);
goto out;
}
Stream_Write_UINT32(s, pdu.versionMajor); /* versionMajor (4 bytes) */
Stream_Write_UINT32(s, pdu.versionMinor); /* versionMinor (4 bytes) */
Stream_SealLength(s);
if ((error = remdesk_virtual_channel_write(context, s)))
WLog_ERR(TAG, "remdesk_virtual_channel_write failed with error %lu!", error);
WLog_ERR(TAG, "remdesk_virtual_channel_write failed with error %u!", error);
out:
Stream_Free(s, TRUE);
return error;
}
@ -254,7 +253,8 @@ out:
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT remdesk_recv_ctl_version_info_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header)
static UINT remdesk_recv_ctl_version_info_pdu(RemdeskServerContext* context,
wStream* s, REMDESK_CHANNEL_HEADER* header)
{
UINT32 versionMajor;
UINT32 versionMinor;
@ -267,7 +267,6 @@ static UINT remdesk_recv_ctl_version_info_pdu(RemdeskServerContext* context, wSt
Stream_Read_UINT32(s, versionMajor); /* versionMajor (4 bytes) */
Stream_Read_UINT32(s, versionMinor); /* versionMinor (4 bytes) */
return CHANNEL_RC_OK;
}
@ -276,7 +275,8 @@ static UINT remdesk_recv_ctl_version_info_pdu(RemdeskServerContext* context, wSt
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT remdesk_recv_ctl_remote_control_desktop_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header)
static UINT remdesk_recv_ctl_remote_control_desktop_pdu(
RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header)
{
int status;
int cchStringW;
@ -286,9 +286,7 @@ static UINT remdesk_recv_ctl_remote_control_desktop_pdu(RemdeskServerContext* co
WCHAR* raConnectionStringW = NULL;
REMDESK_CTL_REMOTE_CONTROL_DESKTOP_PDU pdu;
UINT error;
msgLength = header->DataLength - 4;
pStringW = (WCHAR*) Stream_Pointer(s);
raConnectionStringW = pStringW;
cchStringW = 0;
@ -304,11 +302,9 @@ static UINT remdesk_recv_ctl_remote_control_desktop_pdu(RemdeskServerContext* co
cchStringW++;
cbRaConnectionStringW = cchStringW * 2;
pdu.raConnectionString = NULL;
status = ConvertFromUnicode(CP_UTF8, 0, raConnectionStringW,
cbRaConnectionStringW / 2, &pdu.raConnectionString, 0, NULL, NULL);
cbRaConnectionStringW / 2, &pdu.raConnectionString, 0, NULL, NULL);
if (status <= 0)
{
@ -317,11 +313,11 @@ static UINT remdesk_recv_ctl_remote_control_desktop_pdu(RemdeskServerContext* co
}
WLog_INFO(TAG, "RaConnectionString: %s",
pdu.raConnectionString);
pdu.raConnectionString);
free(pdu.raConnectionString);
if ((error = remdesk_send_ctl_result_pdu(context, 0)))
WLog_ERR(TAG, "remdesk_send_ctl_result_pdu failed with error %lu!", error);
WLog_ERR(TAG, "remdesk_send_ctl_result_pdu failed with error %u!", error);
return error;
}
@ -331,7 +327,8 @@ static UINT remdesk_recv_ctl_remote_control_desktop_pdu(RemdeskServerContext* co
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT remdesk_recv_ctl_authenticate_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header)
static UINT remdesk_recv_ctl_authenticate_pdu(RemdeskServerContext* context,
wStream* s, REMDESK_CHANNEL_HEADER* header)
{
int status;
int cchStringW;
@ -342,9 +339,7 @@ static UINT remdesk_recv_ctl_authenticate_pdu(RemdeskServerContext* context, wSt
int cbRaConnectionStringW = 0;
WCHAR* raConnectionStringW = NULL;
REMDESK_CTL_AUTHENTICATE_PDU pdu;
msgLength = header->DataLength - 4;
pStringW = (WCHAR*) Stream_Pointer(s);
raConnectionStringW = pStringW;
cchStringW = 0;
@ -360,7 +355,6 @@ static UINT remdesk_recv_ctl_authenticate_pdu(RemdeskServerContext* context, wSt
cchStringW++;
cbRaConnectionStringW = cchStringW * 2;
pStringW += cchStringW;
expertBlobW = pStringW;
cchStringW = 0;
@ -376,11 +370,9 @@ static UINT remdesk_recv_ctl_authenticate_pdu(RemdeskServerContext* context, wSt
cchStringW++;
cbExpertBlobW = cchStringW * 2;
pdu.raConnectionString = NULL;
status = ConvertFromUnicode(CP_UTF8, 0, raConnectionStringW,
cbRaConnectionStringW / 2, &pdu.raConnectionString, 0, NULL, NULL);
cbRaConnectionStringW / 2, &pdu.raConnectionString, 0, NULL, NULL);
if (status <= 0)
{
@ -389,9 +381,8 @@ static UINT remdesk_recv_ctl_authenticate_pdu(RemdeskServerContext* context, wSt
}
pdu.expertBlob = NULL;
status = ConvertFromUnicode(CP_UTF8, 0, expertBlobW,
cbExpertBlobW / 2, &pdu.expertBlob, 0, NULL, NULL);
cbExpertBlobW / 2, &pdu.expertBlob, 0, NULL, NULL);
if (status <= 0)
{
@ -401,10 +392,9 @@ static UINT remdesk_recv_ctl_authenticate_pdu(RemdeskServerContext* context, wSt
}
WLog_INFO(TAG, "RaConnectionString: %s ExpertBlob: %s",
pdu.raConnectionString, pdu.expertBlob);
pdu.raConnectionString, pdu.expertBlob);
free(pdu.raConnectionString);
free(pdu.expertBlob);
return CHANNEL_RC_OK;
}
@ -413,7 +403,8 @@ static UINT remdesk_recv_ctl_authenticate_pdu(RemdeskServerContext* context, wSt
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT remdesk_recv_ctl_verify_password_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header)
static UINT remdesk_recv_ctl_verify_password_pdu(RemdeskServerContext* context,
wStream* s, REMDESK_CHANNEL_HEADER* header)
{
int status;
int cbExpertBlobW = 0;
@ -430,8 +421,8 @@ static UINT remdesk_recv_ctl_verify_password_pdu(RemdeskServerContext* context,
pdu.expertBlob = NULL;
expertBlobW = (WCHAR*) Stream_Pointer(s);
cbExpertBlobW = header->DataLength - 4;
status = ConvertFromUnicode(CP_UTF8, 0, expertBlobW, cbExpertBlobW / 2, &pdu.expertBlob, 0, NULL, NULL);
status = ConvertFromUnicode(CP_UTF8, 0, expertBlobW, cbExpertBlobW / 2,
&pdu.expertBlob, 0, NULL, NULL);
if (status <= 0)
{
@ -440,8 +431,9 @@ static UINT remdesk_recv_ctl_verify_password_pdu(RemdeskServerContext* context,
}
WLog_INFO(TAG, "ExpertBlob: %s", pdu.expertBlob);
if ((error = remdesk_send_ctl_result_pdu(context, 0)))
WLog_ERR(TAG, "remdesk_send_ctl_result_pdu failed with error %lu!", error);
WLog_ERR(TAG, "remdesk_send_ctl_result_pdu failed with error %u!", error);
return error;
}
@ -451,7 +443,8 @@ static UINT remdesk_recv_ctl_verify_password_pdu(RemdeskServerContext* context,
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT remdesk_recv_ctl_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header)
static UINT remdesk_recv_ctl_pdu(RemdeskServerContext* context, wStream* s,
REMDESK_CHANNEL_HEADER* header)
{
UINT error = CHANNEL_RC_OK;
UINT32 msgType = 0;
@ -470,28 +463,34 @@ static UINT remdesk_recv_ctl_pdu(RemdeskServerContext* context, wStream* s, REMD
case REMDESK_CTL_REMOTE_CONTROL_DESKTOP:
if ((error = remdesk_recv_ctl_remote_control_desktop_pdu(context, s, header)))
{
WLog_ERR(TAG, "remdesk_recv_ctl_remote_control_desktop_pdu failed with error %lu!", error);
WLog_ERR(TAG,
"remdesk_recv_ctl_remote_control_desktop_pdu failed with error %u!", error);
return error;
}
break;
case REMDESK_CTL_AUTHENTICATE:
if ((error = remdesk_recv_ctl_authenticate_pdu(context, s, header)))
{
WLog_ERR(TAG, "remdesk_recv_ctl_authenticate_pdu failed with error %lu!", error);
WLog_ERR(TAG, "remdesk_recv_ctl_authenticate_pdu failed with error %u!",
error);
return error;
}
break;
case REMDESK_CTL_DISCONNECT:
break;
case REMDESK_CTL_VERSIONINFO:
if((error = remdesk_recv_ctl_version_info_pdu(context, s, header)))
if ((error = remdesk_recv_ctl_version_info_pdu(context, s, header)))
{
WLog_ERR(TAG, "remdesk_recv_ctl_version_info_pdu failed with error %lu!", error);
WLog_ERR(TAG, "remdesk_recv_ctl_version_info_pdu failed with error %u!",
error);
return error;
}
break;
case REMDESK_CTL_ISCONNECTED:
@ -500,9 +499,11 @@ static UINT remdesk_recv_ctl_pdu(RemdeskServerContext* context, wStream* s, REMD
case REMDESK_CTL_VERIFY_PASSWORD:
if ((error = remdesk_recv_ctl_verify_password_pdu(context, s, header)))
{
WLog_ERR(TAG, "remdesk_recv_ctl_verify_password_pdu failed with error %lu!", error);
WLog_ERR(TAG, "remdesk_recv_ctl_verify_password_pdu failed with error %u!",
error);
return error;
}
break;
case REMDESK_CTL_EXPERT_ON_VISTA:
@ -531,11 +532,11 @@ static UINT remdesk_recv_ctl_pdu(RemdeskServerContext* context, wStream* s, REMD
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT remdesk_server_receive_pdu(RemdeskServerContext* context, wStream* s)
static UINT remdesk_server_receive_pdu(RemdeskServerContext* context,
wStream* s)
{
UINT error = CHANNEL_RC_OK;
REMDESK_CHANNEL_HEADER header;
#if 0
WLog_INFO(TAG, "RemdeskReceive: %d", Stream_GetRemainingLength(s));
winpr_HexDump(Stream_Pointer(s), Stream_GetRemainingLength(s));
@ -543,42 +544,35 @@ static UINT remdesk_server_receive_pdu(RemdeskServerContext* context, wStream* s
if ((error = remdesk_read_channel_header(s, &header)))
{
WLog_ERR(TAG, "remdesk_read_channel_header failed with error %lu!", error);
WLog_ERR(TAG, "remdesk_read_channel_header failed with error %u!", error);
return error;
}
if (strcmp(header.ChannelName, "RC_CTL") == 0)
{
if ((error = remdesk_recv_ctl_pdu(context, s, &header)))
{
WLog_ERR(TAG, "remdesk_recv_ctl_pdu failed with error %lu!", error);
WLog_ERR(TAG, "remdesk_recv_ctl_pdu failed with error %u!", error);
return error;
}
}
else if (strcmp(header.ChannelName, "70") == 0)
{
}
else if (strcmp(header.ChannelName, "71") == 0)
{
}
else if (strcmp(header.ChannelName, ".") == 0)
{
}
else if (strcmp(header.ChannelName, "1000.") == 0)
{
}
else if (strcmp(header.ChannelName, "RA_FX") == 0)
{
}
else
{
}
return error;
@ -597,14 +591,13 @@ static void* remdesk_server_thread(void* arg)
DWORD BytesReturned;
RemdeskServerContext* context;
UINT error;
context = (RemdeskServerContext*) arg;
buffer = NULL;
BytesReturned = 0;
ChannelEvent = NULL;
s = Stream_New(NULL, 4096);
if (!s)
{
WLog_ERR(TAG, "Stream_New failed!");
@ -612,7 +605,8 @@ static void* remdesk_server_thread(void* arg)
goto out;
}
if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE)
if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle,
&buffer, &BytesReturned) == TRUE)
{
if (BytesReturned == sizeof(HANDLE))
CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE));
@ -632,7 +626,8 @@ static void* remdesk_server_thread(void* arg)
if ((error = remdesk_send_ctl_version_info_pdu(context)))
{
WLog_ERR(TAG, "remdesk_send_ctl_version_info_pdu failed with error %lu!", error);
WLog_ERR(TAG, "remdesk_send_ctl_version_info_pdu failed with error %u!",
error);
goto out;
}
@ -640,22 +635,21 @@ static void* remdesk_server_thread(void* arg)
{
status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error);
break;
}
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u", error);
break;
}
status = WaitForSingleObject(context->priv->StopEvent, 0);
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error);
break;
}
status = WaitForSingleObject(context->priv->StopEvent, 0);
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error);
break;
}
if (status == WAIT_OBJECT_0)
{
@ -663,7 +657,7 @@ static void* remdesk_server_thread(void* arg)
}
if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0,
(PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned))
(PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned))
{
if (BytesReturned)
Stream_Seek(s, BytesReturned);
@ -687,11 +681,13 @@ static void* remdesk_server_thread(void* arg)
{
Stream_SealLength(s);
Stream_SetPosition(s, 0);
if ((error = remdesk_server_receive_pdu(context, s)))
{
WLog_ERR(TAG, "remdesk_server_receive_pdu failed with error %lu!", error);
WLog_ERR(TAG, "remdesk_server_receive_pdu failed with error %u!", error);
break;
}
Stream_SetPosition(s, 0);
}
}
@ -699,8 +695,10 @@ static void* remdesk_server_thread(void* arg)
Stream_Free(s, TRUE);
out:
if (error && context->rdpcontext)
setChannelError(context->rdpcontext, error, "remdesk_server_thread reported an error");
setChannelError(context->rdpcontext, error,
"remdesk_server_thread reported an error");
ExitThread((DWORD)error);
return NULL;
@ -713,7 +711,8 @@ out:
*/
static UINT remdesk_server_start(RemdeskServerContext* context)
{
context->priv->ChannelHandle = WTSVirtualChannelOpen(context->vcm, WTS_CURRENT_SESSION, "remdesk");
context->priv->ChannelHandle = WTSVirtualChannelOpen(context->vcm,
WTS_CURRENT_SESSION, "remdesk");
if (!context->priv->ChannelHandle)
{
@ -728,7 +727,7 @@ static UINT remdesk_server_start(RemdeskServerContext* context)
}
if (!(context->priv->Thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) remdesk_server_thread, (void*) context, 0, NULL)))
(LPTHREAD_START_ROUTINE) remdesk_server_thread, (void*) context, 0, NULL)))
{
WLog_ERR(TAG, "CreateThread failed!");
CloseHandle(context->priv->StopEvent);
@ -746,34 +745,30 @@ static UINT remdesk_server_start(RemdeskServerContext* context)
*/
static UINT remdesk_server_stop(RemdeskServerContext* context)
{
UINT error;
UINT error;
SetEvent(context->priv->StopEvent);
if (WaitForSingleObject(context->priv->Thread, INFINITE) == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
return error;
}
CloseHandle(context->priv->Thread);
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error);
return error;
}
CloseHandle(context->priv->Thread);
return CHANNEL_RC_OK;
}
RemdeskServerContext* remdesk_server_context_new(HANDLE vcm)
{
RemdeskServerContext* context;
context = (RemdeskServerContext*) calloc(1, sizeof(RemdeskServerContext));
if (context)
{
context->vcm = vcm;
context->Start = remdesk_server_start;
context->Stop = remdesk_server_stop;
context->priv = (RemdeskServerPrivate*) calloc(1, sizeof(RemdeskServerPrivate));
if (!context->priv)
@ -781,6 +776,7 @@ RemdeskServerContext* remdesk_server_context_new(HANDLE vcm)
free(context);
return NULL;
}
context->priv->Version = 1;
}

View File

@ -27,7 +27,7 @@ add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE
target_link_libraries(${MODULE_NAME} winpr freerdp)
if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS)
if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS)
install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols)
endif()

View File

@ -47,7 +47,7 @@
/* TODO: all #ifdef __linux__ could be removed once only some generic
* functions will be used. Replace CommReadFile by ReadFile,
* CommWriteFile by WriteFile etc.. */
#if defined __linux__ && !defined ANDROID
#if defined __linux__ && !defined ANDROID
#define MAX_IRP_THREADS 5
@ -65,7 +65,7 @@ struct _SERIAL_DEVICE
wMessageQueue* MainIrpQueue;
/* one thread per pending IRP and indexed according their CompletionId */
wListDictionary *IrpThreads;
wListDictionary* IrpThreads;
UINT32 IrpThreadToBeTerminatedCount;
CRITICAL_SECTION TerminatingIrpThreadsLock;
rdpContext* rdpcontext;
@ -75,15 +75,14 @@ typedef struct _IRP_THREAD_DATA IRP_THREAD_DATA;
struct _IRP_THREAD_DATA
{
SERIAL_DEVICE *serial;
IRP *irp;
SERIAL_DEVICE* serial;
IRP* irp;
};
static UINT32 _GetLastErrorToIoStatus(SERIAL_DEVICE* serial)
{
/* http://msdn.microsoft.com/en-us/library/ff547466%28v=vs.85%29.aspx#generic_status_values_for_serial_device_control_requests */
switch(GetLastError())
switch (GetLastError())
{
case ERROR_BAD_DEVICE:
return STATUS_INVALID_DEVICE_REQUEST;
@ -117,11 +116,11 @@ static UINT32 _GetLastErrorToIoStatus(SERIAL_DEVICE* serial)
case ERROR_TIMEOUT:
return STATUS_TIMEOUT;
/* no default */
/* no default */
}
WLog_Print(serial->log, WLOG_DEBUG, "unexpected last-error: 0x%lx", GetLastError());
WLog_Print(serial->log, WLOG_DEBUG, "unexpected last-error: 0x%lx",
GetLastError());
return STATUS_UNSUCCESSFUL;
}
@ -131,19 +130,16 @@ static void serial_process_irp_create(SERIAL_DEVICE* serial, IRP* irp)
DWORD SharedAccess;
DWORD CreateDisposition;
UINT32 PathLength;
Stream_Read_UINT32(irp->input, DesiredAccess); /* DesiredAccess (4 bytes) */
Stream_Seek_UINT64(irp->input); /* AllocationSize (8 bytes) */
Stream_Seek_UINT32(irp->input); /* FileAttributes (4 bytes) */
Stream_Read_UINT32(irp->input, SharedAccess); /* SharedAccess (4 bytes) */
Stream_Read_UINT32(irp->input, CreateDisposition); /* CreateDisposition (4 bytes) */
Stream_Read_UINT32(irp->input,
CreateDisposition); /* CreateDisposition (4 bytes) */
Stream_Seek_UINT32(irp->input); /* CreateOptions (4 bytes) */
Stream_Read_UINT32(irp->input, PathLength); /* PathLength (4 bytes) */
Stream_Seek(irp->input, PathLength); /* Path (variable) */
assert(PathLength == 0); /* MS-RDPESP 2.2.2.2 */
#ifndef _WIN32
/* Windows 2012 server sends on a first call :
* DesiredAccess = 0x00100080: SYNCHRONIZE | FILE_READ_ATTRIBUTES
@ -160,35 +156,32 @@ static void serial_process_irp_create(SERIAL_DEVICE* serial, IRP* irp)
* assert(CreateDisposition == OPEN_EXISTING);
*
*/
WLog_Print(serial->log, WLOG_DEBUG, "DesiredAccess: 0x%lX, SharedAccess: 0x%lX, CreateDisposition: 0x%lX", DesiredAccess, SharedAccess, CreateDisposition);
WLog_Print(serial->log, WLOG_DEBUG,
"DesiredAccess: 0x%lX, SharedAccess: 0x%lX, CreateDisposition: 0x%lX",
DesiredAccess, SharedAccess, CreateDisposition);
/* FIXME: As of today only the flags below are supported by CommCreateFileA: */
DesiredAccess = GENERIC_READ | GENERIC_WRITE;
SharedAccess = 0;
CreateDisposition = OPEN_EXISTING;
#endif
serial->hComm = CreateFile(serial->device.name,
DesiredAccess,
SharedAccess,
NULL, /* SecurityAttributes */
CreateDisposition,
0, /* FlagsAndAttributes */
NULL); /* TemplateFile */
DesiredAccess,
SharedAccess,
NULL, /* SecurityAttributes */
CreateDisposition,
0, /* FlagsAndAttributes */
NULL); /* TemplateFile */
if (!serial->hComm || (serial->hComm == INVALID_HANDLE_VALUE))
{
WLog_Print(serial->log, WLOG_WARN, "CreateFile failure: %s last-error: 0x%lX\n", serial->device.name, GetLastError());
WLog_Print(serial->log, WLOG_WARN, "CreateFile failure: %s last-error: 0x%lX\n",
serial->device.name, GetLastError());
irp->IoStatus = STATUS_UNSUCCESSFUL;
goto error_handle;
}
_comm_setServerSerialDriver(serial->hComm, serial->ServerSerialDriverId);
_comm_set_permissive(serial->hComm, serial->permissive);
/* NOTE: binary mode/raw mode required for the redirection. On
* Linux, CommCreateFileA forces this setting.
*/
@ -197,15 +190,13 @@ static void serial_process_irp_create(SERIAL_DEVICE* serial, IRP* irp)
/* GetCommState(serial->hComm, &dcb); */
/* dcb.fBinary = TRUE; */
/* SetCommState(serial->hComm, &dcb); */
assert(irp->FileId == 0);
irp->FileId = irp->devman->id_sequence++; /* FIXME: why not ((WINPR_COMM*)hComm)->fd? */
irp->FileId =
irp->devman->id_sequence++; /* FIXME: why not ((WINPR_COMM*)hComm)->fd? */
irp->IoStatus = STATUS_SUCCESS;
WLog_Print(serial->log, WLOG_DEBUG, "%s (DeviceId: %d, FileId: %d) created.", serial->device.name, irp->device->id, irp->FileId);
error_handle:
WLog_Print(serial->log, WLOG_DEBUG, "%s (DeviceId: %d, FileId: %d) created.",
serial->device.name, irp->device->id, irp->FileId);
error_handle:
Stream_Write_UINT32(irp->output, irp->FileId); /* FileId (4 bytes) */
Stream_Write_UINT8(irp->output, 0); /* Information (1 byte) */
}
@ -216,17 +207,17 @@ static void serial_process_irp_close(SERIAL_DEVICE* serial, IRP* irp)
if (!CloseHandle(serial->hComm))
{
WLog_Print(serial->log, WLOG_WARN, "CloseHandle failure: %s (%d) closed.", serial->device.name, irp->device->id);
WLog_Print(serial->log, WLOG_WARN, "CloseHandle failure: %s (%d) closed.",
serial->device.name, irp->device->id);
irp->IoStatus = STATUS_UNSUCCESSFUL;
goto error_handle;
}
WLog_Print(serial->log, WLOG_DEBUG, "%s (DeviceId: %d, FileId: %d) closed.", serial->device.name, irp->device->id, irp->FileId);
WLog_Print(serial->log, WLOG_DEBUG, "%s (DeviceId: %d, FileId: %d) closed.",
serial->device.name, irp->device->id, irp->FileId);
serial->hComm = NULL;
irp->IoStatus = STATUS_SUCCESS;
error_handle:
error_handle:
Stream_Zero(irp->output, 5); /* Padding (5 bytes) */
}
@ -241,26 +232,22 @@ static UINT serial_process_irp_read(SERIAL_DEVICE* serial, IRP* irp)
UINT64 Offset;
BYTE* buffer = NULL;
DWORD nbRead = 0;
Stream_Read_UINT32(irp->input, Length); /* Length (4 bytes) */
Stream_Read_UINT64(irp->input, Offset); /* Offset (8 bytes) */
Stream_Seek(irp->input, 20); /* Padding (20 bytes) */
buffer = (BYTE*)calloc(Length, sizeof(BYTE));
if (buffer == NULL)
{
irp->IoStatus = STATUS_NO_MEMORY;
goto error_handle;
}
/* MS-RDPESP 3.2.5.1.4: If the Offset field is not set to 0, the value MUST be ignored
* assert(Offset == 0);
*/
WLog_Print(serial->log, WLOG_DEBUG, "reading %d bytes from %s", Length, serial->device.name);
WLog_Print(serial->log, WLOG_DEBUG, "reading %d bytes from %s", Length,
serial->device.name);
/* FIXME: CommReadFile to be replaced by ReadFile */
if (CommReadFile(serial->hComm, buffer, Length, &nbRead, NULL))
@ -269,15 +256,15 @@ static UINT serial_process_irp_read(SERIAL_DEVICE* serial, IRP* irp)
}
else
{
WLog_Print(serial->log, WLOG_DEBUG, "read failure to %s, nbRead=%ld, last-error: 0x%lX", serial->device.name, nbRead, GetLastError());
WLog_Print(serial->log, WLOG_DEBUG,
"read failure to %s, nbRead=%ld, last-error: 0x%lX", serial->device.name,
nbRead, GetLastError());
irp->IoStatus = _GetLastErrorToIoStatus(serial);
}
WLog_Print(serial->log, WLOG_DEBUG, "%lu bytes read from %s", nbRead, serial->device.name);
error_handle:
WLog_Print(serial->log, WLOG_DEBUG, "%lu bytes read from %s", nbRead,
serial->device.name);
error_handle:
Stream_Write_UINT32(irp->output, nbRead); /* Length (4 bytes) */
if (nbRead > 0)
@ -288,6 +275,7 @@ static UINT serial_process_irp_read(SERIAL_DEVICE* serial, IRP* irp)
free(buffer);
return CHANNEL_RC_NO_MEMORY;
}
Stream_Write(irp->output, buffer, nbRead); /* ReadData */
}
@ -300,34 +288,34 @@ static void serial_process_irp_write(SERIAL_DEVICE* serial, IRP* irp)
UINT32 Length;
UINT64 Offset;
DWORD nbWritten = 0;
Stream_Read_UINT32(irp->input, Length); /* Length (4 bytes) */
Stream_Read_UINT64(irp->input, Offset); /* Offset (8 bytes) */
Stream_Seek(irp->input, 20); /* Padding (20 bytes) */
/* MS-RDPESP 3.2.5.1.5: The Offset field is ignored
* assert(Offset == 0);
*
* Using a serial printer, noticed though this field could be
* set.
*/
WLog_Print(serial->log, WLOG_DEBUG, "writing %d bytes to %s", Length, serial->device.name);
WLog_Print(serial->log, WLOG_DEBUG, "writing %d bytes to %s", Length,
serial->device.name);
/* FIXME: CommWriteFile to be replaced by WriteFile */
if (CommWriteFile(serial->hComm, Stream_Pointer(irp->input), Length, &nbWritten, NULL))
if (CommWriteFile(serial->hComm, Stream_Pointer(irp->input), Length, &nbWritten,
NULL))
{
irp->IoStatus = STATUS_SUCCESS;
}
else
{
WLog_Print(serial->log, WLOG_DEBUG, "write failure to %s, nbWritten=%ld, last-error: 0x%lX", serial->device.name, nbWritten, GetLastError());
WLog_Print(serial->log, WLOG_DEBUG,
"write failure to %s, nbWritten=%ld, last-error: 0x%lX", serial->device.name,
nbWritten, GetLastError());
irp->IoStatus = _GetLastErrorToIoStatus(serial);
}
WLog_Print(serial->log, WLOG_DEBUG, "%lu bytes written to %s", nbWritten, serial->device.name);
WLog_Print(serial->log, WLOG_DEBUG, "%lu bytes written to %s", (unsigned long) nbWritten,
serial->device.name);
Stream_Write_UINT32(irp->output, nbWritten); /* Length (4 bytes) */
Stream_Write_UINT8(irp->output, 0); /* Padding (1 byte) */
}
@ -346,13 +334,14 @@ static UINT serial_process_irp_device_control(SERIAL_DEVICE* serial, IRP* irp)
UINT32 OutputBufferLength;
BYTE* OutputBuffer = NULL;
DWORD BytesReturned = 0;
Stream_Read_UINT32(irp->input, OutputBufferLength); /* OutputBufferLength (4 bytes) */
Stream_Read_UINT32(irp->input, InputBufferLength); /* InputBufferLength (4 bytes) */
Stream_Read_UINT32(irp->input,
OutputBufferLength); /* OutputBufferLength (4 bytes) */
Stream_Read_UINT32(irp->input,
InputBufferLength); /* InputBufferLength (4 bytes) */
Stream_Read_UINT32(irp->input, IoControlCode); /* IoControlCode (4 bytes) */
Stream_Seek(irp->input, 20); /* Padding (20 bytes) */
OutputBuffer = (BYTE*)calloc(OutputBufferLength, sizeof(BYTE));
if (OutputBuffer == NULL)
{
irp->IoStatus = STATUS_NO_MEMORY;
@ -360,6 +349,7 @@ static UINT serial_process_irp_device_control(SERIAL_DEVICE* serial, IRP* irp)
}
InputBuffer = (BYTE*)calloc(InputBufferLength, sizeof(BYTE));
if (InputBuffer == NULL)
{
irp->IoStatus = STATUS_NO_MEMORY;
@ -367,32 +357,32 @@ static UINT serial_process_irp_device_control(SERIAL_DEVICE* serial, IRP* irp)
}
Stream_Read(irp->input, InputBuffer, InputBufferLength);
WLog_Print(serial->log, WLOG_DEBUG, "CommDeviceIoControl: CompletionId=%d, IoControlCode=[0x%X] %s", irp->CompletionId, IoControlCode, _comm_serial_ioctl_name(IoControlCode));
WLog_Print(serial->log, WLOG_DEBUG,
"CommDeviceIoControl: CompletionId=%d, IoControlCode=[0x%X] %s",
irp->CompletionId, IoControlCode, _comm_serial_ioctl_name(IoControlCode));
/* FIXME: CommDeviceIoControl to be replaced by DeviceIoControl() */
if (CommDeviceIoControl(serial->hComm, IoControlCode, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, &BytesReturned, NULL))
if (CommDeviceIoControl(serial->hComm, IoControlCode, InputBuffer,
InputBufferLength, OutputBuffer, OutputBufferLength, &BytesReturned, NULL))
{
/* WLog_Print(serial->log, WLOG_DEBUG, "CommDeviceIoControl: CompletionId=%d, IoControlCode=[0x%X] %s done", irp->CompletionId, IoControlCode, _comm_serial_ioctl_name(IoControlCode)); */
irp->IoStatus = STATUS_SUCCESS;
}
else
{
WLog_Print(serial->log, WLOG_DEBUG, "CommDeviceIoControl failure: IoControlCode=[0x%X] %s, last-error: 0x%lX",
IoControlCode, _comm_serial_ioctl_name(IoControlCode), GetLastError());
WLog_Print(serial->log, WLOG_DEBUG,
"CommDeviceIoControl failure: IoControlCode=[0x%X] %s, last-error: 0x%lX",
IoControlCode, _comm_serial_ioctl_name(IoControlCode), GetLastError());
irp->IoStatus = _GetLastErrorToIoStatus(serial);
}
error_handle:
error_handle:
/* FIXME: find out whether it's required or not to get
* BytesReturned == OutputBufferLength when
* CommDeviceIoControl returns FALSE */
assert(OutputBufferLength == BytesReturned);
Stream_Write_UINT32(irp->output, BytesReturned); /* OutputBufferLength (4 bytes) */
Stream_Write_UINT32(irp->output,
BytesReturned); /* OutputBufferLength (4 bytes) */
if (BytesReturned > 0)
{
@ -406,6 +396,7 @@ static UINT serial_process_irp_device_control(SERIAL_DEVICE* serial, IRP* irp)
Stream_Write(irp->output, OutputBuffer, BytesReturned); /* OutputBuffer */
}
/* FIXME: Why at least Windows 2008R2 gets lost with this
* extra byte and likely on a IOCTL_SERIAL_SET_BAUD_RATE? The
* extra byte is well required according MS-RDPEFS
@ -414,7 +405,6 @@ static UINT serial_process_irp_device_control(SERIAL_DEVICE* serial, IRP* irp)
/* { */
/* Stream_Write_UINT8(irp->output, 0); /\* Padding (1 byte) *\/ */
/* } */
free(InputBuffer);
free(OutputBuffer);
return CHANNEL_RC_OK;
@ -428,8 +418,9 @@ static UINT serial_process_irp_device_control(SERIAL_DEVICE* serial, IRP* irp)
static UINT serial_process_irp(SERIAL_DEVICE* serial, IRP* irp)
{
UINT error = CHANNEL_RC_OK;
WLog_Print(serial->log, WLOG_DEBUG, "IRP MajorFunction: 0x%04X MinorFunction: 0x%04X\n",
irp->MajorFunction, irp->MinorFunction);
WLog_Print(serial->log, WLOG_DEBUG,
"IRP MajorFunction: 0x%04X MinorFunction: 0x%04X\n",
irp->MajorFunction, irp->MinorFunction);
switch (irp->MajorFunction)
{
@ -443,7 +434,8 @@ static UINT serial_process_irp(SERIAL_DEVICE* serial, IRP* irp)
case IRP_MJ_READ:
if ((error = serial_process_irp_read(serial, irp)))
WLog_ERR(TAG, "serial_process_irp_read failed with error %lu!", error);
WLog_ERR(TAG, "serial_process_irp_read failed with error %u!", error);
break;
case IRP_MJ_WRITE:
@ -452,58 +444,57 @@ static UINT serial_process_irp(SERIAL_DEVICE* serial, IRP* irp)
case IRP_MJ_DEVICE_CONTROL:
if ((error = serial_process_irp_device_control(serial, irp)))
WLog_ERR(TAG, "serial_process_irp_device_control failed with error %lu!", error);
WLog_ERR(TAG, "serial_process_irp_device_control failed with error %u!",
error);
break;
default:
irp->IoStatus = STATUS_NOT_SUPPORTED;
break;
}
return error;
}
static void* irp_thread_func(void* arg)
{
IRP_THREAD_DATA *data = (IRP_THREAD_DATA*)arg;
IRP_THREAD_DATA* data = (IRP_THREAD_DATA*)arg;
UINT error;
/* blocks until the end of the request */
if ((error = serial_process_irp(data->serial, data->irp)))
{
WLog_ERR(TAG, "serial_process_irp failed with error %lu", error);
WLog_ERR(TAG, "serial_process_irp failed with error %u", error);
goto error_out;
}
EnterCriticalSection(&data->serial->TerminatingIrpThreadsLock);
data->serial->IrpThreadToBeTerminatedCount++;
error = data->irp->Complete(data->irp);
LeaveCriticalSection(&data->serial->TerminatingIrpThreadsLock);
error_out:
if (error && data->serial->rdpcontext)
setChannelError(data->serial->rdpcontext, error, "irp_thread_func reported an error");
setChannelError(data->serial->rdpcontext, error,
"irp_thread_func reported an error");
/* NB: At this point, the server might already being reusing
* the CompletionId whereas the thread is not yet
* terminated */
free(data);
ExitThread((DWORD)error);
return NULL;
}
static void create_irp_thread(SERIAL_DEVICE *serial, IRP *irp)
static void create_irp_thread(SERIAL_DEVICE* serial, IRP* irp)
{
IRP_THREAD_DATA *data = NULL;
IRP_THREAD_DATA* data = NULL;
HANDLE irpThread;
HANDLE previousIrpThread;
uintptr_t key;
/* for a test/debug purpose, uncomment the code below to get a
* single thread for all IRPs. NB: two IRPs could not be
* processed at the same time, typically two concurent
@ -511,65 +502,57 @@ static void create_irp_thread(SERIAL_DEVICE *serial, IRP *irp)
/* serial_process_irp(serial, irp); */
/* irp->Complete(irp); */
/* return; */
/* NOTE: for good or bad, this implementation relies on the
* server to avoid a flooding of requests. see also _purge().
*/
EnterCriticalSection(&serial->TerminatingIrpThreadsLock);
while (serial->IrpThreadToBeTerminatedCount > 0)
{
/* Cleaning up termitating and pending irp
* threads. See also: irp_thread_func() */
HANDLE irpThread;
ULONG_PTR *ids;
ULONG_PTR* ids;
int i, nbIds;
nbIds = ListDictionary_GetKeys(serial->IrpThreads, &ids);
for (i=0; i<nbIds; i++)
for (i = 0; i < nbIds; i++)
{
/* Checking if ids[i] is terminating or pending */
DWORD waitResult;
ULONG_PTR id = ids[i];
irpThread = ListDictionary_GetItemValue(serial->IrpThreads, (void*)id);
/* FIXME: not quite sure a zero timeout is a good thing to check whether a thread is stil alived or not */
waitResult = WaitForSingleObject(irpThread, 0);
if (waitResult == WAIT_OBJECT_0)
{
/* terminating thread */
/* WLog_Print(serial->log, WLOG_DEBUG, "IRP thread with CompletionId=%d naturally died", id); */
CloseHandle(irpThread);
ListDictionary_Remove(serial->IrpThreads, (void*)id);
serial->IrpThreadToBeTerminatedCount--;
}
else if (waitResult != WAIT_TIMEOUT)
{
{
/* unexpected thread state */
WLog_Print(serial->log, WLOG_WARN, "WaitForSingleObject, got an unexpected result=0x%lX\n", waitResult);
WLog_Print(serial->log, WLOG_WARN,
"WaitForSingleObject, got an unexpected result=0x%lX\n", waitResult);
assert(FALSE);
}
/* pending thread (but not yet terminating thread) if waitResult == WAIT_TIMEOUT */
}
if (serial->IrpThreadToBeTerminatedCount > 0)
{
WLog_Print(serial->log, WLOG_DEBUG, "%d IRP thread(s) not yet terminated", serial->IrpThreadToBeTerminatedCount);
WLog_Print(serial->log, WLOG_DEBUG, "%d IRP thread(s) not yet terminated",
serial->IrpThreadToBeTerminatedCount);
Sleep(1); /* 1 ms */
}
}
LeaveCriticalSection(&serial->TerminatingIrpThreadsLock);
LeaveCriticalSection(&serial->TerminatingIrpThreadsLock);
/* NB: At this point and thanks to the synchronization we're
* sure that the incoming IRP uses well a recycled
* CompletionId or the server sent again an IRP already posted
@ -580,22 +563,20 @@ static void create_irp_thread(SERIAL_DEVICE *serial, IRP *irp)
* FIXME: behavior documented somewhere? behavior not yet
* observed with FreeRDP).
*/
key = irp->CompletionId;
previousIrpThread = ListDictionary_GetItemValue(serial->IrpThreads, (void*)key);
if (previousIrpThread)
{
/* Thread still alived <=> Request still pending */
WLog_Print(serial->log, WLOG_DEBUG, "IRP recall: IRP with the CompletionId=%d not yet completed!", irp->CompletionId);
WLog_Print(serial->log, WLOG_DEBUG,
"IRP recall: IRP with the CompletionId=%d not yet completed!",
irp->CompletionId);
assert(FALSE); /* unimplemented */
/* TODO: asserts that previousIrpThread handles well
* the same request by checking more details. Need an
* access to the IRP object used by previousIrpThread
*/
/* TODO: taking over the pending IRP or sending a kind
* of wake up signal to accelerate the pending
* request
@ -605,18 +586,16 @@ static void create_irp_thread(SERIAL_DEVICE *serial, IRP *irp)
* pComm->PendingEvents |= SERIAL_EV_FREERDP_*;
* }
*/
irp->Discard(irp);
return;
}
if (ListDictionary_Count(serial->IrpThreads) >= MAX_IRP_THREADS)
{
WLog_Print(serial->log, WLOG_WARN, "Number of IRP threads threshold reached: %d, keep on anyway", ListDictionary_Count(serial->IrpThreads));
WLog_Print(serial->log, WLOG_WARN,
"Number of IRP threads threshold reached: %d, keep on anyway",
ListDictionary_Count(serial->IrpThreads));
assert(FALSE); /* unimplemented */
/* TODO: MAX_IRP_THREADS has been thought to avoid a
* flooding of pending requests. Use
* WaitForMultipleObjects() when available in winpr
@ -624,10 +603,9 @@ static void create_irp_thread(SERIAL_DEVICE *serial, IRP *irp)
*/
}
/* error_handle to be used ... */
data = (IRP_THREAD_DATA*)calloc(1, sizeof(IRP_THREAD_DATA));
if (data == NULL)
{
WLog_Print(serial->log, WLOG_WARN, "Could not allocate a new IRP_THREAD_DATA.");
@ -636,15 +614,13 @@ static void create_irp_thread(SERIAL_DEVICE *serial, IRP *irp)
data->serial = serial;
data->irp = irp;
/* data freed by irp_thread_func */
irpThread = CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)irp_thread_func,
(void*)data,
0,
NULL);
0,
(LPTHREAD_START_ROUTINE)irp_thread_func,
(void*)data,
0,
NULL);
if (irpThread == INVALID_HANDLE_VALUE)
{
@ -652,8 +628,8 @@ static void create_irp_thread(SERIAL_DEVICE *serial, IRP *irp)
goto error_handle;
}
key = irp->CompletionId;
if (!ListDictionary_Add(serial->IrpThreads, (void*)key, irpThread))
{
WLog_ERR(TAG, "ListDictionary_Add failed!");
@ -661,43 +637,36 @@ static void create_irp_thread(SERIAL_DEVICE *serial, IRP *irp)
}
return;
error_handle:
error_handle:
irp->IoStatus = STATUS_NO_MEMORY;
irp->Complete(irp);
free(data);
}
static void terminate_pending_irp_threads(SERIAL_DEVICE *serial)
static void terminate_pending_irp_threads(SERIAL_DEVICE* serial)
{
ULONG_PTR *ids;
ULONG_PTR* ids;
int i, nbIds;
nbIds = ListDictionary_GetKeys(serial->IrpThreads, &ids);
WLog_Print(serial->log, WLOG_DEBUG, "Terminating %d IRP thread(s)", nbIds);
for (i=0; i<nbIds; i++)
for (i = 0; i < nbIds; i++)
{
HANDLE irpThread;
ULONG_PTR id = ids[i];
irpThread = ListDictionary_GetItemValue(serial->IrpThreads, (void*)id);
TerminateThread(irpThread, 0);
if (WaitForSingleObject(irpThread, INFINITE) == WAIT_FAILED)
{
WLog_ERR(TAG,"WaitForSingleObject failed!");
continue;
}
{
WLog_ERR(TAG, "WaitForSingleObject failed!");
continue;
}
CloseHandle(irpThread);
WLog_Print(serial->log, WLOG_DEBUG, "IRP thread terminated, CompletionId %d", id);
WLog_Print(serial->log, WLOG_DEBUG, "IRP thread terminated, CompletionId %d",
id);
}
ListDictionary_Clear(serial->IrpThreads);
@ -740,7 +709,8 @@ static void* serial_thread_func(void* arg)
}
if (error && serial->rdpcontext)
setChannelError(serial->rdpcontext, error, "serial_thread_func reported an error");
setChannelError(serial->rdpcontext, error,
"serial_thread_func reported an error");
ExitThread((DWORD) error);
return NULL;
@ -755,7 +725,6 @@ static void* serial_thread_func(void* arg)
static UINT serial_irp_request(DEVICE* device, IRP* irp)
{
SERIAL_DEVICE* serial = (SERIAL_DEVICE*) device;
assert(irp != NULL);
if (irp == NULL)
@ -771,6 +740,7 @@ static UINT serial_irp_request(DEVICE* device, IRP* irp)
WLog_ERR(TAG, "MessageQueue_Post failed!");
return ERROR_INTERNAL_ERROR;
}
return CHANNEL_RC_OK;
}
@ -782,18 +752,18 @@ static UINT serial_irp_request(DEVICE* device, IRP* irp)
*/
static UINT serial_free(DEVICE* device)
{
UINT error;
UINT error;
SERIAL_DEVICE* serial = (SERIAL_DEVICE*) device;
WLog_Print(serial->log, WLOG_DEBUG, "freeing");
MessageQueue_PostQuit(serial->MainIrpQueue, 0);
if (WaitForSingleObject(serial->MainThread, INFINITE) == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
return error;
}
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error);
return error;
}
CloseHandle(serial->MainThread);
if (serial->hComm)
@ -804,14 +774,13 @@ static UINT serial_free(DEVICE* device)
MessageQueue_Free(serial->MainIrpQueue);
ListDictionary_Free(serial->IrpThreads);
DeleteCriticalSection(&serial->TerminatingIrpThreadsLock);
free(serial);
return CHANNEL_RC_OK;
return CHANNEL_RC_OK;
}
#endif /* __linux__ */
#ifdef STATIC_CHANNELS
#ifdef BUILTIN_CHANNELS
#define DeviceServiceEntry serial_DeviceServiceEntry
#else
#define DeviceServiceEntry FREERDP_API DeviceServiceEntry
@ -833,7 +802,6 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
SERIAL_DEVICE* serial;
#endif /* __linux__ */
UINT error = CHANNEL_RC_OK;
device = (RDPDR_SERIAL*) pEntryPoints->device;
name = device->Name;
path = device->Path;
@ -848,18 +816,14 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
if ((name && name[0]) && (path && path[0]))
{
wLog* log;
WLog_Init();
log = WLog_Get("com.freerdp.channel.serial.client");
WLog_Print(log, WLOG_DEBUG, "initializing");
#ifndef __linux__ /* to be removed */
WLog_Print(log, WLOG_WARN, "Serial ports redirection not supported on this platform.");
WLog_Print(log, WLOG_WARN,
"Serial ports redirection not supported on this platform.");
return CHANNEL_RC_INITIALIZATION_ERROR;
#else /* __linux __ */
WLog_Print(log, WLOG_DEBUG, "Defining %s as %s", name, path);
if (!DefineCommDevice(name /* eg: COM1 */, path /* eg: /dev/ttyS0 */))
@ -869,6 +833,7 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
}
serial = (SERIAL_DEVICE*) calloc(1, sizeof(SERIAL_DEVICE));
if (!serial)
{
WLog_ERR(TAG, "calloc failed!");
@ -876,15 +841,14 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
}
serial->log = log;
serial->device.type = RDPDR_DTYP_SERIAL;
serial->device.name = name;
serial->device.IRPRequest = serial_irp_request;
serial->device.Free = serial_free;
serial->rdpcontext = pEntryPoints->rdpcontext;
len = strlen(name);
serial->device.data = Stream_New(NULL, len + 1);
if (!serial->device.data)
{
WLog_ERR(TAG, "calloc failed!");
@ -906,8 +870,8 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
else
{
assert(FALSE);
WLog_Print(serial->log, WLOG_DEBUG, "Unknown server's serial driver: %s. SerCx2 will be used", driver);
WLog_Print(serial->log, WLOG_DEBUG,
"Unknown server's serial driver: %s. SerCx2 will be used", driver);
serial->ServerSerialDriverId = SerialDriverSerialSys;
}
}
@ -917,7 +881,6 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
serial->ServerSerialDriverId = SerialDriverSerialSys;
}
if (device->Permissive != NULL)
{
if (_stricmp(device->Permissive, "permissive") == 0)
@ -931,11 +894,11 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
}
}
WLog_Print(serial->log, WLOG_DEBUG, "Server's serial driver: %s (id: %d)", driver, serial->ServerSerialDriverId);
WLog_Print(serial->log, WLOG_DEBUG, "Server's serial driver: %s (id: %d)",
driver, serial->ServerSerialDriverId);
/* TODO: implement auto detection of the server's serial driver */
serial->MainIrpQueue = MessageQueue_New(NULL);
if (!serial->MainIrpQueue)
{
WLog_ERR(TAG, "MessageQueue_New failed!");
@ -945,32 +908,36 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
/* IrpThreads content only modified by create_irp_thread() */
serial->IrpThreads = ListDictionary_New(FALSE);
if(!serial->IrpThreads)
if (!serial->IrpThreads)
{
WLog_ERR(TAG, "ListDictionary_New failed!");
error = CHANNEL_RC_NO_MEMORY;
goto error_out;
}
serial->IrpThreadToBeTerminatedCount = 0;
InitializeCriticalSection(&serial->TerminatingIrpThreadsLock);
if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) serial)))
if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman,
(DEVICE*) serial)))
{
WLog_ERR(TAG, "EntryPoints->RegisterDevice failed with error %lu!", error);
WLog_ERR(TAG, "EntryPoints->RegisterDevice failed with error %u!", error);
goto error_out;
}
if (!(serial->MainThread = CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE) serial_thread_func,
(void*) serial,
0,
NULL)))
0,
(LPTHREAD_START_ROUTINE) serial_thread_func,
(void*) serial,
0,
NULL)))
{
WLog_ERR(TAG, "CreateThread failed!");
error = ERROR_INTERNAL_ERROR;
goto error_out;
}
#endif /* __linux __ */
}

View File

@ -49,6 +49,7 @@
#include <freerdp/server/drdynvc.h>
#include <freerdp/server/remdesk.h>
#include <freerdp/server/encomsp.h>
#include <freerdp/server/rdpgfx.h>
void freerdp_channels_dummy()
{
@ -79,6 +80,8 @@ void freerdp_channels_dummy()
encomsp_server_context_new(NULL);
encomsp_server_context_free(NULL);
rdpgfx_server_context_new(NULL);
rdpgfx_server_context_free(NULL);
}
/**

View File

@ -7,6 +7,7 @@
* Copyright 2011 Anthony Tong <atong@trustedcs.com>
* Copyright 2015 Thincast Technologies GmbH
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
* Copyright 2016 David PHAM-VAN <d.phamvan@inuvika.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -43,7 +44,6 @@ void* smartcard_context_thread(SMARTCARD_CONTEXT* pContext)
SMARTCARD_DEVICE* smartcard;
SMARTCARD_OPERATION* operation;
UINT error = CHANNEL_RC_OK;
smartcard = pContext->smartcard;
nCount = 0;
@ -56,7 +56,7 @@ void* smartcard_context_thread(SMARTCARD_CONTEXT* pContext)
if (waitStatus == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error);
WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u!", error);
break;
}
@ -65,7 +65,7 @@ void* smartcard_context_thread(SMARTCARD_CONTEXT* pContext)
if (waitStatus == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error);
break;
}
@ -78,7 +78,6 @@ void* smartcard_context_thread(SMARTCARD_CONTEXT* pContext)
break;
}
if (message.id == WMQ_QUIT)
break;
@ -88,7 +87,8 @@ void* smartcard_context_thread(SMARTCARD_CONTEXT* pContext)
{
if ((status = smartcard_irp_device_control_call(smartcard, operation)))
{
WLog_ERR(TAG, "smartcard_irp_device_control_call failed with error %lu", status);
WLog_ERR(TAG, "smartcard_irp_device_control_call failed with error %u",
status);
break;
}
@ -97,7 +97,6 @@ void* smartcard_context_thread(SMARTCARD_CONTEXT* pContext)
WLog_ERR(TAG, "Queue_Enqueue failed!");
status = ERROR_INTERNAL_ERROR;
break;
}
free(operation);
@ -106,17 +105,19 @@ void* smartcard_context_thread(SMARTCARD_CONTEXT* pContext)
}
if (status && smartcard->rdpcontext)
setChannelError(smartcard->rdpcontext, error, "smartcard_context_thread reported an error");
setChannelError(smartcard->rdpcontext, error,
"smartcard_context_thread reported an error");
ExitThread((DWORD)status);
return NULL;
}
SMARTCARD_CONTEXT* smartcard_context_new(SMARTCARD_DEVICE* smartcard, SCARDCONTEXT hContext)
SMARTCARD_CONTEXT* smartcard_context_new(SMARTCARD_DEVICE* smartcard,
SCARDCONTEXT hContext)
{
SMARTCARD_CONTEXT* pContext;
pContext = (SMARTCARD_CONTEXT*) calloc(1, sizeof(SMARTCARD_CONTEXT));
if (!pContext)
{
WLog_ERR(TAG, "calloc failed!");
@ -125,8 +126,8 @@ SMARTCARD_CONTEXT* smartcard_context_new(SMARTCARD_DEVICE* smartcard, SCARDCONTE
pContext->smartcard = smartcard;
pContext->hContext = hContext;
pContext->IrpQueue = MessageQueue_New(NULL);
if (!pContext->IrpQueue)
{
WLog_ERR(TAG, "MessageQueue_New failed!");
@ -134,8 +135,9 @@ SMARTCARD_CONTEXT* smartcard_context_new(SMARTCARD_DEVICE* smartcard, SCARDCONTE
}
pContext->thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) smartcard_context_thread,
pContext, 0, NULL);
(LPTHREAD_START_ROUTINE) smartcard_context_thread,
pContext, 0, NULL);
if (!pContext->thread)
{
WLog_ERR(TAG, "CreateThread failed!");
@ -143,7 +145,6 @@ SMARTCARD_CONTEXT* smartcard_context_new(SMARTCARD_DEVICE* smartcard, SCARDCONTE
}
return pContext;
error_thread:
MessageQueue_Free(pContext->IrpQueue);
error_irpqueue:
@ -158,18 +159,19 @@ void smartcard_context_free(SMARTCARD_CONTEXT* pContext)
/* cancel blocking calls like SCardGetStatusChange */
SCardCancel(pContext->hContext);
if (MessageQueue_PostQuit(pContext->IrpQueue, 0) && (WaitForSingleObject(pContext->thread, INFINITE) == WAIT_FAILED))
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", GetLastError());
if (MessageQueue_PostQuit(pContext->IrpQueue, 0)
&& (WaitForSingleObject(pContext->thread, INFINITE) == WAIT_FAILED))
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", (unsigned long) GetLastError());
CloseHandle(pContext->thread);
MessageQueue_Free(pContext->IrpQueue);
free(pContext);
}
static void smartcard_release_all_contexts(SMARTCARD_DEVICE* smartcard) {
static void smartcard_release_all_contexts(SMARTCARD_DEVICE* smartcard)
{
int index;
int keyCount;
ULONG_PTR* pKeys;
@ -193,7 +195,8 @@ static void smartcard_release_all_contexts(SMARTCARD_DEVICE* smartcard) {
for (index = 0; index < keyCount; index++)
{
pContext = (SMARTCARD_CONTEXT*) ListDictionary_GetItemValue(smartcard->rgSCardContextList, (void*) pKeys[index]);
pContext = (SMARTCARD_CONTEXT*) ListDictionary_GetItemValue(
smartcard->rgSCardContextList, (void*) pKeys[index]);
if (!pContext)
continue;
@ -220,7 +223,8 @@ static void smartcard_release_all_contexts(SMARTCARD_DEVICE* smartcard) {
for (index = 0; index < keyCount; index++)
{
pContext = (SMARTCARD_CONTEXT*) ListDictionary_Remove(smartcard->rgSCardContextList, (void*) pKeys[index]);
pContext = (SMARTCARD_CONTEXT*) ListDictionary_Remove(
smartcard->rgSCardContextList, (void*) pKeys[index]);
if (!pContext)
continue;
@ -230,6 +234,14 @@ static void smartcard_release_all_contexts(SMARTCARD_DEVICE* smartcard) {
if (SCardIsValidContext(hContext) == SCARD_S_SUCCESS)
{
SCardReleaseContext(hContext);
if (MessageQueue_PostQuit(pContext->IrpQueue, 0)
&& (WaitForSingleObject(pContext->thread, INFINITE) == WAIT_FAILED))
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", (unsigned long) GetLastError());
CloseHandle(pContext->thread);
MessageQueue_Free(pContext->IrpQueue);
free(pContext);
}
}
@ -247,28 +259,26 @@ static UINT smartcard_free(DEVICE* device)
{
UINT error;
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device;
/**
* Calling smartcard_release_all_contexts to unblock all operations waiting for transactions
* to unlock.
*/
smartcard_release_all_contexts(smartcard);
/* Stopping all threads and cancelling all IRPs */
if (smartcard->IrpQueue)
{
if (MessageQueue_PostQuit(smartcard->IrpQueue, 0) && (WaitForSingleObject(smartcard->thread, INFINITE) == WAIT_FAILED))
if (MessageQueue_PostQuit(smartcard->IrpQueue, 0)
&& (WaitForSingleObject(smartcard->thread, INFINITE) == WAIT_FAILED))
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error);
return error;
}
MessageQueue_Free(smartcard->IrpQueue);
smartcard->IrpQueue = NULL;
CloseHandle(smartcard->thread);
smartcard->thread = NULL;
}
@ -290,7 +300,6 @@ static UINT smartcard_free(DEVICE* device)
}
free(device);
return CHANNEL_RC_OK;
}
@ -307,9 +316,7 @@ static UINT smartcard_free(DEVICE* device)
static UINT smartcard_init(DEVICE* device)
{
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device;
smartcard_release_all_contexts(smartcard);
return CHANNEL_RC_OK;
}
@ -321,10 +328,8 @@ static UINT smartcard_init(DEVICE* device)
UINT smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
{
void* key;
key = (void*) (size_t) irp->CompletionId;
key = (void*)(size_t) irp->CompletionId;
ListDictionary_Remove(smartcard->rgOutstandingMessages, key);
return irp->Complete(irp);
}
@ -345,8 +350,8 @@ UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
BOOL asyncIrp = FALSE;
SMARTCARD_CONTEXT* pContext = NULL;
SMARTCARD_OPERATION* operation = NULL;
key = (void*)(size_t) irp->CompletionId;
key = (void*) (size_t) irp->CompletionId;
if (!ListDictionary_Add(smartcard->rgOutstandingMessages, key, irp))
{
WLog_ERR(TAG, "ListDictionary_Add failed!");
@ -364,7 +369,6 @@ UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
}
operation->irp = irp;
status = smartcard_irp_device_control_decode(smartcard, operation);
if (status != SCARD_S_SUCCESS)
@ -451,7 +455,8 @@ UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
break;
}
pContext = ListDictionary_GetItemValue(smartcard->rgSCardContextList, (void*) operation->hContext);
pContext = ListDictionary_GetItemValue(smartcard->rgSCardContextList,
(void*) operation->hContext);
if (!pContext)
asyncIrp = FALSE;
@ -460,14 +465,17 @@ UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
{
if ((status = smartcard_irp_device_control_call(smartcard, operation)))
{
WLog_ERR(TAG, "smartcard_irp_device_control_call failed with error %lu!", status);
WLog_ERR(TAG, "smartcard_irp_device_control_call failed with error %ld!",
status);
return (UINT32)status;
}
if (!Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) irp))
{
WLog_ERR(TAG, "Queue_Enqueue failed!");
return ERROR_INTERNAL_ERROR;
}
free(operation);
}
else
@ -484,8 +492,9 @@ UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
}
else
{
WLog_ERR(TAG, "Unexpected SmartCard IRP: MajorFunction 0x%08X MinorFunction: 0x%08X",
irp->MajorFunction, irp->MinorFunction);
WLog_ERR(TAG,
"Unexpected SmartCard IRP: MajorFunction 0x%08X MinorFunction: 0x%08X",
irp->MajorFunction, irp->MinorFunction);
irp->IoStatus = (UINT32)STATUS_NOT_SUPPORTED;
if (!Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) irp))
@ -494,6 +503,7 @@ UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
return ERROR_INTERNAL_ERROR;
}
}
return CHANNEL_RC_OK;
}
@ -518,7 +528,7 @@ static void* smartcard_thread_func(void* arg)
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error);
WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u!", error);
break;
}
@ -527,7 +537,7 @@ static void* smartcard_thread_func(void* arg)
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error);
break;
}
@ -540,7 +550,6 @@ static void* smartcard_thread_func(void* arg)
break;
}
if (message.id == WMQ_QUIT)
{
while (1)
@ -550,7 +559,7 @@ static void* smartcard_thread_func(void* arg)
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error);
goto out;
}
@ -568,7 +577,7 @@ static void* smartcard_thread_func(void* arg)
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error);
goto out;
}
@ -578,7 +587,7 @@ static void* smartcard_thread_func(void* arg)
if ((error = smartcard_complete_irp(smartcard, irp)))
{
WLog_ERR(TAG, "smartcard_complete_irp failed with error %lu!", error);
WLog_ERR(TAG, "smartcard_complete_irp failed with error %u!", error);
goto out;
}
}
@ -593,7 +602,7 @@ static void* smartcard_thread_func(void* arg)
{
if ((error = smartcard_process_irp(smartcard, irp)))
{
WLog_ERR(TAG, "smartcard_process_irp failed with error %lu!", error);
WLog_ERR(TAG, "smartcard_process_irp failed with error %u!", error);
goto out;
}
}
@ -604,13 +613,12 @@ static void* smartcard_thread_func(void* arg)
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error);
break;
}
if (status == WAIT_OBJECT_0)
{
irp = (IRP*) Queue_Dequeue(smartcard->CompletedIrpQueue);
if (irp)
@ -622,7 +630,7 @@ static void* smartcard_thread_func(void* arg)
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error);
break;
}
@ -632,15 +640,24 @@ static void* smartcard_thread_func(void* arg)
if ((error = smartcard_complete_irp(smartcard, irp)))
{
WLog_ERR(TAG, "smartcard_complete_irp failed with error %lu!", error);
if (error == CHANNEL_RC_NOT_CONNECTED)
{
error = CHANNEL_RC_OK;
goto out;
}
WLog_ERR(TAG, "smartcard_complete_irp failed with error %u!", error);
goto out;
}
}
}
}
out:
if (error && smartcard->rdpcontext)
setChannelError(smartcard->rdpcontext, error, "smartcard_thread_func reported an error");
setChannelError(smartcard->rdpcontext, error,
"smartcard_thread_func reported an error");
ExitThread((DWORD)error);
return NULL;
@ -654,11 +671,13 @@ out:
static UINT smartcard_irp_request(DEVICE* device, IRP* irp)
{
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device;
if (!MessageQueue_Post(smartcard->IrpQueue, NULL, 0, (void*) irp, NULL))
{
WLog_ERR(TAG, "MessageQueue_Post failed!");
return ERROR_INTERNAL_ERROR;
}
return CHANNEL_RC_OK;
}
@ -679,13 +698,11 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
RDPDR_SMARTCARD* device;
SMARTCARD_DEVICE* smartcard;
UINT error = CHANNEL_RC_NO_MEMORY;
device = (RDPDR_SMARTCARD*) pEntryPoints->device;
name = device->Name;
path = device->Path;
smartcard = (SMARTCARD_DEVICE*) calloc(1, sizeof(SMARTCARD_DEVICE));
if (!smartcard)
{
WLog_ERR(TAG, "calloc failed!");
@ -698,9 +715,9 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
smartcard->device.Init = smartcard_init;
smartcard->device.Free = smartcard_free;
smartcard->rdpcontext = pEntryPoints->rdpcontext;
length = strlen(smartcard->device.name);
smartcard->device.data = Stream_New(NULL, length + 1);
if (!smartcard->device.data)
{
WLog_ERR(TAG, "Stream_New failed!");
@ -708,7 +725,6 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
}
Stream_Write(smartcard->device.data, "SCARD", 6);
smartcard->name = NULL;
smartcard->path = NULL;
@ -726,14 +742,15 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
}
smartcard->IrpQueue = MessageQueue_New(NULL);
if (!smartcard->IrpQueue)
{
WLog_ERR(TAG, "MessageQueue_New failed!");
goto error_irp_queue;
}
smartcard->CompletedIrpQueue = Queue_New(TRUE, -1, -1);
if (!smartcard->CompletedIrpQueue)
{
WLog_ERR(TAG, "Queue_New failed!");
@ -741,6 +758,7 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
}
smartcard->rgSCardContextList = ListDictionary_New(TRUE);
if (!smartcard->rgSCardContextList)
{
WLog_ERR(TAG, "ListDictionary_New failed!");
@ -748,24 +766,26 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
}
ListDictionary_ValueObject(smartcard->rgSCardContextList)->fnObjectFree =
(OBJECT_FREE_FN) smartcard_context_free;
(OBJECT_FREE_FN) smartcard_context_free;
smartcard->rgOutstandingMessages = ListDictionary_New(TRUE);
if (!smartcard->rgOutstandingMessages)
{
WLog_ERR(TAG, "ListDictionary_New failed!");
goto error_outstanding_messages;
}
if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) smartcard)))
if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman,
(DEVICE*) smartcard)))
{
WLog_ERR(TAG, "RegisterDevice failed!");
goto error_outstanding_messages;
}
smartcard->thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) smartcard_thread_func,
smartcard, CREATE_SUSPENDED, NULL);
smartcard->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) smartcard_thread_func,
smartcard, CREATE_SUSPENDED, NULL);
if (!smartcard->thread)
{
WLog_ERR(TAG, "ListDictionary_New failed!");
@ -774,9 +794,7 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
}
ResumeThread(smartcard->thread);
return CHANNEL_RC_OK;
error_thread:
ListDictionary_Free(smartcard->rgOutstandingMessages);
error_outstanding_messages:

View File

@ -202,7 +202,7 @@ static LONG smartcard_EstablishContext_Decode(SMARTCARD_DEVICE* smartcard, SMART
if ((status = smartcard_unpack_establish_context_call(smartcard, irp->input, call)))
{
WLog_ERR(TAG, "smartcard_unpack_establish_context_call failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_establish_context_call failed with error %ld", status);
return status;
}
smartcard_trace_establish_context_call(smartcard, call);
@ -236,7 +236,7 @@ static LONG smartcard_EstablishContext_Call(SMARTCARD_DEVICE* smartcard, SMARTCA
}
else
{
WLog_ERR(TAG, "SCardEstablishContext failed with error %lu", status);
WLog_ERR(TAG, "SCardEstablishContext failed with error %ld", status);
return status;
}
@ -244,7 +244,7 @@ static LONG smartcard_EstablishContext_Call(SMARTCARD_DEVICE* smartcard, SMARTCA
smartcard_trace_establish_context_return(smartcard, &ret);
if ((status = smartcard_pack_establish_context_return(smartcard, irp->output, &ret)))
{
WLog_ERR(TAG, "smartcard_pack_establish_context_return failed with error %lu", status);
WLog_ERR(TAG, "smartcard_pack_establish_context_return failed with error %ld", status);
return status;
}
@ -260,7 +260,7 @@ static LONG smartcard_ReleaseContext_Decode(SMARTCARD_DEVICE* smartcard, SMARTCA
return STATUS_NO_MEMORY;
if ((status = smartcard_unpack_context_call(smartcard, irp->input, call)))
WLog_ERR(TAG, "smartcard_unpack_context_call failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_context_call failed with error %ld", status);
smartcard_trace_context_call(smartcard, call, "ReleaseContext");
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
return status;
@ -282,7 +282,7 @@ static LONG smartcard_ReleaseContext_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD
}
else
{
WLog_ERR(TAG, "SCardReleaseContext failed with error %lu", status);
WLog_ERR(TAG, "SCardReleaseContext failed with error %ld", status);
return status;
}
@ -299,7 +299,7 @@ static LONG smartcard_IsValidContext_Decode(SMARTCARD_DEVICE* smartcard, SMARTCA
return STATUS_NO_MEMORY;
if ((status = smartcard_unpack_context_call(smartcard, irp->input, call)))
WLog_ERR(TAG, "smartcard_unpack_context_call failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_context_call failed with error %ld", status);
smartcard_trace_context_call(smartcard, call, "IsValidContext");
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
return status;
@ -311,7 +311,7 @@ static LONG smartcard_IsValidContext_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD
Long_Return ret;
if ((status = ret.ReturnCode = SCardIsValidContext(operation->hContext)))
{
WLog_ERR(TAG, "SCardIsValidContext failed with error %lu", status);
WLog_ERR(TAG, "SCardIsValidContext failed with error %ld", status);
return status;
}
smartcard_trace_long_return(smartcard, &ret, "IsValidContext");
@ -327,7 +327,7 @@ static LONG smartcard_ListReadersA_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD
return STATUS_NO_MEMORY;
if ((status = smartcard_unpack_list_readers_call(smartcard, irp->input, call)))
WLog_ERR(TAG, "smartcard_unpack_list_readers_call failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_list_readers_call failed with error %ld", status);
smartcard_trace_list_readers_call(smartcard, call, FALSE);
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
return status;
@ -356,14 +356,14 @@ static LONG smartcard_ListReadersA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_O
if (status)
{
WLog_ERR(TAG, "SCardListReadersA failed with error %lu", status);
WLog_ERR(TAG, "SCardListReadersA failed with error %ld", status);
return status;
}
smartcard_trace_list_readers_return(smartcard, &ret, FALSE);
if ((status = smartcard_pack_list_readers_return(smartcard, irp->output, &ret)))
{
WLog_ERR(TAG, "smartcard_pack_list_readers_return failed with error %lu", status);
WLog_ERR(TAG, "smartcard_pack_list_readers_return failed with error %ld", status);
return status;
}
@ -385,7 +385,7 @@ static LONG smartcard_ListReadersW_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD
return STATUS_NO_MEMORY;
if ((status = smartcard_unpack_list_readers_call(smartcard, irp->input, call)))
WLog_ERR(TAG, "smartcard_unpack_list_readers_call failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_list_readers_call failed with error %ld", status);
smartcard_trace_list_readers_call(smartcard, call, TRUE);
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
@ -417,7 +417,7 @@ static LONG smartcard_ListReadersW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_O
if (status)
{
WLog_ERR(TAG, "SCardListReadersW failed with error %lu", status);
WLog_ERR(TAG, "SCardListReadersW failed with error %ld", status);
return status;
}
@ -425,7 +425,7 @@ static LONG smartcard_ListReadersW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_O
if ((status = smartcard_pack_list_readers_return(smartcard, irp->output, &ret)))
{
WLog_ERR(TAG, "smartcard_pack_list_readers_return failed with error %lu", status);
WLog_ERR(TAG, "smartcard_pack_list_readers_return failed with error %ld", status);
return status;
}
@ -448,7 +448,7 @@ static LONG smartcard_GetStatusChangeA_Decode(SMARTCARD_DEVICE* smartcard, SMART
if ((status = smartcard_unpack_get_status_change_a_call(smartcard, irp->input, call)))
{
WLog_ERR(TAG, "smartcard_unpack_get_status_change_a_call failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_get_status_change_a_call failed with error %ld", status);
return status;
}
@ -492,7 +492,7 @@ static LONG smartcard_GetStatusChangeA_Call(SMARTCARD_DEVICE* smartcard, SMARTCA
smartcard_trace_get_status_change_return(smartcard, &ret, FALSE);
if ((status = smartcard_pack_get_status_change_return(smartcard, irp->output, &ret)))
{
WLog_ERR(TAG, "smartcard_pack_get_status_change_return failed with error %lu", status);
WLog_ERR(TAG, "smartcard_pack_get_status_change_return failed with error %ld", status);
return status;
}
@ -520,7 +520,7 @@ static LONG smartcard_GetStatusChangeW_Decode(SMARTCARD_DEVICE* smartcard, SMART
return STATUS_NO_MEMORY;
if ((status = smartcard_unpack_get_status_change_w_call(smartcard, irp->input, call)))
WLog_ERR(TAG, "smartcard_unpack_get_status_change_w_call failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_get_status_change_w_call failed with error %ld", status);
smartcard_trace_get_status_change_w_call(smartcard, call);
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
return status;
@ -559,7 +559,7 @@ static LONG smartcard_GetStatusChangeW_Call(SMARTCARD_DEVICE* smartcard, SMARTCA
smartcard_trace_get_status_change_return(smartcard, &ret, TRUE);
if ((status = smartcard_pack_get_status_change_return(smartcard, irp->output, &ret)))
{
WLog_ERR(TAG, "smartcard_pack_get_status_change_return failed with error %lu", status);
WLog_ERR(TAG, "smartcard_pack_get_status_change_return failed with error %ld", status);
return status;
}
@ -587,7 +587,7 @@ static LONG smartcard_Cancel_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERA
return STATUS_NO_MEMORY;
if ((status = smartcard_unpack_context_call(smartcard, irp->input, call)))
WLog_ERR(TAG, "smartcard_unpack_context_call failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_context_call failed with error %ld", status);
smartcard_trace_context_call(smartcard, call, "Cancel");
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
return status;
@ -600,7 +600,7 @@ static LONG smartcard_Cancel_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATI
if ((status = ret.ReturnCode = SCardCancel(operation->hContext)))
{
WLog_ERR(TAG, "SCardCancel failed with error %lu", status);
WLog_ERR(TAG, "SCardCancel failed with error %ld", status);
return status;
}
smartcard_trace_long_return(smartcard, &ret, "Cancel");
@ -616,7 +616,7 @@ static LONG smartcard_ConnectA_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPE
return STATUS_NO_MEMORY;
if ((status = smartcard_unpack_connect_a_call(smartcard, irp->input, call)))
WLog_ERR(TAG, "smartcard_unpack_connect_a_call failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_connect_a_call failed with error %ld", status);
smartcard_trace_connect_a_call(smartcard, call);
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->Common.hContext));
return status;
@ -644,14 +644,14 @@ static LONG smartcard_ConnectA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERA
if (status)
{
WLog_ERR(TAG, "SCardConnectA failed with error %lu", status);
WLog_ERR(TAG, "SCardConnectA failed with error %ld", status);
return status;
}
if ((status = smartcard_pack_connect_return(smartcard, irp->output, &ret)))
{
WLog_ERR(TAG, "smartcard_pack_connect_return failed with error %lu", status);
WLog_ERR(TAG, "smartcard_pack_connect_return failed with error %ld", status);
return status;
}
@ -669,7 +669,7 @@ static LONG smartcard_ConnectW_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPE
return STATUS_NO_MEMORY;
if ((status = smartcard_unpack_connect_w_call(smartcard, irp->input, call)))
WLog_ERR(TAG, "smartcard_unpack_connect_w_call failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_connect_w_call failed with error %ld", status);
smartcard_trace_connect_w_call(smartcard, call);
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->Common.hContext));
@ -699,13 +699,13 @@ static LONG smartcard_ConnectW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERA
if (status)
{
WLog_ERR(TAG, "SCardConnectW failed with error %lu", status);
WLog_ERR(TAG, "SCardConnectW failed with error %ld", status);
return status;
}
if ((status = smartcard_pack_connect_return(smartcard, irp->output, &ret)))
{
WLog_ERR(TAG, "smartcard_pack_connect_return failed with error %lu", status);
WLog_ERR(TAG, "smartcard_pack_connect_return failed with error %ld", status);
return status;
}
@ -723,7 +723,7 @@ static LONG smartcard_Reconnect_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OP
return STATUS_NO_MEMORY;
if ((status = smartcard_unpack_reconnect_call(smartcard, irp->input, call)))
WLog_ERR(TAG, "smartcard_unpack_reconnect_call failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_reconnect_call failed with error %ld", status);
smartcard_trace_reconnect_call(smartcard, call);
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard));
@ -740,7 +740,7 @@ static LONG smartcard_Reconnect_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPER
smartcard_trace_reconnect_return(smartcard, &ret);
if ((status = smartcard_pack_reconnect_return(smartcard, irp->output, &ret)))
{
WLog_ERR(TAG, "smartcard_pack_reconnect_return failed with error %lu", status);
WLog_ERR(TAG, "smartcard_pack_reconnect_return failed with error %ld", status);
return status;
}
@ -756,7 +756,7 @@ static LONG smartcard_Disconnect_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_O
return STATUS_NO_MEMORY;
if ((status = smartcard_unpack_hcard_and_disposition_call(smartcard, irp->input, call)))
WLog_ERR(TAG, "smartcard_unpack_hcard_and_disposition_call failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_hcard_and_disposition_call failed with error %ld", status);
smartcard_trace_hcard_and_disposition_call(smartcard, call, "Disconnect");
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard));
@ -769,7 +769,7 @@ static LONG smartcard_Disconnect_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPE
Long_Return ret;
if ((status = ret.ReturnCode = SCardDisconnect(operation->hCard, call->dwDisposition)))
{
WLog_ERR(TAG, "SCardDisconnect failed with error %lu", status);
WLog_ERR(TAG, "SCardDisconnect failed with error %ld", status);
return status;
}
smartcard_trace_long_return(smartcard, &ret, "Disconnect");
@ -786,7 +786,7 @@ static LONG smartcard_BeginTransaction_Decode(SMARTCARD_DEVICE* smartcard, SMART
return STATUS_NO_MEMORY;
if ((status = smartcard_unpack_hcard_and_disposition_call(smartcard, irp->input, call)))
WLog_ERR(TAG, "smartcard_unpack_hcard_and_disposition_call failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_hcard_and_disposition_call failed with error %ld", status);
smartcard_trace_hcard_and_disposition_call(smartcard, call, "BeginTransaction");
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard));
@ -798,7 +798,7 @@ static LONG smartcard_BeginTransaction_Call(SMARTCARD_DEVICE* smartcard, SMARTCA
Long_Return ret;
if ((ret.ReturnCode = SCardBeginTransaction(operation->hCard)))
{
WLog_ERR(TAG, "SCardBeginTransaction failed with error %lu", ret.ReturnCode);
WLog_ERR(TAG, "SCardBeginTransaction failed with error %ld", ret.ReturnCode);
return ret.ReturnCode;
}
smartcard_trace_long_return(smartcard, &ret, "BeginTransaction");
@ -814,7 +814,7 @@ static LONG smartcard_EndTransaction_Decode(SMARTCARD_DEVICE* smartcard, SMARTCA
return STATUS_NO_MEMORY;
if ((status = smartcard_unpack_hcard_and_disposition_call(smartcard, irp->input, call)))
WLog_ERR(TAG, "smartcard_unpack_hcard_and_disposition_call failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_hcard_and_disposition_call failed with error %ld", status);
smartcard_trace_hcard_and_disposition_call(smartcard, call, "EndTransaction");
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard));
@ -826,7 +826,7 @@ static LONG smartcard_EndTransaction_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD
Long_Return ret;
if ((ret.ReturnCode = SCardEndTransaction(operation->hCard, call->dwDisposition)))
{
WLog_ERR(TAG, "SCardEndTransaction failed with error %lu", ret.ReturnCode);
WLog_ERR(TAG, "SCardEndTransaction failed with error %ld", ret.ReturnCode);
return ret.ReturnCode;
}
smartcard_trace_long_return(smartcard, &ret, "EndTransaction");
@ -842,7 +842,7 @@ static LONG smartcard_State_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERAT
return STATUS_NO_MEMORY;
if ((status = smartcard_unpack_state_call(smartcard, irp->input, call)))
WLog_ERR(TAG, "smartcard_unpack_state_call failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_state_call failed with error %ld", status);
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard));
return status;
@ -857,7 +857,7 @@ static LONG smartcard_State_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATIO
ret.ReturnCode = SCardState(operation->hCard, &ret.dwState, &ret.dwProtocol, (BYTE*) &ret.rgAtr, &ret.cbAtrLen);
if ((status = smartcard_pack_state_return(smartcard, irp->output, &ret)))
{
WLog_ERR(TAG, "smartcard_pack_state_return failed with error %lu", status);
WLog_ERR(TAG, "smartcard_pack_state_return failed with error %ld", status);
return status;
}
@ -873,7 +873,7 @@ static LONG smartcard_StatusA_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPER
return STATUS_NO_MEMORY;
if ((status = smartcard_unpack_status_call(smartcard, irp->input, call)))
WLog_ERR(TAG, "smartcard_unpack_status_call failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_status_call failed with error %ld", status);
smartcard_trace_status_call(smartcard, call, FALSE);
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard));
@ -904,7 +904,7 @@ static LONG smartcard_StatusA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERAT
smartcard_trace_status_return(smartcard, &ret, FALSE);
if ((status = smartcard_pack_status_return(smartcard, irp->output, &ret)))
{
WLog_ERR(TAG, "smartcard_pack_status_return failed with error %lu", status);
WLog_ERR(TAG, "smartcard_pack_status_return failed with error %ld", status);
return status;
}
@ -923,7 +923,7 @@ static LONG smartcard_StatusW_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPER
return STATUS_NO_MEMORY;
if ((status = smartcard_unpack_status_call(smartcard, irp->input, call)))
WLog_ERR(TAG, "smartcard_unpack_status_call failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_status_call failed with error %ld", status);
smartcard_trace_status_call(smartcard, call, TRUE);
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard));
@ -950,7 +950,7 @@ static LONG smartcard_StatusW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERAT
smartcard_trace_status_return(smartcard, &ret, TRUE);
if ((status = smartcard_pack_status_return(smartcard, irp->output, &ret)))
{
WLog_ERR(TAG, "smartcard_pack_status_return failed with error %lu", status);
WLog_ERR(TAG, "smartcard_pack_status_return failed with error %ld", status);
return status;
}
@ -969,7 +969,7 @@ static LONG smartcard_Transmit_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPE
return STATUS_NO_MEMORY;
if ((status = smartcard_unpack_transmit_call(smartcard, irp->input, call)))
WLog_ERR(TAG, "smartcard_unpack_transmit_call failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_transmit_call failed with error %ld", status);
smartcard_trace_transmit_call(smartcard, call);
@ -1007,7 +1007,7 @@ static LONG smartcard_Transmit_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERA
smartcard_trace_transmit_return(smartcard, &ret);
if ((status = smartcard_pack_transmit_return(smartcard, irp->output, &ret)))
{
WLog_ERR(TAG, "smartcard_pack_transmit_return failed with error %lu", status);
WLog_ERR(TAG, "smartcard_pack_transmit_return failed with error %ld", status);
return status;
}
@ -1028,7 +1028,7 @@ static LONG smartcard_Control_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPER
return STATUS_NO_MEMORY;
if ((status = smartcard_unpack_control_call(smartcard, irp->input, call)))
WLog_ERR(TAG, "smartcard_unpack_control_call failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_control_call failed with error %ld", status);
smartcard_trace_control_call(smartcard, call);
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard));
@ -1053,7 +1053,7 @@ static LONG smartcard_Control_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERAT
smartcard_trace_control_return(smartcard, &ret);
if ((status = smartcard_pack_control_return(smartcard, irp->output, &ret)))
{
WLog_ERR(TAG, "smartcard_pack_control_return failed with error %lu", status);
WLog_ERR(TAG, "smartcard_pack_control_return failed with error %ld", status);
return status;
}
@ -1072,7 +1072,7 @@ static LONG smartcard_GetAttrib_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OP
return STATUS_NO_MEMORY;
if ((status = smartcard_unpack_get_attrib_call(smartcard, irp->input, call)))
WLog_ERR(TAG, "smartcard_unpack_get_attrib_call failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_get_attrib_call failed with error %ld", status);
smartcard_trace_get_attrib_call(smartcard, call);
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard));
@ -1123,7 +1123,7 @@ static LONG smartcard_GetAttrib_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPER
if ((status = smartcard_pack_get_attrib_return(smartcard, irp->output, &ret)))
{
WLog_ERR(TAG, "smartcard_pack_get_attrib_return failed with error %lu", status);
WLog_ERR(TAG, "smartcard_pack_get_attrib_return failed with error %ld", status);
return status;
}
@ -1169,7 +1169,7 @@ static LONG smartcard_LocateCardsByATRA_Decode(SMARTCARD_DEVICE* smartcard, SMAR
return STATUS_NO_MEMORY;
if ((status = smartcard_unpack_locate_cards_by_atr_a_call(smartcard, irp->input, call)))
WLog_ERR(TAG, "smartcard_unpack_locate_cards_by_atr_a_call failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_locate_cards_by_atr_a_call failed with error %ld", status);
smartcard_trace_locate_cards_by_atr_a_call(smartcard, call);
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
return status;
@ -1249,7 +1249,7 @@ static LONG smartcard_LocateCardsByATRA_Call(SMARTCARD_DEVICE* smartcard, SMARTC
smartcard_trace_get_status_change_return(smartcard, &ret, FALSE);
if ((status = smartcard_pack_get_status_change_return(smartcard, irp->output, &ret)))
{
WLog_ERR(TAG, "smartcard_pack_get_status_change_return failed with error %lu", status);
WLog_ERR(TAG, "smartcard_pack_get_status_change_return failed with error %ld", status);
return status;
}
@ -1287,8 +1287,8 @@ LONG smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_
if (Stream_GetRemainingLength(irp->input) < 32)
{
WLog_WARN(TAG, "Device Control Request is too short: %d",
(int) Stream_GetRemainingLength(irp->input));
WLog_WARN(TAG, "Device Control Request is too short: %lu",
(unsigned long) Stream_GetRemainingLength(irp->input));
return SCARD_F_INTERNAL_ERROR;
}
@ -1300,8 +1300,9 @@ LONG smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_
if (Stream_Length(irp->input) != (Stream_GetPosition(irp->input) + inputBufferLength))
{
WLog_WARN(TAG, "InputBufferLength mismatch: Actual: %d Expected: %d",
Stream_Length(irp->input), Stream_GetPosition(irp->input) + inputBufferLength);
WLog_WARN(TAG, "InputBufferLength mismatch: Actual: %lu Expected: %lu",
(unsigned long) Stream_Length(irp->input),
(unsigned long) (Stream_GetPosition(irp->input) + inputBufferLength));
return SCARD_F_INTERNAL_ERROR;
}
@ -1314,13 +1315,13 @@ LONG smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_
{
if ((status = smartcard_unpack_common_type_header(smartcard, irp->input)))
{
WLog_ERR(TAG, "smartcard_unpack_common_type_header failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_common_type_header failed with error %ld", status);
return SCARD_F_INTERNAL_ERROR;
}
if ((status = smartcard_unpack_private_type_header(smartcard, irp->input)))
{
WLog_ERR(TAG, "smartcard_unpack_common_type_header failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_common_type_header failed with error %ld", status);
return SCARD_F_INTERNAL_ERROR;
}
}
@ -1945,12 +1946,12 @@ LONG smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OP
Stream_Write_UINT32(irp->output, outputBufferLength); /* OutputBufferLength (4 bytes) */
if ((result = smartcard_pack_common_type_header(smartcard, irp->output))) /* CommonTypeHeader (8 bytes) */
{
WLog_ERR(TAG, "smartcard_pack_common_type_header failed with error %lu", result);
WLog_ERR(TAG, "smartcard_pack_common_type_header failed with error %ld", result);
return result;
}
if ((result = smartcard_pack_private_type_header(smartcard, irp->output, objectBufferLength))) /* PrivateTypeHeader (8 bytes) */
{
WLog_ERR(TAG, "smartcard_pack_private_type_header failed with error %lu", result);
WLog_ERR(TAG, "smartcard_pack_private_type_header failed with error %ld", result);
return result;
}

View File

@ -109,8 +109,8 @@ LONG smartcard_unpack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream*
if (objectBufferLength != Stream_GetRemainingLength(s))
{
WLog_WARN(TAG, "PrivateTypeHeader ObjectBufferLength mismatch: Actual: %d, Expected: %d",
(int) objectBufferLength, Stream_GetRemainingLength(s));
WLog_WARN(TAG, "PrivateTypeHeader ObjectBufferLength mismatch: Actual: %lu, Expected: %lu",
(unsigned long) objectBufferLength, (unsigned long)Stream_GetRemainingLength(s));
return STATUS_INVALID_PARAMETER;
}
@ -166,8 +166,8 @@ SCARDCONTEXT smartcard_scard_context_native_from_redir(SMARTCARD_DEVICE* smartca
if ((context->cbContext != sizeof(ULONG_PTR)) && (context->cbContext != 0))
{
WLog_WARN(TAG, "REDIR_SCARDCONTEXT does not match native size: Actual: %d, Expected: %d",
context->cbContext, sizeof(ULONG_PTR));
WLog_WARN(TAG, "REDIR_SCARDCONTEXT does not match native size: Actual: %lu, Expected: %lu",
(unsigned long) context->cbContext, (unsigned long) sizeof(ULONG_PTR));
return 0;
}
@ -192,8 +192,8 @@ SCARDHANDLE smartcard_scard_handle_native_from_redir(SMARTCARD_DEVICE* smartcard
if (handle->cbHandle != sizeof(ULONG_PTR))
{
WLog_WARN(TAG, "REDIR_SCARDHANDLE does not match native size: Actual: %d, Expected: %d",
handle->cbHandle, sizeof(ULONG_PTR));
WLog_WARN(TAG, "REDIR_SCARDHANDLE does not match native size: Actual: %lu, Expected: %lu",
(unsigned long) handle->cbHandle, (unsigned long) sizeof(ULONG_PTR));
return 0;
}
@ -446,12 +446,12 @@ LONG smartcard_pack_establish_context_return(SMARTCARD_DEVICE* smartcard, wStrea
if ((status = smartcard_pack_redir_scard_context(smartcard, s, &(ret->hContext))))
{
WLog_ERR(TAG, "smartcard_pack_redir_scard_context failed with error %lu", status);
WLog_ERR(TAG, "smartcard_pack_redir_scard_context failed with error %ld", status);
return status;
}
if ((status = smartcard_pack_redir_scard_context_ref(smartcard, s, &(ret->hContext))))
WLog_ERR(TAG, "smartcard_pack_redir_scard_context_ref failed with error %lu", status);
WLog_ERR(TAG, "smartcard_pack_redir_scard_context_ref failed with error %ld", status);
return status;
}
@ -490,12 +490,12 @@ LONG smartcard_unpack_context_call(SMARTCARD_DEVICE* smartcard, wStream* s, Cont
if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %ld", status);
return status;
}
if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext))))
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status);
return status;
}
@ -548,7 +548,7 @@ LONG smartcard_unpack_list_readers_call(SMARTCARD_DEVICE* smartcard, wStream* s,
if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %ld", status);
return status;
}
@ -566,7 +566,7 @@ LONG smartcard_unpack_list_readers_call(SMARTCARD_DEVICE* smartcard, wStream* s,
if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status);
return status;
}
@ -622,7 +622,7 @@ void smartcard_trace_list_readers_call(SMARTCARD_DEVICE* smartcard, ListReaders_
if (unicode)
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) call->mszGroups, call->cBytes / 2, &mszGroupsA, 0, NULL, NULL);
WLog_DBG(TAG, "ListReaders%S_Call {", unicode ? "W" : "A");
WLog_DBG(TAG, "ListReaders%s_Call {", unicode ? "W" : "A");
pb = (BYTE*) &(call->hContext.pbContext);
@ -676,7 +676,7 @@ LONG smartcard_pack_list_readers_return(SMARTCARD_DEVICE* smartcard, wStream* s,
if ((error = smartcard_pack_write_size_align(smartcard, s, ret->cBytes, 4)))
{
WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %lu", error);
WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %ld", error);
return error;
}
}
@ -752,7 +752,7 @@ LONG smartcard_unpack_connect_common(SMARTCARD_DEVICE* smartcard, wStream* s, Co
if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(common->hContext))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %ld", status);
return status;
}
@ -780,7 +780,7 @@ LONG smartcard_unpack_connect_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, Co
if ((status = smartcard_unpack_connect_common(smartcard, s, &(call->Common))))
{
WLog_ERR(TAG, "smartcard_unpack_connect_common failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_connect_common failed with error %ld", status);
return status;
}
@ -803,7 +803,7 @@ LONG smartcard_unpack_connect_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, Co
call->szReader[count] = '\0';
if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->Common.hContext))))
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status);
return status;
}
@ -855,7 +855,7 @@ LONG smartcard_unpack_connect_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, Co
if ((status = smartcard_unpack_connect_common(smartcard, s, &(call->Common))))
{
WLog_ERR(TAG, "smartcard_unpack_connect_common failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_connect_common failed with error %ld", status);
return status;
}
@ -878,7 +878,7 @@ LONG smartcard_unpack_connect_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, Co
call->szReader[count] = '\0';
if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->Common.hContext))))
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status);
return status;
}
@ -923,13 +923,13 @@ LONG smartcard_pack_connect_return(SMARTCARD_DEVICE* smartcard, wStream* s, Conn
if ((status = smartcard_pack_redir_scard_context(smartcard, s, &(ret->hContext))))
{
WLog_ERR(TAG, "smartcard_pack_redir_scard_context failed with error %lu", status);
WLog_ERR(TAG, "smartcard_pack_redir_scard_context failed with error %ld", status);
return status;
}
if ((status = smartcard_pack_redir_scard_handle(smartcard, s, &(ret->hCard))))
{
WLog_ERR(TAG, "smartcard_pack_redir_scard_handle failed with error %lu", status);
WLog_ERR(TAG, "smartcard_pack_redir_scard_handle failed with error %ld", status);
return status;
}
@ -937,12 +937,12 @@ LONG smartcard_pack_connect_return(SMARTCARD_DEVICE* smartcard, wStream* s, Conn
if ((status = smartcard_pack_redir_scard_context_ref(smartcard, s, &(ret->hContext))))
{
WLog_ERR(TAG, "smartcard_pack_redir_scard_context_ref failed with error %lu", status);
WLog_ERR(TAG, "smartcard_pack_redir_scard_context_ref failed with error %ld", status);
return status;
}
if ((status = smartcard_pack_redir_scard_handle_ref(smartcard, s, &(ret->hCard))))
WLog_ERR(TAG, "smartcard_pack_redir_scard_handle_ref failed with error %lu", status);
WLog_ERR(TAG, "smartcard_pack_redir_scard_handle_ref failed with error %ld", status);
return status;
}
@ -997,13 +997,13 @@ LONG smartcard_unpack_reconnect_call(SMARTCARD_DEVICE* smartcard, wStream* s, Re
if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %ld", status);
return status;
}
if ((status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %ld", status);
return status;
}
@ -1021,12 +1021,12 @@ LONG smartcard_unpack_reconnect_call(SMARTCARD_DEVICE* smartcard, wStream* s, Re
if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status);
return status;
}
if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->hCard))))
WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %ld", status);
return status;
}
@ -1103,13 +1103,13 @@ LONG smartcard_unpack_hcard_and_disposition_call(SMARTCARD_DEVICE* smartcard, wS
if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %ld", status);
return status;
}
if ((status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %ld", status);
return status;
}
@ -1124,12 +1124,12 @@ LONG smartcard_unpack_hcard_and_disposition_call(SMARTCARD_DEVICE* smartcard, wS
if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status);
return status;
}
if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->hCard))))
WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %ld", status);
return status;
}
@ -1190,7 +1190,7 @@ LONG smartcard_unpack_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, wStr
if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %ld", status);
return status;
}
@ -1207,7 +1207,7 @@ LONG smartcard_unpack_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, wStr
if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status);
return status;
}
@ -1368,7 +1368,7 @@ LONG smartcard_unpack_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, wStr
if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %ld", status);
return status;
}
@ -1385,7 +1385,7 @@ LONG smartcard_unpack_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, wStr
if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status);
return status;
}
@ -1601,13 +1601,13 @@ LONG smartcard_unpack_state_call(SMARTCARD_DEVICE* smartcard, wStream* s, State_
if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %ld", status);
return status;
}
if ((status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %ld", status);
return status;
}
@ -1623,12 +1623,12 @@ LONG smartcard_unpack_state_call(SMARTCARD_DEVICE* smartcard, wStream* s, State_
if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status);
return status;
}
if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->hCard))))
WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %ld", status);
return status;
}
@ -1645,7 +1645,7 @@ LONG smartcard_pack_state_return(SMARTCARD_DEVICE* smartcard, wStream* s, State_
Stream_Write(s, ret->rgAtr, ret->cbAtrLen); /* rgAtr */
if ((status = smartcard_pack_write_size_align(smartcard, s, ret->cbAtrLen, 4)))
WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %lu", status);
WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %ld", status);
return status;
}
@ -1656,13 +1656,13 @@ LONG smartcard_unpack_status_call(SMARTCARD_DEVICE* smartcard, wStream* s, Statu
if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %ld", status);
return status;
}
if ((status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %ld", status);
return status;
}
@ -1679,12 +1679,12 @@ LONG smartcard_unpack_status_call(SMARTCARD_DEVICE* smartcard, wStream* s, Statu
if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status);
return status;
}
if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->hCard))))
WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %ld", status);
return status;
}
@ -1754,7 +1754,7 @@ LONG smartcard_pack_status_return(SMARTCARD_DEVICE* smartcard, wStream* s, Statu
Stream_Zero(s, ret->cBytes);
if ((status = smartcard_pack_write_size_align(smartcard, s, ret->cBytes, 4)))
WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %lu", status);
WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %ld", status);
return status;
}
@ -1834,13 +1834,13 @@ LONG smartcard_unpack_get_attrib_call(SMARTCARD_DEVICE* smartcard, wStream* s, G
if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %ld", status);
return status;
}
if ((status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %ld", status);
return status;
}
@ -1857,12 +1857,12 @@ LONG smartcard_unpack_get_attrib_call(SMARTCARD_DEVICE* smartcard, wStream* s, G
if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status);
return status;
}
if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->hCard))))
WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %ld", status);
return status;
}
@ -1927,7 +1927,7 @@ LONG smartcard_pack_get_attrib_return(SMARTCARD_DEVICE* smartcard, wStream* s, G
Stream_Write(s, ret->pbAttr, ret->cbAttrLen); /* pbAttr */
if ((status = smartcard_pack_write_size_align(smartcard, s, ret->cbAttrLen, 4)))
WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %lu", status);
WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %ld", status);
return status;
}
@ -1968,13 +1968,13 @@ LONG smartcard_unpack_control_call(SMARTCARD_DEVICE* smartcard, wStream* s, Cont
if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %ld", status);
return status;
}
if ((status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %ld", status);
return status;
}
@ -1993,13 +1993,13 @@ LONG smartcard_unpack_control_call(SMARTCARD_DEVICE* smartcard, wStream* s, Cont
if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status);
return status;
}
if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->hCard))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status);
return status;
}
@ -2107,7 +2107,7 @@ LONG smartcard_pack_control_return(SMARTCARD_DEVICE* smartcard, wStream* s, Cont
Stream_Write(s, ret->pvOutBuffer, ret->cbOutBufferSize); /* pvOutBuffer */
if ((error = smartcard_pack_write_size_align(smartcard, s, ret->cbOutBufferSize, 4)))
{
WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %lu", error);
WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %ld", error);
return error;
}
}
@ -2158,13 +2158,13 @@ LONG smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Tra
if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %ld", status);
return status;
}
if ((status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %ld", status);
return status;
}
@ -2200,13 +2200,13 @@ LONG smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Tra
if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status);
return status;
}
if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->hCard))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %ld", status);
return status;
}
@ -2528,7 +2528,7 @@ LONG smartcard_pack_transmit_return(SMARTCARD_DEVICE* smartcard, wStream* s, Tra
Stream_Write(s, pbExtraBytes, cbExtraBytes);
if ((error = smartcard_pack_write_size_align(smartcard, s, cbExtraBytes, 4)))
{
WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %lu!", error);
WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %ld!", error);
return error;
}
}
@ -2546,7 +2546,7 @@ LONG smartcard_pack_transmit_return(SMARTCARD_DEVICE* smartcard, wStream* s, Tra
Stream_Write(s, ret->pbRecvBuffer, ret->cbRecvLength);
if ((error = smartcard_pack_write_size_align(smartcard, s, ret->cbRecvLength, 4)))
{
WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %lu!", error);
WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %ld!", error);
return error;
}
}
@ -2619,7 +2619,7 @@ LONG smartcard_unpack_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, wS
if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %ld", status);
return status;
}
@ -2637,7 +2637,7 @@ LONG smartcard_unpack_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, wS
if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext))))
{
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status);
WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status);
return status;
}

View File

@ -42,7 +42,7 @@ add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE
target_link_libraries(${MODULE_NAME} freerdp winpr)
if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS)
if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS)
install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols)
endif()

View File

@ -231,7 +231,7 @@ static void tsmf_alsa_free(ITSMFAudioDevice *audio)
free(alsa);
}
#ifdef STATIC_CHANNELS
#ifdef BUILTIN_CHANNELS
#define freerdp_tsmf_client_audio_subsystem_entry alsa_freerdp_tsmf_client_audio_subsystem_entry
#else
#define freerdp_tsmf_client_audio_subsystem_entry FREERDP_API freerdp_tsmf_client_audio_subsystem_entry

View File

@ -39,7 +39,7 @@ else()
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
endif()
if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS)
if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS)
install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols)
endif()

View File

@ -541,7 +541,7 @@ static void tsmf_ffmpeg_free(ITSMFDecoder* decoder)
static BOOL initialized = FALSE;
#ifdef STATIC_CHANNELS
#ifdef BUILTIN_CHANNELS
#define freerdp_tsmf_client_subsystem_entry ffmpeg_freerdp_tsmf_client_decoder_subsystem_entry
#else
#define freerdp_tsmf_client_subsystem_entry FREERDP_API freerdp_tsmf_client_decoder_subsystem_entry

View File

@ -1010,7 +1010,7 @@ BOOL tsmf_gstreamer_sync(ITSMFDecoder* decoder, void (*cb)(void *), void *stream
return TRUE;
}
#ifdef STATIC_CHANNELS
#ifdef BUILTIN_CHANNELS
#define freerdp_tsmf_client_subsystem_entry gstreamer_freerdp_tsmf_client_decoder_subsystem_entry
#else
#define freerdp_tsmf_client_subsystem_entry FREERDP_API freerdp_tsmf_client_decoder_subsystem_entry

View File

@ -236,7 +236,7 @@ static void tsmf_oss_free(ITSMFAudioDevice* audio)
free(oss);
}
#ifdef STATIC_CHANNELS
#ifdef BUILTIN_CHANNELS
#define freerdp_tsmf_client_audio_subsystem_entry oss_freerdp_tsmf_client_audio_subsystem_entry
#else
#define freerdp_tsmf_client_audio_subsystem_entry FREERDP_API freerdp_tsmf_client_audio_subsystem_entry

View File

@ -358,7 +358,7 @@ static void tsmf_pulse_free(ITSMFAudioDevice *audio)
free(pulse);
}
#ifdef STATIC_CHANNELS
#ifdef BUILTIN_CHANNELS
ITSMFAudioDevice *pulse_freerdp_tsmf_client_audio_subsystem_entry(void)
#else
FREERDP_API ITSMFAudioDevice *freerdp_tsmf_client_audio_subsystem_entry(void)

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