mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
libfreerdp-core: server-side auto-detect feature.
This commit is contained in:
60
include/freerdp/autodetect.h
Normal file
60
include/freerdp/autodetect.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Auto-Detect PDUs
|
||||
*
|
||||
* Copyright 2014 Dell Software <Mike.McDonald@software.dell.com>
|
||||
* Copyright 2014 Vic Lee
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_AUTODETECT_H
|
||||
#define FREERDP_AUTODETECT_H
|
||||
|
||||
typedef struct rdp_autodetect rdpAutoDetect;
|
||||
|
||||
typedef BOOL (*pRTTMeasureRequest)(rdpContext* context, UINT16 sequenceNumber);
|
||||
typedef BOOL (*pRTTMeasureResponse)(rdpContext* context, UINT16 sequenceNumber);
|
||||
typedef BOOL (*pBandwidthMeasureStart)(rdpContext* context, UINT16 sequenceNumber);
|
||||
typedef BOOL (*pBandwidthMeasurePayload)(rdpContext* context, UINT16 payloadLength, UINT16 sequenceNumber);
|
||||
typedef BOOL (*pBandwidthMeasureStop)(rdpContext* context, UINT16 payloadLength, UINT16 sequenceNumber);
|
||||
typedef BOOL (*pBandwidthMeasureResults)(rdpContext* context, UINT16 sequenceNumber);
|
||||
typedef BOOL (*pNetworkCharacteristicsResult)(rdpContext* context, UINT16 sequenceNumber);
|
||||
|
||||
struct rdp_autodetect
|
||||
{
|
||||
ALIGN64 rdpContext* context; /* 0 */
|
||||
/* RTT measurement */
|
||||
ALIGN64 UINT32 rttMeasureStartTime; /* 1 */
|
||||
/* Bandwidth measurement */
|
||||
ALIGN64 UINT32 bandwidthMeasureStartTime; /* 2 */
|
||||
ALIGN64 UINT32 bandwidthMeasureTimeDelta; /* 3 */
|
||||
ALIGN64 UINT32 bandwidthMeasureByteCount; /* 4 */
|
||||
/* Network characteristics (as reported by server) */
|
||||
ALIGN64 UINT32 netCharBandwidth; /* 5 */
|
||||
ALIGN64 UINT32 netCharBaseRTT; /* 6 */
|
||||
ALIGN64 UINT32 netCharAverageRTT; /* 7 */
|
||||
UINT64 paddingA[16 - 8]; /* 8 */
|
||||
|
||||
ALIGN64 pRTTMeasureRequest RTTMeasureRequest; /* 16 */
|
||||
ALIGN64 pRTTMeasureResponse RTTMeasureResponse; /* 17 */
|
||||
ALIGN64 pBandwidthMeasureStart BandwidthMeasureStart; /* 18 */
|
||||
ALIGN64 pBandwidthMeasurePayload BandwidthMeasurePayload; /* 19 */
|
||||
ALIGN64 pBandwidthMeasureStop BandwidthMeasureStop; /* 20 */
|
||||
ALIGN64 pBandwidthMeasureResults BandwidthMeasureResults; /* 21 */
|
||||
ALIGN64 pNetworkCharacteristicsResult NetworkCharacteristicsResult; /* 22 */
|
||||
UINT64 paddingB[32 - 23]; /* 23 */
|
||||
};
|
||||
|
||||
|
||||
#endif /* FREERDP_AUTODETECT_H */
|
||||
@@ -51,6 +51,7 @@ typedef RDP_CLIENT_ENTRY_POINTS_V1 RDP_CLIENT_ENTRY_POINTS;
|
||||
#include <freerdp/input.h>
|
||||
#include <freerdp/update.h>
|
||||
#include <freerdp/message.h>
|
||||
#include <freerdp/autodetect.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -123,7 +124,8 @@ struct rdp_context
|
||||
ALIGN64 rdpSettings* settings; /* 40 */
|
||||
ALIGN64 rdpMetrics* metrics; /* 41 */
|
||||
ALIGN64 rdpCodecs* codecs; /* 42 */
|
||||
UINT64 paddingC[64 - 43]; /* 43 */
|
||||
ALIGN64 rdpAutoDetect* autodetect; /* 43 */
|
||||
UINT64 paddingC[64 - 44]; /* 44 */
|
||||
|
||||
UINT64 paddingD[96 - 64]; /* 64 */
|
||||
UINT64 paddingE[128 - 96]; /* 96 */
|
||||
@@ -161,7 +163,10 @@ struct rdp_freerdp
|
||||
ALIGN64 rdpSettings* settings; /**< (offset 18)
|
||||
Pointer to a rdpSettings structure. Will be used to maintain the required RDP settings.
|
||||
Will be initialized by a call to freerdp_context_new() */
|
||||
UINT64 paddingB[32 - 19]; /* 19 */
|
||||
ALIGN64 rdpAutoDetect* autodetect; /* (offset 19)
|
||||
Auto-Detect handle for the connection.
|
||||
Will be initialized by a call to freerdp_context_new() */
|
||||
UINT64 paddingB[32 - 20]; /* 20 */
|
||||
|
||||
ALIGN64 size_t ContextSize; /* (offset 32)
|
||||
Specifies the size of the 'context' field. freerdp_context_new() will use this size to allocate the context buffer.
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <freerdp/settings.h>
|
||||
#include <freerdp/input.h>
|
||||
#include <freerdp/update.h>
|
||||
#include <freerdp/autodetect.h>
|
||||
|
||||
#include <winpr/sspi.h>
|
||||
|
||||
@@ -65,6 +66,7 @@ struct rdp_freerdp_peer
|
||||
rdpInput* input;
|
||||
rdpUpdate* update;
|
||||
rdpSettings* settings;
|
||||
rdpAutoDetect* autodetect;
|
||||
|
||||
void* ContextExtra;
|
||||
size_t ContextSize;
|
||||
|
||||
@@ -41,6 +41,27 @@ typedef struct
|
||||
UINT16 responseType;
|
||||
} AUTODETECT_RSP_PDU;
|
||||
|
||||
static BOOL autodetect_send_rtt_measure_request(rdpContext* context, UINT16 sequenceNumber)
|
||||
{
|
||||
wStream* s;
|
||||
|
||||
s = rdp_message_channel_pdu_init(context->rdp);
|
||||
|
||||
if (!s)
|
||||
return FALSE;
|
||||
|
||||
WLog_DBG(AUTODETECT_TAG, "sending RTT Measure Request PDU");
|
||||
|
||||
Stream_Write_UINT8(s, 0x06); /* headerLength (1 byte) */
|
||||
Stream_Write_UINT8(s, TYPE_ID_AUTODETECT_REQUEST); /* headerTypeId (1 byte) */
|
||||
Stream_Write_UINT16(s, sequenceNumber); /* sequenceNumber (2 bytes) */
|
||||
Stream_Write_UINT16(s, 0x0001); /* requestType (2 bytes) */
|
||||
|
||||
context->rdp->autodetect->rttMeasureStartTime = GetTickCount();
|
||||
|
||||
return rdp_send_message_channel_pdu(context->rdp, s, SEC_AUTODETECT_REQ);
|
||||
}
|
||||
|
||||
static BOOL autodetect_send_rtt_measure_response(rdpRdp* rdp, UINT16 sequenceNumber)
|
||||
{
|
||||
wStream* s;
|
||||
@@ -62,6 +83,88 @@ static BOOL autodetect_send_rtt_measure_response(rdpRdp* rdp, UINT16 sequenceNum
|
||||
return rdp_send_message_channel_pdu(rdp, s, SEC_AUTODETECT_RSP);
|
||||
}
|
||||
|
||||
static BOOL autodetect_send_bandwidth_measure_start(rdpContext* context, UINT16 sequenceNumber)
|
||||
{
|
||||
wStream* s;
|
||||
|
||||
s = rdp_message_channel_pdu_init(context->rdp);
|
||||
|
||||
if (!s)
|
||||
return FALSE;
|
||||
|
||||
WLog_DBG(AUTODETECT_TAG, "sending Bandwidth Measure Start PDU");
|
||||
|
||||
Stream_Write_UINT8(s, 0x06); /* headerLength (1 byte) */
|
||||
Stream_Write_UINT8(s, TYPE_ID_AUTODETECT_REQUEST); /* headerTypeId (1 byte) */
|
||||
Stream_Write_UINT16(s, sequenceNumber); /* sequenceNumber (2 bytes) */
|
||||
Stream_Write_UINT16(s, 0x0014); /* requestType (2 bytes) */
|
||||
|
||||
return rdp_send_message_channel_pdu(context->rdp, s, SEC_AUTODETECT_REQ);
|
||||
}
|
||||
|
||||
static BOOL autodetect_send_bandwidth_measure_payload(rdpContext* context, UINT16 payloadLength, UINT16 sequenceNumber)
|
||||
{
|
||||
UINT32 i;
|
||||
wStream* s;
|
||||
|
||||
s = rdp_message_channel_pdu_init(context->rdp);
|
||||
|
||||
if (!s)
|
||||
return FALSE;
|
||||
|
||||
WLog_DBG(AUTODETECT_TAG, "sending Bandwidth Measure Payload PDU -> payloadLength=%u");
|
||||
|
||||
/* 4-bytes aligned */
|
||||
payloadLength &= ~3;
|
||||
|
||||
Stream_Write_UINT8(s, 0x08); /* headerLength (1 byte) */
|
||||
Stream_Write_UINT8(s, TYPE_ID_AUTODETECT_REQUEST); /* headerTypeId (1 byte) */
|
||||
Stream_Write_UINT16(s, sequenceNumber); /* sequenceNumber (2 bytes) */
|
||||
Stream_Write_UINT16(s, 0x0002); /* requestType (2 bytes) */
|
||||
Stream_Write_UINT16(s, payloadLength); /* payloadLength (2 bytes) */
|
||||
Stream_EnsureRemainingCapacity(s, payloadLength);
|
||||
/* Random data (better measurement in case the line is compressed) */
|
||||
for (i = 0; i < payloadLength / 4; i++)
|
||||
{
|
||||
Stream_Write_UINT32(s, rand());
|
||||
}
|
||||
|
||||
return rdp_send_message_channel_pdu(context->rdp, s, SEC_AUTODETECT_REQ);
|
||||
}
|
||||
|
||||
static BOOL autodetect_send_bandwidth_measure_stop(rdpContext* context, UINT16 payloadLength, UINT16 sequenceNumber)
|
||||
{
|
||||
UINT32 i;
|
||||
wStream* s;
|
||||
|
||||
s = rdp_message_channel_pdu_init(context->rdp);
|
||||
|
||||
if (!s)
|
||||
return FALSE;
|
||||
|
||||
WLog_DBG(AUTODETECT_TAG, "sending Bandwidth Measure Stop PDU -> payloadLength=%u");
|
||||
|
||||
/* 4-bytes aligned */
|
||||
payloadLength &= ~3;
|
||||
|
||||
Stream_Write_UINT8(s, 0x08); /* headerLength (1 byte) */
|
||||
Stream_Write_UINT8(s, TYPE_ID_AUTODETECT_REQUEST); /* headerTypeId (1 byte) */
|
||||
Stream_Write_UINT16(s, sequenceNumber); /* sequenceNumber (2 bytes) */
|
||||
Stream_Write_UINT16(s, 0x002B); /* requestType (2 bytes) */
|
||||
Stream_Write_UINT16(s, payloadLength); /* payloadLength (2 bytes) */
|
||||
if (payloadLength > 0)
|
||||
{
|
||||
Stream_EnsureRemainingCapacity(s, payloadLength);
|
||||
/* Random data (better measurement in case the line is compressed) */
|
||||
for (i = 0; i < payloadLength / 4; i++)
|
||||
{
|
||||
Stream_Write_UINT32(s, rand());
|
||||
}
|
||||
}
|
||||
|
||||
return rdp_send_message_channel_pdu(context->rdp, s, SEC_AUTODETECT_REQ);
|
||||
}
|
||||
|
||||
static BOOL autodetect_send_bandwidth_measure_results(rdpRdp* rdp, UINT16 responseType, UINT16 sequenceNumber)
|
||||
{
|
||||
wStream* s;
|
||||
@@ -89,6 +192,40 @@ static BOOL autodetect_send_bandwidth_measure_results(rdpRdp* rdp, UINT16 respon
|
||||
return rdp_send_message_channel_pdu(rdp, s, SEC_AUTODETECT_RSP);
|
||||
}
|
||||
|
||||
static BOOL autodetect_send_netchar_result(rdpContext* context, UINT16 sequenceNumber)
|
||||
{
|
||||
wStream* s;
|
||||
|
||||
s = rdp_message_channel_pdu_init(context->rdp);
|
||||
|
||||
if (!s)
|
||||
return FALSE;
|
||||
|
||||
WLog_DBG(AUTODETECT_TAG, "sending Bandwidth Network Characteristics Result PDU");
|
||||
|
||||
if (context->rdp->autodetect->netCharBandwidth > 0)
|
||||
{
|
||||
Stream_Write_UINT8(s, 0x12); /* headerLength (1 byte) */
|
||||
Stream_Write_UINT8(s, TYPE_ID_AUTODETECT_REQUEST); /* headerTypeId (1 byte) */
|
||||
Stream_Write_UINT16(s, sequenceNumber); /* sequenceNumber (2 bytes) */
|
||||
Stream_Write_UINT16(s, 0x08C0); /* requestType (2 bytes) */
|
||||
Stream_Write_UINT32(s, context->rdp->autodetect->netCharBaseRTT); /* baseRTT (4 bytes) */
|
||||
Stream_Write_UINT32(s, context->rdp->autodetect->netCharBandwidth); /* bandwidth (4 bytes) */
|
||||
Stream_Write_UINT32(s, context->rdp->autodetect->netCharAverageRTT); /* averageRTT (4 bytes) */
|
||||
}
|
||||
else
|
||||
{
|
||||
Stream_Write_UINT8(s, 0x0E); /* headerLength (1 byte) */
|
||||
Stream_Write_UINT8(s, TYPE_ID_AUTODETECT_REQUEST); /* headerTypeId (1 byte) */
|
||||
Stream_Write_UINT16(s, sequenceNumber); /* sequenceNumber (2 bytes) */
|
||||
Stream_Write_UINT16(s, 0x0840); /* requestType (2 bytes) */
|
||||
Stream_Write_UINT32(s, context->rdp->autodetect->netCharBaseRTT); /* baseRTT (4 bytes) */
|
||||
Stream_Write_UINT32(s, context->rdp->autodetect->netCharAverageRTT); /* averageRTT (4 bytes) */
|
||||
}
|
||||
|
||||
return rdp_send_message_channel_pdu(context->rdp, s, SEC_AUTODETECT_REQ);
|
||||
}
|
||||
|
||||
BOOL autodetect_send_netchar_sync(rdpRdp* rdp, UINT16 sequenceNumber)
|
||||
{
|
||||
wStream* s;
|
||||
@@ -123,6 +260,24 @@ static BOOL autodetect_recv_rtt_measure_request(rdpRdp* rdp, wStream* s, AUTODET
|
||||
return autodetect_send_rtt_measure_response(rdp, autodetectReqPdu->sequenceNumber);
|
||||
}
|
||||
|
||||
static BOOL autodetect_recv_rtt_measure_response(rdpRdp* rdp, wStream* s, AUTODETECT_RSP_PDU* autodetectRspPdu)
|
||||
{
|
||||
BOOL success = TRUE;
|
||||
|
||||
if (autodetectRspPdu->headerLength != 0x06)
|
||||
return FALSE;
|
||||
|
||||
WLog_DBG(AUTODETECT_TAG, "received RTT Measure Response PDU");
|
||||
|
||||
rdp->autodetect->netCharAverageRTT = GetTickCount() - rdp->autodetect->rttMeasureStartTime;
|
||||
if (rdp->autodetect->netCharBaseRTT == 0 || rdp->autodetect->netCharBaseRTT > rdp->autodetect->netCharAverageRTT)
|
||||
rdp->autodetect->netCharBaseRTT = rdp->autodetect->netCharAverageRTT;
|
||||
|
||||
IFCALLRET(rdp->autodetect->RTTMeasureResponse, success, rdp->context, autodetectRspPdu->sequenceNumber);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static BOOL autodetect_recv_bandwidth_measure_start(rdpRdp* rdp, wStream* s, AUTODETECT_REQ_PDU* autodetectReqPdu)
|
||||
{
|
||||
if (autodetectReqPdu->headerLength != 0x06)
|
||||
@@ -191,8 +346,32 @@ static BOOL autodetect_recv_bandwidth_measure_stop(rdpRdp* rdp, wStream* s, AUTO
|
||||
return autodetect_send_bandwidth_measure_results(rdp, responseType, autodetectReqPdu->sequenceNumber);
|
||||
}
|
||||
|
||||
static BOOL autodetect_recv_bandwidth_measure_results(rdpRdp* rdp, wStream* s, AUTODETECT_RSP_PDU* autodetectRspPdu)
|
||||
{
|
||||
BOOL success = TRUE;
|
||||
|
||||
if (autodetectRspPdu->headerLength != 0x0E)
|
||||
return FALSE;
|
||||
|
||||
WLog_DBG(AUTODETECT_TAG, "received Bandwidth Measure Results PDU");
|
||||
|
||||
Stream_Read_UINT32(s, rdp->autodetect->bandwidthMeasureTimeDelta); /* timeDelta (4 bytes) */
|
||||
Stream_Read_UINT32(s, rdp->autodetect->bandwidthMeasureByteCount); /* byteCount (4 bytes) */
|
||||
|
||||
if (rdp->autodetect->bandwidthMeasureTimeDelta > 0)
|
||||
rdp->autodetect->netCharBandwidth = rdp->autodetect->bandwidthMeasureByteCount * 8 / rdp->autodetect->bandwidthMeasureTimeDelta;
|
||||
else
|
||||
rdp->autodetect->netCharBandwidth = 0;
|
||||
|
||||
IFCALLRET(rdp->autodetect->BandwidthMeasureResults, success, rdp->context, autodetectRspPdu->sequenceNumber);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static BOOL autodetect_recv_netchar_result(rdpRdp* rdp, wStream* s, AUTODETECT_REQ_PDU* autodetectReqPdu)
|
||||
{
|
||||
BOOL success = TRUE;
|
||||
|
||||
switch (autodetectReqPdu->requestType)
|
||||
{
|
||||
case 0x0840:
|
||||
@@ -222,8 +401,10 @@ static BOOL autodetect_recv_netchar_result(rdpRdp* rdp, wStream* s, AUTODETECT_R
|
||||
}
|
||||
|
||||
WLog_DBG(AUTODETECT_TAG, "received Network Characteristics Result PDU -> baseRTT=%u, bandwidth=%u, averageRTT=%u", rdp->autodetect->netCharBaseRTT, rdp->autodetect->netCharBandwidth, rdp->autodetect->netCharAverageRTT);
|
||||
|
||||
IFCALLRET(rdp->autodetect->NetworkCharacteristicsResult, success, rdp->context, autodetectReqPdu->sequenceNumber);
|
||||
|
||||
return TRUE;
|
||||
return success;
|
||||
}
|
||||
|
||||
int rdp_recv_autodetect_request_packet(rdpRdp* rdp, wStream* s)
|
||||
@@ -309,6 +490,23 @@ int rdp_recv_autodetect_response_packet(rdpRdp* rdp, wStream* s)
|
||||
if (autodetectRspPdu.headerTypeId != TYPE_ID_AUTODETECT_RESPONSE)
|
||||
return -1;
|
||||
|
||||
switch (autodetectRspPdu.responseType)
|
||||
{
|
||||
case 0x0000:
|
||||
/* RTT Measure Response (RDP_RTT_RESPONSE) - MS-RDPBCGR 2.2.14.2.1 */
|
||||
success = autodetect_recv_rtt_measure_response(rdp, s, &autodetectRspPdu);
|
||||
break;
|
||||
|
||||
case 0x0003:
|
||||
case 0x000B:
|
||||
/* Bandwidth Measure Results (RDP_BW_RESULTS) - MS-RDPBCGR 2.2.14.2.2 */
|
||||
success = autodetect_recv_bandwidth_measure_results(rdp, s, &autodetectRspPdu);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return success ? 0 : -1;
|
||||
}
|
||||
|
||||
@@ -328,3 +526,12 @@ void autodetect_free(rdpAutoDetect* autoDetect)
|
||||
{
|
||||
free(autoDetect);
|
||||
}
|
||||
|
||||
void autodetect_register_server_callbacks(rdpAutoDetect* autodetect)
|
||||
{
|
||||
autodetect->RTTMeasureRequest = autodetect_send_rtt_measure_request;
|
||||
autodetect->BandwidthMeasureStart = autodetect_send_bandwidth_measure_start;
|
||||
autodetect->BandwidthMeasurePayload = autodetect_send_bandwidth_measure_payload;
|
||||
autodetect->BandwidthMeasureStop = autodetect_send_bandwidth_measure_stop;
|
||||
autodetect->NetworkCharacteristicsResult = autodetect_send_netchar_result;
|
||||
}
|
||||
|
||||
@@ -20,11 +20,10 @@
|
||||
#ifndef __AUTODETECT_H
|
||||
#define __AUTODETECT_H
|
||||
|
||||
typedef struct rdp_autodetect rdpAutoDetect;
|
||||
|
||||
#include "rdp.h"
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/autodetect.h>
|
||||
#include <freerdp/log.h>
|
||||
|
||||
#include <winpr/stream.h>
|
||||
@@ -33,24 +32,14 @@ typedef struct rdp_autodetect rdpAutoDetect;
|
||||
#define TYPE_ID_AUTODETECT_REQUEST 0x00
|
||||
#define TYPE_ID_AUTODETECT_RESPONSE 0x01
|
||||
|
||||
struct rdp_autodetect
|
||||
{
|
||||
/* Bandwidth measurement */
|
||||
UINT32 bandwidthMeasureStartTime;
|
||||
UINT32 bandwidthMeasureByteCount;
|
||||
|
||||
/* Network characteristics (as reported by server) */
|
||||
UINT32 netCharBandwidth;
|
||||
UINT32 netCharBaseRTT;
|
||||
UINT32 netCharAverageRTT;
|
||||
};
|
||||
|
||||
int rdp_recv_autodetect_request_packet(rdpRdp* rdp, wStream* s);
|
||||
int rdp_recv_autodetect_response_packet(rdpRdp* rdp, wStream* s);
|
||||
|
||||
rdpAutoDetect* autodetect_new(void);
|
||||
void autodetect_free(rdpAutoDetect* autodetect);
|
||||
|
||||
void autodetect_register_server_callbacks(rdpAutoDetect* autodetect);
|
||||
|
||||
#define AUTODETECT_TAG FREERDP_TAG("core.autodetect")
|
||||
|
||||
#endif /* __AUTODETECT_H */
|
||||
|
||||
@@ -426,6 +426,7 @@ int freerdp_context_new(freerdp* instance)
|
||||
instance->input = rdp->input;
|
||||
instance->update = rdp->update;
|
||||
instance->settings = rdp->settings;
|
||||
instance->autodetect = rdp->autodetect;
|
||||
|
||||
context->graphics = graphics_new(context);
|
||||
context->rdp = rdp;
|
||||
@@ -433,6 +434,7 @@ int freerdp_context_new(freerdp* instance)
|
||||
context->input = instance->input;
|
||||
context->update = instance->update;
|
||||
context->settings = instance->settings;
|
||||
context->autodetect = instance->autodetect;
|
||||
|
||||
instance->update->context = instance->context;
|
||||
instance->update->pointer->context = instance->context;
|
||||
@@ -442,6 +444,8 @@ int freerdp_context_new(freerdp* instance)
|
||||
|
||||
instance->input->context = context;
|
||||
|
||||
instance->autodetect->context = context;
|
||||
|
||||
update_register_client_callbacks(rdp->update);
|
||||
|
||||
IFCALL(instance->ContextNew, instance, instance->context);
|
||||
|
||||
@@ -606,17 +606,21 @@ void freerdp_peer_context_new(freerdp_peer* client)
|
||||
client->input = rdp->input;
|
||||
client->update = rdp->update;
|
||||
client->settings = rdp->settings;
|
||||
client->autodetect = rdp->autodetect;
|
||||
|
||||
client->context->rdp = rdp;
|
||||
client->context->peer = client;
|
||||
client->context->input = client->input;
|
||||
client->context->update = client->update;
|
||||
client->context->settings = client->settings;
|
||||
client->context->autodetect = client->autodetect;
|
||||
|
||||
client->update->context = client->context;
|
||||
client->input->context = client->context;
|
||||
client->autodetect->context = client->context;
|
||||
|
||||
update_register_server_callbacks(client->update);
|
||||
autodetect_register_server_callbacks(client->autodetect);
|
||||
|
||||
transport_attach(rdp->transport, client->sockfd);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user