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 "capabilities.h"
23 static const char* const CAPSET_TYPE_STRINGS[] =
42 "Offscreen Bitmap Cache",
43 "Bitmap Cache Host Support",
50 "Desktop Composition",
51 "Multifragment Update",
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"
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"
65 void rdp_read_capability_set_header(STREAM* s, uint16* length, uint16* type)
67 stream_read_uint16(s, *type); /* capabilitySetType */
68 stream_read_uint16(s, *length); /* lengthCapability */
71 void rdp_write_capability_set_header(STREAM* s, uint16 length, uint16 type)
73 stream_write_uint16(s, type); /* capabilitySetType */
74 stream_write_uint16(s, length); /* lengthCapability */
77 uint8* rdp_capability_set_start(STREAM* s)
81 stream_get_mark(s, header);
82 stream_write_zero(s, CAPSET_HEADER_LENGTH);
87 void rdp_capability_set_finish(STREAM* s, uint8* header, uint16 type)
93 length = footer - header;
94 stream_set_mark(s, header);
96 rdp_write_capability_set_header(s, length, type);
97 stream_set_mark(s, footer);
101 * Read general capability set.\n
104 * @param settings settings
107 void rdp_read_general_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
110 uint8 refreshRectSupport;
111 uint8 suppressOutputSupport;
113 if (settings->server_mode)
115 stream_read_uint16(s, settings->os_major_type); /* osMajorType (2 bytes) */
116 stream_read_uint16(s, settings->os_minor_type); /* osMinorType (2 bytes) */
120 stream_seek_uint16(s); /* osMajorType (2 bytes) */
121 stream_seek_uint16(s); /* osMinorType (2 bytes) */
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) */
133 if (!(extraFlags & FASTPATH_OUTPUT_SUPPORTED))
134 settings->fastpath_output = false;
136 if (refreshRectSupport == false)
137 settings->refresh_rect = false;
139 if (suppressOutputSupport == false)
140 settings->suppress_output = false;
144 * Write general capability set.\n
147 * @param settings settings
150 void rdp_write_general_capability_set(STREAM* s, rdpSettings* settings)
155 header = rdp_capability_set_start(s);
157 extraFlags = LONG_CREDENTIALS_SUPPORTED | NO_BITMAP_COMPRESSION_HDR;
159 if (settings->auto_reconnection)
160 extraFlags |= AUTORECONNECT_SUPPORTED;
162 if (settings->fastpath_output)
163 extraFlags |= FASTPATH_OUTPUT_SUPPORTED;
165 if (settings->server_mode)
167 /* not yet supported server-side */
168 settings->refresh_rect = false;
169 settings->suppress_output = false;
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) */
184 rdp_capability_set_finish(s, header, CAPSET_TYPE_GENERAL);
188 * Read bitmap capability set.\n
191 * @param settings settings
194 void rdp_read_bitmap_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
198 uint16 desktopHeight;
199 uint16 desktopResizeFlag;
200 uint16 preferredBitsPerPixel;
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) */
216 if (!settings->server_mode && preferredBitsPerPixel != settings->color_depth)
218 /* The client must respect the actual color depth used by the server */
219 settings->color_depth = preferredBitsPerPixel;
222 if (desktopResizeFlag == false)
223 settings->desktop_resize = false;
225 if (!settings->server_mode && settings->desktop_resize)
227 /* The server may request a different desktop size during Deactivation-Reactivation sequence */
228 settings->width = desktopWidth;
229 settings->height = desktopHeight;
234 * Write bitmap capability set.\n
237 * @param settings settings
240 void rdp_write_bitmap_capability_set(STREAM* s, rdpSettings* settings)
244 uint16 desktopResizeFlag;
245 uint16 preferredBitsPerPixel;
247 header = rdp_capability_set_start(s);
251 if (settings->rdp_version > 5)
252 preferredBitsPerPixel = settings->color_depth;
254 preferredBitsPerPixel = 8;
256 desktopResizeFlag = settings->desktop_resize;
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) */
272 rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP);
276 * Read order capability set.\n
279 * @param settings settings
282 void rdp_read_order_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
286 uint8 orderSupport[32];
287 uint16 orderSupportExFlags;
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) */
307 for (i = 0; i < 32; i++)
309 if (orderSupport[i] == false)
310 settings->order_support[i] = false;
315 * Write order capability set.\n
318 * @param settings settings
321 void rdp_write_order_capability_set(STREAM* s, rdpSettings* settings)
325 uint16 orderSupportExFlags;
326 uint16 textANSICodePage;
328 header = rdp_capability_set_start(s);
330 /* see [MSDN-CP]: http://msdn.microsoft.com/en-us/library/dd317756 */
331 textANSICodePage = 65001; /* Unicode (UTF-8) */
333 orderSupportExFlags = 0;
334 orderFlags = NEGOTIATE_ORDER_SUPPORT | ZERO_BOUNDS_DELTA_SUPPORT | COLOR_INDEX_SUPPORT;
336 if (settings->bitmap_cache_v3)
338 orderSupportExFlags |= CACHE_BITMAP_V3_SUPPORT;
339 orderFlags |= ORDER_FLAGS_EXTRA_SUPPORT;
342 if (settings->frame_marker)
344 orderSupportExFlags |= ALTSEC_FRAME_MARKER_SUPPORT;
345 orderFlags |= ORDER_FLAGS_EXTRA_SUPPORT;
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) */
366 rdp_capability_set_finish(s, header, CAPSET_TYPE_ORDER);
370 * Read bitmap cache capability set.\n
373 * @param settings settings
376 void rdp_read_bitmap_cache_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
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) */
393 * Write bitmap cache capability set.\n
396 * @param settings settings
399 void rdp_write_bitmap_cache_capability_set(STREAM* s, rdpSettings* settings)
405 header = rdp_capability_set_start(s);
407 bpp = (settings->color_depth + 7) / 8;
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) */
417 stream_write_uint16(s, 200); /* Cache0Entries (2 bytes) */
418 stream_write_uint16(s, size); /* Cache0MaximumCellSize (2 bytes) */
421 stream_write_uint16(s, 600); /* Cache1Entries (2 bytes) */
422 stream_write_uint16(s, size); /* Cache1MaximumCellSize (2 bytes) */
425 stream_write_uint16(s, 1000); /* Cache2Entries (2 bytes) */
426 stream_write_uint16(s, size); /* Cache2MaximumCellSize (2 bytes) */
428 rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE);
432 * Read control capability set.\n
435 * @param settings settings
438 void rdp_read_control_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
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) */
447 * Write control capability set.\n
450 * @param settings settings
453 void rdp_write_control_capability_set(STREAM* s, rdpSettings* settings)
457 header = rdp_capability_set_start(s);
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) */
464 rdp_capability_set_finish(s, header, CAPSET_TYPE_CONTROL);
468 * Read window activation capability set.\n
471 * @param settings settings
474 void rdp_read_window_activation_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
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) */
483 * Write window activation capability set.\n
486 * @param settings settings
489 void rdp_write_window_activation_capability_set(STREAM* s, rdpSettings* settings)
493 header = rdp_capability_set_start(s);
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) */
500 rdp_capability_set_finish(s, header, CAPSET_TYPE_ACTIVATION);
504 * Read pointer capability set.\n
507 * @param settings settings
510 void rdp_read_pointer_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
512 uint16 colorPointerFlag;
513 uint16 colorPointerCacheSize;
514 uint16 pointerCacheSize;
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) */
520 if (colorPointerFlag == false)
521 settings->color_pointer = false;
523 if (settings->server_mode)
525 settings->pointer_cache_size = pointerCacheSize;
530 * Write pointer capability set.\n
533 * @param settings settings
536 void rdp_write_pointer_capability_set(STREAM* s, rdpSettings* settings)
539 uint16 colorPointerFlag;
541 header = rdp_capability_set_start(s);
543 colorPointerFlag = (settings->color_pointer) ? 1 : 0;
545 stream_write_uint16(s, colorPointerFlag); /* colorPointerFlag (2 bytes) */
546 stream_write_uint16(s, settings->pointer_cache_size); /* colorPointerCacheSize (2 bytes) */
548 if (settings->large_pointer)
550 stream_write_uint16(s, settings->pointer_cache_size); /* pointerCacheSize (2 bytes) */
553 rdp_capability_set_finish(s, header, CAPSET_TYPE_POINTER);
557 * Read share capability set.\n
560 * @param settings settings
563 void rdp_read_share_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
565 stream_seek_uint16(s); /* nodeId (2 bytes) */
566 stream_seek_uint16(s); /* pad2Octets (2 bytes) */
570 * Write share capability set.\n
573 * @param settings settings
576 void rdp_write_share_capability_set(STREAM* s, rdpSettings* settings)
581 header = rdp_capability_set_start(s);
583 nodeId = (settings->server_mode) ? 0x03EA : 0;
585 stream_write_uint16(s, nodeId); /* nodeId (2 bytes) */
586 stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */
588 rdp_capability_set_finish(s, header, CAPSET_TYPE_SHARE);
592 * Read color cache capability set.\n
595 * @param settings settings
598 void rdp_read_color_cache_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
600 stream_seek_uint16(s); /* colorTableCacheSize (2 bytes) */
601 stream_seek_uint16(s); /* pad2Octets (2 bytes) */
605 * Write color cache capability set.\n
608 * @param settings settings
611 void rdp_write_color_cache_capability_set(STREAM* s, rdpSettings* settings)
615 header = rdp_capability_set_start(s);
617 stream_write_uint16(s, 6); /* colorTableCacheSize (2 bytes) */
618 stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */
620 rdp_capability_set_finish(s, header, CAPSET_TYPE_COLOR_CACHE);
624 * Read sound capability set.\n
627 * @param settings settings
630 void rdp_read_sound_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
634 stream_read_uint16(s, soundFlags); /* soundFlags (2 bytes) */
635 stream_seek_uint16(s); /* pad2OctetsA (2 bytes) */
637 settings->sound_beeps = (soundFlags & SOUND_BEEPS_FLAG) ? true : false;
641 * Write sound capability set.\n
644 * @param settings settings
647 void rdp_write_sound_capability_set(STREAM* s, rdpSettings* settings)
652 header = rdp_capability_set_start(s);
654 soundFlags = (settings->sound_beeps) ? SOUND_BEEPS_FLAG : 0;
656 stream_write_uint16(s, soundFlags); /* soundFlags (2 bytes) */
657 stream_write_uint16(s, 0); /* pad2OctetsA (2 bytes) */
659 rdp_capability_set_finish(s, header, CAPSET_TYPE_SOUND);
663 * Read input capability set.\n
666 * @param settings settings
669 void rdp_read_input_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
673 stream_read_uint16(s, inputFlags); /* inputFlags (2 bytes) */
674 stream_seek_uint16(s); /* pad2OctetsA (2 bytes) */
676 if (settings->server_mode)
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) */
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) */
691 stream_seek(s, 64); /* imeFileName (64 bytes) */
693 if (settings->server_mode != true)
695 if (inputFlags & INPUT_FLAG_FASTPATH_INPUT)
697 /* advertised by RDP 5.0 and 5.1 servers */
699 else if (inputFlags & INPUT_FLAG_FASTPATH_INPUT2)
701 /* avertised by RDP 5.2, 6.0, 6.1 and 7.0 servers */
705 /* server does not support fastpath input */
706 settings->fastpath_input = false;
712 * Write input capability set.\n
715 * @param settings settings
718 void rdp_write_input_capability_set(STREAM* s, rdpSettings* settings)
723 header = rdp_capability_set_start(s);
725 inputFlags = INPUT_FLAG_SCANCODES | INPUT_FLAG_MOUSEX | INPUT_FLAG_UNICODE;
727 if (settings->fastpath_input)
729 inputFlags |= INPUT_FLAG_FASTPATH_INPUT;
730 inputFlags |= INPUT_FLAG_FASTPATH_INPUT2;
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) */
741 rdp_capability_set_finish(s, header, CAPSET_TYPE_INPUT);
745 * Read font capability set.\n
748 * @param settings settings
751 void rdp_read_font_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
754 stream_seek_uint16(s); /* fontSupportFlags (2 bytes) */
757 stream_seek_uint16(s); /* pad2Octets (2 bytes) */
761 * Write font capability set.\n
764 * @param settings settings
767 void rdp_write_font_capability_set(STREAM* s, rdpSettings* settings)
771 header = rdp_capability_set_start(s);
773 stream_write_uint16(s, FONTSUPPORT_FONTLIST); /* fontSupportFlags (2 bytes) */
774 stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */
776 rdp_capability_set_finish(s, header, CAPSET_TYPE_FONT);
780 * Read brush capability set.\n
783 * @param settings settings
786 void rdp_read_brush_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
788 stream_seek_uint32(s); /* brushSupportLevel (4 bytes) */
792 * Write brush capability set.\n
795 * @param settings settings
798 void rdp_write_brush_capability_set(STREAM* s, rdpSettings* settings)
802 header = rdp_capability_set_start(s);
804 stream_write_uint32(s, BRUSH_COLOR_FULL); /* brushSupportLevel (4 bytes) */
806 rdp_capability_set_finish(s, header, CAPSET_TYPE_BRUSH);
810 * Read cache definition (glyph).\n
814 void rdp_read_cache_definition(STREAM* s, GLYPH_CACHE_DEFINITION* cache_definition)
816 stream_read_uint16(s, cache_definition->cacheEntries); /* cacheEntries (2 bytes) */
817 stream_read_uint16(s, cache_definition->cacheMaximumCellSize); /* cacheMaximumCellSize (2 bytes) */
821 * Write cache definition (glyph).\n
825 void rdp_write_cache_definition(STREAM* s, GLYPH_CACHE_DEFINITION* cache_definition)
827 stream_write_uint16(s, cache_definition->cacheEntries); /* cacheEntries (2 bytes) */
828 stream_write_uint16(s, cache_definition->cacheMaximumCellSize); /* cacheMaximumCellSize (2 bytes) */
832 * Read glyph cache capability set.\n
835 * @param settings settings
838 void rdp_read_glyph_cache_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
840 uint16 glyphSupportLevel;
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) */
847 settings->glyphSupportLevel = glyphSupportLevel;
851 * Write glyph cache capability set.\n
854 * @param settings settings
857 void rdp_write_glyph_cache_capability_set(STREAM* s, rdpSettings* settings)
861 header = rdp_capability_set_start(s);
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) */
875 rdp_write_cache_definition(s, settings->fragCache); /* fragCache (4 bytes) */
877 stream_write_uint16(s, settings->glyphSupportLevel); /* glyphSupportLevel (2 bytes) */
879 stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */
881 rdp_capability_set_finish(s, header, CAPSET_TYPE_GLYPH_CACHE);
885 * Read offscreen bitmap cache capability set.\n
888 * @param settings settings
891 void rdp_read_offscreen_bitmap_cache_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
893 uint32 offscreenSupportLevel;
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) */
899 if (offscreenSupportLevel & true)
900 settings->offscreen_bitmap_cache = true;
904 * Write offscreen bitmap cache capability set.\n
907 * @param settings settings
910 void rdp_write_offscreen_bitmap_cache_capability_set(STREAM* s, rdpSettings* settings)
913 uint32 offscreenSupportLevel = false;
915 header = rdp_capability_set_start(s);
917 if (settings->offscreen_bitmap_cache)
918 offscreenSupportLevel = true;
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) */
924 rdp_capability_set_finish(s, header, CAPSET_TYPE_OFFSCREEN_CACHE);
928 * Read bitmap cache host support capability set.\n
931 * @param settings settings
934 void rdp_read_bitmap_cache_host_support_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
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) */
942 if (cacheVersion & BITMAP_CACHE_V2)
943 settings->persistent_bitmap_cache = true;
947 * Write bitmap cache host support capability set.\n
950 * @param settings settings
953 void rdp_write_bitmap_cache_host_support_capability_set(STREAM* s, rdpSettings* settings)
957 header = rdp_capability_set_start(s);
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) */
963 rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT);
966 void rdp_write_bitmap_cache_cell_info(STREAM* s, BITMAP_CACHE_V2_CELL_INFO* cellInfo)
971 * numEntries is in the first 31 bits, while the last bit (k)
972 * is used to indicate a persistent bitmap cache.
975 info = (cellInfo->numEntries | (cellInfo->persistent << 31));
976 stream_write_uint32(s, info);
980 * Read bitmap cache v2 capability set.\n
983 * @param settings settings
986 void rdp_read_bitmap_cache_v2_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
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) */
1000 * Write bitmap cache v2 capability set.\n
1003 * @param settings settings
1006 void rdp_write_bitmap_cache_v2_capability_set(STREAM* s, rdpSettings* settings)
1011 header = rdp_capability_set_start(s);
1013 cacheFlags = ALLOW_CACHE_WAITING_LIST_FLAG;
1015 if (settings->persistent_bitmap_cache)
1016 cacheFlags |= PERSISTENT_KEYS_EXPECTED_FLAG;
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) */
1028 rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_V2);
1032 * Read virtual channel capability set.\n
1035 * @param settings settings
1038 void rdp_read_virtual_channel_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
1043 stream_read_uint32(s, flags); /* flags (4 bytes) */
1046 stream_read_uint32(s, VCChunkSize); /* VCChunkSize (4 bytes) */
1050 if (settings->server_mode != true)
1051 settings->vc_chunk_size = VCChunkSize;
1055 * Write virtual channel capability set.\n
1058 * @param settings settings
1061 void rdp_write_virtual_channel_capability_set(STREAM* s, rdpSettings* settings)
1066 header = rdp_capability_set_start(s);
1068 flags = (settings->server_mode) ? VCCAPS_COMPR_CS_8K : VCCAPS_NO_COMPR;
1070 stream_write_uint32(s, flags); /* flags (4 bytes) */
1071 stream_write_uint32(s, settings->vc_chunk_size); /* VCChunkSize (4 bytes) */
1073 rdp_capability_set_finish(s, header, CAPSET_TYPE_VIRTUAL_CHANNEL);
1077 * Read drawn nine grid cache capability set.\n
1080 * @param settings settings
1083 void rdp_read_draw_nine_grid_cache_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
1085 uint32 drawNineGridSupportLevel;
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) */
1091 if ((drawNineGridSupportLevel & DRAW_NINEGRID_SUPPORTED) ||
1092 (drawNineGridSupportLevel & DRAW_NINEGRID_SUPPORTED_V2))
1093 settings->draw_nine_grid = true;
1097 * Write drawn nine grid cache capability set.\n
1100 * @param settings settings
1103 void rdp_write_draw_nine_grid_cache_capability_set(STREAM* s, rdpSettings* settings)
1106 uint32 drawNineGridSupportLevel;
1108 header = rdp_capability_set_start(s);
1110 drawNineGridSupportLevel = (settings->draw_nine_grid) ? DRAW_NINEGRID_SUPPORTED : DRAW_NINEGRID_NO_SUPPORT;
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) */
1116 rdp_capability_set_finish(s, header, CAPSET_TYPE_DRAW_NINE_GRID_CACHE);
1119 void rdp_write_gdiplus_cache_entries(STREAM* s, uint16 gce, uint16 bce, uint16 pce, uint16 ice, uint16 ace)
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) */
1128 void rdp_write_gdiplus_cache_chunk_size(STREAM* s, uint16 gccs, uint16 obccs, uint16 opccs, uint16 oiaccs)
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) */
1136 void rdp_write_gdiplus_image_cache_properties(STREAM* s, uint16 oiccs, uint16 oicts, uint16 oicms)
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) */
1144 * Read GDI+ cache capability set.\n
1147 * @param settings settings
1150 void rdp_read_draw_gdiplus_cache_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
1152 uint32 drawGDIPlusSupportLevel;
1153 uint32 drawGdiplusCacheLevel;
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) */
1162 if (drawGDIPlusSupportLevel & DRAW_GDIPLUS_SUPPORTED)
1163 settings->draw_gdi_plus = true;
1165 if (drawGdiplusCacheLevel & DRAW_GDIPLUS_CACHE_LEVEL_ONE)
1166 settings->draw_gdi_plus_cache = true;
1170 * Write GDI+ cache capability set.\n
1173 * @param settings settings
1176 void rdp_write_draw_gdiplus_cache_capability_set(STREAM* s, rdpSettings* settings)
1179 uint32 drawGDIPlusSupportLevel;
1180 uint32 drawGdiplusCacheLevel;
1182 header = rdp_capability_set_start(s);
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;
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) */
1194 rdp_capability_set_finish(s, header, CAPSET_TYPE_DRAW_GDI_PLUS);
1198 * Read remote programs capability set.\n
1201 * @param settings settings
1204 void rdp_read_remote_programs_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
1206 uint32 railSupportLevel;
1208 stream_read_uint32(s, railSupportLevel); /* railSupportLevel (4 bytes) */
1210 if ((railSupportLevel & RAIL_LEVEL_SUPPORTED) == 0)
1212 if (settings->remote_app == true)
1214 /* RemoteApp Failure! */
1215 settings->remote_app = false;
1221 * Write remote programs capability set.\n
1224 * @param settings settings
1227 void rdp_write_remote_programs_capability_set(STREAM* s, rdpSettings* settings)
1230 uint32 railSupportLevel;
1232 header = rdp_capability_set_start(s);
1234 railSupportLevel = RAIL_LEVEL_SUPPORTED;
1236 if (settings->rail_langbar_supported)
1237 railSupportLevel |= RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED;
1239 stream_write_uint32(s, railSupportLevel); /* railSupportLevel (4 bytes) */
1241 rdp_capability_set_finish(s, header, CAPSET_TYPE_RAIL);
1245 * Read window list capability set.\n
1248 * @param settings settings
1251 void rdp_read_window_list_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
1253 stream_seek_uint32(s); /* wndSupportLevel (4 bytes) */
1254 stream_seek_uint8(s); /* numIconCaches (1 byte) */
1255 stream_seek_uint16(s); /* numIconCacheEntries (2 bytes) */
1259 * Write window list capability set.\n
1262 * @param settings settings
1265 void rdp_write_window_list_capability_set(STREAM* s, rdpSettings* settings)
1268 uint32 wndSupportLevel;
1270 header = rdp_capability_set_start(s);
1272 wndSupportLevel = WINDOW_LEVEL_SUPPORTED_EX;
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) */
1278 rdp_capability_set_finish(s, header, CAPSET_TYPE_WINDOW);
1282 * Read desktop composition capability set.\n
1285 * @param settings settings
1288 void rdp_read_desktop_composition_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
1290 stream_seek_uint16(s); /* compDeskSupportLevel (2 bytes) */
1294 * Write desktop composition capability set.\n
1297 * @param settings settings
1300 void rdp_write_desktop_composition_capability_set(STREAM* s, rdpSettings* settings)
1303 uint16 compDeskSupportLevel;
1305 header = rdp_capability_set_start(s);
1307 compDeskSupportLevel = (settings->desktop_composition) ? COMPDESK_SUPPORTED : COMPDESK_NOT_SUPPORTED;
1309 stream_write_uint16(s, compDeskSupportLevel); /* compDeskSupportLevel (2 bytes) */
1311 rdp_capability_set_finish(s, header, CAPSET_TYPE_COMP_DESK);
1315 * Read multifragment update capability set.\n
1318 * @param settings settings
1321 void rdp_read_multifragment_update_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
1323 stream_read_uint32(s, settings->multifrag_max_request_size); /* MaxRequestSize (4 bytes) */
1327 * Write multifragment update capability set.\n
1330 * @param settings settings
1333 void rdp_write_multifragment_update_capability_set(STREAM* s, rdpSettings* settings)
1337 header = rdp_capability_set_start(s);
1339 stream_write_uint32(s, settings->multifrag_max_request_size); /* MaxRequestSize (4 bytes) */
1341 rdp_capability_set_finish(s, header, CAPSET_TYPE_MULTI_FRAGMENT_UPDATE);
1345 * Read large pointer capability set.\n
1348 * @param settings settings
1351 void rdp_read_large_pointer_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
1353 stream_seek_uint16(s); /* largePointerSupportFlags (2 bytes) */
1357 * Write large pointer capability set.\n
1360 * @param settings settings
1363 void rdp_write_large_pointer_capability_set(STREAM* s, rdpSettings* settings)
1366 uint16 largePointerSupportFlags;
1368 header = rdp_capability_set_start(s);
1370 largePointerSupportFlags = (settings->large_pointer) ? LARGE_POINTER_FLAG_96x96 : 0;
1372 stream_write_uint16(s, largePointerSupportFlags); /* largePointerSupportFlags (2 bytes) */
1374 rdp_capability_set_finish(s, header, CAPSET_TYPE_LARGE_POINTER);
1378 * Read surface commands capability set.\n
1381 * @param settings settings
1384 void rdp_read_surface_commands_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
1386 stream_seek_uint32(s); /* cmdFlags (4 bytes) */
1387 stream_seek_uint32(s); /* reserved (4 bytes) */
1389 settings->surface_commands = true;
1393 * Write surface commands capability set.\n
1396 * @param settings settings
1399 void rdp_write_surface_commands_capability_set(STREAM* s, rdpSettings* settings)
1404 header = rdp_capability_set_start(s);
1406 cmdFlags = SURFCMDS_FRAME_MARKER |
1407 SURFCMDS_SET_SURFACE_BITS |
1408 SURFCMDS_STREAM_SURFACE_BITS;
1410 stream_write_uint32(s, cmdFlags); /* cmdFlags (4 bytes) */
1411 stream_write_uint32(s, 0); /* reserved (4 bytes) */
1413 rdp_capability_set_finish(s, header, CAPSET_TYPE_SURFACE_COMMANDS);
1417 * Read bitmap codecs capability set.\n
1420 * @param settings settings
1423 void rdp_read_bitmap_codecs_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
1425 uint8 bitmapCodecCount;
1426 uint16 codecPropertiesLength;
1428 stream_read_uint8(s, bitmapCodecCount); /* bitmapCodecCount (1 byte) */
1430 if (settings->server_mode)
1432 settings->rfx_codec = false;
1433 settings->ns_codec = false;
1436 while (bitmapCodecCount > 0)
1438 if (settings->server_mode && strncmp((char*)stream_get_tail(s), CODEC_GUID_REMOTEFX, 16) == 0)
1440 stream_seek(s, 16); /* codecGUID (16 bytes) */
1441 stream_read_uint8(s, settings->rfx_codec_id);
1442 settings->rfx_codec = true;
1444 else if (settings->server_mode && strncmp((char*)stream_get_tail(s),CODEC_GUID_NSCODEC, 16) == 0)
1446 stream_seek(s, 16); /*codec GUID (16 bytes) */
1447 stream_read_uint8(s, settings->ns_codec_id);
1448 settings->ns_codec = true;
1452 stream_seek(s, 16); /* codecGUID (16 bytes) */
1453 stream_seek_uint8(s); /* codecID (1 byte) */
1456 stream_read_uint16(s, codecPropertiesLength); /* codecPropertiesLength (2 bytes) */
1457 stream_seek(s, codecPropertiesLength); /* codecProperties */
1464 * Write RemoteFX Client Capability Container.\n
1466 * @param settings settings
1468 void rdp_write_rfx_client_capability_container(STREAM* s, rdpSettings* settings)
1470 uint32 captureFlags;
1473 captureFlags = settings->dump_rfx ? 0 : CARDP_CAPS_CAPTURE_NON_CAC;
1474 codecMode = settings->rfx_codec_mode;
1476 stream_write_uint16(s, 49); /* codecPropertiesLength */
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 */
1484 stream_write_uint16(s, CBY_CAPS); /* blockType */
1485 stream_write_uint32(s, 8); /* blockLen */
1486 stream_write_uint16(s, 1); /* numCapsets */
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 */
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 */
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 */
1514 * Write NSCODEC Client Capability Container.\n
1516 * @param settings settings
1518 void rdp_write_nsc_client_capability_container(STREAM* s, rdpSettings* settings)
1520 stream_write_uint16(s, 3); /* codecPropertiesLength */
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 */
1529 * Write RemoteFX Server Capability Container.\n
1531 * @param settings settings
1533 void rdp_write_rfx_server_capability_container(STREAM* s, rdpSettings* settings)
1535 stream_write_uint16(s, 4); /* codecPropertiesLength */
1536 stream_write_uint32(s, 0); /* reserved */
1540 * Write NSCODEC Server Capability Container.\n
1542 * @param settings settings
1544 void rdp_write_nsc_server_capability_container(STREAM* s, rdpSettings* settings)
1546 stream_write_uint16(s, 4); /* codecPropertiesLength */
1547 stream_write_uint32(s, 0); /* reserved */
1552 * Write bitmap codecs capability set.\n
1555 * @param settings settings
1558 void rdp_write_bitmap_codecs_capability_set(STREAM* s, rdpSettings* settings)
1561 uint8 bitmapCodecCount;
1563 header = rdp_capability_set_start(s);
1565 bitmapCodecCount = 0;
1566 if (settings->rfx_codec)
1568 if (settings->ns_codec)
1571 stream_write_uint8(s, bitmapCodecCount);
1573 if (settings->rfx_codec)
1575 stream_write(s, CODEC_GUID_REMOTEFX, 16); /* codecGUID */
1577 if (settings->server_mode)
1579 stream_write_uint8(s, 0); /* codecID is defined by the client */
1580 rdp_write_rfx_server_capability_container(s, settings);
1584 stream_write_uint8(s, CODEC_ID_REMOTEFX); /* codecID */
1585 rdp_write_rfx_client_capability_container(s, settings);
1588 if (settings->ns_codec)
1590 stream_write(s, CODEC_GUID_NSCODEC, 16);
1591 if (settings->server_mode)
1593 stream_write_uint8(s, 0); /* codecID is defined by the client */
1594 rdp_write_nsc_server_capability_container(s, settings);
1598 stream_write_uint8(s, CODEC_ID_NSCODEC); /* codecID */
1599 rdp_write_nsc_client_capability_container(s, settings);
1602 rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CODECS);
1606 * Read frame acknowledge capability set.\n
1608 * @param settings settings
1611 void rdp_read_frame_acknowledge_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
1613 stream_seek_uint32(s); /* (4 bytes) */
1617 * Write frame acknowledge capability set.\n
1619 * @param settings settings
1622 void rdp_write_frame_acknowledge_capability_set(STREAM* s, rdpSettings* settings)
1626 header = rdp_capability_set_start(s);
1628 stream_write_uint32(s, 2); /* (4 bytes) */
1630 rdp_capability_set_finish(s, header, CAPSET_TYPE_FRAME_ACKNOWLEDGE);
1633 boolean rdp_read_capability_sets(STREAM* s, rdpSettings* settings, uint16 numberCapabilities)
1639 while (numberCapabilities > 0)
1641 stream_get_mark(s, bm);
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;
1648 if (stream_get_left(s) < length - 4)
1650 printf("error processing stream\n");
1656 case CAPSET_TYPE_GENERAL:
1657 rdp_read_general_capability_set(s, length, settings);
1660 case CAPSET_TYPE_BITMAP:
1661 rdp_read_bitmap_capability_set(s, length, settings);
1664 case CAPSET_TYPE_ORDER:
1665 rdp_read_order_capability_set(s, length, settings);
1668 case CAPSET_TYPE_BITMAP_CACHE:
1669 rdp_read_bitmap_cache_capability_set(s, length, settings);
1672 case CAPSET_TYPE_CONTROL:
1673 rdp_read_control_capability_set(s, length, settings);
1676 case CAPSET_TYPE_ACTIVATION:
1677 rdp_read_window_activation_capability_set(s, length, settings);
1680 case CAPSET_TYPE_POINTER:
1681 rdp_read_pointer_capability_set(s, length, settings);
1684 case CAPSET_TYPE_SHARE:
1685 rdp_read_share_capability_set(s, length, settings);
1688 case CAPSET_TYPE_COLOR_CACHE:
1689 rdp_read_color_cache_capability_set(s, length, settings);
1692 case CAPSET_TYPE_SOUND:
1693 rdp_read_sound_capability_set(s, length, settings);
1696 case CAPSET_TYPE_INPUT:
1697 rdp_read_input_capability_set(s, length, settings);
1700 case CAPSET_TYPE_FONT:
1701 rdp_read_font_capability_set(s, length, settings);
1704 case CAPSET_TYPE_BRUSH:
1705 rdp_read_brush_capability_set(s, length, settings);
1708 case CAPSET_TYPE_GLYPH_CACHE:
1709 rdp_read_glyph_cache_capability_set(s, length, settings);
1712 case CAPSET_TYPE_OFFSCREEN_CACHE:
1713 rdp_read_offscreen_bitmap_cache_capability_set(s, length, settings);
1716 case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
1717 rdp_read_bitmap_cache_host_support_capability_set(s, length, settings);
1720 case CAPSET_TYPE_BITMAP_CACHE_V2:
1721 rdp_read_bitmap_cache_v2_capability_set(s, length, settings);
1724 case CAPSET_TYPE_VIRTUAL_CHANNEL:
1725 rdp_read_virtual_channel_capability_set(s, length, settings);
1728 case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
1729 rdp_read_draw_nine_grid_cache_capability_set(s, length, settings);
1732 case CAPSET_TYPE_DRAW_GDI_PLUS:
1733 rdp_read_draw_gdiplus_cache_capability_set(s, length, settings);
1736 case CAPSET_TYPE_RAIL:
1737 rdp_read_remote_programs_capability_set(s, length, settings);
1740 case CAPSET_TYPE_WINDOW:
1741 rdp_read_window_list_capability_set(s, length, settings);
1744 case CAPSET_TYPE_COMP_DESK:
1745 rdp_read_desktop_composition_capability_set(s, length, settings);
1748 case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
1749 rdp_read_multifragment_update_capability_set(s, length, settings);
1752 case CAPSET_TYPE_LARGE_POINTER:
1753 rdp_read_large_pointer_capability_set(s, length, settings);
1756 case CAPSET_TYPE_SURFACE_COMMANDS:
1757 rdp_read_surface_commands_capability_set(s, length, settings);
1760 case CAPSET_TYPE_BITMAP_CODECS:
1761 rdp_read_bitmap_codecs_capability_set(s, length, settings);
1764 case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
1765 rdp_read_frame_acknowledge_capability_set(s, length, settings);
1769 printf("unknown capability type %d\n", type);
1775 printf("incorrect offset, type:0x%02X actual:%d expected:%d\n",
1776 type, (int) (s->p - bm), (int) (em - bm));
1779 stream_set_mark(s, em);
1780 numberCapabilities--;
1786 boolean rdp_recv_demand_active(rdpRdp* rdp, STREAM* s)
1793 uint16 numberCapabilities;
1794 uint16 lengthSourceDescriptor;
1795 uint16 lengthCombinedCapabilities;
1796 uint16 securityFlags;
1798 if (!rdp_read_header(rdp, s, &length, &channelId))
1801 if (rdp->disconnect)
1804 if (rdp->settings->encryption)
1806 rdp_read_security_header(s, &securityFlags);
1807 if (securityFlags & SEC_ENCRYPT)
1809 if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
1811 printf("rdp_decrypt failed\n");
1817 if (channelId != MCS_GLOBAL_CHANNEL_ID)
1819 printf("channelId bad\n");
1823 if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource))
1825 printf("rdp_read_share_control_header failed\n");
1829 rdp->settings->pdu_source = pduSource;
1831 if (pduType != PDU_TYPE_DEMAND_ACTIVE)
1833 printf("pduType bad\n");
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) */
1844 /* capabilitySets */
1845 if (!rdp_read_capability_sets(s, rdp->settings, numberCapabilities))
1847 printf("rdp_read_capability_sets failed\n");
1851 rdp->update->secondary->glyph_v2 = (rdp->settings->glyphSupportLevel > GLYPH_SUPPORT_FULL) ? true : false;
1856 void rdp_write_demand_active(STREAM* s, rdpSettings* settings)
1858 uint8 *bm, *em, *lm;
1859 uint16 numberCapabilities;
1860 uint16 lengthCombinedCapabilities;
1862 stream_write_uint32(s, settings->share_id); /* shareId (4 bytes) */
1863 stream_write_uint16(s, 4); /* lengthSourceDescriptor (2 bytes) */
1865 stream_get_mark(s, lm);
1866 stream_seek_uint16(s); /* lengthCombinedCapabilities (2 bytes) */
1867 stream_write(s, "RDP", 4); /* sourceDescriptor */
1869 stream_get_mark(s, bm);
1870 stream_seek_uint16(s); /* numberCapabilities (2 bytes) */
1871 stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */
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);
1889 stream_get_mark(s, em);
1891 stream_set_mark(s, lm); /* go back to lengthCombinedCapabilities */
1892 lengthCombinedCapabilities = (em - bm);
1893 stream_write_uint16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */
1895 stream_set_mark(s, bm); /* go back to numberCapabilities */
1896 stream_write_uint16(s, numberCapabilities); /* numberCapabilities (2 bytes) */
1898 stream_set_mark(s, em);
1900 stream_write_uint32(s, 0); /* sessionId */
1903 boolean rdp_send_demand_active(rdpRdp* rdp)
1907 s = rdp_pdu_init(rdp);
1909 rdp->settings->share_id = 0x10000 + rdp->mcs->user_id;
1911 rdp_write_demand_active(s, rdp->settings);
1913 rdp_send_pdu(rdp, s, PDU_TYPE_DEMAND_ACTIVE, rdp->mcs->user_id);
1918 boolean rdp_recv_confirm_active(rdpRdp* rdp, STREAM* s)
1925 uint16 lengthSourceDescriptor;
1926 uint16 lengthCombinedCapabilities;
1927 uint16 numberCapabilities;
1928 uint16 securityFlags;
1930 if (!rdp_read_header(rdp, s, &length, &channelId))
1933 if (rdp->settings->encryption)
1935 rdp_read_security_header(s, &securityFlags);
1936 if (securityFlags & SEC_ENCRYPT)
1938 if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
1940 printf("rdp_decrypt failed\n");
1946 if (channelId != MCS_GLOBAL_CHANNEL_ID)
1949 if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource))
1952 rdp->settings->pdu_source = pduSource;
1954 if (pduType != PDU_TYPE_CONFIRM_ACTIVE)
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) */
1965 if (!rdp_read_capability_sets(s, rdp->settings, numberCapabilities))
1971 void rdp_write_confirm_active(STREAM* s, rdpSettings* settings)
1973 uint8 *bm, *em, *lm;
1974 uint16 numberCapabilities;
1975 uint16 lengthSourceDescriptor;
1976 uint16 lengthCombinedCapabilities;
1978 lengthSourceDescriptor = sizeof(SOURCE_DESCRIPTOR);
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) */
1984 stream_get_mark(s, lm);
1985 stream_seek_uint16(s); /* lengthCombinedCapabilities (2 bytes) */
1986 stream_write(s, SOURCE_DESCRIPTOR, lengthSourceDescriptor); /* sourceDescriptor */
1988 stream_get_mark(s, bm);
1989 stream_seek_uint16(s); /* numberCapabilities (2 bytes) */
1990 stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */
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);
1998 if (settings->rdp_version >= 5)
1999 rdp_write_bitmap_cache_v2_capability_set(s, settings);
2001 rdp_write_bitmap_cache_capability_set(s, settings);
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);
2015 if (settings->offscreen_bitmap_cache)
2017 numberCapabilities++;
2018 rdp_write_offscreen_bitmap_cache_capability_set(s, settings);
2021 if (settings->received_caps[CAPSET_TYPE_LARGE_POINTER])
2023 if (settings->large_pointer)
2025 numberCapabilities++;
2026 rdp_write_large_pointer_capability_set(s, settings);
2030 if (settings->remote_app)
2032 numberCapabilities += 2;
2033 rdp_write_remote_programs_capability_set(s, settings);
2034 rdp_write_window_list_capability_set(s, settings);
2037 if (settings->received_caps[CAPSET_TYPE_MULTI_FRAGMENT_UPDATE])
2039 numberCapabilities++;
2040 rdp_write_multifragment_update_capability_set(s, settings);
2043 if (settings->received_caps[CAPSET_TYPE_SURFACE_COMMANDS])
2045 numberCapabilities++;
2046 rdp_write_surface_commands_capability_set(s, settings);
2049 if (settings->received_caps[CAPSET_TYPE_BITMAP_CODECS])
2051 numberCapabilities++;
2052 rdp_write_bitmap_codecs_capability_set(s, settings);
2055 if (settings->received_caps[CAPSET_TYPE_FRAME_ACKNOWLEDGE])
2057 if (settings->frame_acknowledge)
2059 numberCapabilities++;
2060 rdp_write_frame_acknowledge_capability_set(s, settings);
2064 stream_get_mark(s, em);
2066 stream_set_mark(s, lm); /* go back to lengthCombinedCapabilities */
2067 lengthCombinedCapabilities = (em - bm);
2068 stream_write_uint16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */
2070 stream_set_mark(s, bm); /* go back to numberCapabilities */
2071 stream_write_uint16(s, numberCapabilities); /* numberCapabilities (2 bytes) */
2073 stream_set_mark(s, em);
2076 boolean rdp_send_confirm_active(rdpRdp* rdp)
2080 s = rdp_pdu_init(rdp);
2082 rdp_write_confirm_active(s, rdp->settings);
2084 return rdp_send_pdu(rdp, s, PDU_TYPE_CONFIRM_ACTIVE, rdp->mcs->user_id);