From d3e92109851402d58fcecea656542e781bc51d93 Mon Sep 17 00:00:00 2001 From: akallabeth Date: Thu, 1 Dec 2022 14:40:27 +0100 Subject: [PATCH] [core] added freerdp_is_active_state Since client and server use different states to indicate the connection is activated, add this convenience function to determine that --- include/freerdp/freerdp.h | 24 ++++++++++++++++ libfreerdp/core/connection.c | 55 ++++++++++++++++++++++++++++++++++++ libfreerdp/core/connection.h | 1 + libfreerdp/core/freerdp.c | 6 ++++ 4 files changed, 86 insertions(+) diff --git a/include/freerdp/freerdp.h b/include/freerdp/freerdp.h index 030713871..8af99d324 100644 --- a/include/freerdp/freerdp.h +++ b/include/freerdp/freerdp.h @@ -639,9 +639,33 @@ owned by rdpRdp */ FREERDP_API const char* freerdp_nego_get_routing_token(rdpContext* context, DWORD* length); + /** \brief returns the current \b CONNECTION_STATE of the context. + * + * \param context A pointer to the context to query state + * + * \return A \b CONNECTION_STATE the context is currently in + */ FREERDP_API CONNECTION_STATE freerdp_get_state(const rdpContext* context); + + /** \brief returns a string representation of a \b CONNECTION_STATE + * + * \param state the \b CONNECTION_STATE to stringify + * + * \return The string representation of the \b CONNECTION_STATE + */ FREERDP_API const char* freerdp_state_string(CONNECTION_STATE state); + /** \brief Queries if the current \b CONNECTION_STATE of the context is an active connection. + * + * A connection is active, if the connection sequence has been passed, no disconnection requests + * have been received and no network or other errors have forced a disconnect. + * + * \param context A pointer to the context to query state + * + * \return \b TRUE if the connection state indicates an active connection, \b FALSE otherwise + */ + FREERDP_API BOOL freerdp_is_active_state(const rdpContext* context); + FREERDP_API BOOL freerdp_channels_from_mcs(rdpSettings* settings, const rdpContext* context); FREERDP_API BOOL freerdp_is_valid_mcs_create_request(const BYTE* data, size_t size); diff --git a/libfreerdp/core/connection.c b/libfreerdp/core/connection.c index 4797dbb91..35cabad25 100644 --- a/libfreerdp/core/connection.c +++ b/libfreerdp/core/connection.c @@ -1601,6 +1601,61 @@ BOOL rdp_server_reactivate(rdpRdp* rdp) return state_run_success(rc); } +static BOOL rdp_is_active_peer_state(CONNECTION_STATE state) +{ + /* [MS-RDPBCGR] 1.3.1.1 Connection Sequence states: + * 'upon receipt of the Font List PDU the server can start sending graphics + * output to the client' + */ + switch (state) + { + case CONNECTION_STATE_FINALIZATION_CLIENT_SYNC: + case CONNECTION_STATE_FINALIZATION_CLIENT_COOPERATE: + case CONNECTION_STATE_FINALIZATION_CLIENT_GRANTED_CONTROL: + case CONNECTION_STATE_FINALIZATION_CLIENT_FONT_MAP: + case CONNECTION_STATE_ACTIVE: + return TRUE; + default: + return FALSE; + } +} + +static BOOL rdp_is_active_client_state(CONNECTION_STATE state) +{ + /* [MS-RDPBCGR] 1.3.1.1 Connection Sequence states: + * 'Once the client has sent the Confirm Active PDU, it can start sending + * mouse and keyboard input to the server' + */ + switch (state) + { + case CONNECTION_STATE_FINALIZATION_SYNC: + case CONNECTION_STATE_FINALIZATION_COOPERATE: + case CONNECTION_STATE_FINALIZATION_REQUEST_CONTROL: + case CONNECTION_STATE_FINALIZATION_PERSISTENT_KEY_LIST: + case CONNECTION_STATE_FINALIZATION_FONT_LIST: + case CONNECTION_STATE_FINALIZATION_CLIENT_SYNC: + case CONNECTION_STATE_FINALIZATION_CLIENT_COOPERATE: + case CONNECTION_STATE_FINALIZATION_CLIENT_GRANTED_CONTROL: + case CONNECTION_STATE_FINALIZATION_CLIENT_FONT_MAP: + case CONNECTION_STATE_ACTIVE: + return TRUE; + default: + return FALSE; + } +} + +BOOL rdp_is_active_state(const rdpRdp* rdp) +{ + WINPR_ASSERT(rdp); + WINPR_ASSERT(rdp->context); + + const CONNECTION_STATE state = rdp_get_state(rdp); + if (freerdp_settings_get_bool(rdp->context->settings, FreeRDP_ServerMode)) + return rdp_is_active_peer_state(state); + else + return rdp_is_active_client_state(state); +} + BOOL rdp_server_transition_to_state(rdpRdp* rdp, CONNECTION_STATE state) { BOOL status = FALSE; diff --git a/libfreerdp/core/connection.h b/libfreerdp/core/connection.h index e3afca794..cec0b5cb3 100644 --- a/libfreerdp/core/connection.h +++ b/libfreerdp/core/connection.h @@ -52,6 +52,7 @@ FREERDP_LOCAL BOOL rdp_client_transition_to_state(rdpRdp* rdp, CONNECTION_STATE FREERDP_LOCAL CONNECTION_STATE rdp_get_state(const rdpRdp* rdp); FREERDP_LOCAL const char* rdp_state_string(CONNECTION_STATE state); +FREERDP_LOCAL BOOL rdp_is_active_state(const rdpRdp* rdp); FREERDP_LOCAL BOOL rdp_server_accept_nego(rdpRdp* rdp, wStream* s); FREERDP_LOCAL BOOL rdp_server_accept_mcs_connect_initial(rdpRdp* rdp, wStream* s); diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c index 6c9167dec..b6470fa23 100644 --- a/libfreerdp/core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -1216,6 +1216,12 @@ const char* freerdp_state_string(CONNECTION_STATE state) return rdp_state_string(state); } +BOOL freerdp_is_active_state(const rdpContext* context) +{ + WINPR_ASSERT(context); + return rdp_is_active_state(context->rdp); +} + BOOL freerdp_channels_from_mcs(rdpSettings* settings, const rdpContext* context) { WINPR_ASSERT(context);