You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by al...@apache.org on 2024/05/07 08:03:15 UTC

(guacamole-server) branch RDP-3 updated (bcf3db9b -> 8a2e8a85)

This is an automated email from the ASF dual-hosted git repository.

aleitner pushed a change to branch RDP-3
in repository https://gitbox.apache.org/repos/asf/guacamole-server.git


 discard bcf3db9b RDP-3.
     new 8a2e8a85 RDP-3.

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (bcf3db9b)
            \
             N -- N -- N   refs/heads/RDP-3 (8a2e8a85)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 configure.ac                | 18 ++++++++++++++++++
 src/protocols/rdp/bitmap.c  |  7 +++++++
 src/protocols/rdp/pointer.c |  7 +++++++
 3 files changed, 32 insertions(+)


(guacamole-server) 01/01: RDP-3.

Posted by al...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aleitner pushed a commit to branch RDP-3
in repository https://gitbox.apache.org/repos/asf/guacamole-server.git

commit 8a2e8a8516213fbcd03211cbd9fe536dc944ca2b
Author: Alex Leitner <le...@gmail.com>
AuthorDate: Tue May 7 17:02:26 2024 +0900

    RDP-3.
---
 Dockerfile                                         |   5 +-
 configure.ac                                       |  83 +++++---
 src/libguac/guacamole/string.h                     |  33 ++-
 src/libguac/string.c                               |  25 ++-
 src/protocols/rdp/Makefile.am                      |   3 +-
 src/protocols/rdp/bitmap.c                         |   8 +-
 src/protocols/rdp/channels/cliprdr.c               |  23 +-
 .../rdp/channels/rdpsnd/rdpsnd-messages.c          |   3 +-
 src/protocols/rdp/color.c                          |   5 +-
 src/protocols/rdp/gdi.c                            |   3 +-
 src/protocols/rdp/glyph.c                          |   3 +-
 src/protocols/rdp/glyph.h                          |   2 +-
 src/protocols/rdp/input.c                          |  10 +-
 src/protocols/rdp/keyboard.c                       |   6 +-
 src/protocols/rdp/plugins/channels.c               |   3 +-
 src/protocols/rdp/plugins/guacai/guacai.c          |   3 +-
 src/protocols/rdp/pointer.c                        |  12 +-
 src/protocols/rdp/pointer.h                        |   2 +-
 src/protocols/rdp/rdp.c                            |  37 ++--
 src/protocols/rdp/settings.c                       | 233 +++++++++++----------
 20 files changed, 292 insertions(+), 210 deletions(-)

diff --git a/Dockerfile b/Dockerfile
index 5f1e824c..7ff1856e 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -64,7 +64,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='3(\.\d+)+'
 ARG WITH_LIBSSH2='libssh2-\d+(\.\d+)+'
 ARG WITH_LIBTELNET='\d+(\.\d+)+'
 ARG WITH_LIBVNCCLIENT='LibVNCServer-\d+(\.\d+)+'
@@ -145,7 +145,7 @@ RUN ${BUILD_DIR}/src/guacd-docker/bin/build-all.sh
 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   \
+        ${PREFIX_DIR}/lib/freerdp3/*guac*.so   \
         > ${PREFIX_DIR}/DEPENDENCIES
 
 # Use same Alpine version as the base for the runtime image
@@ -202,4 +202,3 @@ EXPOSE 4822
 # PREFIX_DIR build argument.
 #
 CMD /opt/guacamole/sbin/guacd -b 0.0.0.0 -L $GUACD_LOG_LEVEL -f
-
diff --git a/configure.ac b/configure.ac
index c0394ac8..12c774e4 100644
--- a/configure.ac
+++ b/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
+    freerdp_version=3
+    have_freerdp=yes
+    PKG_CHECK_MODULES([RDP], [freerdp3 freerdp-client3 winpr3],
+                      [CPPFLAGS="${RDP_CFLAGS} -Werror $CPPFLAGS"]
+                      [AS_IF([test "x${FREERDP_PLUGIN_DIR}" = "x"],
+                             [FREERDP_PLUGIN_DIR="`$PKG_CONFIG --variable=libdir freerdp3`/freerdp3"])],
+                      [AC_MSG_WARN([
+  --------------------------------------------
+   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${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 freerdp2`/freerdp2"])],
                       [AC_MSG_WARN([
   --------------------------------------------
-   Unable to find FreeRDP (libfreerdp2 / libfreerdp-client2 / libwinpr2)
+   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,35 @@ 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>]])
 fi
 
+if test "x$have_freerdp" = "xyes"; then
+
+    # FreeRDP 3.x uses winpr_aligned_free() instead of _aligned_free()
+    AC_CHECK_DECL([winpr_aligned_free],
+                  [AC_DEFINE([HAVE_WINPR_ALIGNED_FREE], [1],
+                             [Defined if winpr_aligned_free() is available])],,
+                  [#include <winpr/crt.h>])
+
+    # Fallback to check for _aligned_free if winpr_aligned_free is not found
+    if test "x$ac_cv_have_decl_winpr_aligned_free" != "xyes"; then
+        AC_CHECK_DECL([_aligned_free],
+                      [AC_DEFINE([HAVE_ALIGNED_FREE], [1],
+                                 [Defined if _aligned_free() is available])],,
+                      [#include <winpr/crt.h>])
+    fi
+
+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 +1273,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 +1286,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 +1316,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.
 "
-
diff --git a/src/libguac/guacamole/string.h b/src/libguac/guacamole/string.h
index a94d53c2..bec28115 100644
--- a/src/libguac/guacamole/string.h
+++ b/src/libguac/guacamole/string.h
@@ -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
-
diff --git a/src/libguac/string.c b/src/libguac/string.c
index 2a7ec2cd..0fbf0bc4 100644
--- a/src/libguac/string.c
+++ b/src/libguac/string.c
@@ -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;
 
 }
-
diff --git a/src/protocols/rdp/Makefile.am b/src/protocols/rdp/Makefile.am
index 1c393c30..57204f2a 100644
--- a/src/protocols/rdp/Makefile.am
+++ b/src/protocols/rdp/Makefile.am
@@ -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
-
diff --git a/src/protocols/rdp/bitmap.c b/src/protocols/rdp/bitmap.c
index 05f9e214..ceef25bd 100644
--- a/src/protocols/rdp/bitmap.c
+++ b/src/protocols/rdp/bitmap.c
@@ -133,7 +133,14 @@ void guac_rdp_bitmap_free(rdpContext* context, rdpBitmap* bitmap) {
      * for the rdpBitmap will NOT be automatically released after this free
      * handler is invoked, thus we must do so manually here */
 
+    /* Use the appropriate aligned free function based on the FreeRDP version */
+    #ifdef HAVE_WINPR_ALIGNED_FREE
+    winpr_aligned_free(bitmap->data);
+    #else
+    /* Fall back to _aligned_free if winpr_aligned_free is not available */
     _aligned_free(bitmap->data);
+    #endif
+
     free(bitmap);
 #endif
 
@@ -167,4 +174,3 @@ BOOL guac_rdp_bitmap_setsurface(rdpContext* context, rdpBitmap* bitmap, BOOL pri
     return TRUE;
 
 }
-
diff --git a/src/protocols/rdp/channels/cliprdr.c b/src/protocols/rdp/channels/cliprdr.c
index 4b37d58a..d128b24f 100644
--- a/src/protocols/rdp/channels/cliprdr.c
+++ b/src/protocols/rdp/channels/cliprdr.c
@@ -80,9 +80,13 @@ static UINT guac_rdp_cliprdr_send_format_list(CliprdrClientContext* cliprdr) {
     guac_client* client = clipboard->client;
     guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
 
+
+
     /* We support CP-1252 and UTF-16 text */
     CLIPRDR_FORMAT_LIST format_list = {
-        .msgType = CB_FORMAT_LIST,
+        .common = {
+            .msgType = CB_FORMAT_LIST
+        },
         .formats = (CLIPRDR_FORMAT[]) {
             { .formatId = CF_TEXT },
             { .formatId = CF_UNICODETEXT }
@@ -298,9 +302,11 @@ 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 = {
-        .msgFlags = CB_RESPONSE_OK
+        .common = {
+            .msgType = CB_FORMAT_LIST_RESPONSE,
+            .msgFlags = CB_RESPONSE_OK
+        }
     };
-
     /* Report successful processing of format list */
     pthread_mutex_lock(&(rdp_client->message_lock));
     cliprdr->ClientFormatListResponse(cliprdr, &format_list_response);
@@ -394,8 +400,12 @@ static UINT guac_rdp_cliprdr_format_data_request(CliprdrClientContext* cliprdr,
 
     CLIPRDR_FORMAT_DATA_RESPONSE data_response = {
         .requestedFormatData = (BYTE*) start,
-        .dataLen = ((BYTE*) output) - start,
-        .msgFlags = CB_RESPONSE_OK
+        
+        .common = {
+            .msgType = CB_FORMAT_DATA_RESPONSE,
+            .msgFlags = CB_RESPONSE_OK,
+            .dataLen = ((BYTE*) output) - start,
+        },
     };
 
     guac_client_log(client, GUAC_LOG_TRACE, "CLIPRDR: Sending format data response.");
@@ -484,7 +494,7 @@ static UINT guac_rdp_cliprdr_format_data_response(CliprdrClientContext* cliprdr,
 
     /* 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, format_data_response->common.dataLen,
             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 +722,3 @@ int guac_rdp_clipboard_end_handler(guac_user* user, guac_stream* stream) {
     return 0;
 
 }
-
diff --git a/src/protocols/rdp/channels/rdpsnd/rdpsnd-messages.c b/src/protocols/rdp/channels/rdpsnd/rdpsnd-messages.c
index 1aeb8df9..7c57bc5c 100644
--- a/src/protocols/rdp/channels/rdpsnd/rdpsnd-messages.c
+++ b/src/protocols/rdp/channels/rdpsnd/rdpsnd-messages.c
@@ -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 */
 
 }
-
diff --git a/src/protocols/rdp/color.c b/src/protocols/rdp/color.c
index 964310af..0a86eca5 100644
--- a/src/protocols/rdp/color.c
+++ b/src/protocols/rdp/color.c
@@ -56,7 +56,7 @@ 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 = FreeRDPReadColor((BYTE*) &color, src_format);
 
     /* Convert color from RDP source format to the native format used by Cairo,
      * still maintaining intermediate representation */
@@ -69,8 +69,7 @@ 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);
+    FreeRDPWriteColor((BYTE*) &color, dst_format, intermed);
     return color;
 
 }
-
diff --git a/src/protocols/rdp/gdi.c b/src/protocols/rdp/gdi.c
index 6fc311bf..c43e38b5 100644
--- a/src/protocols/rdp/gdi.c
+++ b/src/protocols/rdp/gdi.c
@@ -412,7 +412,7 @@ 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)
+    if (freerdp_settings_get_uint32(context->settings, FreeRDP_FrameAcknowledge) > 0)
         IFCALL(context->update->SurfaceFrameAcknowledge, context,
                 surface_frame_marker->frameId);
 
@@ -496,4 +496,3 @@ BOOL guac_rdp_gdi_desktop_resize(rdpContext* context) {
             guac_rdp_get_height(context->instance));
 
 }
-
diff --git a/src/protocols/rdp/glyph.c b/src/protocols/rdp/glyph.c
index 7241a385..14d1fbdd 100644
--- a/src/protocols/rdp/glyph.c
+++ b/src/protocols/rdp/glyph.c
@@ -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, rdpGlyph* glyph) {
 
     int x, y, i;
     int stride;
@@ -168,4 +168,3 @@ BOOL guac_rdp_glyph_enddraw(rdpContext* context,
     /* IGNORE */
     return TRUE;
 }
-
diff --git a/src/protocols/rdp/glyph.h b/src/protocols/rdp/glyph.h
index b217de02..29612346 100644
--- a/src/protocols/rdp/glyph.h
+++ b/src/protocols/rdp/glyph.h
@@ -71,7 +71,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, rdpGlyph* glyph);
 
 /**
  * Draws a previously-cached glyph at the given coordinates within the current
diff --git a/src/protocols/rdp/input.c b/src/protocols/rdp/input.c
index 458c12e7..9b072b54 100644
--- a/src/protocols/rdp/input.c
+++ b/src/protocols/rdp/input.c
@@ -57,7 +57,7 @@ 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);
+        rdp_inst->context->input->MouseEvent(rdp_inst->context->input, PTR_FLAGS_MOVE, x, y);
         pthread_mutex_unlock(&(rdp_client->message_lock));
     }
 
@@ -80,7 +80,7 @@ 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);
+            rdp_inst->context->input->MouseEvent(rdp_inst->context->input, flags, x, y);
             pthread_mutex_unlock(&(rdp_client->message_lock));
 
         }
@@ -98,7 +98,7 @@ 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);
+            rdp_inst->context->input->MouseEvent(rdp_inst->context->input, flags, x, y);
             pthread_mutex_unlock(&(rdp_client->message_lock));
 
         }
@@ -109,14 +109,14 @@ 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);
+                rdp_inst->context->input->MouseEvent(rdp_inst->context->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);
+                rdp_inst->context->input->MouseEvent(rdp_inst->context->input, PTR_FLAGS_WHEEL | PTR_FLAGS_WHEEL_NEGATIVE | 0x88, x, y);
                 pthread_mutex_unlock(&(rdp_client->message_lock));
             }
 
diff --git a/src/protocols/rdp/keyboard.c b/src/protocols/rdp/keyboard.c
index fa93c20e..7c68f1fd 100644
--- a/src/protocols/rdp/keyboard.c
+++ b/src/protocols/rdp/keyboard.c
@@ -107,7 +107,7 @@ 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);
+    rdp_inst->context->input->KeyboardEvent(rdp_inst->context->input, flags | pressed_flags, scancode);
     pthread_mutex_unlock(&(rdp_client->message_lock));
 
 }
@@ -136,7 +136,7 @@ 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);
+    rdp_inst->context->input->UnicodeKeyboardEvent(rdp_inst->context->input, 0, codepoint);
     pthread_mutex_unlock(&(rdp_client->message_lock));
 
 }
@@ -165,7 +165,7 @@ 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);
+    rdp_inst->context->input->SynchronizeEvent(rdp_inst->context->input, flags);
     pthread_mutex_unlock(&(rdp_client->message_lock));
 
 }
diff --git a/src/protocols/rdp/plugins/channels.c b/src/protocols/rdp/plugins/channels.c
index 342ca33b..640bb708 100644
--- a/src/protocols/rdp/plugins/channels.c
+++ b/src/protocols/rdp/plugins/channels.c
@@ -136,8 +136,7 @@ void guac_freerdp_dynamic_channel_collection_add(rdpSettings* settings,
     va_end(args);
 
     /* Register plugin with FreeRDP */
-    settings->SupportDynamicChannels = TRUE;
+    freerdp_settings_set_bool(settings, FreeRDP_SupportDynamicChannels, TRUE);
     freerdp_dynamic_channel_collection_add(settings, freerdp_args);
 
 }
-
diff --git a/src/protocols/rdp/plugins/guacai/guacai.c b/src/protocols/rdp/plugins/guacai/guacai.c
index 6ab633c0..aa8ecd42 100644
--- a/src/protocols/rdp/plugins/guacai/guacai.c
+++ b/src/protocols/rdp/plugins/guacai/guacai.c
@@ -283,7 +283,7 @@ static UINT guac_rdp_ai_terminated(IWTSPlugin* plugin) {
 UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) {
 
     /* Pull guac_client from arguments */
-    ADDIN_ARGV* args = pEntryPoints->GetPluginData(pEntryPoints);
+    const ADDIN_ARGV* args = pEntryPoints->GetPluginData(pEntryPoints);
     guac_client* client = (guac_client*) guac_rdp_string_to_ptr(args->argv[1]);
 
     /* Pull previously-allocated plugin */
@@ -309,4 +309,3 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) {
     return CHANNEL_RC_OK;
 
 }
-
diff --git a/src/protocols/rdp/pointer.c b/src/protocols/rdp/pointer.c
index 8c024b71..4e219c51 100644
--- a/src/protocols/rdp/pointer.c
+++ b/src/protocols/rdp/pointer.c
@@ -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 = winpr_aligned_malloc(pointer->width * pointer->height * 4, 16);
 
     cairo_surface_t* surface;
 
@@ -64,7 +64,14 @@ BOOL guac_rdp_pointer_new(rdpContext* context, rdpPointer* pointer) {
 
     /* Free surface */
     cairo_surface_destroy(surface);
+    
+    /* Use the appropriate aligned free function based on the FreeRDP version */
+    #ifdef HAVE_WINPR_ALIGNED_FREE
+    winpr_aligned_free(data);
+    #else
+    /* Fall back to _aligned_free if winpr_aligned_free is not available */
     _aligned_free(data);
+    #endif
 
     /* Remember buffer */
     ((guac_rdp_pointer*) pointer)->layer = buffer;
@@ -73,7 +80,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, rdpPointer* pointer) {
 
     guac_client* client = ((rdp_freerdp_context*) context)->client;
     guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
@@ -156,4 +163,3 @@ BOOL guac_rdp_pointer_set_default(rdpContext* context) {
 
     return TRUE;
 }
-
diff --git a/src/protocols/rdp/pointer.h b/src/protocols/rdp/pointer.h
index b5fa6a23..42edb136 100644
--- a/src/protocols/rdp/pointer.h
+++ b/src/protocols/rdp/pointer.h
@@ -71,7 +71,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, rdpPointer* pointer);
 
 /**
  * Frees all Guacamole-related data associated with the given pointer, allowing
diff --git a/src/protocols/rdp/rdp.c b/src/protocols/rdp/rdp.c
index dff536ef..15e8691b 100644
--- a/src/protocols/rdp/rdp.c
+++ b/src/protocols/rdp/rdp.c
@@ -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>
@@ -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;
+    instance->context->update->PlaySound = guac_rdp_beep_play_sound;
 
     /* Automatically synchronize keyboard locks when changed server-side */
-    instance->update->SetKeyboardIndicators = guac_rdp_keyboard_set_indicators;
+    instance->context->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;
+    instance->context->update->DesktopResize = guac_rdp_gdi_desktop_resize;
+    instance->context->update->BeginPaint = guac_rdp_gdi_begin_paint;
+    instance->context->update->EndPaint = guac_rdp_gdi_end_paint;
+    instance->context->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;
+    instance->context->update->SurfaceFrameMarker = guac_rdp_gdi_surface_frame_marker;
+    instance->context->update->altsec->FrameMarker = guac_rdp_gdi_frame_marker;
 
-    rdpPrimaryUpdate* primary = instance->update->primary;
+    rdpPrimaryUpdate* primary = instance->context->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(instance->context->settings, FreeRDP_SupportDynamicChannels) &&
             guac_freerdp_channels_load_plugin(context, "drdynvc",
-                instance->settings)) {
+                instance->context->settings)) {
         guac_client_log(client, GUAC_LOG_WARNING,
                 "Failed to load drdynvc plugin. Display update and audio "
                 "input support will be disabled.");
@@ -622,7 +609,7 @@ 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 = freerdp_shall_disconnect_context(rdp_inst->context);
 
         /* Close connection cleanly if server is disconnecting */
         if (connection_closing)
diff --git a/src/protocols/rdp/settings.c b/src/protocols/rdp/settings.c
index 4b02b3eb..af1008ad 100644
--- a/src/protocols/rdp/settings.c
+++ b/src/protocols/rdp/settings.c
@@ -1395,15 +1395,15 @@ void guac_rdp_settings_free(guac_rdp_settings* settings) {
 }
 
 int guac_rdp_get_width(freerdp* rdp) {
-    return rdp->settings->DesktopWidth;
+    return freerdp_settings_get_uint32(rdp->context->settings, FreeRDP_DesktopWidth);
 }
 
 int guac_rdp_get_height(freerdp* rdp) {
-    return rdp->settings->DesktopHeight;
+    return freerdp_settings_get_uint32(rdp->context->settings, FreeRDP_DesktopHeight);
 }
 
 int guac_rdp_get_depth(freerdp* rdp) {
-    return rdp->settings->ColorDepth;
+    return freerdp_settings_get_uint32(rdp->context->settings, FreeRDP_ColorDepth);
 }
 
 /**
@@ -1454,78 +1454,80 @@ static int guac_rdp_get_performance_flags(guac_rdp_settings* guac_settings) {
 void guac_rdp_push_settings(guac_client* client,
         guac_rdp_settings* guac_settings, freerdp* rdp) {
 
-    rdpSettings* rdp_settings = rdp->settings;
+    rdpSettings* rdp_settings = rdp->context->settings;
 
     /* Authentication */
-    rdp_settings->Domain = guac_strdup(guac_settings->domain);
-    rdp_settings->Username = guac_strdup(guac_settings->username);
-    rdp_settings->Password = guac_strdup(guac_settings->password);
+    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 */
-    rdp_settings->ServerHostname = guac_strdup(guac_settings->hostname);
-    rdp_settings->ServerPort = guac_settings->port;
+    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 */
-    rdp_settings->ColorDepth = guac_settings->color_depth;
-    rdp_settings->DesktopWidth = guac_settings->width;
-    rdp_settings->DesktopHeight = guac_settings->height;
-    rdp_settings->AlternateShell = guac_strdup(guac_settings->initial_program);
-    rdp_settings->KeyboardLayout = guac_settings->server_layout->freerdp_keyboard_layout;
+
+    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 */
-    rdp_settings->PerformanceFlags = guac_rdp_get_performance_flags(guac_settings);
+    freerdp_settings_set_uint32(rdp_settings, FreeRDP_PerformanceFlags, guac_rdp_get_performance_flags(guac_settings));
 
     /* Always request frame markers */
-    rdp_settings->FrameMarkerCommandEnabled = TRUE;
-    rdp_settings->SurfaceFrameMarkerEnabled = TRUE;
+    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) {
 
-        rdp_settings->SupportGraphicsPipeline = TRUE;
-        rdp_settings->RemoteFxCodec = TRUE;
+        freerdp_settings_set_bool(rdp_settings, FreeRDP_SupportGraphicsPipeline, TRUE);
+        freerdp_settings_set_bool(rdp_settings, FreeRDP_RemoteFxCodec, TRUE);
 
-        if (rdp_settings->ColorDepth != RDP_GFX_REQUIRED_DEPTH) {
+        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.", rdp_settings->ColorDepth, RDP_GFX_REQUIRED_DEPTH);
+                    "requires %i bpp.", freerdp_settings_get_uint32(rdp_settings, FreeRDP_ColorDepth), RDP_GFX_REQUIRED_DEPTH);
         }
 
         /* Required for RemoteFX / Graphics Pipeline */
-        rdp_settings->FastPathOutput = TRUE;
-        rdp_settings->ColorDepth = RDP_GFX_REQUIRED_DEPTH;
-        rdp_settings->SoftwareGdi = TRUE;
+        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 the 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;
-    rdp_settings->DisableMenuAnims = !guac_settings->menu_animations_enabled;
-    rdp_settings->DisableThemes = !guac_settings->theming_enabled;
-    rdp_settings->AllowDesktopComposition = guac_settings->desktop_composition_enabled;
+    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) {
-        guac_strlcpy(rdp_settings->ClientHostname, guac_settings->client_name,
-                RDP_CLIENT_HOSTNAME_SIZE);
+        freerdp_settings_set_string(rdp_settings, FreeRDP_ClientHostname, 
+                guac_strndup(guac_settings->client_name, RDP_CLIENT_HOSTNAME_SIZE));
     }
 
     /* Console */
-    rdp_settings->ConsoleSession = guac_settings->console;
-    rdp_settings->RemoteConsoleAudio = guac_settings->console_audio;
+    freerdp_settings_set_bool(rdp_settings, FreeRDP_ConsoleSession, guac_settings->console);
+    freerdp_settings_set_bool(rdp_settings, FreeRDP_RemoteConsoleAudio, guac_settings->console_audio);
 
     /* Audio */
-    rdp_settings->AudioPlayback = guac_settings->audio_enabled;
+    freerdp_settings_set_bool(rdp_settings, FreeRDP_AudioPlayback, guac_settings->audio_enabled);
 
     /* Audio capture */
-    rdp_settings->AudioCapture = guac_settings->enable_audio_input;
+    freerdp_settings_set_bool(rdp_settings, FreeRDP_AudioCapture, guac_settings->enable_audio_input);
 
     /* Display Update channel */
-    rdp_settings->SupportDisplayControl =
-        (guac_settings->resize_method == GUAC_RESIZE_DISPLAY_UPDATE);
+    freerdp_settings_set_bool(rdp_settings, FreeRDP_SupportDisplayControl, 
+            (guac_settings->resize_method == GUAC_RESIZE_DISPLAY_UPDATE));
 
     /* Timezone redirection */
     if (guac_settings->timezone) {
@@ -1537,64 +1539,62 @@ void guac_rdp_push_settings(guac_client* client,
     }
 
     /* Device redirection */
-    rdp_settings->DeviceRedirection =  guac_settings->audio_enabled
-                                    || guac_settings->drive_enabled
-                                    || guac_settings->printing_enabled;
+    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:
-            rdp_settings->RdpSecurity = TRUE;
-            rdp_settings->TlsSecurity = FALSE;
-            rdp_settings->NlaSecurity = FALSE;
-            rdp_settings->ExtSecurity = FALSE;
-            rdp_settings->UseRdpSecurityLayer = TRUE;
-            rdp_settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE;
-            rdp_settings->EncryptionMethods =
-                  ENCRYPTION_METHOD_40BIT
-                | ENCRYPTION_METHOD_128BIT 
-                | ENCRYPTION_METHOD_FIPS;
+            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:
-            rdp_settings->RdpSecurity = FALSE;
-            rdp_settings->TlsSecurity = TRUE;
-            rdp_settings->NlaSecurity = FALSE;
-            rdp_settings->ExtSecurity = FALSE;
+            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:
-            rdp_settings->RdpSecurity = FALSE;
-            rdp_settings->TlsSecurity = FALSE;
-            rdp_settings->NlaSecurity = TRUE;
-            rdp_settings->ExtSecurity = FALSE;
+            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:
-            rdp_settings->RdpSecurity = FALSE;
-            rdp_settings->TlsSecurity = FALSE;
-            rdp_settings->NlaSecurity = FALSE;
-            rdp_settings->ExtSecurity = TRUE;
+            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:
-            rdp_settings->RdpSecurity = FALSE;
-            rdp_settings->TlsSecurity = TRUE;
-            rdp_settings->NlaSecurity = TRUE;
-            rdp_settings->ExtSecurity = FALSE;
-            rdp_settings->VmConnectMode = TRUE;
+            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:
-            rdp_settings->RdpSecurity = TRUE;
-            rdp_settings->TlsSecurity = TRUE;
+            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()) {
@@ -1602,95 +1602,100 @@ void guac_rdp_push_settings(guac_client* client,
                 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).");
-                rdp_settings->NlaSecurity = FALSE;
+                freerdp_settings_set_bool(rdp_settings, FreeRDP_NlaSecurity, FALSE);
 
             }
 
             /* NLA mode is allowed if FIPS is not enabled */
             else
-                rdp_settings->NlaSecurity = TRUE;
+                freerdp_settings_set_bool(rdp_settings, FreeRDP_NlaSecurity, TRUE);
 
-            rdp_settings->ExtSecurity = FALSE;
+            freerdp_settings_set_bool(rdp_settings, FreeRDP_ExtSecurity, FALSE);
             break;
 
     }
 
     /* Security */
-    rdp_settings->Authentication = !guac_settings->disable_authentication;
-    rdp_settings->IgnoreCertificate = guac_settings->ignore_certificate;
-    rdp_settings->AutoAcceptCertificate = guac_settings->certificate_tofu;
+    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)
-        rdp_settings->CertificateAcceptedFingerprints = guac_strdup(guac_settings->certificate_fingerprints);
+        freerdp_settings_set_string(rdp_settings, FreeRDP_CertificateAcceptedFingerprints, 
+                guac_strdup(guac_settings->certificate_fingerprints));
+
 
     /* RemoteApp */
     if (guac_settings->remote_app != NULL) {
-        rdp_settings->Workarea = TRUE;
-        rdp_settings->RemoteApplicationMode = TRUE;
-        rdp_settings->RemoteAppLanguageBarSupported = TRUE;
-        rdp_settings->RemoteApplicationProgram = guac_strdup(guac_settings->remote_app);
-        rdp_settings->ShellWorkingDirectory = guac_strdup(guac_settings->remote_app_dir);
-        rdp_settings->RemoteApplicationCmdLine = guac_strdup(guac_settings->remote_app_args);
+        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) {
-        rdp_settings->NegotiateSecurityLayer = FALSE;
-        rdp_settings->SendPreconnectionPdu = TRUE;
-        rdp_settings->PreconnectionId = guac_settings->preconnection_id;
+        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) {
-        rdp_settings->NegotiateSecurityLayer = FALSE;
-        rdp_settings->SendPreconnectionPdu = TRUE;
-        rdp_settings->PreconnectionBlob = guac_strdup(guac_settings->preconnection_blob);
+        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 */
-        rdp_settings->GatewayEnabled = TRUE;
+        freerdp_settings_set_bool(rdp_settings, FreeRDP_GatewayEnabled, TRUE);
 
         /* RD gateway connection details */
-        rdp_settings->GatewayHostname = guac_strdup(guac_settings->gateway_hostname);
-        rdp_settings->GatewayPort = guac_settings->gateway_port;
+        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 */
-        rdp_settings->GatewayUseSameCredentials = FALSE;
-        rdp_settings->GatewayDomain = guac_strdup(guac_settings->gateway_domain);
-        rdp_settings->GatewayUsername = guac_strdup(guac_settings->gateway_username);
-        rdp_settings->GatewayPassword = guac_strdup(guac_settings->gateway_password);
+        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) {
-        rdp_settings->LoadBalanceInfo = (BYTE*) guac_strdup(guac_settings->load_balance_info);
-        rdp_settings->LoadBalanceInfoLength = strlen(guac_settings->load_balance_info);
+        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));
     }
 
-    rdp_settings->BitmapCacheEnabled = !guac_settings->disable_bitmap_caching;
-    rdp_settings->OffscreenSupportLevel = !guac_settings->disable_offscreen_caching;
-    rdp_settings->GlyphSupportLevel = !guac_settings->disable_glyph_caching ? GLYPH_SUPPORT_FULL : GLYPH_SUPPORT_NONE;
-    rdp_settings->OsMajorType = OSMAJORTYPE_UNSPECIFIED;
-    rdp_settings->OsMinorType = OSMINORTYPE_UNSPECIFIED;
-    rdp_settings->DesktopResize = TRUE;
+    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 */
-    ZeroMemory(rdp_settings->OrderSupport, GUAC_RDP_ORDER_SUPPORT_LENGTH);
-    rdp_settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE;
-    rdp_settings->OrderSupport[NEG_SCRBLT_INDEX] = TRUE;
-    rdp_settings->OrderSupport[NEG_MEMBLT_INDEX] = !guac_settings->disable_bitmap_caching;
-    rdp_settings->OrderSupport[NEG_MEMBLT_V2_INDEX] = !guac_settings->disable_bitmap_caching;
-    rdp_settings->OrderSupport[NEG_GLYPH_INDEX_INDEX] = !guac_settings->disable_glyph_caching;
-    rdp_settings->OrderSupport[NEG_FAST_INDEX_INDEX] = !guac_settings->disable_glyph_caching;
-    rdp_settings->OrderSupport[NEG_FAST_GLYPH_INDEX] = !guac_settings->disable_glyph_caching;
+	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 */
-    rdp_settings->AllowUnanouncedOrdersFromServer = TRUE;
+    freerdp_settings_set_bool(rdp_settings, FreeRDP_AllowUnanouncedOrdersFromServer, TRUE);
 #endif
 
 }
-