Unified setting of finalize_sc_pdus

This commit is contained in:
akallabeth 2022-06-23 09:59:24 +02:00 committed by akallabeth
parent fbe1075a30
commit 43b1f51984
5 changed files with 158 additions and 42 deletions

View File

@ -26,16 +26,6 @@
#define TAG FREERDP_TAG("core.activation")
/*
static const char* const CTRLACTION_STRINGS[] =
{
"",
"CTRLACTION_REQUEST_CONTROL",
"CTRLACTION_GRANTED_CONTROL",
"CTRLACTION_DETACH",
"CTRLACTION_COOPERATE"
};
*/
static BOOL rdp_recv_server_synchronize_pdu(rdpRdp* rdp, wStream* s);
static BOOL rdp_recv_client_font_list_pdu(wStream* s);
static BOOL rdp_recv_client_persistent_key_list_pdu(wStream* s);
@ -72,8 +62,7 @@ BOOL rdp_recv_server_synchronize_pdu(rdpRdp* rdp, wStream* s)
WINPR_ASSERT(rdp);
WINPR_ASSERT(s);
rdp->finalize_sc_pdus |= FINALIZE_SC_SYNCHRONIZE_PDU;
return TRUE;
return rdp_finalize_set_flag(rdp, FINALIZE_SC_SYNCHRONIZE_PDU);
}
BOOL rdp_send_server_synchronize_pdu(rdpRdp* rdp)
@ -100,7 +89,8 @@ BOOL rdp_recv_client_synchronize_pdu(rdpRdp* rdp, wStream* s)
WINPR_ASSERT(rdp);
WINPR_ASSERT(s);
rdp->finalize_sc_pdus |= FINALIZE_SC_SYNCHRONIZE_PDU;
if (!rdp_finalize_set_flag(rdp, FINALIZE_SC_SYNCHRONIZE_PDU))
return FALSE;
if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
return FALSE;
@ -173,16 +163,19 @@ BOOL rdp_recv_server_control_pdu(rdpRdp* rdp, wStream* s)
switch (action)
{
case CTRLACTION_COOPERATE:
rdp->finalize_sc_pdus |= FINALIZE_SC_CONTROL_COOPERATE_PDU;
break;
return rdp_finalize_set_flag(rdp, FINALIZE_SC_CONTROL_COOPERATE_PDU);
case CTRLACTION_GRANTED_CONTROL:
rdp->finalize_sc_pdus |= FINALIZE_SC_CONTROL_GRANTED_PDU;
rdp->resendFocus = TRUE;
break;
return rdp_finalize_set_flag(rdp, FINALIZE_SC_CONTROL_GRANTED_PDU);
default:
{
char buffer[128] = { 0 };
WLog_WARN(TAG, "Unexpected control PDU %s",
rdp_ctrlaction_string(action, buffer, sizeof(buffer)));
return TRUE;
}
}
return TRUE;
}
BOOL rdp_send_server_control_cooperate_pdu(rdpRdp* rdp)
@ -526,8 +519,7 @@ BOOL rdp_recv_server_font_map_pdu(rdpRdp* rdp, wStream* s)
WINPR_ASSERT(s);
WLog_WARN(TAG, "Invalid PDU received: FONT_MAP only allowed client -> server");
rdp->finalize_sc_pdus |= FINALIZE_SC_FONT_MAP_PDU;
return FALSE;
return rdp_finalize_set_flag(rdp, FINALIZE_SC_FONT_MAP_PDU);
}
BOOL rdp_recv_client_font_map_pdu(rdpRdp* rdp, wStream* s)
@ -535,7 +527,8 @@ BOOL rdp_recv_client_font_map_pdu(rdpRdp* rdp, wStream* s)
WINPR_ASSERT(rdp);
WINPR_ASSERT(s);
rdp->finalize_sc_pdus |= FINALIZE_SC_FONT_MAP_PDU;
if (!rdp_finalize_set_flag(rdp, FINALIZE_SC_FONT_MAP_PDU))
return FALSE;
if (Stream_GetRemainingLength(s) >= 8)
{
@ -576,9 +569,10 @@ BOOL rdp_recv_deactivate_all(rdpRdp* rdp, wStream* s)
WINPR_ASSERT(s);
if (rdp_get_state(rdp) == CONNECTION_STATE_ACTIVE)
rdp->deactivation_reactivation = TRUE;
else
rdp->deactivation_reactivation = FALSE;
{
if (!rdp_finalize_set_flag(rdp, FINALIZE_DEACTIVATE_REACTIVATE))
return FALSE;
}
/*
* Windows XP can send short DEACTIVATE_ALL PDU that doesn't contain
@ -729,3 +723,29 @@ BOOL rdp_server_accept_client_persistent_key_list_pdu(rdpRdp* rdp, wStream* s)
// TODO: Actually do something with this
return TRUE;
}
const char* rdp_ctrlaction_string(UINT16 action, char* buffer, size_t size)
{
const char* actstr;
switch (action)
{
case CTRLACTION_COOPERATE:
actstr = "CTRLACTION_COOPERATE";
break;
case CTRLACTION_DETACH:
actstr = "CTRLACTION_DETACH";
break;
case CTRLACTION_GRANTED_CONTROL:
actstr = "CTRLACTION_GRANTED_CONTROL";
break;
case CTRLACTION_REQUEST_CONTROL:
actstr = "CTRLACTION_REQUEST_CONTROL";
break;
default:
actstr = "CTRLACTION_UNKNOWN";
break;
}
_snprintf(buffer, size, "%s [0x%04" PRIx16 "]", actstr, action);
return buffer;
}

View File

@ -28,10 +28,13 @@
#define SYNCMSGTYPE_SYNC 0x0001
#define CTRLACTION_REQUEST_CONTROL 0x0001
#define CTRLACTION_GRANTED_CONTROL 0x0002
#define CTRLACTION_DETACH 0x0003
#define CTRLACTION_COOPERATE 0x0004
typedef enum
{
CTRLACTION_REQUEST_CONTROL = 0x0001,
CTRLACTION_GRANTED_CONTROL = 0x0002,
CTRLACTION_DETACH = 0x0003,
CTRLACTION_COOPERATE = 0x0004
} CTRLACTION;
struct _RDP_BITMAP_PERSISTENT_INFO
{
@ -56,6 +59,7 @@ typedef struct _RDP_BITMAP_PERSISTENT_INFO RDP_BITMAP_PERSISTENT_INFO;
#define FONTLIST_FIRST 0x0001
#define FONTLIST_LAST 0x0002
FREERDP_LOCAL const char* rdp_ctrlaction_string(UINT16 action, char* buffer, size_t size);
FREERDP_LOCAL BOOL rdp_recv_deactivate_all(rdpRdp* rdp, wStream* s);
FREERDP_LOCAL BOOL rdp_send_deactivate_all(rdpRdp* rdp);

View File

@ -1143,7 +1143,8 @@ int rdp_client_connect_finalize(rdpRdp* rdp)
* host cache and a deactivation reactivation sequence is *not* in progress.
*/
if (!rdp->deactivation_reactivation && rdp->settings->BitmapCachePersistEnabled)
if (!rdp_finalize_is_flag_set(rdp, FINALIZE_DEACTIVATE_REACTIVATE) &&
rdp->settings->BitmapCachePersistEnabled)
{
if (!rdp_send_client_persistent_key_list_pdu(rdp))
return -1;
@ -1166,7 +1167,7 @@ int rdp_client_transition_to_state(rdpRdp* rdp, CONNECTION_STATE state)
{
case CONNECTION_STATE_FINALIZATION:
update_reset_state(rdp->update);
rdp->finalize_sc_pdus = 0;
rdp_finalize_reset_flags(rdp, FALSE);
break;
case CONNECTION_STATE_ACTIVE:
@ -1174,7 +1175,8 @@ int rdp_client_transition_to_state(rdpRdp* rdp, CONNECTION_STATE state)
ActivatedEventArgs activatedEvent;
rdpContext* context = rdp->context;
EventArgsInit(&activatedEvent, "libfreerdp");
activatedEvent.firstActivation = !rdp->deactivation_reactivation;
activatedEvent.firstActivation =
!rdp_finalize_is_flag_set(rdp, FINALIZE_DEACTIVATE_REACTIVATE);
PubSub_OnActivated(context->pubSub, context, &activatedEvent);
}
@ -1458,7 +1460,8 @@ BOOL rdp_server_transition_to_state(rdpRdp* rdp, CONNECTION_STATE state)
break;
case CONNECTION_STATE_FINALIZATION:
rdp->finalize_sc_pdus = 0;
if (!rdp_finalize_reset_flags(rdp, FALSE))
goto fail;
break;
case CONNECTION_STATE_ACTIVE:

View File

@ -21,6 +21,7 @@
#include <freerdp/config.h>
#include <winpr/crt.h>
#include <winpr/string.h>
#include <winpr/synch.h>
#include <winpr/assert.h>
@ -1745,7 +1746,7 @@ int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra)
case CONNECTION_STATE_FINALIZATION:
status = rdp_recv_pdu(rdp, s);
if ((status >= 0) && (rdp->finalize_sc_pdus == FINALIZE_SC_COMPLETE))
if ((status >= 0) && rdp_finalize_is_flag_set(rdp, FINALIZE_SC_COMPLETE))
{
rdp_client_transition_to_state(rdp, CONNECTION_STATE_ACTIVE);
return 2;
@ -2070,8 +2071,7 @@ BOOL rdp_reset(rdpRdp* rdp)
goto fail;
rdp->errorInfo = 0;
rdp->deactivation_reactivation = FALSE;
rdp->finalize_sc_pdus = 0;
rdp_finalize_reset_flags(rdp, TRUE);
rc = TRUE;
@ -2144,3 +2144,70 @@ void* rdp_get_io_callback_context(rdpRdp* rdp)
WINPR_ASSERT(rdp);
return rdp->ioContext;
}
const char* rdp_finalize_flags_to_str(UINT32 flags, char* buffer, size_t size)
{
char number[32] = { 0 };
const UINT32 mask = ~(FINALIZE_SC_SYNCHRONIZE_PDU | FINALIZE_SC_CONTROL_COOPERATE_PDU |
FINALIZE_SC_CONTROL_GRANTED_PDU | FINALIZE_SC_FONT_MAP_PDU |
FINALIZE_CS_SYNCHRONIZE_PDU | FINALIZE_CS_CONTROL_COOPERATE_PDU |
FINALIZE_CS_CONTROL_REQUEST_PDU | FINALIZE_CS_PERSISTENT_KEY_LIST_PDU |
FINALIZE_CS_FONT_LIST_PDU | FINALIZE_DEACTIVATE_REACTIVATE);
if (flags & FINALIZE_SC_SYNCHRONIZE_PDU)
winpr_str_append("FINALIZE_SC_SYNCHRONIZE_PDU", buffer, size, "|");
if (flags & FINALIZE_SC_CONTROL_COOPERATE_PDU)
winpr_str_append("FINALIZE_SC_CONTROL_COOPERATE_PDU", buffer, size, "|");
if (flags & FINALIZE_SC_CONTROL_GRANTED_PDU)
winpr_str_append("FINALIZE_SC_CONTROL_GRANTED_PDU", buffer, size, "|");
if (flags & FINALIZE_SC_FONT_MAP_PDU)
winpr_str_append("FINALIZE_SC_FONT_MAP_PDU", buffer, size, "|");
if (flags & FINALIZE_CS_SYNCHRONIZE_PDU)
winpr_str_append("FINALIZE_CS_SYNCHRONIZE_PDU", buffer, size, "|");
if (flags & FINALIZE_CS_CONTROL_COOPERATE_PDU)
winpr_str_append("FINALIZE_CS_CONTROL_COOPERATE_PDU", buffer, size, "|");
if (flags & FINALIZE_CS_CONTROL_REQUEST_PDU)
winpr_str_append("FINALIZE_CS_CONTROL_REQUEST_PDU", buffer, size, "|");
if (flags & FINALIZE_CS_PERSISTENT_KEY_LIST_PDU)
winpr_str_append("FINALIZE_CS_PERSISTENT_KEY_LIST_PDU", buffer, size, "|");
if (flags & FINALIZE_CS_FONT_LIST_PDU)
winpr_str_append("FINALIZE_CS_FONT_LIST_PDU", buffer, size, "|");
if (flags & FINALIZE_DEACTIVATE_REACTIVATE)
winpr_str_append("FINALIZE_DEACTIVATE_REACTIVATE", buffer, size, "|");
if (flags & mask)
winpr_str_append("UNKNOWN_FLAG", buffer, size, "|");
if (flags == 0)
winpr_str_append("NO_FLAG_SET", buffer, size, "|");
_snprintf(number, sizeof(number), " [0x%04" PRIx16 "]", flags);
winpr_str_append(number, buffer, size, "|");
return buffer;
}
BOOL rdp_finalize_reset_flags(rdpRdp* rdp, BOOL clearAll)
{
WINPR_ASSERT(rdp);
WLog_DBG(TAG, "[%s] reset finalize_sc_pdus", rdp_get_state_string(rdp));
if (clearAll)
rdp->finalize_sc_pdus = 0;
else
rdp->finalize_sc_pdus &= FINALIZE_DEACTIVATE_REACTIVATE;
return TRUE;
}
BOOL rdp_finalize_set_flag(rdpRdp* rdp, UINT32 flag)
{
char buffer[1024] = { 0 };
WINPR_ASSERT(rdp);
WLog_DBG(TAG, "[%s] received flag %s", rdp_get_state_string(rdp),
rdp_finalize_flags_to_str(flag, buffer, sizeof(buffer)));
rdp->finalize_sc_pdus |= flag;
return TRUE;
}
BOOL rdp_finalize_is_flag_set(rdpRdp* rdp, UINT32 flag)
{
WINPR_ASSERT(rdp);
return (rdp->finalize_sc_pdus & flag) == flag;
}

View File

@ -89,11 +89,29 @@
#define PDU_TYPE_FLOW_RESPONSE 0x42
#define PDU_TYPE_FLOW_STOP 0x43
#define FINALIZE_SC_SYNCHRONIZE_PDU 0x01
#define FINALIZE_SC_CONTROL_COOPERATE_PDU 0x02
#define FINALIZE_SC_CONTROL_GRANTED_PDU 0x04
#define FINALIZE_SC_FONT_MAP_PDU 0x08
#define FINALIZE_SC_COMPLETE 0x0F
typedef enum
{
FINALIZE_SC_SYNCHRONIZE_PDU = 0x01,
FINALIZE_SC_CONTROL_COOPERATE_PDU = 0x02,
FINALIZE_SC_CONTROL_GRANTED_PDU = 0x04,
FINALIZE_SC_FONT_MAP_PDU = 0x08,
FINALIZE_CS_SYNCHRONIZE_PDU = 0x10,
FINALIZE_CS_CONTROL_COOPERATE_PDU = 0x20,
FINALIZE_CS_CONTROL_REQUEST_PDU = 0x40,
FINALIZE_CS_PERSISTENT_KEY_LIST_PDU = 0x80,
FINALIZE_CS_FONT_LIST_PDU = 0x100,
FINALIZE_DEACTIVATE_REACTIVATE = 0x200
} rdpFinalizePduType;
#define FINALIZE_SC_COMPLETE \
(FINALIZE_SC_SYNCHRONIZE_PDU | FINALIZE_SC_CONTROL_COOPERATE_PDU | \
FINALIZE_SC_CONTROL_GRANTED_PDU | FINALIZE_SC_FONT_MAP_PDU)
#define FINALIZE_CS_COMPLETE \
(FINALIZE_CS_SYNCHRONIZE_PDU | FINALIZE_CS_CONTROL_COOPERATE_PDU | \
FINALIZE_CS_CONTROL_REQUEST_PDU | FINALIZE_CS_PERSISTENT_KEY_LIST_PDU | \
FINALIZE_CS_FONT_LIST_PDU)
/* Data PDU Types */
typedef enum
@ -173,7 +191,6 @@ struct rdp_rdp
UINT32 errorInfo;
UINT32 finalize_sc_pdus;
BOOL resendFocus;
BOOL deactivation_reactivation;
BOOL AwaitCapabilities;
UINT64 inBytes;
UINT64 inPackets;
@ -248,6 +265,11 @@ FREERDP_LOCAL void* rdp_get_io_callback_context(rdpRdp* rdp);
const char* data_pdu_type_to_string(UINT8 type);
const char* pdu_type_to_str(UINT16 pduType);
BOOL rdp_finalize_reset_flags(rdpRdp* rdp, BOOL clearAll);
BOOL rdp_finalize_set_flag(rdpRdp* rdp, UINT32 flag);
BOOL rdp_finalize_is_flag_set(rdpRdp* rdp, UINT32 flag);
const char* rdp_finalize_flags_to_str(UINT32 flags, char* buffer, size_t size);
BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, UINT16* pLength, UINT16 securityFlags);
BOOL rdp_set_error_info(rdpRdp* rdp, UINT32 errorInfo);