diff --git a/libfreerdp-core/capabilities.c b/libfreerdp-core/capabilities.c index e765583a3..8901a6372 100644 --- a/libfreerdp-core/capabilities.c +++ b/libfreerdp-core/capabilities.c @@ -1533,10 +1533,11 @@ void rdp_recv_demand_active(rdpRdp* rdp, STREAM* s, rdpSettings* settings) { rdp_read_demand_active(s, settings); rdp_send_confirm_active(rdp); - - rdp_recv(rdp); /* synchronize */ rdp_send_client_synchronize_pdu(rdp); + return; + rdp_recv(rdp); /* synchronize */ + rdp_send_client_control_pdu(rdp, CTRLACTION_COOPERATE); rdp_recv(rdp); /* cooperate */ @@ -1554,6 +1555,8 @@ void rdp_recv_demand_active(rdpRdp* rdp, STREAM* s, rdpSettings* settings) rdp_send_client_font_list_pdu(rdp, FONTLIST_FIRST); rdp_send_client_font_list_pdu(rdp, FONTLIST_LAST); } + + rdp->activated = True; } void rdp_write_confirm_active(STREAM* s, rdpSettings* settings) diff --git a/libfreerdp-core/connection.c b/libfreerdp-core/connection.c index 985ecfad4..6aa8da159 100644 --- a/libfreerdp-core/connection.c +++ b/libfreerdp-core/connection.c @@ -49,6 +49,15 @@ * */ +uint8 CTRLACTION_STRINGS[][32] = +{ + "", + "CTRLACTION_REQUEST_CONTROL", + "CTRLACTION_GRANTED_CONTROL", + "CTRLACTION_DETACH", + "CTRLACTION_COOPERATE" +}; + /** * Establish RDP Connection.\n * @msdn{cc240452} @@ -91,9 +100,21 @@ boolean rdp_client_connect(rdpRdp* rdp) return False; } - rdp->connected = True; + rdp->licensed = True; - rdp_recv(rdp); + rdp_client_activate(rdp); + + return True; +} + +boolean rdp_client_activate(rdpRdp* rdp) +{ + while (rdp->activated != True) + { + rdp_recv(rdp); + } + + printf("client is activated\n"); return True; } @@ -104,6 +125,11 @@ void rdp_write_client_synchronize_pdu(STREAM* s, rdpSettings* settings) stream_write_uint16(s, settings->pdu_source); /* targetUser (2 bytes) */ } +void rdp_recv_server_synchronize_pdu(rdpRdp* rdp, STREAM* s, rdpSettings* settings) +{ + rdp_send_client_control_pdu(rdp, CTRLACTION_COOPERATE); +} + void rdp_send_client_synchronize_pdu(rdpRdp* rdp) { STREAM* s; @@ -116,6 +142,13 @@ void rdp_send_client_synchronize_pdu(rdpRdp* rdp) MCS_BASE_CHANNEL_ID + rdp->mcs->user_id); } +void rdp_read_server_control_pdu(STREAM* s, uint16* action) +{ + stream_read_uint16(s, *action); /* action (2 bytes) */ + stream_seek_uint16(s); /* grantId (2 bytes) */ + stream_seek_uint32(s); /* controlId (4 bytes) */ +} + void rdp_write_client_control_pdu(STREAM* s, uint16 action) { stream_write_uint16(s, action); /* action (2 bytes) */ @@ -123,12 +156,32 @@ void rdp_write_client_control_pdu(STREAM* s, uint16 action) stream_write_uint32(s, 0); /* controlId (4 bytes) */ } +void rdp_recv_server_control_pdu(rdpRdp* rdp, STREAM* s, rdpSettings* settings) +{ + uint16 action; + + rdp_read_server_control_pdu(s, &action); + + printf("Server Control Action: %s\n", CTRLACTION_STRINGS[action]); + + if (action == CTRLACTION_COOPERATE) + { + rdp_send_client_control_pdu(rdp, CTRLACTION_REQUEST_CONTROL); + } + else if (action == CTRLACTION_GRANTED_CONTROL) + { + rdp_send_client_font_list_pdu(rdp, FONTLIST_FIRST | FONTLIST_LAST); + } +} + void rdp_send_client_control_pdu(rdpRdp* rdp, uint16 action) { STREAM* s; s = rdp_data_pdu_init(rdp); + printf("Client Control Action: %s\n", CTRLACTION_STRINGS[action]); + rdp_write_client_control_pdu(s, action); rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_CONTROL, diff --git a/libfreerdp-core/connection.h b/libfreerdp-core/connection.h index f546ca425..de88b1b92 100644 --- a/libfreerdp-core/connection.h +++ b/libfreerdp-core/connection.h @@ -44,8 +44,12 @@ #define FONTLIST_LAST 0x0002 boolean rdp_client_connect(rdpRdp* rdp); +boolean rdp_client_activate(rdpRdp* rdp); +void rdp_recv_server_synchronize_pdu(rdpRdp* rdp, STREAM* s, rdpSettings* settings); void rdp_send_client_synchronize_pdu(rdpRdp* rdp); +void rdp_recv_server_control_pdu(rdpRdp* rdp, STREAM* s, rdpSettings* settings); +void rdp_read_server_control_pdu(STREAM* s, uint16* action); void rdp_send_client_control_pdu(rdpRdp* rdp, uint16 action); void rdp_send_client_persistent_key_list_pdu(rdpRdp* rdp); void rdp_send_client_font_list_pdu(rdpRdp* rdp, uint16 flags); diff --git a/libfreerdp-core/rdp.c b/libfreerdp-core/rdp.c index 76d919984..f40f6fe40 100644 --- a/libfreerdp-core/rdp.c +++ b/libfreerdp-core/rdp.c @@ -249,6 +249,7 @@ void rdp_read_data_pdu(rdpRdp* rdp, STREAM* s) break; case DATA_PDU_TYPE_CONTROL: + rdp_recv_server_control_pdu(rdp, s, rdp->settings); break; case DATA_PDU_TYPE_POINTER: @@ -258,6 +259,7 @@ void rdp_read_data_pdu(rdpRdp* rdp, STREAM* s) break; case DATA_PDU_TYPE_SYNCHRONIZE: + rdp_recv_server_synchronize_pdu(rdp, s, rdp->settings); break; case DATA_PDU_TYPE_REFRESH_RECT: @@ -350,7 +352,7 @@ void rdp_recv(rdpRdp* rdp) stream_seek(s, 1); /* dataPriority + Segmentation (0x70) */ per_read_length(s, &pduLength); /* userData (OCTET_STRING) */ - if (rdp->connected != True) + if (rdp->licensed != True) { rdp_read_security_header(s, &sec_flags); @@ -414,7 +416,7 @@ rdpRdp* rdp_new() if (rdp != NULL) { - rdp->connected = False; + rdp->licensed = False; rdp->settings = settings_new(); rdp->registry = registry_new(rdp->settings); rdp->transport = transport_new(rdp->settings); diff --git a/libfreerdp-core/rdp.h b/libfreerdp-core/rdp.h index efd5733fc..0a5afa9bc 100644 --- a/libfreerdp-core/rdp.h +++ b/libfreerdp-core/rdp.h @@ -201,7 +201,8 @@ typedef struct rdp_rdp rdpRdp; struct rdp_rdp { - boolean connected; + boolean licensed; + boolean activated; struct rdp_mcs* mcs; struct rdp_nego* nego; struct rdp_license* license;