2 * FreeRDP: A Remote Desktop Protocol Client
5 * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
20 #include "activation.h"
23 static const char* const CTRLACTION_STRINGS[] =
26 "CTRLACTION_REQUEST_CONTROL",
27 "CTRLACTION_GRANTED_CONTROL",
29 "CTRLACTION_COOPERATE"
33 void rdp_write_synchronize_pdu(STREAM* s, rdpSettings* settings)
35 stream_write_uint16(s, SYNCMSGTYPE_SYNC); /* messageType (2 bytes) */
36 stream_write_uint16(s, settings->pdu_source); /* targetUser (2 bytes) */
39 boolean rdp_recv_synchronize_pdu(rdpRdp* rdp, STREAM* s)
41 if (rdp->settings->server_mode)
42 return rdp_recv_server_synchronize_pdu(rdp, s);
44 return rdp_recv_client_synchronize_pdu(rdp, s);
47 boolean rdp_recv_server_synchronize_pdu(rdpRdp* rdp, STREAM* s)
49 rdp->finalize_sc_pdus |= FINALIZE_SC_SYNCHRONIZE_PDU;
53 boolean rdp_send_server_synchronize_pdu(rdpRdp* rdp)
57 s = rdp_data_pdu_init(rdp);
59 rdp_write_synchronize_pdu(s, rdp->settings);
60 rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SYNCHRONIZE, rdp->mcs->user_id);
65 boolean rdp_recv_client_synchronize_pdu(rdpRdp* rdp, STREAM* s)
69 rdp->finalize_sc_pdus |= FINALIZE_SC_SYNCHRONIZE_PDU;
71 if (stream_get_left(s) < 4)
74 stream_read_uint16(s, messageType); /* messageType (2 bytes) */
76 if (messageType != SYNCMSGTYPE_SYNC)
79 /* targetUser (2 bytes) */
80 stream_seek_uint16(s);
85 boolean rdp_send_client_synchronize_pdu(rdpRdp* rdp)
89 s = rdp_data_pdu_init(rdp);
91 rdp_write_synchronize_pdu(s, rdp->settings);
93 return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SYNCHRONIZE, rdp->mcs->user_id);
96 boolean rdp_recv_control_pdu(STREAM* s, uint16* action)
98 if (stream_get_left(s) < 8)
101 stream_read_uint16(s, *action); /* action (2 bytes) */
102 stream_seek_uint16(s); /* grantId (2 bytes) */
103 stream_seek_uint32(s); /* controlId (4 bytes) */
108 void rdp_write_client_control_pdu(STREAM* s, uint16 action)
110 stream_write_uint16(s, action); /* action (2 bytes) */
111 stream_write_uint16(s, 0); /* grantId (2 bytes) */
112 stream_write_uint32(s, 0); /* controlId (4 bytes) */
115 boolean rdp_recv_server_control_pdu(rdpRdp* rdp, STREAM* s)
119 rdp_recv_control_pdu(s, &action);
123 case CTRLACTION_COOPERATE:
124 rdp->finalize_sc_pdus |= FINALIZE_SC_CONTROL_COOPERATE_PDU;
127 case CTRLACTION_GRANTED_CONTROL:
128 rdp->finalize_sc_pdus |= FINALIZE_SC_CONTROL_GRANTED_PDU;
135 boolean rdp_send_server_control_cooperate_pdu(rdpRdp* rdp)
139 s = rdp_data_pdu_init(rdp);
141 stream_write_uint16(s, CTRLACTION_COOPERATE); /* action (2 bytes) */
142 stream_write_uint16(s, 0); /* grantId (2 bytes) */
143 stream_write_uint32(s, 0); /* controlId (4 bytes) */
145 rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_CONTROL, rdp->mcs->user_id);
150 boolean rdp_send_server_control_granted_pdu(rdpRdp* rdp)
154 s = rdp_data_pdu_init(rdp);
156 stream_write_uint16(s, CTRLACTION_GRANTED_CONTROL); /* action (2 bytes) */
157 stream_write_uint16(s, rdp->mcs->user_id); /* grantId (2 bytes) */
158 stream_write_uint32(s, 0x03EA); /* controlId (4 bytes) */
160 rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_CONTROL, rdp->mcs->user_id);
165 boolean rdp_send_client_control_pdu(rdpRdp* rdp, uint16 action)
169 s = rdp_data_pdu_init(rdp);
170 rdp_write_client_control_pdu(s, action);
172 return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_CONTROL, rdp->mcs->user_id);
175 void rdp_write_persistent_list_entry(STREAM* s, uint32 key1, uint32 key2)
177 stream_write_uint32(s, key1); /* key1 (4 bytes) */
178 stream_write_uint32(s, key2); /* key2 (4 bytes) */
181 void rdp_write_client_persistent_key_list_pdu(STREAM* s, rdpSettings* settings)
183 stream_write_uint16(s, 0); /* numEntriesCache0 (2 bytes) */
184 stream_write_uint16(s, 0); /* numEntriesCache1 (2 bytes) */
185 stream_write_uint16(s, 0); /* numEntriesCache2 (2 bytes) */
186 stream_write_uint16(s, 0); /* numEntriesCache3 (2 bytes) */
187 stream_write_uint16(s, 0); /* numEntriesCache4 (2 bytes) */
188 stream_write_uint16(s, 0); /* totalEntriesCache0 (2 bytes) */
189 stream_write_uint16(s, 0); /* totalEntriesCache1 (2 bytes) */
190 stream_write_uint16(s, 0); /* totalEntriesCache2 (2 bytes) */
191 stream_write_uint16(s, 0); /* totalEntriesCache3 (2 bytes) */
192 stream_write_uint16(s, 0); /* totalEntriesCache4 (2 bytes) */
193 stream_write_uint8(s, PERSIST_FIRST_PDU | PERSIST_LAST_PDU); /* bBitMask (1 byte) */
194 stream_write_uint8(s, 0); /* pad1 (1 byte) */
195 stream_write_uint16(s, 0); /* pad3 (2 bytes) */
200 boolean rdp_send_client_persistent_key_list_pdu(rdpRdp* rdp)
204 s = rdp_data_pdu_init(rdp);
205 rdp_write_client_persistent_key_list_pdu(s, rdp->settings);
207 return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST, rdp->mcs->user_id);
210 boolean rdp_recv_client_font_list_pdu(STREAM* s)
212 if (stream_get_left(s) < 8)
218 void rdp_write_client_font_list_pdu(STREAM* s, uint16 flags)
220 stream_write_uint16(s, 0); /* numberFonts (2 bytes) */
221 stream_write_uint16(s, 0); /* totalNumFonts (2 bytes) */
222 stream_write_uint16(s, flags); /* listFlags (2 bytes) */
223 stream_write_uint16(s, 50); /* entrySize (2 bytes) */
226 boolean rdp_send_client_font_list_pdu(rdpRdp* rdp, uint16 flags)
230 s = rdp_data_pdu_init(rdp);
231 rdp_write_client_font_list_pdu(s, flags);
233 return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FONT_LIST, rdp->mcs->user_id);
236 boolean rdp_recv_font_map_pdu(rdpRdp* rdp, STREAM* s)
238 if (rdp->settings->server_mode)
239 return rdp_recv_server_font_map_pdu(rdp, s);
241 return rdp_recv_client_font_map_pdu(rdp, s);
244 boolean rdp_recv_server_font_map_pdu(rdpRdp* rdp, STREAM* s)
246 rdp->finalize_sc_pdus |= FINALIZE_SC_FONT_MAP_PDU;
250 boolean rdp_recv_client_font_map_pdu(rdpRdp* rdp, STREAM* s)
252 rdp->finalize_sc_pdus |= FINALIZE_SC_FONT_MAP_PDU;
254 stream_seek_uint16(s); /* numberEntries (2 bytes) */
255 stream_seek_uint16(s); /* totalNumEntries (2 bytes) */
256 stream_seek_uint16(s); /* mapFlags (2 bytes) */
257 stream_seek_uint16(s); /* entrySize (2 bytes) */
262 boolean rdp_send_server_font_map_pdu(rdpRdp* rdp)
266 s = rdp_data_pdu_init(rdp);
268 stream_write_uint16(s, 0); /* numberEntries (2 bytes) */
269 stream_write_uint16(s, 0); /* totalNumEntries (2 bytes) */
270 stream_write_uint16(s, FONTLIST_FIRST | FONTLIST_LAST); /* mapFlags (2 bytes) */
271 stream_write_uint16(s, 4); /* entrySize (2 bytes) */
273 return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FONT_MAP, rdp->mcs->user_id);
276 boolean rdp_recv_deactivate_all(rdpRdp* rdp, STREAM* s)
278 uint16 lengthSourceDescriptor;
281 * Windows XP can send short DEACTIVATE_ALL PDU that doesn't contain
282 * the following fields.
284 if (stream_get_left(s) > 0)
286 stream_read_uint32(s, rdp->settings->share_id); /* shareId (4 bytes) */
287 stream_read_uint16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */
288 stream_seek(s, lengthSourceDescriptor); /* sourceDescriptor (should be 0x00) */
291 rdp->state = CONNECTION_STATE_CAPABILITY;
293 while (rdp->state != CONNECTION_STATE_ACTIVE)
295 if (rdp_check_fds(rdp) < 0)
304 boolean rdp_send_deactivate_all(rdpRdp* rdp)
308 s = rdp_pdu_init(rdp);
310 stream_write_uint32(s, rdp->settings->share_id); /* shareId (4 bytes) */
311 stream_write_uint16(s, 1); /* lengthSourceDescriptor (2 bytes) */
312 stream_write_uint8(s, 0); /* sourceDescriptor (should be 0x00) */
314 return rdp_send_pdu(rdp, s, PDU_TYPE_DEACTIVATE_ALL, rdp->mcs->user_id);
317 boolean rdp_server_accept_client_control_pdu(rdpRdp* rdp, STREAM* s)
321 if (!rdp_recv_control_pdu(s, &action))
323 if (action == CTRLACTION_REQUEST_CONTROL)
325 if (!rdp_send_server_control_granted_pdu(rdp))
331 boolean rdp_server_accept_client_font_list_pdu(rdpRdp* rdp, STREAM* s)
333 if (!rdp_recv_client_font_list_pdu(s))
335 if (!rdp_send_server_font_map_pdu(rdp))