Initial commit - from Precise source
[freerdp-ubuntu-pcb-backport.git] / libfreerdp-core / capabilities.c
1 /**
2  * FreeRDP: A Remote Desktop Protocol Client
3  * RDP Capability Sets
4  *
5  * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6  *
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
10  *
11  *       http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  */
19
20 #include "capabilities.h"
21
22 /*
23 static const char* const CAPSET_TYPE_STRINGS[] =
24 {
25                 "Unknown",
26                 "General",
27                 "Bitmap",
28                 "Order",
29                 "Bitmap Cache",
30                 "Control",
31                 "Unknown",
32                 "Window Activation",
33                 "Pointer",
34                 "Share",
35                 "Color Cache",
36                 "Unknown",
37                 "Sound",
38                 "Input",
39                 "Font",
40                 "Brush",
41                 "Glyph Cache",
42                 "Offscreen Bitmap Cache",
43                 "Bitmap Cache Host Support",
44                 "Bitmap Cache v2",
45                 "Virtual Channel",
46                 "DrawNineGrid Cache",
47                 "Draw GDI+ Cache",
48                 "Remote Programs",
49                 "Window List",
50                 "Desktop Composition",
51                 "Multifragment Update",
52                 "Large Pointer",
53                 "Surface Commands",
54                 "Bitmap Codecs",
55                 "Frame Acknowledge"
56 };
57 */
58
59 /* CODEC_GUID_REMOTEFX 0x76772F12BD724463AFB3B73C9C6F7886 */
60 #define CODEC_GUID_REMOTEFX "\x12\x2F\x77\x76\x72\xBD\x63\x44\xAF\xB3\xB7\x3C\x9C\x6F\x78\x86"
61
62 /* CODEC_GUID_NSCODEC  0xCA8D1BB9000F154F589FAE2D1A87E2D6 */
63 #define CODEC_GUID_NSCODEC "\xb9\x1b\x8d\xca\x0f\x00\x4f\x15\x58\x9f\xae\x2d\x1a\x87\xe2\xd6"
64
65 void rdp_read_capability_set_header(STREAM* s, uint16* length, uint16* type)
66 {
67         stream_read_uint16(s, *type); /* capabilitySetType */
68         stream_read_uint16(s, *length); /* lengthCapability */
69 }
70
71 void rdp_write_capability_set_header(STREAM* s, uint16 length, uint16 type)
72 {
73         stream_write_uint16(s, type); /* capabilitySetType */
74         stream_write_uint16(s, length); /* lengthCapability */
75 }
76
77 uint8* rdp_capability_set_start(STREAM* s)
78 {
79         uint8* header;
80
81         stream_get_mark(s, header);
82         stream_write_zero(s, CAPSET_HEADER_LENGTH);
83
84         return header;
85 }
86
87 void rdp_capability_set_finish(STREAM* s, uint8* header, uint16 type)
88 {
89         uint16 length;
90         uint8* footer;
91
92         footer = s->p;
93         length = footer - header;
94         stream_set_mark(s, header);
95
96         rdp_write_capability_set_header(s, length, type);
97         stream_set_mark(s, footer);
98 }
99
100 /**
101  * Read general capability set.\n
102  * @msdn{cc240549}
103  * @param s stream
104  * @param settings settings
105  */
106
107 void rdp_read_general_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
108 {
109         uint16 extraFlags;
110         uint8 refreshRectSupport;
111         uint8 suppressOutputSupport;
112
113         if (settings->server_mode)
114         {
115                 stream_read_uint16(s, settings->os_major_type); /* osMajorType (2 bytes) */
116                 stream_read_uint16(s, settings->os_minor_type); /* osMinorType (2 bytes) */
117         }
118         else
119         {
120                 stream_seek_uint16(s); /* osMajorType (2 bytes) */
121                 stream_seek_uint16(s); /* osMinorType (2 bytes) */
122         }
123         stream_seek_uint16(s); /* protocolVersion (2 bytes) */
124         stream_seek_uint16(s); /* pad2OctetsA (2 bytes) */
125         stream_seek_uint16(s); /* generalCompressionTypes (2 bytes) */
126         stream_read_uint16(s, extraFlags); /* extraFlags (2 bytes) */
127         stream_seek_uint16(s); /* updateCapabilityFlag (2 bytes) */
128         stream_seek_uint16(s); /* remoteUnshareFlag (2 bytes) */
129         stream_seek_uint16(s); /* generalCompressionLevel (2 bytes) */
130         stream_read_uint8(s, refreshRectSupport); /* refreshRectSupport (1 byte) */
131         stream_read_uint8(s, suppressOutputSupport); /* suppressOutputSupport (1 byte) */
132
133         if (!(extraFlags & FASTPATH_OUTPUT_SUPPORTED))
134                 settings->fastpath_output = false;
135
136         if (refreshRectSupport == false)
137                 settings->refresh_rect = false;
138
139         if (suppressOutputSupport == false)
140                 settings->suppress_output = false;
141 }
142
143 /**
144  * Write general capability set.\n
145  * @msdn{cc240549}
146  * @param s stream
147  * @param settings settings
148  */
149
150 void rdp_write_general_capability_set(STREAM* s, rdpSettings* settings)
151 {
152         uint8* header;
153         uint16 extraFlags;
154
155         header = rdp_capability_set_start(s);
156
157         extraFlags = LONG_CREDENTIALS_SUPPORTED | NO_BITMAP_COMPRESSION_HDR;
158
159         if (settings->auto_reconnection)
160                 extraFlags |= AUTORECONNECT_SUPPORTED;
161
162         if (settings->fastpath_output)
163                 extraFlags |= FASTPATH_OUTPUT_SUPPORTED;
164
165         if (settings->server_mode)
166         {
167                 /* not yet supported server-side */
168                 settings->refresh_rect = false;
169                 settings->suppress_output = false;
170         }
171
172         stream_write_uint16(s, settings->os_major_type); /* osMajorType (2 bytes) */
173         stream_write_uint16(s, settings->os_minor_type); /* osMinorType (2 bytes) */
174         stream_write_uint16(s, CAPS_PROTOCOL_VERSION); /* protocolVersion (2 bytes) */
175         stream_write_uint16(s, 0); /* pad2OctetsA (2 bytes) */
176         stream_write_uint16(s, 0); /* generalCompressionTypes (2 bytes) */
177         stream_write_uint16(s, extraFlags); /* extraFlags (2 bytes) */
178         stream_write_uint16(s, 0); /* updateCapabilityFlag (2 bytes) */
179         stream_write_uint16(s, 0); /* remoteUnshareFlag (2 bytes) */
180         stream_write_uint16(s, 0); /* generalCompressionLevel (2 bytes) */
181         stream_write_uint8(s, settings->refresh_rect); /* refreshRectSupport (1 byte) */
182         stream_write_uint8(s, settings->suppress_output); /* suppressOutputSupport (1 byte) */
183
184         rdp_capability_set_finish(s, header, CAPSET_TYPE_GENERAL);
185 }
186
187 /**
188  * Read bitmap capability set.\n
189  * @msdn{cc240554}
190  * @param s stream
191  * @param settings settings
192  */
193
194 void rdp_read_bitmap_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
195 {
196         uint8 drawingFlags;
197         uint16 desktopWidth;
198         uint16 desktopHeight;
199         uint16 desktopResizeFlag;
200         uint16 preferredBitsPerPixel;
201
202         stream_read_uint16(s, preferredBitsPerPixel); /* preferredBitsPerPixel (2 bytes) */
203         stream_seek_uint16(s); /* receive1BitPerPixel (2 bytes) */
204         stream_seek_uint16(s); /* receive4BitsPerPixel (2 bytes) */
205         stream_seek_uint16(s); /* receive8BitsPerPixel (2 bytes) */
206         stream_read_uint16(s, desktopWidth); /* desktopWidth (2 bytes) */
207         stream_read_uint16(s, desktopHeight); /* desktopHeight (2 bytes) */
208         stream_seek_uint16(s); /* pad2Octets (2 bytes) */
209         stream_read_uint16(s, desktopResizeFlag); /* desktopResizeFlag (2 bytes) */
210         stream_seek_uint16(s); /* bitmapCompressionFlag (2 bytes) */
211         stream_seek_uint8(s); /* highColorFlags (1 byte) */
212         stream_read_uint8(s, drawingFlags); /* drawingFlags (1 byte) */
213         stream_seek_uint16(s); /* multipleRectangleSupport (2 bytes) */
214         stream_seek_uint16(s); /* pad2OctetsB (2 bytes) */
215
216         if (!settings->server_mode && preferredBitsPerPixel != settings->color_depth)
217         {
218                 /* The client must respect the actual color depth used by the server */
219                 settings->color_depth = preferredBitsPerPixel;
220         }
221
222         if (desktopResizeFlag == false)
223                 settings->desktop_resize = false;
224
225         if (!settings->server_mode && settings->desktop_resize)
226         {
227                 /* The server may request a different desktop size during Deactivation-Reactivation sequence */
228                 settings->width = desktopWidth;
229                 settings->height = desktopHeight;
230         }
231 }
232
233 /**
234  * Write bitmap capability set.\n
235  * @msdn{cc240554}
236  * @param s stream
237  * @param settings settings
238  */
239
240 void rdp_write_bitmap_capability_set(STREAM* s, rdpSettings* settings)
241 {
242         uint8* header;
243         uint8 drawingFlags;
244         uint16 desktopResizeFlag;
245         uint16 preferredBitsPerPixel;
246
247         header = rdp_capability_set_start(s);
248
249         drawingFlags = 0;
250
251         if (settings->rdp_version > 5)
252                 preferredBitsPerPixel = settings->color_depth;
253         else
254                 preferredBitsPerPixel = 8;
255
256         desktopResizeFlag = settings->desktop_resize;
257
258         stream_write_uint16(s, preferredBitsPerPixel); /* preferredBitsPerPixel (2 bytes) */
259         stream_write_uint16(s, 1); /* receive1BitPerPixel (2 bytes) */
260         stream_write_uint16(s, 1); /* receive4BitsPerPixel (2 bytes) */
261         stream_write_uint16(s, 1); /* receive8BitsPerPixel (2 bytes) */
262         stream_write_uint16(s, settings->width); /* desktopWidth (2 bytes) */
263         stream_write_uint16(s, settings->height); /* desktopHeight (2 bytes) */
264         stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */
265         stream_write_uint16(s, desktopResizeFlag); /* desktopResizeFlag (2 bytes) */
266         stream_write_uint16(s, 1); /* bitmapCompressionFlag (2 bytes) */
267         stream_write_uint8(s, 0); /* highColorFlags (1 byte) */
268         stream_write_uint8(s, drawingFlags); /* drawingFlags (1 byte) */
269         stream_write_uint16(s, 1); /* multipleRectangleSupport (2 bytes) */
270         stream_write_uint16(s, 0); /* pad2OctetsB (2 bytes) */
271
272         rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP);
273 }
274
275 /**
276  * Read order capability set.\n
277  * @msdn{cc240556}
278  * @param s stream
279  * @param settings settings
280  */
281
282 void rdp_read_order_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
283 {
284         int i;
285         uint16 orderFlags;
286         uint8 orderSupport[32];
287         uint16 orderSupportExFlags;
288
289         stream_seek(s, 16); /* terminalDescriptor (16 bytes) */
290         stream_seek_uint32(s); /* pad4OctetsA (4 bytes) */
291         stream_seek_uint16(s); /* desktopSaveXGranularity (2 bytes) */
292         stream_seek_uint16(s); /* desktopSaveYGranularity (2 bytes) */
293         stream_seek_uint16(s); /* pad2OctetsA (2 bytes) */
294         stream_seek_uint16(s); /* maximumOrderLevel (2 bytes) */
295         stream_seek_uint16(s); /* numberFonts (2 bytes) */
296         stream_read_uint16(s, orderFlags); /* orderFlags (2 bytes) */
297         stream_read(s, orderSupport, 32); /* orderSupport (32 bytes) */
298         stream_seek_uint16(s); /* textFlags (2 bytes) */
299         stream_read_uint16(s, orderSupportExFlags); /* orderSupportExFlags (2 bytes) */
300         stream_seek_uint32(s); /* pad4OctetsB (4 bytes) */
301         stream_seek_uint32(s); /* desktopSaveSize (4 bytes) */
302         stream_seek_uint16(s); /* pad2OctetsC (2 bytes) */
303         stream_seek_uint16(s); /* pad2OctetsD (2 bytes) */
304         stream_seek_uint16(s); /* textANSICodePage (2 bytes) */
305         stream_seek_uint16(s); /* pad2OctetsE (2 bytes) */
306
307         for (i = 0; i < 32; i++)
308         {
309                 if (orderSupport[i] == false)
310                         settings->order_support[i] = false;
311         }
312 }
313
314 /**
315  * Write order capability set.\n
316  * @msdn{cc240556}
317  * @param s stream
318  * @param settings settings
319  */
320
321 void rdp_write_order_capability_set(STREAM* s, rdpSettings* settings)
322 {
323         uint8* header;
324         uint16 orderFlags;
325         uint16 orderSupportExFlags;
326         uint16 textANSICodePage;
327
328         header = rdp_capability_set_start(s);
329
330         /* see [MSDN-CP]: http://msdn.microsoft.com/en-us/library/dd317756 */
331         textANSICodePage = 65001; /* Unicode (UTF-8) */
332
333         orderSupportExFlags = 0;
334         orderFlags = NEGOTIATE_ORDER_SUPPORT | ZERO_BOUNDS_DELTA_SUPPORT | COLOR_INDEX_SUPPORT;
335
336         if (settings->bitmap_cache_v3)
337         {
338                 orderSupportExFlags |= CACHE_BITMAP_V3_SUPPORT;
339                 orderFlags |= ORDER_FLAGS_EXTRA_SUPPORT;
340         }
341
342         if (settings->frame_marker)
343         {
344                 orderSupportExFlags |= ALTSEC_FRAME_MARKER_SUPPORT;
345                 orderFlags |= ORDER_FLAGS_EXTRA_SUPPORT;
346         }
347
348         stream_write_zero(s, 16); /* terminalDescriptor (16 bytes) */
349         stream_write_uint32(s, 0); /* pad4OctetsA (4 bytes) */
350         stream_write_uint16(s, 1); /* desktopSaveXGranularity (2 bytes) */
351         stream_write_uint16(s, 20); /* desktopSaveYGranularity (2 bytes) */
352         stream_write_uint16(s, 0); /* pad2OctetsA (2 bytes) */
353         stream_write_uint16(s, 1); /* maximumOrderLevel (2 bytes) */
354         stream_write_uint16(s, 0); /* numberFonts (2 bytes) */
355         stream_write_uint16(s, orderFlags); /* orderFlags (2 bytes) */
356         stream_write(s, settings->order_support, 32); /* orderSupport (32 bytes) */
357         stream_write_uint16(s, 0); /* textFlags (2 bytes) */
358         stream_write_uint16(s, orderSupportExFlags); /* orderSupportExFlags (2 bytes) */
359         stream_write_uint32(s, 0); /* pad4OctetsB (4 bytes) */
360         stream_write_uint32(s, 230400); /* desktopSaveSize (4 bytes) */
361         stream_write_uint16(s, 0); /* pad2OctetsC (2 bytes) */
362         stream_write_uint16(s, 0); /* pad2OctetsD (2 bytes) */
363         stream_write_uint16(s, 0); /* textANSICodePage (2 bytes) */
364         stream_write_uint16(s, 0); /* pad2OctetsE (2 bytes) */
365
366         rdp_capability_set_finish(s, header, CAPSET_TYPE_ORDER);
367 }
368
369 /**
370  * Read bitmap cache capability set.\n
371  * @msdn{cc240559}
372  * @param s stream
373  * @param settings settings
374  */
375
376 void rdp_read_bitmap_cache_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
377 {
378         stream_seek_uint32(s); /* pad1 (4 bytes) */
379         stream_seek_uint32(s); /* pad2 (4 bytes) */
380         stream_seek_uint32(s); /* pad3 (4 bytes) */
381         stream_seek_uint32(s); /* pad4 (4 bytes) */
382         stream_seek_uint32(s); /* pad5 (4 bytes) */
383         stream_seek_uint32(s); /* pad6 (4 bytes) */
384         stream_seek_uint16(s); /* Cache0Entries (2 bytes) */
385         stream_seek_uint16(s); /* Cache0MaximumCellSize (2 bytes) */
386         stream_seek_uint16(s); /* Cache1Entries (2 bytes) */
387         stream_seek_uint16(s); /* Cache1MaximumCellSize (2 bytes) */
388         stream_seek_uint16(s); /* Cache2Entries (2 bytes) */
389         stream_seek_uint16(s); /* Cache2MaximumCellSize (2 bytes) */
390 }
391
392 /**
393  * Write bitmap cache capability set.\n
394  * @msdn{cc240559}
395  * @param s stream
396  * @param settings settings
397  */
398
399 void rdp_write_bitmap_cache_capability_set(STREAM* s, rdpSettings* settings)
400 {
401         int bpp;
402         uint16 size;
403         uint8* header;
404
405         header = rdp_capability_set_start(s);
406
407         bpp = (settings->color_depth + 7) / 8;
408
409         stream_write_uint32(s, 0); /* pad1 (4 bytes) */
410         stream_write_uint32(s, 0); /* pad2 (4 bytes) */
411         stream_write_uint32(s, 0); /* pad3 (4 bytes) */
412         stream_write_uint32(s, 0); /* pad4 (4 bytes) */
413         stream_write_uint32(s, 0); /* pad5 (4 bytes) */
414         stream_write_uint32(s, 0); /* pad6 (4 bytes) */
415
416         size = bpp * 256;
417         stream_write_uint16(s, 200); /* Cache0Entries (2 bytes) */
418         stream_write_uint16(s, size); /* Cache0MaximumCellSize (2 bytes) */
419
420         size = bpp * 1024;
421         stream_write_uint16(s, 600); /* Cache1Entries (2 bytes) */
422         stream_write_uint16(s, size); /* Cache1MaximumCellSize (2 bytes) */
423
424         size = bpp * 4096;
425         stream_write_uint16(s, 1000); /* Cache2Entries (2 bytes) */
426         stream_write_uint16(s, size); /* Cache2MaximumCellSize (2 bytes) */
427
428         rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE);
429 }
430
431 /**
432  * Read control capability set.\n
433  * @msdn{cc240568}
434  * @param s stream
435  * @param settings settings
436  */
437
438 void rdp_read_control_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
439 {
440         stream_seek_uint16(s); /* controlFlags (2 bytes) */
441         stream_seek_uint16(s); /* remoteDetachFlag (2 bytes) */
442         stream_seek_uint16(s); /* controlInterest (2 bytes) */
443         stream_seek_uint16(s); /* detachInterest (2 bytes) */
444 }
445
446 /**
447  * Write control capability set.\n
448  * @msdn{cc240568}
449  * @param s stream
450  * @param settings settings
451  */
452
453 void rdp_write_control_capability_set(STREAM* s, rdpSettings* settings)
454 {
455         uint8* header;
456
457         header = rdp_capability_set_start(s);
458
459         stream_write_uint16(s, 0); /* controlFlags (2 bytes) */
460         stream_write_uint16(s, 0); /* remoteDetachFlag (2 bytes) */
461         stream_write_uint16(s, 2); /* controlInterest (2 bytes) */
462         stream_write_uint16(s, 2); /* detachInterest (2 bytes) */
463
464         rdp_capability_set_finish(s, header, CAPSET_TYPE_CONTROL);
465 }
466
467 /**
468  * Read window activation capability set.\n
469  * @msdn{cc240569}
470  * @param s stream
471  * @param settings settings
472  */
473
474 void rdp_read_window_activation_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
475 {
476         stream_seek_uint16(s); /* helpKeyFlag (2 bytes) */
477         stream_seek_uint16(s); /* helpKeyIndexFlag (2 bytes) */
478         stream_seek_uint16(s); /* helpExtendedKeyFlag (2 bytes) */
479         stream_seek_uint16(s); /* windowManagerKeyFlag (2 bytes) */
480 }
481
482 /**
483  * Write window activation capability set.\n
484  * @msdn{cc240569}
485  * @param s stream
486  * @param settings settings
487  */
488
489 void rdp_write_window_activation_capability_set(STREAM* s, rdpSettings* settings)
490 {
491         uint8* header;
492
493         header = rdp_capability_set_start(s);
494
495         stream_write_uint16(s, 0); /* helpKeyFlag (2 bytes) */
496         stream_write_uint16(s, 0); /* helpKeyIndexFlag (2 bytes) */
497         stream_write_uint16(s, 0); /* helpExtendedKeyFlag (2 bytes) */
498         stream_write_uint16(s, 0); /* windowManagerKeyFlag (2 bytes) */
499
500         rdp_capability_set_finish(s, header, CAPSET_TYPE_ACTIVATION);
501 }
502
503 /**
504  * Read pointer capability set.\n
505  * @msdn{cc240562}
506  * @param s stream
507  * @param settings settings
508  */
509
510 void rdp_read_pointer_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
511 {
512         uint16 colorPointerFlag;
513         uint16 colorPointerCacheSize;
514         uint16 pointerCacheSize;
515
516         stream_read_uint16(s, colorPointerFlag); /* colorPointerFlag (2 bytes) */
517         stream_read_uint16(s, colorPointerCacheSize); /* colorPointerCacheSize (2 bytes) */
518         stream_read_uint16(s, pointerCacheSize); /* pointerCacheSize (2 bytes) */
519
520         if (colorPointerFlag == false)
521                 settings->color_pointer = false;
522
523         if (settings->server_mode)
524         {
525                 settings->pointer_cache_size = pointerCacheSize;
526         }
527 }
528
529 /**
530  * Write pointer capability set.\n
531  * @msdn{cc240562}
532  * @param s stream
533  * @param settings settings
534  */
535
536 void rdp_write_pointer_capability_set(STREAM* s, rdpSettings* settings)
537 {
538         uint8* header;
539         uint16 colorPointerFlag;
540
541         header = rdp_capability_set_start(s);
542
543         colorPointerFlag = (settings->color_pointer) ? 1 : 0;
544
545         stream_write_uint16(s, colorPointerFlag); /* colorPointerFlag (2 bytes) */
546         stream_write_uint16(s, settings->pointer_cache_size); /* colorPointerCacheSize (2 bytes) */
547
548         if (settings->large_pointer)
549         {
550                 stream_write_uint16(s, settings->pointer_cache_size); /* pointerCacheSize (2 bytes) */
551         }
552
553         rdp_capability_set_finish(s, header, CAPSET_TYPE_POINTER);
554 }
555
556 /**
557  * Read share capability set.\n
558  * @msdn{cc240570}
559  * @param s stream
560  * @param settings settings
561  */
562
563 void rdp_read_share_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
564 {
565         stream_seek_uint16(s); /* nodeId (2 bytes) */
566         stream_seek_uint16(s); /* pad2Octets (2 bytes) */
567 }
568
569 /**
570  * Write share capability set.\n
571  * @msdn{cc240570}
572  * @param s stream
573  * @param settings settings
574  */
575
576 void rdp_write_share_capability_set(STREAM* s, rdpSettings* settings)
577 {
578         uint8* header;
579         uint16 nodeId;
580
581         header = rdp_capability_set_start(s);
582
583         nodeId = (settings->server_mode) ? 0x03EA : 0;
584
585         stream_write_uint16(s, nodeId); /* nodeId (2 bytes) */
586         stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */
587
588         rdp_capability_set_finish(s, header, CAPSET_TYPE_SHARE);
589 }
590
591 /**
592  * Read color cache capability set.\n
593  * @msdn{cc241564}
594  * @param s stream
595  * @param settings settings
596  */
597
598 void rdp_read_color_cache_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
599 {
600         stream_seek_uint16(s); /* colorTableCacheSize (2 bytes) */
601         stream_seek_uint16(s); /* pad2Octets (2 bytes) */
602 }
603
604 /**
605  * Write color cache capability set.\n
606  * @msdn{cc241564}
607  * @param s stream
608  * @param settings settings
609  */
610
611 void rdp_write_color_cache_capability_set(STREAM* s, rdpSettings* settings)
612 {
613         uint8* header;
614
615         header = rdp_capability_set_start(s);
616
617         stream_write_uint16(s, 6); /* colorTableCacheSize (2 bytes) */
618         stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */
619
620         rdp_capability_set_finish(s, header, CAPSET_TYPE_COLOR_CACHE);
621 }
622
623 /**
624  * Read sound capability set.\n
625  * @msdn{cc240552}
626  * @param s stream
627  * @param settings settings
628  */
629
630 void rdp_read_sound_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
631 {
632         uint16 soundFlags;
633
634         stream_read_uint16(s, soundFlags); /* soundFlags (2 bytes) */
635         stream_seek_uint16(s); /* pad2OctetsA (2 bytes) */
636
637         settings->sound_beeps = (soundFlags & SOUND_BEEPS_FLAG) ? true : false;
638 }
639
640 /**
641  * Write sound capability set.\n
642  * @msdn{cc240552}
643  * @param s stream
644  * @param settings settings
645  */
646
647 void rdp_write_sound_capability_set(STREAM* s, rdpSettings* settings)
648 {
649         uint8* header;
650         uint16 soundFlags;
651
652         header = rdp_capability_set_start(s);
653
654         soundFlags = (settings->sound_beeps) ? SOUND_BEEPS_FLAG : 0;
655
656         stream_write_uint16(s, soundFlags); /* soundFlags (2 bytes) */
657         stream_write_uint16(s, 0); /* pad2OctetsA (2 bytes) */
658
659         rdp_capability_set_finish(s, header, CAPSET_TYPE_SOUND);
660 }
661
662 /**
663  * Read input capability set.\n
664  * @msdn{cc240563}
665  * @param s stream
666  * @param settings settings
667  */
668
669 void rdp_read_input_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
670 {
671         uint16 inputFlags;
672
673         stream_read_uint16(s, inputFlags); /* inputFlags (2 bytes) */
674         stream_seek_uint16(s); /* pad2OctetsA (2 bytes) */
675
676         if (settings->server_mode)
677         {
678                 stream_read_uint32(s, settings->kbd_layout); /* keyboardLayout (4 bytes) */
679                 stream_read_uint32(s, settings->kbd_type); /* keyboardType (4 bytes) */
680                 stream_read_uint32(s, settings->kbd_subtype); /* keyboardSubType (4 bytes) */
681                 stream_read_uint32(s, settings->kbd_fn_keys); /* keyboardFunctionKeys (4 bytes) */
682         }
683         else
684         {
685                 stream_seek_uint32(s); /* keyboardLayout (4 bytes) */
686                 stream_seek_uint32(s); /* keyboardType (4 bytes) */
687                 stream_seek_uint32(s); /* keyboardSubType (4 bytes) */
688                 stream_seek_uint32(s); /* keyboardFunctionKeys (4 bytes) */
689         }
690
691         stream_seek(s, 64); /* imeFileName (64 bytes) */
692
693         if (settings->server_mode != true)
694         {
695                 if (inputFlags & INPUT_FLAG_FASTPATH_INPUT)
696                 {
697                         /* advertised by RDP 5.0 and 5.1 servers */
698                 }
699                 else if (inputFlags & INPUT_FLAG_FASTPATH_INPUT2)
700                 {
701                         /* avertised by RDP 5.2, 6.0, 6.1 and 7.0 servers */
702                 }
703                 else
704                 {
705                         /* server does not support fastpath input */
706                         settings->fastpath_input = false;
707                 }
708         }
709 }
710
711 /**
712  * Write input capability set.\n
713  * @msdn{cc240563}
714  * @param s stream
715  * @param settings settings
716  */
717
718 void rdp_write_input_capability_set(STREAM* s, rdpSettings* settings)
719 {
720         uint8* header;
721         uint16 inputFlags;
722
723         header = rdp_capability_set_start(s);
724
725         inputFlags = INPUT_FLAG_SCANCODES | INPUT_FLAG_MOUSEX | INPUT_FLAG_UNICODE;
726
727         if (settings->fastpath_input)
728         {
729                 inputFlags |= INPUT_FLAG_FASTPATH_INPUT;
730                 inputFlags |= INPUT_FLAG_FASTPATH_INPUT2;
731         }
732
733         stream_write_uint16(s, inputFlags); /* inputFlags (2 bytes) */
734         stream_write_uint16(s, 0); /* pad2OctetsA (2 bytes) */
735         stream_write_uint32(s, settings->kbd_layout); /* keyboardLayout (4 bytes) */
736         stream_write_uint32(s, settings->kbd_type); /* keyboardType (4 bytes) */
737         stream_write_uint32(s, settings->kbd_subtype); /* keyboardSubType (4 bytes) */
738         stream_write_uint32(s, settings->kbd_fn_keys); /* keyboardFunctionKeys (4 bytes) */
739         stream_write_zero(s, 64); /* imeFileName (64 bytes) */
740
741         rdp_capability_set_finish(s, header, CAPSET_TYPE_INPUT);
742 }
743
744 /**
745  * Read font capability set.\n
746  * @msdn{cc240571}
747  * @param s stream
748  * @param settings settings
749  */
750
751 void rdp_read_font_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
752 {
753         if (length > 4)
754                 stream_seek_uint16(s); /* fontSupportFlags (2 bytes) */
755
756         if (length > 6)
757                 stream_seek_uint16(s); /* pad2Octets (2 bytes) */
758 }
759
760 /**
761  * Write font capability set.\n
762  * @msdn{cc240571}
763  * @param s stream
764  * @param settings settings
765  */
766
767 void rdp_write_font_capability_set(STREAM* s, rdpSettings* settings)
768 {
769         uint8* header;
770
771         header = rdp_capability_set_start(s);
772
773         stream_write_uint16(s, FONTSUPPORT_FONTLIST); /* fontSupportFlags (2 bytes) */
774         stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */
775
776         rdp_capability_set_finish(s, header, CAPSET_TYPE_FONT);
777 }
778
779 /**
780  * Read brush capability set.\n
781  * @msdn{cc240564}
782  * @param s stream
783  * @param settings settings
784  */
785
786 void rdp_read_brush_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
787 {
788         stream_seek_uint32(s); /* brushSupportLevel (4 bytes) */
789 }
790
791 /**
792  * Write brush capability set.\n
793  * @msdn{cc240564}
794  * @param s stream
795  * @param settings settings
796  */
797
798 void rdp_write_brush_capability_set(STREAM* s, rdpSettings* settings)
799 {
800         uint8* header;
801
802         header = rdp_capability_set_start(s);
803
804         stream_write_uint32(s, BRUSH_COLOR_FULL); /* brushSupportLevel (4 bytes) */
805
806         rdp_capability_set_finish(s, header, CAPSET_TYPE_BRUSH);
807 }
808
809 /**
810  * Read cache definition (glyph).\n
811  * @msdn{cc240566}
812  * @param s stream
813  */
814 void rdp_read_cache_definition(STREAM* s, GLYPH_CACHE_DEFINITION* cache_definition)
815 {
816         stream_read_uint16(s, cache_definition->cacheEntries); /* cacheEntries (2 bytes) */
817         stream_read_uint16(s, cache_definition->cacheMaximumCellSize); /* cacheMaximumCellSize (2 bytes) */
818 }
819
820 /**
821  * Write cache definition (glyph).\n
822  * @msdn{cc240566}
823  * @param s stream
824  */
825 void rdp_write_cache_definition(STREAM* s, GLYPH_CACHE_DEFINITION* cache_definition)
826 {
827         stream_write_uint16(s, cache_definition->cacheEntries); /* cacheEntries (2 bytes) */
828         stream_write_uint16(s, cache_definition->cacheMaximumCellSize); /* cacheMaximumCellSize (2 bytes) */
829 }
830
831 /**
832  * Read glyph cache capability set.\n
833  * @msdn{cc240565}
834  * @param s stream
835  * @param settings settings
836  */
837
838 void rdp_read_glyph_cache_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
839 {
840         uint16 glyphSupportLevel;
841
842         stream_seek(s, 40); /* glyphCache (40 bytes) */
843         stream_seek_uint32(s); /* fragCache (4 bytes) */
844         stream_read_uint16(s, glyphSupportLevel); /* glyphSupportLevel (2 bytes) */
845         stream_seek_uint16(s); /* pad2Octets (2 bytes) */
846
847         settings->glyphSupportLevel = glyphSupportLevel;
848 }
849
850 /**
851  * Write glyph cache capability set.\n
852  * @msdn{cc240565}
853  * @param s stream
854  * @param settings settings
855  */
856
857 void rdp_write_glyph_cache_capability_set(STREAM* s, rdpSettings* settings)
858 {
859         uint8* header;
860
861         header = rdp_capability_set_start(s);
862
863         /* glyphCache (40 bytes) */
864         rdp_write_cache_definition(s, &(settings->glyphCache[0])); /* glyphCache0 (4 bytes) */
865         rdp_write_cache_definition(s, &(settings->glyphCache[1])); /* glyphCache1 (4 bytes) */
866         rdp_write_cache_definition(s, &(settings->glyphCache[2])); /* glyphCache2 (4 bytes) */
867         rdp_write_cache_definition(s, &(settings->glyphCache[3])); /* glyphCache3 (4 bytes) */
868         rdp_write_cache_definition(s, &(settings->glyphCache[4])); /* glyphCache4 (4 bytes) */
869         rdp_write_cache_definition(s, &(settings->glyphCache[5])); /* glyphCache5 (4 bytes) */
870         rdp_write_cache_definition(s, &(settings->glyphCache[6])); /* glyphCache6 (4 bytes) */
871         rdp_write_cache_definition(s, &(settings->glyphCache[7])); /* glyphCache7 (4 bytes) */
872         rdp_write_cache_definition(s, &(settings->glyphCache[8])); /* glyphCache8 (4 bytes) */
873         rdp_write_cache_definition(s, &(settings->glyphCache[9])); /* glyphCache9 (4 bytes) */
874
875         rdp_write_cache_definition(s, settings->fragCache);  /* fragCache (4 bytes) */
876
877         stream_write_uint16(s, settings->glyphSupportLevel); /* glyphSupportLevel (2 bytes) */
878
879         stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */
880
881         rdp_capability_set_finish(s, header, CAPSET_TYPE_GLYPH_CACHE);
882 }
883
884 /**
885  * Read offscreen bitmap cache capability set.\n
886  * @msdn{cc240550}
887  * @param s stream
888  * @param settings settings
889  */
890
891 void rdp_read_offscreen_bitmap_cache_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
892 {
893         uint32 offscreenSupportLevel;
894
895         stream_read_uint32(s, offscreenSupportLevel); /* offscreenSupportLevel (4 bytes) */
896         stream_read_uint16(s, settings->offscreen_bitmap_cache_size); /* offscreenCacheSize (2 bytes) */
897         stream_read_uint16(s, settings->offscreen_bitmap_cache_entries); /* offscreenCacheEntries (2 bytes) */
898
899         if (offscreenSupportLevel & true)
900                 settings->offscreen_bitmap_cache = true;
901 }
902
903 /**
904  * Write offscreen bitmap cache capability set.\n
905  * @msdn{cc240550}
906  * @param s stream
907  * @param settings settings
908  */
909
910 void rdp_write_offscreen_bitmap_cache_capability_set(STREAM* s, rdpSettings* settings)
911 {
912         uint8* header;
913         uint32 offscreenSupportLevel = false;
914
915         header = rdp_capability_set_start(s);
916
917         if (settings->offscreen_bitmap_cache)
918                 offscreenSupportLevel = true;
919
920         stream_write_uint32(s, offscreenSupportLevel); /* offscreenSupportLevel (4 bytes) */
921         stream_write_uint16(s, settings->offscreen_bitmap_cache_size); /* offscreenCacheSize (2 bytes) */
922         stream_write_uint16(s, settings->offscreen_bitmap_cache_entries); /* offscreenCacheEntries (2 bytes) */
923
924         rdp_capability_set_finish(s, header, CAPSET_TYPE_OFFSCREEN_CACHE);
925 }
926
927 /**
928  * Read bitmap cache host support capability set.\n
929  * @msdn{cc240557}
930  * @param s stream
931  * @param settings settings
932  */
933
934 void rdp_read_bitmap_cache_host_support_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
935 {
936         uint8 cacheVersion;
937
938         stream_read_uint8(s, cacheVersion); /* cacheVersion (1 byte) */
939         stream_seek_uint8(s); /* pad1 (1 byte) */
940         stream_seek_uint16(s); /* pad2 (2 bytes) */
941
942         if (cacheVersion & BITMAP_CACHE_V2)
943                 settings->persistent_bitmap_cache = true;
944 }
945
946 /**
947  * Write bitmap cache host support capability set.\n
948  * @msdn{cc240557}
949  * @param s stream
950  * @param settings settings
951  */
952
953 void rdp_write_bitmap_cache_host_support_capability_set(STREAM* s, rdpSettings* settings)
954 {
955         uint8* header;
956
957         header = rdp_capability_set_start(s);
958
959         stream_write_uint8(s, BITMAP_CACHE_V2); /* cacheVersion (1 byte) */
960         stream_write_uint8(s, 0); /* pad1 (1 byte) */
961         stream_write_uint16(s, 0); /* pad2 (2 bytes) */
962
963         rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT);
964 }
965
966 void rdp_write_bitmap_cache_cell_info(STREAM* s, BITMAP_CACHE_V2_CELL_INFO* cellInfo)
967 {
968         uint32 info;
969
970         /**
971          * numEntries is in the first 31 bits, while the last bit (k)
972          * is used to indicate a persistent bitmap cache.
973          */
974
975         info = (cellInfo->numEntries | (cellInfo->persistent << 31));
976         stream_write_uint32(s, info);
977 }
978
979 /**
980  * Read bitmap cache v2 capability set.\n
981  * @msdn{cc240560}
982  * @param s stream
983  * @param settings settings
984  */
985
986 void rdp_read_bitmap_cache_v2_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
987 {
988         stream_seek_uint16(s); /* cacheFlags (2 bytes) */
989         stream_seek_uint8(s); /* pad2 (1 byte) */
990         stream_seek_uint8(s); /* numCellCaches (1 byte) */
991         stream_seek(s, 4); /* bitmapCache0CellInfo (4 bytes) */
992         stream_seek(s, 4); /* bitmapCache1CellInfo (4 bytes) */
993         stream_seek(s, 4); /* bitmapCache2CellInfo (4 bytes) */
994         stream_seek(s, 4); /* bitmapCache3CellInfo (4 bytes) */
995         stream_seek(s, 4); /* bitmapCache4CellInfo (4 bytes) */
996         stream_seek(s, 12); /* pad3 (12 bytes) */
997 }
998
999 /**
1000  * Write bitmap cache v2 capability set.\n
1001  * @msdn{cc240560}
1002  * @param s stream
1003  * @param settings settings
1004  */
1005
1006 void rdp_write_bitmap_cache_v2_capability_set(STREAM* s, rdpSettings* settings)
1007 {
1008         uint8* header;
1009         uint16 cacheFlags;
1010
1011         header = rdp_capability_set_start(s);
1012
1013         cacheFlags = ALLOW_CACHE_WAITING_LIST_FLAG;
1014
1015         if (settings->persistent_bitmap_cache)
1016                 cacheFlags |= PERSISTENT_KEYS_EXPECTED_FLAG;
1017
1018         stream_write_uint16(s, cacheFlags); /* cacheFlags (2 bytes) */
1019         stream_write_uint8(s, 0); /* pad2 (1 byte) */
1020         stream_write_uint8(s, settings->bitmapCacheV2NumCells); /* numCellCaches (1 byte) */
1021         rdp_write_bitmap_cache_cell_info(s, &settings->bitmapCacheV2CellInfo[0]); /* bitmapCache0CellInfo (4 bytes) */
1022         rdp_write_bitmap_cache_cell_info(s, &settings->bitmapCacheV2CellInfo[1]); /* bitmapCache1CellInfo (4 bytes) */
1023         rdp_write_bitmap_cache_cell_info(s, &settings->bitmapCacheV2CellInfo[2]); /* bitmapCache2CellInfo (4 bytes) */
1024         rdp_write_bitmap_cache_cell_info(s, &settings->bitmapCacheV2CellInfo[3]); /* bitmapCache3CellInfo (4 bytes) */
1025         rdp_write_bitmap_cache_cell_info(s, &settings->bitmapCacheV2CellInfo[4]); /* bitmapCache4CellInfo (4 bytes) */
1026         stream_write_zero(s, 12); /* pad3 (12 bytes) */
1027
1028         rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_V2);
1029 }
1030
1031 /**
1032  * Read virtual channel capability set.\n
1033  * @msdn{cc240551}
1034  * @param s stream
1035  * @param settings settings
1036  */
1037
1038 void rdp_read_virtual_channel_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
1039 {
1040         uint32 flags;
1041         uint32 VCChunkSize;
1042
1043         stream_read_uint32(s, flags); /* flags (4 bytes) */
1044
1045         if (length > 8)
1046                 stream_read_uint32(s, VCChunkSize); /* VCChunkSize (4 bytes) */
1047         else
1048                 VCChunkSize = 1600;
1049
1050         if (settings->server_mode != true)
1051                 settings->vc_chunk_size = VCChunkSize;
1052 }
1053
1054 /**
1055  * Write virtual channel capability set.\n
1056  * @msdn{cc240551}
1057  * @param s stream
1058  * @param settings settings
1059  */
1060
1061 void rdp_write_virtual_channel_capability_set(STREAM* s, rdpSettings* settings)
1062 {
1063         uint8* header;
1064         uint32 flags;
1065
1066         header = rdp_capability_set_start(s);
1067
1068         flags = (settings->server_mode) ? VCCAPS_COMPR_CS_8K : VCCAPS_NO_COMPR;
1069
1070         stream_write_uint32(s, flags); /* flags (4 bytes) */
1071         stream_write_uint32(s, settings->vc_chunk_size); /* VCChunkSize (4 bytes) */
1072
1073         rdp_capability_set_finish(s, header, CAPSET_TYPE_VIRTUAL_CHANNEL);
1074 }
1075
1076 /**
1077  * Read drawn nine grid cache capability set.\n
1078  * @msdn{cc241565}
1079  * @param s stream
1080  * @param settings settings
1081  */
1082
1083 void rdp_read_draw_nine_grid_cache_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
1084 {
1085         uint32 drawNineGridSupportLevel;
1086
1087         stream_read_uint32(s, drawNineGridSupportLevel); /* drawNineGridSupportLevel (4 bytes) */
1088         stream_read_uint16(s, settings->draw_nine_grid_cache_size); /* drawNineGridCacheSize (2 bytes) */
1089         stream_read_uint16(s, settings->draw_nine_grid_cache_entries); /* drawNineGridCacheEntries (2 bytes) */
1090
1091         if ((drawNineGridSupportLevel & DRAW_NINEGRID_SUPPORTED) ||
1092                         (drawNineGridSupportLevel & DRAW_NINEGRID_SUPPORTED_V2))
1093                 settings->draw_nine_grid = true;
1094 }
1095
1096 /**
1097  * Write drawn nine grid cache capability set.\n
1098  * @msdn{cc241565}
1099  * @param s stream
1100  * @param settings settings
1101  */
1102
1103 void rdp_write_draw_nine_grid_cache_capability_set(STREAM* s, rdpSettings* settings)
1104 {
1105         uint8* header;
1106         uint32 drawNineGridSupportLevel;
1107
1108         header = rdp_capability_set_start(s);
1109
1110         drawNineGridSupportLevel = (settings->draw_nine_grid) ? DRAW_NINEGRID_SUPPORTED : DRAW_NINEGRID_NO_SUPPORT;
1111
1112         stream_write_uint32(s, drawNineGridSupportLevel); /* drawNineGridSupportLevel (4 bytes) */
1113         stream_write_uint16(s, settings->draw_nine_grid_cache_size); /* drawNineGridCacheSize (2 bytes) */
1114         stream_write_uint16(s, settings->draw_nine_grid_cache_entries); /* drawNineGridCacheEntries (2 bytes) */
1115
1116         rdp_capability_set_finish(s, header, CAPSET_TYPE_DRAW_NINE_GRID_CACHE);
1117 }
1118
1119 void rdp_write_gdiplus_cache_entries(STREAM* s, uint16 gce, uint16 bce, uint16 pce, uint16 ice, uint16 ace)
1120 {
1121         stream_write_uint16(s, gce); /* gdipGraphicsCacheEntries (2 bytes) */
1122         stream_write_uint16(s, bce); /* gdipBrushCacheEntries (2 bytes) */
1123         stream_write_uint16(s, pce); /* gdipPenCacheEntries (2 bytes) */
1124         stream_write_uint16(s, ice); /* gdipImageCacheEntries (2 bytes) */
1125         stream_write_uint16(s, ace); /* gdipImageAttributesCacheEntries (2 bytes) */
1126 }
1127
1128 void rdp_write_gdiplus_cache_chunk_size(STREAM* s, uint16 gccs, uint16 obccs, uint16 opccs, uint16 oiaccs)
1129 {
1130         stream_write_uint16(s, gccs); /* gdipGraphicsCacheChunkSize (2 bytes) */
1131         stream_write_uint16(s, obccs); /* gdipObjectBrushCacheChunkSize (2 bytes) */
1132         stream_write_uint16(s, opccs); /* gdipObjectPenCacheChunkSize (2 bytes) */
1133         stream_write_uint16(s, oiaccs); /* gdipObjectImageAttributesCacheChunkSize (2 bytes) */
1134 }
1135
1136 void rdp_write_gdiplus_image_cache_properties(STREAM* s, uint16 oiccs, uint16 oicts, uint16 oicms)
1137 {
1138         stream_write_uint16(s, oiccs); /* gdipObjectImageCacheChunkSize (2 bytes) */
1139         stream_write_uint16(s, oicts); /* gdipObjectImageCacheTotalSize (2 bytes) */
1140         stream_write_uint16(s, oicms); /* gdipObjectImageCacheMaxSize (2 bytes) */
1141 }
1142
1143 /**
1144  * Read GDI+ cache capability set.\n
1145  * @msdn{cc241566}
1146  * @param s stream
1147  * @param settings settings
1148  */
1149
1150 void rdp_read_draw_gdiplus_cache_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
1151 {
1152         uint32 drawGDIPlusSupportLevel;
1153         uint32 drawGdiplusCacheLevel;
1154
1155         stream_read_uint32(s, drawGDIPlusSupportLevel); /* drawGDIPlusSupportLevel (4 bytes) */
1156         stream_seek_uint32(s); /* GdipVersion (4 bytes) */
1157         stream_read_uint32(s, drawGdiplusCacheLevel); /* drawGdiplusCacheLevel (4 bytes) */
1158         stream_seek(s, 10); /* GdipCacheEntries (10 bytes) */
1159         stream_seek(s, 8); /* GdipCacheChunkSize (8 bytes) */
1160         stream_seek(s, 6); /* GdipImageCacheProperties (6 bytes) */
1161
1162         if (drawGDIPlusSupportLevel & DRAW_GDIPLUS_SUPPORTED)
1163                 settings->draw_gdi_plus = true;
1164
1165         if (drawGdiplusCacheLevel & DRAW_GDIPLUS_CACHE_LEVEL_ONE)
1166                 settings->draw_gdi_plus_cache = true;
1167 }
1168
1169 /**
1170  * Write GDI+ cache capability set.\n
1171  * @msdn{cc241566}
1172  * @param s stream
1173  * @param settings settings
1174  */
1175
1176 void rdp_write_draw_gdiplus_cache_capability_set(STREAM* s, rdpSettings* settings)
1177 {
1178         uint8* header;
1179         uint32 drawGDIPlusSupportLevel;
1180         uint32 drawGdiplusCacheLevel;
1181
1182         header = rdp_capability_set_start(s);
1183
1184         drawGDIPlusSupportLevel = (settings->draw_gdi_plus) ? DRAW_GDIPLUS_SUPPORTED : DRAW_GDIPLUS_DEFAULT;
1185         drawGdiplusCacheLevel = (settings->draw_gdi_plus) ? DRAW_GDIPLUS_CACHE_LEVEL_ONE : DRAW_GDIPLUS_CACHE_LEVEL_DEFAULT;
1186
1187         stream_write_uint32(s, drawGDIPlusSupportLevel); /* drawGDIPlusSupportLevel (4 bytes) */
1188         stream_write_uint32(s, 0); /* GdipVersion (4 bytes) */
1189         stream_write_uint32(s, drawGdiplusCacheLevel); /* drawGdiplusCacheLevel (4 bytes) */
1190         rdp_write_gdiplus_cache_entries(s, 10, 5, 5, 10, 2); /* GdipCacheEntries (10 bytes) */
1191         rdp_write_gdiplus_cache_chunk_size(s, 512, 2048, 1024, 64); /* GdipCacheChunkSize (8 bytes) */
1192         rdp_write_gdiplus_image_cache_properties(s, 4096, 256, 128); /* GdipImageCacheProperties (6 bytes) */
1193
1194         rdp_capability_set_finish(s, header, CAPSET_TYPE_DRAW_GDI_PLUS);
1195 }
1196
1197 /**
1198  * Read remote programs capability set.\n
1199  * @msdn{cc242518}
1200  * @param s stream
1201  * @param settings settings
1202  */
1203
1204 void rdp_read_remote_programs_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
1205 {
1206         uint32 railSupportLevel;
1207
1208         stream_read_uint32(s, railSupportLevel); /* railSupportLevel (4 bytes) */
1209
1210         if ((railSupportLevel & RAIL_LEVEL_SUPPORTED) == 0)
1211         {
1212                 if (settings->remote_app == true)
1213                 {
1214                         /* RemoteApp Failure! */
1215                         settings->remote_app = false;
1216                 }
1217         }
1218 }
1219
1220 /**
1221  * Write remote programs capability set.\n
1222  * @msdn{cc242518}
1223  * @param s stream
1224  * @param settings settings
1225  */
1226
1227 void rdp_write_remote_programs_capability_set(STREAM* s, rdpSettings* settings)
1228 {
1229         uint8* header;
1230         uint32 railSupportLevel;
1231
1232         header = rdp_capability_set_start(s);
1233
1234         railSupportLevel = RAIL_LEVEL_SUPPORTED;
1235
1236         if (settings->rail_langbar_supported)
1237                 railSupportLevel |= RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED;
1238
1239         stream_write_uint32(s, railSupportLevel); /* railSupportLevel (4 bytes) */
1240
1241         rdp_capability_set_finish(s, header, CAPSET_TYPE_RAIL);
1242 }
1243
1244 /**
1245  * Read window list capability set.\n
1246  * @msdn{cc242564}
1247  * @param s stream
1248  * @param settings settings
1249  */
1250
1251 void rdp_read_window_list_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
1252 {
1253         stream_seek_uint32(s); /* wndSupportLevel (4 bytes) */
1254         stream_seek_uint8(s); /* numIconCaches (1 byte) */
1255         stream_seek_uint16(s); /* numIconCacheEntries (2 bytes) */
1256 }
1257
1258 /**
1259  * Write window list capability set.\n
1260  * @msdn{cc242564}
1261  * @param s stream
1262  * @param settings settings
1263  */
1264
1265 void rdp_write_window_list_capability_set(STREAM* s, rdpSettings* settings)
1266 {
1267         uint8* header;
1268         uint32 wndSupportLevel;
1269
1270         header = rdp_capability_set_start(s);
1271
1272         wndSupportLevel = WINDOW_LEVEL_SUPPORTED_EX;
1273
1274         stream_write_uint32(s, wndSupportLevel); /* wndSupportLevel (4 bytes) */
1275         stream_write_uint8(s, settings->num_icon_caches); /* numIconCaches (1 byte) */
1276         stream_write_uint16(s, settings->num_icon_cache_entries); /* numIconCacheEntries (2 bytes) */
1277
1278         rdp_capability_set_finish(s, header, CAPSET_TYPE_WINDOW);
1279 }
1280
1281 /**
1282  * Read desktop composition capability set.\n
1283  * @msdn{cc240855}
1284  * @param s stream
1285  * @param settings settings
1286  */
1287
1288 void rdp_read_desktop_composition_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
1289 {
1290         stream_seek_uint16(s); /* compDeskSupportLevel (2 bytes) */
1291 }
1292
1293 /**
1294  * Write desktop composition capability set.\n
1295  * @msdn{cc240855}
1296  * @param s stream
1297  * @param settings settings
1298  */
1299
1300 void rdp_write_desktop_composition_capability_set(STREAM* s, rdpSettings* settings)
1301 {
1302         uint8* header;
1303         uint16 compDeskSupportLevel;
1304
1305         header = rdp_capability_set_start(s);
1306
1307         compDeskSupportLevel = (settings->desktop_composition) ? COMPDESK_SUPPORTED : COMPDESK_NOT_SUPPORTED;
1308
1309         stream_write_uint16(s, compDeskSupportLevel); /* compDeskSupportLevel (2 bytes) */
1310
1311         rdp_capability_set_finish(s, header, CAPSET_TYPE_COMP_DESK);
1312 }
1313
1314 /**
1315  * Read multifragment update capability set.\n
1316  * @msdn{cc240649}
1317  * @param s stream
1318  * @param settings settings
1319  */
1320
1321 void rdp_read_multifragment_update_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
1322 {
1323         stream_read_uint32(s, settings->multifrag_max_request_size); /* MaxRequestSize (4 bytes) */
1324 }
1325
1326 /**
1327  * Write multifragment update capability set.\n
1328  * @msdn{cc240649}
1329  * @param s stream
1330  * @param settings settings
1331  */
1332
1333 void rdp_write_multifragment_update_capability_set(STREAM* s, rdpSettings* settings)
1334 {
1335         uint8* header;
1336
1337         header = rdp_capability_set_start(s);
1338
1339         stream_write_uint32(s, settings->multifrag_max_request_size); /* MaxRequestSize (4 bytes) */
1340
1341         rdp_capability_set_finish(s, header, CAPSET_TYPE_MULTI_FRAGMENT_UPDATE);
1342 }
1343
1344 /**
1345  * Read large pointer capability set.\n
1346  * @msdn{cc240650}
1347  * @param s stream
1348  * @param settings settings
1349  */
1350
1351 void rdp_read_large_pointer_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
1352 {
1353         stream_seek_uint16(s); /* largePointerSupportFlags (2 bytes) */
1354 }
1355
1356 /**
1357  * Write large pointer capability set.\n
1358  * @msdn{cc240650}
1359  * @param s stream
1360  * @param settings settings
1361  */
1362
1363 void rdp_write_large_pointer_capability_set(STREAM* s, rdpSettings* settings)
1364 {
1365         uint8* header;
1366         uint16 largePointerSupportFlags;
1367
1368         header = rdp_capability_set_start(s);
1369
1370         largePointerSupportFlags = (settings->large_pointer) ? LARGE_POINTER_FLAG_96x96 : 0;
1371
1372         stream_write_uint16(s, largePointerSupportFlags); /* largePointerSupportFlags (2 bytes) */
1373
1374         rdp_capability_set_finish(s, header, CAPSET_TYPE_LARGE_POINTER);
1375 }
1376
1377 /**
1378  * Read surface commands capability set.\n
1379  * @msdn{dd871563}
1380  * @param s stream
1381  * @param settings settings
1382  */
1383
1384 void rdp_read_surface_commands_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
1385 {
1386         stream_seek_uint32(s); /* cmdFlags (4 bytes) */
1387         stream_seek_uint32(s); /* reserved (4 bytes) */
1388
1389         settings->surface_commands = true;
1390 }
1391
1392 /**
1393  * Write surface commands capability set.\n
1394  * @msdn{dd871563}
1395  * @param s stream
1396  * @param settings settings
1397  */
1398
1399 void rdp_write_surface_commands_capability_set(STREAM* s, rdpSettings* settings)
1400 {
1401         uint8* header;
1402         uint32 cmdFlags;
1403
1404         header = rdp_capability_set_start(s);
1405
1406         cmdFlags = SURFCMDS_FRAME_MARKER |
1407                         SURFCMDS_SET_SURFACE_BITS |
1408                         SURFCMDS_STREAM_SURFACE_BITS;
1409
1410         stream_write_uint32(s, cmdFlags); /* cmdFlags (4 bytes) */
1411         stream_write_uint32(s, 0); /* reserved (4 bytes) */
1412
1413         rdp_capability_set_finish(s, header, CAPSET_TYPE_SURFACE_COMMANDS);
1414 }
1415
1416 /**
1417  * Read bitmap codecs capability set.\n
1418  * @msdn{dd891377}
1419  * @param s stream
1420  * @param settings settings
1421  */
1422
1423 void rdp_read_bitmap_codecs_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
1424 {
1425         uint8 bitmapCodecCount;
1426         uint16 codecPropertiesLength;
1427
1428         stream_read_uint8(s, bitmapCodecCount); /* bitmapCodecCount (1 byte) */
1429
1430         if (settings->server_mode)
1431         {
1432                 settings->rfx_codec = false;
1433                 settings->ns_codec = false;
1434         }
1435
1436         while (bitmapCodecCount > 0)
1437         {
1438                 if (settings->server_mode && strncmp((char*)stream_get_tail(s), CODEC_GUID_REMOTEFX, 16) == 0)
1439                 {
1440                         stream_seek(s, 16); /* codecGUID (16 bytes) */
1441                         stream_read_uint8(s, settings->rfx_codec_id);
1442                         settings->rfx_codec = true;
1443                 }
1444                 else if (settings->server_mode && strncmp((char*)stream_get_tail(s),CODEC_GUID_NSCODEC, 16) == 0)
1445                 {
1446                         stream_seek(s, 16); /*codec GUID (16 bytes) */
1447                         stream_read_uint8(s, settings->ns_codec_id);
1448                         settings->ns_codec = true;
1449                 }
1450                 else
1451                 {
1452                         stream_seek(s, 16); /* codecGUID (16 bytes) */
1453                         stream_seek_uint8(s); /* codecID (1 byte) */
1454                 }
1455
1456                 stream_read_uint16(s, codecPropertiesLength); /* codecPropertiesLength (2 bytes) */
1457                 stream_seek(s, codecPropertiesLength); /* codecProperties */
1458
1459                 bitmapCodecCount--;
1460         }
1461 }
1462
1463 /**
1464  * Write RemoteFX Client Capability Container.\n
1465  * @param s stream
1466  * @param settings settings
1467  */
1468 void rdp_write_rfx_client_capability_container(STREAM* s, rdpSettings* settings)
1469 {
1470         uint32 captureFlags;
1471         uint8 codecMode;
1472
1473         captureFlags = settings->dump_rfx ? 0 : CARDP_CAPS_CAPTURE_NON_CAC;
1474         codecMode = settings->rfx_codec_mode;
1475
1476         stream_write_uint16(s, 49); /* codecPropertiesLength */
1477
1478         /* TS_RFX_CLNT_CAPS_CONTAINER */
1479         stream_write_uint32(s, 49); /* length */
1480         stream_write_uint32(s, captureFlags); /* captureFlags */
1481         stream_write_uint32(s, 37); /* capsLength */
1482
1483         /* TS_RFX_CAPS */
1484         stream_write_uint16(s, CBY_CAPS); /* blockType */
1485         stream_write_uint32(s, 8); /* blockLen */
1486         stream_write_uint16(s, 1); /* numCapsets */
1487
1488         /* TS_RFX_CAPSET */
1489         stream_write_uint16(s, CBY_CAPSET); /* blockType */
1490         stream_write_uint32(s, 29); /* blockLen */
1491         stream_write_uint8(s, 0x01); /* codecId (MUST be set to 0x01) */
1492         stream_write_uint16(s, CLY_CAPSET); /* capsetType */
1493         stream_write_uint16(s, 2); /* numIcaps */
1494         stream_write_uint16(s, 8); /* icapLen */
1495
1496         /* TS_RFX_ICAP (RLGR1) */
1497         stream_write_uint16(s, CLW_VERSION_1_0); /* version */
1498         stream_write_uint16(s, CT_TILE_64x64); /* tileSize */
1499         stream_write_uint8(s, codecMode); /* flags */
1500         stream_write_uint8(s, CLW_COL_CONV_ICT); /* colConvBits */
1501         stream_write_uint8(s, CLW_XFORM_DWT_53_A); /* transformBits */
1502         stream_write_uint8(s, CLW_ENTROPY_RLGR1); /* entropyBits */
1503
1504         /* TS_RFX_ICAP (RLGR3) */
1505         stream_write_uint16(s, CLW_VERSION_1_0); /* version */
1506         stream_write_uint16(s, CT_TILE_64x64); /* tileSize */
1507         stream_write_uint8(s, codecMode); /* flags */
1508         stream_write_uint8(s, CLW_COL_CONV_ICT); /* colConvBits */
1509         stream_write_uint8(s, CLW_XFORM_DWT_53_A); /* transformBits */
1510         stream_write_uint8(s, CLW_ENTROPY_RLGR3); /* entropyBits */
1511 }
1512
1513 /**
1514  * Write NSCODEC Client Capability Container.\n
1515  * @param s stream
1516  * @param settings settings
1517  */
1518 void rdp_write_nsc_client_capability_container(STREAM* s, rdpSettings* settings)
1519 {
1520         stream_write_uint16(s, 3); /* codecPropertiesLength */
1521
1522         /* TS_NSCODEC_CAPABILITYSET */
1523         stream_write_uint8(s, 1);  /* fAllowDynamicFidelity */
1524         stream_write_uint8(s, 1);  /* fAllowSubsampling */
1525         stream_write_uint8(s, 3);  /* colorLossLevel */
1526 }
1527
1528 /**
1529  * Write RemoteFX Server Capability Container.\n
1530  * @param s stream
1531  * @param settings settings
1532  */
1533 void rdp_write_rfx_server_capability_container(STREAM* s, rdpSettings* settings)
1534 {
1535         stream_write_uint16(s, 4); /* codecPropertiesLength */
1536         stream_write_uint32(s, 0); /* reserved */
1537 }
1538
1539 /**
1540  * Write NSCODEC Server Capability Container.\n
1541  * @param s stream
1542  * @param settings settings
1543  */
1544 void rdp_write_nsc_server_capability_container(STREAM* s, rdpSettings* settings)
1545 {
1546         stream_write_uint16(s, 4); /* codecPropertiesLength */
1547         stream_write_uint32(s, 0); /* reserved */
1548 }
1549
1550
1551 /**
1552  * Write bitmap codecs capability set.\n
1553  * @msdn{dd891377}
1554  * @param s stream
1555  * @param settings settings
1556  */
1557
1558 void rdp_write_bitmap_codecs_capability_set(STREAM* s, rdpSettings* settings)
1559 {
1560         uint8* header;
1561         uint8 bitmapCodecCount;
1562
1563         header = rdp_capability_set_start(s);
1564
1565         bitmapCodecCount = 0;
1566         if (settings->rfx_codec)
1567                 bitmapCodecCount++;
1568         if (settings->ns_codec)
1569                 bitmapCodecCount++;
1570
1571         stream_write_uint8(s, bitmapCodecCount);
1572
1573         if (settings->rfx_codec)
1574         {
1575                 stream_write(s, CODEC_GUID_REMOTEFX, 16); /* codecGUID */
1576
1577                 if (settings->server_mode)
1578                 {
1579                         stream_write_uint8(s, 0); /* codecID is defined by the client */
1580                         rdp_write_rfx_server_capability_container(s, settings);
1581                 }
1582                 else
1583                 {
1584                         stream_write_uint8(s, CODEC_ID_REMOTEFX); /* codecID */
1585                         rdp_write_rfx_client_capability_container(s, settings);
1586                 }
1587         }
1588         if (settings->ns_codec)
1589         {
1590                 stream_write(s, CODEC_GUID_NSCODEC, 16);
1591                 if (settings->server_mode)
1592                 {
1593                         stream_write_uint8(s, 0); /* codecID is defined by the client */
1594                         rdp_write_nsc_server_capability_container(s, settings);
1595                 }
1596                 else
1597                 {
1598                         stream_write_uint8(s, CODEC_ID_NSCODEC); /* codecID */
1599                         rdp_write_nsc_client_capability_container(s, settings);
1600                 }
1601         }
1602         rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CODECS);
1603 }
1604
1605 /**
1606  * Read frame acknowledge capability set.\n
1607  * @param s stream
1608  * @param settings settings
1609  */
1610
1611 void rdp_read_frame_acknowledge_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
1612 {
1613         stream_seek_uint32(s); /* (4 bytes) */
1614 }
1615
1616 /**
1617  * Write frame acknowledge capability set.\n
1618  * @param s stream
1619  * @param settings settings
1620  */
1621
1622 void rdp_write_frame_acknowledge_capability_set(STREAM* s, rdpSettings* settings)
1623 {
1624         uint8* header;
1625
1626         header = rdp_capability_set_start(s);
1627
1628         stream_write_uint32(s, 2); /* (4 bytes) */
1629
1630         rdp_capability_set_finish(s, header, CAPSET_TYPE_FRAME_ACKNOWLEDGE);
1631 }
1632
1633 boolean rdp_read_capability_sets(STREAM* s, rdpSettings* settings, uint16 numberCapabilities)
1634 {
1635         uint16 type;
1636         uint16 length;
1637         uint8 *bm, *em;
1638
1639         while (numberCapabilities > 0)
1640         {
1641                 stream_get_mark(s, bm);
1642
1643                 rdp_read_capability_set_header(s, &length, &type);
1644                 //printf("%s Capability Set (0x%02X), length:%d\n", CAPSET_TYPE_STRINGS[type], type, length);
1645                 settings->received_caps[type] = true;
1646                 em = bm + length;
1647
1648                 if (stream_get_left(s) < length - 4)
1649                 {
1650                         printf("error processing stream\n");
1651                         return false;
1652                 }
1653
1654                 switch (type)
1655                 {
1656                         case CAPSET_TYPE_GENERAL:
1657                                 rdp_read_general_capability_set(s, length, settings);
1658                                 break;
1659
1660                         case CAPSET_TYPE_BITMAP:
1661                                 rdp_read_bitmap_capability_set(s, length, settings);
1662                                 break;
1663
1664                         case CAPSET_TYPE_ORDER:
1665                                 rdp_read_order_capability_set(s, length, settings);
1666                                 break;
1667
1668                         case CAPSET_TYPE_BITMAP_CACHE:
1669                                 rdp_read_bitmap_cache_capability_set(s, length, settings);
1670                                 break;
1671
1672                         case CAPSET_TYPE_CONTROL:
1673                                 rdp_read_control_capability_set(s, length, settings);
1674                                 break;
1675
1676                         case CAPSET_TYPE_ACTIVATION:
1677                                 rdp_read_window_activation_capability_set(s, length, settings);
1678                                 break;
1679
1680                         case CAPSET_TYPE_POINTER:
1681                                 rdp_read_pointer_capability_set(s, length, settings);
1682                                 break;
1683
1684                         case CAPSET_TYPE_SHARE:
1685                                 rdp_read_share_capability_set(s, length, settings);
1686                                 break;
1687
1688                         case CAPSET_TYPE_COLOR_CACHE:
1689                                 rdp_read_color_cache_capability_set(s, length, settings);
1690                                 break;
1691
1692                         case CAPSET_TYPE_SOUND:
1693                                 rdp_read_sound_capability_set(s, length, settings);
1694                                 break;
1695
1696                         case CAPSET_TYPE_INPUT:
1697                                 rdp_read_input_capability_set(s, length, settings);
1698                                 break;
1699
1700                         case CAPSET_TYPE_FONT:
1701                                 rdp_read_font_capability_set(s, length, settings);
1702                                 break;
1703
1704                         case CAPSET_TYPE_BRUSH:
1705                                 rdp_read_brush_capability_set(s, length, settings);
1706                                 break;
1707
1708                         case CAPSET_TYPE_GLYPH_CACHE:
1709                                 rdp_read_glyph_cache_capability_set(s, length, settings);
1710                                 break;
1711
1712                         case CAPSET_TYPE_OFFSCREEN_CACHE:
1713                                 rdp_read_offscreen_bitmap_cache_capability_set(s, length, settings);
1714                                 break;
1715
1716                         case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
1717                                 rdp_read_bitmap_cache_host_support_capability_set(s, length, settings);
1718                                 break;
1719
1720                         case CAPSET_TYPE_BITMAP_CACHE_V2:
1721                                 rdp_read_bitmap_cache_v2_capability_set(s, length, settings);
1722                                 break;
1723
1724                         case CAPSET_TYPE_VIRTUAL_CHANNEL:
1725                                 rdp_read_virtual_channel_capability_set(s, length, settings);
1726                                 break;
1727
1728                         case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
1729                                 rdp_read_draw_nine_grid_cache_capability_set(s, length, settings);
1730                                 break;
1731
1732                         case CAPSET_TYPE_DRAW_GDI_PLUS:
1733                                 rdp_read_draw_gdiplus_cache_capability_set(s, length, settings);
1734                                 break;
1735
1736                         case CAPSET_TYPE_RAIL:
1737                                 rdp_read_remote_programs_capability_set(s, length, settings);
1738                                 break;
1739
1740                         case CAPSET_TYPE_WINDOW:
1741                                 rdp_read_window_list_capability_set(s, length, settings);
1742                                 break;
1743
1744                         case CAPSET_TYPE_COMP_DESK:
1745                                 rdp_read_desktop_composition_capability_set(s, length, settings);
1746                                 break;
1747
1748                         case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
1749                                 rdp_read_multifragment_update_capability_set(s, length, settings);
1750                                 break;
1751
1752                         case CAPSET_TYPE_LARGE_POINTER:
1753                                 rdp_read_large_pointer_capability_set(s, length, settings);
1754                                 break;
1755
1756                         case CAPSET_TYPE_SURFACE_COMMANDS:
1757                                 rdp_read_surface_commands_capability_set(s, length, settings);
1758                                 break;
1759
1760                         case CAPSET_TYPE_BITMAP_CODECS:
1761                                 rdp_read_bitmap_codecs_capability_set(s, length, settings);
1762                                 break;
1763
1764                         case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
1765                                 rdp_read_frame_acknowledge_capability_set(s, length, settings);
1766                                 break;
1767
1768                         default:
1769                                 printf("unknown capability type %d\n", type);
1770                                 break;
1771                 }
1772
1773                 if (s->p != em)
1774                 {
1775                         printf("incorrect offset, type:0x%02X actual:%d expected:%d\n",
1776                                 type, (int) (s->p - bm), (int) (em - bm));
1777                 }
1778
1779                 stream_set_mark(s, em);
1780                 numberCapabilities--;
1781         }
1782
1783         return true;
1784 }
1785
1786 boolean rdp_recv_demand_active(rdpRdp* rdp, STREAM* s)
1787 {
1788         uint16 length;
1789         uint16 channelId;
1790         uint16 pduType;
1791         uint16 pduLength;
1792         uint16 pduSource;
1793         uint16 numberCapabilities;
1794         uint16 lengthSourceDescriptor;
1795         uint16 lengthCombinedCapabilities;
1796         uint16 securityFlags;
1797
1798         if (!rdp_read_header(rdp, s, &length, &channelId))
1799                 return false;
1800
1801         if (rdp->disconnect)
1802                 return true;
1803
1804         if (rdp->settings->encryption)
1805         {
1806                 rdp_read_security_header(s, &securityFlags);
1807                 if (securityFlags & SEC_ENCRYPT)
1808                 {
1809                         if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
1810                         {
1811                                 printf("rdp_decrypt failed\n");
1812                                 return false;
1813                         }
1814                 }
1815         }
1816
1817         if (channelId != MCS_GLOBAL_CHANNEL_ID)
1818         {
1819                 printf("channelId bad\n");
1820                 return false;
1821         }
1822
1823         if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource))
1824         {
1825                 printf("rdp_read_share_control_header failed\n");
1826                 return false;
1827         }
1828
1829         rdp->settings->pdu_source = pduSource;
1830
1831         if (pduType != PDU_TYPE_DEMAND_ACTIVE)
1832         {
1833                 printf("pduType bad\n");
1834                 return false;
1835         }
1836
1837         stream_read_uint32(s, rdp->settings->share_id); /* shareId (4 bytes) */
1838         stream_read_uint16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */
1839         stream_read_uint16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */
1840         stream_seek(s, lengthSourceDescriptor); /* sourceDescriptor */
1841         stream_read_uint16(s, numberCapabilities); /* numberCapabilities (2 bytes) */
1842         stream_seek(s, 2); /* pad2Octets (2 bytes) */
1843
1844         /* capabilitySets */
1845         if (!rdp_read_capability_sets(s, rdp->settings, numberCapabilities))
1846         {
1847                 printf("rdp_read_capability_sets failed\n");
1848                 return false;
1849         }
1850
1851         rdp->update->secondary->glyph_v2 = (rdp->settings->glyphSupportLevel > GLYPH_SUPPORT_FULL) ? true : false;
1852
1853         return true;
1854 }
1855
1856 void rdp_write_demand_active(STREAM* s, rdpSettings* settings)
1857 {
1858         uint8 *bm, *em, *lm;
1859         uint16 numberCapabilities;
1860         uint16 lengthCombinedCapabilities;
1861
1862         stream_write_uint32(s, settings->share_id); /* shareId (4 bytes) */
1863         stream_write_uint16(s, 4); /* lengthSourceDescriptor (2 bytes) */
1864
1865         stream_get_mark(s, lm);
1866         stream_seek_uint16(s); /* lengthCombinedCapabilities (2 bytes) */
1867         stream_write(s, "RDP", 4); /* sourceDescriptor */
1868
1869         stream_get_mark(s, bm);
1870         stream_seek_uint16(s); /* numberCapabilities (2 bytes) */
1871         stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */
1872
1873         numberCapabilities = 14;
1874         rdp_write_general_capability_set(s, settings);
1875         rdp_write_bitmap_capability_set(s, settings);
1876         rdp_write_order_capability_set(s, settings);
1877         rdp_write_pointer_capability_set(s, settings);
1878         rdp_write_input_capability_set(s, settings);
1879         rdp_write_virtual_channel_capability_set(s, settings);
1880         rdp_write_bitmap_cache_host_support_capability_set(s, settings);
1881         rdp_write_share_capability_set(s, settings);
1882         rdp_write_font_capability_set(s, settings);
1883         rdp_write_multifragment_update_capability_set(s, settings);
1884         rdp_write_large_pointer_capability_set(s, settings);
1885         rdp_write_desktop_composition_capability_set(s, settings);
1886         rdp_write_surface_commands_capability_set(s, settings);
1887         rdp_write_bitmap_codecs_capability_set(s, settings);
1888
1889         stream_get_mark(s, em);
1890
1891         stream_set_mark(s, lm); /* go back to lengthCombinedCapabilities */
1892         lengthCombinedCapabilities = (em - bm);
1893         stream_write_uint16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */
1894
1895         stream_set_mark(s, bm); /* go back to numberCapabilities */
1896         stream_write_uint16(s, numberCapabilities); /* numberCapabilities (2 bytes) */
1897
1898         stream_set_mark(s, em);
1899
1900         stream_write_uint32(s, 0); /* sessionId */
1901 }
1902
1903 boolean rdp_send_demand_active(rdpRdp* rdp)
1904 {
1905         STREAM* s;
1906
1907         s = rdp_pdu_init(rdp);
1908
1909         rdp->settings->share_id = 0x10000 + rdp->mcs->user_id;
1910
1911         rdp_write_demand_active(s, rdp->settings);
1912
1913         rdp_send_pdu(rdp, s, PDU_TYPE_DEMAND_ACTIVE, rdp->mcs->user_id);
1914
1915         return true;
1916 }
1917
1918 boolean rdp_recv_confirm_active(rdpRdp* rdp, STREAM* s)
1919 {
1920         uint16 length;
1921         uint16 channelId;
1922         uint16 pduType;
1923         uint16 pduLength;
1924         uint16 pduSource;
1925         uint16 lengthSourceDescriptor;
1926         uint16 lengthCombinedCapabilities;
1927         uint16 numberCapabilities;
1928         uint16 securityFlags;
1929
1930         if (!rdp_read_header(rdp, s, &length, &channelId))
1931                 return false;
1932
1933         if (rdp->settings->encryption)
1934         {
1935                 rdp_read_security_header(s, &securityFlags);
1936                 if (securityFlags & SEC_ENCRYPT)
1937                 {
1938                         if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
1939                         {
1940                                 printf("rdp_decrypt failed\n");
1941                                 return false;
1942                         }
1943                 }
1944         }
1945
1946         if (channelId != MCS_GLOBAL_CHANNEL_ID)
1947                 return false;
1948
1949         if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource))
1950                 return false;
1951
1952         rdp->settings->pdu_source = pduSource;
1953
1954         if (pduType != PDU_TYPE_CONFIRM_ACTIVE)
1955                 return false;
1956
1957         stream_seek_uint32(s); /* shareId (4 bytes) */
1958         stream_seek_uint16(s); /* originatorId (2 bytes) */
1959         stream_read_uint16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */
1960         stream_read_uint16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */
1961         stream_seek(s, lengthSourceDescriptor); /* sourceDescriptor */
1962         stream_read_uint16(s, numberCapabilities); /* numberCapabilities (2 bytes) */
1963         stream_seek(s, 2); /* pad2Octets (2 bytes) */
1964
1965         if (!rdp_read_capability_sets(s, rdp->settings, numberCapabilities))
1966                 return false;
1967
1968         return true;
1969 }
1970
1971 void rdp_write_confirm_active(STREAM* s, rdpSettings* settings)
1972 {
1973         uint8 *bm, *em, *lm;
1974         uint16 numberCapabilities;
1975         uint16 lengthSourceDescriptor;
1976         uint16 lengthCombinedCapabilities;
1977
1978         lengthSourceDescriptor = sizeof(SOURCE_DESCRIPTOR);
1979
1980         stream_write_uint32(s, settings->share_id); /* shareId (4 bytes) */
1981         stream_write_uint16(s, 0x03EA); /* originatorId (2 bytes) */
1982         stream_write_uint16(s, lengthSourceDescriptor);/* lengthSourceDescriptor (2 bytes) */
1983
1984         stream_get_mark(s, lm);
1985         stream_seek_uint16(s); /* lengthCombinedCapabilities (2 bytes) */
1986         stream_write(s, SOURCE_DESCRIPTOR, lengthSourceDescriptor); /* sourceDescriptor */
1987
1988         stream_get_mark(s, bm);
1989         stream_seek_uint16(s); /* numberCapabilities (2 bytes) */
1990         stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */
1991
1992         /* Capability Sets */
1993         numberCapabilities = 15;
1994         rdp_write_general_capability_set(s, settings);
1995         rdp_write_bitmap_capability_set(s, settings);
1996         rdp_write_order_capability_set(s, settings);
1997
1998         if (settings->rdp_version >= 5)
1999                 rdp_write_bitmap_cache_v2_capability_set(s, settings);
2000         else
2001                 rdp_write_bitmap_cache_capability_set(s, settings);
2002
2003         rdp_write_pointer_capability_set(s, settings);
2004         rdp_write_input_capability_set(s, settings);
2005         rdp_write_brush_capability_set(s, settings);
2006         rdp_write_glyph_cache_capability_set(s, settings);
2007         rdp_write_virtual_channel_capability_set(s, settings);
2008         rdp_write_sound_capability_set(s, settings);
2009         rdp_write_share_capability_set(s, settings);
2010         rdp_write_font_capability_set(s, settings);
2011         rdp_write_control_capability_set(s, settings);
2012         rdp_write_color_cache_capability_set(s, settings);
2013         rdp_write_window_activation_capability_set(s, settings);
2014
2015         if (settings->offscreen_bitmap_cache)
2016         {
2017                 numberCapabilities++;
2018                 rdp_write_offscreen_bitmap_cache_capability_set(s, settings);
2019         }
2020
2021         if (settings->received_caps[CAPSET_TYPE_LARGE_POINTER])
2022         {
2023                 if (settings->large_pointer)
2024                 {
2025                         numberCapabilities++;
2026                         rdp_write_large_pointer_capability_set(s, settings);
2027                 }
2028         }
2029
2030         if (settings->remote_app)
2031         {
2032                 numberCapabilities += 2;
2033                 rdp_write_remote_programs_capability_set(s, settings);
2034                 rdp_write_window_list_capability_set(s, settings);
2035         }
2036
2037         if (settings->received_caps[CAPSET_TYPE_MULTI_FRAGMENT_UPDATE])
2038         {
2039                 numberCapabilities++;
2040                 rdp_write_multifragment_update_capability_set(s, settings);
2041         }
2042
2043         if (settings->received_caps[CAPSET_TYPE_SURFACE_COMMANDS])
2044         {
2045                 numberCapabilities++;
2046                 rdp_write_surface_commands_capability_set(s, settings);
2047         }
2048
2049         if (settings->received_caps[CAPSET_TYPE_BITMAP_CODECS])
2050         {
2051                 numberCapabilities++;
2052                 rdp_write_bitmap_codecs_capability_set(s, settings);
2053         }
2054
2055         if (settings->received_caps[CAPSET_TYPE_FRAME_ACKNOWLEDGE])
2056         {
2057                 if (settings->frame_acknowledge)
2058                 {
2059                         numberCapabilities++;
2060                         rdp_write_frame_acknowledge_capability_set(s, settings);
2061                 }
2062         }
2063
2064         stream_get_mark(s, em);
2065
2066         stream_set_mark(s, lm); /* go back to lengthCombinedCapabilities */
2067         lengthCombinedCapabilities = (em - bm);
2068         stream_write_uint16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */
2069
2070         stream_set_mark(s, bm); /* go back to numberCapabilities */
2071         stream_write_uint16(s, numberCapabilities); /* numberCapabilities (2 bytes) */
2072
2073         stream_set_mark(s, em);
2074 }
2075
2076 boolean rdp_send_confirm_active(rdpRdp* rdp)
2077 {
2078         STREAM* s;
2079
2080         s = rdp_pdu_init(rdp);
2081
2082         rdp_write_confirm_active(s, rdp->settings);
2083
2084         return rdp_send_pdu(rdp, s, PDU_TYPE_CONFIRM_ACTIVE, rdp->mcs->user_id);
2085 }
2086