server: add MCS Channel Join Request/Confirm.

This commit is contained in:
Vic Lee 2011-08-20 14:05:03 +08:00
parent a312d47599
commit d229efdf14
5 changed files with 96 additions and 1 deletions

View File

@ -213,3 +213,35 @@ boolean rdp_server_accept_mcs_attach_user_request(rdpRdp* rdp, STREAM* s)
return True; return True;
} }
boolean rdp_server_accept_mcs_channel_join_request(rdpRdp* rdp, STREAM* s)
{
int i;
uint16 channel_id;
boolean all_joined = True;
if (!mcs_read_channel_join_request(rdp->mcs, s, &channel_id))
return False;
if (!mcs_send_channel_join_confirm(rdp->mcs, channel_id))
return False;
if (channel_id == rdp->mcs->user_id)
rdp->mcs->user_channel_joined = True;
else if (channel_id == MCS_GLOBAL_CHANNEL_ID)
rdp->mcs->global_channel_joined = True;
for (i = 0; i < rdp->settings->num_channels; i++)
{
if (rdp->settings->channels[i].chan_id == channel_id)
rdp->settings->channels[i].joined = True;
if (!rdp->settings->channels[i].joined)
all_joined = False;
}
if (rdp->mcs->user_channel_joined && rdp->mcs->global_channel_joined && all_joined)
rdp->state = CONNECTION_STATE_CHANNEL_JOIN;
return True;
}

View File

@ -37,7 +37,8 @@ enum CONNECTION_STATE
CONNECTION_STATE_NEGO, CONNECTION_STATE_NEGO,
CONNECTION_STATE_MCS_CONNECT, CONNECTION_STATE_MCS_CONNECT,
CONNECTION_STATE_MCS_ERECT_DOMAIN, CONNECTION_STATE_MCS_ERECT_DOMAIN,
CONNECTION_STATE_MCS_ATTACH_USER CONNECTION_STATE_MCS_ATTACH_USER,
CONNECTION_STATE_CHANNEL_JOIN
}; };
boolean rdp_client_connect(rdpRdp* rdp); boolean rdp_client_connect(rdpRdp* rdp);
@ -46,5 +47,6 @@ boolean rdp_server_accept_nego(rdpRdp* rdp, STREAM* s);
boolean rdp_server_accept_mcs_connect_initial(rdpRdp* rdp, STREAM* s); boolean rdp_server_accept_mcs_connect_initial(rdpRdp* rdp, STREAM* s);
boolean rdp_server_accept_mcs_erect_domain_request(rdpRdp* rdp, STREAM* s); boolean rdp_server_accept_mcs_erect_domain_request(rdpRdp* rdp, STREAM* s);
boolean rdp_server_accept_mcs_attach_user_request(rdpRdp* rdp, STREAM* s); boolean rdp_server_accept_mcs_attach_user_request(rdpRdp* rdp, STREAM* s);
boolean rdp_server_accept_mcs_channel_join_request(rdpRdp* rdp, STREAM* s);
#endif /* __CONNECTION_H */ #endif /* __CONNECTION_H */

View File

@ -718,6 +718,33 @@ boolean mcs_send_attach_user_confirm(rdpMcs* mcs)
return True; return True;
} }
/**
* Read MCS Channel Join Request.\n
* @msdn{cc240526}
* @param mcs mcs module
* @param s stream
*/
boolean mcs_read_channel_join_request(rdpMcs* mcs, STREAM* s, uint16* channel_id)
{
int length;
enum DomainMCSPDU MCSPDU;
uint16 user_id;
MCSPDU = DomainMCSPDU_ChannelJoinRequest;
if (!mcs_read_domain_mcspdu_header(s, &MCSPDU, &length))
return False;
if (!per_read_integer16(s, &user_id, MCS_BASE_CHANNEL_ID))
return False;
if (user_id != mcs->user_id)
return False;
if (!per_read_integer16(s, channel_id, 0))
return False;
return True;
}
/** /**
* Send MCS Channel Join Request.\n * Send MCS Channel Join Request.\n
* @msdn{cc240526} * @msdn{cc240526}
@ -767,6 +794,30 @@ void mcs_recv_channel_join_confirm(rdpMcs* mcs)
per_read_integer16(s, &channelId, 0); /* channelId */ per_read_integer16(s, &channelId, 0); /* channelId */
} }
/**
* Send MCS Channel Join Confirm.\n
* @msdn{cc240527}
* @param mcs mcs module
*/
boolean mcs_send_channel_join_confirm(rdpMcs* mcs, uint16 channel_id)
{
STREAM* s;
int length = 15;
s = transport_send_stream_init(mcs->transport, 15);
mcs_write_domain_mcspdu_header(s, DomainMCSPDU_ChannelJoinConfirm, length, 2);
per_write_enumerated(s, 0, MCS_Result_enum_length); /* result */
per_write_integer16(s, mcs->user_id, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */
per_write_integer16(s, channel_id, 0); /* requested (ChannelId) */
per_write_integer16(s, channel_id, 0); /* channelId */
transport_write(mcs->transport, s);
return True;
}
/** /**
* Instantiate new MCS module. * Instantiate new MCS module.
* @param transport transport * @param transport transport

View File

@ -118,6 +118,9 @@ struct rdp_mcs
DomainParameters targetParameters; DomainParameters targetParameters;
DomainParameters minimumParameters; DomainParameters minimumParameters;
DomainParameters maximumParameters; DomainParameters maximumParameters;
boolean user_channel_joined;
boolean global_channel_joined;
}; };
typedef struct rdp_mcs rdpMcs; typedef struct rdp_mcs rdpMcs;
@ -141,8 +144,10 @@ boolean mcs_read_attach_user_request(rdpMcs* mcs, STREAM* s);
void mcs_send_attach_user_request(rdpMcs* mcs); void mcs_send_attach_user_request(rdpMcs* mcs);
void mcs_recv_attach_user_confirm(rdpMcs* mcs); void mcs_recv_attach_user_confirm(rdpMcs* mcs);
boolean mcs_send_attach_user_confirm(rdpMcs* mcs); boolean mcs_send_attach_user_confirm(rdpMcs* mcs);
boolean mcs_read_channel_join_request(rdpMcs* mcs, STREAM* s, uint16* channel_id);
void mcs_send_channel_join_request(rdpMcs* mcs, uint16 channel_id); void mcs_send_channel_join_request(rdpMcs* mcs, uint16 channel_id);
void mcs_recv_channel_join_confirm(rdpMcs* mcs); void mcs_recv_channel_join_confirm(rdpMcs* mcs);
boolean mcs_send_channel_join_confirm(rdpMcs* mcs, uint16 channel_id);
boolean mcs_read_domain_mcspdu_header(STREAM* s, enum DomainMCSPDU* domainMCSPDU, int* length); boolean mcs_read_domain_mcspdu_header(STREAM* s, enum DomainMCSPDU* domainMCSPDU, int* length);
void mcs_write_domain_mcspdu_header(STREAM* s, enum DomainMCSPDU domainMCSPDU, int length, uint8 options); void mcs_write_domain_mcspdu_header(STREAM* s, enum DomainMCSPDU domainMCSPDU, int length, uint8 options);

View File

@ -79,6 +79,11 @@ static int peer_recv_callback(rdpTransport* transport, STREAM* s, void* extra)
return -1; return -1;
break; break;
case CONNECTION_STATE_MCS_ATTACH_USER:
if (!rdp_server_accept_mcs_channel_join_request(peer->rdp, s))
return -1;
break;
default: default:
printf("Invalid state %d\n", peer->rdp->state); printf("Invalid state %d\n", peer->rdp->state);
return -1; return -1;