Blame libfreerdp/core/activation.c

Packit 1fb8d4
/**
Packit 1fb8d4
 * FreeRDP: A Remote Desktop Protocol Implementation
Packit 1fb8d4
 * Activation Sequence
Packit 1fb8d4
 *
Packit 1fb8d4
 * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
Packit 1fb8d4
 *
Packit 1fb8d4
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit 1fb8d4
 * you may not use this file except in compliance with the License.
Packit 1fb8d4
 * You may obtain a copy of the License at
Packit 1fb8d4
 *
Packit 1fb8d4
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit 1fb8d4
 *
Packit 1fb8d4
 * Unless required by applicable law or agreed to in writing, software
Packit 1fb8d4
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 1fb8d4
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 1fb8d4
 * See the License for the specific language governing permissions and
Packit 1fb8d4
 * limitations under the License.
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#ifdef HAVE_CONFIG_H
Packit 1fb8d4
#include "config.h"
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#include "activation.h"
Packit Service 5a9772
#include "display.h"
Packit Service 5a9772
Packit Service 5a9772
#define TAG FREERDP_TAG("core.activation")
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
static const char* const CTRLACTION_STRINGS[] =
Packit 1fb8d4
{
Packit Service 5a9772
        "",
Packit Service 5a9772
        "CTRLACTION_REQUEST_CONTROL",
Packit Service 5a9772
        "CTRLACTION_GRANTED_CONTROL",
Packit Service 5a9772
        "CTRLACTION_DETACH",
Packit Service 5a9772
        "CTRLACTION_COOPERATE"
Packit 1fb8d4
};
Packit 1fb8d4
*/
Packit Service 5a9772
static BOOL rdp_recv_server_synchronize_pdu(rdpRdp* rdp, wStream* s);
Packit Service 5a9772
static BOOL rdp_recv_client_font_list_pdu(wStream* s);
Packit Service 5a9772
static BOOL rdp_recv_server_font_map_pdu(rdpRdp* rdp, wStream* s);
Packit Service 5a9772
static BOOL rdp_recv_client_font_map_pdu(rdpRdp* rdp, wStream* s);
Packit Service 5a9772
static BOOL rdp_send_server_font_map_pdu(rdpRdp* rdp);
Packit 1fb8d4
Packit Service 5a9772
static void rdp_write_synchronize_pdu(wStream* s, rdpSettings* settings)
Packit 1fb8d4
{
Packit Service 5a9772
	Stream_Write_UINT16(s, SYNCMSGTYPE_SYNC);    /* messageType (2 bytes) */
Packit 1fb8d4
	Stream_Write_UINT16(s, settings->PduSource); /* targetUser (2 bytes) */
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL rdp_recv_synchronize_pdu(rdpRdp* rdp, wStream* s)
Packit 1fb8d4
{
Packit 1fb8d4
	if (rdp->settings->ServerMode)
Packit 1fb8d4
		return rdp_recv_server_synchronize_pdu(rdp, s);
Packit 1fb8d4
	else
Packit 1fb8d4
		return rdp_recv_client_synchronize_pdu(rdp, s);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL rdp_recv_server_synchronize_pdu(rdpRdp* rdp, wStream* s)
Packit 1fb8d4
{
Packit 1fb8d4
	rdp->finalize_sc_pdus |= FINALIZE_SC_SYNCHRONIZE_PDU;
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL rdp_send_server_synchronize_pdu(rdpRdp* rdp)
Packit 1fb8d4
{
Packit 1fb8d4
	wStream* s = rdp_data_pdu_init(rdp);
Packit 1fb8d4
	rdp_write_synchronize_pdu(s, rdp->settings);
Packit 1fb8d4
	return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SYNCHRONIZE, rdp->mcs->userId);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL rdp_recv_client_synchronize_pdu(rdpRdp* rdp, wStream* s)
Packit 1fb8d4
{
Packit 1fb8d4
	UINT16 messageType;
Packit 1fb8d4
	rdp->finalize_sc_pdus |= FINALIZE_SC_SYNCHRONIZE_PDU;
Packit 1fb8d4
Packit 1fb8d4
	if (Stream_GetRemainingLength(s) < 4)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	Stream_Read_UINT16(s, messageType); /* messageType (2 bytes) */
Packit 1fb8d4
Packit 1fb8d4
	if (messageType != SYNCMSGTYPE_SYNC)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	/* targetUser (2 bytes) */
Packit 1fb8d4
	Stream_Seek_UINT16(s);
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL rdp_send_client_synchronize_pdu(rdpRdp* rdp)
Packit 1fb8d4
{
Packit 1fb8d4
	wStream* s = rdp_data_pdu_init(rdp);
Packit 1fb8d4
	rdp_write_synchronize_pdu(s, rdp->settings);
Packit 1fb8d4
	return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SYNCHRONIZE, rdp->mcs->userId);
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
static BOOL rdp_recv_control_pdu(wStream* s, UINT16* action)
Packit 1fb8d4
{
Packit 1fb8d4
	if (Stream_GetRemainingLength(s) < 8)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	Stream_Read_UINT16(s, *action); /* action (2 bytes) */
Packit Service 5a9772
	Stream_Seek_UINT16(s);          /* grantId (2 bytes) */
Packit Service 5a9772
	Stream_Seek_UINT32(s);          /* controlId (4 bytes) */
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
static void rdp_write_client_control_pdu(wStream* s, UINT16 action)
Packit 1fb8d4
{
Packit 1fb8d4
	Stream_Write_UINT16(s, action); /* action (2 bytes) */
Packit Service 5a9772
	Stream_Write_UINT16(s, 0);      /* grantId (2 bytes) */
Packit Service 5a9772
	Stream_Write_UINT32(s, 0);      /* controlId (4 bytes) */
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL rdp_recv_server_control_pdu(rdpRdp* rdp, wStream* s)
Packit 1fb8d4
{
Packit 1fb8d4
	UINT16 action;
Packit 1fb8d4
Packit 1fb8d4
	if (rdp_recv_control_pdu(s, &action) == FALSE)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	switch (action)
Packit 1fb8d4
	{
Packit 1fb8d4
		case CTRLACTION_COOPERATE:
Packit 1fb8d4
			rdp->finalize_sc_pdus |= FINALIZE_SC_CONTROL_COOPERATE_PDU;
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case CTRLACTION_GRANTED_CONTROL:
Packit 1fb8d4
			rdp->finalize_sc_pdus |= FINALIZE_SC_CONTROL_GRANTED_PDU;
Packit 1fb8d4
			rdp->resendFocus = TRUE;
Packit 1fb8d4
			break;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL rdp_send_server_control_cooperate_pdu(rdpRdp* rdp)
Packit 1fb8d4
{
Packit 1fb8d4
	wStream* s = rdp_data_pdu_init(rdp);
Packit 1fb8d4
	Stream_Write_UINT16(s, CTRLACTION_COOPERATE); /* action (2 bytes) */
Packit Service 5a9772
	Stream_Write_UINT16(s, 0);                    /* grantId (2 bytes) */
Packit Service 5a9772
	Stream_Write_UINT32(s, 0);                    /* controlId (4 bytes) */
Packit 1fb8d4
	return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_CONTROL, rdp->mcs->userId);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL rdp_send_server_control_granted_pdu(rdpRdp* rdp)
Packit 1fb8d4
{
Packit 1fb8d4
	wStream* s = rdp_data_pdu_init(rdp);
Packit 1fb8d4
	Stream_Write_UINT16(s, CTRLACTION_GRANTED_CONTROL); /* action (2 bytes) */
Packit Service 5a9772
	Stream_Write_UINT16(s, rdp->mcs->userId);           /* grantId (2 bytes) */
Packit Service 5a9772
	Stream_Write_UINT32(s, 0x03EA);                     /* controlId (4 bytes) */
Packit 1fb8d4
	return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_CONTROL, rdp->mcs->userId);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL rdp_send_client_control_pdu(rdpRdp* rdp, UINT16 action)
Packit 1fb8d4
{
Packit 1fb8d4
	wStream* s = rdp_data_pdu_init(rdp);
Packit 1fb8d4
	rdp_write_client_control_pdu(s, action);
Packit 1fb8d4
	return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_CONTROL, rdp->mcs->userId);
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
static void rdp_write_persistent_list_entry(wStream* s, UINT32 key1, UINT32 key2)
Packit 1fb8d4
{
Packit 1fb8d4
	Stream_Write_UINT32(s, key1); /* key1 (4 bytes) */
Packit 1fb8d4
	Stream_Write_UINT32(s, key2); /* key2 (4 bytes) */
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
static void rdp_write_client_persistent_key_list_pdu(wStream* s, rdpSettings* settings)
Packit 1fb8d4
{
Packit Service 5a9772
	Stream_Write_UINT16(s, 0);                                   /* numEntriesCache0 (2 bytes) */
Packit Service 5a9772
	Stream_Write_UINT16(s, 0);                                   /* numEntriesCache1 (2 bytes) */
Packit Service 5a9772
	Stream_Write_UINT16(s, 0);                                   /* numEntriesCache2 (2 bytes) */
Packit Service 5a9772
	Stream_Write_UINT16(s, 0);                                   /* numEntriesCache3 (2 bytes) */
Packit Service 5a9772
	Stream_Write_UINT16(s, 0);                                   /* numEntriesCache4 (2 bytes) */
Packit Service 5a9772
	Stream_Write_UINT16(s, 0);                                   /* totalEntriesCache0 (2 bytes) */
Packit Service 5a9772
	Stream_Write_UINT16(s, 0);                                   /* totalEntriesCache1 (2 bytes) */
Packit Service 5a9772
	Stream_Write_UINT16(s, 0);                                   /* totalEntriesCache2 (2 bytes) */
Packit Service 5a9772
	Stream_Write_UINT16(s, 0);                                   /* totalEntriesCache3 (2 bytes) */
Packit Service 5a9772
	Stream_Write_UINT16(s, 0);                                   /* totalEntriesCache4 (2 bytes) */
Packit 1fb8d4
	Stream_Write_UINT8(s, PERSIST_FIRST_PDU | PERSIST_LAST_PDU); /* bBitMask (1 byte) */
Packit Service 5a9772
	Stream_Write_UINT8(s, 0);                                    /* pad1 (1 byte) */
Packit Service 5a9772
	Stream_Write_UINT16(s, 0);                                   /* pad3 (2 bytes) */
Packit Service 5a9772
	                                                             /* entries */
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL rdp_send_client_persistent_key_list_pdu(rdpRdp* rdp)
Packit 1fb8d4
{
Packit 1fb8d4
	wStream* s;
Packit 1fb8d4
	s = rdp_data_pdu_init(rdp);
Packit 1fb8d4
	rdp_write_client_persistent_key_list_pdu(s, rdp->settings);
Packit 1fb8d4
	return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST, rdp->mcs->userId);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL rdp_recv_client_font_list_pdu(wStream* s)
Packit 1fb8d4
{
Packit 1fb8d4
	if (Stream_GetRemainingLength(s) < 8)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit Service 5a9772
	/* 2.2.1.18.1 Font List PDU Data (TS_FONT_LIST_PDU) */
Packit Service 5a9772
	Stream_Seek(s, 8);
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
static void rdp_write_client_font_list_pdu(wStream* s, UINT16 flags)
Packit 1fb8d4
{
Packit Service 5a9772
	Stream_Write_UINT16(s, 0);     /* numberFonts (2 bytes) */
Packit Service 5a9772
	Stream_Write_UINT16(s, 0);     /* totalNumFonts (2 bytes) */
Packit 1fb8d4
	Stream_Write_UINT16(s, flags); /* listFlags (2 bytes) */
Packit Service 5a9772
	Stream_Write_UINT16(s, 50);    /* entrySize (2 bytes) */
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL rdp_send_client_font_list_pdu(rdpRdp* rdp, UINT16 flags)
Packit 1fb8d4
{
Packit 1fb8d4
	wStream* s = rdp_data_pdu_init(rdp);
Packit 1fb8d4
	rdp_write_client_font_list_pdu(s, flags);
Packit 1fb8d4
	return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FONT_LIST, rdp->mcs->userId);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL rdp_recv_font_map_pdu(rdpRdp* rdp, wStream* s)
Packit 1fb8d4
{
Packit 1fb8d4
	if (rdp->settings->ServerMode)
Packit 1fb8d4
		return rdp_recv_server_font_map_pdu(rdp, s);
Packit 1fb8d4
	else
Packit 1fb8d4
		return rdp_recv_client_font_map_pdu(rdp, s);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL rdp_recv_server_font_map_pdu(rdpRdp* rdp, wStream* s)
Packit 1fb8d4
{
Packit 1fb8d4
	rdp->finalize_sc_pdus |= FINALIZE_SC_FONT_MAP_PDU;
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL rdp_recv_client_font_map_pdu(rdpRdp* rdp, wStream* s)
Packit 1fb8d4
{
Packit 1fb8d4
	rdp->finalize_sc_pdus |= FINALIZE_SC_FONT_MAP_PDU;
Packit 1fb8d4
Packit 1fb8d4
	if (Stream_GetRemainingLength(s) >= 8)
Packit 1fb8d4
	{
Packit 1fb8d4
		Stream_Seek_UINT16(s); /* numberEntries (2 bytes) */
Packit 1fb8d4
		Stream_Seek_UINT16(s); /* totalNumEntries (2 bytes) */
Packit 1fb8d4
		Stream_Seek_UINT16(s); /* mapFlags (2 bytes) */
Packit 1fb8d4
		Stream_Seek_UINT16(s); /* entrySize (2 bytes) */
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL rdp_send_server_font_map_pdu(rdpRdp* rdp)
Packit 1fb8d4
{
Packit 1fb8d4
	wStream* s;
Packit 1fb8d4
	s = rdp_data_pdu_init(rdp);
Packit Service 5a9772
	Stream_Write_UINT16(s, 0);                              /* numberEntries (2 bytes) */
Packit Service 5a9772
	Stream_Write_UINT16(s, 0);                              /* totalNumEntries (2 bytes) */
Packit 1fb8d4
	Stream_Write_UINT16(s, FONTLIST_FIRST | FONTLIST_LAST); /* mapFlags (2 bytes) */
Packit Service 5a9772
	Stream_Write_UINT16(s, 4);                              /* entrySize (2 bytes) */
Packit 1fb8d4
	return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FONT_MAP, rdp->mcs->userId);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL rdp_recv_deactivate_all(rdpRdp* rdp, wStream* s)
Packit 1fb8d4
{
Packit 1fb8d4
	UINT16 lengthSourceDescriptor;
Packit Service 5a9772
	UINT32 timeout;
Packit 1fb8d4
Packit 1fb8d4
	if (rdp->state == CONNECTION_STATE_ACTIVE)
Packit 1fb8d4
		rdp->deactivation_reactivation = TRUE;
Packit 1fb8d4
	else
Packit 1fb8d4
		rdp->deactivation_reactivation = FALSE;
Packit 1fb8d4
Packit 1fb8d4
	/*
Packit 1fb8d4
	 * Windows XP can send short DEACTIVATE_ALL PDU that doesn't contain
Packit 1fb8d4
	 * the following fields.
Packit 1fb8d4
	 */
Packit 1fb8d4
	if (Stream_GetRemainingLength(s) > 0)
Packit 1fb8d4
	{
Packit 1fb8d4
		do
Packit 1fb8d4
		{
Packit 1fb8d4
			if (Stream_GetRemainingLength(s) < 4)
Packit 1fb8d4
				break;
Packit 1fb8d4
Packit 1fb8d4
			Stream_Read_UINT32(s, rdp->settings->ShareId); /* shareId (4 bytes) */
Packit 1fb8d4
Packit 1fb8d4
			if (Stream_GetRemainingLength(s) < 2)
Packit 1fb8d4
				break;
Packit 1fb8d4
Packit 1fb8d4
			Stream_Read_UINT16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */
Packit 1fb8d4
Packit 1fb8d4
			if (Stream_GetRemainingLength(s) < lengthSourceDescriptor)
Packit 1fb8d4
				break;
Packit 1fb8d4
Packit 1fb8d4
			Stream_Seek(s, lengthSourceDescriptor); /* sourceDescriptor (should be 0x00) */
Packit Service 5a9772
		} while (0);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	rdp_client_transition_to_state(rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE);
Packit 1fb8d4
Packit Service 5a9772
	for (timeout = 0; timeout < rdp->settings->TcpAckTimeout; timeout += 100)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (rdp_check_fds(rdp) < 0)
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
Packit 1fb8d4
		if (freerdp_shall_disconnect(rdp->instance))
Packit Service 5a9772
			return TRUE;
Packit Service 5a9772
Packit Service 5a9772
		if (rdp->state == CONNECTION_STATE_ACTIVE)
Packit Service 5a9772
			return TRUE;
Packit Service 5a9772
Packit Service 5a9772
		Sleep(100);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit Service 5a9772
	WLog_ERR(TAG, "Timeout waiting for activation");
Packit Service 5a9772
	return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL rdp_send_deactivate_all(rdpRdp* rdp)
Packit 1fb8d4
{
Packit 1fb8d4
	wStream* s = rdp_send_stream_pdu_init(rdp);
Packit 1fb8d4
	BOOL status;
Packit 1fb8d4
Packit 1fb8d4
	if (!s)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	Stream_Write_UINT32(s, rdp->settings->ShareId); /* shareId (4 bytes) */
Packit Service 5a9772
	Stream_Write_UINT16(s, 1);                      /* lengthSourceDescriptor (2 bytes) */
Packit Service 5a9772
	Stream_Write_UINT8(s, 0);                       /* sourceDescriptor (should be 0x00) */
Packit 1fb8d4
	status = rdp_send_pdu(rdp, s, PDU_TYPE_DEACTIVATE_ALL, rdp->mcs->userId);
Packit 1fb8d4
	Stream_Release(s);
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL rdp_server_accept_client_control_pdu(rdpRdp* rdp, wStream* s)
Packit 1fb8d4
{
Packit 1fb8d4
	UINT16 action;
Packit 1fb8d4
Packit 1fb8d4
	if (!rdp_recv_control_pdu(s, &action))
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	if (action == CTRLACTION_REQUEST_CONTROL)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (!rdp_send_server_control_granted_pdu(rdp))
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL rdp_server_accept_client_font_list_pdu(rdpRdp* rdp, wStream* s)
Packit 1fb8d4
{
Packit 1fb8d4
	rdpSettings* settings = rdp->settings;
Packit 1fb8d4
	freerdp_peer* peer = rdp->context->peer;
Packit 1fb8d4
Packit 1fb8d4
	if (!rdp_recv_client_font_list_pdu(s))
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	if (settings->SupportMonitorLayoutPdu && settings->MonitorCount && peer->AdjustMonitorsLayout &&
Packit 1fb8d4
	    peer->AdjustMonitorsLayout(peer))
Packit 1fb8d4
	{
Packit 1fb8d4
		/* client supports the monitorLayout PDU, let's send him the monitors if any */
Packit Service 5a9772
		MONITOR_DEF* monitors = (MONITOR_DEF*)calloc(settings->MonitorCount, sizeof(MONITOR_DEF));
Packit 1fb8d4
Packit Service 5a9772
		if (!monitors)
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
Packit Service 5a9772
		if (!display_convert_rdp_monitor_to_monitor_def(settings->MonitorCount,
Packit Service 5a9772
		                                                settings->MonitorDefArray, &monitors))
Packit 1fb8d4
		{
Packit Service 5a9772
			free(monitors);
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
		}
Packit 1fb8d4
Packit Service 5a9772
		if (!freerdp_display_send_monitor_layout(rdp->context, settings->MonitorCount, monitors))
Packit Service 5a9772
		{
Packit Service 5a9772
			free(monitors);
Packit 1fb8d4
			return FALSE;
Packit Service 5a9772
		}
Packit Service 5a9772
Packit Service 5a9772
		free(monitors);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (!rdp_send_server_font_map_pdu(rdp))
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	if (rdp_server_transition_to_state(rdp, CONNECTION_STATE_ACTIVE) < 0)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}