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 = 13;
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_share_capability_set(s, settings);
1881
rdp_write_font_capability_set(s, settings);
1882
rdp_write_multifragment_update_capability_set(s, settings);
1883
rdp_write_large_pointer_capability_set(s, settings);
1884
rdp_write_desktop_composition_capability_set(s, settings);
1885
rdp_write_surface_commands_capability_set(s, settings);
1886
rdp_write_bitmap_codecs_capability_set(s, settings);
1888
if (settings->persistent_bitmap_cache)
1890
numberCapabilities++;
1891
rdp_write_bitmap_cache_host_support_capability_set(s, settings);
1894
stream_get_mark(s, em);
1896
stream_set_mark(s, lm); /* go back to lengthCombinedCapabilities */
1897
lengthCombinedCapabilities = (em - bm);
1898
stream_write_uint16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */
1900
stream_set_mark(s, bm); /* go back to numberCapabilities */
1901
stream_write_uint16(s, numberCapabilities); /* numberCapabilities (2 bytes) */
1903
stream_set_mark(s, em);
1905
stream_write_uint32(s, 0); /* sessionId */
1908
boolean rdp_send_demand_active(rdpRdp* rdp)
1912
s = rdp_pdu_init(rdp);
1914
rdp->settings->share_id = 0x10000 + rdp->mcs->user_id;
1916
rdp_write_demand_active(s, rdp->settings);
1918
rdp_send_pdu(rdp, s, PDU_TYPE_DEMAND_ACTIVE, rdp->mcs->user_id);
1923
boolean rdp_recv_confirm_active(rdpRdp* rdp, STREAM* s)
1930
uint16 lengthSourceDescriptor;
1931
uint16 lengthCombinedCapabilities;
1932
uint16 numberCapabilities;
1933
uint16 securityFlags;
1935
if (!rdp_read_header(rdp, s, &length, &channelId))
1938
if (rdp->settings->encryption)
1940
rdp_read_security_header(s, &securityFlags);
1941
if (securityFlags & SEC_ENCRYPT)
1943
if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
1945
printf("rdp_decrypt failed\n");
1951
if (channelId != MCS_GLOBAL_CHANNEL_ID)
1954
if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource))
1957
rdp->settings->pdu_source = pduSource;
1959
if (pduType != PDU_TYPE_CONFIRM_ACTIVE)
1962
stream_seek_uint32(s); /* shareId (4 bytes) */
1963
stream_seek_uint16(s); /* originatorId (2 bytes) */
1964
stream_read_uint16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */
1965
stream_read_uint16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */
1966
stream_seek(s, lengthSourceDescriptor); /* sourceDescriptor */
1967
stream_read_uint16(s, numberCapabilities); /* numberCapabilities (2 bytes) */
1968
stream_seek(s, 2); /* pad2Octets (2 bytes) */
1970
if (!rdp_read_capability_sets(s, rdp->settings, numberCapabilities))
1976
void rdp_write_confirm_active(STREAM* s, rdpSettings* settings)
1978
uint8 *bm, *em, *lm;
1979
uint16 numberCapabilities;
1980
uint16 lengthSourceDescriptor;
1981
uint16 lengthCombinedCapabilities;
1983
lengthSourceDescriptor = sizeof(SOURCE_DESCRIPTOR);
1985
stream_write_uint32(s, settings->share_id); /* shareId (4 bytes) */
1986
stream_write_uint16(s, 0x03EA); /* originatorId (2 bytes) */
1987
stream_write_uint16(s, lengthSourceDescriptor);/* lengthSourceDescriptor (2 bytes) */
1989
stream_get_mark(s, lm);
1990
stream_seek_uint16(s); /* lengthCombinedCapabilities (2 bytes) */
1991
stream_write(s, SOURCE_DESCRIPTOR, lengthSourceDescriptor); /* sourceDescriptor */
1993
stream_get_mark(s, bm);
1994
stream_seek_uint16(s); /* numberCapabilities (2 bytes) */
1995
stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */
1997
/* Capability Sets */
1998
numberCapabilities = 15;
1999
rdp_write_general_capability_set(s, settings);
2000
rdp_write_bitmap_capability_set(s, settings);
2001
rdp_write_order_capability_set(s, settings);
2003
if (settings->rdp_version >= 5)
2004
rdp_write_bitmap_cache_v2_capability_set(s, settings);
2006
rdp_write_bitmap_cache_capability_set(s, settings);
2008
rdp_write_pointer_capability_set(s, settings);
2009
rdp_write_input_capability_set(s, settings);
2010
rdp_write_brush_capability_set(s, settings);
2011
rdp_write_glyph_cache_capability_set(s, settings);
2012
rdp_write_virtual_channel_capability_set(s, settings);
2013
rdp_write_sound_capability_set(s, settings);
2014
rdp_write_share_capability_set(s, settings);
2015
rdp_write_font_capability_set(s, settings);
2016
rdp_write_control_capability_set(s, settings);
2017
rdp_write_color_cache_capability_set(s, settings);
2018
rdp_write_window_activation_capability_set(s, settings);
2020
if (settings->offscreen_bitmap_cache)
2022
numberCapabilities++;
2023
rdp_write_offscreen_bitmap_cache_capability_set(s, settings);
2026
if (settings->received_caps[CAPSET_TYPE_LARGE_POINTER])
2028
if (settings->large_pointer)
2030
numberCapabilities++;
2031
rdp_write_large_pointer_capability_set(s, settings);
2035
if (settings->remote_app)
2037
numberCapabilities += 2;
2038
rdp_write_remote_programs_capability_set(s, settings);
2039
rdp_write_window_list_capability_set(s, settings);
2042
if (settings->received_caps[CAPSET_TYPE_MULTI_FRAGMENT_UPDATE])
2044
numberCapabilities++;
2045
rdp_write_multifragment_update_capability_set(s, settings);
2048
if (settings->received_caps[CAPSET_TYPE_SURFACE_COMMANDS])
2050
numberCapabilities++;
2051
rdp_write_surface_commands_capability_set(s, settings);
2054
if (settings->received_caps[CAPSET_TYPE_BITMAP_CODECS])
2056
numberCapabilities++;
2057
rdp_write_bitmap_codecs_capability_set(s, settings);
2060
if (settings->received_caps[CAPSET_TYPE_FRAME_ACKNOWLEDGE])
2062
if (settings->frame_acknowledge)
2064
numberCapabilities++;
2065
rdp_write_frame_acknowledge_capability_set(s, settings);
2069
stream_get_mark(s, em);
2071
stream_set_mark(s, lm); /* go back to lengthCombinedCapabilities */
2072
lengthCombinedCapabilities = (em - bm);
2073
stream_write_uint16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */
2075
stream_set_mark(s, bm); /* go back to numberCapabilities */
2076
stream_write_uint16(s, numberCapabilities); /* numberCapabilities (2 bytes) */
2078
stream_set_mark(s, em);
2081
boolean rdp_send_confirm_active(rdpRdp* rdp)
2085
s = rdp_pdu_init(rdp);
2087
rdp_write_confirm_active(s, rdp->settings);
2089
return rdp_send_pdu(rdp, s, PDU_TYPE_CONFIRM_ACTIVE, rdp->mcs->user_id);