GUACAMOLE-1026: Add support for FreeRDP3.
This commit is contained in:
parent
3ad3b041f2
commit
97ca969e3f
23
Dockerfile
23
Dockerfile
@ -27,16 +27,21 @@
|
||||
ARG ALPINE_BASE_IMAGE=3.18
|
||||
FROM alpine:${ALPINE_BASE_IMAGE} AS builder
|
||||
|
||||
# FreeRDP version (default to version 3)
|
||||
ARG FREERDP_VERSION=3
|
||||
|
||||
# Install build dependencies
|
||||
RUN apk add --no-cache \
|
||||
autoconf \
|
||||
automake \
|
||||
build-base \
|
||||
cairo-dev \
|
||||
cjson-dev \
|
||||
cmake \
|
||||
cunit-dev \
|
||||
git \
|
||||
grep \
|
||||
krb5-dev \
|
||||
libjpeg-turbo-dev \
|
||||
libpng-dev \
|
||||
libtool \
|
||||
@ -45,7 +50,10 @@ RUN apk add --no-cache \
|
||||
openssl1.1-compat-dev \
|
||||
pango-dev \
|
||||
pulseaudio-dev \
|
||||
util-linux-dev
|
||||
sdl2-dev \
|
||||
sdl2_ttf-dev \
|
||||
util-linux-dev \
|
||||
webkit2gtk-dev
|
||||
|
||||
# Copy source to container for sake of build
|
||||
ARG BUILD_DIR=/tmp/guacamole-server
|
||||
@ -64,7 +72,7 @@ ARG PREFIX_DIR=/opt/guacamole
|
||||
# library (these can be overridden at build time if a specific version is
|
||||
# needed)
|
||||
#
|
||||
ARG WITH_FREERDP='2(\.\d+)+'
|
||||
ARG WITH_FREERDP="${FREERDP_VERSION}(\.\d+)+"
|
||||
ARG WITH_LIBSSH2='libssh2-\d+(\.\d+)+'
|
||||
ARG WITH_LIBTELNET='\d+(\.\d+)+'
|
||||
ARG WITH_LIBVNCCLIENT='LibVNCServer-\d+(\.\d+)+'
|
||||
@ -77,6 +85,7 @@ ARG WITH_LIBWEBSOCKETS='v\d+(\.\d+)+'
|
||||
#
|
||||
|
||||
ARG FREERDP_OPTS="\
|
||||
-DALLOW_IN_SOURCE_BUILD=ON \
|
||||
-DBUILTIN_CHANNELS=OFF \
|
||||
-DCHANNEL_URBDRC=OFF \
|
||||
-DWITH_ALSA=OFF \
|
||||
@ -86,22 +95,26 @@ ARG FREERDP_OPTS="\
|
||||
-DWITH_CUPS=OFF \
|
||||
-DWITH_DIRECTFB=OFF \
|
||||
-DWITH_FFMPEG=OFF \
|
||||
-DWITH_FUSE=OFF \
|
||||
-DWITH_GSM=OFF \
|
||||
-DWITH_GSSAPI=OFF \
|
||||
-DWITH_IPP=OFF \
|
||||
-DWITH_JPEG=ON \
|
||||
-DWITH_KRB5=ON \
|
||||
-DWITH_LIBSYSTEMD=OFF \
|
||||
-DWITH_MANPAGES=OFF \
|
||||
-DWITH_OPENH264=OFF \
|
||||
-DWITH_OPENSSL=ON \
|
||||
-DWITH_OSS=OFF \
|
||||
-DWITH_PCSC=OFF \
|
||||
-DWITH_PKCS11=OFF \
|
||||
-DWITH_PULSE=OFF \
|
||||
-DWITH_SERVER=OFF \
|
||||
-DWITH_SERVER_INTERFACE=OFF \
|
||||
-DWITH_SHADOW_MAC=OFF \
|
||||
-DWITH_SHADOW_X11=OFF \
|
||||
-DWITH_SSE2=ON \
|
||||
-DWITH_SWSCALE=OFF \
|
||||
-DWITH_WAYLAND=OFF \
|
||||
-DWITH_X11=OFF \
|
||||
-DWITH_X264=OFF \
|
||||
@ -141,11 +154,14 @@ ARG LIBWEBSOCKETS_OPTS="\
|
||||
# Build guacamole-server and its core protocol library dependencies
|
||||
RUN ${BUILD_DIR}/src/guacd-docker/bin/build-all.sh
|
||||
|
||||
# Determine location of the FREERDP library based on the version.
|
||||
ARG FREERDP_LIB_PATH=${PREFIX_DIR}/lib/freerdp${FREERDP_VERSION}
|
||||
|
||||
# Record the packages of all runtime library dependencies
|
||||
RUN ${BUILD_DIR}/src/guacd-docker/bin/list-dependencies.sh \
|
||||
${PREFIX_DIR}/sbin/guacd \
|
||||
${PREFIX_DIR}/lib/libguac-client-*.so \
|
||||
${PREFIX_DIR}/lib/freerdp2/*guac*.so \
|
||||
${FREERDP_LIB_PATH}/*guac*.so \
|
||||
> ${PREFIX_DIR}/DEPENDENCIES
|
||||
|
||||
# Use same Alpine version as the base for the runtime image
|
||||
@ -202,4 +218,3 @@ EXPOSE 4822
|
||||
# PREFIX_DIR build argument.
|
||||
#
|
||||
CMD /opt/guacamole/sbin/guacd -b 0.0.0.0 -L $GUACD_LOG_LEVEL -f
|
||||
|
||||
|
||||
203
configure.ac
203
configure.ac
@ -648,11 +648,12 @@ then
|
||||
fi
|
||||
|
||||
#
|
||||
# FreeRDP 2 (libfreerdp2, libfreerdp-client2, and libwinpr2)
|
||||
# FreeRDP (libfreerdpX, libfreerdp-clientX, and libwinprX)
|
||||
#
|
||||
|
||||
have_freerdp2=disabled
|
||||
FREERDP2_PLUGIN_DIR=
|
||||
freerdp_version=
|
||||
have_freerdp=
|
||||
FREERDP_PLUGIN_DIR=
|
||||
|
||||
AC_ARG_WITH([rdp],
|
||||
[AS_HELP_STRING([--with-rdp],
|
||||
@ -664,7 +665,7 @@ AC_ARG_WITH([rdp],
|
||||
AC_ARG_WITH(freerdp_plugin_dir,
|
||||
[AS_HELP_STRING([--with-freerdp-plugin-dir=<path>],
|
||||
[install FreeRDP plugins to the given directory @<:@default=check@:>@])
|
||||
],FREERDP2_PLUGIN_DIR=$withval)
|
||||
],FREERDP_PLUGIN_DIR=$withval)
|
||||
|
||||
# Preserve CPPFLAGS so it can be restored later, following the addition of
|
||||
# options specific to FreeRDP tests
|
||||
@ -672,21 +673,38 @@ OLDCPPFLAGS="$CPPFLAGS"
|
||||
|
||||
if test "x$with_rdp" != "xno"
|
||||
then
|
||||
have_freerdp2=yes
|
||||
PKG_CHECK_MODULES([RDP], [freerdp2 freerdp-client2 winpr2],
|
||||
freerdp_version=3
|
||||
have_freerdp=yes
|
||||
PKG_CHECK_MODULES([RDP], [freerdp3 freerdp-client3 winpr3],
|
||||
[CPPFLAGS="${RDP_CFLAGS} -Werror $CPPFLAGS"]
|
||||
[AS_IF([test "x${FREERDP2_PLUGIN_DIR}" = "x"],
|
||||
[FREERDP2_PLUGIN_DIR="`$PKG_CONFIG --variable=libdir freerdp2`/freerdp2"])],
|
||||
[AS_IF([test "x${FREERDP_PLUGIN_DIR}" = "x"],
|
||||
[FREERDP_PLUGIN_DIR="`$PKG_CONFIG --variable=libdir freerdp3`/freerdp3"])],
|
||||
[AC_MSG_WARN([
|
||||
--------------------------------------------
|
||||
Unable to find FreeRDP (libfreerdp2 / libfreerdp-client2 / libwinpr2)
|
||||
Unable to find FreeRDP3 (libfreerdp3 / libfreerdp-client3 / libwinpr3).
|
||||
Checking for FreeRDP2.
|
||||
--------------------------------------------])
|
||||
have_freerdp=no])
|
||||
fi
|
||||
|
||||
if test "x$with_rdp" != "xno" -a "x${have_freerdp}" = "xno"
|
||||
then
|
||||
freerdp_version=2
|
||||
have_freerdp=yes
|
||||
PKG_CHECK_MODULES([RDP], [freerdp2 freerdp-client2 winpr2],
|
||||
[CPPFLAGS="${RDP_CFLAGS} -Werror $CPPFLAGS"]
|
||||
[AS_IF([test "x${FREERDP_PLUGIN_DIR}" = "x"],
|
||||
[FREERDP_PLUGIN_DIR="`$PKG_CONFIG --variable=libdir freerdp2`/freerdp2"])],
|
||||
[AC_MSG_WARN([
|
||||
--------------------------------------------
|
||||
Unable to find FreeRDP2 (libfreerdp2 / libfreerdp-client2 / libwinpr2)
|
||||
RDP will be disabled.
|
||||
--------------------------------------------])
|
||||
have_freerdp2=no])
|
||||
have_freerdp=no])
|
||||
fi
|
||||
|
||||
# Available color conversion functions
|
||||
if test "x$have_freerdp2" = "xyes"
|
||||
if test "x${have_freerdp}" = "xyes"
|
||||
then
|
||||
|
||||
# FreeRDP 2.0.0-rc3 and older referred to FreeRDPConvertColor() as
|
||||
@ -708,7 +726,7 @@ AC_ARG_ENABLE(allow_freerdp_snapshots,
|
||||
[allow building against unknown development snapshots of FreeRDP])
|
||||
],allow_freerdp_snapshots=yes)
|
||||
|
||||
if test "x${have_freerdp2}" = "xyes" -a "x${allow_freerdp_snapshots}" != "xyes"
|
||||
if test "x${have_freerdp}" = "xyes" -a "x${allow_freerdp_snapshots}" != "xyes"
|
||||
then
|
||||
|
||||
AC_MSG_CHECKING([whether FreeRDP appears to be a development version])
|
||||
@ -736,7 +754,7 @@ then
|
||||
fi
|
||||
|
||||
# Variation in memory internal allocation/free behavior for bitmaps
|
||||
if test "x${have_freerdp2}" = "xyes"
|
||||
if test "x${have_freerdp}" = "xyes"
|
||||
then
|
||||
|
||||
# FreeRDP 2.0.0-rc0 and older automatically free rdpBitmap and its
|
||||
@ -760,7 +778,7 @@ then
|
||||
fi
|
||||
|
||||
# Variation in memory internal allocation/free behavior for channel streams
|
||||
if test "x${have_freerdp2}" = "xyes"
|
||||
if test "x${have_freerdp}" = "xyes"
|
||||
then
|
||||
|
||||
# FreeRDP 2.0.0-rc3 through 2.0.0-rc4 automatically free the wStream
|
||||
@ -782,7 +800,7 @@ then
|
||||
fi
|
||||
|
||||
# Glyph callback variants
|
||||
if test "x${have_freerdp2}" = "xyes"
|
||||
if test "x${have_freerdp}" = "xyes"
|
||||
then
|
||||
|
||||
# FreeRDP 2.0.0-rc3 and older used UINT32 for integer parameters to all
|
||||
@ -815,7 +833,7 @@ then
|
||||
fi
|
||||
|
||||
# CLIPRDR callback variants
|
||||
if test "x${have_freerdp2}" = "xyes"
|
||||
if test "x${have_freerdp}" = "xyes"
|
||||
then
|
||||
|
||||
# FreeRDP 2.0.0-rc3 and older did not use const for CLIPRDR callbacks
|
||||
@ -845,7 +863,7 @@ then
|
||||
fi
|
||||
|
||||
# RAIL callback variants
|
||||
if test "x${have_freerdp2}" = "xyes"
|
||||
if test "x${have_freerdp}" = "xyes"
|
||||
then
|
||||
|
||||
# FreeRDP 2.0.0-rc3 and older did not use const for RAIL callbacks
|
||||
@ -875,7 +893,7 @@ then
|
||||
fi
|
||||
|
||||
# Support for receiving unannounced orders from the RDP server
|
||||
if test "x${have_freerdp2}" = "xyes"
|
||||
if test "x${have_freerdp}" = "xyes"
|
||||
then
|
||||
AC_CHECK_MEMBERS([rdpSettings.AllowUnanouncedOrdersFromServer],,
|
||||
[AC_MSG_WARN([
|
||||
@ -891,17 +909,151 @@ fi
|
||||
|
||||
# Updated certificate verification callback (introduced with 2.0.0, not present
|
||||
# in 2.0.0-rc4 or earlier)
|
||||
if test "x${have_freerdp2}" = "xyes"
|
||||
if test "x${have_freerdp}" = "xyes"
|
||||
then
|
||||
AC_CHECK_MEMBERS([freerdp.VerifyCertificateEx],,,
|
||||
[[#include <freerdp/freerdp.h>]])
|
||||
[[#include <freerdp/freerdp.h>]])
|
||||
fi
|
||||
|
||||
if test "x${have_freerdp}" = "xyes"
|
||||
then
|
||||
AC_CHECK_DECLS([winpr_aligned_free],
|
||||
[AC_DEFINE([HAVE_WINPR_ALIGNED],,
|
||||
[Defined if winpr_aligned_free() and winpr_aligned_malloc() are available])],,
|
||||
[#include <winpr/crt.h>])
|
||||
fi
|
||||
|
||||
if test "x${have_freerdp}" = "xyes"
|
||||
then
|
||||
AC_MSG_CHECKING([whether CLIPRDR structs have a common CLIPRDR_HEADER])
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
|
||||
#include <freerdp/client/cliprdr.h>
|
||||
int main() {
|
||||
CLIPRDR_FORMAT_LIST list;
|
||||
list.common.msgType = 0;
|
||||
return 0;
|
||||
}
|
||||
]])],
|
||||
[AC_MSG_RESULT([yes])]
|
||||
[AC_DEFINE([HAVE_CLIPRDR_HEADER],,
|
||||
[Defined if CLIPRDR structs have a common CLIPRDR_HEADER])],
|
||||
[AC_MSG_RESULT([no])])
|
||||
fi
|
||||
|
||||
if test "x${have_freerdp}" = "xyes"
|
||||
then
|
||||
AC_CHECK_DECLS([FreeRDPReadColor],
|
||||
[AC_DEFINE([USE_UPDATED_RW_COLOR_FUNCS],,
|
||||
[Defined if FreeRDPReadColor() and FreeRDPWriteColor() are available])],,
|
||||
[#include <freerdp/codec/color.h>])
|
||||
fi
|
||||
|
||||
if test "x${have_freerdp}" = "xyes"
|
||||
then
|
||||
AC_CHECK_DECLS([freerdp_settings_set_pointer],
|
||||
[AC_DEFINE([HAVE_SETTERS_GETTERS],,
|
||||
[Defined if freerdp_settings_set_pointer is available])],,
|
||||
[#include <freerdp/settings.h>])
|
||||
fi
|
||||
|
||||
if test "x${have_freerdp}" = "xyes"
|
||||
then
|
||||
AC_MSG_CHECKING([whether freerdp structs have a context])
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
|
||||
#include <freerdp/freerdp.h>
|
||||
int main() {
|
||||
freerdp* instance = freerdp_new();
|
||||
/* We cast to void to prevent unused variable warnings */
|
||||
(void)instance->context->input;
|
||||
(void)instance->context->settings;
|
||||
freerdp_free(instance);
|
||||
return 0;
|
||||
}
|
||||
]])],
|
||||
[AC_MSG_RESULT([yes])]
|
||||
[AC_DEFINE([FREERDP_HAS_CONTEXT],,
|
||||
[FreeRDP structs have a context])],
|
||||
[AC_MSG_RESULT([no])])
|
||||
fi
|
||||
|
||||
if test "x${have_freerdp}" = "xyes"
|
||||
then
|
||||
AC_CHECK_DECL([freerdp_shall_disconnect_context],
|
||||
[AC_DEFINE([HAVE_DISCONNECT_CONTEXT],,
|
||||
[Defined if 'freerdp_shall_disconnect_context' is available in FreeRDP])],,
|
||||
[#include <freerdp/freerdp.h>])
|
||||
fi
|
||||
if test "x${have_freerdp}" = "xyes"
|
||||
then
|
||||
# Check whether FreeRDP 3.x requires const for GetPluginData
|
||||
AC_MSG_CHECKING([whether GetPluginData requires const for the returned args])
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
|
||||
#include <freerdp/dvc.h>
|
||||
int main() {
|
||||
IDRDYNVC_ENTRY_POINTS test_entry_points;
|
||||
const ADDIN_ARGV* args = test_entry_points.GetPluginData(&test_entry_points);
|
||||
(void)args;
|
||||
return 0;
|
||||
}
|
||||
]])],
|
||||
[AC_MSG_RESULT([yes])]
|
||||
[AC_DEFINE([PLUGIN_DATA_CONST],,
|
||||
[Defined if GetPluginData returns a pointer to a const ADDIN_ARGV])],
|
||||
[AC_MSG_RESULT([no])])
|
||||
fi
|
||||
|
||||
if test "x${have_freerdp}" = "xyes"
|
||||
then
|
||||
# Check whether glyph.New expects a const rdpGlyph* parameter
|
||||
AC_MSG_CHECKING([whether glyph.New expects a const rdpGlyph* parameter])
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
|
||||
#include <freerdp/graphics.h>
|
||||
BOOL mock_glyph_new(rdpContext* context, const rdpGlyph* glyph) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int main() {
|
||||
rdpGlyph* glyph = (rdpGlyph*) malloc(sizeof(rdpGlyph));
|
||||
glyph->New = mock_glyph_new;
|
||||
free(glyph);
|
||||
return 0;
|
||||
}
|
||||
]])],
|
||||
[AC_MSG_RESULT([yes])]
|
||||
[AC_DEFINE([RDP_GLYPH_NEW_REQUIRES_CONST],,
|
||||
[Defined if glyph.New expects a const rdpGlyph* parameter])],
|
||||
[AC_MSG_RESULT([no])])
|
||||
fi
|
||||
|
||||
if test "x${have_freerdp}" = "xyes"
|
||||
then
|
||||
# Check whether pointer.Set expects a const rdpPointer* parameter
|
||||
AC_MSG_CHECKING([whether pointer.Set expects a const rdpPointer* parameter])
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
|
||||
#include <freerdp/graphics.h>
|
||||
|
||||
BOOL mock_pointer_set(rdpContext* context, const rdpPointer* pointer) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int main() {
|
||||
rdpPointer* pointer = (rdpPointer*) malloc(sizeof(rdpPointer));
|
||||
pointer->Set = mock_pointer_set;
|
||||
free(pointer);
|
||||
return 0;
|
||||
}
|
||||
]])],
|
||||
[AC_MSG_RESULT([yes])]
|
||||
[AC_DEFINE([RDP_POINTER_SET_REQUIRES_CONST],,
|
||||
[Defined if pointer.Set expects a const rdpPointer* parameter])],
|
||||
[AC_MSG_RESULT([no])])
|
||||
fi
|
||||
|
||||
# Restore CPPFLAGS, removing FreeRDP-specific options needed for testing
|
||||
CPPFLAGS="$OLDCPPFLAGS"
|
||||
|
||||
AC_SUBST(FREERDP2_PLUGIN_DIR)
|
||||
AM_CONDITIONAL([ENABLE_RDP], [test "x${have_freerdp2}" = "xyes"])
|
||||
AC_SUBST(FREERDP_PLUGIN_DIR)
|
||||
AM_CONDITIONAL([ENABLE_RDP], [test "x${have_freerdp}" = "xyes"])
|
||||
|
||||
#
|
||||
# libssh2
|
||||
@ -1237,7 +1389,7 @@ AM_COND_IF([ENABLE_SYSTEMD], [build_systemd="${systemd_dir}"], [build_systemd=no
|
||||
# FreeRDP plugins
|
||||
#
|
||||
|
||||
AM_COND_IF([ENABLE_RDP], [build_rdp_plugins="${FREERDP2_PLUGIN_DIR}"], [build_rdp_plugins=no])
|
||||
AM_COND_IF([ENABLE_RDP], [build_rdp_plugins="${FREERDP_PLUGIN_DIR}"], [build_rdp_plugins=no])
|
||||
|
||||
#
|
||||
# Display summary
|
||||
@ -1250,7 +1402,7 @@ $PACKAGE_NAME version $PACKAGE_VERSION
|
||||
|
||||
Library status:
|
||||
|
||||
freerdp2 ............ ${have_freerdp2}
|
||||
freerdp${freerdp_version} ............ ${have_freerdp}
|
||||
pango ............... ${have_pango}
|
||||
libavcodec .......... ${have_libavcodec}
|
||||
libavformat ......... ${have_libavformat}
|
||||
@ -1280,10 +1432,9 @@ $PACKAGE_NAME version $PACKAGE_VERSION
|
||||
guacenc .... ${build_guacenc}
|
||||
guaclog .... ${build_guaclog}
|
||||
|
||||
FreeRDP plugins: ${build_rdp_plugins}
|
||||
FreeRDP${freerdp_version} plugins: ${build_rdp_plugins}
|
||||
Init scripts: ${build_init}
|
||||
Systemd units: ${build_systemd}
|
||||
|
||||
Type \"make\" to compile $PACKAGE_NAME.
|
||||
"
|
||||
|
||||
|
||||
@ -128,4 +128,3 @@ install_from_git "https://github.com/warmcat/libwebsockets" "$WITH_LIBWEBSOCKETS
|
||||
cd "$BUILD_DIR"
|
||||
autoreconf -fi && ./configure --prefix="$PREFIX_DIR" $GUACAMOLE_SERVER_OPTS
|
||||
make && make check && make install
|
||||
|
||||
|
||||
@ -131,6 +131,38 @@ size_t guac_strlcat(char* restrict dest, const char* restrict src, size_t n);
|
||||
*/
|
||||
char* guac_strnstr(const char *haystack, const char *needle, size_t len);
|
||||
|
||||
/**
|
||||
* Duplicates up to the given number of characters from the provided string,
|
||||
* returning a newly-allocated string containing the copied contents. The
|
||||
* provided string must be null-terminated, and only the first 'n' characters
|
||||
* will be considered for duplication, or the full string length if it is
|
||||
* shorter than 'n'. The memory block for the newly-allocated string will
|
||||
* include enough space for these characters, as well as for the null
|
||||
* terminator.
|
||||
*
|
||||
* The pointer returned by guac_strndup() SHOULD be freed with a subsequent call
|
||||
* to guac_mem_free(), but MAY instead be freed with a subsequent call to free().
|
||||
*
|
||||
* This function behaves similarly to the POSIX strndup() function, except that
|
||||
* NULL will be returned if the provided string is NULL or if memory allocation
|
||||
* fails. Also, the length of the string to be duplicated will be checked to
|
||||
* prevent overflow if adding space for the null terminator.
|
||||
*
|
||||
* @param str
|
||||
* The string of which up to the first 'n' characters should be duplicated
|
||||
* as a newly-allocated string. If 'n' exceeds the length of the string,
|
||||
* the entire string is duplicated.
|
||||
*
|
||||
* @param n
|
||||
* The maximum number of characters to duplicate from the given string.
|
||||
*
|
||||
* @return
|
||||
* A newly-allocated string containing up to the first 'n' characters from
|
||||
* the given string, including a terminating null byte, or NULL if the
|
||||
* provided string was NULL or if memory allocation fails.
|
||||
*/
|
||||
char* guac_strndup(const char* str, size_t n);
|
||||
|
||||
/**
|
||||
* Duplicates the given string, returning a newly-allocated string containing
|
||||
* the same contents. The provided string must be null-terminated. The size of
|
||||
@ -202,4 +234,3 @@ size_t guac_strljoin(char* restrict dest, const char* restrict const* elements,
|
||||
int nmemb, const char* restrict delim, size_t n);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -115,7 +115,7 @@ char* guac_strnstr(const char *haystack, const char *needle, size_t len) {
|
||||
|
||||
}
|
||||
|
||||
char* guac_strdup(const char* str) {
|
||||
char* guac_strndup(const char* str, size_t n) {
|
||||
|
||||
/* Return NULL if no string provided */
|
||||
if (str == NULL)
|
||||
@ -124,18 +124,30 @@ char* guac_strdup(const char* str) {
|
||||
/* Do not attempt to duplicate if the length is somehow magically so
|
||||
* obscenely large that it will not be possible to add a null terminator */
|
||||
size_t length;
|
||||
if (guac_mem_ckd_add(&length, strlen(str), 1))
|
||||
size_t length_to_copy = strnlen(str, n);
|
||||
if (guac_mem_ckd_add(&length, length_to_copy, 1))
|
||||
return NULL;
|
||||
|
||||
/* Otherwise just copy to a new string in same manner as strdup() */
|
||||
void* new_str = guac_mem_alloc(length);
|
||||
if (new_str != NULL)
|
||||
memcpy(new_str, str, length);
|
||||
/* Otherwise just copy to a new string in same manner as strndup() */
|
||||
char* new_str = (char*)guac_mem_alloc(length);
|
||||
if (new_str != NULL) {
|
||||
memcpy(new_str, str, length_to_copy);
|
||||
new_str[length_to_copy] = '\0';
|
||||
}
|
||||
|
||||
return new_str;
|
||||
|
||||
}
|
||||
|
||||
char* guac_strdup(const char* str) {
|
||||
|
||||
/* Return NULL if no string provided */
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
|
||||
return guac_strndup(str, strlen(str));
|
||||
}
|
||||
|
||||
size_t guac_strljoin(char* restrict dest, const char* restrict const* elements,
|
||||
int nmemb, const char* restrict delim, size_t n) {
|
||||
|
||||
@ -159,4 +171,3 @@ size_t guac_strljoin(char* restrict dest, const char* restrict const* elements,
|
||||
return length;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -158,7 +158,7 @@ freerdp_LTLIBRARIES = \
|
||||
libguac-common-svc-client.la \
|
||||
libguacai-client.la
|
||||
|
||||
freerdpdir = @FREERDP2_PLUGIN_DIR@
|
||||
freerdpdir = @FREERDP_PLUGIN_DIR@
|
||||
|
||||
#
|
||||
# Common SVC plugin (shared by RDPDR, RDPSND, etc.)
|
||||
@ -264,4 +264,3 @@ EXTRA_DIST = \
|
||||
$(rdp_keymaps) \
|
||||
keymaps/generate.pl \
|
||||
plugins/generate-entry-wrappers.pl
|
||||
|
||||
|
||||
@ -132,8 +132,7 @@ void guac_rdp_bitmap_free(rdpContext* context, rdpBitmap* bitmap) {
|
||||
/* NOTE: Except in FreeRDP 2.0.0-rc0 and earlier, FreeRDP-allocated memory
|
||||
* for the rdpBitmap will NOT be automatically released after this free
|
||||
* handler is invoked, thus we must do so manually here */
|
||||
|
||||
_aligned_free(bitmap->data);
|
||||
GUAC_ALIGNED_FREE(bitmap->data);
|
||||
free(bitmap);
|
||||
#endif
|
||||
|
||||
@ -167,4 +166,3 @@ BOOL guac_rdp_bitmap_setsurface(rdpContext* context, rdpBitmap* bitmap, BOOL pri
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -82,7 +82,13 @@ static UINT guac_rdp_cliprdr_send_format_list(CliprdrClientContext* cliprdr) {
|
||||
|
||||
/* We support CP-1252 and UTF-16 text */
|
||||
CLIPRDR_FORMAT_LIST format_list = {
|
||||
#ifdef HAVE_CLIPRDR_HEADER
|
||||
.common = {
|
||||
.msgType = CB_FORMAT_LIST
|
||||
},
|
||||
#else
|
||||
.msgType = CB_FORMAT_LIST,
|
||||
#endif
|
||||
.formats = (CLIPRDR_FORMAT[]) {
|
||||
{ .formatId = CF_TEXT },
|
||||
{ .formatId = CF_UNICODETEXT }
|
||||
@ -298,9 +304,15 @@ static UINT guac_rdp_cliprdr_format_list(CliprdrClientContext* cliprdr,
|
||||
guac_client_log(client, GUAC_LOG_TRACE, "CLIPRDR: Received format list.");
|
||||
|
||||
CLIPRDR_FORMAT_LIST_RESPONSE format_list_response = {
|
||||
#ifdef HAVE_CLIPRDR_HEADER
|
||||
.common = {
|
||||
.msgType = CB_FORMAT_LIST_RESPONSE,
|
||||
.msgFlags = CB_RESPONSE_OK
|
||||
}
|
||||
#else
|
||||
.msgFlags = CB_RESPONSE_OK
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Report successful processing of format list */
|
||||
pthread_mutex_lock(&(rdp_client->message_lock));
|
||||
cliprdr->ClientFormatListResponse(cliprdr, &format_list_response);
|
||||
@ -394,8 +406,16 @@ static UINT guac_rdp_cliprdr_format_data_request(CliprdrClientContext* cliprdr,
|
||||
|
||||
CLIPRDR_FORMAT_DATA_RESPONSE data_response = {
|
||||
.requestedFormatData = (BYTE*) start,
|
||||
#ifdef HAVE_CLIPRDR_HEADER
|
||||
.common = {
|
||||
.msgType = CB_FORMAT_DATA_RESPONSE,
|
||||
.msgFlags = CB_RESPONSE_OK,
|
||||
.dataLen = ((BYTE*) output) - start,
|
||||
}
|
||||
#else
|
||||
.dataLen = ((BYTE*) output) - start,
|
||||
.msgFlags = CB_RESPONSE_OK
|
||||
#endif
|
||||
};
|
||||
|
||||
guac_client_log(client, GUAC_LOG_TRACE, "CLIPRDR: Sending format data response.");
|
||||
@ -482,9 +502,16 @@ static UINT guac_rdp_cliprdr_format_data_response(CliprdrClientContext* cliprdr,
|
||||
|
||||
}
|
||||
|
||||
int data_len;
|
||||
#ifdef HAVE_CLIPRDR_HEADER
|
||||
data_len = format_data_response->common.dataLen;
|
||||
#else
|
||||
data_len = format_data_response->dataLen;
|
||||
#endif
|
||||
|
||||
/* Convert, store, and forward the clipboard data received from RDP
|
||||
* server */
|
||||
if (guac_iconv(remote_reader, &input, format_data_response->dataLen,
|
||||
if (guac_iconv(remote_reader, &input, data_len,
|
||||
GUAC_WRITE_UTF8, &output, sizeof(received_data))) {
|
||||
int length = strnlen(received_data, sizeof(received_data));
|
||||
guac_common_clipboard_reset(clipboard->clipboard, "text/plain");
|
||||
@ -712,4 +739,3 @@ int guac_rdp_clipboard_end_handler(guac_user* user, guac_stream* stream) {
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -204,7 +204,7 @@ void guac_rdpsnd_formats_handler(guac_rdp_common_svc* svc,
|
||||
Stream_Write_UINT16(output_stream, rdpsnd->format_count);
|
||||
|
||||
/* Reposition cursor at end (necessary for message send) */
|
||||
Stream_SetPointer(output_stream, output_stream_end);
|
||||
Stream_SetPosition(output_stream, output_stream_end - Stream_Buffer(output_stream));
|
||||
|
||||
/* Send accepted formats */
|
||||
guac_rdp_common_svc_write(svc, output_stream);
|
||||
@ -366,4 +366,3 @@ void guac_rdpsnd_close_handler(guac_rdp_common_svc* svc,
|
||||
/* Do nothing */
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -56,7 +56,12 @@ UINT32 guac_rdp_convert_color(rdpContext* context, UINT32 color) {
|
||||
|
||||
/* Convert provided color into the intermediate representation expected by
|
||||
* FreeRDPConvertColor() */
|
||||
UINT32 intermed = ReadColor((BYTE*) &color, src_format);
|
||||
UINT32 intermed;
|
||||
#ifdef USE_UPDATED_RW_COLOR_FUNCS
|
||||
intermed = FreeRDPReadColor((BYTE*) &color, src_format);
|
||||
#else
|
||||
intermed = ReadColor((BYTE*) &color, src_format);
|
||||
#endif
|
||||
|
||||
/* Convert color from RDP source format to the native format used by Cairo,
|
||||
* still maintaining intermediate representation */
|
||||
@ -69,8 +74,12 @@ UINT32 guac_rdp_convert_color(rdpContext* context, UINT32 color) {
|
||||
|
||||
/* Convert color from intermediate representation to the actual desired
|
||||
* format */
|
||||
WriteColor((BYTE*) &color, dst_format, intermed);
|
||||
#ifdef USE_UPDATED_RW_COLOR_FUNCS
|
||||
intermed = FreeRDPWriteColor((BYTE*) &color, dst_format, intermed);
|
||||
#else
|
||||
intermed = WriteColor((BYTE*) &color, dst_format, intermed);
|
||||
#endif
|
||||
|
||||
return color;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -412,7 +412,14 @@ BOOL guac_rdp_gdi_surface_frame_marker(rdpContext* context, const SURFACE_FRAME_
|
||||
|
||||
guac_rdp_gdi_mark_frame(context, surface_frame_marker->frameAction != SURFACECMD_FRAMEACTION_END);
|
||||
|
||||
if (context->settings->FrameAcknowledge > 0)
|
||||
int frame_acknowledge;
|
||||
#ifdef HAVE_SETTERS_GETTERS
|
||||
frame_acknowledge = freerdp_settings_get_uint32(context->settings, FreeRDP_FrameAcknowledge);
|
||||
#else
|
||||
frame_acknowledge = context->settings->FrameAcknowledge;
|
||||
#endif
|
||||
|
||||
if (frame_acknowledge > 0)
|
||||
IFCALL(context->update->SurfaceFrameAcknowledge, context,
|
||||
surface_frame_marker->frameId);
|
||||
|
||||
@ -496,4 +503,3 @@ BOOL guac_rdp_gdi_desktop_resize(rdpContext* context) {
|
||||
guac_rdp_get_height(context->instance));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -36,7 +36,7 @@
|
||||
#define cairo_format_stride_for_width(format, width) (width*4)
|
||||
#endif
|
||||
|
||||
BOOL guac_rdp_glyph_new(rdpContext* context, const rdpGlyph* glyph) {
|
||||
BOOL guac_rdp_glyph_new(rdpContext* context, GLYPH_NEW_CONST rdpGlyph* glyph) {
|
||||
|
||||
int x, y, i;
|
||||
int stride;
|
||||
@ -168,4 +168,3 @@ BOOL guac_rdp_glyph_enddraw(rdpContext* context,
|
||||
/* IGNORE */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@ -41,6 +41,12 @@
|
||||
#define GLYPH_CALLBACK_INT32 UINT32
|
||||
#endif
|
||||
|
||||
#ifdef RDP_GLYPH_NEW_REQUIRES_CONST
|
||||
#define GLYPH_NEW_CONST const
|
||||
#else
|
||||
#define GLYPH_NEW_CONST
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Guacamole-specific rdpGlyph data.
|
||||
*/
|
||||
@ -71,7 +77,7 @@ typedef struct guac_rdp_glyph {
|
||||
* @return
|
||||
* TRUE if successful, FALSE otherwise.
|
||||
*/
|
||||
BOOL guac_rdp_glyph_new(rdpContext* context, const rdpGlyph* glyph);
|
||||
BOOL guac_rdp_glyph_new(rdpContext* context, GLYPH_NEW_CONST rdpGlyph* glyph);
|
||||
|
||||
/**
|
||||
* Draws a previously-cached glyph at the given coordinates within the current
|
||||
|
||||
@ -57,7 +57,8 @@ int guac_rdp_user_mouse_handler(guac_user* user, int x, int y, int mask) {
|
||||
/* If button mask unchanged, just send move event */
|
||||
if (mask == rdp_client->mouse_button_mask) {
|
||||
pthread_mutex_lock(&(rdp_client->message_lock));
|
||||
rdp_inst->input->MouseEvent(rdp_inst->input, PTR_FLAGS_MOVE, x, y);
|
||||
GUAC_RDP_CONTEXT(rdp_inst)->input->MouseEvent(
|
||||
GUAC_RDP_CONTEXT(rdp_inst)->input, PTR_FLAGS_MOVE, x, y);
|
||||
pthread_mutex_unlock(&(rdp_client->message_lock));
|
||||
}
|
||||
|
||||
@ -80,7 +81,8 @@ int guac_rdp_user_mouse_handler(guac_user* user, int x, int y, int mask) {
|
||||
if (released_mask & 0x04) flags |= PTR_FLAGS_BUTTON2;
|
||||
|
||||
pthread_mutex_lock(&(rdp_client->message_lock));
|
||||
rdp_inst->input->MouseEvent(rdp_inst->input, flags, x, y);
|
||||
GUAC_RDP_CONTEXT(rdp_inst)->input->MouseEvent(
|
||||
GUAC_RDP_CONTEXT(rdp_inst)->input, flags, x, y);
|
||||
pthread_mutex_unlock(&(rdp_client->message_lock));
|
||||
|
||||
}
|
||||
@ -98,7 +100,8 @@ int guac_rdp_user_mouse_handler(guac_user* user, int x, int y, int mask) {
|
||||
|
||||
/* Send event */
|
||||
pthread_mutex_lock(&(rdp_client->message_lock));
|
||||
rdp_inst->input->MouseEvent(rdp_inst->input, flags, x, y);
|
||||
GUAC_RDP_CONTEXT(rdp_inst)->input->MouseEvent(
|
||||
GUAC_RDP_CONTEXT(rdp_inst)->input, flags, x, y);
|
||||
pthread_mutex_unlock(&(rdp_client->message_lock));
|
||||
|
||||
}
|
||||
@ -109,14 +112,16 @@ int guac_rdp_user_mouse_handler(guac_user* user, int x, int y, int mask) {
|
||||
/* Down */
|
||||
if (pressed_mask & 0x08) {
|
||||
pthread_mutex_lock(&(rdp_client->message_lock));
|
||||
rdp_inst->input->MouseEvent(rdp_inst->input, PTR_FLAGS_WHEEL | 0x78, x, y);
|
||||
GUAC_RDP_CONTEXT(rdp_inst)->input->MouseEvent(
|
||||
GUAC_RDP_CONTEXT(rdp_inst)->input, PTR_FLAGS_WHEEL | 0x78, x, y);
|
||||
pthread_mutex_unlock(&(rdp_client->message_lock));
|
||||
}
|
||||
|
||||
/* Up */
|
||||
if (pressed_mask & 0x10) {
|
||||
pthread_mutex_lock(&(rdp_client->message_lock));
|
||||
rdp_inst->input->MouseEvent(rdp_inst->input, PTR_FLAGS_WHEEL | PTR_FLAGS_WHEEL_NEGATIVE | 0x88, x, y);
|
||||
GUAC_RDP_CONTEXT(rdp_inst)->input->MouseEvent(
|
||||
GUAC_RDP_CONTEXT(rdp_inst)->input, PTR_FLAGS_WHEEL | PTR_FLAGS_WHEEL_NEGATIVE | 0x88, x, y);
|
||||
pthread_mutex_unlock(&(rdp_client->message_lock));
|
||||
}
|
||||
|
||||
|
||||
@ -107,7 +107,8 @@ static void guac_rdp_send_key_event(guac_rdp_client* rdp_client,
|
||||
|
||||
/* Send actual key */
|
||||
pthread_mutex_lock(&(rdp_client->message_lock));
|
||||
rdp_inst->input->KeyboardEvent(rdp_inst->input, flags | pressed_flags, scancode);
|
||||
GUAC_RDP_CONTEXT(rdp_inst)->input->KeyboardEvent(
|
||||
GUAC_RDP_CONTEXT(rdp_inst)->input, flags | pressed_flags, scancode);
|
||||
pthread_mutex_unlock(&(rdp_client->message_lock));
|
||||
|
||||
}
|
||||
@ -136,7 +137,8 @@ static void guac_rdp_send_unicode_event(guac_rdp_client* rdp_client,
|
||||
|
||||
/* Send Unicode event */
|
||||
pthread_mutex_lock(&(rdp_client->message_lock));
|
||||
rdp_inst->input->UnicodeKeyboardEvent(rdp_inst->input, 0, codepoint);
|
||||
GUAC_RDP_CONTEXT(rdp_inst)->input->UnicodeKeyboardEvent(
|
||||
GUAC_RDP_CONTEXT(rdp_inst)->input, 0, codepoint);
|
||||
pthread_mutex_unlock(&(rdp_client->message_lock));
|
||||
|
||||
}
|
||||
@ -165,7 +167,8 @@ static void guac_rdp_send_synchronize_event(guac_rdp_client* rdp_client,
|
||||
|
||||
/* Synchronize lock key states */
|
||||
pthread_mutex_lock(&(rdp_client->message_lock));
|
||||
rdp_inst->input->SynchronizeEvent(rdp_inst->input, flags);
|
||||
GUAC_RDP_CONTEXT(rdp_inst)->input->SynchronizeEvent(
|
||||
GUAC_RDP_CONTEXT(rdp_inst)->input, flags);
|
||||
pthread_mutex_unlock(&(rdp_client->message_lock));
|
||||
|
||||
}
|
||||
|
||||
@ -136,8 +136,11 @@ void guac_freerdp_dynamic_channel_collection_add(rdpSettings* settings,
|
||||
va_end(args);
|
||||
|
||||
/* Register plugin with FreeRDP */
|
||||
#ifdef HAVE_SETTERS_GETTERS
|
||||
freerdp_settings_set_bool(settings, FreeRDP_SupportDynamicChannels, TRUE);
|
||||
#else
|
||||
settings->SupportDynamicChannels = TRUE;
|
||||
#endif
|
||||
|
||||
freerdp_dynamic_channel_collection_add(settings, freerdp_args);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -61,8 +61,8 @@
|
||||
* The name of the plugin to load. If the plugin is not statically built
|
||||
* into FreeRDP, this name will determine the filename of the library to be
|
||||
* loaded dynamically. For a plugin named "NAME", the library called
|
||||
* "libNAME-client" will be loaded from the "freerdp2" subdirectory of the
|
||||
* main directory containing the FreeRDP libraries.
|
||||
* "libNAME-client" will be loaded from the "freerdp2" or "freerdp3"
|
||||
* subdirectory of the main directory containing the FreeRDP libraries.
|
||||
*
|
||||
* @param data
|
||||
* Arbitrary data to be passed to the plugin entry point. For most plugins
|
||||
@ -105,8 +105,8 @@ int guac_freerdp_channels_load_plugin(rdpContext* context,
|
||||
* The name of the plugin to load. If the plugin is not statically built
|
||||
* into FreeRDP, this name will determine the filename of the library to be
|
||||
* loaded dynamically. For a plugin named "NAME", the library called
|
||||
* "libNAME-client" will be loaded from the "freerdp2" subdirectory of the
|
||||
* main directory containing the FreeRDP libraries.
|
||||
* "libNAME-client" will be loaded from the "freerdp2" or "freerdp3"
|
||||
* subdirectory of the main directory containing the FreeRDP libraries.
|
||||
*
|
||||
* @param ...
|
||||
* Arbitrary arguments to be passed to the plugin entry point. For most
|
||||
@ -204,4 +204,3 @@ PVIRTUALCHANNELENTRY guac_rdp_plugin_wrap_entry(guac_client* client,
|
||||
PVIRTUALCHANNELENTRY entry);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -283,7 +283,12 @@ static UINT guac_rdp_ai_terminated(IWTSPlugin* plugin) {
|
||||
UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) {
|
||||
|
||||
/* Pull guac_client from arguments */
|
||||
#ifdef PLUGIN_DATA_CONST
|
||||
const ADDIN_ARGV* args = pEntryPoints->GetPluginData(pEntryPoints);
|
||||
#else
|
||||
ADDIN_ARGV* args = pEntryPoints->GetPluginData(pEntryPoints);
|
||||
#endif
|
||||
|
||||
guac_client* client = (guac_client*) guac_rdp_string_to_ptr(args->argv[1]);
|
||||
|
||||
/* Pull previously-allocated plugin */
|
||||
@ -309,4 +314,3 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) {
|
||||
return CHANNEL_RC_OK;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -42,7 +42,7 @@ BOOL guac_rdp_pointer_new(rdpContext* context, rdpPointer* pointer) {
|
||||
rdp_client->display, pointer->width, pointer->height);
|
||||
|
||||
/* Allocate data for image */
|
||||
unsigned char* data = _aligned_malloc(pointer->width * pointer->height * 4, 16);
|
||||
unsigned char* data = GUAC_ALIGNED_MALLOC(pointer->width * pointer->height * 4, 16);
|
||||
|
||||
cairo_surface_t* surface;
|
||||
|
||||
@ -64,7 +64,7 @@ BOOL guac_rdp_pointer_new(rdpContext* context, rdpPointer* pointer) {
|
||||
|
||||
/* Free surface */
|
||||
cairo_surface_destroy(surface);
|
||||
_aligned_free(data);
|
||||
GUAC_ALIGNED_FREE(data);
|
||||
|
||||
/* Remember buffer */
|
||||
((guac_rdp_pointer*) pointer)->layer = buffer;
|
||||
@ -73,7 +73,7 @@ BOOL guac_rdp_pointer_new(rdpContext* context, rdpPointer* pointer) {
|
||||
|
||||
}
|
||||
|
||||
BOOL guac_rdp_pointer_set(rdpContext* context, const rdpPointer* pointer) {
|
||||
BOOL guac_rdp_pointer_set(rdpContext* context, POINTER_SET_CONST rdpPointer* pointer) {
|
||||
|
||||
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
||||
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
||||
@ -156,4 +156,3 @@ BOOL guac_rdp_pointer_set_default(rdpContext* context) {
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@ -26,6 +26,12 @@
|
||||
#include <freerdp/graphics.h>
|
||||
#include <winpr/wtypes.h>
|
||||
|
||||
#ifdef RDP_POINTER_SET_REQUIRES_CONST
|
||||
#define POINTER_SET_CONST const
|
||||
#else
|
||||
#define POINTER_SET_CONST
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Guacamole-specific rdpPointer data.
|
||||
*/
|
||||
@ -71,7 +77,7 @@ BOOL guac_rdp_pointer_new(rdpContext* context, rdpPointer* pointer);
|
||||
* @return
|
||||
* TRUE if successful, FALSE otherwise.
|
||||
*/
|
||||
BOOL guac_rdp_pointer_set(rdpContext* context, const rdpPointer* pointer);
|
||||
BOOL guac_rdp_pointer_set(rdpContext* context, POINTER_SET_CONST rdpPointer* pointer);
|
||||
|
||||
/**
|
||||
* Frees all Guacamole-related data associated with the given pointer, allowing
|
||||
|
||||
@ -53,12 +53,6 @@
|
||||
#endif
|
||||
|
||||
#include <freerdp/addin.h>
|
||||
#include <freerdp/cache/bitmap.h>
|
||||
#include <freerdp/cache/brush.h>
|
||||
#include <freerdp/cache/glyph.h>
|
||||
#include <freerdp/cache/offscreen.h>
|
||||
#include <freerdp/cache/palette.h>
|
||||
#include <freerdp/cache/pointer.h>
|
||||
#include <freerdp/channels/channels.h>
|
||||
#include <freerdp/client/channels.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
@ -86,7 +80,7 @@
|
||||
|
||||
BOOL rdp_freerdp_pre_connect(freerdp* instance) {
|
||||
|
||||
rdpContext* context = instance->context;
|
||||
rdpContext* context = GUAC_RDP_CONTEXT(instance);
|
||||
rdpGraphics* graphics = context->graphics;
|
||||
|
||||
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
||||
@ -112,7 +106,7 @@ BOOL rdp_freerdp_pre_connect(freerdp* instance) {
|
||||
/* Upgrade the lock to write temporarily for setting the newly allocated audio buffer */
|
||||
guac_rwlock_acquire_write_lock(&(rdp_client->lock));
|
||||
rdp_client->audio_input = guac_rdp_audio_buffer_alloc(client);
|
||||
guac_rdp_audio_load_plugin(instance->context);
|
||||
guac_rdp_audio_load_plugin(GUAC_RDP_CONTEXT(instance));
|
||||
|
||||
/* Downgrade the lock to allow for concurrent read access */
|
||||
guac_rwlock_release_lock(&(rdp_client->lock));
|
||||
@ -178,42 +172,35 @@ BOOL rdp_freerdp_pre_connect(freerdp* instance) {
|
||||
graphics_register_pointer(graphics, &pointer);
|
||||
|
||||
/* Beep on receipt of Play Sound PDU */
|
||||
instance->update->PlaySound = guac_rdp_beep_play_sound;
|
||||
GUAC_RDP_CONTEXT(instance)->update->PlaySound = guac_rdp_beep_play_sound;
|
||||
|
||||
/* Automatically synchronize keyboard locks when changed server-side */
|
||||
instance->update->SetKeyboardIndicators = guac_rdp_keyboard_set_indicators;
|
||||
GUAC_RDP_CONTEXT(instance)->update->SetKeyboardIndicators = guac_rdp_keyboard_set_indicators;
|
||||
|
||||
/* Set up GDI */
|
||||
instance->update->DesktopResize = guac_rdp_gdi_desktop_resize;
|
||||
instance->update->BeginPaint = guac_rdp_gdi_begin_paint;
|
||||
instance->update->EndPaint = guac_rdp_gdi_end_paint;
|
||||
instance->update->SetBounds = guac_rdp_gdi_set_bounds;
|
||||
GUAC_RDP_CONTEXT(instance)->update->DesktopResize = guac_rdp_gdi_desktop_resize;
|
||||
GUAC_RDP_CONTEXT(instance)->update->BeginPaint = guac_rdp_gdi_begin_paint;
|
||||
GUAC_RDP_CONTEXT(instance)->update->EndPaint = guac_rdp_gdi_end_paint;
|
||||
GUAC_RDP_CONTEXT(instance)->update->SetBounds = guac_rdp_gdi_set_bounds;
|
||||
|
||||
instance->update->SurfaceFrameMarker = guac_rdp_gdi_surface_frame_marker;
|
||||
instance->update->altsec->FrameMarker = guac_rdp_gdi_frame_marker;
|
||||
GUAC_RDP_CONTEXT(instance)->update->SurfaceFrameMarker = guac_rdp_gdi_surface_frame_marker;
|
||||
GUAC_RDP_CONTEXT(instance)->update->altsec->FrameMarker = guac_rdp_gdi_frame_marker;
|
||||
|
||||
rdpPrimaryUpdate* primary = instance->update->primary;
|
||||
rdpPrimaryUpdate* primary = GUAC_RDP_CONTEXT(instance)->update->primary;
|
||||
primary->DstBlt = guac_rdp_gdi_dstblt;
|
||||
primary->PatBlt = guac_rdp_gdi_patblt;
|
||||
primary->ScrBlt = guac_rdp_gdi_scrblt;
|
||||
primary->MemBlt = guac_rdp_gdi_memblt;
|
||||
primary->OpaqueRect = guac_rdp_gdi_opaquerect;
|
||||
|
||||
pointer_cache_register_callbacks(instance->update);
|
||||
glyph_cache_register_callbacks(instance->update);
|
||||
brush_cache_register_callbacks(instance->update);
|
||||
bitmap_cache_register_callbacks(instance->update);
|
||||
offscreen_cache_register_callbacks(instance->update);
|
||||
palette_cache_register_callbacks(instance->update);
|
||||
|
||||
/* Load "rdpgfx" plugin for Graphics Pipeline Extension */
|
||||
if (settings->enable_gfx)
|
||||
guac_rdp_rdpgfx_load_plugin(context);
|
||||
|
||||
/* Load plugin providing Dynamic Virtual Channel support, if required */
|
||||
if (instance->settings->SupportDynamicChannels &&
|
||||
if (freerdp_settings_get_bool(GUAC_RDP_CONTEXT(instance)->settings, FreeRDP_SupportDynamicChannels) &&
|
||||
guac_freerdp_channels_load_plugin(context, "drdynvc",
|
||||
instance->settings)) {
|
||||
GUAC_RDP_CONTEXT(instance)->settings)) {
|
||||
guac_client_log(client, GUAC_LOG_WARNING,
|
||||
"Failed to load drdynvc plugin. Display update and audio "
|
||||
"input support will be disabled.");
|
||||
@ -254,7 +241,7 @@ BOOL rdp_freerdp_pre_connect(freerdp* instance) {
|
||||
static BOOL rdp_freerdp_authenticate(freerdp* instance, char** username,
|
||||
char** password, char** domain) {
|
||||
|
||||
rdpContext* context = instance->context;
|
||||
rdpContext* context = GUAC_RDP_CONTEXT(instance);
|
||||
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
||||
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
||||
guac_rdp_settings* settings = rdp_client->settings;
|
||||
@ -396,7 +383,7 @@ static DWORD rdp_freerdp_verify_certificate(freerdp* instance,
|
||||
const char* fingerprint, BOOL host_mismatch) {
|
||||
#endif
|
||||
|
||||
rdpContext* context = instance->context;
|
||||
rdpContext* context = GUAC_RDP_CONTEXT(instance);
|
||||
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
||||
guac_rdp_client* rdp_client =
|
||||
(guac_rdp_client*) client->data;
|
||||
@ -432,7 +419,7 @@ static int rdp_guac_client_wait_for_messages(guac_client* client,
|
||||
freerdp* rdp_inst = rdp_client->rdp_inst;
|
||||
|
||||
HANDLE handles[GUAC_RDP_MAX_FILE_DESCRIPTORS];
|
||||
int num_handles = freerdp_get_event_handles(rdp_inst->context, handles,
|
||||
int num_handles = freerdp_get_event_handles(GUAC_RDP_CONTEXT(rdp_inst), handles,
|
||||
GUAC_RDP_MAX_FILE_DESCRIPTORS);
|
||||
|
||||
/* Wait for data and construct a reasonable frame */
|
||||
@ -521,7 +508,7 @@ static int guac_rdp_handle_connection(guac_client* client) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
((rdp_freerdp_context*) rdp_inst->context)->client = client;
|
||||
((rdp_freerdp_context*) GUAC_RDP_CONTEXT(rdp_inst))->client = client;
|
||||
|
||||
/* Load keymap into client */
|
||||
rdp_client->keyboard = guac_rdp_keyboard_alloc(client,
|
||||
@ -579,7 +566,7 @@ static int guac_rdp_handle_connection(guac_client* client) {
|
||||
/* Handle any queued FreeRDP events (this may result in RDP
|
||||
* messages being sent) */
|
||||
pthread_mutex_lock(&(rdp_client->message_lock));
|
||||
int event_result = freerdp_check_event_handles(rdp_inst->context);
|
||||
int event_result = freerdp_check_event_handles(GUAC_RDP_CONTEXT(rdp_inst));
|
||||
pthread_mutex_unlock(&(rdp_client->message_lock));
|
||||
|
||||
/* Abort if FreeRDP event handling fails */
|
||||
@ -622,7 +609,12 @@ static int guac_rdp_handle_connection(guac_client* client) {
|
||||
}
|
||||
|
||||
/* Test whether the RDP server is closing the connection */
|
||||
int connection_closing = freerdp_shall_disconnect(rdp_inst);
|
||||
int connection_closing;
|
||||
#ifdef HAVE_DISCONNECT_CONTEXT
|
||||
connection_closing = freerdp_shall_disconnect_context(rdp_inst->context);
|
||||
#else
|
||||
connection_closing = freerdp_shall_disconnect(rdp_inst);
|
||||
#endif
|
||||
|
||||
/* Close connection cleanly if server is disconnecting */
|
||||
if (connection_closing)
|
||||
|
||||
@ -51,6 +51,20 @@
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef HAVE_WINPR_ALIGNED
|
||||
#define GUAC_ALIGNED_FREE winpr_aligned_free
|
||||
#define GUAC_ALIGNED_MALLOC winpr_aligned_malloc
|
||||
#else
|
||||
#define GUAC_ALIGNED_FREE _aligned_free
|
||||
#define GUAC_ALIGNED_MALLOC _aligned_malloc
|
||||
#endif
|
||||
|
||||
#ifdef FREERDP_HAS_CONTEXT
|
||||
#define GUAC_RDP_CONTEXT(rdp_instance) ((rdp_instance)->context)
|
||||
#else
|
||||
#define GUAC_RDP_CONTEXT(rdp_instance) ((rdp_instance))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* RDP-specific client data.
|
||||
*/
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include "common/defaults.h"
|
||||
#include "common/string.h"
|
||||
#include "config.h"
|
||||
#include "rdp.h"
|
||||
#include "resolution.h"
|
||||
#include "settings.h"
|
||||
|
||||
@ -1394,18 +1395,6 @@ void guac_rdp_settings_free(guac_rdp_settings* settings) {
|
||||
|
||||
}
|
||||
|
||||
int guac_rdp_get_width(freerdp* rdp) {
|
||||
return rdp->settings->DesktopWidth;
|
||||
}
|
||||
|
||||
int guac_rdp_get_height(freerdp* rdp) {
|
||||
return rdp->settings->DesktopHeight;
|
||||
}
|
||||
|
||||
int guac_rdp_get_depth(freerdp* rdp) {
|
||||
return rdp->settings->ColorDepth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the settings structure of the Guacamole RDP client, calculates the
|
||||
* standard performance flag value to send to the RDP server. The value of
|
||||
@ -1451,11 +1440,279 @@ static int guac_rdp_get_performance_flags(guac_rdp_settings* guac_settings) {
|
||||
|
||||
}
|
||||
|
||||
int guac_rdp_get_width(freerdp* rdp) {
|
||||
#ifdef HAVE_SETTERS_GETTERS
|
||||
return freerdp_settings_get_uint32(rdp->context->settings, FreeRDP_DesktopWidth);
|
||||
#else
|
||||
return rdp->settings->DesktopWidth;
|
||||
#endif
|
||||
}
|
||||
|
||||
int guac_rdp_get_height(freerdp* rdp) {
|
||||
#ifdef HAVE_SETTERS_GETTERS
|
||||
return freerdp_settings_get_uint32(rdp->context->settings, FreeRDP_DesktopHeight);
|
||||
#else
|
||||
return rdp->settings->DesktopHeight;
|
||||
#endif
|
||||
}
|
||||
|
||||
int guac_rdp_get_depth(freerdp* rdp) {
|
||||
#ifdef HAVE_SETTERS_GETTERS
|
||||
return freerdp_settings_get_uint32(rdp->context->settings, FreeRDP_ColorDepth);
|
||||
#else
|
||||
return rdp->settings->ColorDepth;
|
||||
#endif
|
||||
}
|
||||
|
||||
void guac_rdp_push_settings(guac_client* client,
|
||||
guac_rdp_settings* guac_settings, freerdp* rdp) {
|
||||
|
||||
rdpSettings* rdp_settings = rdp->settings;
|
||||
rdpSettings* rdp_settings = GUAC_RDP_CONTEXT(rdp)->settings;
|
||||
|
||||
#ifdef HAVE_SETTERS_GETTERS
|
||||
/* Authentication */
|
||||
freerdp_settings_set_string(rdp_settings, FreeRDP_Domain, guac_strdup(guac_settings->domain));
|
||||
freerdp_settings_set_string(rdp_settings, FreeRDP_Username, guac_strdup(guac_settings->username));
|
||||
freerdp_settings_set_string(rdp_settings, FreeRDP_Password, guac_strdup(guac_settings->password));
|
||||
|
||||
/* Connection */
|
||||
freerdp_settings_set_string(rdp_settings, FreeRDP_ServerHostname, guac_strdup(guac_settings->hostname));
|
||||
freerdp_settings_set_uint32(rdp_settings, FreeRDP_ServerPort, guac_settings->port);
|
||||
|
||||
/* Session */
|
||||
|
||||
freerdp_settings_set_uint32(rdp_settings, FreeRDP_DesktopWidth, guac_settings->width);
|
||||
freerdp_settings_set_uint32(rdp_settings, FreeRDP_DesktopHeight, guac_settings->height);
|
||||
freerdp_settings_set_uint32(rdp_settings, FreeRDP_ColorDepth, guac_settings->color_depth);
|
||||
freerdp_settings_set_string(rdp_settings, FreeRDP_AlternateShell, guac_strdup(guac_settings->initial_program));
|
||||
freerdp_settings_set_uint32(rdp_settings, FreeRDP_KeyboardLayout, guac_settings->server_layout->freerdp_keyboard_layout);
|
||||
|
||||
|
||||
/* Performance flags */
|
||||
/* Explicitly set flag value */
|
||||
freerdp_settings_set_uint32(rdp_settings, FreeRDP_PerformanceFlags, guac_rdp_get_performance_flags(guac_settings));
|
||||
|
||||
/* Always request frame markers */
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_FrameMarkerCommandEnabled, TRUE);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_SurfaceFrameMarkerEnabled, TRUE);
|
||||
|
||||
/* Enable RemoteFX / Graphics Pipeline */
|
||||
if (guac_settings->enable_gfx) {
|
||||
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_SupportGraphicsPipeline, TRUE);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_RemoteFxCodec, TRUE);
|
||||
|
||||
if (freerdp_settings_get_uint32(rdp_settings, FreeRDP_ColorDepth) != RDP_GFX_REQUIRED_DEPTH) {
|
||||
guac_client_log(client, GUAC_LOG_WARNING, "Ignoring requested "
|
||||
"color depth of %i bpp, as the RDP Graphics Pipeline "
|
||||
"requires %i bpp.", freerdp_settings_get_uint32(rdp_settings, FreeRDP_ColorDepth), RDP_GFX_REQUIRED_DEPTH);
|
||||
}
|
||||
|
||||
/* Required for RemoteFX / Graphics Pipeline */
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_FastPathOutput, TRUE);
|
||||
freerdp_settings_set_uint32(rdp_settings, FreeRDP_ColorDepth, RDP_GFX_REQUIRED_DEPTH);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_SoftwareGdi, TRUE);
|
||||
|
||||
}
|
||||
|
||||
/* Set individual flags - some FreeRDP versions overwrite flags set by guac_rdp_get_performance_flags() above */
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_AllowFontSmoothing, guac_settings->font_smoothing_enabled);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_DisableWallpaper, guac_settings->wallpaper_enabled);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_DisableFullWindowDrag, guac_settings->full_window_drag_enabled);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_DisableMenuAnims, guac_settings->menu_animations_enabled);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_DisableThemes, guac_settings->theming_enabled);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_AllowDesktopComposition, guac_settings->desktop_composition_enabled);
|
||||
|
||||
/* Client name */
|
||||
if (guac_settings->client_name != NULL) {
|
||||
freerdp_settings_set_string(rdp_settings, FreeRDP_ClientHostname,
|
||||
guac_strndup(guac_settings->client_name, RDP_CLIENT_HOSTNAME_SIZE));
|
||||
}
|
||||
|
||||
/* Console */
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_ConsoleSession, guac_settings->console);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_RemoteConsoleAudio, guac_settings->console_audio);
|
||||
|
||||
/* Audio */
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_AudioPlayback, guac_settings->audio_enabled);
|
||||
|
||||
/* Audio capture */
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_AudioCapture, guac_settings->enable_audio_input);
|
||||
|
||||
/* Display Update channel */
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_SupportDisplayControl,
|
||||
(guac_settings->resize_method == GUAC_RESIZE_DISPLAY_UPDATE));
|
||||
|
||||
/* Timezone redirection */
|
||||
if (guac_settings->timezone) {
|
||||
if (setenv("TZ", guac_settings->timezone, 1)) {
|
||||
guac_client_log(client, GUAC_LOG_WARNING,
|
||||
"Unable to forward timezone: TZ environment variable "
|
||||
"could not be set: %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
/* Device redirection */
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_DeviceRedirection,
|
||||
(guac_settings->audio_enabled || guac_settings->drive_enabled || guac_settings->printing_enabled));
|
||||
|
||||
/* Security */
|
||||
switch (guac_settings->security_mode) {
|
||||
|
||||
/* Legacy RDP encryption */
|
||||
case GUAC_SECURITY_RDP:
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_RdpSecurity, TRUE);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_TlsSecurity, FALSE);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_NlaSecurity, FALSE);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_ExtSecurity, FALSE);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_UseRdpSecurityLayer, TRUE);
|
||||
freerdp_settings_set_uint32(rdp_settings, FreeRDP_EncryptionLevel,
|
||||
ENCRYPTION_LEVEL_CLIENT_COMPATIBLE);
|
||||
freerdp_settings_set_uint32(rdp_settings, FreeRDP_EncryptionMethods,
|
||||
ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS);
|
||||
break;
|
||||
|
||||
/* TLS encryption */
|
||||
case GUAC_SECURITY_TLS:
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_RdpSecurity, FALSE);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_TlsSecurity, TRUE);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_NlaSecurity, FALSE);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_ExtSecurity, FALSE);
|
||||
break;
|
||||
|
||||
/* Network level authentication */
|
||||
case GUAC_SECURITY_NLA:
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_RdpSecurity, FALSE);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_TlsSecurity, FALSE);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_NlaSecurity, TRUE);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_ExtSecurity, FALSE);
|
||||
break;
|
||||
|
||||
/* Extended network level authentication */
|
||||
case GUAC_SECURITY_EXTENDED_NLA:
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_RdpSecurity, FALSE);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_TlsSecurity, FALSE);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_NlaSecurity, FALSE);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_ExtSecurity, TRUE);
|
||||
break;
|
||||
|
||||
/* Hyper-V "VMConnect" negotiation mode */
|
||||
case GUAC_SECURITY_VMCONNECT:
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_RdpSecurity, FALSE);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_TlsSecurity, TRUE);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_NlaSecurity, TRUE);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_ExtSecurity, FALSE);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_VmConnectMode, TRUE);
|
||||
break;
|
||||
|
||||
/* All security types */
|
||||
case GUAC_SECURITY_ANY:
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_RdpSecurity, TRUE);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_TlsSecurity, TRUE);
|
||||
|
||||
/* Explicitly disable NLA if FIPS mode is enabled - it won't work */
|
||||
if (guac_fips_enabled()) {
|
||||
|
||||
guac_client_log(client, GUAC_LOG_INFO,
|
||||
"FIPS mode is enabled. Excluding NLA security mode from security negotiation "
|
||||
"(see: https://github.com/FreeRDP/FreeRDP/issues/3412).");
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_NlaSecurity, FALSE);
|
||||
|
||||
}
|
||||
|
||||
/* NLA mode is allowed if FIPS is not enabled */
|
||||
else
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_NlaSecurity, TRUE);
|
||||
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_ExtSecurity, FALSE);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
/* Security */
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_Authentication, !guac_settings->disable_authentication);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_IgnoreCertificate, guac_settings->ignore_certificate);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_AutoAcceptCertificate, guac_settings->certificate_tofu);
|
||||
if (guac_settings->certificate_fingerprints != NULL)
|
||||
freerdp_settings_set_string(rdp_settings, FreeRDP_CertificateAcceptedFingerprints,
|
||||
guac_strdup(guac_settings->certificate_fingerprints));
|
||||
|
||||
|
||||
/* RemoteApp */
|
||||
if (guac_settings->remote_app != NULL) {
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_Workarea, TRUE);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_RemoteApplicationMode, TRUE);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_RemoteAppLanguageBarSupported, TRUE);
|
||||
freerdp_settings_set_string(rdp_settings, FreeRDP_RemoteApplicationProgram, guac_strdup(guac_settings->remote_app));
|
||||
freerdp_settings_set_string(rdp_settings, FreeRDP_ShellWorkingDirectory, guac_strdup(guac_settings->remote_app_dir));
|
||||
freerdp_settings_set_string(rdp_settings, FreeRDP_RemoteApplicationCmdLine, guac_strdup(guac_settings->remote_app_args));
|
||||
}
|
||||
|
||||
/* Preconnection ID */
|
||||
if (guac_settings->preconnection_id != -1) {
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_NegotiateSecurityLayer, FALSE);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_SendPreconnectionPdu, TRUE);
|
||||
freerdp_settings_set_uint32(rdp_settings, FreeRDP_PreconnectionId, guac_settings->preconnection_id);
|
||||
}
|
||||
|
||||
/* Preconnection BLOB */
|
||||
if (guac_settings->preconnection_blob != NULL) {
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_NegotiateSecurityLayer, FALSE);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_SendPreconnectionPdu, TRUE);
|
||||
freerdp_settings_set_string(rdp_settings, FreeRDP_PreconnectionBlob, guac_strdup(guac_settings->preconnection_blob));
|
||||
}
|
||||
|
||||
/* Enable use of RD gateway if a gateway hostname is provided */
|
||||
if (guac_settings->gateway_hostname != NULL) {
|
||||
|
||||
/* Enable RD gateway */
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_GatewayEnabled, TRUE);
|
||||
|
||||
/* RD gateway connection details */
|
||||
freerdp_settings_set_string(rdp_settings, FreeRDP_GatewayHostname, guac_strdup(guac_settings->gateway_hostname));
|
||||
freerdp_settings_set_uint32(rdp_settings, FreeRDP_GatewayPort, guac_settings->gateway_port);
|
||||
|
||||
/* RD gateway credentials */
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_GatewayUseSameCredentials, FALSE);
|
||||
freerdp_settings_set_string(rdp_settings, FreeRDP_GatewayDomain, guac_strdup(guac_settings->gateway_domain));
|
||||
freerdp_settings_set_string(rdp_settings, FreeRDP_GatewayUsername, guac_strdup(guac_settings->gateway_username));
|
||||
freerdp_settings_set_string(rdp_settings, FreeRDP_GatewayPassword, guac_strdup(guac_settings->gateway_password));
|
||||
|
||||
}
|
||||
|
||||
/* Store load balance info (and calculate length) if provided */
|
||||
if (guac_settings->load_balance_info != NULL) {
|
||||
freerdp_settings_set_pointer(rdp_settings, FreeRDP_LoadBalanceInfo, (BYTE*) guac_strdup(guac_settings->load_balance_info));
|
||||
freerdp_settings_set_uint32(rdp_settings, FreeRDP_LoadBalanceInfoLength, strlen(guac_settings->load_balance_info));
|
||||
}
|
||||
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_BitmapCacheEnabled, !guac_settings->disable_bitmap_caching);
|
||||
freerdp_settings_set_uint32(rdp_settings, FreeRDP_OffscreenSupportLevel, !guac_settings->disable_offscreen_caching);
|
||||
freerdp_settings_set_uint32(rdp_settings, FreeRDP_GlyphSupportLevel,
|
||||
(!guac_settings->disable_glyph_caching ? GLYPH_SUPPORT_FULL : GLYPH_SUPPORT_NONE));
|
||||
freerdp_settings_set_uint32(rdp_settings, FreeRDP_OsMajorType, OSMAJORTYPE_UNSPECIFIED);
|
||||
freerdp_settings_set_uint32(rdp_settings, FreeRDP_OsMinorType, OSMINORTYPE_UNSPECIFIED);
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_DesktopResize, TRUE);
|
||||
|
||||
/* Claim support only for specific updates, independent of FreeRDP defaults */
|
||||
BYTE* order_support = freerdp_settings_get_pointer_writable(rdp_settings, FreeRDP_OrderSupport);
|
||||
if (order_support) {
|
||||
ZeroMemory(order_support, GUAC_RDP_ORDER_SUPPORT_LENGTH);
|
||||
order_support[NEG_DSTBLT_INDEX] = TRUE;
|
||||
order_support[NEG_SCRBLT_INDEX] = TRUE;
|
||||
order_support[NEG_MEMBLT_INDEX] = !guac_settings->disable_bitmap_caching;
|
||||
order_support[NEG_MEMBLT_V2_INDEX] = !guac_settings->disable_bitmap_caching;
|
||||
order_support[NEG_GLYPH_INDEX_INDEX] = !guac_settings->disable_glyph_caching;
|
||||
order_support[NEG_FAST_INDEX_INDEX] = !guac_settings->disable_glyph_caching;
|
||||
order_support[NEG_FAST_GLYPH_INDEX] = !guac_settings->disable_glyph_caching;
|
||||
}
|
||||
|
||||
#ifdef HAVE_RDPSETTINGS_ALLOWUNANOUNCEDORDERSFROMSERVER
|
||||
/* Do not consider server use of unannounced orders to be a fatal error */
|
||||
freerdp_settings_set_bool(rdp_settings, FreeRDP_AllowUnanouncedOrdersFromServer, TRUE);
|
||||
#endif
|
||||
|
||||
#else
|
||||
/* Authentication */
|
||||
rdp_settings->Domain = guac_strdup(guac_settings->domain);
|
||||
rdp_settings->Username = guac_strdup(guac_settings->username);
|
||||
@ -1499,7 +1756,7 @@ void guac_rdp_push_settings(guac_client* client,
|
||||
|
||||
}
|
||||
|
||||
/* Set individual flags - some FreeRDP versions overwrite the above */
|
||||
/* Set individual flags - some FreeRDP versions overwrite flags set by guac_rdp_get_performance_flags() above */
|
||||
rdp_settings->AllowFontSmoothing = guac_settings->font_smoothing_enabled;
|
||||
rdp_settings->DisableWallpaper = !guac_settings->wallpaper_enabled;
|
||||
rdp_settings->DisableFullWindowDrag = !guac_settings->full_window_drag_enabled;
|
||||
@ -1692,5 +1949,5 @@ void guac_rdp_push_settings(guac_client* client,
|
||||
rdp_settings->AllowUnanouncedOrdersFromServer = TRUE;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user