From 8ecf841e71bfffafe36b2cca3dbe224d81bbb2d0 Mon Sep 17 00:00:00 2001 From: akallabeth Date: Wed, 29 Jun 2022 12:35:31 +0200 Subject: [PATCH] Added RAIL compartmentinfo server to client message --- channels/rail/client/rail_orders.c | 58 +++++++++++++++++++++++++++++- include/freerdp/settings.h | 3 ++ libfreerdp/common/settings.c | 23 ++++++++++++ 3 files changed, 83 insertions(+), 1 deletion(-) diff --git a/channels/rail/client/rail_orders.c b/channels/rail/client/rail_orders.c index 2d27b5f41..e08542243 100644 --- a/channels/rail/client/rail_orders.c +++ b/channels/rail/client/rail_orders.c @@ -30,6 +30,8 @@ #include "rail_orders.h" +static BOOL rail_is_feature_supported(const rdpContext* context, UINT32 featureMask); + /** * Function description * @@ -372,7 +374,46 @@ static UINT rail_recv_handshake_order(railPlugin* rail, wStream* s) return error; } -static BOOL rail_is_feature_supported(const rdpContext* context, UINT32 featureMask) +static UINT rail_read_compartment_info_order(wStream* s, + RAIL_COMPARTMENT_INFO_ORDER* compartmentInfo) +{ + if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_COMPARTMENT_INFO_ORDER_LENGTH)) + return ERROR_INVALID_DATA; + + Stream_Read_UINT32(s, compartmentInfo->ImeState); /* ImeState (4 bytes) */ + Stream_Read_UINT32(s, compartmentInfo->ImeConvMode); /* ImeConvMode (4 bytes) */ + Stream_Read_UINT32(s, compartmentInfo->ImeSentenceMode); /* ImeSentenceMode (4 bytes) */ + Stream_Read_UINT32(s, compartmentInfo->KanaMode); /* KANAMode (4 bytes) */ + return CHANNEL_RC_OK; +} + +static UINT rail_recv_compartmentinfo_order(railPlugin* rail, wStream* s) +{ + RailClientContext* context = rail_get_client_interface(rail); + RAIL_COMPARTMENT_INFO_ORDER pdu = { 0 }; + UINT error; + + if (!context || !s) + return ERROR_INVALID_PARAMETER; + + if (!rail_is_feature_supported(rail->rdpcontext, RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED)) + return ERROR_BAD_CONFIGURATION; + + if ((error = rail_read_compartment_info_order(s, &pdu))) + return error; + + if (context->custom) + { + IFCALLRET(context->ClientCompartmentInfo, error, context, &pdu); + + if (error) + WLog_ERR(TAG, "context.ClientCompartmentInfo failed with error %" PRIu32 "", error); + } + + return error; +} + +BOOL rail_is_feature_supported(const rdpContext* context, UINT32 featureMask) { UINT32 supported, masked; @@ -384,7 +425,15 @@ static BOOL rail_is_feature_supported(const rdpContext* context, UINT32 featureM masked = (supported & featureMask); if (masked != featureMask) + { + char mask[256] = { 0 }; + char actual[256] = { 0 }; + + WLog_WARN(TAG, "[%s] have %s, require %s", __func__, + freerdp_rail_support_flags_to_string(supported, actual, sizeof(actual)), + freerdp_rail_support_flags_to_string(featureMask, mask, sizeof(mask))); return FALSE; + } return TRUE; } @@ -968,6 +1017,10 @@ UINT rail_order_recv(LPVOID userdata, wStream* s) error = rail_recv_handshake_order(rail, s); break; + case TS_RAIL_ORDER_COMPARTMENTINFO: + error = rail_recv_compartmentinfo_order(rail, s); + break; + case TS_RAIL_ORDER_HANDSHAKE_EX: error = rail_recv_handshake_ex_order(rail, s); break; @@ -1423,6 +1476,9 @@ UINT rail_send_client_compartment_info_order(railPlugin* rail, if (!rail || !compartmentInfo) return ERROR_INVALID_PARAMETER; + if (!rail_is_feature_supported(rail->rdpcontext, RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED)) + return ERROR_BAD_CONFIGURATION; + s = rail_pdu_init(RAIL_COMPARTMENT_INFO_ORDER_LENGTH); if (!s) diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 65d8aa0c1..2fff745d6 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -1819,6 +1819,9 @@ extern "C" FREERDP_API const char* freerdp_settings_get_name_for_key(size_t key); FREERDP_API UINT32 freerdp_settings_get_codecs_flags(const rdpSettings* settings); + FREERDP_API char* freerdp_rail_support_flags_to_string(UINT32 flags, char* buffer, + size_t length); + #ifdef __cplusplus } #endif diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index 80de6504a..f543012d4 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -1811,3 +1811,26 @@ BOOL freerdp_device_equal(const RDPDR_DEVICE* what, const RDPDR_DEVICE* expect) return TRUE; } + +char* freerdp_rail_support_flags_to_string(UINT32 flags, char* buffer, size_t length) +{ + if (flags & RAIL_LEVEL_SUPPORTED) + winpr_str_append("RAIL_LEVEL_SUPPORTED", buffer, length, "|"); + if (flags & RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED) + winpr_str_append("RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED", buffer, length, "|"); + if (flags & RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED) + winpr_str_append("RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED", buffer, length, "|"); + if (flags & RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED) + winpr_str_append("RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED", buffer, length, "|"); + if (flags & RAIL_LEVEL_SERVER_TO_CLIENT_IME_SYNC_SUPPORTED) + winpr_str_append("RAIL_LEVEL_SERVER_TO_CLIENT_IME_SYNC_SUPPORTED", buffer, length, "|"); + if (flags & RAIL_LEVEL_HIDE_MINIMIZED_APPS_SUPPORTED) + winpr_str_append("RAIL_LEVEL_HIDE_MINIMIZED_APPS_SUPPORTED", buffer, length, "|"); + if (flags & RAIL_LEVEL_WINDOW_CLOAKING_SUPPORTED) + winpr_str_append("RAIL_LEVEL_WINDOW_CLOAKING_SUPPORTED", buffer, length, "|"); + if (flags & RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED) + winpr_str_append("RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED", buffer, length, "|"); + if (flags & RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED) + winpr_str_append("RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED", buffer, length, "|"); + return buffer; +}