2 * FreeRDP: A Remote Desktop Protocol Implementation
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.
24 #include "activation.h"
27 static const char* const CTRLACTION_STRINGS[] =
30 "CTRLACTION_REQUEST_CONTROL",
31 "CTRLACTION_GRANTED_CONTROL",
33 "CTRLACTION_COOPERATE"
37 void rdp_write_synchronize_pdu(wStream* s, rdpSettings* settings)
39 stream_write_UINT16(s, SYNCMSGTYPE_SYNC); /* messageType (2 bytes) */
40 stream_write_UINT16(s, settings->PduSource); /* targetUser (2 bytes) */
43 BOOL rdp_recv_synchronize_pdu(rdpRdp* rdp, wStream* s)
45 if (rdp->settings->ServerMode)
46 return rdp_recv_server_synchronize_pdu(rdp, s);
48 return rdp_recv_client_synchronize_pdu(rdp, s);
51 BOOL rdp_recv_server_synchronize_pdu(rdpRdp* rdp, wStream* s)
53 rdp->finalize_sc_pdus |= FINALIZE_SC_SYNCHRONIZE_PDU;
57 BOOL rdp_send_server_synchronize_pdu(rdpRdp* rdp)
61 s = rdp_data_pdu_init(rdp);
63 rdp_write_synchronize_pdu(s, rdp->settings);
64 return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SYNCHRONIZE, rdp->mcs->user_id);
67 BOOL rdp_recv_client_synchronize_pdu(rdpRdp* rdp, wStream* s)
71 rdp->finalize_sc_pdus |= FINALIZE_SC_SYNCHRONIZE_PDU;
73 if (Stream_GetRemainingLength(s) < 4)
76 stream_read_UINT16(s, messageType); /* messageType (2 bytes) */
78 if (messageType != SYNCMSGTYPE_SYNC)
81 /* targetUser (2 bytes) */
82 Stream_Seek_UINT16(s);
87 BOOL rdp_send_client_synchronize_pdu(rdpRdp* rdp)
91 s = rdp_data_pdu_init(rdp);
93 rdp_write_synchronize_pdu(s, rdp->settings);
95 return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SYNCHRONIZE, rdp->mcs->user_id);
98 BOOL rdp_recv_control_pdu(wStream* s, UINT16* action)
100 if (Stream_GetRemainingLength(s) < 8)
103 stream_read_UINT16(s, *action); /* action (2 bytes) */
104 Stream_Seek_UINT16(s); /* grantId (2 bytes) */
105 Stream_Seek_UINT32(s); /* controlId (4 bytes) */
110 void rdp_write_client_control_pdu(wStream* s, UINT16 action)
112 stream_write_UINT16(s, action); /* action (2 bytes) */
113 stream_write_UINT16(s, 0); /* grantId (2 bytes) */
114 stream_write_UINT32(s, 0); /* controlId (4 bytes) */
117 BOOL rdp_recv_server_control_pdu(rdpRdp* rdp, wStream* s)
121 if(rdp_recv_control_pdu(s, &action) == FALSE)
126 case CTRLACTION_COOPERATE:
127 rdp->finalize_sc_pdus |= FINALIZE_SC_CONTROL_COOPERATE_PDU;
130 case CTRLACTION_GRANTED_CONTROL:
131 rdp->finalize_sc_pdus |= FINALIZE_SC_CONTROL_GRANTED_PDU;
132 rdp->resendFocus = TRUE;
139 BOOL rdp_send_server_control_cooperate_pdu(rdpRdp* rdp)
143 s = rdp_data_pdu_init(rdp);
145 stream_write_UINT16(s, CTRLACTION_COOPERATE); /* action (2 bytes) */
146 stream_write_UINT16(s, 0); /* grantId (2 bytes) */
147 stream_write_UINT32(s, 0); /* controlId (4 bytes) */
149 return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_CONTROL, rdp->mcs->user_id);
152 BOOL rdp_send_server_control_granted_pdu(rdpRdp* rdp)
156 s = rdp_data_pdu_init(rdp);
158 stream_write_UINT16(s, CTRLACTION_GRANTED_CONTROL); /* action (2 bytes) */
159 stream_write_UINT16(s, rdp->mcs->user_id); /* grantId (2 bytes) */
160 stream_write_UINT32(s, 0x03EA); /* controlId (4 bytes) */
162 return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_CONTROL, rdp->mcs->user_id);
165 BOOL 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(wStream* 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(wStream* 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_BYTE(s, PERSIST_FIRST_PDU | PERSIST_LAST_PDU); /* bBitMask (1 byte) */
194 stream_write_BYTE(s, 0); /* pad1 (1 byte) */
195 stream_write_UINT16(s, 0); /* pad3 (2 bytes) */
200 BOOL 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 BOOL rdp_recv_client_font_list_pdu(wStream* s)
212 if (Stream_GetRemainingLength(s) < 8)
218 void rdp_write_client_font_list_pdu(wStream* 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 BOOL 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 BOOL rdp_recv_font_map_pdu(rdpRdp* rdp, wStream* s)
238 if (rdp->settings->ServerMode)
239 return rdp_recv_server_font_map_pdu(rdp, s);
241 return rdp_recv_client_font_map_pdu(rdp, s);
244 BOOL rdp_recv_server_font_map_pdu(rdpRdp* rdp, wStream* s)
246 rdp->finalize_sc_pdus |= FINALIZE_SC_FONT_MAP_PDU;
250 BOOL rdp_recv_client_font_map_pdu(rdpRdp* rdp, wStream* s)
252 rdp->finalize_sc_pdus |= FINALIZE_SC_FONT_MAP_PDU;
253 if(Stream_GetRemainingLength(s) >= 8)
255 Stream_Seek_UINT16(s); /* numberEntries (2 bytes) */
256 Stream_Seek_UINT16(s); /* totalNumEntries (2 bytes) */
257 Stream_Seek_UINT16(s); /* mapFlags (2 bytes) */
258 Stream_Seek_UINT16(s); /* entrySize (2 bytes) */
264 BOOL rdp_send_server_font_map_pdu(rdpRdp* rdp)
268 s = rdp_data_pdu_init(rdp);
270 stream_write_UINT16(s, 0); /* numberEntries (2 bytes) */
271 stream_write_UINT16(s, 0); /* totalNumEntries (2 bytes) */
272 stream_write_UINT16(s, FONTLIST_FIRST | FONTLIST_LAST); /* mapFlags (2 bytes) */
273 stream_write_UINT16(s, 4); /* entrySize (2 bytes) */
275 return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FONT_MAP, rdp->mcs->user_id);
278 BOOL rdp_recv_deactivate_all(rdpRdp* rdp, wStream* s)
280 UINT16 lengthSourceDescriptor;
283 * Windows XP can send short DEACTIVATE_ALL PDU that doesn't contain
284 * the following fields.
286 if (Stream_GetRemainingLength(s) > 0)
289 if(Stream_GetRemainingLength(s) < 4)
291 stream_read_UINT32(s, rdp->settings->ShareId); /* shareId (4 bytes) */
292 if(Stream_GetRemainingLength(s) < 2)
294 stream_read_UINT16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */
295 if(Stream_GetRemainingLength(s) < lengthSourceDescriptor)
297 Stream_Seek(s, lengthSourceDescriptor); /* sourceDescriptor (should be 0x00) */
301 rdp->state = CONNECTION_STATE_CAPABILITY;
303 while (rdp->state != CONNECTION_STATE_ACTIVE)
305 if (rdp_check_fds(rdp) < 0)
314 BOOL rdp_send_deactivate_all(rdpRdp* rdp)
318 s = rdp_pdu_init(rdp);
320 stream_write_UINT32(s, rdp->settings->ShareId); /* shareId (4 bytes) */
321 stream_write_UINT16(s, 1); /* lengthSourceDescriptor (2 bytes) */
322 stream_write_BYTE(s, 0); /* sourceDescriptor (should be 0x00) */
324 return rdp_send_pdu(rdp, s, PDU_TYPE_DEACTIVATE_ALL, rdp->mcs->user_id);
327 BOOL rdp_server_accept_client_control_pdu(rdpRdp* rdp, wStream* s)
331 if (!rdp_recv_control_pdu(s, &action))
333 if (action == CTRLACTION_REQUEST_CONTROL)
335 if (!rdp_send_server_control_granted_pdu(rdp))
341 BOOL rdp_server_accept_client_font_list_pdu(rdpRdp* rdp, wStream* s)
343 if (!rdp_recv_client_font_list_pdu(s))
345 if (!rdp_send_server_font_map_pdu(rdp))