20#include <winpr/wtsapi.h>
21#include <winpr/assert.h>
22#include <winpr/cast.h>
23#include <freerdp/config.h>
26#include "capabilities.h"
32#include <freerdp/log.h>
34static const char*
const CAPSET_TYPE_STRINGS[] = {
"Unknown",
51 "Offscreen Bitmap Cache",
52 "Bitmap Cache Host Support",
59 "Desktop Composition",
60 "Multifragment Update",
64 "Frame Acknowledge" };
66static const char* get_capability_name(UINT16 type)
68 if (type > CAPSET_TYPE_FRAME_ACKNOWLEDGE)
71 return CAPSET_TYPE_STRINGS[type];
74#ifdef WITH_DEBUG_CAPABILITIES
75static BOOL rdp_print_capability_sets(wLog* log,
wStream* s,
size_t start, BOOL receiving);
80static const GUID CODEC_GUID_REMOTEFX = {
81 0x76772F12, 0xBD72, 0x4463, { 0xAF, 0xB3, 0xB7, 0x3C, 0x9C, 0x6F, 0x78, 0x86 }
86static const GUID CODEC_GUID_NSCODEC = {
87 0xCA8D1BB9, 0x000F, 0x154F, { 0x58, 0x9F, 0xAE, 0x2D, 0x1A, 0x87, 0xE2, 0xD6 }
92static const GUID CODEC_GUID_IGNORE = {
93 0x9C4351A6, 0x3535, 0x42AE, { 0x91, 0x0C, 0xCD, 0xFC, 0xE5, 0x76, 0x0B, 0x58 }
98static const GUID CODEC_GUID_IMAGE_REMOTEFX = {
99 0x2744CCD4, 0x9D8A, 0x4E74, { 0x80, 0x3C, 0x0E, 0xCB, 0xEE, 0xA1, 0x9C, 0x54 }
102#if defined(WITH_JPEG)
105static const GUID CODEC_GUID_JPEG = {
106 0x430C9EED, 0x1BAF, 0x4CE6, { 0x86, 0x9A, 0xCB, 0x8B, 0x37, 0xB6, 0x62, 0x37 }
110static BOOL rdp_read_capability_set_header(wLog* log,
wStream* s, UINT16* length, UINT16* type)
113 WINPR_ASSERT(length);
116 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
118 Stream_Read_UINT16(s, *type);
119 Stream_Read_UINT16(s, *length);
120 return (*length >= 4);
123static void rdp_write_capability_set_header(
wStream* s, UINT16 length, UINT16 type)
126 WINPR_ASSERT(Stream_GetRemainingCapacity(s) >= 4);
127 Stream_Write_UINT16(s, type);
128 Stream_Write_UINT16(s, length);
131static size_t rdp_capability_set_start(wLog* log,
wStream* s)
133 size_t header = Stream_GetPosition(s);
134 if (!Stream_CheckAndLogRequiredCapacityWLog(log, (s), CAPSET_HEADER_LENGTH))
136 Stream_Zero(s, CAPSET_HEADER_LENGTH);
140static BOOL rdp_capability_set_finish(
wStream* s,
size_t header, UINT16 type)
142 const size_t footer = Stream_GetPosition(s);
145 if (header > UINT16_MAX)
147 const size_t length = footer - header;
148 if ((Stream_Capacity(s) < header + 4ULL) || (length > UINT16_MAX))
150 if (!Stream_SetPosition(s, header))
152 rdp_write_capability_set_header(s, (UINT16)length, type);
153 return Stream_SetPosition(s, footer);
156static BOOL rdp_apply_general_capability_set(rdpSettings* settings,
const rdpSettings* src)
158 WINPR_ASSERT(settings);
161 if (settings->ServerMode)
163 settings->OsMajorType = src->OsMajorType;
164 settings->OsMinorType = src->OsMinorType;
167 settings->CapsProtocolVersion = src->CapsProtocolVersion;
168 settings->NoBitmapCompressionHeader = src->NoBitmapCompressionHeader;
169 settings->LongCredentialsSupported = src->LongCredentialsSupported;
170 settings->AutoReconnectionPacketSupported = src->AutoReconnectionPacketSupported;
171 if (!src->FastPathOutput)
172 settings->FastPathOutput = FALSE;
174 if (!src->SaltedChecksum)
175 settings->SaltedChecksum = FALSE;
177 if (!settings->ServerMode)
184 if (!src->RefreshRect)
185 settings->RefreshRect = FALSE;
187 if (!src->SuppressOutput)
188 settings->SuppressOutput = FALSE;
198static BOOL rdp_read_general_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
200 UINT16 extraFlags = 0;
201 BYTE refreshRectSupport = 0;
202 BYTE suppressOutputSupport = 0;
204 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 20))
207 WINPR_ASSERT(settings);
208 Stream_Read_UINT16(s, settings->OsMajorType);
209 Stream_Read_UINT16(s, settings->OsMinorType);
211 Stream_Read_UINT16(s, settings->CapsProtocolVersion);
212 if (settings->CapsProtocolVersion != TS_CAPS_PROTOCOLVERSION)
214 WLog_Print(log, WLOG_ERROR,
215 "TS_GENERAL_CAPABILITYSET::protocolVersion(0x%04" PRIx16
216 ") != TS_CAPS_PROTOCOLVERSION(0x%04" PRIx32
")",
217 settings->CapsProtocolVersion,
218 WINPR_CXX_COMPAT_CAST(UINT32, TS_CAPS_PROTOCOLVERSION));
219 if (settings->CapsProtocolVersion == 0x0000)
221 WLog_Print(log, WLOG_WARN,
222 "TS_GENERAL_CAPABILITYSET::protocolVersion(0x%04" PRIx16
223 " assuming old FreeRDP, ignoring protocol violation, correcting value.",
224 settings->CapsProtocolVersion);
225 settings->CapsProtocolVersion = TS_CAPS_PROTOCOLVERSION;
230 Stream_Seek_UINT16(s);
232 s, settings->CapsGeneralCompressionTypes);
233 Stream_Read_UINT16(s, extraFlags);
234 Stream_Read_UINT16(s, settings->CapsUpdateCapabilityFlag);
235 Stream_Read_UINT16(s, settings->CapsRemoteUnshareFlag);
237 s, settings->CapsGeneralCompressionLevel);
238 Stream_Read_UINT8(s, refreshRectSupport);
239 Stream_Read_UINT8(s, suppressOutputSupport);
240 settings->NoBitmapCompressionHeader = (extraFlags & NO_BITMAP_COMPRESSION_HDR) != 0;
241 settings->LongCredentialsSupported = (extraFlags & LONG_CREDENTIALS_SUPPORTED) != 0;
243 settings->AutoReconnectionPacketSupported = (extraFlags & AUTORECONNECT_SUPPORTED) != 0;
244 settings->FastPathOutput = (extraFlags & FASTPATH_OUTPUT_SUPPORTED) != 0;
245 settings->SaltedChecksum = (extraFlags & ENC_SALTED_CHECKSUM) != 0;
246 settings->RefreshRect = refreshRectSupport;
247 settings->SuppressOutput = suppressOutputSupport;
257static BOOL rdp_write_general_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
259 if (!Stream_EnsureRemainingCapacity(s, 64))
262 const size_t header = rdp_capability_set_start(log, s);
263 UINT16 extraFlags = 0;
265 WINPR_ASSERT(settings);
266 if (settings->LongCredentialsSupported)
267 extraFlags |= LONG_CREDENTIALS_SUPPORTED;
269 if (settings->NoBitmapCompressionHeader)
270 extraFlags |= NO_BITMAP_COMPRESSION_HDR;
272 if (settings->AutoReconnectionPacketSupported)
273 extraFlags |= AUTORECONNECT_SUPPORTED;
275 if (settings->FastPathOutput)
276 extraFlags |= FASTPATH_OUTPUT_SUPPORTED;
278 if (settings->SaltedChecksum)
279 extraFlags |= ENC_SALTED_CHECKSUM;
281 if ((settings->OsMajorType > UINT16_MAX) || (settings->OsMinorType > UINT16_MAX))
283 WLog_Print(log, WLOG_ERROR,
284 "OsMajorType=%08" PRIx32
", OsMinorType=%08" PRIx32
285 " they need to be smaller %04" PRIx32,
286 settings->OsMajorType, settings->OsMinorType,
287 WINPR_CXX_COMPAT_CAST(UINT32, UINT16_MAX));
290 if (settings->CapsProtocolVersion != TS_CAPS_PROTOCOLVERSION)
292 WLog_Print(log, WLOG_ERROR,
293 "TS_GENERAL_CAPABILITYSET::protocolVersion(0x%04" PRIx16
294 ") != TS_CAPS_PROTOCOLVERSION(0x%04" PRIx32
")",
295 settings->CapsProtocolVersion,
296 WINPR_CXX_COMPAT_CAST(UINT32, TS_CAPS_PROTOCOLVERSION));
299 Stream_Write_UINT16(s, (UINT16)settings->OsMajorType);
300 Stream_Write_UINT16(s, (UINT16)settings->OsMinorType);
301 Stream_Write_UINT16(s, settings->CapsProtocolVersion);
302 Stream_Write_UINT16(s, 0);
304 s, settings->CapsGeneralCompressionTypes);
305 Stream_Write_UINT16(s, extraFlags);
306 Stream_Write_UINT16(s, settings->CapsUpdateCapabilityFlag);
307 Stream_Write_UINT16(s, settings->CapsRemoteUnshareFlag);
309 s, settings->CapsGeneralCompressionLevel);
310 Stream_Write_UINT8(s, settings->RefreshRect ? 1 : 0);
311 Stream_Write_UINT8(s, settings->SuppressOutput ? 1 : 0);
312 return rdp_capability_set_finish(s, header, CAPSET_TYPE_GENERAL);
315#ifdef WITH_DEBUG_CAPABILITIES
316static BOOL rdp_print_general_capability_set(wLog* log,
wStream* s)
318 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 20))
321 WLog_Print(log, WLOG_TRACE,
322 "GeneralCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
323 const uint16_t osMinorType = Stream_Get_UINT16(s);
324 const uint16_t osMajorType = Stream_Get_UINT16(s);
325 const uint16_t protocolVersion = Stream_Get_UINT16(s);
326 const uint16_t pad2OctetsA = Stream_Get_UINT16(s);
327 const uint16_t generalCompressionTypes =
328 Stream_Get_UINT16(s);
329 const uint16_t extraFlags = Stream_Get_UINT16(s);
330 const uint16_t updateCapabilityFlag = Stream_Get_UINT16(s);
331 const uint16_t remoteUnshareFlag = Stream_Get_UINT16(s);
332 const uint16_t generalCompressionLevel =
333 Stream_Get_UINT16(s);
334 const uint8_t refreshRectSupport = Stream_Get_UINT8(s);
335 const uint8_t suppressOutputSupport = Stream_Get_UINT8(s);
336 WLog_Print(log, WLOG_TRACE,
"\tosMajorType: 0x%04" PRIX16
"", osMajorType);
337 WLog_Print(log, WLOG_TRACE,
"\tosMinorType: 0x%04" PRIX16
"", osMinorType);
338 WLog_Print(log, WLOG_TRACE,
"\tprotocolVersion: 0x%04" PRIX16
"", protocolVersion);
339 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
340 WLog_Print(log, WLOG_TRACE,
"\tgeneralCompressionTypes: 0x%04" PRIX16
"",
341 generalCompressionTypes);
342 WLog_Print(log, WLOG_TRACE,
"\textraFlags: 0x%04" PRIX16
"", extraFlags);
343 WLog_Print(log, WLOG_TRACE,
"\tupdateCapabilityFlag: 0x%04" PRIX16
"", updateCapabilityFlag);
344 WLog_Print(log, WLOG_TRACE,
"\tremoteUnshareFlag: 0x%04" PRIX16
"", remoteUnshareFlag);
345 WLog_Print(log, WLOG_TRACE,
"\tgeneralCompressionLevel: 0x%04" PRIX16
"",
346 generalCompressionLevel);
347 WLog_Print(log, WLOG_TRACE,
"\trefreshRectSupport: 0x%02" PRIX8
"", refreshRectSupport);
348 WLog_Print(log, WLOG_TRACE,
"\tsuppressOutputSupport: 0x%02" PRIX8
"", suppressOutputSupport);
352static BOOL rdp_apply_bitmap_capability_set(rdpSettings* settings,
const rdpSettings* src)
354 WINPR_ASSERT(settings);
357 if (!settings->ServerMode)
364 if (!src->DesktopResize)
365 settings->DesktopResize = FALSE;
367 if (!settings->ServerMode && settings->DesktopResize)
371 settings->DesktopWidth = src->DesktopWidth;
372 settings->DesktopHeight = src->DesktopHeight;
375 if (settings->DrawAllowSkipAlpha)
376 settings->DrawAllowSkipAlpha = src->DrawAllowSkipAlpha;
378 if (settings->DrawAllowDynamicColorFidelity)
379 settings->DrawAllowDynamicColorFidelity = src->DrawAllowDynamicColorFidelity;
381 if (settings->DrawAllowColorSubsampling)
382 settings->DrawAllowColorSubsampling = src->DrawAllowColorSubsampling;
392static BOOL rdp_read_bitmap_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
394 BYTE drawingFlags = 0;
395 UINT16 desktopWidth = 0;
396 UINT16 desktopHeight = 0;
397 UINT16 desktopResizeFlag = 0;
398 UINT16 preferredBitsPerPixel = 0;
400 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 24))
403 Stream_Read_UINT16(s, preferredBitsPerPixel);
404 Stream_Seek_UINT16(s);
405 Stream_Seek_UINT16(s);
406 Stream_Seek_UINT16(s);
407 Stream_Read_UINT16(s, desktopWidth);
408 Stream_Read_UINT16(s, desktopHeight);
409 Stream_Seek_UINT16(s);
410 Stream_Read_UINT16(s, desktopResizeFlag);
411 Stream_Seek_UINT16(s);
412 Stream_Seek_UINT8(s);
413 Stream_Read_UINT8(s, drawingFlags);
414 Stream_Seek_UINT16(s);
415 Stream_Seek_UINT16(s);
419 settings->DesktopResize = desktopResizeFlag;
420 settings->DesktopWidth = desktopWidth;
421 settings->DesktopHeight = desktopHeight;
422 settings->DrawAllowSkipAlpha = (drawingFlags & DRAW_ALLOW_SKIP_ALPHA) != 0;
423 settings->DrawAllowDynamicColorFidelity =
424 (drawingFlags & DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY) != 0;
425 settings->DrawAllowColorSubsampling = (drawingFlags & DRAW_ALLOW_COLOR_SUBSAMPLING) != 0;
435static BOOL rdp_write_bitmap_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
437 BYTE drawingFlags = 0;
438 UINT16 preferredBitsPerPixel = 0;
440 if (!Stream_EnsureRemainingCapacity(s, 64))
443 const size_t header = rdp_capability_set_start(log, s);
445 WINPR_ASSERT(settings);
446 if (settings->DrawAllowSkipAlpha)
447 drawingFlags |= DRAW_ALLOW_SKIP_ALPHA;
449 if (settings->DrawAllowDynamicColorFidelity)
450 drawingFlags |= DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY;
452 if (settings->DrawAllowColorSubsampling)
453 drawingFlags |= DRAW_ALLOW_COLOR_SUBSAMPLING;
465 (settings->DesktopWidth > UINT16_MAX) || (settings->DesktopHeight > UINT16_MAX))
468 if (settings->RdpVersion >= RDP_VERSION_5_PLUS)
471 preferredBitsPerPixel = 8;
473 Stream_Write_UINT16(s, preferredBitsPerPixel);
474 Stream_Write_UINT16(s, 1);
475 Stream_Write_UINT16(s, 1);
476 Stream_Write_UINT16(s, 1);
477 Stream_Write_UINT16(s, (UINT16)settings->DesktopWidth);
478 Stream_Write_UINT16(s, (UINT16)settings->DesktopHeight);
479 Stream_Write_UINT16(s, 0);
480 Stream_Write_UINT16(s, (UINT16)settings->DesktopResize);
481 Stream_Write_UINT16(s, 1);
482 Stream_Write_UINT8(s, 0);
483 Stream_Write_UINT8(s, drawingFlags);
484 Stream_Write_UINT16(s, 1);
485 Stream_Write_UINT16(s, 0);
486 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP);
489#ifdef WITH_DEBUG_CAPABILITIES
490static BOOL rdp_print_bitmap_capability_set(wLog* log,
wStream* s)
492 UINT16 preferredBitsPerPixel = 0;
493 UINT16 receive1BitPerPixel = 0;
494 UINT16 receive4BitsPerPixel = 0;
495 UINT16 receive8BitsPerPixel = 0;
496 UINT16 desktopWidth = 0;
497 UINT16 desktopHeight = 0;
498 UINT16 pad2Octets = 0;
499 UINT16 desktopResizeFlag = 0;
500 UINT16 bitmapCompressionFlag = 0;
501 BYTE highColorFlags = 0;
502 BYTE drawingFlags = 0;
503 UINT16 multipleRectangleSupport = 0;
504 UINT16 pad2OctetsB = 0;
505 WLog_Print(log, WLOG_TRACE,
506 "BitmapCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
508 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 24))
511 Stream_Read_UINT16(s, preferredBitsPerPixel);
512 Stream_Read_UINT16(s, receive1BitPerPixel);
513 Stream_Read_UINT16(s, receive4BitsPerPixel);
514 Stream_Read_UINT16(s, receive8BitsPerPixel);
515 Stream_Read_UINT16(s, desktopWidth);
516 Stream_Read_UINT16(s, desktopHeight);
517 Stream_Read_UINT16(s, pad2Octets);
518 Stream_Read_UINT16(s, desktopResizeFlag);
519 Stream_Read_UINT16(s, bitmapCompressionFlag);
520 Stream_Read_UINT8(s, highColorFlags);
521 Stream_Read_UINT8(s, drawingFlags);
522 Stream_Read_UINT16(s, multipleRectangleSupport);
523 Stream_Read_UINT16(s, pad2OctetsB);
524 WLog_Print(log, WLOG_TRACE,
"\tpreferredBitsPerPixel: 0x%04" PRIX16
"", preferredBitsPerPixel);
525 WLog_Print(log, WLOG_TRACE,
"\treceive1BitPerPixel: 0x%04" PRIX16
"", receive1BitPerPixel);
526 WLog_Print(log, WLOG_TRACE,
"\treceive4BitsPerPixel: 0x%04" PRIX16
"", receive4BitsPerPixel);
527 WLog_Print(log, WLOG_TRACE,
"\treceive8BitsPerPixel: 0x%04" PRIX16
"", receive8BitsPerPixel);
528 WLog_Print(log, WLOG_TRACE,
"\tdesktopWidth: 0x%04" PRIX16
"", desktopWidth);
529 WLog_Print(log, WLOG_TRACE,
"\tdesktopHeight: 0x%04" PRIX16
"", desktopHeight);
530 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
531 WLog_Print(log, WLOG_TRACE,
"\tdesktopResizeFlag: 0x%04" PRIX16
"", desktopResizeFlag);
532 WLog_Print(log, WLOG_TRACE,
"\tbitmapCompressionFlag: 0x%04" PRIX16
"", bitmapCompressionFlag);
533 WLog_Print(log, WLOG_TRACE,
"\thighColorFlags: 0x%02" PRIX8
"", highColorFlags);
534 WLog_Print(log, WLOG_TRACE,
"\tdrawingFlags: 0x%02" PRIX8
"", drawingFlags);
535 WLog_Print(log, WLOG_TRACE,
"\tmultipleRectangleSupport: 0x%04" PRIX16
"",
536 multipleRectangleSupport);
537 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsB: 0x%04" PRIX16
"", pad2OctetsB);
541static BOOL rdp_apply_order_capability_set(rdpSettings* settings,
const rdpSettings* src)
543 WINPR_ASSERT(settings);
546 BOOL BitmapCacheV3Enabled = FALSE;
547 BOOL FrameMarkerCommandEnabled = FALSE;
549 for (
size_t i = 0; i < 32; i++)
551 if (!src->OrderSupport[i])
552 settings->OrderSupport[i] = FALSE;
555 if (src->OrderSupportFlags & ORDER_FLAGS_EXTRA_SUPPORT)
557 if (src->OrderSupportFlagsEx & CACHE_BITMAP_V3_SUPPORT)
558 BitmapCacheV3Enabled = TRUE;
560 if (src->OrderSupportFlagsEx & ALTSEC_FRAME_MARKER_SUPPORT)
561 FrameMarkerCommandEnabled = TRUE;
564 if (BitmapCacheV3Enabled && settings->BitmapCacheV3Enabled)
566 settings->BitmapCacheV3Enabled = src->BitmapCacheV3Enabled;
567 settings->BitmapCacheVersion = src->BitmapCacheVersion;
570 settings->BitmapCacheV3Enabled = FALSE;
572 settings->FrameMarkerCommandEnabled =
573 (FrameMarkerCommandEnabled && src->FrameMarkerCommandEnabled);
583static BOOL rdp_read_order_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
585 char terminalDescriptor[17] = WINPR_C_ARRAY_INIT;
586 BYTE orderSupport[32] = WINPR_C_ARRAY_INIT;
587 BOOL BitmapCacheV3Enabled = FALSE;
588 BOOL FrameMarkerCommandEnabled = FALSE;
590 WINPR_ASSERT(settings);
591 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 84))
594 Stream_Read(s, terminalDescriptor, 16);
595 Stream_Seek_UINT32(s);
596 Stream_Seek_UINT16(s);
597 Stream_Seek_UINT16(s);
598 Stream_Seek_UINT16(s);
599 Stream_Seek_UINT16(s);
600 Stream_Seek_UINT16(s);
601 Stream_Read_UINT16(s, settings->OrderSupportFlags);
602 Stream_Read(s, orderSupport, 32);
603 Stream_Seek_UINT16(s);
604 Stream_Read_UINT16(s, settings->OrderSupportFlagsEx);
605 Stream_Seek_UINT32(s);
606 Stream_Seek_UINT32(s);
607 Stream_Seek_UINT16(s);
608 Stream_Seek_UINT16(s);
609 Stream_Read_UINT16(s, settings->TextANSICodePage);
610 Stream_Seek_UINT16(s);
615 for (
size_t i = 0; i < ARRAYSIZE(orderSupport); i++)
616 settings->OrderSupport[i] = orderSupport[i];
618 if (settings->OrderSupportFlags & ORDER_FLAGS_EXTRA_SUPPORT)
620 BitmapCacheV3Enabled = (settings->OrderSupportFlagsEx & CACHE_BITMAP_V3_SUPPORT) != 0;
621 FrameMarkerCommandEnabled =
622 (settings->OrderSupportFlagsEx & ALTSEC_FRAME_MARKER_SUPPORT) != 0;
625 settings->BitmapCacheV3Enabled = BitmapCacheV3Enabled;
626 if (BitmapCacheV3Enabled)
627 settings->BitmapCacheVersion = 3;
629 settings->FrameMarkerCommandEnabled = FrameMarkerCommandEnabled;
639static BOOL rdp_write_order_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
641 char terminalDescriptor[16] = WINPR_C_ARRAY_INIT;
643 WINPR_ASSERT(settings);
644 if (!Stream_EnsureRemainingCapacity(s, 64))
647 const size_t header = rdp_capability_set_start(log, s);
649 UINT16 orderSupportExFlags = settings->OrderSupportFlagsEx;
650 UINT16 orderFlags = settings->OrderSupportFlags;
652 if (settings->BitmapCacheV3Enabled)
654 if ((orderSupportExFlags & CACHE_BITMAP_V3_SUPPORT) == 0)
656 WLog_Print(log, WLOG_WARN,
657 "rdpSettings::BitmapCacheV3Enabled=TRUE, but CACHE_BITMAP_V3_SUPPORT not "
658 "set in rdpSettings::OrderSupportEx, aborting.");
660 if ((orderFlags & ORDER_FLAGS_EXTRA_SUPPORT) == 0)
662 WLog_Print(log, WLOG_WARN,
663 "rdpSettings::BitmapCacheV3Enabled=TRUE, but ORDER_FLAGS_EXTRA_SUPPORT not "
664 "set in rdpSettings::OrderSupport, aborting.");
668 if (settings->FrameMarkerCommandEnabled)
670 if ((orderSupportExFlags & ALTSEC_FRAME_MARKER_SUPPORT) == 0)
674 "rdpSettings::FrameMarkerCommandEnabled=TRUE, but "
675 "ALTSEC_FRAME_MARKER_SUPPORT not set in rdpSettings::OrderSupportEx, aborting.");
677 if ((orderFlags & ORDER_FLAGS_EXTRA_SUPPORT) == 0)
679 WLog_Print(log, WLOG_WARN,
680 "rdpSettings::FrameMarkerCommandEnabled=TRUE, but ORDER_FLAGS_EXTRA_SUPPORT "
681 "not set in rdpSettings::OrderSupport, aborting.");
688 const size_t len = strnlen(dsc, ARRAYSIZE(terminalDescriptor));
689 strncpy(terminalDescriptor, dsc, len);
691 Stream_Write(s, terminalDescriptor,
692 sizeof(terminalDescriptor));
693 Stream_Write_UINT32(s, 0);
694 Stream_Write_UINT16(s, 1);
695 Stream_Write_UINT16(s, 20);
696 Stream_Write_UINT16(s, 0);
697 Stream_Write_UINT16(s, 1);
698 Stream_Write_UINT16(s, 0);
699 Stream_Write_UINT16(s, orderFlags);
700 Stream_Write(s, settings->OrderSupport, 32);
701 Stream_Write_UINT16(s, 0);
702 Stream_Write_UINT16(s, orderSupportExFlags);
703 Stream_Write_UINT32(s, 0);
704 Stream_Write_UINT32(s, 230400);
705 Stream_Write_UINT16(s, 0);
706 Stream_Write_UINT16(s, 0);
707 Stream_Write_UINT16(s, settings->TextANSICodePage);
708 Stream_Write_UINT16(s, 0);
709 return rdp_capability_set_finish(s, header, CAPSET_TYPE_ORDER);
712#ifdef WITH_DEBUG_CAPABILITIES
713static BOOL rdp_print_order_capability_set(wLog* log,
wStream* s)
715 BYTE terminalDescriptor[16];
716 UINT32 pad4OctetsA = 0;
717 UINT16 desktopSaveXGranularity = 0;
718 UINT16 desktopSaveYGranularity = 0;
719 UINT16 pad2OctetsA = 0;
720 UINT16 maximumOrderLevel = 0;
721 UINT16 numberFonts = 0;
722 UINT16 orderFlags = 0;
723 BYTE orderSupport[32];
724 UINT16 textFlags = 0;
725 UINT16 orderSupportExFlags = 0;
726 UINT32 pad4OctetsB = 0;
727 UINT32 desktopSaveSize = 0;
728 UINT16 pad2OctetsC = 0;
729 UINT16 pad2OctetsD = 0;
730 UINT16 textANSICodePage = 0;
731 UINT16 pad2OctetsE = 0;
732 WLog_Print(log, WLOG_TRACE,
733 "OrderCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
735 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 84))
738 Stream_Read(s, terminalDescriptor, 16);
739 Stream_Read_UINT32(s, pad4OctetsA);
740 Stream_Read_UINT16(s, desktopSaveXGranularity);
741 Stream_Read_UINT16(s, desktopSaveYGranularity);
742 Stream_Read_UINT16(s, pad2OctetsA);
743 Stream_Read_UINT16(s, maximumOrderLevel);
744 Stream_Read_UINT16(s, numberFonts);
745 Stream_Read_UINT16(s, orderFlags);
746 Stream_Read(s, orderSupport, 32);
747 Stream_Read_UINT16(s, textFlags);
748 Stream_Read_UINT16(s, orderSupportExFlags);
749 Stream_Read_UINT32(s, pad4OctetsB);
750 Stream_Read_UINT32(s, desktopSaveSize);
751 Stream_Read_UINT16(s, pad2OctetsC);
752 Stream_Read_UINT16(s, pad2OctetsD);
753 Stream_Read_UINT16(s, textANSICodePage);
754 Stream_Read_UINT16(s, pad2OctetsE);
755 WLog_Print(log, WLOG_TRACE,
"\tpad4OctetsA: 0x%08" PRIX32
"", pad4OctetsA);
756 WLog_Print(log, WLOG_TRACE,
"\tdesktopSaveXGranularity: 0x%04" PRIX16
"",
757 desktopSaveXGranularity);
758 WLog_Print(log, WLOG_TRACE,
"\tdesktopSaveYGranularity: 0x%04" PRIX16
"",
759 desktopSaveYGranularity);
760 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
761 WLog_Print(log, WLOG_TRACE,
"\tmaximumOrderLevel: 0x%04" PRIX16
"", maximumOrderLevel);
762 WLog_Print(log, WLOG_TRACE,
"\tnumberFonts: 0x%04" PRIX16
"", numberFonts);
763 WLog_Print(log, WLOG_TRACE,
"\torderFlags: 0x%04" PRIX16
"", orderFlags);
764 WLog_Print(log, WLOG_TRACE,
"\torderSupport:");
765 WLog_Print(log, WLOG_TRACE,
"\t\tDSTBLT: %" PRIu8
"", orderSupport[NEG_DSTBLT_INDEX]);
766 WLog_Print(log, WLOG_TRACE,
"\t\tPATBLT: %" PRIu8
"", orderSupport[NEG_PATBLT_INDEX]);
767 WLog_Print(log, WLOG_TRACE,
"\t\tSCRBLT: %" PRIu8
"", orderSupport[NEG_SCRBLT_INDEX]);
768 WLog_Print(log, WLOG_TRACE,
"\t\tMEMBLT: %" PRIu8
"", orderSupport[NEG_MEMBLT_INDEX]);
769 WLog_Print(log, WLOG_TRACE,
"\t\tMEM3BLT: %" PRIu8
"", orderSupport[NEG_MEM3BLT_INDEX]);
770 WLog_Print(log, WLOG_TRACE,
"\t\tATEXTOUT: %" PRIu8
"", orderSupport[NEG_ATEXTOUT_INDEX]);
771 WLog_Print(log, WLOG_TRACE,
"\t\tAEXTTEXTOUT: %" PRIu8
"", orderSupport[NEG_AEXTTEXTOUT_INDEX]);
772 WLog_Print(log, WLOG_TRACE,
"\t\tDRAWNINEGRID: %" PRIu8
"",
773 orderSupport[NEG_DRAWNINEGRID_INDEX]);
774 WLog_Print(log, WLOG_TRACE,
"\t\tLINETO: %" PRIu8
"", orderSupport[NEG_LINETO_INDEX]);
775 WLog_Print(log, WLOG_TRACE,
"\t\tMULTI_DRAWNINEGRID: %" PRIu8
"",
776 orderSupport[NEG_MULTI_DRAWNINEGRID_INDEX]);
777 WLog_Print(log, WLOG_TRACE,
"\t\tOPAQUE_RECT: %" PRIu8
"", orderSupport[NEG_OPAQUE_RECT_INDEX]);
778 WLog_Print(log, WLOG_TRACE,
"\t\tSAVEBITMAP: %" PRIu8
"", orderSupport[NEG_SAVEBITMAP_INDEX]);
779 WLog_Print(log, WLOG_TRACE,
"\t\tWTEXTOUT: %" PRIu8
"", orderSupport[NEG_WTEXTOUT_INDEX]);
780 WLog_Print(log, WLOG_TRACE,
"\t\tMEMBLT_V2: %" PRIu8
"", orderSupport[NEG_MEMBLT_V2_INDEX]);
781 WLog_Print(log, WLOG_TRACE,
"\t\tMEM3BLT_V2: %" PRIu8
"", orderSupport[NEG_MEM3BLT_V2_INDEX]);
782 WLog_Print(log, WLOG_TRACE,
"\t\tMULTIDSTBLT: %" PRIu8
"", orderSupport[NEG_MULTIDSTBLT_INDEX]);
783 WLog_Print(log, WLOG_TRACE,
"\t\tMULTIPATBLT: %" PRIu8
"", orderSupport[NEG_MULTIPATBLT_INDEX]);
784 WLog_Print(log, WLOG_TRACE,
"\t\tMULTISCRBLT: %" PRIu8
"", orderSupport[NEG_MULTISCRBLT_INDEX]);
785 WLog_Print(log, WLOG_TRACE,
"\t\tMULTIOPAQUERECT: %" PRIu8
"",
786 orderSupport[NEG_MULTIOPAQUERECT_INDEX]);
787 WLog_Print(log, WLOG_TRACE,
"\t\tFAST_INDEX: %" PRIu8
"", orderSupport[NEG_FAST_INDEX_INDEX]);
788 WLog_Print(log, WLOG_TRACE,
"\t\tPOLYGON_SC: %" PRIu8
"", orderSupport[NEG_POLYGON_SC_INDEX]);
789 WLog_Print(log, WLOG_TRACE,
"\t\tPOLYGON_CB: %" PRIu8
"", orderSupport[NEG_POLYGON_CB_INDEX]);
790 WLog_Print(log, WLOG_TRACE,
"\t\tPOLYLINE: %" PRIu8
"", orderSupport[NEG_POLYLINE_INDEX]);
791 WLog_Print(log, WLOG_TRACE,
"\t\tUNUSED23: %" PRIu8
"", orderSupport[NEG_UNUSED23_INDEX]);
792 WLog_Print(log, WLOG_TRACE,
"\t\tFAST_GLYPH: %" PRIu8
"", orderSupport[NEG_FAST_GLYPH_INDEX]);
793 WLog_Print(log, WLOG_TRACE,
"\t\tELLIPSE_SC: %" PRIu8
"", orderSupport[NEG_ELLIPSE_SC_INDEX]);
794 WLog_Print(log, WLOG_TRACE,
"\t\tELLIPSE_CB: %" PRIu8
"", orderSupport[NEG_ELLIPSE_CB_INDEX]);
795 WLog_Print(log, WLOG_TRACE,
"\t\tGLYPH_INDEX: %" PRIu8
"", orderSupport[NEG_GLYPH_INDEX_INDEX]);
796 WLog_Print(log, WLOG_TRACE,
"\t\tGLYPH_WEXTTEXTOUT: %" PRIu8
"",
797 orderSupport[NEG_GLYPH_WEXTTEXTOUT_INDEX]);
798 WLog_Print(log, WLOG_TRACE,
"\t\tGLYPH_WLONGTEXTOUT: %" PRIu8
"",
799 orderSupport[NEG_GLYPH_WLONGTEXTOUT_INDEX]);
800 WLog_Print(log, WLOG_TRACE,
"\t\tGLYPH_WLONGEXTTEXTOUT: %" PRIu8
"",
801 orderSupport[NEG_GLYPH_WLONGEXTTEXTOUT_INDEX]);
802 WLog_Print(log, WLOG_TRACE,
"\t\tUNUSED31: %" PRIu8
"", orderSupport[NEG_UNUSED31_INDEX]);
803 WLog_Print(log, WLOG_TRACE,
"\ttextFlags: 0x%04" PRIX16
"", textFlags);
804 WLog_Print(log, WLOG_TRACE,
"\torderSupportExFlags: 0x%04" PRIX16
"", orderSupportExFlags);
805 WLog_Print(log, WLOG_TRACE,
"\tpad4OctetsB: 0x%08" PRIX32
"", pad4OctetsB);
806 WLog_Print(log, WLOG_TRACE,
"\tdesktopSaveSize: 0x%08" PRIX32
"", desktopSaveSize);
807 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsC: 0x%04" PRIX16
"", pad2OctetsC);
808 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsD: 0x%04" PRIX16
"", pad2OctetsD);
809 WLog_Print(log, WLOG_TRACE,
"\ttextANSICodePage: 0x%04" PRIX16
"", textANSICodePage);
810 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsE: 0x%04" PRIX16
"", pad2OctetsE);
815static BOOL rdp_apply_bitmap_cache_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
816 WINPR_ATTR_UNUSED
const rdpSettings* src)
818 WINPR_ASSERT(settings);
828static BOOL rdp_read_bitmap_cache_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
830 WINPR_UNUSED(settings);
831 WINPR_ASSERT(settings);
833 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
836 Stream_Seek_UINT32(s);
837 Stream_Seek_UINT32(s);
838 Stream_Seek_UINT32(s);
839 Stream_Seek_UINT32(s);
840 Stream_Seek_UINT32(s);
841 Stream_Seek_UINT32(s);
842 Stream_Seek_UINT16(s);
843 Stream_Seek_UINT16(s);
844 Stream_Seek_UINT16(s);
845 Stream_Seek_UINT16(s);
846 Stream_Seek_UINT16(s);
847 Stream_Seek_UINT16(s);
856static BOOL rdp_write_bitmap_cache_capability_set(wLog* log,
wStream* s,
857 const rdpSettings* settings)
859 if (!Stream_EnsureRemainingCapacity(s, 64))
862 const size_t header = rdp_capability_set_start(log, s);
864 if (bpp > UINT16_MAX)
866 Stream_Write_UINT32(s, 0);
867 Stream_Write_UINT32(s, 0);
868 Stream_Write_UINT32(s, 0);
869 Stream_Write_UINT32(s, 0);
870 Stream_Write_UINT32(s, 0);
871 Stream_Write_UINT32(s, 0);
872 UINT32 size = bpp * 256;
873 if (size > UINT16_MAX)
875 Stream_Write_UINT16(s, 200);
876 Stream_Write_UINT16(s, (UINT16)size);
878 if (size > UINT16_MAX)
880 Stream_Write_UINT16(s, 600);
881 Stream_Write_UINT16(s, (UINT16)size);
883 if (size > UINT16_MAX)
885 Stream_Write_UINT16(s, 1000);
886 Stream_Write_UINT16(s, (UINT16)size);
887 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE);
890#ifdef WITH_DEBUG_CAPABILITIES
891static BOOL rdp_print_bitmap_cache_capability_set(wLog* log,
wStream* s)
899 UINT16 Cache0Entries = 0;
900 UINT16 Cache0MaximumCellSize = 0;
901 UINT16 Cache1Entries = 0;
902 UINT16 Cache1MaximumCellSize = 0;
903 UINT16 Cache2Entries = 0;
904 UINT16 Cache2MaximumCellSize = 0;
905 WLog_Print(log, WLOG_TRACE,
906 "BitmapCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
908 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
911 Stream_Read_UINT32(s, pad1);
912 Stream_Read_UINT32(s, pad2);
913 Stream_Read_UINT32(s, pad3);
914 Stream_Read_UINT32(s, pad4);
915 Stream_Read_UINT32(s, pad5);
916 Stream_Read_UINT32(s, pad6);
917 Stream_Read_UINT16(s, Cache0Entries);
918 Stream_Read_UINT16(s, Cache0MaximumCellSize);
919 Stream_Read_UINT16(s, Cache1Entries);
920 Stream_Read_UINT16(s, Cache1MaximumCellSize);
921 Stream_Read_UINT16(s, Cache2Entries);
922 Stream_Read_UINT16(s, Cache2MaximumCellSize);
923 WLog_Print(log, WLOG_TRACE,
"\tpad1: 0x%08" PRIX32
"", pad1);
924 WLog_Print(log, WLOG_TRACE,
"\tpad2: 0x%08" PRIX32
"", pad2);
925 WLog_Print(log, WLOG_TRACE,
"\tpad3: 0x%08" PRIX32
"", pad3);
926 WLog_Print(log, WLOG_TRACE,
"\tpad4: 0x%08" PRIX32
"", pad4);
927 WLog_Print(log, WLOG_TRACE,
"\tpad5: 0x%08" PRIX32
"", pad5);
928 WLog_Print(log, WLOG_TRACE,
"\tpad6: 0x%08" PRIX32
"", pad6);
929 WLog_Print(log, WLOG_TRACE,
"\tCache0Entries: 0x%04" PRIX16
"", Cache0Entries);
930 WLog_Print(log, WLOG_TRACE,
"\tCache0MaximumCellSize: 0x%04" PRIX16
"", Cache0MaximumCellSize);
931 WLog_Print(log, WLOG_TRACE,
"\tCache1Entries: 0x%04" PRIX16
"", Cache1Entries);
932 WLog_Print(log, WLOG_TRACE,
"\tCache1MaximumCellSize: 0x%04" PRIX16
"", Cache1MaximumCellSize);
933 WLog_Print(log, WLOG_TRACE,
"\tCache2Entries: 0x%04" PRIX16
"", Cache2Entries);
934 WLog_Print(log, WLOG_TRACE,
"\tCache2MaximumCellSize: 0x%04" PRIX16
"", Cache2MaximumCellSize);
939static BOOL rdp_apply_control_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
940 WINPR_ATTR_UNUSED
const rdpSettings* src)
942 WINPR_ASSERT(settings);
953static BOOL rdp_read_control_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
955 WINPR_UNUSED(settings);
956 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
959 Stream_Seek_UINT16(s);
960 Stream_Seek_UINT16(s);
961 Stream_Seek_UINT16(s);
962 Stream_Seek_UINT16(s);
971static BOOL rdp_write_control_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
973 WINPR_UNUSED(settings);
974 if (!Stream_EnsureRemainingCapacity(s, 32))
977 const size_t header = rdp_capability_set_start(log, s);
978 Stream_Write_UINT16(s, 0);
979 Stream_Write_UINT16(s, 0);
980 Stream_Write_UINT16(s, 2);
981 Stream_Write_UINT16(s, 2);
982 return rdp_capability_set_finish(s, header, CAPSET_TYPE_CONTROL);
985#ifdef WITH_DEBUG_CAPABILITIES
986static BOOL rdp_print_control_capability_set(wLog* log,
wStream* s)
988 UINT16 controlFlags = 0;
989 UINT16 remoteDetachFlag = 0;
990 UINT16 controlInterest = 0;
991 UINT16 detachInterest = 0;
992 WLog_Print(log, WLOG_TRACE,
993 "ControlCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
995 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
998 Stream_Read_UINT16(s, controlFlags);
999 Stream_Read_UINT16(s, remoteDetachFlag);
1000 Stream_Read_UINT16(s, controlInterest);
1001 Stream_Read_UINT16(s, detachInterest);
1002 WLog_Print(log, WLOG_TRACE,
"\tcontrolFlags: 0x%04" PRIX16
"", controlFlags);
1003 WLog_Print(log, WLOG_TRACE,
"\tremoteDetachFlag: 0x%04" PRIX16
"", remoteDetachFlag);
1004 WLog_Print(log, WLOG_TRACE,
"\tcontrolInterest: 0x%04" PRIX16
"", controlInterest);
1005 WLog_Print(log, WLOG_TRACE,
"\tdetachInterest: 0x%04" PRIX16
"", detachInterest);
1010static BOOL rdp_apply_window_activation_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
1011 WINPR_ATTR_UNUSED
const rdpSettings* src)
1013 WINPR_ASSERT(settings);
1024static BOOL rdp_read_window_activation_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1026 WINPR_UNUSED(settings);
1027 WINPR_ASSERT(settings);
1028 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1031 Stream_Seek_UINT16(s);
1032 Stream_Seek_UINT16(s);
1033 Stream_Seek_UINT16(s);
1034 Stream_Seek_UINT16(s);
1043static BOOL rdp_write_window_activation_capability_set(wLog* log,
wStream* s,
1044 const rdpSettings* settings)
1046 WINPR_UNUSED(settings);
1047 WINPR_ASSERT(settings);
1048 if (!Stream_EnsureRemainingCapacity(s, 32))
1051 const size_t header = rdp_capability_set_start(log, s);
1052 Stream_Write_UINT16(s, 0);
1053 Stream_Write_UINT16(s, 0);
1054 Stream_Write_UINT16(s, 0);
1055 Stream_Write_UINT16(s, 0);
1056 return rdp_capability_set_finish(s, header, CAPSET_TYPE_ACTIVATION);
1059#ifdef WITH_DEBUG_CAPABILITIES
1060static BOOL rdp_print_window_activation_capability_set(wLog* log,
wStream* s)
1062 UINT16 helpKeyFlag = 0;
1063 UINT16 helpKeyIndexFlag = 0;
1064 UINT16 helpExtendedKeyFlag = 0;
1065 UINT16 windowManagerKeyFlag = 0;
1066 WLog_Print(log, WLOG_TRACE,
1067 "WindowActivationCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1069 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1072 Stream_Read_UINT16(s, helpKeyFlag);
1073 Stream_Read_UINT16(s, helpKeyIndexFlag);
1074 Stream_Read_UINT16(s, helpExtendedKeyFlag);
1075 Stream_Read_UINT16(s, windowManagerKeyFlag);
1076 WLog_Print(log, WLOG_TRACE,
"\thelpKeyFlag: 0x%04" PRIX16
"", helpKeyFlag);
1077 WLog_Print(log, WLOG_TRACE,
"\thelpKeyIndexFlag: 0x%04" PRIX16
"", helpKeyIndexFlag);
1078 WLog_Print(log, WLOG_TRACE,
"\thelpExtendedKeyFlag: 0x%04" PRIX16
"", helpExtendedKeyFlag);
1079 WLog_Print(log, WLOG_TRACE,
"\twindowManagerKeyFlag: 0x%04" PRIX16
"", windowManagerKeyFlag);
1084static BOOL rdp_apply_pointer_capability_set(rdpSettings* settings,
const rdpSettings* src)
1086 WINPR_ASSERT(settings);
1090 const UINT32 colorPointerCacheSize =
1092 const UINT32 dstPointerCacheSize =
1094 const UINT32 dstColorPointerCacheSize =
1098 const UINT32 actualPointerCacheSize = MIN(pointerCacheSize, dstPointerCacheSize);
1099 const UINT32 actualColorPointerCacheSize = MIN(colorPointerCacheSize, dstColorPointerCacheSize);
1104 actualColorPointerCacheSize));
1112static BOOL rdp_read_pointer_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1114 UINT16 colorPointerFlag = 0;
1115 UINT16 colorPointerCacheSize = 0;
1116 UINT16 pointerCacheSize = 0;
1118 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1121 Stream_Read_UINT16(s, colorPointerFlag);
1122 Stream_Read_UINT16(s, colorPointerCacheSize);
1124 if (colorPointerFlag == 0)
1126 WLog_Print(log, WLOG_WARN,
1127 "[MS-RDPBCGR] 2.2.7.1.5 Pointer Capability Set "
1128 "(TS_POINTER_CAPABILITYSET)::colorPointerFlag received is %" PRIu16
1129 ". Value is ignored and always assumed to be TRUE",
1134 if (Stream_GetRemainingLength(s) >= 2)
1135 Stream_Read_UINT16(s, pointerCacheSize);
1137 WINPR_ASSERT(settings);
1138 settings->PointerCacheSize = pointerCacheSize;
1139 settings->ColorPointerCacheSize = colorPointerCacheSize;
1149static BOOL rdp_write_pointer_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1151 if (!Stream_EnsureRemainingCapacity(s, 32))
1154 const size_t header = rdp_capability_set_start(log, s);
1155 if (settings->PointerCacheSize > UINT16_MAX)
1157 if (settings->ColorPointerCacheSize > UINT16_MAX)
1160 WINPR_ASSERT(settings);
1161 const UINT32 colorPointerFlag =
1164 Stream_Write_UINT16(s, colorPointerFlag);
1165 Stream_Write_UINT16(
1166 s, (UINT16)settings->ColorPointerCacheSize);
1167 Stream_Write_UINT16(s, (UINT16)settings->PointerCacheSize);
1169 return rdp_capability_set_finish(s, header, CAPSET_TYPE_POINTER);
1172#ifdef WITH_DEBUG_CAPABILITIES
1173static BOOL rdp_print_pointer_capability_set(wLog* log,
wStream* s)
1175 UINT16 colorPointerFlag = 0;
1176 UINT16 colorPointerCacheSize = 0;
1177 UINT16 pointerCacheSize = 0;
1179 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 6))
1182 WLog_Print(log, WLOG_TRACE,
1183 "PointerCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1184 Stream_Read_UINT16(s, colorPointerFlag);
1185 Stream_Read_UINT16(s, colorPointerCacheSize);
1186 Stream_Read_UINT16(s, pointerCacheSize);
1187 WLog_Print(log, WLOG_TRACE,
"\tcolorPointerFlag: 0x%04" PRIX16
"", colorPointerFlag);
1188 WLog_Print(log, WLOG_TRACE,
"\tcolorPointerCacheSize: 0x%04" PRIX16
"", colorPointerCacheSize);
1189 WLog_Print(log, WLOG_TRACE,
"\tpointerCacheSize: 0x%04" PRIX16
"", pointerCacheSize);
1194static BOOL rdp_apply_share_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
1195 WINPR_ATTR_UNUSED
const rdpSettings* src)
1197 WINPR_ASSERT(settings);
1208static BOOL rdp_read_share_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1210 WINPR_UNUSED(settings);
1211 WINPR_ASSERT(settings);
1213 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1216 Stream_Seek_UINT16(s);
1217 Stream_Seek_UINT16(s);
1226static BOOL rdp_write_share_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1228 if (!Stream_EnsureRemainingCapacity(s, 32))
1231 const size_t header = rdp_capability_set_start(log, s);
1233 WINPR_ASSERT(settings);
1234 const UINT16 nodeId = (settings->ServerMode) ? 0x03EA : 0;
1235 Stream_Write_UINT16(s, nodeId);
1236 Stream_Write_UINT16(s, 0);
1237 return rdp_capability_set_finish(s, header, CAPSET_TYPE_SHARE);
1240#ifdef WITH_DEBUG_CAPABILITIES
1241static BOOL rdp_print_share_capability_set(wLog* log,
wStream* s)
1244 UINT16 pad2Octets = 0;
1245 WLog_Print(log, WLOG_TRACE,
1246 "ShareCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1248 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1251 Stream_Read_UINT16(s, nodeId);
1252 Stream_Read_UINT16(s, pad2Octets);
1253 WLog_Print(log, WLOG_TRACE,
"\tnodeId: 0x%04" PRIX16
"", nodeId);
1254 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1259static BOOL rdp_apply_color_cache_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
1260 WINPR_ATTR_UNUSED
const rdpSettings* src)
1262 WINPR_ASSERT(settings);
1272static BOOL rdp_read_color_cache_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1274 WINPR_UNUSED(settings);
1275 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1278 Stream_Seek_UINT16(s);
1279 Stream_Seek_UINT16(s);
1288static BOOL rdp_write_color_cache_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1290 WINPR_UNUSED(settings);
1291 if (!Stream_EnsureRemainingCapacity(s, 32))
1294 const size_t header = rdp_capability_set_start(log, s);
1295 Stream_Write_UINT16(s, 6);
1296 Stream_Write_UINT16(s, 0);
1297 return rdp_capability_set_finish(s, header, CAPSET_TYPE_COLOR_CACHE);
1300#ifdef WITH_DEBUG_CAPABILITIES
1301static BOOL rdp_print_color_cache_capability_set(wLog* log,
wStream* s)
1303 UINT16 colorTableCacheSize = 0;
1304 UINT16 pad2Octets = 0;
1305 WLog_Print(log, WLOG_TRACE,
1306 "ColorCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1308 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1311 Stream_Read_UINT16(s, colorTableCacheSize);
1312 Stream_Read_UINT16(s, pad2Octets);
1313 WLog_Print(log, WLOG_TRACE,
"\tcolorTableCacheSize: 0x%04" PRIX16
"", colorTableCacheSize);
1314 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1319static BOOL rdp_apply_sound_capability_set(rdpSettings* settings,
const rdpSettings* src)
1321 WINPR_ASSERT(settings);
1324 settings->SoundBeepsEnabled = src->SoundBeepsEnabled;
1334static BOOL rdp_read_sound_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1336 UINT16 soundFlags = 0;
1338 WINPR_ASSERT(settings);
1339 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1342 Stream_Read_UINT16(s, soundFlags);
1343 Stream_Seek_UINT16(s);
1344 settings->SoundBeepsEnabled = (soundFlags & SOUND_BEEPS_FLAG) != 0;
1353static BOOL rdp_write_sound_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1355 WINPR_ASSERT(settings);
1356 if (!Stream_EnsureRemainingCapacity(s, 32))
1359 const size_t header = rdp_capability_set_start(log, s);
1360 const UINT16 soundFlags = (settings->SoundBeepsEnabled) ? SOUND_BEEPS_FLAG : 0;
1361 Stream_Write_UINT16(s, soundFlags);
1362 Stream_Write_UINT16(s, 0);
1363 return rdp_capability_set_finish(s, header, CAPSET_TYPE_SOUND);
1366#ifdef WITH_DEBUG_CAPABILITIES
1367static BOOL rdp_print_sound_capability_set(wLog* log,
wStream* s)
1369 UINT16 soundFlags = 0;
1370 UINT16 pad2OctetsA = 0;
1371 WLog_Print(log, WLOG_TRACE,
1372 "SoundCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1374 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1377 Stream_Read_UINT16(s, soundFlags);
1378 Stream_Read_UINT16(s, pad2OctetsA);
1379 WLog_Print(log, WLOG_TRACE,
"\tsoundFlags: 0x%04" PRIX16
"", soundFlags);
1380 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
1385static BOOL rdp_apply_input_capability_set(rdpSettings* settings,
const rdpSettings* src)
1387 WINPR_ASSERT(settings);
1390 if (settings->ServerMode)
1392 settings->KeyboardLayout = src->KeyboardLayout;
1393 settings->KeyboardType = src->KeyboardType;
1394 settings->KeyboardSubType = src->KeyboardSubType;
1395 settings->KeyboardFunctionKey = src->KeyboardFunctionKey;
1401 if (!settings->ServerMode)
1403 settings->FastPathInput = src->FastPathInput;
1409 if (settings->HasHorizontalWheel)
1410 settings->HasHorizontalWheel = src->HasHorizontalWheel;
1418 if (settings->HasExtendedMouseEvent)
1419 settings->HasExtendedMouseEvent = src->HasExtendedMouseEvent;
1420 if (settings->HasRelativeMouseEvent)
1421 settings->HasRelativeMouseEvent = src->HasRelativeMouseEvent;
1433static BOOL rdp_read_input_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1435 UINT16 inputFlags = 0;
1437 WINPR_ASSERT(settings);
1438 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 84))
1441 Stream_Read_UINT16(s, inputFlags);
1442 Stream_Seek_UINT16(s);
1444 Stream_Read_UINT32(s, settings->KeyboardLayout);
1445 Stream_Read_UINT32(s, settings->KeyboardType);
1446 Stream_Read_UINT32(s, settings->KeyboardSubType);
1447 Stream_Read_UINT32(s, settings->KeyboardFunctionKey);
1450 WCHAR wstr[32] = WINPR_C_ARRAY_INIT;
1451 char str[65] = WINPR_C_ARRAY_INIT;
1457 if (!Stream_Read_UTF16_String(s, wstr, ARRAYSIZE(wstr)))
1460 if (ConvertWCharNToUtf8(wstr, ARRAYSIZE(wstr), str, ARRAYSIZE(str)) < 0)
1461 memset(str, 0,
sizeof(str));
1469 (INPUT_FLAG_FASTPATH_INPUT | INPUT_FLAG_FASTPATH_INPUT2)))
1472 (inputFlags & TS_INPUT_FLAG_MOUSE_HWHEEL) != 0))
1475 (inputFlags & INPUT_FLAG_UNICODE) != 0))
1478 (inputFlags & INPUT_FLAG_MOUSE_RELATIVE) != 0))
1481 (inputFlags & INPUT_FLAG_MOUSEX) != 0))
1484 (inputFlags & TS_INPUT_FLAG_QOE_TIMESTAMPS) != 0))
1495static BOOL rdp_write_input_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1497 WINPR_ASSERT(settings);
1498 if (!Stream_EnsureRemainingCapacity(s, 128))
1501 const size_t header = rdp_capability_set_start(log, s);
1502 UINT16 inputFlags = INPUT_FLAG_SCANCODES;
1504 if (settings->FastPathInput)
1506 inputFlags |= INPUT_FLAG_FASTPATH_INPUT;
1507 inputFlags |= INPUT_FLAG_FASTPATH_INPUT2;
1511 inputFlags |= INPUT_FLAG_MOUSE_RELATIVE;
1514 inputFlags |= TS_INPUT_FLAG_MOUSE_HWHEEL;
1517 inputFlags |= INPUT_FLAG_UNICODE;
1520 inputFlags |= TS_INPUT_FLAG_QOE_TIMESTAMPS;
1522 if (settings->HasExtendedMouseEvent)
1523 inputFlags |= INPUT_FLAG_MOUSEX;
1525 Stream_Write_UINT16(s, inputFlags);
1526 Stream_Write_UINT16(s, 0);
1527 Stream_Write_UINT32(s, settings->KeyboardLayout);
1528 Stream_Write_UINT32(s, settings->KeyboardType);
1529 Stream_Write_UINT32(s, settings->KeyboardSubType);
1530 Stream_Write_UINT32(s, settings->KeyboardFunctionKey);
1532 return rdp_capability_set_finish(s, header, CAPSET_TYPE_INPUT);
1535#ifdef WITH_DEBUG_CAPABILITIES
1536static BOOL rdp_print_input_capability_set(wLog* log,
wStream* s)
1538 UINT16 inputFlags = 0;
1539 UINT16 pad2OctetsA = 0;
1540 UINT32 keyboardLayout = 0;
1541 UINT32 keyboardType = 0;
1542 UINT32 keyboardSubType = 0;
1543 UINT32 keyboardFunctionKey = 0;
1544 WLog_Print(log, WLOG_TRACE,
"InputCapabilitySet (length %" PRIuz
")",
1545 Stream_GetRemainingLength(s));
1547 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 84))
1550 Stream_Read_UINT16(s, inputFlags);
1551 Stream_Read_UINT16(s, pad2OctetsA);
1552 Stream_Read_UINT32(s, keyboardLayout);
1553 Stream_Read_UINT32(s, keyboardType);
1554 Stream_Read_UINT32(s, keyboardSubType);
1555 Stream_Read_UINT32(s, keyboardFunctionKey);
1557 WLog_Print(log, WLOG_TRACE,
"\tinputFlags: 0x%04" PRIX16
"", inputFlags);
1558 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
1559 WLog_Print(log, WLOG_TRACE,
"\tkeyboardLayout: 0x%08" PRIX32
"", keyboardLayout);
1560 WLog_Print(log, WLOG_TRACE,
"\tkeyboardType: 0x%08" PRIX32
"", keyboardType);
1561 WLog_Print(log, WLOG_TRACE,
"\tkeyboardSubType: 0x%08" PRIX32
"", keyboardSubType);
1562 WLog_Print(log, WLOG_TRACE,
"\tkeyboardFunctionKey: 0x%08" PRIX32
"", keyboardFunctionKey);
1567static BOOL rdp_apply_font_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
1568 WINPR_ATTR_UNUSED
const rdpSettings* src)
1570 WINPR_ASSERT(settings);
1580static BOOL rdp_read_font_capability_set(WINPR_ATTR_UNUSED wLog* log,
wStream* s,
1581 rdpSettings* settings)
1583 WINPR_UNUSED(settings);
1584 if (Stream_GetRemainingLength(s) >= 2)
1585 Stream_Seek_UINT16(s);
1587 if (Stream_GetRemainingLength(s) >= 2)
1588 Stream_Seek_UINT16(s);
1598static BOOL rdp_write_font_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1600 WINPR_UNUSED(settings);
1601 if (!Stream_EnsureRemainingCapacity(s, 32))
1604 const size_t header = rdp_capability_set_start(log, s);
1605 Stream_Write_UINT16(s, FONTSUPPORT_FONTLIST);
1606 Stream_Write_UINT16(s, 0);
1607 return rdp_capability_set_finish(s, header, CAPSET_TYPE_FONT);
1610#ifdef WITH_DEBUG_CAPABILITIES
1611static BOOL rdp_print_font_capability_set(wLog* log,
wStream* s)
1613 UINT16 fontSupportFlags = 0;
1614 UINT16 pad2Octets = 0;
1615 WLog_Print(log, WLOG_TRACE,
1616 "FontCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1618 if (Stream_GetRemainingLength(s) >= 2)
1619 Stream_Read_UINT16(s, fontSupportFlags);
1621 if (Stream_GetRemainingLength(s) >= 2)
1622 Stream_Read_UINT16(s, pad2Octets);
1624 WLog_Print(log, WLOG_TRACE,
"\tfontSupportFlags: 0x%04" PRIX16
"", fontSupportFlags);
1625 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1630static BOOL rdp_apply_brush_capability_set(rdpSettings* settings,
const rdpSettings* src)
1632 WINPR_ASSERT(settings);
1636 settings->BrushSupportLevel = src->BrushSupportLevel;
1645static BOOL rdp_read_brush_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1647 WINPR_UNUSED(settings);
1648 WINPR_ASSERT(settings);
1650 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1652 Stream_Read_UINT32(s, settings->BrushSupportLevel);
1661static BOOL rdp_write_brush_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1663 WINPR_ASSERT(settings);
1664 if (!Stream_EnsureRemainingCapacity(s, 32))
1667 const size_t header = rdp_capability_set_start(log, s);
1668 Stream_Write_UINT32(s, settings->BrushSupportLevel);
1669 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BRUSH);
1672#ifdef WITH_DEBUG_CAPABILITIES
1673static BOOL rdp_print_brush_capability_set(wLog* log,
wStream* s)
1675 UINT32 brushSupportLevel = 0;
1676 WLog_Print(log, WLOG_TRACE,
1677 "BrushCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1679 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1682 Stream_Read_UINT32(s, brushSupportLevel);
1683 WLog_Print(log, WLOG_TRACE,
"\tbrushSupportLevel: 0x%08" PRIX32
"", brushSupportLevel);
1694 WINPR_ASSERT(cache_definition);
1695 Stream_Read_UINT16(s, cache_definition->cacheEntries);
1696 Stream_Read_UINT16(s,
1697 cache_definition->cacheMaximumCellSize);
1706 WINPR_ASSERT(cache_definition);
1707 Stream_Write_UINT16(s, cache_definition->cacheEntries);
1708 Stream_Write_UINT16(
1709 s, cache_definition->cacheMaximumCellSize);
1712static BOOL rdp_apply_glyph_cache_capability_set(rdpSettings* settings,
const rdpSettings* src)
1714 WINPR_ASSERT(settings);
1717 WINPR_ASSERT(src->GlyphCache);
1718 WINPR_ASSERT(settings->GlyphCache);
1719 for (
size_t x = 0; x < 10; x++)
1720 settings->GlyphCache[x] = src->GlyphCache[x];
1722 WINPR_ASSERT(src->FragCache);
1723 WINPR_ASSERT(settings->FragCache);
1724 settings->FragCache[0] = src->FragCache[0];
1725 settings->GlyphSupportLevel = src->GlyphSupportLevel;
1735static BOOL rdp_read_glyph_cache_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1737 WINPR_ASSERT(settings);
1738 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 48))
1742 for (
size_t x = 0; x < 10; x++)
1743 rdp_read_cache_definition(s, &(settings->GlyphCache[x]));
1744 rdp_read_cache_definition(s, settings->FragCache);
1745 Stream_Read_UINT16(s, settings->GlyphSupportLevel);
1746 Stream_Seek_UINT16(s);
1755static BOOL rdp_write_glyph_cache_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1757 WINPR_ASSERT(settings);
1758 if (!Stream_EnsureRemainingCapacity(s, 64))
1761 const size_t header = rdp_capability_set_start(log, s);
1762 if (settings->GlyphSupportLevel > UINT16_MAX)
1765 for (
size_t x = 0; x < 10; x++)
1766 rdp_write_cache_definition(s, &(settings->GlyphCache[x]));
1767 rdp_write_cache_definition(s, settings->FragCache);
1768 Stream_Write_UINT16(s, (UINT16)settings->GlyphSupportLevel);
1769 Stream_Write_UINT16(s, 0);
1770 return rdp_capability_set_finish(s, header, CAPSET_TYPE_GLYPH_CACHE);
1773#ifdef WITH_DEBUG_CAPABILITIES
1774static BOOL rdp_print_glyph_cache_capability_set(wLog* log,
wStream* s)
1778 UINT16 glyphSupportLevel = 0;
1779 UINT16 pad2Octets = 0;
1780 WLog_Print(log, WLOG_TRACE,
1781 "GlyphCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1783 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 48))
1787 rdp_read_cache_definition(s, &glyphCache[0]);
1788 rdp_read_cache_definition(s, &glyphCache[1]);
1789 rdp_read_cache_definition(s, &glyphCache[2]);
1790 rdp_read_cache_definition(s, &glyphCache[3]);
1791 rdp_read_cache_definition(s, &glyphCache[4]);
1792 rdp_read_cache_definition(s, &glyphCache[5]);
1793 rdp_read_cache_definition(s, &glyphCache[6]);
1794 rdp_read_cache_definition(s, &glyphCache[7]);
1795 rdp_read_cache_definition(s, &glyphCache[8]);
1796 rdp_read_cache_definition(s, &glyphCache[9]);
1797 rdp_read_cache_definition(s, &fragCache);
1798 Stream_Read_UINT16(s, glyphSupportLevel);
1799 Stream_Read_UINT16(s, pad2Octets);
1800 WLog_Print(log, WLOG_TRACE,
"\tglyphCache0: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1801 glyphCache[0].cacheEntries, glyphCache[0].cacheMaximumCellSize);
1802 WLog_Print(log, WLOG_TRACE,
"\tglyphCache1: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1803 glyphCache[1].cacheEntries, glyphCache[1].cacheMaximumCellSize);
1804 WLog_Print(log, WLOG_TRACE,
"\tglyphCache2: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1805 glyphCache[2].cacheEntries, glyphCache[2].cacheMaximumCellSize);
1806 WLog_Print(log, WLOG_TRACE,
"\tglyphCache3: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1807 glyphCache[3].cacheEntries, glyphCache[3].cacheMaximumCellSize);
1808 WLog_Print(log, WLOG_TRACE,
"\tglyphCache4: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1809 glyphCache[4].cacheEntries, glyphCache[4].cacheMaximumCellSize);
1810 WLog_Print(log, WLOG_TRACE,
"\tglyphCache5: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1811 glyphCache[5].cacheEntries, glyphCache[5].cacheMaximumCellSize);
1812 WLog_Print(log, WLOG_TRACE,
"\tglyphCache6: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1813 glyphCache[6].cacheEntries, glyphCache[6].cacheMaximumCellSize);
1814 WLog_Print(log, WLOG_TRACE,
"\tglyphCache7: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1815 glyphCache[7].cacheEntries, glyphCache[7].cacheMaximumCellSize);
1816 WLog_Print(log, WLOG_TRACE,
"\tglyphCache8: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1817 glyphCache[8].cacheEntries, glyphCache[8].cacheMaximumCellSize);
1818 WLog_Print(log, WLOG_TRACE,
"\tglyphCache9: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1819 glyphCache[9].cacheEntries, glyphCache[9].cacheMaximumCellSize);
1820 WLog_Print(log, WLOG_TRACE,
"\tfragCache: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1821 fragCache.cacheEntries, fragCache.cacheMaximumCellSize);
1822 WLog_Print(log, WLOG_TRACE,
"\tglyphSupportLevel: 0x%04" PRIX16
"", glyphSupportLevel);
1823 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1828static BOOL rdp_apply_offscreen_bitmap_cache_capability_set(rdpSettings* settings,
1829 const rdpSettings* src)
1831 WINPR_ASSERT(settings);
1834 settings->OffscreenCacheSize = src->OffscreenCacheSize;
1835 settings->OffscreenCacheEntries = src->OffscreenCacheEntries;
1836 settings->OffscreenSupportLevel = src->OffscreenSupportLevel;
1846static BOOL rdp_read_offscreen_bitmap_cache_capability_set(wLog* log,
wStream* s,
1847 rdpSettings* settings)
1849 UINT32 offscreenSupportLevel = 0;
1851 WINPR_ASSERT(settings);
1852 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1855 Stream_Read_UINT32(s, offscreenSupportLevel);
1856 Stream_Read_UINT16(s, settings->OffscreenCacheSize);
1857 Stream_Read_UINT16(s, settings->OffscreenCacheEntries);
1859 settings->OffscreenSupportLevel = offscreenSupportLevel & 0x01;
1869static BOOL rdp_write_offscreen_bitmap_cache_capability_set(wLog* log,
wStream* s,
1870 const rdpSettings* settings)
1872 UINT32 offscreenSupportLevel = 0x00;
1874 WINPR_ASSERT(settings);
1875 if (!Stream_EnsureRemainingCapacity(s, 32))
1878 const size_t header = rdp_capability_set_start(log, s);
1879 if (settings->OffscreenSupportLevel)
1881 offscreenSupportLevel = 0x01;
1882 Stream_Write_UINT32(s, offscreenSupportLevel);
1883 Stream_Write_UINT16(
1884 s, WINPR_ASSERTING_INT_CAST(
1885 uint16_t, settings->OffscreenCacheSize));
1886 Stream_Write_UINT16(
1888 WINPR_ASSERTING_INT_CAST(
1889 uint16_t, settings->OffscreenCacheEntries));
1894 return rdp_capability_set_finish(s, header, CAPSET_TYPE_OFFSCREEN_CACHE);
1897#ifdef WITH_DEBUG_CAPABILITIES
1898static BOOL rdp_print_offscreen_bitmap_cache_capability_set(wLog* log,
wStream* s)
1900 UINT32 offscreenSupportLevel = 0;
1901 UINT16 offscreenCacheSize = 0;
1902 UINT16 offscreenCacheEntries = 0;
1903 WLog_Print(log, WLOG_TRACE,
"OffscreenBitmapCacheCapabilitySet (length %" PRIuz
"):",
1904 Stream_GetRemainingLength(s));
1906 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1909 Stream_Read_UINT32(s, offscreenSupportLevel);
1910 Stream_Read_UINT16(s, offscreenCacheSize);
1911 Stream_Read_UINT16(s, offscreenCacheEntries);
1912 WLog_Print(log, WLOG_TRACE,
"\toffscreenSupportLevel: 0x%08" PRIX32
"", offscreenSupportLevel);
1913 WLog_Print(log, WLOG_TRACE,
"\toffscreenCacheSize: 0x%04" PRIX16
"", offscreenCacheSize);
1914 WLog_Print(log, WLOG_TRACE,
"\toffscreenCacheEntries: 0x%04" PRIX16
"", offscreenCacheEntries);
1919static BOOL rdp_apply_bitmap_cache_host_support_capability_set(rdpSettings* settings,
1920 const rdpSettings* src)
1932static BOOL rdp_read_bitmap_cache_host_support_capability_set(wLog* log,
wStream* s,
1933 rdpSettings* settings)
1935 BYTE cacheVersion = 0;
1937 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1940 Stream_Read_UINT8(s, cacheVersion);
1941 Stream_Seek_UINT8(s);
1942 Stream_Seek_UINT16(s);
1945 cacheVersion & BITMAP_CACHE_V2);
1953static BOOL rdp_write_bitmap_cache_host_support_capability_set(wLog* log,
wStream* s,
1954 const rdpSettings* settings)
1956 UINT8 cacheVersion = 0;
1959 cacheVersion |= BITMAP_CACHE_V2;
1961 if (!Stream_EnsureRemainingCapacity(s, 32))
1964 const size_t header = rdp_capability_set_start(log, s);
1965 Stream_Write_UINT8(s, cacheVersion);
1966 Stream_Write_UINT8(s, 0);
1967 Stream_Write_UINT16(s, 0);
1968 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT);
1971#ifdef WITH_DEBUG_CAPABILITIES
1972static BOOL rdp_print_bitmap_cache_host_support_capability_set(wLog* log,
wStream* s)
1974 BYTE cacheVersion = 0;
1977 WLog_Print(log, WLOG_TRACE,
"BitmapCacheHostSupportCapabilitySet (length %" PRIuz
"):",
1978 Stream_GetRemainingLength(s));
1980 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1983 Stream_Read_UINT8(s, cacheVersion);
1984 Stream_Read_UINT8(s, pad1);
1985 Stream_Read_UINT16(s, pad2);
1986 WLog_Print(log, WLOG_TRACE,
"\tcacheVersion: 0x%02" PRIX8
"", cacheVersion);
1987 WLog_Print(log, WLOG_TRACE,
"\tpad1: 0x%02" PRIX8
"", pad1);
1988 WLog_Print(log, WLOG_TRACE,
"\tpad2: 0x%04" PRIX16
"", pad2);
1993static BOOL rdp_read_bitmap_cache_cell_info(wLog* log,
wStream* s,
1998 WINPR_ASSERT(cellInfo);
1999 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2006 Stream_Read_UINT32(s, info);
2007 cellInfo->numEntries = (info & 0x7FFFFFFF);
2008 cellInfo->persistent = (info & 0x80000000) ? 1 : 0;
2019 WINPR_ASSERT(cellInfo);
2020 info = (cellInfo->numEntries | (((UINT32)cellInfo->persistent << 31) & 0xFF000000));
2021 Stream_Write_UINT32(s, info);
2024static BOOL rdp_apply_bitmap_cache_v2_capability_set(rdpSettings* settings,
const rdpSettings* src)
2026 const FreeRDP_Settings_Keys_Bool keys[] = { FreeRDP_BitmapCacheEnabled,
2027 FreeRDP_BitmapCachePersistEnabled };
2029 for (
size_t x = 0; x < ARRAYSIZE(keys); x++)
2031 const FreeRDP_Settings_Keys_Bool
id = keys[x];
2038 const UINT32 BitmapCacheV2NumCells =
2041 BitmapCacheV2NumCells))
2044 for (
size_t x = 0; x < BitmapCacheV2NumCells; x++)
2047 freerdp_settings_get_pointer_array(src, FreeRDP_BitmapCacheV2CellInfo, x);
2048 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_BitmapCacheV2CellInfo, x,
2062static BOOL rdp_read_bitmap_cache_v2_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2064 UINT16 cacheFlags = 0;
2065 WINPR_UNUSED(settings);
2066 WINPR_ASSERT(settings);
2068 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
2071 Stream_Read_UINT16(s, cacheFlags);
2076 cacheFlags & PERSISTENT_KEYS_EXPECTED_FLAG))
2079 Stream_Seek_UINT8(s);
2080 Stream_Read_UINT8(s, settings->BitmapCacheV2NumCells);
2081 if (settings->BitmapCacheV2NumCells > 5)
2083 WLog_Print(log, WLOG_ERROR,
2084 "Invalid TS_BITMAPCACHE_CAPABILITYSET_REV2::numCellCaches %" PRIu32
" > 5",
2085 settings->BitmapCacheV2NumCells);
2089 for (
size_t x = 0; x < settings->BitmapCacheV2NumCells; x++)
2092 freerdp_settings_get_pointer_array_writable(settings, FreeRDP_BitmapCacheV2CellInfo, x);
2093 if (!rdp_read_bitmap_cache_cell_info(log, s, info))
2098 for (
size_t x = settings->BitmapCacheV2NumCells; x < 5; x++)
2100 if (!Stream_SafeSeek(s, 4))
2112static BOOL rdp_write_bitmap_cache_v2_capability_set(wLog* log,
wStream* s,
2113 const rdpSettings* settings)
2115 WINPR_ASSERT(settings);
2116 if (!Stream_EnsureRemainingCapacity(s, 64))
2119 const size_t header = rdp_capability_set_start(log, s);
2120 UINT16 cacheFlags = ALLOW_CACHE_WAITING_LIST_FLAG;
2124 cacheFlags |= PERSISTENT_KEYS_EXPECTED_FLAG;
2125 settings->BitmapCacheV2CellInfo[0].persistent = 1;
2126 settings->BitmapCacheV2CellInfo[1].persistent = 1;
2127 settings->BitmapCacheV2CellInfo[2].persistent = 1;
2128 settings->BitmapCacheV2CellInfo[3].persistent = 1;
2129 settings->BitmapCacheV2CellInfo[4].persistent = 1;
2132 Stream_Write_UINT16(s, cacheFlags);
2133 Stream_Write_UINT8(s, 0);
2135 s, WINPR_ASSERTING_INT_CAST(uint8_t,
2136 settings->BitmapCacheV2NumCells));
2137 rdp_write_bitmap_cache_cell_info(
2138 s, &settings->BitmapCacheV2CellInfo[0]);
2139 rdp_write_bitmap_cache_cell_info(
2140 s, &settings->BitmapCacheV2CellInfo[1]);
2141 rdp_write_bitmap_cache_cell_info(
2142 s, &settings->BitmapCacheV2CellInfo[2]);
2143 rdp_write_bitmap_cache_cell_info(
2144 s, &settings->BitmapCacheV2CellInfo[3]);
2145 rdp_write_bitmap_cache_cell_info(
2146 s, &settings->BitmapCacheV2CellInfo[4]);
2148 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_V2);
2151#ifdef WITH_DEBUG_CAPABILITIES
2152static BOOL rdp_print_bitmap_cache_v2_capability_set(wLog* log,
wStream* s)
2155 WLog_Print(log, WLOG_TRACE,
2156 "BitmapCacheV2CapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2158 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
2161 const UINT16 cacheFlags = Stream_Get_UINT16(s);
2162 const UINT8 pad2 = Stream_Get_UINT8(s);
2163 const UINT8 numCellCaches = Stream_Get_UINT8(s);
2165 for (
size_t x = 0; x < ARRAYSIZE(bitmapCacheV2CellInfo); x++)
2167 if (!rdp_read_bitmap_cache_cell_info(
2168 log, s, &bitmapCacheV2CellInfo[x]))
2172 if (!Stream_SafeSeek(s, 12))
2175 WLog_Print(log, WLOG_TRACE,
"\tcacheFlags: 0x%04" PRIX16
"", cacheFlags);
2176 WLog_Print(log, WLOG_TRACE,
"\tpad2: 0x%02" PRIX8
"", pad2);
2177 WLog_Print(log, WLOG_TRACE,
"\tnumCellCaches: 0x%02" PRIX8
"", numCellCaches);
2178 for (
size_t x = 0; x < ARRAYSIZE(bitmapCacheV2CellInfo); x++)
2181 WLog_Print(log, WLOG_TRACE,
2182 "\tbitmapCache%" PRIuz
"CellInfo: numEntries: %" PRIu32
" persistent: %" PRId32
2184 x, info->numEntries, info->persistent);
2190static BOOL rdp_apply_virtual_channel_capability_set(rdpSettings* settings,
const rdpSettings* src)
2192 WINPR_ASSERT(settings);
2196 if (settings->ServerMode && (settings->VCFlags & VCCAPS_COMPR_SC) &&
2197 (src->VCFlags & VCCAPS_COMPR_SC))
2198 settings->VCFlags |= VCCAPS_COMPR_SC;
2200 settings->VCFlags &= (uint32_t)~VCCAPS_COMPR_SC;
2202 if (!settings->ServerMode && (settings->VCFlags & VCCAPS_COMPR_CS_8K) &&
2203 (src->VCFlags & VCCAPS_COMPR_CS_8K))
2204 settings->VCFlags |= VCCAPS_COMPR_CS_8K;
2206 settings->VCFlags &= (uint32_t)~VCCAPS_COMPR_CS_8K;
2213 if (!settings->ServerMode)
2215 if ((src->VCChunkSize > CHANNEL_CHUNK_MAX_LENGTH) || (src->VCChunkSize == 0))
2216 settings->VCChunkSize = CHANNEL_CHUNK_LENGTH;
2219 settings->VCChunkSize = src->VCChunkSize;
2231static BOOL rdp_read_virtual_channel_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2234 UINT32 VCChunkSize = 0;
2236 WINPR_ASSERT(settings);
2237 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2240 Stream_Read_UINT32(s, flags);
2242 if (Stream_GetRemainingLength(s) >= 4)
2243 Stream_Read_UINT32(s, VCChunkSize);
2245 VCChunkSize = UINT32_MAX;
2247 settings->VCFlags = flags;
2248 settings->VCChunkSize = VCChunkSize;
2258static BOOL rdp_write_virtual_channel_capability_set(wLog* log,
wStream* s,
2259 const rdpSettings* settings)
2261 WINPR_ASSERT(settings);
2262 if (!Stream_EnsureRemainingCapacity(s, 32))
2265 const size_t header = rdp_capability_set_start(log, s);
2266 Stream_Write_UINT32(s, settings->VCFlags);
2267 Stream_Write_UINT32(s, settings->VCChunkSize);
2268 return rdp_capability_set_finish(s, header, CAPSET_TYPE_VIRTUAL_CHANNEL);
2271#ifdef WITH_DEBUG_CAPABILITIES
2272static BOOL rdp_print_virtual_channel_capability_set(wLog* log,
wStream* s)
2275 UINT32 VCChunkSize = 0;
2276 WLog_Print(log, WLOG_TRACE,
2277 "VirtualChannelCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2279 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2282 Stream_Read_UINT32(s, flags);
2284 if (Stream_GetRemainingLength(s) >= 4)
2285 Stream_Read_UINT32(s, VCChunkSize);
2289 WLog_Print(log, WLOG_TRACE,
"\tflags: 0x%08" PRIX32
"", flags);
2290 WLog_Print(log, WLOG_TRACE,
"\tVCChunkSize: 0x%08" PRIX32
"", VCChunkSize);
2295static BOOL rdp_apply_draw_nine_grid_cache_capability_set(rdpSettings* settings,
2296 const rdpSettings* src)
2298 WINPR_ASSERT(settings);
2301 settings->DrawNineGridCacheSize = src->DrawNineGridCacheSize;
2302 settings->DrawNineGridCacheEntries = src->DrawNineGridCacheEntries;
2303 settings->DrawNineGridEnabled = src->DrawNineGridEnabled;
2313static BOOL rdp_read_draw_nine_grid_cache_capability_set(wLog* log,
wStream* s,
2314 rdpSettings* settings)
2316 UINT32 drawNineGridSupportLevel = 0;
2318 WINPR_ASSERT(settings);
2319 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
2322 Stream_Read_UINT32(s, drawNineGridSupportLevel);
2323 Stream_Read_UINT16(s, settings->DrawNineGridCacheSize);
2324 Stream_Read_UINT16(s,
2325 settings->DrawNineGridCacheEntries);
2327 settings->DrawNineGridEnabled =
2328 (drawNineGridSupportLevel & (DRAW_NINEGRID_SUPPORTED | DRAW_NINEGRID_SUPPORTED_V2)) != 0;
2338static BOOL rdp_write_draw_nine_grid_cache_capability_set(wLog* log,
wStream* s,
2339 const rdpSettings* settings)
2341 WINPR_ASSERT(settings);
2342 if (!Stream_EnsureRemainingCapacity(s, 32))
2345 const size_t header = rdp_capability_set_start(log, s);
2346 const UINT32 drawNineGridSupportLevel =
2347 (settings->DrawNineGridEnabled) ? DRAW_NINEGRID_SUPPORTED_V2 : DRAW_NINEGRID_NO_SUPPORT;
2348 Stream_Write_UINT32(s, drawNineGridSupportLevel);
2349 Stream_Write_UINT16(
2350 s, WINPR_ASSERTING_INT_CAST(
2351 uint16_t, settings->DrawNineGridCacheSize));
2352 Stream_Write_UINT16(
2354 WINPR_ASSERTING_INT_CAST(
2355 uint16_t, settings->DrawNineGridCacheEntries));
2356 return rdp_capability_set_finish(s, header, CAPSET_TYPE_DRAW_NINE_GRID_CACHE);
2359#ifdef WITH_DEBUG_CAPABILITIES
2360static BOOL rdp_print_draw_nine_grid_cache_capability_set(wLog* log,
wStream* s)
2362 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
2365 const uint32_t drawNineGridSupportLevel =
2366 Stream_Get_UINT32(s);
2367 const uint32_t DrawNineGridCacheSize =
2368 Stream_Get_UINT16(s);
2369 const uint32_t DrawNineGridCacheEntries =
2370 Stream_Get_UINT16(s);
2372 WLog_Print(log, WLOG_TRACE,
2373 "DrawNineGridCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2374 WLog_Print(log, WLOG_TRACE,
"drawNineGridSupportLevel=0x%08" PRIx32, drawNineGridSupportLevel);
2375 WLog_Print(log, WLOG_TRACE,
"DrawNineGridCacheSize=0x%08" PRIx32, DrawNineGridCacheSize);
2376 WLog_Print(log, WLOG_TRACE,
"DrawNineGridCacheEntries=0x%08" PRIx32, DrawNineGridCacheEntries);
2381static BOOL rdp_apply_draw_gdiplus_cache_capability_set(rdpSettings* settings,
2382 const rdpSettings* src)
2384 WINPR_ASSERT(settings);
2387 if (src->DrawGdiPlusEnabled)
2388 settings->DrawGdiPlusEnabled = TRUE;
2390 if (src->DrawGdiPlusCacheEnabled)
2391 settings->DrawGdiPlusCacheEnabled = TRUE;
2401static BOOL rdp_read_draw_gdiplus_cache_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2403 UINT32 drawGDIPlusSupportLevel = 0;
2404 UINT32 drawGdiplusCacheLevel = 0;
2406 WINPR_ASSERT(settings);
2407 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
2410 Stream_Read_UINT32(s, drawGDIPlusSupportLevel);
2411 Stream_Seek_UINT32(s);
2412 Stream_Read_UINT32(s, drawGdiplusCacheLevel);
2417 settings->DrawGdiPlusEnabled = (drawGDIPlusSupportLevel & DRAW_GDIPLUS_SUPPORTED) != 0;
2418 settings->DrawGdiPlusCacheEnabled = (drawGdiplusCacheLevel & DRAW_GDIPLUS_CACHE_LEVEL_ONE) != 0;
2423#ifdef WITH_DEBUG_CAPABILITIES
2424static BOOL rdp_print_draw_gdiplus_cache_capability_set(wLog* log,
wStream* s)
2426 WLog_Print(log, WLOG_TRACE,
2427 "DrawGdiPlusCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2429 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
2432 const uint32_t drawGdiPlusSupportLevel =
2433 Stream_Get_UINT32(s);
2434 const uint32_t GdipVersion = Stream_Get_UINT32(s);
2435 const uint32_t drawGdiplusCacheLevel =
2436 Stream_Get_UINT32(s);
2437 WLog_Print(log, WLOG_TRACE,
2438 "drawGdiPlusSupportLevel=0x%08" PRIx32
", GdipVersion=0x%08" PRIx32
2439 ", drawGdiplusdrawGdiplusCacheLevelCacheLevel=0x%08" PRIx32,
2440 drawGdiPlusSupportLevel, GdipVersion, drawGdiplusCacheLevel);
2442 const uint16_t GdipGraphicsCacheEntries = Stream_Get_UINT16(s);
2443 const uint16_t GdipBrushCacheEntries = Stream_Get_UINT16(s);
2444 const uint16_t GdipPenCacheEntries = Stream_Get_UINT16(s);
2445 const uint16_t GdipImageCacheEntries = Stream_Get_UINT16(s);
2446 const uint16_t GdipImageAttributesCacheEntries = Stream_Get_UINT16(s);
2447 WLog_Print(log, WLOG_TRACE,
2448 "GdipGraphicsCacheEntries=0x%04" PRIx16
", GdipBrushCacheEntries=0x%04" PRIx16
2449 ", GdipPenCacheEntries=0x%04" PRIx16
", GdipImageCacheEntries=0x%04" PRIx16
2450 ", GdipImageAttributesCacheEntries=0x%04" PRIx16,
2451 GdipGraphicsCacheEntries, GdipBrushCacheEntries, GdipPenCacheEntries,
2452 GdipImageCacheEntries, GdipImageAttributesCacheEntries);
2454 const uint16_t GdipGraphicsCacheChunkSize = Stream_Get_UINT16(s);
2455 const uint16_t GdipObjectBrushCacheChunkSize = Stream_Get_UINT16(s);
2456 const uint16_t GdipObjectPenCacheChunkSize = Stream_Get_UINT16(s);
2457 const uint16_t GdipObjectImageAttributesCacheChunkSize = Stream_Get_UINT16(s);
2458 WLog_Print(log, WLOG_TRACE,
2459 "GdipGraphicsCacheChunkSize=0x%04" PRIx16
2460 ", GdipObjectBrushCacheChunkSize=0x%04" PRIx16
2461 ", GdipObjectPenCacheChunkSize=0x%04" PRIx16
2462 ",GdipObjectImageAttributesCacheChunkSize=0x%04" PRIx16,
2463 GdipGraphicsCacheChunkSize, GdipObjectBrushCacheChunkSize,
2464 GdipObjectPenCacheChunkSize, GdipObjectImageAttributesCacheChunkSize);
2466 const uint16_t GdipObjectImageCacheChunkSize = Stream_Get_UINT16(s);
2467 const uint16_t GdipObjectImageCacheTotalSize = Stream_Get_UINT16(s);
2468 const uint16_t GdipObjectImageCacheMaxSize = Stream_Get_UINT16(s);
2471 "GdipObjectImageCacheChunkSize=0x%04" PRIx16
", GdipObjectImageCacheTotalSize=0x%04" PRIx16
2472 ", GdipObjectImageCacheMaxSize=0x%04" PRIx16,
2473 GdipObjectImageCacheChunkSize, GdipObjectImageCacheTotalSize, GdipObjectImageCacheMaxSize);
2478static BOOL rdp_apply_remote_programs_capability_set(rdpSettings* settings,
const rdpSettings* src)
2480 WINPR_ASSERT(settings);
2483 if (settings->RemoteApplicationMode)
2484 settings->RemoteApplicationMode = src->RemoteApplicationMode;
2489 UINT32 supportLevel = src->RemoteApplicationSupportLevel;
2490 if (settings->RemoteApplicationMode)
2491 supportLevel |= RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED;
2493 settings->RemoteApplicationSupportLevel = supportLevel & settings->RemoteApplicationSupportMask;
2503static BOOL rdp_read_remote_programs_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2505 UINT32 railSupportLevel = 0;
2507 WINPR_ASSERT(settings);
2508 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2511 Stream_Read_UINT32(s, railSupportLevel);
2513 settings->RemoteApplicationMode = (railSupportLevel & RAIL_LEVEL_SUPPORTED) != 0;
2514 settings->RemoteApplicationSupportLevel = railSupportLevel;
2523static BOOL rdp_write_remote_programs_capability_set(wLog* log,
wStream* s,
2524 const rdpSettings* settings)
2526 WINPR_ASSERT(settings);
2527 if (!Stream_EnsureRemainingCapacity(s, 64))
2530 const size_t header = rdp_capability_set_start(log, s);
2531 UINT32 railSupportLevel = RAIL_LEVEL_SUPPORTED;
2533 if (settings->RemoteApplicationSupportLevel & RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED)
2535 if (settings->RemoteAppLanguageBarSupported)
2536 railSupportLevel |= RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED;
2539 railSupportLevel |= RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED;
2540 railSupportLevel |= RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED;
2541 railSupportLevel |= RAIL_LEVEL_SERVER_TO_CLIENT_IME_SYNC_SUPPORTED;
2542 railSupportLevel |= RAIL_LEVEL_HIDE_MINIMIZED_APPS_SUPPORTED;
2543 railSupportLevel |= RAIL_LEVEL_WINDOW_CLOAKING_SUPPORTED;
2544 railSupportLevel |= RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED;
2546 railSupportLevel &= settings->RemoteApplicationSupportLevel;
2547 Stream_Write_UINT32(s, railSupportLevel);
2548 return rdp_capability_set_finish(s, header, CAPSET_TYPE_RAIL);
2551#ifdef WITH_DEBUG_CAPABILITIES
2552static BOOL rdp_print_remote_programs_capability_set(wLog* log,
wStream* s)
2554 UINT32 railSupportLevel = 0;
2555 WLog_Print(log, WLOG_TRACE,
2556 "RemoteProgramsCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2558 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2561 Stream_Read_UINT32(s, railSupportLevel);
2562 WLog_Print(log, WLOG_TRACE,
"\trailSupportLevel: 0x%08" PRIX32
"", railSupportLevel);
2567static BOOL rdp_apply_window_list_capability_set(rdpSettings* settings,
const rdpSettings* src)
2569 WINPR_ASSERT(settings);
2572 settings->RemoteWndSupportLevel = src->RemoteWndSupportLevel;
2573 settings->RemoteAppNumIconCaches = src->RemoteAppNumIconCaches;
2574 settings->RemoteAppNumIconCacheEntries = src->RemoteAppNumIconCacheEntries;
2584static BOOL rdp_read_window_list_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2586 WINPR_ASSERT(settings);
2587 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 7))
2590 Stream_Read_UINT32(s, settings->RemoteWndSupportLevel);
2591 Stream_Read_UINT8(s, settings->RemoteAppNumIconCaches);
2592 Stream_Read_UINT16(s,
2593 settings->RemoteAppNumIconCacheEntries);
2602static BOOL rdp_write_window_list_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
2604 WINPR_ASSERT(settings);
2605 if (!Stream_EnsureRemainingCapacity(s, 32))
2608 const size_t header = rdp_capability_set_start(log, s);
2609 Stream_Write_UINT32(s, settings->RemoteWndSupportLevel);
2611 s, WINPR_ASSERTING_INT_CAST(uint8_t,
2612 settings->RemoteAppNumIconCaches));
2613 Stream_Write_UINT16(
2615 WINPR_ASSERTING_INT_CAST(
2616 uint16_t, settings->RemoteAppNumIconCacheEntries));
2617 return rdp_capability_set_finish(s, header, CAPSET_TYPE_WINDOW);
2620#ifdef WITH_DEBUG_CAPABILITIES
2621static BOOL rdp_print_window_list_capability_set(wLog* log,
wStream* s)
2623 UINT32 wndSupportLevel = 0;
2624 BYTE numIconCaches = 0;
2625 UINT16 numIconCacheEntries = 0;
2626 WLog_Print(log, WLOG_TRACE,
2627 "WindowListCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2629 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 7))
2632 Stream_Read_UINT32(s, wndSupportLevel);
2633 Stream_Read_UINT8(s, numIconCaches);
2634 Stream_Read_UINT16(s, numIconCacheEntries);
2635 WLog_Print(log, WLOG_TRACE,
"\twndSupportLevel: 0x%08" PRIX32
"", wndSupportLevel);
2636 WLog_Print(log, WLOG_TRACE,
"\tnumIconCaches: 0x%02" PRIX8
"", numIconCaches);
2637 WLog_Print(log, WLOG_TRACE,
"\tnumIconCacheEntries: 0x%04" PRIX16
"", numIconCacheEntries);
2642static BOOL rdp_apply_desktop_composition_capability_set(rdpSettings* settings,
2643 const rdpSettings* src)
2645 WINPR_ASSERT(settings);
2648 settings->CompDeskSupportLevel = src->CompDeskSupportLevel;
2657static BOOL rdp_read_desktop_composition_capability_set(wLog* log,
wStream* s,
2658 rdpSettings* settings)
2660 WINPR_UNUSED(settings);
2661 WINPR_ASSERT(settings);
2663 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 2))
2666 Stream_Read_UINT16(s, settings->CompDeskSupportLevel);
2675static BOOL rdp_write_desktop_composition_capability_set(wLog* log,
wStream* s,
2676 const rdpSettings* settings)
2678 WINPR_ASSERT(settings);
2680 if (!Stream_EnsureRemainingCapacity(s, 32))
2683 const size_t header = rdp_capability_set_start(log, s);
2684 const UINT16 compDeskSupportLevel =
2685 (settings->AllowDesktopComposition) ? COMPDESK_SUPPORTED : COMPDESK_NOT_SUPPORTED;
2686 Stream_Write_UINT16(s, compDeskSupportLevel);
2687 return rdp_capability_set_finish(s, header, CAPSET_TYPE_COMP_DESK);
2690#ifdef WITH_DEBUG_CAPABILITIES
2691static BOOL rdp_print_desktop_composition_capability_set(wLog* log,
wStream* s)
2693 UINT16 compDeskSupportLevel = 0;
2694 WLog_Print(log, WLOG_TRACE,
"DesktopCompositionCapabilitySet (length %" PRIuz
"):",
2695 Stream_GetRemainingLength(s));
2697 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 2))
2700 Stream_Read_UINT16(s, compDeskSupportLevel);
2701 WLog_Print(log, WLOG_TRACE,
"\tcompDeskSupportLevel: 0x%04" PRIX16
"", compDeskSupportLevel);
2706static BOOL rdp_apply_multifragment_update_capability_set(rdpSettings* settings,
2707 const rdpSettings* src)
2709 WINPR_ASSERT(settings);
2712 UINT32 multifragMaxRequestSize =
2715 if (settings->ServerMode)
2725 if (multifragMaxRequestSize < FASTPATH_MAX_PACKET_SIZE)
2726 multifragMaxRequestSize = FASTPATH_FRAGMENT_SAFE_SIZE;
2728 if (settings->RemoteFxCodec)
2735 if (multifragMaxRequestSize <
2742 settings->RemoteFxCodec = FALSE;
2744 multifragMaxRequestSize))
2755 multifragMaxRequestSize))
2766 if (multifragMaxRequestSize >
2770 multifragMaxRequestSize))
2782static BOOL rdp_read_multifragment_update_capability_set(wLog* log,
wStream* s,
2783 rdpSettings* settings)
2785 WINPR_ASSERT(settings);
2786 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2789 const UINT32 multifragMaxRequestSize = Stream_Get_UINT32(s);
2791 multifragMaxRequestSize);
2799static BOOL rdp_write_multifragment_update_capability_set(wLog* log,
wStream* s,
2800 rdpSettings* settings)
2802 WINPR_ASSERT(settings);
2803 if (settings->ServerMode &&
2817 const UINT32 tileNumX = (settings->DesktopWidth + 63) / 64;
2818 const UINT32 tileNumY = (settings->DesktopHeight + 63) / 64;
2820 WINPR_ASSERT(tileNumX < UINT32_MAX / tileNumY);
2821 WINPR_ASSERT(tileNumY < UINT32_MAX / tileNumX);
2822 WINPR_ASSERT(tileNumX * tileNumY < UINT32_MAX / 16384u);
2825 const UINT32 MultifragMaxRequestSize = (tileNumX * tileNumY + 1u) * 16384u;
2828 MultifragMaxRequestSize))
2832 if (!Stream_EnsureRemainingCapacity(s, 32))
2834 const size_t header = rdp_capability_set_start(log, s);
2835 Stream_Write_UINT32(s, settings->MultifragMaxRequestSize);
2836 return rdp_capability_set_finish(s, header, CAPSET_TYPE_MULTI_FRAGMENT_UPDATE);
2839#ifdef WITH_DEBUG_CAPABILITIES
2840static BOOL rdp_print_multifragment_update_capability_set(wLog* log,
wStream* s)
2842 UINT32 maxRequestSize = 0;
2843 WLog_Print(log, WLOG_TRACE,
"MultifragmentUpdateCapabilitySet (length %" PRIuz
"):",
2844 Stream_GetRemainingLength(s));
2846 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2849 Stream_Read_UINT32(s, maxRequestSize);
2850 WLog_Print(log, WLOG_TRACE,
"\tmaxRequestSize: 0x%08" PRIX32
"", maxRequestSize);
2855static BOOL rdp_apply_large_pointer_capability_set(rdpSettings* settings,
const rdpSettings* src)
2857 WINPR_ASSERT(settings);
2860 settings->LargePointerFlag = src->LargePointerFlag;
2869static BOOL rdp_read_large_pointer_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2871 UINT16 largePointerSupportFlags = 0;
2873 WINPR_ASSERT(settings);
2874 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 2))
2877 Stream_Read_UINT16(s, largePointerSupportFlags);
2878 settings->LargePointerFlag &= largePointerSupportFlags;
2879 if ((largePointerSupportFlags & ~(LARGE_POINTER_FLAG_96x96 | LARGE_POINTER_FLAG_384x384)) != 0)
2883 "TS_LARGE_POINTER_CAPABILITYSET with unsupported flags %04X (all flags %04X) received",
2884 WINPR_CXX_COMPAT_CAST(UINT32, largePointerSupportFlags & ~(LARGE_POINTER_FLAG_96x96 |
2885 LARGE_POINTER_FLAG_384x384)),
2886 largePointerSupportFlags);
2896static BOOL rdp_write_large_pointer_capability_set(wLog* log,
wStream* s,
2897 const rdpSettings* settings)
2899 WINPR_ASSERT(settings);
2900 if (!Stream_EnsureRemainingCapacity(s, 32))
2903 const size_t header = rdp_capability_set_start(log, s);
2904 const UINT16 largePointerSupportFlags =
2905 settings->LargePointerFlag & (LARGE_POINTER_FLAG_96x96 | LARGE_POINTER_FLAG_384x384);
2906 Stream_Write_UINT16(s, largePointerSupportFlags);
2907 return rdp_capability_set_finish(s, header, CAPSET_TYPE_LARGE_POINTER);
2910#ifdef WITH_DEBUG_CAPABILITIES
2911static BOOL rdp_print_large_pointer_capability_set(wLog* log,
wStream* s)
2913 UINT16 largePointerSupportFlags = 0;
2914 WLog_Print(log, WLOG_TRACE,
2915 "LargePointerCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2917 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 2))
2920 Stream_Read_UINT16(s, largePointerSupportFlags);
2921 WLog_Print(log, WLOG_TRACE,
"\tlargePointerSupportFlags: 0x%04" PRIX16
"",
2922 largePointerSupportFlags);
2927static BOOL rdp_apply_surface_commands_capability_set(rdpSettings* settings,
const rdpSettings* src)
2929 WINPR_ASSERT(settings);
2936 if (src->FastPathOutput)
2938 settings->SurfaceCommandsSupported &= src->SurfaceCommandsSupported;
2939 settings->SurfaceCommandsEnabled = src->SurfaceCommandsEnabled;
2940 settings->SurfaceFrameMarkerEnabled = src->SurfaceFrameMarkerEnabled;
2944 settings->SurfaceCommandsSupported = 0;
2945 settings->SurfaceCommandsEnabled = FALSE;
2946 settings->SurfaceFrameMarkerEnabled = FALSE;
2957static BOOL rdp_read_surface_commands_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2959 UINT32 cmdFlags = 0;
2961 WINPR_ASSERT(settings);
2962 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
2965 Stream_Read_UINT32(s, cmdFlags);
2966 Stream_Seek_UINT32(s);
2967 settings->SurfaceCommandsSupported = cmdFlags;
2968 settings->SurfaceCommandsEnabled =
2969 (cmdFlags & (SURFCMDS_SET_SURFACE_BITS | SURFCMDS_STREAM_SURFACE_BITS)) != 0;
2970 settings->SurfaceFrameMarkerEnabled = (cmdFlags & SURFCMDS_FRAME_MARKER) != 0;
2979static BOOL rdp_write_surface_commands_capability_set(wLog* log,
wStream* s,
2980 const rdpSettings* settings)
2982 WINPR_ASSERT(settings);
2983 if (!Stream_EnsureRemainingCapacity(s, 32))
2986 const size_t header = rdp_capability_set_start(log, s);
2990 if (settings->SurfaceFrameMarkerEnabled)
2991 cmdFlags |= SURFCMDS_FRAME_MARKER;
2993 Stream_Write_UINT32(s, cmdFlags);
2994 Stream_Write_UINT32(s, 0);
2995 return rdp_capability_set_finish(s, header, CAPSET_TYPE_SURFACE_COMMANDS);
2998static bool sUuidEqual(
const UUID* Uuid1,
const UUID* Uuid2)
3000 if (!Uuid1 && !Uuid2)
3003 if (Uuid1 && !Uuid2)
3006 if (!Uuid1 && Uuid2)
3009 if (Uuid1->Data1 != Uuid2->Data1)
3012 if (Uuid1->Data2 != Uuid2->Data2)
3015 if (Uuid1->Data3 != Uuid2->Data3)
3018 for (
int index = 0; index < 8; index++)
3020 if (Uuid1->Data4[index] != Uuid2->Data4[index])
3027#ifdef WITH_DEBUG_CAPABILITIES
3028static BOOL rdp_print_surface_commands_capability_set(wLog* log,
wStream* s)
3030 UINT32 cmdFlags = 0;
3031 UINT32 reserved = 0;
3033 WLog_Print(log, WLOG_TRACE,
3034 "SurfaceCommandsCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
3036 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
3039 Stream_Read_UINT32(s, cmdFlags);
3040 Stream_Read_UINT32(s, reserved);
3041 WLog_Print(log, WLOG_TRACE,
"\tcmdFlags: 0x%08" PRIX32
"", cmdFlags);
3042 WLog_Print(log, WLOG_TRACE,
"\treserved: 0x%08" PRIX32
"", reserved);
3046static void rdp_print_bitmap_codec_guid(wLog* log,
const GUID* guid)
3049 WLog_Print(log, WLOG_TRACE,
3050 "%08" PRIX32
"%04" PRIX16
"%04" PRIX16
"%02" PRIX8
"%02" PRIX8
"%02" PRIX8
3051 "%02" PRIX8
"%02" PRIX8
"%02" PRIX8
"%02" PRIX8
"%02" PRIX8
"",
3052 guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], guid->Data4[1],
3053 guid->Data4[2], guid->Data4[3], guid->Data4[4], guid->Data4[5], guid->Data4[6],
3057static char* rdp_get_bitmap_codec_guid_name(
const GUID* guid)
3060 if (sUuidEqual(guid, &CODEC_GUID_REMOTEFX))
3061 return "CODEC_GUID_REMOTEFX";
3062 else if (sUuidEqual(guid, &CODEC_GUID_NSCODEC))
3063 return "CODEC_GUID_NSCODEC";
3064 else if (sUuidEqual(guid, &CODEC_GUID_IGNORE))
3065 return "CODEC_GUID_IGNORE";
3066 else if (sUuidEqual(guid, &CODEC_GUID_IMAGE_REMOTEFX))
3067 return "CODEC_GUID_IMAGE_REMOTEFX";
3069#if defined(WITH_JPEG)
3070 else if (sUuidEqual(guid, &CODEC_GUID_JPEG))
3071 return "CODEC_GUID_JPEG";
3074 return "CODEC_GUID_UNKNOWN";
3078static BOOL rdp_read_bitmap_codec_guid(wLog* log,
wStream* s, GUID* guid)
3080 BYTE g[16] = WINPR_C_ARRAY_INIT;
3083 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 16))
3085 Stream_Read(s, g, 16);
3086 guid->Data1 = ((UINT32)g[3] << 24U) | ((UINT32)g[2] << 16U) | (UINT32)(g[1] << 8U) | g[0];
3087 guid->Data2 = ((g[5] << 8U) | g[4]) & 0xFFFF;
3088 guid->Data3 = ((g[7] << 8U) | g[6]) & 0xFFFF;
3089 guid->Data4[0] = g[8];
3090 guid->Data4[1] = g[9];
3091 guid->Data4[2] = g[10];
3092 guid->Data4[3] = g[11];
3093 guid->Data4[4] = g[12];
3094 guid->Data4[5] = g[13];
3095 guid->Data4[6] = g[14];
3096 guid->Data4[7] = g[15];
3100static void rdp_write_bitmap_codec_guid(
wStream* s,
const GUID* guid)
3102 BYTE g[16] = WINPR_C_ARRAY_INIT;
3104 g[0] = guid->Data1 & 0xFF;
3105 g[1] = (guid->Data1 >> 8) & 0xFF;
3106 g[2] = (guid->Data1 >> 16) & 0xFF;
3107 g[3] = (guid->Data1 >> 24) & 0xFF;
3108 g[4] = (guid->Data2) & 0xFF;
3109 g[5] = (guid->Data2 >> 8) & 0xFF;
3110 g[6] = (guid->Data3) & 0xFF;
3111 g[7] = (guid->Data3 >> 8) & 0xFF;
3112 g[8] = guid->Data4[0];
3113 g[9] = guid->Data4[1];
3114 g[10] = guid->Data4[2];
3115 g[11] = guid->Data4[3];
3116 g[12] = guid->Data4[4];
3117 g[13] = guid->Data4[5];
3118 g[14] = guid->Data4[6];
3119 g[15] = guid->Data4[7];
3120 Stream_Write(s, g, 16);
3123static BOOL rdp_apply_bitmap_codecs_capability_set(rdpSettings* settings,
const rdpSettings* src)
3125 WINPR_ASSERT(settings);
3128 if (settings->ServerMode)
3131 settings->RemoteFxCodecId = src->RemoteFxCodecId;
3132 settings->RemoteFxCaptureFlags = src->RemoteFxCaptureFlags;
3133 settings->RemoteFxOnly = src->RemoteFxOnly;
3134 settings->RemoteFxRlgrMode = src->RemoteFxRlgrMode;
3135 settings->RemoteFxCodecMode = src->RemoteFxCodecMode;
3136 settings->NSCodecId = src->NSCodecId;
3137 settings->NSCodecAllowDynamicColorFidelity = src->NSCodecAllowDynamicColorFidelity;
3138 settings->NSCodecAllowSubsampling = src->NSCodecAllowSubsampling;
3139 settings->NSCodecColorLossLevel = src->NSCodecColorLossLevel;
3142 settings->RemoteFxCodec = settings->RemoteFxCodec && src->RemoteFxCodecId;
3143 settings->RemoteFxImageCodec = settings->RemoteFxImageCodec && src->RemoteFxImageCodec;
3145 settings->NSCodec && src->NSCodec))
3147 settings->JpegCodec = src->JpegCodec;
3152static BOOL rdp_read_codec_ts_rfx_icap(wLog* log,
wStream* sub, rdpSettings* settings,
3156 UINT16 tileSize = 0;
3157 BYTE codecFlags = 0;
3158 BYTE colConvBits = 0;
3159 BYTE transformBits = 0;
3160 BYTE entropyBits = 0;
3164 WLog_Print(log, WLOG_ERROR,
3165 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP size %" PRIu16
3166 " unsupported, expecting size %" PRIu16
" not supported",
3171 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 8))
3174 Stream_Read_UINT16(sub, version);
3175 Stream_Read_UINT16(sub, tileSize);
3176 Stream_Read_UINT8(sub, codecFlags);
3177 Stream_Read_UINT8(sub, colConvBits);
3178 Stream_Read_UINT8(sub, transformBits);
3179 Stream_Read_UINT8(sub, entropyBits);
3181 if (version == 0x0009)
3184 if (tileSize != 0x0080)
3186 WLog_Print(log, WLOG_ERROR,
3187 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::version %" PRIu16
3188 " tile size %" PRIu16
" not supported",
3193 else if (version == 0x0100)
3196 if (tileSize != 0x0040)
3198 WLog_Print(log, WLOG_ERROR,
3199 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::version %" PRIu16
3200 " tile size %" PRIu16
" not supported",
3207 WLog_Print(log, WLOG_ERROR,
3208 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::version %" PRIu16
" not supported",
3214 if (colConvBits != 1)
3216 WLog_Print(log, WLOG_ERROR,
3217 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::colConvBits %" PRIu8
3218 " not supported, must be CLW_COL_CONV_ICT (0x1)",
3224 if (transformBits != 1)
3226 WLog_Print(log, WLOG_ERROR,
3227 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::transformBits %" PRIu8
3228 " not supported, must be CLW_XFORM_DWT_53_A (0x1)",
3233 const UINT8 CODEC_MODE = 0x02;
3237 if ((codecFlags & CODEC_MODE) != 0)
3242 else if ((codecFlags & ~CODEC_MODE) != 0)
3243 WLog_Print(log, WLOG_WARN,
3244 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::flags unknown value "
3246 WINPR_CXX_COMPAT_CAST(UINT32, (codecFlags & ~CODEC_MODE)));
3248 switch (entropyBits)
3250 case CLW_ENTROPY_RLGR1:
3254 case CLW_ENTROPY_RLGR3:
3259 WLog_Print(log, WLOG_ERROR,
3260 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::entropyBits "
3261 "unsupported value 0x%02" PRIx8
3262 ", must be CLW_ENTROPY_RLGR1 (0x01) or CLW_ENTROPY_RLGR3 "
3270static BOOL rdp_read_codec_ts_rfx_capset(wLog* log,
wStream* s, rdpSettings* settings)
3272 UINT16 blockType = 0;
3273 UINT32 blockLen = 0;
3274 BYTE rfxCodecId = 0;
3275 UINT16 capsetType = 0;
3276 UINT16 numIcaps = 0;
3279 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 6))
3283 Stream_Read_UINT16(s, blockType);
3284 Stream_Read_UINT32(s, blockLen);
3285 if (blockType != 0xCBC1)
3287 WLog_Print(log, WLOG_ERROR,
3288 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::blockType[0x%04" PRIx16
3289 "] != CBY_CAPSET (0xCBC1)",
3293 if (blockLen < 6ull)
3295 WLog_Print(log, WLOG_ERROR,
3296 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::blockLen[%" PRIu16
"] < 6", blockLen);
3299 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, blockLen - 6ull))
3302 wStream sbuffer = WINPR_C_ARRAY_INIT;
3303 wStream* sub = Stream_StaticConstInit(&sbuffer, Stream_Pointer(s), blockLen - 6ull);
3306 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 7))
3309 Stream_Read_UINT8(sub, rfxCodecId);
3310 Stream_Read_UINT16(sub, capsetType);
3311 Stream_Read_UINT16(sub, numIcaps);
3312 Stream_Read_UINT16(sub, icapLen);
3314 if (rfxCodecId != 1)
3316 WLog_Print(log, WLOG_ERROR,
3317 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::codecId[%" PRIu16
"] != 1", rfxCodecId);
3321 if (capsetType != 0xCFC0)
3323 WLog_Print(log, WLOG_ERROR,
3324 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::capsetType[0x%04" PRIx16
3325 "] != CLY_CAPSET (0xCFC0)",
3332 if (!rdp_read_codec_ts_rfx_icap(log, sub, settings, icapLen))
3338static BOOL rdp_read_codec_ts_rfx_caps(wLog* log,
wStream* sub, rdpSettings* settings)
3340 if (Stream_GetRemainingLength(sub) == 0)
3343 UINT16 blockType = 0;
3344 UINT32 blockLen = 0;
3345 UINT16 numCapsets = 0;
3348 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 8))
3350 Stream_Read_UINT16(sub, blockType);
3351 Stream_Read_UINT32(sub, blockLen);
3352 Stream_Read_UINT16(sub, numCapsets);
3354 if (blockType != 0xCBC0)
3356 WLog_Print(log, WLOG_ERROR,
3357 "[MS_RDPRFX] 2.2.1.1.1 TS_RFX_CAPS::blockType[0x%04" PRIx16
3358 "] != CBY_CAPS (0xCBC0)",
3365 WLog_Print(log, WLOG_ERROR,
"[MS_RDPRFX] 2.2.1.1.1 TS_RFX_CAPS::blockLen[%" PRIu16
"] != 8",
3370 if (numCapsets != 1)
3372 WLog_Print(log, WLOG_ERROR,
3373 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::numIcaps[%" PRIu16
"] != 1", numCapsets);
3377 for (UINT16 x = 0; x < numCapsets; x++)
3379 if (!rdp_read_codec_ts_rfx_capset(log, sub, settings))
3386static BOOL rdp_read_codec_ts_rfx_clnt_caps_container(wLog* log,
wStream* s, rdpSettings* settings)
3388 UINT32 rfxCapsLength = 0;
3389 UINT32 rfxPropsLength = 0;
3390 UINT32 captureFlags = 0;
3393 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
3395 Stream_Read_UINT32(s, rfxPropsLength);
3396 if (rfxPropsLength < 4)
3398 WLog_Print(log, WLOG_ERROR,
3399 "[MS_RDPRFX] 2.2.1.1 TS_RFX_CLNT_CAPS_CONTAINER::length %" PRIu32
3400 " too short, require at least 4 bytes",
3404 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, rfxPropsLength - 4ull))
3407 wStream sbuffer = WINPR_C_ARRAY_INIT;
3408 wStream* sub = Stream_StaticConstInit(&sbuffer, Stream_Pointer(s), rfxPropsLength - 4ull);
3411 Stream_Seek(s, rfxPropsLength - 4ull);
3413 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 8))
3416 Stream_Read_UINT32(sub, captureFlags);
3417 Stream_Read_UINT32(sub, rfxCapsLength);
3418 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, rfxCapsLength))
3421 settings->RemoteFxCaptureFlags = captureFlags;
3422 settings->RemoteFxOnly = !(captureFlags & CARDP_CAPS_CAPTURE_NON_CAC);
3425 wStream tsbuffer = WINPR_C_ARRAY_INIT;
3426 wStream* ts_sub = Stream_StaticConstInit(&tsbuffer, Stream_Pointer(sub), rfxCapsLength);
3427 WINPR_ASSERT(ts_sub);
3428 return rdp_read_codec_ts_rfx_caps(log, ts_sub, settings);
3436static BOOL rdp_read_bitmap_codecs_capability_set(wLog* log,
wStream* s, rdpSettings* settings,
3440 GUID codecGuid = WINPR_C_ARRAY_INIT;
3441 BYTE bitmapCodecCount = 0;
3442 UINT16 codecPropertiesLength = 0;
3444 BOOL guidNSCodec = FALSE;
3445 BOOL guidRemoteFx = FALSE;
3446 BOOL guidRemoteFxImage = FALSE;
3448 WINPR_ASSERT(settings);
3449 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 1))
3452 Stream_Read_UINT8(s, bitmapCodecCount);
3454 while (bitmapCodecCount > 0)
3456 wStream subbuffer = WINPR_C_ARRAY_INIT;
3458 if (!rdp_read_bitmap_codec_guid(log, s, &codecGuid))
3460 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 3))
3462 Stream_Read_UINT8(s, codecId);
3463 Stream_Read_UINT16(s, codecPropertiesLength);
3465 wStream* sub = Stream_StaticInit(&subbuffer, Stream_Pointer(s), codecPropertiesLength);
3466 if (!Stream_SafeSeek(s, codecPropertiesLength))
3471 if (sUuidEqual(&codecGuid, &CODEC_GUID_REMOTEFX))
3473 guidRemoteFx = TRUE;
3474 settings->RemoteFxCodecId = codecId;
3475 if (!rdp_read_codec_ts_rfx_clnt_caps_container(log, sub, settings))
3478 else if (sUuidEqual(&codecGuid, &CODEC_GUID_IMAGE_REMOTEFX))
3481 guidRemoteFxImage = TRUE;
3482 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3485 else if (sUuidEqual(&codecGuid, &CODEC_GUID_NSCODEC))
3487 BYTE colorLossLevel = 0;
3488 BYTE fAllowSubsampling = 0;
3489 BYTE fAllowDynamicFidelity = 0;
3491 settings->NSCodecId = codecId;
3492 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 3))
3494 Stream_Read_UINT8(sub, fAllowDynamicFidelity);
3495 Stream_Read_UINT8(sub, fAllowSubsampling);
3496 Stream_Read_UINT8(sub, colorLossLevel);
3498 if (colorLossLevel < 1)
3501 if (colorLossLevel > 7)
3504 settings->NSCodecAllowDynamicColorFidelity = fAllowDynamicFidelity;
3505 settings->NSCodecAllowSubsampling = fAllowSubsampling;
3506 settings->NSCodecColorLossLevel = colorLossLevel;
3508 else if (sUuidEqual(&codecGuid, &CODEC_GUID_IGNORE))
3510 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3515 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3521 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3525 const size_t rest = Stream_GetRemainingLength(sub);
3528 WLog_Print(log, WLOG_ERROR,
3529 "error while reading codec properties: actual size: %" PRIuz
3530 " expected size: %" PRIu32
"",
3531 rest + codecPropertiesLength, codecPropertiesLength);
3552static BOOL rdp_write_rfx_client_capability_container(
wStream* s,
const rdpSettings* settings)
3554 WINPR_ASSERT(settings);
3555 if (!Stream_EnsureRemainingCapacity(s, 64))
3558 const UINT32 captureFlags = settings->RemoteFxOnly ? 0 : CARDP_CAPS_CAPTURE_NON_CAC;
3560 WINPR_ASSERT(settings->RemoteFxCodecMode <= UINT8_MAX);
3561 const UINT8 codecMode = (UINT8)settings->RemoteFxCodecMode;
3562 Stream_Write_UINT16(s, 49);
3564 Stream_Write_UINT32(s, 49);
3565 Stream_Write_UINT32(s, captureFlags);
3566 Stream_Write_UINT32(s, 37);
3568 Stream_Write_UINT16(s, CBY_CAPS);
3569 Stream_Write_UINT32(s, 8);
3570 Stream_Write_UINT16(s, 1);
3572 Stream_Write_UINT16(s, CBY_CAPSET);
3573 Stream_Write_UINT32(s, 29);
3574 Stream_Write_UINT8(s, 0x01);
3575 Stream_Write_UINT16(s, CLY_CAPSET);
3576 Stream_Write_UINT16(s, 2);
3577 Stream_Write_UINT16(s, 8);
3579 Stream_Write_UINT16(s, CLW_VERSION_1_0);
3580 Stream_Write_UINT16(s, CT_TILE_64x64);
3581 Stream_Write_UINT8(s, codecMode);
3582 Stream_Write_UINT8(s, CLW_COL_CONV_ICT);
3583 Stream_Write_UINT8(s, CLW_XFORM_DWT_53_A);
3584 Stream_Write_UINT8(s, CLW_ENTROPY_RLGR1);
3586 Stream_Write_UINT16(s, CLW_VERSION_1_0);
3587 Stream_Write_UINT16(s, CT_TILE_64x64);
3588 Stream_Write_UINT8(s, codecMode);
3589 Stream_Write_UINT8(s, CLW_COL_CONV_ICT);
3590 Stream_Write_UINT8(s, CLW_XFORM_DWT_53_A);
3591 Stream_Write_UINT8(s, CLW_ENTROPY_RLGR3);
3598static BOOL rdp_write_nsc_client_capability_container(
wStream* s,
const rdpSettings* settings)
3600 WINPR_ASSERT(settings);
3602 const BOOL fAllowDynamicFidelity = settings->NSCodecAllowDynamicColorFidelity;
3603 const BOOL fAllowSubsampling = settings->NSCodecAllowSubsampling;
3604 UINT32 colorLossLevel = settings->NSCodecColorLossLevel;
3606 if (colorLossLevel < 1)
3609 if (colorLossLevel > 7)
3612 if (!Stream_EnsureRemainingCapacity(s, 8))
3615 Stream_Write_UINT16(s, 3);
3617 Stream_Write_UINT8(s, fAllowDynamicFidelity != 0);
3618 Stream_Write_UINT8(s, fAllowSubsampling != 0);
3619 Stream_Write_UINT8(s, (UINT8)colorLossLevel);
3623#if defined(WITH_JPEG)
3624static BOOL rdp_write_jpeg_client_capability_container(
wStream* s,
const rdpSettings* settings)
3626 WINPR_ASSERT(settings);
3627 if (!Stream_EnsureRemainingCapacity(s, 8))
3630 Stream_Write_UINT16(s, 1);
3631 Stream_Write_UINT8(s, settings->JpegQuality);
3639static BOOL rdp_write_rfx_server_capability_container(
wStream* s,
const rdpSettings* settings)
3641 WINPR_UNUSED(settings);
3642 WINPR_ASSERT(settings);
3644 if (!Stream_EnsureRemainingCapacity(s, 8))
3647 Stream_Write_UINT16(s, 4);
3648 Stream_Write_UINT32(s, 0);
3652#if defined(WITH_JPEG)
3653static BOOL rdp_write_jpeg_server_capability_container(
wStream* s,
const rdpSettings* settings)
3655 WINPR_UNUSED(settings);
3656 WINPR_ASSERT(settings);
3658 if (!Stream_EnsureRemainingCapacity(s, 8))
3661 Stream_Write_UINT16(s, 1);
3662 Stream_Write_UINT8(s, 75);
3670static BOOL rdp_write_nsc_server_capability_container(
wStream* s,
const rdpSettings* settings)
3672 WINPR_UNUSED(settings);
3673 WINPR_ASSERT(settings);
3675 if (!Stream_EnsureRemainingCapacity(s, 8))
3678 Stream_Write_UINT16(s, 4);
3679 Stream_Write_UINT32(s, 0);
3688static BOOL rdp_write_bitmap_codecs_capability_set(wLog* log,
wStream* s,
3689 const rdpSettings* settings)
3691 WINPR_ASSERT(settings);
3692 if (!Stream_EnsureRemainingCapacity(s, 64))
3695 const size_t header = rdp_capability_set_start(log, s);
3696 BYTE bitmapCodecCount = 0;
3698 if (settings->RemoteFxCodec)
3704#if defined(WITH_JPEG)
3706 if (settings->JpegCodec)
3711 if (settings->RemoteFxImageCodec)
3714 Stream_Write_UINT8(s, bitmapCodecCount);
3716 if (settings->RemoteFxCodec)
3718 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_REMOTEFX);
3720 if (settings->ServerMode)
3722 Stream_Write_UINT8(s, 0);
3724 if (!rdp_write_rfx_server_capability_container(s, settings))
3729 Stream_Write_UINT8(s, RDP_CODEC_ID_REMOTEFX);
3731 if (!rdp_write_rfx_client_capability_container(s, settings))
3738 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_NSCODEC);
3740 if (settings->ServerMode)
3742 Stream_Write_UINT8(s, 0);
3744 if (!rdp_write_nsc_server_capability_container(s, settings))
3749 Stream_Write_UINT8(s, RDP_CODEC_ID_NSCODEC);
3751 if (!rdp_write_nsc_client_capability_container(s, settings))
3756#if defined(WITH_JPEG)
3758 if (settings->JpegCodec)
3760 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_JPEG);
3762 if (settings->ServerMode)
3764 Stream_Write_UINT8(s, 0);
3766 if (!rdp_write_jpeg_server_capability_container(s, settings))
3771 Stream_Write_UINT8(s, RDP_CODEC_ID_JPEG);
3773 if (!rdp_write_jpeg_client_capability_container(s, settings))
3780 if (settings->RemoteFxImageCodec)
3782 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_IMAGE_REMOTEFX);
3784 if (settings->ServerMode)
3786 Stream_Write_UINT8(s, 0);
3788 if (!rdp_write_rfx_server_capability_container(s, settings))
3793 Stream_Write_UINT8(s, RDP_CODEC_ID_IMAGE_REMOTEFX);
3795 if (!rdp_write_rfx_client_capability_container(s, settings))
3800 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CODECS);
3803#ifdef WITH_DEBUG_CAPABILITIES
3804static BOOL rdp_print_bitmap_codecs_capability_set(wLog* log,
wStream* s)
3806 GUID codecGuid = WINPR_C_ARRAY_INIT;
3807 BYTE bitmapCodecCount = 0;
3809 UINT16 codecPropertiesLength = 0;
3811 WLog_Print(log, WLOG_TRACE,
3812 "BitmapCodecsCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
3814 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 1))
3817 Stream_Read_UINT8(s, bitmapCodecCount);
3818 WLog_Print(log, WLOG_TRACE,
"\tbitmapCodecCount: %" PRIu8
"", bitmapCodecCount);
3820 while (bitmapCodecCount > 0)
3822 if (!rdp_read_bitmap_codec_guid(log, s, &codecGuid))
3824 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 3))
3826 Stream_Read_UINT8(s, codecId);
3827 WLog_Print(log, WLOG_TRACE,
"\tcodecGuid: 0x");
3828 rdp_print_bitmap_codec_guid(log, &codecGuid);
3829 WLog_Print(log, WLOG_TRACE,
" (%s)", rdp_get_bitmap_codec_guid_name(&codecGuid));
3830 WLog_Print(log, WLOG_TRACE,
"\tcodecId: %" PRIu8
"", codecId);
3831 Stream_Read_UINT16(s, codecPropertiesLength);
3832 WLog_Print(log, WLOG_TRACE,
"\tcodecPropertiesLength: %" PRIu16
"", codecPropertiesLength);
3834 if (!Stream_SafeSeek(s, codecPropertiesLength))
3843static BOOL rdp_apply_frame_acknowledge_capability_set(rdpSettings* settings,
3844 const rdpSettings* src)
3846 WINPR_ASSERT(settings);
3849 if (settings->ServerMode)
3850 settings->FrameAcknowledge = src->FrameAcknowledge;
3859static BOOL rdp_read_frame_acknowledge_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
3861 WINPR_ASSERT(settings);
3862 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
3865 Stream_Read_UINT32(s, settings->FrameAcknowledge);
3874static BOOL rdp_write_frame_acknowledge_capability_set(wLog* log,
wStream* s,
3875 const rdpSettings* settings)
3877 WINPR_ASSERT(settings);
3878 if (!Stream_EnsureRemainingCapacity(s, 32))
3881 const size_t header = rdp_capability_set_start(log, s);
3882 Stream_Write_UINT32(s, settings->FrameAcknowledge);
3883 return rdp_capability_set_finish(s, header, CAPSET_TYPE_FRAME_ACKNOWLEDGE);
3886#ifdef WITH_DEBUG_CAPABILITIES
3887static BOOL rdp_print_frame_acknowledge_capability_set(wLog* log,
wStream* s)
3889 UINT32 frameAcknowledge = 0;
3890 WLog_Print(log, WLOG_TRACE,
3891 "FrameAcknowledgeCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
3893 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
3896 Stream_Read_UINT32(s, frameAcknowledge);
3897 WLog_Print(log, WLOG_TRACE,
"\tframeAcknowledge: 0x%08" PRIX32
"", frameAcknowledge);
3902static BOOL rdp_apply_bitmap_cache_v3_codec_id_capability_set(rdpSettings* settings,
3903 const rdpSettings* src)
3905 WINPR_ASSERT(settings);
3908 settings->BitmapCacheV3CodecId = src->BitmapCacheV3CodecId;
3912static BOOL rdp_read_bitmap_cache_v3_codec_id_capability_set(wLog* log,
wStream* s,
3913 rdpSettings* settings)
3915 BYTE bitmapCacheV3CodecId = 0;
3917 WINPR_ASSERT(settings);
3918 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 1))
3921 Stream_Read_UINT8(s, bitmapCacheV3CodecId);
3922 settings->BitmapCacheV3CodecId = bitmapCacheV3CodecId;
3926static BOOL rdp_write_bitmap_cache_v3_codec_id_capability_set(wLog* log,
wStream* s,
3927 const rdpSettings* settings)
3929 WINPR_ASSERT(settings);
3930 if (!Stream_EnsureRemainingCapacity(s, 32))
3933 const size_t header = rdp_capability_set_start(log, s);
3934 if (settings->BitmapCacheV3CodecId > UINT8_MAX)
3936 Stream_Write_UINT8(s, (UINT8)settings->BitmapCacheV3CodecId);
3937 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID);
3940#ifdef WITH_DEBUG_CAPABILITIES
3941static BOOL rdp_print_bitmap_cache_v3_codec_id_capability_set(wLog* log,
wStream* s)
3943 BYTE bitmapCacheV3CodecId = 0;
3944 WLog_Print(log, WLOG_TRACE,
"BitmapCacheV3CodecIdCapabilitySet (length %" PRIuz
"):",
3945 Stream_GetRemainingLength(s));
3947 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 1))
3950 Stream_Read_UINT8(s, bitmapCacheV3CodecId);
3951 WLog_Print(log, WLOG_TRACE,
"\tbitmapCacheV3CodecId: 0x%02" PRIX8
"", bitmapCacheV3CodecId);
3955BOOL rdp_print_capability_sets(wLog* log,
wStream* s,
size_t start, BOOL receiving)
3960 UINT16 numberCapabilities = 0;
3962 size_t pos = Stream_GetPosition(s);
3964 if (!Stream_SetPosition(s, start))
3969 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
3974 if (!Stream_CheckAndLogRequiredCapacityWLog(log, (s), 4))
3978 Stream_Read_UINT16(s, numberCapabilities);
3981 while (numberCapabilities > 0)
3987 if (!rdp_read_capability_set_header(log, s, &length, &type))
3990 WLog_Print(log, WLOG_TRACE,
"%s ", receiving ?
"Receiving" :
"Sending");
3991 sub = Stream_StaticInit(&subBuffer, Stream_Pointer(s), length - 4);
3992 if (!Stream_SafeSeek(s, length - 4))
3997 case CAPSET_TYPE_GENERAL:
3998 if (!rdp_print_general_capability_set(log, sub))
4003 case CAPSET_TYPE_BITMAP:
4004 if (!rdp_print_bitmap_capability_set(log, sub))
4009 case CAPSET_TYPE_ORDER:
4010 if (!rdp_print_order_capability_set(log, sub))
4015 case CAPSET_TYPE_BITMAP_CACHE:
4016 if (!rdp_print_bitmap_cache_capability_set(log, sub))
4021 case CAPSET_TYPE_CONTROL:
4022 if (!rdp_print_control_capability_set(log, sub))
4027 case CAPSET_TYPE_ACTIVATION:
4028 if (!rdp_print_window_activation_capability_set(log, sub))
4033 case CAPSET_TYPE_POINTER:
4034 if (!rdp_print_pointer_capability_set(log, sub))
4039 case CAPSET_TYPE_SHARE:
4040 if (!rdp_print_share_capability_set(log, sub))
4045 case CAPSET_TYPE_COLOR_CACHE:
4046 if (!rdp_print_color_cache_capability_set(log, sub))
4051 case CAPSET_TYPE_SOUND:
4052 if (!rdp_print_sound_capability_set(log, sub))
4057 case CAPSET_TYPE_INPUT:
4058 if (!rdp_print_input_capability_set(log, sub))
4063 case CAPSET_TYPE_FONT:
4064 if (!rdp_print_font_capability_set(log, sub))
4069 case CAPSET_TYPE_BRUSH:
4070 if (!rdp_print_brush_capability_set(log, sub))
4075 case CAPSET_TYPE_GLYPH_CACHE:
4076 if (!rdp_print_glyph_cache_capability_set(log, sub))
4081 case CAPSET_TYPE_OFFSCREEN_CACHE:
4082 if (!rdp_print_offscreen_bitmap_cache_capability_set(log, sub))
4087 case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
4088 if (!rdp_print_bitmap_cache_host_support_capability_set(log, sub))
4093 case CAPSET_TYPE_BITMAP_CACHE_V2:
4094 if (!rdp_print_bitmap_cache_v2_capability_set(log, sub))
4099 case CAPSET_TYPE_VIRTUAL_CHANNEL:
4100 if (!rdp_print_virtual_channel_capability_set(log, sub))
4105 case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
4106 if (!rdp_print_draw_nine_grid_cache_capability_set(log, sub))
4111 case CAPSET_TYPE_DRAW_GDI_PLUS:
4112 if (!rdp_print_draw_gdiplus_cache_capability_set(log, sub))
4117 case CAPSET_TYPE_RAIL:
4118 if (!rdp_print_remote_programs_capability_set(log, sub))
4123 case CAPSET_TYPE_WINDOW:
4124 if (!rdp_print_window_list_capability_set(log, sub))
4129 case CAPSET_TYPE_COMP_DESK:
4130 if (!rdp_print_desktop_composition_capability_set(log, sub))
4135 case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
4136 if (!rdp_print_multifragment_update_capability_set(log, sub))
4141 case CAPSET_TYPE_LARGE_POINTER:
4142 if (!rdp_print_large_pointer_capability_set(log, sub))
4147 case CAPSET_TYPE_SURFACE_COMMANDS:
4148 if (!rdp_print_surface_commands_capability_set(log, sub))
4153 case CAPSET_TYPE_BITMAP_CODECS:
4154 if (!rdp_print_bitmap_codecs_capability_set(log, sub))
4159 case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
4160 if (!rdp_print_frame_acknowledge_capability_set(log, sub))
4165 case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID:
4166 if (!rdp_print_bitmap_cache_v3_codec_id_capability_set(log, sub))
4172 WLog_Print(log, WLOG_ERROR,
"unknown capability type %" PRIu16
"", type);
4176 rest = Stream_GetRemainingLength(sub);
4179 WLog_Print(log, WLOG_WARN,
4180 "incorrect capability offset, type:0x%04" PRIX16
" %" PRIu16
4181 " bytes expected, %" PRIuz
"bytes remaining",
4182 type, length, rest);
4185 numberCapabilities--;
4190 if (!Stream_SetPosition(s, pos))
4197static BOOL rdp_apply_from_received(UINT16 type, rdpSettings* dst,
const rdpSettings* src)
4201 case CAPSET_TYPE_GENERAL:
4202 return rdp_apply_general_capability_set(dst, src);
4203 case CAPSET_TYPE_BITMAP:
4204 return rdp_apply_bitmap_capability_set(dst, src);
4205 case CAPSET_TYPE_ORDER:
4206 return rdp_apply_order_capability_set(dst, src);
4207 case CAPSET_TYPE_POINTER:
4208 return rdp_apply_pointer_capability_set(dst, src);
4209 case CAPSET_TYPE_INPUT:
4210 return rdp_apply_input_capability_set(dst, src);
4211 case CAPSET_TYPE_VIRTUAL_CHANNEL:
4212 return rdp_apply_virtual_channel_capability_set(dst, src);
4213 case CAPSET_TYPE_SHARE:
4214 return rdp_apply_share_capability_set(dst, src);
4215 case CAPSET_TYPE_COLOR_CACHE:
4216 return rdp_apply_color_cache_capability_set(dst, src);
4217 case CAPSET_TYPE_FONT:
4218 return rdp_apply_font_capability_set(dst, src);
4219 case CAPSET_TYPE_DRAW_GDI_PLUS:
4220 return rdp_apply_draw_gdiplus_cache_capability_set(dst, src);
4221 case CAPSET_TYPE_RAIL:
4222 return rdp_apply_remote_programs_capability_set(dst, src);
4223 case CAPSET_TYPE_WINDOW:
4224 return rdp_apply_window_list_capability_set(dst, src);
4225 case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
4226 return rdp_apply_multifragment_update_capability_set(dst, src);
4227 case CAPSET_TYPE_LARGE_POINTER:
4228 return rdp_apply_large_pointer_capability_set(dst, src);
4229 case CAPSET_TYPE_COMP_DESK:
4230 return rdp_apply_desktop_composition_capability_set(dst, src);
4231 case CAPSET_TYPE_SURFACE_COMMANDS:
4232 return rdp_apply_surface_commands_capability_set(dst, src);
4233 case CAPSET_TYPE_BITMAP_CODECS:
4234 return rdp_apply_bitmap_codecs_capability_set(dst, src);
4235 case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
4236 return rdp_apply_frame_acknowledge_capability_set(dst, src);
4237 case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID:
4238 return rdp_apply_bitmap_cache_v3_codec_id_capability_set(dst, src);
4239 case CAPSET_TYPE_BITMAP_CACHE:
4240 return rdp_apply_bitmap_cache_capability_set(dst, src);
4241 case CAPSET_TYPE_BITMAP_CACHE_V2:
4242 return rdp_apply_bitmap_cache_v2_capability_set(dst, src);
4243 case CAPSET_TYPE_BRUSH:
4244 return rdp_apply_brush_capability_set(dst, src);
4245 case CAPSET_TYPE_GLYPH_CACHE:
4246 return rdp_apply_glyph_cache_capability_set(dst, src);
4247 case CAPSET_TYPE_OFFSCREEN_CACHE:
4248 return rdp_apply_offscreen_bitmap_cache_capability_set(dst, src);
4249 case CAPSET_TYPE_SOUND:
4250 return rdp_apply_sound_capability_set(dst, src);
4251 case CAPSET_TYPE_CONTROL:
4252 return rdp_apply_control_capability_set(dst, src);
4253 case CAPSET_TYPE_ACTIVATION:
4254 return rdp_apply_window_activation_capability_set(dst, src);
4255 case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
4256 return rdp_apply_draw_nine_grid_cache_capability_set(dst, src);
4257 case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
4258 return rdp_apply_bitmap_cache_host_support_capability_set(dst, src);
4264BOOL rdp_read_capability_set(wLog* log,
wStream* sub, UINT16 type, rdpSettings* settings,
4267 WINPR_ASSERT(settings);
4269 if (type <= CAPSET_TYPE_FRAME_ACKNOWLEDGE)
4271 const size_t size = Stream_Length(sub);
4272 if (size > UINT32_MAX)
4275 WINPR_ASSERT(settings->ReceivedCapabilities);
4276 settings->ReceivedCapabilities[type] = TRUE;
4278 WINPR_ASSERT(settings->ReceivedCapabilityDataSizes);
4279 settings->ReceivedCapabilityDataSizes[type] = (UINT32)size;
4281 WINPR_ASSERT(settings->ReceivedCapabilityData);
4282 void* tmp = realloc(settings->ReceivedCapabilityData[type], size);
4283 if (!tmp && (size > 0))
4285 memcpy(tmp, Stream_Buffer(sub), size);
4286 settings->ReceivedCapabilityData[type] = tmp;
4289 WLog_Print(log, WLOG_WARN,
"not handling capability type %" PRIu16
" yet", type);
4291 BOOL treated = TRUE;
4295 case CAPSET_TYPE_GENERAL:
4296 if (!rdp_read_general_capability_set(log, sub, settings))
4301 case CAPSET_TYPE_BITMAP:
4302 if (!rdp_read_bitmap_capability_set(log, sub, settings))
4307 case CAPSET_TYPE_ORDER:
4308 if (!rdp_read_order_capability_set(log, sub, settings))
4313 case CAPSET_TYPE_POINTER:
4314 if (!rdp_read_pointer_capability_set(log, sub, settings))
4319 case CAPSET_TYPE_INPUT:
4320 if (!rdp_read_input_capability_set(log, sub, settings))
4325 case CAPSET_TYPE_VIRTUAL_CHANNEL:
4326 if (!rdp_read_virtual_channel_capability_set(log, sub, settings))
4331 case CAPSET_TYPE_SHARE:
4332 if (!rdp_read_share_capability_set(log, sub, settings))
4337 case CAPSET_TYPE_COLOR_CACHE:
4338 if (!rdp_read_color_cache_capability_set(log, sub, settings))
4343 case CAPSET_TYPE_FONT:
4344 if (!rdp_read_font_capability_set(log, sub, settings))
4349 case CAPSET_TYPE_DRAW_GDI_PLUS:
4350 if (!rdp_read_draw_gdiplus_cache_capability_set(log, sub, settings))
4355 case CAPSET_TYPE_RAIL:
4356 if (!rdp_read_remote_programs_capability_set(log, sub, settings))
4361 case CAPSET_TYPE_WINDOW:
4362 if (!rdp_read_window_list_capability_set(log, sub, settings))
4367 case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
4368 if (!rdp_read_multifragment_update_capability_set(log, sub, settings))
4373 case CAPSET_TYPE_LARGE_POINTER:
4374 if (!rdp_read_large_pointer_capability_set(log, sub, settings))
4379 case CAPSET_TYPE_COMP_DESK:
4380 if (!rdp_read_desktop_composition_capability_set(log, sub, settings))
4385 case CAPSET_TYPE_SURFACE_COMMANDS:
4386 if (!rdp_read_surface_commands_capability_set(log, sub, settings))
4391 case CAPSET_TYPE_BITMAP_CODECS:
4392 if (!rdp_read_bitmap_codecs_capability_set(log, sub, settings, isServer))
4397 case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
4398 if (!rdp_read_frame_acknowledge_capability_set(log, sub, settings))
4403 case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID:
4404 if (!rdp_read_bitmap_cache_v3_codec_id_capability_set(log, sub, settings))
4421 case CAPSET_TYPE_BITMAP_CACHE:
4422 if (!rdp_read_bitmap_cache_capability_set(log, sub, settings))
4427 case CAPSET_TYPE_BITMAP_CACHE_V2:
4428 if (!rdp_read_bitmap_cache_v2_capability_set(log, sub, settings))
4433 case CAPSET_TYPE_BRUSH:
4434 if (!rdp_read_brush_capability_set(log, sub, settings))
4439 case CAPSET_TYPE_GLYPH_CACHE:
4440 if (!rdp_read_glyph_cache_capability_set(log, sub, settings))
4445 case CAPSET_TYPE_OFFSCREEN_CACHE:
4446 if (!rdp_read_offscreen_bitmap_cache_capability_set(log, sub, settings))
4451 case CAPSET_TYPE_SOUND:
4452 if (!rdp_read_sound_capability_set(log, sub, settings))
4457 case CAPSET_TYPE_CONTROL:
4458 if (!rdp_read_control_capability_set(log, sub, settings))
4463 case CAPSET_TYPE_ACTIVATION:
4464 if (!rdp_read_window_activation_capability_set(log, sub, settings))
4469 case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
4470 if (!rdp_read_draw_nine_grid_cache_capability_set(log, sub, settings))
4476 WLog_Print(log, WLOG_ERROR,
4477 "capability %s(%" PRIu16
") not expected from client",
4478 get_capability_name(type), type);
4487 case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
4488 if (!rdp_read_bitmap_cache_host_support_capability_set(log, sub, settings))
4494 WLog_Print(log, WLOG_ERROR,
4495 "capability %s(%" PRIu16
") not expected from server",
4496 get_capability_name(type), type);
4502 const size_t rest = Stream_GetRemainingLength(sub);
4505 const size_t length = Stream_Capacity(sub);
4506 WLog_Print(log, WLOG_ERROR,
4507 "incorrect offset, type:0x%04" PRIx16
" actual:%" PRIuz
" expected:%" PRIuz
"",
4508 type, length - rest, length);
4513static BOOL rdp_read_capability_sets(wLog* log,
wStream* s, rdpSettings* settings,
4514 rdpSettings* rcvSettings, UINT16 totalLength)
4520 UINT16 numberCapabilities = 0;
4523#ifdef WITH_DEBUG_CAPABILITIES
4524 const size_t capstart = Stream_GetPosition(s);
4528 WINPR_ASSERT(settings);
4530 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
4533 Stream_Read_UINT16(s, numberCapabilities);
4535 count = numberCapabilities;
4537 start = Stream_GetPosition(s);
4538 while (numberCapabilities > 0 && Stream_GetRemainingLength(s) >= 4)
4545 if (!rdp_read_capability_set_header(log, s, &length, &type))
4547 sub = Stream_StaticInit(&subbuffer, Stream_Pointer(s), length - 4);
4548 if (!Stream_SafeSeek(s, length - 4))
4551 if (!rdp_read_capability_set(log, sub, type, rcvSettings, settings->ServerMode))
4554 if (!rdp_apply_from_received(type, settings, rcvSettings))
4556 numberCapabilities--;
4559 end = Stream_GetPosition(s);
4562 if (numberCapabilities)
4564 WLog_Print(log, WLOG_ERROR,
4565 "strange we haven't read the number of announced capacity sets, read=%d "
4566 "expected=%" PRIu16
"",
4567 count - numberCapabilities, count);
4570#ifdef WITH_DEBUG_CAPABILITIES
4571 rdp_print_capability_sets(log, s, capstart, TRUE);
4574 if (len > totalLength)
4576 WLog_Print(log, WLOG_ERROR,
"Capability length expected %" PRIu16
", actual %" PRIuz,
4580 rc = freerdp_capability_buffer_copy(settings, rcvSettings);
4585BOOL rdp_recv_get_active_header(rdpRdp* rdp,
wStream* s, UINT16* pChannelId, UINT16* length)
4588 WINPR_ASSERT(rdp->context);
4590 if (!rdp_read_header(rdp, s, length, pChannelId))
4593 if (freerdp_shall_disconnect_context(rdp->context))
4596 if (*pChannelId != MCS_GLOBAL_CHANNEL_ID)
4598 UINT16 mcsMessageChannelId = rdp->mcs->messageChannelId;
4600 if ((mcsMessageChannelId == 0) || (*pChannelId != mcsMessageChannelId))
4602 WLog_Print(rdp->log, WLOG_ERROR,
"unexpected MCS channel id %04" PRIx16
" received",
4611BOOL rdp_recv_demand_active(rdpRdp* rdp,
wStream* s, UINT16 pduSource, UINT16 length)
4613 UINT16 lengthSourceDescriptor = 0;
4614 UINT16 lengthCombinedCapabilities = 0;
4617 WINPR_ASSERT(rdp->settings);
4618 WINPR_ASSERT(rdp->context);
4621 rdp->settings->PduSource = pduSource;
4623 if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 8))
4626 Stream_Read_UINT32(s, rdp->settings->ShareId);
4627 Stream_Read_UINT16(s, lengthSourceDescriptor);
4628 Stream_Read_UINT16(s, lengthCombinedCapabilities);
4630 if (!Stream_SafeSeek(s, lengthSourceDescriptor) ||
4631 !Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 4))
4635 if (!rdp_read_capability_sets(rdp->log, s, rdp->settings, rdp->remoteSettings,
4636 lengthCombinedCapabilities))
4638 WLog_Print(rdp->log, WLOG_ERROR,
"rdp_read_capability_sets failed");
4642 if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 4))
4647 Stream_Seek_UINT32(s);
4651 secondary->glyph_v2 = (rdp->settings->GlyphSupportLevel > GLYPH_SUPPORT_FULL);
4654 return tpkt_ensure_stream_consumed(rdp->log, s, length);
4657static BOOL rdp_write_demand_active(wLog* log,
wStream* s, rdpSettings* settings)
4662 UINT16 numberCapabilities = 0;
4663 size_t lengthCombinedCapabilities = 0;
4665 if (!Stream_EnsureRemainingCapacity(s, 64))
4668 Stream_Write_UINT32(s, settings->ShareId);
4669 Stream_Write_UINT16(s, 4);
4670 lm = Stream_GetPosition(s);
4671 Stream_Seek_UINT16(s);
4672 Stream_Write(s,
"RDP", 4);
4673 bm = Stream_GetPosition(s);
4674 Stream_Seek_UINT16(s);
4675 Stream_Write_UINT16(s, 0);
4676 numberCapabilities = 14;
4678 if (!rdp_write_general_capability_set(log, s, settings) ||
4679 !rdp_write_bitmap_capability_set(log, s, settings) ||
4680 !rdp_write_order_capability_set(log, s, settings) ||
4681 !rdp_write_pointer_capability_set(log, s, settings) ||
4682 !rdp_write_input_capability_set(log, s, settings) ||
4683 !rdp_write_virtual_channel_capability_set(log, s, settings) ||
4684 !rdp_write_share_capability_set(log, s, settings) ||
4685 !rdp_write_font_capability_set(log, s, settings) ||
4686 !rdp_write_multifragment_update_capability_set(log, s, settings) ||
4687 !rdp_write_large_pointer_capability_set(log, s, settings) ||
4688 !rdp_write_desktop_composition_capability_set(log, s, settings) ||
4689 !rdp_write_surface_commands_capability_set(log, s, settings) ||
4690 !rdp_write_bitmap_codecs_capability_set(log, s, settings) ||
4691 !rdp_write_frame_acknowledge_capability_set(log, s, settings))
4698 numberCapabilities++;
4700 if (!rdp_write_bitmap_cache_host_support_capability_set(log, s, settings))
4704 if (settings->RemoteApplicationMode)
4706 numberCapabilities += 2;
4708 if (!rdp_write_remote_programs_capability_set(log, s, settings) ||
4709 !rdp_write_window_list_capability_set(log, s, settings))
4713 em = Stream_GetPosition(s);
4714 if (!Stream_SetPosition(s, lm))
4716 lengthCombinedCapabilities = (em - bm);
4717 if (lengthCombinedCapabilities > UINT16_MAX)
4719 Stream_Write_UINT16(
4720 s, (UINT16)lengthCombinedCapabilities);
4721 if (!Stream_SetPosition(s, bm))
4723 Stream_Write_UINT16(s, numberCapabilities);
4724#ifdef WITH_DEBUG_CAPABILITIES
4725 rdp_print_capability_sets(log, s, bm, FALSE);
4727 if (!Stream_SetPosition(s, em))
4729 Stream_Write_UINT32(s, 0);
4733BOOL rdp_send_demand_active(rdpRdp* rdp)
4735 UINT16 sec_flags = 0;
4736 wStream* s = rdp_send_stream_pdu_init(rdp, &sec_flags);
4742 rdp->settings->ShareId = 0x10000 + rdp->mcs->userId;
4743 status = rdp_write_demand_active(rdp->log, s, rdp->settings) &&
4744 rdp_send_pdu(rdp, s, PDU_TYPE_DEMAND_ACTIVE, rdp->mcs->userId, sec_flags);
4749BOOL rdp_recv_confirm_active(rdpRdp* rdp,
wStream* s, UINT16 pduLength)
4751 rdpSettings* settings =
nullptr;
4752 UINT16 lengthSourceDescriptor = 0;
4753 UINT16 lengthCombinedCapabilities = 0;
4757 settings = rdp->settings;
4758 WINPR_ASSERT(settings);
4760 if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 10))
4763 Stream_Seek_UINT32(s);
4764 Stream_Seek_UINT16(s);
4765 Stream_Read_UINT16(s, lengthSourceDescriptor);
4766 Stream_Read_UINT16(s, lengthCombinedCapabilities);
4768 if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, lengthSourceDescriptor + 4U))
4771 Stream_Seek(s, lengthSourceDescriptor);
4772 if (!rdp_read_capability_sets(rdp->log, s, rdp->settings, rdp->remoteSettings,
4773 lengthCombinedCapabilities))
4776 if (!settings->ReceivedCapabilities[CAPSET_TYPE_SURFACE_COMMANDS])
4779 settings->SurfaceCommandsEnabled = FALSE;
4780 settings->SurfaceFrameMarkerEnabled = FALSE;
4783 if (!settings->ReceivedCapabilities[CAPSET_TYPE_FRAME_ACKNOWLEDGE])
4786 settings->FrameAcknowledge = 0;
4789 if (!settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID])
4792 settings->BitmapCacheV3Enabled = FALSE;
4795 if (!settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CODECS])
4806 if (!settings->ReceivedCapabilities[CAPSET_TYPE_MULTI_FRAGMENT_UPDATE])
4810 FASTPATH_FRAGMENT_SAFE_SIZE))
4814 if (!settings->ReceivedCapabilities[CAPSET_TYPE_LARGE_POINTER])
4817 settings->LargePointerFlag = 0;
4820 return tpkt_ensure_stream_consumed(rdp->log, s, pduLength);
4823static BOOL rdp_write_confirm_active(wLog* log,
wStream* s, rdpSettings* settings)
4828 UINT16 numberCapabilities = 0;
4829 UINT16 lengthSourceDescriptor = 0;
4830 size_t lengthCombinedCapabilities = 0;
4833 WINPR_ASSERT(settings);
4835 lengthSourceDescriptor =
sizeof(SOURCE_DESCRIPTOR);
4836 Stream_Write_UINT32(s, settings->ShareId);
4837 Stream_Write_UINT16(s, 0x03EA);
4838 Stream_Write_UINT16(s, lengthSourceDescriptor);
4839 lm = Stream_GetPosition(s);
4840 Stream_Seek_UINT16(s);
4841 Stream_Write(s, SOURCE_DESCRIPTOR, lengthSourceDescriptor);
4842 bm = Stream_GetPosition(s);
4843 Stream_Seek_UINT16(s);
4844 Stream_Write_UINT16(s, 0);
4846 numberCapabilities = 15;
4848 if (!rdp_write_general_capability_set(log, s, settings) ||
4849 !rdp_write_bitmap_capability_set(log, s, settings) ||
4850 !rdp_write_order_capability_set(log, s, settings))
4853 if (settings->RdpVersion >= RDP_VERSION_5_PLUS)
4854 ret = rdp_write_bitmap_cache_v2_capability_set(log, s, settings);
4856 ret = rdp_write_bitmap_cache_capability_set(log, s, settings);
4861 if (!rdp_write_pointer_capability_set(log, s, settings) ||
4862 !rdp_write_input_capability_set(log, s, settings) ||
4863 !rdp_write_brush_capability_set(log, s, settings) ||
4864 !rdp_write_glyph_cache_capability_set(log, s, settings) ||
4865 !rdp_write_virtual_channel_capability_set(log, s, settings) ||
4866 !rdp_write_sound_capability_set(log, s, settings) ||
4867 !rdp_write_share_capability_set(log, s, settings) ||
4868 !rdp_write_font_capability_set(log, s, settings) ||
4869 !rdp_write_control_capability_set(log, s, settings) ||
4870 !rdp_write_color_cache_capability_set(log, s, settings) ||
4871 !rdp_write_window_activation_capability_set(log, s, settings))
4877 numberCapabilities++;
4879 if (!rdp_write_offscreen_bitmap_cache_capability_set(log, s, settings))
4883 if (settings->DrawNineGridEnabled)
4885 numberCapabilities++;
4887 if (!rdp_write_draw_nine_grid_cache_capability_set(log, s, settings))
4891 if (settings->ReceivedCapabilities[CAPSET_TYPE_LARGE_POINTER])
4893 if (settings->LargePointerFlag)
4895 numberCapabilities++;
4897 if (!rdp_write_large_pointer_capability_set(log, s, settings))
4902 if (settings->RemoteApplicationMode)
4904 numberCapabilities += 2;
4906 if (!rdp_write_remote_programs_capability_set(log, s, settings) ||
4907 !rdp_write_window_list_capability_set(log, s, settings))
4911 if (settings->ReceivedCapabilities[CAPSET_TYPE_MULTI_FRAGMENT_UPDATE])
4913 numberCapabilities++;
4915 if (!rdp_write_multifragment_update_capability_set(log, s, settings))
4919 if (settings->ReceivedCapabilities[CAPSET_TYPE_SURFACE_COMMANDS])
4921 numberCapabilities++;
4923 if (!rdp_write_surface_commands_capability_set(log, s, settings))
4927 if (settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CODECS])
4929 numberCapabilities++;
4931 if (!rdp_write_bitmap_codecs_capability_set(log, s, settings))
4935 if (!settings->ReceivedCapabilities[CAPSET_TYPE_FRAME_ACKNOWLEDGE])
4936 settings->FrameAcknowledge = 0;
4938 if (settings->FrameAcknowledge)
4940 numberCapabilities++;
4942 if (!rdp_write_frame_acknowledge_capability_set(log, s, settings))
4946 if (settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID])
4948 if (settings->BitmapCacheV3CodecId != 0)
4950 numberCapabilities++;
4952 if (!rdp_write_bitmap_cache_v3_codec_id_capability_set(log, s, settings))
4957 em = Stream_GetPosition(s);
4958 if (!Stream_SetPosition(s, lm))
4960 lengthCombinedCapabilities = (em - bm);
4961 if (lengthCombinedCapabilities > UINT16_MAX)
4963 Stream_Write_UINT16(
4964 s, (UINT16)lengthCombinedCapabilities);
4965 if (!Stream_SetPosition(s, bm))
4967 Stream_Write_UINT16(s, numberCapabilities);
4968#ifdef WITH_DEBUG_CAPABILITIES
4969 rdp_print_capability_sets(log, s, bm, FALSE);
4971 return Stream_SetPosition(s, em);
4974BOOL rdp_send_confirm_active(rdpRdp* rdp)
4976 UINT16 sec_flags = 0;
4977 wStream* s = rdp_send_stream_pdu_init(rdp, &sec_flags);
4983 status = rdp_write_confirm_active(rdp->log, s, rdp->settings) &&
4984 rdp_send_pdu(rdp, s, PDU_TYPE_CONFIRM_ACTIVE, rdp->mcs->userId, sec_flags);
4989const char* rdp_input_flag_string(UINT16 flags,
char* buffer,
size_t len)
4991 char prefix[16] = WINPR_C_ARRAY_INIT;
4993 (void)_snprintf(prefix,
sizeof(prefix),
"[0x%04" PRIx16
"][", flags);
4994 winpr_str_append(prefix, buffer, len,
"");
4995 if ((flags & INPUT_FLAG_SCANCODES) != 0)
4996 winpr_str_append(
"INPUT_FLAG_SCANCODES", buffer, len,
"|");
4997 if ((flags & INPUT_FLAG_MOUSEX) != 0)
4998 winpr_str_append(
"INPUT_FLAG_MOUSEX", buffer, len,
"|");
4999 if ((flags & INPUT_FLAG_FASTPATH_INPUT) != 0)
5000 winpr_str_append(
"INPUT_FLAG_FASTPATH_INPUT", buffer, len,
"|");
5001 if ((flags & INPUT_FLAG_UNICODE) != 0)
5002 winpr_str_append(
"INPUT_FLAG_UNICODE", buffer, len,
"|");
5003 if ((flags & INPUT_FLAG_FASTPATH_INPUT2) != 0)
5004 winpr_str_append(
"INPUT_FLAG_FASTPATH_INPUT2", buffer, len,
"|");
5005 if ((flags & INPUT_FLAG_UNUSED1) != 0)
5006 winpr_str_append(
"INPUT_FLAG_UNUSED1", buffer, len,
"|");
5007 if ((flags & INPUT_FLAG_MOUSE_RELATIVE) != 0)
5008 winpr_str_append(
"INPUT_FLAG_MOUSE_RELATIVE", buffer, len,
"|");
5009 if ((flags & TS_INPUT_FLAG_MOUSE_HWHEEL) != 0)
5010 winpr_str_append(
"TS_INPUT_FLAG_MOUSE_HWHEEL", buffer, len,
"|");
5011 if ((flags & TS_INPUT_FLAG_QOE_TIMESTAMPS) != 0)
5012 winpr_str_append(
"TS_INPUT_FLAG_QOE_TIMESTAMPS", buffer, len,
"|");
5013 winpr_str_append(
"]", buffer, len,
"");
FREERDP_API BOOL freerdp_settings_set_uint32(rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id, UINT32 val)
Sets a UINT32 settings value.
FREERDP_API BOOL freerdp_settings_set_bool(rdpSettings *settings, FreeRDP_Settings_Keys_Bool id, BOOL val)
Sets a BOOL settings value.
WINPR_ATTR_NODISCARD FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.
FREERDP_API BOOL freerdp_settings_set_pointer_len(rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id, const void *data, size_t len)
Set a pointer to value data.
WINPR_ATTR_NODISCARD FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.
FREERDP_API BOOL freerdp_settings_set_string_len(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const char *val, size_t len)
Sets a string settings value. The val is copied.
FREERDP_API BOOL freerdp_settings_set_string(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const char *val)
Sets a string settings value. The param is copied.