From 6d23c5f6abc28964ef21d44cb53bfac9ec102e18 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 2 Aug 2013 14:02:21 +0200 Subject: [PATCH 01/28] Added proper CMake checks for libraries linked with urbdrc --- channels/urbdrc/client/CMakeLists.txt | 10 ++- cmake/FindDBus.cmake | 73 +++++++++++++++++ cmake/FindDbusGlib.cmake | 38 +++++++++ cmake/FindUDev.cmake | 53 ++++++++++++ cmake/FindUUID.cmake | 113 ++++++++++++++++++++++++++ 5 files changed, 284 insertions(+), 3 deletions(-) create mode 100644 cmake/FindDBus.cmake create mode 100644 cmake/FindDbusGlib.cmake create mode 100644 cmake/FindUDev.cmake create mode 100644 cmake/FindUUID.cmake diff --git a/channels/urbdrc/client/CMakeLists.txt b/channels/urbdrc/client/CMakeLists.txt index 53391f100..736097122 100644 --- a/channels/urbdrc/client/CMakeLists.txt +++ b/channels/urbdrc/client/CMakeLists.txt @@ -31,6 +31,10 @@ set(${MODULE_PREFIX}_SRCS include_directories(..) +find_package(UDev REQUIRED) +find_package(UUID REQUIRED) +find_package(DbusGlib REQUIRED) + add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "DVCPluginEntry") set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") @@ -38,9 +42,9 @@ set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") #set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} libusb-devman) set(${MODULE_PREFIX}_LIBS - dbus-glib-1 - udev - uuid) + ${DBUS_GLIB_LIBRARIES} + ${UDEV_LIBRARIES} + ${UUID_LIBRARIES}) set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHIC_BUILD} diff --git a/cmake/FindDBus.cmake b/cmake/FindDBus.cmake new file mode 100644 index 000000000..b002a754b --- /dev/null +++ b/cmake/FindDBus.cmake @@ -0,0 +1,73 @@ +# - Try to find the low-level D-Bus library +# Once done this will define +# +# DBUS_FOUND - system has D-Bus +# DBUS_INCLUDE_DIR - the D-Bus include directory +# DBUS_ARCH_INCLUDE_DIR - the D-Bus architecture-specific include directory +# DBUS_LIBRARIES - the libraries needed to use D-Bus + +# Copyright (c) 2008, Kevin Kofler, +# modeled after FindLibArt.cmake: +# Copyright (c) 2006, Alexander Neundorf, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +if (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES) + + # in cache already + SET(DBUS_FOUND TRUE) + +else (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES) + + IF (NOT WIN32) + FIND_PACKAGE(PkgConfig) + IF (PKG_CONFIG_FOUND) + # use pkg-config to get the directories and then use these values + # in the FIND_PATH() and FIND_LIBRARY() calls + pkg_check_modules(_DBUS_PC QUIET dbus-1) + ENDIF (PKG_CONFIG_FOUND) + ENDIF (NOT WIN32) + + FIND_PATH(DBUS_INCLUDE_DIR dbus/dbus.h + ${_DBUS_PC_INCLUDE_DIRS} + /usr/include + /usr/include/dbus-1.0 + /usr/local/include + ) + + FIND_PATH(DBUS_ARCH_INCLUDE_DIR dbus/dbus-arch-deps.h + ${_DBUS_PC_INCLUDE_DIRS} + /usr/lib${LIB_SUFFIX}/include + /usr/lib${LIB_SUFFIX}/dbus-1.0/include + /usr/lib64/include + /usr/lib64/dbus-1.0/include + /usr/lib/include + /usr/lib/dbus-1.0/include + ) + + FIND_LIBRARY(DBUS_LIBRARIES NAMES dbus-1 dbus + PATHS + ${_DBUS_PC_LIBDIR} + ) + + + if (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES) + set(DBUS_FOUND TRUE) + endif (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES) + + + if (DBUS_FOUND) + if (NOT DBus_FIND_QUIETLY) + message(STATUS "Found D-Bus: ${DBUS_LIBRARIES}") + endif (NOT DBus_FIND_QUIETLY) + else (DBUS_FOUND) + if (DBus_FIND_REQUIRED) + message(FATAL_ERROR "Could NOT find D-Bus") + endif (DBus_FIND_REQUIRED) + endif (DBUS_FOUND) + + MARK_AS_ADVANCED(DBUS_INCLUDE_DIR DBUS_ARCH_INCLUDE_DIR DBUS_LIBRARIES) + +endif (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES) + diff --git a/cmake/FindDbusGlib.cmake b/cmake/FindDbusGlib.cmake new file mode 100644 index 000000000..ae966bc65 --- /dev/null +++ b/cmake/FindDbusGlib.cmake @@ -0,0 +1,38 @@ +# DbusGlib library detection +# +# Copyright 2013 Thinstuff Technologies GmbH +# Copyright 2013 Armin Novak +# +# 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. + +find_package(PkgConfig) +pkg_check_modules(PC_DBUS_GLIB QUIET dbus-glib-1) +set(DBUS_GLIB_DEFINITIONS ${PC_DBUS_GLIB_CFLAGS_OTHER}) + +find_path(DBUS_GLIB_INCLUDE_DIR dbus/dbus-glib.h + HINTS ${PC_DBUS_GLIB_INCLUDEDIR} ${PC_DBUS_GLIB_INCLUDE_DIRS} + PATH_SUFFIXES dbus-glib-1 ) + +find_library(DBUS_GLIB_LIBRARY NAMES dbus-glib-1 dbus-glib + HINTS ${PC_DBUS_GLIB_LIBDIR} ${PC_DBUS_GLIB_LIBRARY_DIRS} ) + +set(DBUS_GLIB_LIBRARIES ${DBUS_GLIB_LIBRARY} ) +set(DBUS_GLIB_INCLUDE_DIRS ${DBUS_GLIB_INCLUDE_DIR} ) + +include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set DBUS_GLIB_FOUND to TRUE +# if all listed variables are TRUE +find_package_handle_standard_args(dbus-glib DEFAULT_MSG + DBUS_GLIB_LIBRARY DBUS_GLIB_INCLUDE_DIR) + +mark_as_advanced(DBUS_GLIB_INCLUDE_DIR DBUS_GLIB_LIBRARY ) diff --git a/cmake/FindUDev.cmake b/cmake/FindUDev.cmake new file mode 100644 index 000000000..f16761572 --- /dev/null +++ b/cmake/FindUDev.cmake @@ -0,0 +1,53 @@ +# razor-de: Configure libudev environment +# +# UDEV_FOUND - system has a libudev +# UDEV_INCLUDE_DIR - where to find header files +# UDEV_LIBRARIES - the libraries to link against udev +# UDEV_STABLE - it's true when is the version greater or equals to 143 - version when the libudev was stabilized in its API +# +# copyright (c) 2011 Petr Vanek +# Redistribution and use is allowed according to the terms of the BSD license. +# + +FIND_PATH( + UDEV_INCLUDE_DIR + libudev.h + /usr/include + /usr/local/include + ${UDEV_PATH_INCLUDES} +) + +FIND_LIBRARY( + UDEV_LIBRARIES + NAMES udev libudev + PATHS + /usr/lib${LIB_SUFFIX} + /usr/local/lib${LIB_SUFFIX} + ${UDEV_PATH_LIB} +) + +IF (UDEV_LIBRARIES AND UDEV_INCLUDE_DIR) + SET(UDEV_FOUND "YES") + execute_process(COMMAND pkg-config --atleast-version=143 libudev RESULT_VARIABLE UDEV_STABLE) + # retvale is 0 of the condition is "true" so we need to negate the value... + if (UDEV_STABLE) +set(UDEV_STABLE 0) + else (UDEV_STABLE) +set(UDEV_STABLE 1) + endif (UDEV_STABLE) + message(STATUS "libudev stable: ${UDEV_STABLE}") +ENDIF (UDEV_LIBRARIES AND UDEV_INCLUDE_DIR) + +IF (UDEV_FOUND) + MESSAGE(STATUS "Found UDev: ${UDEV_LIBRARIES}") + MESSAGE(STATUS " include: ${UDEV_INCLUDE_DIR}") +ELSE (UDEV_FOUND) + MESSAGE(STATUS "UDev not found.") + MESSAGE(STATUS "UDev: You can specify includes: -DUDEV_PATH_INCLUDES=/opt/udev/include") + MESSAGE(STATUS " currently found includes: ${UDEV_INCLUDE_DIR}") + MESSAGE(STATUS "UDev: You can specify libs: -DUDEV_PATH_LIB=/opt/udev/lib") + MESSAGE(STATUS " currently found libs: ${UDEV_LIBRARIES}") + IF (UDev_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find UDev library") + ENDIF (UDev_FIND_REQUIRED) +ENDIF (UDEV_FOUND) diff --git a/cmake/FindUUID.cmake b/cmake/FindUUID.cmake new file mode 100644 index 000000000..330e5caba --- /dev/null +++ b/cmake/FindUUID.cmake @@ -0,0 +1,113 @@ +# - Try to find UUID +# Once done this will define +# +# UUID_FOUND - system has UUID +# UUID_INCLUDE_DIRS - the UUID include directory +# UUID_LIBRARIES - Link these to use UUID +# UUID_DEFINITIONS - Compiler switches required for using UUID +# +# Copyright (c) 2006 Andreas Schneider +# +# Redistribution and use is allowed according to the terms of the New +# BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. +# + + +if (UUID_LIBRARIES AND UUID_INCLUDE_DIRS) +# in cache already +set(UUID_FOUND TRUE) +else (UUID_LIBRARIES AND UUID_INCLUDE_DIRS) +find_path(UUID_INCLUDE_DIR +NAMES +uuid/uuid.h +PATHS +${UUID_DIR}/include +$ENV{UUID_DIR}/include +$ENV{UUID_DIR} +${DELTA3D_EXT_DIR}/inc +$ENV{DELTA_ROOT}/ext/inc +$ENV{DELTA_ROOT} +~/Library/Frameworks +/Library/Frameworks +/usr/local/include +/usr/include +/usr/include/gdal +/sw/include # Fink +/opt/local/include # DarwinPorts +/opt/csw/include # Blastwave +/opt/include +[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session\ Manager\\Environment;OSG_ROOT]/include +/usr/freeware/include + +) + +find_library(UUID_LIBRARY +NAMES +uuid +PATHS +${UUID_DIR}/lib +$ENV{UUID_DIR}/lib +$ENV{UUID_DIR} +${DELTA3D_EXT_DIR}/lib +$ENV{DELTA_ROOT}/ext/lib +$ENV{DELTA_ROOT} +$ENV{OSG_ROOT}/lib +~/Library/Frameworks +/Library/Frameworks +/usr/local/lib +/usr/lib +/sw/lib +/opt/local/lib +/opt/csw/lib +/opt/lib +/usr/freeware/lib64 +) + +find_library(UUID_LIBRARY_DEBUG +NAMES +uuidd +PATHS +${UUID_DIR}/lib +$ENV{UUID_DIR}/lib +$ENV{UUID_DIR} +${DELTA3D_EXT_DIR}/lib +$ENV{DELTA_ROOT}/ext/lib +$ENV{DELTA_ROOT} +$ENV{OSG_ROOT}/lib +~/Library/Frameworks +/Library/Frameworks +/usr/local/lib +/usr/lib +/sw/lib +/opt/local/lib +/opt/csw/lib +/opt/lib +/usr/freeware/lib64 +) + +set(UUID_INCLUDE_DIRS +${UUID_INCLUDE_DIR} +) +set(UUID_LIBRARIES +${UUID_LIBRARY} +) + +if (UUID_INCLUDE_DIRS AND UUID_LIBRARIES) +set(UUID_FOUND TRUE) +endif (UUID_INCLUDE_DIRS AND UUID_LIBRARIES) + +if (UUID_FOUND) +if (NOT UUID_FIND_QUIETLY) +message(STATUS "Found UUID: ${UUID_LIBRARIES}") +endif (NOT UUID_FIND_QUIETLY) +else (UUID_FOUND) +if (UUID_FIND_REQUIRED) +message(FATAL_ERROR "Could not find UUID") +endif (UUID_FIND_REQUIRED) +endif (UUID_FOUND) + +# show the UUID_INCLUDE_DIRS and UUID_LIBRARIES variables only in the advanced view +mark_as_advanced(UUID_INCLUDE_DIRS UUID_LIBRARIES) + +endif (UUID_LIBRARIES AND UUID_INCLUDE_DIRS) From 9295838f812b4b66bbe4df32f55a51ca8350d95d Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 5 Aug 2013 16:39:49 +0200 Subject: [PATCH 02/28] Added simple converter generating docbook XML from command line argument struct. Modified xfreerdp.1.xml to include generated documentation. Modified CMake to regenerate manpages correctly using the generator. --- client/X11/CMakeLists.txt | 11 +- client/X11/generate_argument_docbook.c | 172 +++++++ client/X11/xfreerdp.1.xml | 619 ++----------------------- 3 files changed, 232 insertions(+), 570 deletions(-) create mode 100644 client/X11/generate_argument_docbook.c diff --git a/client/X11/CMakeLists.txt b/client/X11/CMakeLists.txt index baecfe7a4..eab3cf229 100644 --- a/client/X11/CMakeLists.txt +++ b/client/X11/CMakeLists.txt @@ -68,10 +68,17 @@ set(${MODULE_PREFIX}_LIBS ${CMAKE_DL_LIBS}) if(WITH_MANPAGES) + add_executable(generate_argument_docbook + generate_argument_docbook.c) + target_link_libraries(generate_argument_docbook winpr-utils freerdp-core freerdp-utils freerdp-client) + if(XMLTO_FOUND) add_custom_command(OUTPUT xfreerdp.1 - COMMAND ${XMLTO_EXECUTABLE} man ${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp.1.xml - DEPENDS xfreerdp.1.xml) + COMMAND generate_argument_docbook + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp.1.xml ${CMAKE_CURRENT_BINARY_DIR}/ + COMMAND ${XMLTO_EXECUTABLE} man xfreerdp.1.xml + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS xfreerdp.1.xml generate_argument_docbook) add_custom_target(xfreerdp.manpage ALL DEPENDS xfreerdp.1) diff --git a/client/X11/generate_argument_docbook.c b/client/X11/generate_argument_docbook.c new file mode 100644 index 000000000..df1f90376 --- /dev/null +++ b/client/X11/generate_argument_docbook.c @@ -0,0 +1,172 @@ + +#include +#include +#include + +#include + +/* We need to include the command line c file to get access to + * the argument struct. */ +#include "../common/cmdline.c" + +LPSTR tmp = NULL; + +LPCSTR tr_esc_str(LPCSTR arg) +{ + size_t cs = 0, x, ds; + size_t s; + + if( NULL == arg ) + return NULL; + + s = strlen(arg); + + /* Find trailing whitespaces */ + while( (s > 0) && isspace(arg[s-1])) + s--; + + /* Prepare a initial buffer with the size of the result string. */ + tmp = malloc(s * sizeof(LPCSTR)); + if( NULL == tmp ) + { + fprintf(stderr, "Could not allocate string buffer."); + exit(-2); + } + + /* Copy character for character and check, if it is necessary to escape. */ + ds = s + 1; + for(x=0; x': + ds += 3; + tmp = realloc(tmp, ds * sizeof(LPCSTR)); + if( NULL == tmp ) + { + fprintf(stderr, "Could not reallocate string buffer."); + exit(-4); + } + tmp[cs++] = '&'; + tmp[cs++] = 'g'; + tmp[cs++] = 't'; + tmp[cs++] = ';'; + break; + case '\'': + ds += 5; + tmp = realloc(tmp, ds * sizeof(LPCSTR)); + if( NULL == tmp ) + { + fprintf(stderr, "Could not reallocate string buffer."); + exit(-5); + } + tmp[cs++] = '&'; + tmp[cs++] = 'a'; + tmp[cs++] = 'p'; + tmp[cs++] = 'o'; + tmp[cs++] = 's'; + tmp[cs++] = ';'; + break; + case '"': + ds += 5; + tmp = realloc(tmp, ds * sizeof(LPCSTR)); + if( NULL == tmp ) + { + fprintf(stderr, "Could not reallocate string buffer."); + exit(-6); + } + tmp[cs++] = '&'; + tmp[cs++] = 'q'; + tmp[cs++] = 'u'; + tmp[cs++] = 'o'; + tmp[cs++] = 't'; + tmp[cs++] = ';'; + break; + case '&': + ds += 4; + tmp = realloc(tmp, ds * sizeof(LPCSTR)); + if( NULL == tmp ) + { + fprintf(stderr, "Could not reallocate string buffer."); + exit(-7); + } + tmp[cs++] = '&'; + tmp[cs++] = 'a'; + tmp[cs++] = 'm'; + tmp[cs++] = 'p'; + tmp[cs++] = ';'; + break; + default: + tmp[cs++] = arg[x]; + break; + } + + /* Assure, the string is '\0' terminated. */ + tmp[ds-1] = '\0'; + } + + return tmp; +} + +int main(int argc, char *argv[]) +{ + size_t x; + const char *fname = "xfreerdp-argument.1.xml"; + FILE *fp = NULL; + + /* Open output file for writing, truncate if existing. */ + fp = fopen(fname, "w"); + if( NULL == fp ) + { + fprintf(stderr, "Could not open '%s' for writing.", fname); + return -1; + } + + /* The tag used as header in the manpage */ + fprintf(fp, "\n"); + fprintf(fp, "\tSyntax\n"); + fprintf(fp, "\t\t\n"); + + /* Iterate over argument struct and write data to docbook 4.5 + * compatible XML */ + for(x=0; x\n"); + fprintf(fp, "\t\t\t\t%s\n", tr_esc_str(arg->Name) ); + fprintf(fp, "\t\t\t\t\n"); + if( COMMAND_LINE_VALUE_REQUIRED == arg->Flags ) + fprintf(fp, "\t\t\t\t\t%s %s\n", tr_esc_str(arg->Text), tr_esc_str(arg->Format)); + else + fprintf(fp, "\t\t\t\t\t%s\n", tr_esc_str(arg->Text)); + if( NULL != arg->LongText ) + fprintf(fp, "\t\t\t\t\t%s\n", tr_esc_str(arg->LongText)); + + fprintf(fp, "\t\t\t\t\n"); + fprintf(fp, "\t\t\t\n"); + } + + fprintf(fp, "\t\t\n"); + fprintf(fp, "\t\n"); + fclose(fp); + + if(NULL != tmp) + free(tmp); + + return 0; +} + diff --git a/client/X11/xfreerdp.1.xml b/client/X11/xfreerdp.1.xml index bf7f774e6..a2f7e7ba0 100644 --- a/client/X11/xfreerdp.1.xml +++ b/client/X11/xfreerdp.1.xml @@ -1,571 +1,54 @@ - + + + ] +> + - - 2011-08-27 - - The FreeRDP Team - - - - xfreerdp - 1 - freerdp - xfreerdp - - - xfreerdp - FreeRDP X11 client - - - - 2011-08-27 - - - xfreerdp [options] server[:port] [[options] server[:port] …] - - - - - 2011-08-27 - - DESCRIPTION - - xfreerdp is an X11 Remote Desktop Protocol (RDP) - client which is part of the FreeRDP project. An RDP server is built-in - to many editions of Windows. Alternative servers included xrdp and VRDP (VirtualBox). - - - - OPTIONS - - - -0 - - - Attach to the admin console of the server. - - - - - -a bpp - - - Sets the color depth for the connection to bpp bits per pixel. - Valid values are 8, 15, 16, 24 and 32. The default value is the color depth of the FreeRDP-window. - - - - - -c dir - - - Sets the working-dir to dir. - This parameter is only used when an AlternateShell () is requested. - dir should contain the executable file specified in the AlternateShell. - - - - - -D - - - Removes the windows decorations. - - - - - -d - - - Domain used in authentication. - - - - - -f - - - start in full screen mode. This mode can always be en- and disabled using Ctrl-Alt-Enter. - - - - - -T text - - - Sets the window title to text. - - - - - -g geometry - - - Sets the size of the FreeRDP window (and of the remote desktop, when establishing a new connection). - geometry can have one of the following forms: - - - - WxH - - in this case the resulting window will be of - WxH pixels. - - - - - P% - - in this case the resulting window will be P% - of your screen. - - - - - The special keyword workarea - - in this case the resulting window will be of the same size as your workarea. - - - - - - - - -h - - - Print help. - - - - - -k id - - - Sets the keyboard-layout-id to id. - - - - - -K - - - Do not interfere with window manager bindings. Normally, xfreerdp captures all keystrokes while its window is focused. - - - - - -n hostname - - - Set the reported client hostname to hostname. - Default is to automatically detect the hostname. - - - - - -o - - - Play audio on the console instead of redirecting to the client. - - - - - -p password - - - Password used in authentication. - - - - - -s shell - - - Sets the startup-shell to shell. - This parameter should contain a complete path to the alternate shell. - If the alternete shell requires a different working directory use . - - - - - -t port - - - Connect to port, instead of the default 3389. - - - - - -u username - - - Username used in authentication. - - - - - -x flag - - - Set the experience performance flags. - flag can be one of: - - - - m - (modem): Equivalent to 15. - - - - - b - (broadband): Equivalent to 1. - - - - - l - (lan): Equivalent to 0. - - - - - num - A hexadecimal number that - represents a bit-mask, were numbers mean the following - Taken from - MS-RDPBCGR Section 2.2.1.11.1.1.1 - Extended Info Packet: - - - 1: Disable desktop wallpaper. - - - 2: Disable full-window drag (only the window outline is displayed when the window is moved). - - - 4: Disable menu animations. - - - 8: Disable user interface themes. - - - 20: Disable mouse cursor shadows. - - - 40: Disable cursor blinking. - - - 80: Enable font smoothing. - - - 100: Enable Desktop Composition. - - - - - - - - - - -X xid - - embed xfreerdp into window with xid. - - - - -z - - - Enable compression. - - - - - --app - - - initialize a RemoteApp connection. This implies -g workarea. - - - - - --no-auth - - - Skips authentication. This is useful e.g. for the current FreeRDP server that doesn't yet support server-side authentication. - - - - - --authonly - - - Only authenticates. This is useful to test your credentials (username and password). - Returns status code 0 if the client can connect, 1 otherwise. Requires a username, - password and connection host at the command line. - - - - - --bcv3 codec - - Use codec for bitmap cache v3 - - - - - --no-bmp-cache - - - Disable bitmap cache. - - - - - --certificate-name name - - - use name for the logon certificate, instead of the server name - - - - - --composition - - - Enable composition (RDVH only, not to be confused with remote composition). - - - - - --ext extname - - - load extension extname - - - - - --no-fastpath - - - Disables fast-path. Use slow-path packets instead, which have larger headers. - It might be good for debugging certain issues when you suspect it might be - linked to the parsing of one of the two header types. - - - - - --from-stdin - - Prompts for unspecified arguments -u username, -p - password, -d domain and connection host. This is useful to - hide arguments from ps. Also useful for scripts that will - feed these arguments to the client via (what else?) stdin. - - - - - --disable-full-window-drag - - - Disable full window drag. - - - - - --gdi backend - - - GDI (Graphics Device Interface) rendering backend. backend can be either sw (software) or hw (hardware). - - - - - --ignore-certificate - - - ignore verification of logon certificate. - - - - - --kbd-list - - - list all keyboard layout ids used by -k - - - - - --disable-menu-animations - - - Disable menu animations. - - - - - --no-motion - - - Don't send mouse motion events. - - - - - --no-nego - - disable negotiation of security layer and enforce highest enabled security protocol. - - - - - --no-nla - - - Disable network level authentication. - - - - - --nsc - - - Enable NSCodec. - - - - - --no-osb - - - Disable off screen bitmaps. - - - - - --pcb blob - - - Use preconnection blob. - - - - - --pcid id - - - Use preconnection id. - - - - - --plugin pluginname - - - load pluginname - - - - - --no-rdp - - - Disable Standard RDP encryption. - - - - - --rfx - - - Enable RemoteFX. - - - - - --rfx-mode - - - RemoteFX operational flags. flags can be either v[ideo], i[mage]), default is video. - - - - - --no-salted-checksum - - - disable salted checksums with Standard RDP encryption. - - - - - --ntlm - - - force NTLM protocol version. version can be one of 1 or 2. - - - - - --sec proto - - - force protocol security. proto can be one of rdp, tls or nla. - - - - - --disable-theming - - - Disable theming. - - - - - --no-tls - - - Disable TLS encryption. - - - - - --tsg -username -password -hostname - - - Use Terminal Server Gateway with -username -password -hostname. - - - - - --version - + + 2013-08-05 + + The FreeRDP Team + + + + xfreerdp + 1 + freerdp + xfreerdp + + + xfreerdp + FreeRDP X11 client + + + + 2013-08-05 + - Print version information. - - - - - --disable-wallpaper - - - Disable wallpaper. - - - - - - - LINKS - - http://www.freerdp.com/ - - + xfreerdp [file] [options] [/v:server[:port]] + + + + + 2011-08-27 + + DESCRIPTION + + xfreerdp is an X11 Remote Desktop Protocol (RDP) + client which is part of the FreeRDP project. An RDP server is built-in + to many editions of Windows. Alternative servers included xrdp and VRDP (VirtualBox). + + + + &syntax; + + + LINKS + + http://www.freerdp.com/ + + From 3fa1407c091f41188d2ec1ac0366efe7cf091ed2 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 6 Aug 2013 09:29:30 +0200 Subject: [PATCH 03/28] Removed extended text field. --- client/X11/generate_argument_docbook.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/client/X11/generate_argument_docbook.c b/client/X11/generate_argument_docbook.c index df1f90376..1c324acf9 100644 --- a/client/X11/generate_argument_docbook.c +++ b/client/X11/generate_argument_docbook.c @@ -147,14 +147,12 @@ int main(int argc, char *argv[]) const COMMAND_LINE_ARGUMENT_A *arg = &args[x]; fprintf(fp, "\t\t\t\n"); - fprintf(fp, "\t\t\t\t%s\n", tr_esc_str(arg->Name) ); - fprintf(fp, "\t\t\t\t\n"); if( COMMAND_LINE_VALUE_REQUIRED == arg->Flags ) - fprintf(fp, "\t\t\t\t\t%s %s\n", tr_esc_str(arg->Text), tr_esc_str(arg->Format)); + fprintf(fp, "\t\t\t\t/%s %s\n", tr_esc_str(arg->Name), tr_esc_str(arg->Format) ); else - fprintf(fp, "\t\t\t\t\t%s\n", tr_esc_str(arg->Text)); - if( NULL != arg->LongText ) - fprintf(fp, "\t\t\t\t\t%s\n", tr_esc_str(arg->LongText)); + fprintf(fp, "\t\t\t\t/%s\n", tr_esc_str(arg->Name) ); + fprintf(fp, "\t\t\t\t\n"); + fprintf(fp, "\t\t\t\t\t%s\n", tr_esc_str(arg->Text)); fprintf(fp, "\t\t\t\t\n"); fprintf(fp, "\t\t\t\n"); From 38be366a67cd16a976eb6cff145c2e139fc9bbac Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 6 Aug 2013 10:23:43 +0200 Subject: [PATCH 04/28] Fixed generation of configure header, now replacing date fields with current date. Added CMake script to generate a variable containing the current date. Removed last argument (the terminating NULL element) from output. --- client/X11/CMakeLists.txt | 15 ++++++++++++--- client/X11/generate_argument_docbook.c | 9 ++++++++- client/X11/{xfreerdp.1.xml => xfreerdp.1.xml.in} | 6 +++--- cmake/today.cmake | 16 ++++++++++++++++ 4 files changed, 39 insertions(+), 7 deletions(-) rename client/X11/{xfreerdp.1.xml => xfreerdp.1.xml.in} (94%) create mode 100644 cmake/today.cmake diff --git a/client/X11/CMakeLists.txt b/client/X11/CMakeLists.txt index eab3cf229..5d104cb94 100644 --- a/client/X11/CMakeLists.txt +++ b/client/X11/CMakeLists.txt @@ -68,17 +68,26 @@ set(${MODULE_PREFIX}_LIBS ${CMAKE_DL_LIBS}) if(WITH_MANPAGES) + if(XMLTO_FOUND) + # We need the variable ${MAN_TODAY} to contain the current date in ISO + # format to replace it in the configure_file step. + include(today) + + TODAY(MAN_TODAY) + + configure_file(xfreerdp.1.xml.in xfreerdp.1.xml @ONLY) + add_executable(generate_argument_docbook generate_argument_docbook.c) target_link_libraries(generate_argument_docbook winpr-utils freerdp-core freerdp-utils freerdp-client) - if(XMLTO_FOUND) add_custom_command(OUTPUT xfreerdp.1 COMMAND generate_argument_docbook - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp.1.xml ${CMAKE_CURRENT_BINARY_DIR}/ COMMAND ${XMLTO_EXECUTABLE} man xfreerdp.1.xml WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - DEPENDS xfreerdp.1.xml generate_argument_docbook) + DEPENDS + ${CMAKE_CURRENT_BINARY_DIR}/xfreerdp.1.xml + generate_argument_docbook) add_custom_target(xfreerdp.manpage ALL DEPENDS xfreerdp.1) diff --git a/client/X11/generate_argument_docbook.c b/client/X11/generate_argument_docbook.c index 1c324acf9..37fe96ce8 100644 --- a/client/X11/generate_argument_docbook.c +++ b/client/X11/generate_argument_docbook.c @@ -123,6 +123,7 @@ LPCSTR tr_esc_str(LPCSTR arg) int main(int argc, char *argv[]) { + size_t elements = sizeof(args)/sizeof(args[0]); size_t x; const char *fname = "xfreerdp-argument.1.xml"; FILE *fp = NULL; @@ -142,7 +143,13 @@ int main(int argc, char *argv[]) /* Iterate over argument struct and write data to docbook 4.5 * compatible XML */ - for(x=0; x - 2013-08-05 + @MAN_TODAY@ The FreeRDP Team @@ -25,7 +25,7 @@ PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" - 2013-08-05 + @MAN_TODAY@ xfreerdp [file] [options] [/v:server[:port]] @@ -33,7 +33,7 @@ PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" - 2011-08-27 + @MAN_TODAY@ DESCRIPTION diff --git a/cmake/today.cmake b/cmake/today.cmake new file mode 100644 index 000000000..51d0031a8 --- /dev/null +++ b/cmake/today.cmake @@ -0,0 +1,16 @@ +# This script returns the current date in ISO format +# +# YYYY-MM-DD +# +MACRO (TODAY RESULT) + IF (WIN32) + EXECUTE_PROCESS(COMMAND "cmd" " /C date +%Y-%m-%d" OUTPUT_VARIABLE ${RESULT}) + string(REGEX REPLACE "(..)/(..)/..(..).*" "\\1/\\2/\\3" ${RESULT} ${${RESULT}}) + ELSEIF(UNIX) + EXECUTE_PROCESS(COMMAND "date" "+%Y-%m-%d" OUTPUT_VARIABLE ${RESULT}) + string(REGEX REPLACE "(..)/(..)/..(..).*" "\\1/\\2/\\3" ${RESULT} ${${RESULT}}) + ELSE (WIN32) + MESSAGE(SEND_ERROR "date not implemented") + SET(${RESULT} 000000) + ENDIF (WIN32) +ENDMACRO (TODAY) From e80effa2a883736328fc669c5f1a384329ae9e62 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 6 Aug 2013 11:37:11 +0200 Subject: [PATCH 05/28] Added examples with short description to manpage. Added placeholder for channel documentation. --- client/X11/xfreerdp-channels.1.xml | 11 ++++ client/X11/xfreerdp-examples.1.xml | 89 ++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 client/X11/xfreerdp-channels.1.xml create mode 100644 client/X11/xfreerdp-examples.1.xml diff --git a/client/X11/xfreerdp-channels.1.xml b/client/X11/xfreerdp-channels.1.xml new file mode 100644 index 000000000..4496f70e0 --- /dev/null +++ b/client/X11/xfreerdp-channels.1.xml @@ -0,0 +1,11 @@ + + Channels + + + foo + + bar + + + + diff --git a/client/X11/xfreerdp-examples.1.xml b/client/X11/xfreerdp-examples.1.xml new file mode 100644 index 000000000..bb46f3025 --- /dev/null +++ b/client/X11/xfreerdp-examples.1.xml @@ -0,0 +1,89 @@ + + Examples + + + xfreerdp connection.rdp /p:Pwd123! /f + + Connect in fullscreen mode using a stored configuration connection.rdp and the password Pwd123! + + + + xfreerdp /u:CONTOSO\\JohnDoe /p:Pwd123! /v:rdp.contoso.com + + Connect to host rdp.contoso.com with user CONTOSO\\JohnDoe and password Pwd123! + + + + xfreerdp /u:JohnDoe /p:Pwd123! /w:1366 /h:768 /v:192.168.1.100:4489 + + Connect to host 192.168.1.100 on port 4489 with user JohnDoe, password Pwd123!. The screen width is set to 1366 and the height to 768 + + + + xfreerdp /u:JohnDoe /p:Pwd123! /vmconnect:C824F53E-95D2-46C6-9A18-23A5BB403532 /v:192.168. 1.100 + + Establish a connection to host 192.168.1.100 with user JohnDoe, password Pwd123! and connect to Hyper-V console (use port 2179, disable negotiation) with VMID C824F53E-95D2-46C6-9A18-23A5BB403532 + + + + +clipboard + + Activate clipboard redirection + + + + /drive:home,/home/user + + Activate drive redirection of /home/user as home drive + + + + /smartcard:<device> + + Activate smartcard redirection for device device + + + + /printer:<device>,<driver> + + Activate printer redirection for printer device using driver driver + + + + /serial:<device> + + Activate serial port redirection for port device + + + + /parallel:<device> + + Activate parallel port redirection for port device + + + + /sound:sys:alsa + + Activate audio output redirection using device sys:alsa + + + + /microphone:sys:alsa + + Activate audio input redirection using device sys:alsa + + + + /multimedia:sys:alsa + + Activate multimedia redirection using device sys:alsa + + + + /usb:id,dev:054c:0268 + + Activate USB device redirection for the device identified by 054c:0268 + + + + From be37b91e3d320c443bdd26aca4b9f246f6c8f5f5 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 6 Aug 2013 11:41:38 +0200 Subject: [PATCH 06/28] Minor adjustments in naming. --- client/X11/CMakeLists.txt | 6 +++++- client/X11/generate_argument_docbook.c | 2 +- client/X11/xfreerdp.1.xml.in | 6 ++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/client/X11/CMakeLists.txt b/client/X11/CMakeLists.txt index 5d104cb94..4e6ee98d7 100644 --- a/client/X11/CMakeLists.txt +++ b/client/X11/CMakeLists.txt @@ -75,7 +75,7 @@ if(WITH_MANPAGES) TODAY(MAN_TODAY) - configure_file(xfreerdp.1.xml.in xfreerdp.1.xml @ONLY) + configure_file(xfreerdp.1.xml.in xfreerdp.1.xml @ONLY IMMEDIATE) add_executable(generate_argument_docbook generate_argument_docbook.c) @@ -83,6 +83,10 @@ if(WITH_MANPAGES) add_custom_command(OUTPUT xfreerdp.1 COMMAND generate_argument_docbook + COMMAND ${CMAKE_COMMAND} -E copy + ${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-channels.1.xml ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E copy + ${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-examples.1.xml ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${XMLTO_EXECUTABLE} man xfreerdp.1.xml WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS diff --git a/client/X11/generate_argument_docbook.c b/client/X11/generate_argument_docbook.c index 37fe96ce8..2de0d02f0 100644 --- a/client/X11/generate_argument_docbook.c +++ b/client/X11/generate_argument_docbook.c @@ -138,7 +138,7 @@ int main(int argc, char *argv[]) /* The tag used as header in the manpage */ fprintf(fp, "\n"); - fprintf(fp, "\tSyntax\n"); + fprintf(fp, "\tOptions\n"); fprintf(fp, "\t\t\n"); /* Iterate over argument struct and write data to docbook 4.5 diff --git a/client/X11/xfreerdp.1.xml.in b/client/X11/xfreerdp.1.xml.in index ac67884d3..4dbb42083 100644 --- a/client/X11/xfreerdp.1.xml.in +++ b/client/X11/xfreerdp.1.xml.in @@ -3,6 +3,8 @@ PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ + + ] > @@ -45,6 +47,10 @@ PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" &syntax; + &channels; + + &examples; + LINKS From 68511fc7d4c42bb6dd723e60f4f0141042a11049 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 6 Aug 2013 12:23:31 +0200 Subject: [PATCH 07/28] Added better formatting of commands in manpage. --- client/X11/generate_argument_docbook.c | 4 +- client/X11/xfreerdp-examples.1.xml | 54 +++++++++++++------------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/client/X11/generate_argument_docbook.c b/client/X11/generate_argument_docbook.c index 2de0d02f0..0c1da21a8 100644 --- a/client/X11/generate_argument_docbook.c +++ b/client/X11/generate_argument_docbook.c @@ -155,9 +155,9 @@ int main(int argc, char *argv[]) fprintf(fp, "\t\t\t\n"); if( COMMAND_LINE_VALUE_REQUIRED == arg->Flags ) - fprintf(fp, "\t\t\t\t/%s %s\n", tr_esc_str(arg->Name), tr_esc_str(arg->Format) ); + fprintf(fp, "\t\t\t\t %s\n", tr_esc_str(arg->Name), tr_esc_str(arg->Format) ); else - fprintf(fp, "\t\t\t\t/%s\n", tr_esc_str(arg->Name) ); + fprintf(fp, "\t\t\t\t\n", tr_esc_str(arg->Name) ); fprintf(fp, "\t\t\t\t\n"); fprintf(fp, "\t\t\t\t\t%s\n", tr_esc_str(arg->Text)); diff --git a/client/X11/xfreerdp-examples.1.xml b/client/X11/xfreerdp-examples.1.xml index bb46f3025..462649f68 100644 --- a/client/X11/xfreerdp-examples.1.xml +++ b/client/X11/xfreerdp-examples.1.xml @@ -2,87 +2,87 @@ Examples - xfreerdp connection.rdp /p:Pwd123! /f + xfreerdp connection.rdp /p:Pwd123! /f - Connect in fullscreen mode using a stored configuration connection.rdp and the password Pwd123! + Connect in fullscreen mode using a stored configuration connection.rdp and the password Pwd123! - xfreerdp /u:CONTOSO\\JohnDoe /p:Pwd123! /v:rdp.contoso.com + xfreerdp /u:CONTOSO\\JohnDoe /p:Pwd123! /v:rdp.contoso.com - Connect to host rdp.contoso.com with user CONTOSO\\JohnDoe and password Pwd123! + Connect to host rdp.contoso.com with user CONTOSO\\JohnDoe and password Pwd123! - xfreerdp /u:JohnDoe /p:Pwd123! /w:1366 /h:768 /v:192.168.1.100:4489 + xfreerdp /u:JohnDoe /p:Pwd123! /w:1366 /h:768 /v:192.168.1.100:4489 - Connect to host 192.168.1.100 on port 4489 with user JohnDoe, password Pwd123!. The screen width is set to 1366 and the height to 768 + Connect to host 192.168.1.100 on port 4489 with user JohnDoe, password Pwd123!. The screen width is set to 1366 and the height to 768 - xfreerdp /u:JohnDoe /p:Pwd123! /vmconnect:C824F53E-95D2-46C6-9A18-23A5BB403532 /v:192.168. 1.100 + xfreerdp /u:JohnDoe /p:Pwd123! /vmconnect:C824F53E-95D2-46C6-9A18-23A5BB403532 /v:192.168. 1.100 - Establish a connection to host 192.168.1.100 with user JohnDoe, password Pwd123! and connect to Hyper-V console (use port 2179, disable negotiation) with VMID C824F53E-95D2-46C6-9A18-23A5BB403532 + Establish a connection to host 192.168.1.100 with user JohnDoe, password Pwd123! and connect to Hyper-V console (use port 2179, disable negotiation) with VMID C824F53E-95D2-46C6-9A18-23A5BB403532 - +clipboard + +clipboard Activate clipboard redirection - /drive:home,/home/user + /drive:home,/home/user - Activate drive redirection of /home/user as home drive + Activate drive redirection of /home/user as home drive - /smartcard:<device> + /smartcard:<device> - Activate smartcard redirection for device device + Activate smartcard redirection for device device - /printer:<device>,<driver> + /printer:<device>,<driver> - Activate printer redirection for printer device using driver driver + Activate printer redirection for printer device using driver driver - /serial:<device> + /serial:<device> - Activate serial port redirection for port device + Activate serial port redirection for port device - /parallel:<device> + /parallel:<device> - Activate parallel port redirection for port device + Activate parallel port redirection for port device - /sound:sys:alsa + /sound:sys:alsa - Activate audio output redirection using device sys:alsa + Activate audio output redirection using device sys:alsa - /microphone:sys:alsa + /microphone:sys:alsa - Activate audio input redirection using device sys:alsa + Activate audio input redirection using device sys:alsa - /multimedia:sys:alsa + /multimedia:sys:alsa - Activate multimedia redirection using device sys:alsa + Activate multimedia redirection using device sys:alsa - /usb:id,dev:054c:0268 + /usb:id,dev:054c:0268 - Activate USB device redirection for the device identified by 054c:0268 + Activate USB device redirection for the device identified by 054c:0268 From 6c676e8795aea013dbacbf8a7f82f526793d5525 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 6 Aug 2013 12:25:38 +0200 Subject: [PATCH 08/28] Removed placeholder for channel documentation until it is available. --- client/X11/xfreerdp-channels.1.xml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/client/X11/xfreerdp-channels.1.xml b/client/X11/xfreerdp-channels.1.xml index 4496f70e0..e69de29bb 100644 --- a/client/X11/xfreerdp-channels.1.xml +++ b/client/X11/xfreerdp-channels.1.xml @@ -1,11 +0,0 @@ - - Channels - - - foo - - bar - - - - From ef574c0fcc7184394b2844c26da9bf902539e9b7 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 6 Aug 2013 12:40:48 +0200 Subject: [PATCH 09/28] Added missing dependency for custom command generating manpage. --- client/X11/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/X11/CMakeLists.txt b/client/X11/CMakeLists.txt index 4e6ee98d7..c8c6ae1a7 100644 --- a/client/X11/CMakeLists.txt +++ b/client/X11/CMakeLists.txt @@ -91,6 +91,8 @@ if(WITH_MANPAGES) WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/xfreerdp.1.xml + ${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-examples.1.xml + ${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-channels.1.xml generate_argument_docbook) add_custom_target(xfreerdp.manpage ALL From 9b95c555742a70b9e81be4ee5622e6d743403972 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 6 Aug 2013 15:02:36 +0200 Subject: [PATCH 10/28] Replaced xmlto with xsltproc to word around a bug preventing manpages to be build, when there are spaces in the build path. --- client/X11/CMakeLists.txt | 15 ++++++----- cmake/FindDocBookXSL.cmake | 52 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 6 deletions(-) create mode 100644 cmake/FindDocBookXSL.cmake diff --git a/client/X11/CMakeLists.txt b/client/X11/CMakeLists.txt index c8c6ae1a7..1ccfaea17 100644 --- a/client/X11/CMakeLists.txt +++ b/client/X11/CMakeLists.txt @@ -19,7 +19,7 @@ set(MODULE_NAME "xfreerdp-client") set(MODULE_PREFIX "FREERDP_CLIENT_X11_CONTROL") -include(FindXmlto) +include(FindDocBookXSL) include_directories(${X11_INCLUDE_DIRS}) set(${MODULE_PREFIX}_SRCS @@ -68,7 +68,10 @@ set(${MODULE_PREFIX}_LIBS ${CMAKE_DL_LIBS}) if(WITH_MANPAGES) - if(XMLTO_FOUND) + find_program( XSLTPROC_EXECUTABLE NAMES xsltproc) + + if(DOCBOOKXSL_FOUND AND XSLTPROC_EXECUTABLE) + # We need the variable ${MAN_TODAY} to contain the current date in ISO # format to replace it in the configure_file step. include(today) @@ -87,7 +90,7 @@ if(WITH_MANPAGES) ${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-channels.1.xml ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-examples.1.xml ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${XMLTO_EXECUTABLE} man xfreerdp.1.xml + COMMAND ${XSLTPROC_EXECUTABLE} ${DOCBOOKXSL_DIR}/manpages/docbook.xsl xfreerdp.1.xml WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/xfreerdp.1.xml @@ -99,9 +102,9 @@ if(WITH_MANPAGES) DEPENDS xfreerdp.1) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/xfreerdp.1 DESTINATION share/man/man1) - else(XMLTO_FOUND) - message(WARNING "WITH_MANPAGES was set, but xmlto was not found. man-pages will not be installed") - endif(XMLTO_FOUND) + else(DOCBOOKXSL_FOUND AND XSLTPROC_EXECUTABLE) + message(WARNING "WITH_MANPAGES was set, but xsltproc was not found. man-pages will not be installed") + endif(DOCBOOKXSL_FOUND AND XSLTPROC_EXECUTABLE) endif(WITH_MANPAGES) set(XSHM_FEATURE_TYPE "REQUIRED") diff --git a/cmake/FindDocBookXSL.cmake b/cmake/FindDocBookXSL.cmake new file mode 100644 index 000000000..9192ef9b3 --- /dev/null +++ b/cmake/FindDocBookXSL.cmake @@ -0,0 +1,52 @@ +# Try to find DocBook XSL stylesheet +# Once done, it will define: +# +# DOCBOOKXSL_FOUND - system has the required DocBook XML DTDs +# DOCBOOKXSL_DIR - the directory containing the stylesheets +# used to process DocBook XML + +# Copyright (c) 2010, Luigi Toscano, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +set (STYLESHEET_PATH_LIST + share/xml/docbook/stylesheet/docbook-xsl + share/xml/docbook/xsl-stylesheets + share/sgml/docbook/xsl-stylesheets + share/xml/docbook/stylesheet/nwalsh/current + share/xml/docbook/stylesheet/nwalsh + share/xsl/docbook + share/xsl/docbook-xsl +) + +find_path (DOCBOOKXSL_DIR lib/lib.xsl + PATHS ${CMAKE_SYSTEM_PREFIX_PATH} + PATH_SUFFIXES ${STYLESHEET_PATH_LIST} +) + +if (NOT DOCBOOKXSL_DIR) + # hacks for systems that put the version in the stylesheet dirs + set (STYLESHEET_PATH_LIST) + foreach (STYLESHEET_PREFIX_ITER ${CMAKE_SYSTEM_PREFIX_PATH}) + file(GLOB STYLESHEET_SUFFIX_ITER RELATIVE ${STYLESHEET_PREFIX_ITER} + ${STYLESHEET_PREFIX_ITER}/share/xml/docbook/xsl-stylesheets-* + ) + if (STYLESHEET_SUFFIX_ITER) + list (APPEND STYLESHEET_PATH_LIST ${STYLESHEET_SUFFIX_ITER}) + endif () + endforeach () + + find_path (DOCBOOKXSL_DIR VERSION + PATHS ${CMAKE_SYSTEM_PREFIX_PATH} + PATH_SUFFIXES ${STYLESHEET_PATH_LIST} + ) +endif (NOT DOCBOOKXSL_DIR) + + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args (DocBookXSL + "Could NOT find DocBook XSL stylesheets" + DOCBOOKXSL_DIR) + +mark_as_advanced (DOCBOOKXSL_DIR) From 3246dcff22e90968a75cee1f80b00fcd319d7cd3 Mon Sep 17 00:00:00 2001 From: richterger Date: Wed, 7 Aug 2013 07:58:34 +0200 Subject: [PATCH 11/28] Fixed memory corruption problems within client redirect - set freed pointers to NULL to avoid double free - realloc mppc to cleanly restart compression - avoid releaseing StreamPool from already freed transport after client redirect --- libfreerdp/core/connection.c | 22 ++++++++++++++++++---- libfreerdp/core/transport.c | 6 +++++- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/libfreerdp/core/connection.c b/libfreerdp/core/connection.c index 247494e07..9c4c3d756 100644 --- a/libfreerdp/core/connection.c +++ b/libfreerdp/core/connection.c @@ -194,24 +194,38 @@ BOOL rdp_client_redirect(rdpRdp* rdp) rdp_client_disconnect(rdp); /* FIXME: this is a subset of rdp_free */ + /* --> this should really go into rdp.c */ crypto_rc4_free(rdp->rc4_decrypt_key); + rdp->rc4_decrypt_key = NULL ; crypto_rc4_free(rdp->rc4_encrypt_key); + rdp->rc4_encrypt_key = NULL; crypto_des3_free(rdp->fips_encrypt); + rdp->fips_encrypt = NULL ; crypto_des3_free(rdp->fips_decrypt); + rdp->fips_decrypt = NULL ; crypto_hmac_free(rdp->fips_hmac); + rdp->fips_hmac = NULL ; + + free(settings->ServerRandom); + settings->ServerRandom = NULL ; + free(settings->ServerCertificate); + settings->ServerCertificate = NULL ; + free(settings->ClientAddress); + settings->ClientAddress = NULL ; + + mppc_enc_free(rdp->mppc_enc); + mppc_dec_free(rdp->mppc_dec); mcs_free(rdp->mcs); nego_free(rdp->nego); license_free(rdp->license); transport_free(rdp->transport); - free(settings->ServerRandom); - free(settings->ServerCertificate); - free(settings->ClientAddress); - rdp->transport = transport_new(settings); rdp->license = license_new(rdp); rdp->nego = nego_new(rdp->transport); rdp->mcs = mcs_new(rdp->transport); + rdp->mppc_dec = mppc_dec_new(); + rdp->mppc_enc = mppc_enc_new(PROTO_RDP_50); rdp->transport->layer = TRANSPORT_LAYER_TCP; settings->RedirectedSessionId = redirection->sessionID; diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index 40885442b..0f29c6ca7 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -740,7 +740,11 @@ int transport_check_fds(rdpTransport** ptransport) recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra); - Stream_Release(received); + if (transport == *ptransport) + /* transport might now have been freed by rdp_client_redirect and a new rdp->transport created */ + /* so only release if still valid */ + Stream_Release(received); + if (recv_status < 0) status = -1; From 505facbb6ff715f08963116e212b6065ff8d5e71 Mon Sep 17 00:00:00 2001 From: richterger Date: Wed, 7 Aug 2013 08:01:33 +0200 Subject: [PATCH 12/28] Fix off by one problem in StreamPool allocation --- winpr/libwinpr/utils/collections/StreamPool.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/winpr/libwinpr/utils/collections/StreamPool.c b/winpr/libwinpr/utils/collections/StreamPool.c index 418681c61..a39e01c2d 100644 --- a/winpr/libwinpr/utils/collections/StreamPool.c +++ b/winpr/libwinpr/utils/collections/StreamPool.c @@ -44,7 +44,8 @@ void StreamPool_ShiftUsed(wStreamPool* pool, int index, int count) } else if (count < 0) { - MoveMemory(&pool->uArray[index], &pool->uArray[index - count], (pool->uSize - index) * sizeof(wStream*)); + if (pool->uSize - index + count > 0) + MoveMemory(&pool->uArray[index], &pool->uArray[index - count], (pool->uSize - index + count) * sizeof(wStream*)); pool->uSize += count; } } @@ -101,7 +102,8 @@ void StreamPool_ShiftAvailable(wStreamPool* pool, int index, int count) } else if (count < 0) { - MoveMemory(&pool->aArray[index], &pool->aArray[index - count], (pool->aSize - index) * sizeof(wStream*)); + if (pool->aSize - index + count > 0) + MoveMemory(&pool->aArray[index], &pool->aArray[index - count], (pool->aSize - index + count) * sizeof(wStream*)); pool->aSize += count; } } From d8bd4397e9844c72627f3d91ea548cc394c84901 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 7 Aug 2013 09:19:16 +0200 Subject: [PATCH 13/28] Added generated documentation files to gitignore. --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 048417b7d..ff66464d9 100755 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,9 @@ external/* # Documentation docs/api client/X11/xfreerdp.1 +client/X11/xfreerdp.1.xml +client/X11/xfreerdp-channels.1.xml +client/X11/xfreerdp-examples.1.xml # Mac OS X .DS_Store From 44c80c29ccc9cab9c9cc2d6cda98fe0dff3556b8 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 8 Aug 2013 14:46:21 +0200 Subject: [PATCH 14/28] Fixed #1404, using WaitForMultipleObjects now. --- channels/printer/client/printer_main.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/channels/printer/client/printer_main.c b/channels/printer/client/printer_main.c index 89e2ffb81..3826b7c3a 100644 --- a/channels/printer/client/printer_main.c +++ b/channels/printer/client/printer_main.c @@ -179,13 +179,16 @@ static void* printer_thread_func(void* arg) { IRP* irp; PRINTER_DEVICE* printer_dev = (PRINTER_DEVICE*) arg; + HANDLE obj[] = {printer_dev->event, printer_dev->stopEvent}; while (1) { - WaitForSingleObject(printer_dev->event, INFINITE); + DWORD rc = WaitForMultipleObjects(2, obj, FALSE, INFINITE); - if (WaitForSingleObject(printer_dev->stopEvent, 0) == WAIT_OBJECT_0) + if (rc == WAIT_OBJECT_0 + 1) break; + else if( rc != WAIT_OBJECT_0 ) + continue; ResetEvent(printer_dev->event); From a57f1302f4a3e1c7fe1c16882844755d349b109c Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 9 Aug 2013 16:23:00 +0200 Subject: [PATCH 15/28] Fixed invalid package size allocation and calculation in cliprdr_process_format_list_event Enabled and fixed error handling in cliprdr_process_format_list_response --- channels/cliprdr/client/cliprdr_format.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/channels/cliprdr/client/cliprdr_format.c b/channels/cliprdr/client/cliprdr_format.c index 023bbf8e1..fb6bef988 100644 --- a/channels/cliprdr/client/cliprdr_format.c +++ b/channels/cliprdr/client/cliprdr_format.c @@ -87,14 +87,15 @@ void cliprdr_process_format_list_event(cliprdrPlugin* cliprdr, RDP_CB_FORMAT_LIS if (!cliprdr->use_long_format_names) name_length = 32; - Stream_EnsureRemainingCapacity(body, Stream_Capacity(body) + 4 + name_length); + Stream_EnsureRemainingCapacity(body, 4 + name_length); Stream_Write_UINT32(body, cb_event->formats[i]); Stream_Write(body, name, name_length); } - s = cliprdr_packet_new(CB_FORMAT_LIST, 0, Stream_Capacity(body)); - Stream_Write(s, Stream_Buffer(body), Stream_Capacity(body)); + Stream_SealLength(body); + s = cliprdr_packet_new(CB_FORMAT_LIST, 0, Stream_Length(body)); + Stream_Write(s, Stream_Buffer(body), Stream_Length(body)); Stream_Free(body, TRUE); } @@ -291,15 +292,15 @@ void cliprdr_process_format_list(cliprdrPlugin* cliprdr, wStream* s, UINT32 data void cliprdr_process_format_list_response(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen, UINT16 msgFlags) { /* where is this documented? */ -#if 0 wMessage* event; if ((msgFlags & CB_RESPONSE_FAIL) != 0) { - event = freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, RDP_EVENT_TYPE_CB_MONITOR_READY, NULL, NULL); + /* In case of an error the clipboard will cease to operate. + * Post this event to reenable the plugin. */ + event = freerdp_event_new(CliprdrChannel_Class, CliprdrChannel_MonitorReady, NULL, NULL); svc_plugin_send_event((rdpSvcPlugin*) cliprdr, event); } -#endif } void cliprdr_process_format_data_request(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen, UINT16 msgFlags) From d41f2fa2ed3c2ae8bbb07bcd73c25b20fda849c0 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 12 Aug 2013 09:51:08 +0200 Subject: [PATCH 16/28] Added links to documentation of message sequences for clipboard data exchange. --- channels/cliprdr/client/cliprdr_format.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/channels/cliprdr/client/cliprdr_format.c b/channels/cliprdr/client/cliprdr_format.c index fb6bef988..426475a64 100644 --- a/channels/cliprdr/client/cliprdr_format.c +++ b/channels/cliprdr/client/cliprdr_format.c @@ -291,13 +291,13 @@ void cliprdr_process_format_list(cliprdrPlugin* cliprdr, wStream* s, UINT32 data void cliprdr_process_format_list_response(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen, UINT16 msgFlags) { - /* where is this documented? */ + /* http://msdn.microsoft.com/en-us/library/hh872154.aspx */ wMessage* event; if ((msgFlags & CB_RESPONSE_FAIL) != 0) { - /* In case of an error the clipboard will cease to operate. - * Post this event to reenable the plugin. */ + /* In case of an error the clipboard will not be synchronized with the server. + * Post this event to restart format negociation and data transfer. */ event = freerdp_event_new(CliprdrChannel_Class, CliprdrChannel_MonitorReady, NULL, NULL); svc_plugin_send_event((rdpSvcPlugin*) cliprdr, event); } From 2f45f6852144ee88434aa9e25a42fead354e2c6c Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 12 Aug 2013 12:53:04 +0200 Subject: [PATCH 17/28] Generating config.h now in binray tree. --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dce790c54..820cb3ddb 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -414,12 +414,12 @@ set(FREERDP_ADDIN_PATH "${FREERDP_PLUGIN_PATH}") set(FREERDP_EXTENSION_PATH "${CMAKE_INSTALL_FULL_LIBDIR}/freerdp/extensions") # Include directories -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) # Configure files add_definitions("-DHAVE_CONFIG_H") -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_SOURCE_DIR}/config.h) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) # RPATH configuration set(CMAKE_SKIP_BUILD_RPATH FALSE) From 1a681ad11798a1b66f0ee8e0455811cf59572509 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 12 Aug 2013 13:41:11 +0200 Subject: [PATCH 18/28] Moved generated tables.c to binary folder. --- channels/client/CMakeLists.txt | 22 +++++++++++----------- client/common/CMakeLists.txt | 5 +++-- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/channels/client/CMakeLists.txt b/channels/client/CMakeLists.txt index 6aa60777a..fc42466bb 100644 --- a/channels/client/CMakeLists.txt +++ b/channels/client/CMakeLists.txt @@ -19,16 +19,16 @@ set(MODULE_NAME "freerdp-channels-client") set(MODULE_PREFIX "FREERDP_CHANNELS_CLIENT") set(${MODULE_PREFIX}_SRCS - tables.c - tables.h - addin.c - addin.h - init.c - init.h - open.c - open.h - channels.c - channels.h) + ${CMAKE_CURRENT_BINARY_DIR}/tables.c + ${CMAKE_CURRENT_SOURCE_DIR}/tables.h + ${CMAKE_CURRENT_SOURCE_DIR}/addin.c + ${CMAKE_CURRENT_SOURCE_DIR}/addin.h + ${CMAKE_CURRENT_SOURCE_DIR}/init.c + ${CMAKE_CURRENT_SOURCE_DIR}/init.h + ${CMAKE_CURRENT_SOURCE_DIR}/open.c + ${CMAKE_CURRENT_SOURCE_DIR}/open.h + ${CMAKE_CURRENT_SOURCE_DIR}/channels.c + ${CMAKE_CURRENT_SOURCE_DIR}/channels.h) list(REMOVE_DUPLICATES CHANNEL_STATIC_CLIENT_ENTRIES) @@ -96,7 +96,7 @@ foreach(STATIC_MODULE ${CHANNEL_STATIC_CLIENT_MODULES}) endforeach() set(CLIENT_STATIC_ADDIN_TABLE "${CLIENT_STATIC_ADDIN_TABLE}\n\t{ NULL, NULL, NULL }\n};") -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tables.c.in ${CMAKE_CURRENT_SOURCE_DIR}/tables.c) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tables.c.in ${CMAKE_CURRENT_BINARY_DIR}/tables.c) set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHIC_BUILD} diff --git a/client/common/CMakeLists.txt b/client/common/CMakeLists.txt index 954f3a46f..2b9841e5f 100644 --- a/client/common/CMakeLists.txt +++ b/client/common/CMakeLists.txt @@ -25,9 +25,10 @@ set(${MODULE_PREFIX}_SRCS compatibility.h file.c) -set(FREERDP_CHANNELS_CLIENT_PATH "../../channels/client") foreach(FREERDP_CHANNELS_CLIENT_SRC ${FREERDP_CHANNELS_CLIENT_SRCS}) - set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} "${FREERDP_CHANNELS_CLIENT_PATH}/${FREERDP_CHANNELS_CLIENT_SRC}") + get_filename_component(NINC ${FREERDP_CHANNELS_CLIENT_SRC} PATH) + include_directories(${NINC}) + set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} "${FREERDP_CHANNELS_CLIENT_SRC}") endforeach() if(MSVC) From c39d99b02d3ecd5b653413d6928fbd6bd4df0eac Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 12 Aug 2013 13:51:18 +0200 Subject: [PATCH 19/28] winpr config.h now generated in binary tree. --- CMakeLists.txt | 4 ++-- winpr/CMakeLists.txt | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 820cb3ddb..7ff63cba0 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -444,8 +444,8 @@ if(BUILD_TESTING) endif() # WinPR -set(WINPR_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/winpr/include") -include_directories(${WINPR_INCLUDE_DIR}) +include_directories("${CMAKE_SOURCE_DIR}/winpr/include") +include_directories("${CMAKE_BINARY_DIR}/winpr/include") add_subdirectory(winpr) diff --git a/winpr/CMakeLists.txt b/winpr/CMakeLists.txt index 9e265095e..81904788c 100644 --- a/winpr/CMakeLists.txt +++ b/winpr/CMakeLists.txt @@ -63,11 +63,14 @@ endif() if(FREERDP_BUILD) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include PARENT_SCOPE) + include_directories(${CMAKE_CURRENT_BINARY_DIR}/include PARENT_SCOPE) else() include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) + include_directories(${CMAKE_CURRENT_BINARY_DIR}/include) endif() -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/winpr/config.h.in ${CMAKE_CURRENT_SOURCE_DIR}/include/winpr/config.h) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/winpr/config.h.in + ${CMAKE_CURRENT_BINARY_DIR}/include/winpr/config.h) if(NOT WITH_WAYK) add_subdirectory(include) From 7d27062edd9ac96d5d48197deecaeea50c99aa70 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 13 Aug 2013 14:04:17 +0200 Subject: [PATCH 20/28] Using WaitForMultipleObjects now to reduce CPU load. --- channels/serial/client/serial_main.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/channels/serial/client/serial_main.c b/channels/serial/client/serial_main.c index fb6b07915..80be6c88f 100644 --- a/channels/serial/client/serial_main.c +++ b/channels/serial/client/serial_main.c @@ -323,15 +323,13 @@ static void* serial_thread_func(void* arg) IRP* irp; DWORD status; SERIAL_DEVICE* serial = (SERIAL_DEVICE*)arg; + HANDLE ev[] = {serial->stopEvent, Queue_Event(serial->queue)}; while (1) { - if (WaitForSingleObject(serial->stopEvent, 0) == WAIT_OBJECT_0) - break; + status = WaitForMultipleObjects(2, ev, FALSE, 10); - status = WaitForSingleObject(Queue_Event(serial->queue), 10); - - if ((status != WAIT_OBJECT_0) && (status != WAIT_TIMEOUT)) + if (WAIT_OBJECT_0 == status) break; serial->nfds = 1; @@ -342,7 +340,7 @@ static void* serial_thread_func(void* arg) serial->tv.tv_usec = 0; serial->select_timeout = 0; - if (status == WAIT_OBJECT_0) + if (status == WAIT_OBJECT_0 + 1) { if ((irp = (IRP*) Queue_Dequeue(serial->queue))) serial_process_irp(serial, irp); From c3e847f4724c13a2b9e2f22b404221e74ffa7535 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 13 Aug 2013 14:05:38 +0200 Subject: [PATCH 21/28] Implemented timeouts for WaitForSingleObject. Added assertions for functions not implemented. --- winpr/libwinpr/synch/wait.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/winpr/libwinpr/synch/wait.c b/winpr/libwinpr/synch/wait.c index d488b0eea..cc2e00329 100644 --- a/winpr/libwinpr/synch/wait.c +++ b/winpr/libwinpr/synch/wait.c @@ -25,6 +25,8 @@ #include #endif +#include + #include #include @@ -57,14 +59,21 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) WINPR_THREAD* thread; void* thread_status = NULL; - if (dwMilliseconds != INFINITE) - fprintf(stderr, "WaitForSingleObject: timeout not implemented for thread wait\n"); - thread = (WINPR_THREAD*) Object; if (thread->started) { - status = pthread_join(thread->thread, &thread_status); + if (dwMilliseconds != INFINITE) + { + struct timespec timeout; + + timeout.tv_sec = dwMilliseconds / 1000; + timeout.tv_nsec = (dwMilliseconds % 1000) * 1000000; + + status = pthread_timedjoin_np(thread->thread, &thread_status, &timeout); + } + else + status = pthread_join(thread->thread, &thread_status); if (status != 0) fprintf(stderr, "WaitForSingleObject: pthread_join failure: %d\n", status); @@ -80,9 +89,16 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) mutex = (WINPR_MUTEX*) Object; if (dwMilliseconds != INFINITE) - fprintf(stderr, "WaitForSingleObject: timeout not implemented for mutex wait\n"); + { + struct timespec timeout; - pthread_mutex_lock(&mutex->mutex); + timeout.tv_sec = dwMilliseconds / 1000; + timeout.tv_nsec = (dwMilliseconds % 1000) * 1000000; + + pthread_mutex_timedlock(&mutex->mutex, &timeout); + } + else + pthread_mutex_lock(&mutex->mutex); } else if (Type == HANDLE_TYPE_EVENT) { @@ -213,6 +229,7 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) DWORD WaitForSingleObjectEx(HANDLE hHandle, DWORD dwMilliseconds, BOOL bAlertable) { + assert(0); return WAIT_OBJECT_0; } @@ -336,11 +353,13 @@ DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAl DWORD WaitForMultipleObjectsEx(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll, DWORD dwMilliseconds, BOOL bAlertable) { + assert(0); return 0; } DWORD SignalObjectAndWait(HANDLE hObjectToSignal, HANDLE hObjectToWaitOn, DWORD dwMilliseconds, BOOL bAlertable) { + assert(0); return 0; } From 0752597e00a43fc51de1cc7f2288b82a10273f24 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 14 Aug 2013 12:15:05 +0200 Subject: [PATCH 22/28] Thread timed join now only available with _GUN_SOURCE. --- winpr/libwinpr/synch/wait.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/winpr/libwinpr/synch/wait.c b/winpr/libwinpr/synch/wait.c index cc2e00329..d591c465d 100644 --- a/winpr/libwinpr/synch/wait.c +++ b/winpr/libwinpr/synch/wait.c @@ -45,6 +45,18 @@ #include "../handle/handle.h" +static void ts_add_ms(struct timespec *ts, DWORD dwMilliseconds) +{ + ts->tv_sec += dwMilliseconds / 1000L; + ts->tv_nsec += (dwMilliseconds % 1000L) * 1000000L; + + while(ts->tv_nsec >= 1000000000L) + { + ts->tv_sec ++; + ts->tv_nsec -= 1000000000L; + } +} + DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) { ULONG Type; @@ -55,7 +67,7 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) if (Type == HANDLE_TYPE_THREAD) { - int status; + int status = 0; WINPR_THREAD* thread; void* thread_status = NULL; @@ -65,12 +77,16 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) { if (dwMilliseconds != INFINITE) { +#if _GNU_SOURCE struct timespec timeout; - timeout.tv_sec = dwMilliseconds / 1000; - timeout.tv_nsec = (dwMilliseconds % 1000) * 1000000; + clock_gettime(CLOCK_REALTIME, &timeout); + ts_add_ms(&timeout, dwMilliseconds); status = pthread_timedjoin_np(thread->thread, &thread_status, &timeout); +#else + assert(0); +#endif } else status = pthread_join(thread->thread, &thread_status); @@ -92,8 +108,8 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) { struct timespec timeout; - timeout.tv_sec = dwMilliseconds / 1000; - timeout.tv_nsec = (dwMilliseconds % 1000) * 1000000; + clock_gettime(CLOCK_REALTIME, &timeout); + ts_add_ms(&timeout, dwMilliseconds); pthread_mutex_timedlock(&mutex->mutex, &timeout); } @@ -252,7 +268,10 @@ DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAl ZeroMemory(&timeout, sizeof(timeout)); if (bWaitAll) + { fprintf(stderr, "WaitForMultipleObjects: bWaitAll not yet implemented\n"); + assert(0); + } for (index = 0; index < nCount; index++) { From 86fd873907af0aa1785c1d784a501dff046b63a1 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 14 Aug 2013 13:19:57 +0200 Subject: [PATCH 23/28] Added error messages for not implemented functions. --- winpr/libwinpr/synch/wait.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/winpr/libwinpr/synch/wait.c b/winpr/libwinpr/synch/wait.c index d591c465d..a8d9aeff3 100644 --- a/winpr/libwinpr/synch/wait.c +++ b/winpr/libwinpr/synch/wait.c @@ -85,6 +85,7 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) status = pthread_timedjoin_np(thread->thread, &thread_status, &timeout); #else + fprintf(stderr, "[ERROR] %s: Thread timeouts not implemented.\n", __func__); assert(0); #endif } @@ -245,6 +246,7 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) DWORD WaitForSingleObjectEx(HANDLE hHandle, DWORD dwMilliseconds, BOOL bAlertable) { + fprintf(stderr, "[ERROR] %s: Function not implemented.\n", __func__); assert(0); return WAIT_OBJECT_0; } @@ -372,12 +374,14 @@ DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAl DWORD WaitForMultipleObjectsEx(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll, DWORD dwMilliseconds, BOOL bAlertable) { + fprintf(stderr, "[ERROR] %s: Function not implemented.\n", __func__); assert(0); return 0; } DWORD SignalObjectAndWait(HANDLE hObjectToSignal, HANDLE hObjectToWaitOn, DWORD dwMilliseconds, BOOL bAlertable) { + fprintf(stderr, "[ERROR] %s: Function not implemented.\n", __func__); assert(0); return 0; } From 1d2adcbe26e7223f09823daff7a0e7c9029dc00b Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 13 Aug 2013 16:04:19 +0200 Subject: [PATCH 24/28] Fixed resource leaks. --- channels/parallel/client/parallel_main.c | 1 + channels/serial/client/serial_main.c | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/channels/parallel/client/parallel_main.c b/channels/parallel/client/parallel_main.c index 6e35c1ee9..16bf4bbb0 100644 --- a/channels/parallel/client/parallel_main.c +++ b/channels/parallel/client/parallel_main.c @@ -286,6 +286,7 @@ static void parallel_free(DEVICE* device) MessageQueue_PostQuit(parallel->queue, 0); WaitForSingleObject(parallel->thread, INFINITE); + Stream_Free(parallel->device.data, TRUE); MessageQueue_Free(parallel->queue); CloseHandle(parallel->thread); diff --git a/channels/serial/client/serial_main.c b/channels/serial/client/serial_main.c index 80be6c88f..cb0852a5a 100644 --- a/channels/serial/client/serial_main.c +++ b/channels/serial/client/serial_main.c @@ -365,10 +365,16 @@ static void serial_free(DEVICE* device) DEBUG_SVC("freeing device"); + /* Stop thread */ SetEvent(serial->stopEvent); + WaitForSingleObject(serial->thread, INFINITE); - /* TODO: free lists */ - + /* Clean up resources */ + Stream_Free(serial->device.data, TRUE); + Queue_Free(serial->queue); + list_free(serial->pending_irps); + CloseHandle(serial->stopEvent); + CloseHandle(serial->thread); free(serial); } From 755bd6980b712014ef282419e7dd4d88f02f67f6 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 13 Aug 2013 16:29:19 +0200 Subject: [PATCH 25/28] Fixed resource leaks and missing thread sync. --- channels/smartcard/client/smartcard_main.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/channels/smartcard/client/smartcard_main.c b/channels/smartcard/client/smartcard_main.c index fa4dd0b3d..4efff88ff 100644 --- a/channels/smartcard/client/smartcard_main.c +++ b/channels/smartcard/client/smartcard_main.c @@ -44,8 +44,7 @@ static void smartcard_free(DEVICE* dev) SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) dev; SetEvent(smartcard->stopEvent); - CloseHandle(smartcard->thread); - CloseHandle(smartcard->irpEvent); + WaitForSingleObject(smartcard->thread, INFINITE); while ((irp = (IRP*) InterlockedPopEntrySList(smartcard->pIrpList)) != NULL) irp->Discard(irp); @@ -55,8 +54,14 @@ static void smartcard_free(DEVICE* dev) /* Begin TS Client defect workaround. */ while ((CompletionIdInfo = (COMPLETIONIDINFO*) list_dequeue(smartcard->CompletionIds)) != NULL) - free(CompletionIdInfo); + free(CompletionIdInfo); + CloseHandle(smartcard->thread); + CloseHandle(smartcard->irpEvent); + CloseHandle(smartcard->stopEvent); + CloseHandle(smartcard->CompletionIdsMutex); + + Stream_Free(smartcard->device.data, TRUE); list_free(smartcard->CompletionIds); /* End TS Client defect workaround. */ @@ -119,13 +124,16 @@ static void smartcard_process_irp_thread_func(SMARTCARD_IRP_WORKER* irpWorker) static void* smartcard_thread_func(void* arg) { SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) arg; + HANDLE ev[] = {smartcard->irpEvent, smartcard->stopEvent}; while (1) { - WaitForSingleObject(smartcard->irpEvent, INFINITE); + DWORD status = WaitForSingleObject(2, ev, FALSE, INFINITE); - if (WaitForSingleObject(smartcard->stopEvent, 0) == WAIT_OBJECT_0) + if (status == WAIT_OBJECT_0 + 1) break; + else if(status != WAIT_OBJECT_0) + continue; ResetEvent(smartcard->irpEvent); smartcard_process_irp_list(smartcard); From d4945f7a8133d822e6c7f5f014686fcecee3abe9 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 14 Aug 2013 12:13:48 +0200 Subject: [PATCH 26/28] Fixed high CPU usage. --- channels/serial/client/serial_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/channels/serial/client/serial_main.c b/channels/serial/client/serial_main.c index cb0852a5a..d62ca7a91 100644 --- a/channels/serial/client/serial_main.c +++ b/channels/serial/client/serial_main.c @@ -327,7 +327,7 @@ static void* serial_thread_func(void* arg) while (1) { - status = WaitForMultipleObjects(2, ev, FALSE, 10); + status = WaitForMultipleObjects(2, ev, FALSE, 1); if (WAIT_OBJECT_0 == status) break; @@ -336,7 +336,7 @@ static void* serial_thread_func(void* arg) FD_ZERO(&serial->read_fds); FD_ZERO(&serial->write_fds); - serial->tv.tv_sec = 1; + serial->tv.tv_sec = 0; serial->tv.tv_usec = 0; serial->select_timeout = 0; @@ -344,6 +344,7 @@ static void* serial_thread_func(void* arg) { if ((irp = (IRP*) Queue_Dequeue(serial->queue))) serial_process_irp(serial, irp); + continue; } serial_check_fds(serial); From bb0e5f266045769d48bc3c8e7de5d20fc346cdb1 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 14 Aug 2013 15:14:40 +0200 Subject: [PATCH 27/28] Fixed invalid access to tty in thread, which was already removed by serial_process_irp_close Retry read now, if non blocking IO returns EAGAIN. --- channels/serial/client/serial_main.c | 35 +++++++++++++++++++++++++++- channels/serial/client/serial_tty.c | 14 ++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/channels/serial/client/serial_main.c b/channels/serial/client/serial_main.c index d62ca7a91..d2ff16a48 100644 --- a/channels/serial/client/serial_main.c +++ b/channels/serial/client/serial_main.c @@ -370,6 +370,8 @@ static void serial_free(DEVICE* device) SetEvent(serial->stopEvent); WaitForSingleObject(serial->thread, INFINITE); + serial_tty_free(serial->tty); + /* Clean up resources */ Stream_Free(serial->device.data, TRUE); Queue_Free(serial->queue); @@ -388,6 +390,11 @@ static void serial_abort_single_io(SERIAL_DEVICE* serial, UINT32 file_id, UINT32 DEBUG_SVC("[in] pending size %d", list_size(serial->pending_irps)); tty = serial->tty; + if(!tty) + { + DEBUG_WARN("tty = %p", tty); + return; + } switch (abort_io) { @@ -438,6 +445,11 @@ static void serial_check_for_events(SERIAL_DEVICE* serial) SERIAL_TTY* tty; tty = serial->tty; + if(!tty) + { + DEBUG_WARN("tty = %p", tty); + return; + } DEBUG_SVC("[in] pending size %d", list_size(serial->pending_irps)); @@ -483,6 +495,11 @@ void serial_get_timeouts(SERIAL_DEVICE* serial, IRP* irp, UINT32* timeout, UINT3 DEBUG_SVC("length read %u", Length); tty = serial->tty; + if(!tty) + { + DEBUG_WARN("tty = %p", tty); + return; + } *timeout = (tty->read_total_timeout_multiplier * Length) + tty->read_total_timeout_constant; *interval_timeout = tty->read_interval_timeout; @@ -497,6 +514,11 @@ static void serial_handle_async_irp(SERIAL_DEVICE* serial, IRP* irp) SERIAL_TTY* tty; tty = serial->tty; + if(!tty) + { + DEBUG_WARN("tty = %p", tty); + return; + } switch (irp->MajorFunction) { @@ -547,6 +569,11 @@ static void __serial_check_fds(SERIAL_DEVICE* serial) ZeroMemory(&serial->tv, sizeof(struct timeval)); tty = serial->tty; + if(!tty) + { + DEBUG_WARN("tty = %p", tty); + return; + } /* scan every pending */ irp = list_peek(serial->pending_irps); @@ -609,6 +636,11 @@ static void serial_set_fds(SERIAL_DEVICE* serial) DEBUG_SVC("[in] pending size %d", list_size(serial->pending_irps)); tty = serial->tty; + if(!tty) + { + DEBUG_WARN("tty = %p", tty); + return; + } irp = (IRP*) list_peek(serial->pending_irps); while (irp) @@ -710,7 +742,8 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) serial); - serial->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) serial_thread_func, (void*) serial, 0, NULL); + serial->thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) serial_thread_func, (void*) serial, 0, NULL); } return 0; diff --git a/channels/serial/client/serial_tty.c b/channels/serial/client/serial_tty.c index 23445b2ca..9da45bdb0 100644 --- a/channels/serial/client/serial_tty.c +++ b/channels/serial/client/serial_tty.c @@ -409,10 +409,19 @@ BOOL serial_tty_read(SERIAL_TTY* tty, BYTE* buffer, UINT32* Length) ZeroMemory(buffer, *Length); - status = read(tty->fd, buffer, *Length); + do + { + errno = 0; + status = read(tty->fd, buffer, *Length); + } + while(EAGAIN == errno); if (status < 0) + { + DEBUG_WARN("failed with %zd, errno=[%d] %s\n", + status, errno, strerror(errno)); return FALSE; + } tty->event_txempty = status; *Length = status; @@ -456,6 +465,9 @@ void serial_tty_free(SERIAL_TTY* tty) { DEBUG_SVC("in"); + if(!tty) + return; + if (tty->fd >= 0) { if (tty->pold_termios) From e40d921da35524969e19b0012f451edde5edf179 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 14 Aug 2013 17:33:46 +0200 Subject: [PATCH 28/28] Removed EAGAIN handling, again passing on the error to the server. --- channels/serial/client/serial_tty.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/channels/serial/client/serial_tty.c b/channels/serial/client/serial_tty.c index 9da45bdb0..95bf375fe 100644 --- a/channels/serial/client/serial_tty.c +++ b/channels/serial/client/serial_tty.c @@ -409,12 +409,7 @@ BOOL serial_tty_read(SERIAL_TTY* tty, BYTE* buffer, UINT32* Length) ZeroMemory(buffer, *Length); - do - { - errno = 0; - status = read(tty->fd, buffer, *Length); - } - while(EAGAIN == errno); + status = read(tty->fd, buffer, *Length); if (status < 0) {