diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 539419fcb..5e1909cb4 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -549,6 +549,9 @@ typedef struct #define FreeRDP_DesktopOrientation (147) #define FreeRDP_DesktopScaleFactor (148) #define FreeRDP_DeviceScaleFactor (149) +#define FreeRDP_SupportEdgeActionV1 (150) +#define FreeRDP_SupportEdgeActionV2 (151) +#define FreeRDP_SupportSkipChannelJoin (152) #define FreeRDP_UseRdpSecurityLayer (192) #define FreeRDP_EncryptionMethods (193) #define FreeRDP_ExtEncryptionMethods (194) @@ -1011,7 +1014,11 @@ struct rdp_settings ALIGN64 UINT16 DesktopOrientation; /* 147 */ ALIGN64 UINT32 DesktopScaleFactor; /* 148 */ ALIGN64 UINT32 DeviceScaleFactor; /* 149 */ - UINT64 padding0192[192 - 150]; /* 150 */ + ALIGN64 BOOL SupportEdgeActionV1; /* 150 */ + ALIGN64 BOOL SupportEdgeActionV2; /* 151 */ + ALIGN64 BOOL SupportSkipChannelJoin; /* 152 */ + + UINT64 padding0192[192 - 153]; /* 153 */ /* Client/Server Security Data */ ALIGN64 BOOL UseRdpSecurityLayer; /* 192 */ diff --git a/libfreerdp/common/settings_getters.c b/libfreerdp/common/settings_getters.c index f3e0bd110..2be00e1f0 100644 --- a/libfreerdp/common/settings_getters.c +++ b/libfreerdp/common/settings_getters.c @@ -481,6 +481,12 @@ BOOL freerdp_settings_get_bool(const rdpSettings* settings, size_t id) case FreeRDP_SupportEchoChannel: return settings->SupportEchoChannel; + case FreeRDP_SupportEdgeActionV1: + return settings->SupportEdgeActionV1; + + case FreeRDP_SupportEdgeActionV2: + return settings->SupportEdgeActionV2; + case FreeRDP_SupportErrorInfoPdu: return settings->SupportErrorInfoPdu; @@ -502,6 +508,9 @@ BOOL freerdp_settings_get_bool(const rdpSettings* settings, size_t id) case FreeRDP_SupportSSHAgentChannel: return settings->SupportSSHAgentChannel; + case FreeRDP_SupportSkipChannelJoin: + return settings->SupportSkipChannelJoin; + case FreeRDP_SupportStatusInfoPdu: return settings->SupportStatusInfoPdu; @@ -1177,6 +1186,14 @@ BOOL freerdp_settings_set_bool(rdpSettings* settings, size_t id, BOOL val) settings->SupportEchoChannel = cnv.c; break; + case FreeRDP_SupportEdgeActionV1: + settings->SupportEdgeActionV1 = cnv.c; + break; + + case FreeRDP_SupportEdgeActionV2: + settings->SupportEdgeActionV2 = cnv.c; + break; + case FreeRDP_SupportErrorInfoPdu: settings->SupportErrorInfoPdu = cnv.c; break; @@ -1205,6 +1222,10 @@ BOOL freerdp_settings_set_bool(rdpSettings* settings, size_t id, BOOL val) settings->SupportSSHAgentChannel = cnv.c; break; + case FreeRDP_SupportSkipChannelJoin: + settings->SupportSkipChannelJoin = cnv.c; + break; + case FreeRDP_SupportStatusInfoPdu: settings->SupportStatusInfoPdu = cnv.c; break; diff --git a/libfreerdp/common/settings_str.c b/libfreerdp/common/settings_str.c index b0fe15940..46dabc1e9 100644 --- a/libfreerdp/common/settings_str.c +++ b/libfreerdp/common/settings_str.c @@ -208,6 +208,8 @@ static const struct settings_str_entry settings_map[] = { { FreeRDP_SupportDynamicTimeZone, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SupportDynamicTimeZone" }, { FreeRDP_SupportEchoChannel, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SupportEchoChannel" }, + { FreeRDP_SupportEdgeActionV1, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SupportEdgeActionV1" }, + { FreeRDP_SupportEdgeActionV2, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SupportEdgeActionV2" }, { FreeRDP_SupportErrorInfoPdu, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SupportErrorInfoPdu" }, { FreeRDP_SupportGeometryTracking, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SupportGeometryTracking" }, @@ -219,6 +221,8 @@ static const struct settings_str_entry settings_map[] = { { FreeRDP_SupportMultitransport, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SupportMultitransport" }, { FreeRDP_SupportSSHAgentChannel, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SupportSSHAgentChannel" }, + { FreeRDP_SupportSkipChannelJoin, FREERDP_SETTINGS_TYPE_BOOL, + "FreeRDP_SupportSkipChannelJoin" }, { FreeRDP_SupportStatusInfoPdu, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SupportStatusInfoPdu" }, { FreeRDP_SupportVideoOptimized, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SupportVideoOptimized" }, { FreeRDP_SuppressOutput, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SuppressOutput" }, diff --git a/libfreerdp/core/gcc.c b/libfreerdp/core/gcc.c index 3bf1a3d74..eb6e7192d 100644 --- a/libfreerdp/core/gcc.c +++ b/libfreerdp/core/gcc.c @@ -875,7 +875,17 @@ static UINT32 filterAndLogEarlyServerCapabilityFlags(UINT32 flags) static UINT32 earlyServerCapsFromSettings(const rdpSettings* settings) { - UINT32 EarlyCapabilityFlags = settings->EarlyCapabilityFlags; + UINT32 EarlyCapabilityFlags = 0; + + if (settings->SupportEdgeActionV1) + EarlyCapabilityFlags |= RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V1; + if (settings->SupportDynamicTimeZone) + EarlyCapabilityFlags |= RNS_UD_SC_DYNAMIC_DST_SUPPORTED; + if (settings->SupportEdgeActionV2) + EarlyCapabilityFlags |= RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V2; + if (settings->SupportSkipChannelJoin) + EarlyCapabilityFlags |= RNS_UD_SC_SKIP_CHANNELJOIN_SUPPORTED; + return filterAndLogEarlyServerCapabilityFlags(EarlyCapabilityFlags); } @@ -904,36 +914,41 @@ static UINT16 filterAndLogEarlyClientCapabilityFlags(UINT32 flags) static UINT16 earlyClientCapsFromSettings(const rdpSettings* settings) { - WINPR_ASSERT(settings); - UINT32 earlyCapabilityFlags = settings->EarlyCapabilityFlags; + UINT32 earlyCapabilityFlags = 0; WINPR_ASSERT(settings); if (settings->SupportErrorInfoPdu) earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_ERRINFO_PDU; - if (settings->ConnectionType) - earlyCapabilityFlags |= RNS_UD_CS_VALID_CONNECTION_TYPE; - if (freerdp_settings_get_uint32(settings, FreeRDP_ColorDepth) == 32) earlyCapabilityFlags |= RNS_UD_CS_WANT_32BPP_SESSION; + if (settings->SupportStatusInfoPdu) + earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_STATUSINFO_PDU; + + if (settings->ConnectionType) + earlyCapabilityFlags |= RNS_UD_CS_VALID_CONNECTION_TYPE; + + if (settings->SupportMonitorLayoutPdu) + earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU; + if (freerdp_settings_get_bool(settings, FreeRDP_NetworkAutoDetect)) earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_NETCHAR_AUTODETECT; - if (settings->SupportHeartbeatPdu) - earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_HEARTBEAT_PDU; - if (settings->SupportGraphicsPipeline) earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL; if (settings->SupportDynamicTimeZone) earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE; - if (settings->SupportMonitorLayoutPdu) - earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU; + if (settings->SupportHeartbeatPdu) + earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_HEARTBEAT_PDU; - if (settings->SupportStatusInfoPdu) - earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_STATUSINFO_PDU; + if (settings->SupportAsymetricKeys) + earlyCapabilityFlags |= RNS_UD_CS_STRONG_ASYMMETRIC_KEYS; + + if (settings->SupportSkipChannelJoin) + earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_SKIP_CHANNELJOIN; return filterAndLogEarlyClientCapabilityFlags(earlyCapabilityFlags); } @@ -943,9 +958,35 @@ static BOOL updateEarlyClientCaps(rdpSettings* settings, UINT32 earlyCapabilityF { WINPR_ASSERT(settings); + if (settings->SupportErrorInfoPdu) + settings->SupportErrorInfoPdu = + (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_ERRINFO_PDU) ? TRUE : FALSE; + + /* RNS_UD_CS_WANT_32BPP_SESSION is already handled in gcc_read_client_core_data: + * + * it is evaluated in combination with highColorDepth and the server side + * settings to determine the session color depth to use. + */ + + if (settings->SupportStatusInfoPdu) + settings->SupportStatusInfoPdu = + (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_STATUSINFO_PDU) ? TRUE : FALSE; + + if (settings->SupportAsymetricKeys) + settings->SupportAsymetricKeys = + (earlyCapabilityFlags & RNS_UD_CS_STRONG_ASYMMETRIC_KEYS) ? TRUE : FALSE; + + if (settings->NetworkAutoDetect) + settings->NetworkAutoDetect = + (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_NETCHAR_AUTODETECT) ? TRUE : FALSE; + + if (settings->SupportSkipChannelJoin) + settings->SupportSkipChannelJoin = + (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_SKIP_CHANNELJOIN) ? TRUE : FALSE; + if (settings->SupportMonitorLayoutPdu) settings->SupportMonitorLayoutPdu = - earlyCapabilityFlags & RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU; + (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU) ? TRUE : FALSE; if (settings->SupportHeartbeatPdu) settings->SupportHeartbeatPdu = @@ -959,18 +1000,9 @@ static BOOL updateEarlyClientCaps(rdpSettings* settings, UINT32 earlyCapabilityF settings->SupportDynamicTimeZone = (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE) ? TRUE : FALSE; - if (settings->SupportStatusInfoPdu) - settings->SupportStatusInfoPdu = - (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_STATUSINFO_PDU) ? TRUE : FALSE; - - if (settings->SupportErrorInfoPdu) - settings->SupportErrorInfoPdu = - earlyCapabilityFlags & RNS_UD_CS_SUPPORT_ERRINFO_PDU ? TRUE : FALSE; - - if (!(earlyCapabilityFlags & RNS_UD_CS_VALID_CONNECTION_TYPE)) + if ((earlyCapabilityFlags & RNS_UD_CS_VALID_CONNECTION_TYPE) == 0) connectionType = 0; settings->ConnectionType = connectionType; - settings->EarlyCapabilityFlags = earlyCapabilityFlags; filterAndLogEarlyClientCapabilityFlags(earlyCapabilityFlags); return TRUE; @@ -981,11 +1013,26 @@ static BOOL updateEarlyServerCaps(rdpSettings* settings, UINT32 earlyCapabilityF { WINPR_ASSERT(settings); + settings->SupportEdgeActionV1 = + settings->SupportEdgeActionV1 && + (earlyCapabilityFlags & RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V1) + ? TRUE + : FALSE; settings->SupportDynamicTimeZone = settings->SupportDynamicTimeZone && (earlyCapabilityFlags & RNS_UD_SC_DYNAMIC_DST_SUPPORTED) ? TRUE : FALSE; - settings->EarlyCapabilityFlags = earlyCapabilityFlags; + settings->SupportEdgeActionV2 = + settings->SupportEdgeActionV2 && + (earlyCapabilityFlags & RNS_UD_SC_EDGE_ACTIONS_SUPPORTED_V2) + ? TRUE + : FALSE; + settings->SupportSkipChannelJoin = + settings->SupportSkipChannelJoin && + (earlyCapabilityFlags & RNS_UD_SC_SKIP_CHANNELJOIN_SUPPORTED) + ? TRUE + : FALSE; + filterAndLogEarlyServerCapabilityFlags(earlyCapabilityFlags); return TRUE; } @@ -1012,7 +1059,6 @@ BOOL gcc_read_client_core_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) UINT16 highColorDepth = 0; UINT16 supportedColorDepths = 0; UINT32 serverSelectedProtocol = 0; - UINT16 earlyCapabilityFlags = 0; rdpSettings* settings = mcs_get_settings(mcs); WINPR_ASSERT(s); @@ -1091,7 +1137,7 @@ BOOL gcc_read_client_core_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) if (blockLength < 2) break; - Stream_Read_UINT16(s, earlyCapabilityFlags); /* earlyCapabilityFlags (2 bytes) */ + Stream_Read_UINT16(s, settings->EarlyCapabilityFlags); /* earlyCapabilityFlags (2 bytes) */ blockLength -= 2; /* clientDigProductId (64 bytes): Contains a value that uniquely identifies the client */ @@ -1166,7 +1212,7 @@ BOOL gcc_read_client_core_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) if (highColorDepth > 0) { - if (earlyCapabilityFlags & RNS_UD_CS_WANT_32BPP_SESSION) + if (settings->EarlyCapabilityFlags & RNS_UD_CS_WANT_32BPP_SESSION) clientColorDepth = 32; else clientColorDepth = highColorDepth; @@ -1225,9 +1271,9 @@ BOOL gcc_read_client_core_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) freerdp_settings_set_uint32(settings, FreeRDP_ColorDepth, clientColorDepth); WLog_DBG(TAG, "Received EarlyCapabilityFlags=%s", - rdp_early_client_caps_string(earlyCapabilityFlags, buffer, sizeof(buffer))); + rdp_early_client_caps_string(settings->EarlyCapabilityFlags, buffer, sizeof(buffer))); - return updateEarlyClientCaps(settings, earlyCapabilityFlags, connectionType); + return updateEarlyClientCaps(settings, settings->EarlyCapabilityFlags, connectionType); } /** @@ -1337,7 +1383,6 @@ BOOL gcc_write_client_core_data(wStream* s, const rdpMcs* mcs) BOOL gcc_read_server_core_data(wStream* s, rdpMcs* mcs) { UINT32 serverVersion; - UINT32 EarlyCapabilityFlags = 0; rdpSettings* settings = mcs_get_settings(mcs); WINPR_ASSERT(s); @@ -1358,12 +1403,14 @@ BOOL gcc_read_server_core_data(wStream* s, rdpMcs* mcs) { char buffer[2048] = { 0 }; - Stream_Read_UINT32(s, EarlyCapabilityFlags); /* earlyCapabilityFlags */ - WLog_DBG(TAG, "Received EarlyCapabilityFlags=%s", - rdp_early_client_caps_string(EarlyCapabilityFlags, buffer, sizeof(buffer))); + Stream_Read_UINT32(s, settings->EarlyCapabilityFlags); /* earlyCapabilityFlags */ + WLog_DBG( + TAG, "Received EarlyCapabilityFlags=%s", + rdp_early_client_caps_string(settings->EarlyCapabilityFlags, buffer, sizeof(buffer))); } - return updateEarlyServerCaps(settings, EarlyCapabilityFlags, settings->ConnectionType); + return updateEarlyServerCaps(settings, settings->EarlyCapabilityFlags, + settings->ConnectionType); } /* TODO: This function modifies rdpMcs @@ -1379,9 +1426,7 @@ BOOL gcc_write_server_core_data(wStream* s, rdpMcs* mcs) if (!gcc_write_user_data_header(s, SC_CORE, 16)) return FALSE; - updateEarlyServerCaps(settings, settings->EarlyCapabilityFlags, settings->ConnectionType); const UINT32 EarlyCapabilityFlags = earlyServerCapsFromSettings(settings); - Stream_Write_UINT32(s, settings->RdpVersion); /* version (4 bytes) */ Stream_Write_UINT32(s, settings->RequestedProtocols); /* clientRequestedProtocols (4 bytes) */ Stream_Write_UINT32(s, EarlyCapabilityFlags); /* earlyCapabilityFlags (4 bytes) */ diff --git a/libfreerdp/core/settings.c b/libfreerdp/core/settings.c index 6a2a56927..4656aaa64 100644 --- a/libfreerdp/core/settings.c +++ b/libfreerdp/core/settings.c @@ -741,18 +741,20 @@ rdpSettings* freerdp_settings_new(DWORD flags) if (!freerdp_settings_set_default_order_support(settings)) goto out_fail; - { - BOOL enable = freerdp_settings_get_bool(settings, FreeRDP_ServerMode); + const BOOL enable = freerdp_settings_get_bool(settings, FreeRDP_ServerMode); - if (!freerdp_settings_set_bool(settings, FreeRDP_SupportDynamicTimeZone, enable)) - goto out_fail; - if (!freerdp_settings_set_bool(settings, FreeRDP_SupportGraphicsPipeline, enable)) - goto out_fail; - if (!freerdp_settings_set_bool(settings, FreeRDP_SupportStatusInfoPdu, enable)) - goto out_fail; - if (!freerdp_settings_set_bool(settings, FreeRDP_SupportErrorInfoPdu, enable)) - goto out_fail; + { + const size_t keys[] = { FreeRDP_SupportDynamicTimeZone, FreeRDP_SupportGraphicsPipeline, + FreeRDP_SupportStatusInfoPdu, FreeRDP_SupportErrorInfoPdu, + FreeRDP_SupportAsymetricKeys }; + + for (size_t x = 0; x < ARRAYSIZE(keys); x++) + { + if (!freerdp_settings_set_bool(settings, keys[x], enable)) + goto out_fail; + } } + return settings; out_fail: freerdp_settings_free(settings); diff --git a/libfreerdp/core/test/settings_property_lists.h b/libfreerdp/core/test/settings_property_lists.h index 8729e3c89..056a1b4fe 100644 --- a/libfreerdp/core/test/settings_property_lists.h +++ b/libfreerdp/core/test/settings_property_lists.h @@ -151,6 +151,8 @@ static const size_t bool_list_indices[] = { FreeRDP_SupportDynamicChannels, FreeRDP_SupportDynamicTimeZone, FreeRDP_SupportEchoChannel, + FreeRDP_SupportEdgeActionV1, + FreeRDP_SupportEdgeActionV2, FreeRDP_SupportErrorInfoPdu, FreeRDP_SupportGeometryTracking, FreeRDP_SupportGraphicsPipeline, @@ -158,6 +160,7 @@ static const size_t bool_list_indices[] = { FreeRDP_SupportMonitorLayoutPdu, FreeRDP_SupportMultitransport, FreeRDP_SupportSSHAgentChannel, + FreeRDP_SupportSkipChannelJoin, FreeRDP_SupportStatusInfoPdu, FreeRDP_SupportVideoOptimized, FreeRDP_SuppressOutput,