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>
37static const size_t bitmapCacheV2CellInfoLimits[] = { 600, 600, 65536, 4096, 2048 };
39static const char*
const CAPSET_TYPE_STRINGS[] = {
"Unknown",
56 "Offscreen Bitmap Cache",
57 "Bitmap Cache Host Support",
64 "Desktop Composition",
65 "Multifragment Update",
69 "Frame Acknowledge" };
72static const char* get_capability_name(UINT16 type)
74 if (type > CAPSET_TYPE_FRAME_ACKNOWLEDGE)
77 return CAPSET_TYPE_STRINGS[type];
80#ifdef WITH_DEBUG_CAPABILITIES
81static BOOL rdp_print_capability_sets(wLog* log,
wStream* s,
size_t start, BOOL receiving);
86static const GUID CODEC_GUID_REMOTEFX = {
87 0x76772F12, 0xBD72, 0x4463, { 0xAF, 0xB3, 0xB7, 0x3C, 0x9C, 0x6F, 0x78, 0x86 }
92static const GUID CODEC_GUID_NSCODEC = {
93 0xCA8D1BB9, 0x000F, 0x154F, { 0x58, 0x9F, 0xAE, 0x2D, 0x1A, 0x87, 0xE2, 0xD6 }
98static const GUID CODEC_GUID_IGNORE = {
99 0x9C4351A6, 0x3535, 0x42AE, { 0x91, 0x0C, 0xCD, 0xFC, 0xE5, 0x76, 0x0B, 0x58 }
104static const GUID CODEC_GUID_IMAGE_REMOTEFX = {
105 0x2744CCD4, 0x9D8A, 0x4E74, { 0x80, 0x3C, 0x0E, 0xCB, 0xEE, 0xA1, 0x9C, 0x54 }
108#if defined(WITH_JPEG)
111static const GUID CODEC_GUID_JPEG = {
112 0x430C9EED, 0x1BAF, 0x4CE6, { 0x86, 0x9A, 0xCB, 0x8B, 0x37, 0xB6, 0x62, 0x37 }
117static BOOL rdp_read_capability_set_header(wLog* log,
wStream* s, UINT16* length, UINT16* type)
120 WINPR_ASSERT(length);
123 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
125 Stream_Read_UINT16(s, *type);
126 Stream_Read_UINT16(s, *length);
127 return (*length >= 4);
130static void rdp_write_capability_set_header(
wStream* s, UINT16 length, UINT16 type)
133 WINPR_ASSERT(Stream_GetRemainingCapacity(s) >= 4);
134 Stream_Write_UINT16(s, type);
135 Stream_Write_UINT16(s, length);
139static size_t rdp_capability_set_start(wLog* log,
wStream* s)
141 size_t header = Stream_GetPosition(s);
142 if (!Stream_CheckAndLogRequiredCapacityWLog(log, (s), CAPSET_HEADER_LENGTH))
144 Stream_Zero(s, CAPSET_HEADER_LENGTH);
149static BOOL rdp_capability_set_finish(
wStream* s,
size_t header, UINT16 type)
151 const size_t footer = Stream_GetPosition(s);
154 if (header > UINT16_MAX)
156 const size_t length = footer - header;
157 if ((Stream_Capacity(s) < header + 4ULL) || (length > UINT16_MAX))
159 if (!Stream_SetPosition(s, header))
161 rdp_write_capability_set_header(s, (UINT16)length, type);
162 return Stream_SetPosition(s, footer);
166static BOOL rdp_apply_general_capability_set(rdpSettings* settings,
const rdpSettings* src)
168 WINPR_ASSERT(settings);
171 if (settings->ServerMode)
173 settings->OsMajorType = src->OsMajorType;
174 settings->OsMinorType = src->OsMinorType;
177 settings->CapsProtocolVersion = src->CapsProtocolVersion;
178 settings->NoBitmapCompressionHeader = src->NoBitmapCompressionHeader;
179 settings->LongCredentialsSupported = src->LongCredentialsSupported;
180 settings->AutoReconnectionPacketSupported = src->AutoReconnectionPacketSupported;
181 if (!src->FastPathOutput)
182 settings->FastPathOutput = FALSE;
184 if (!src->SaltedChecksum)
185 settings->SaltedChecksum = FALSE;
187 if (!settings->ServerMode)
194 if (!src->RefreshRect)
195 settings->RefreshRect = FALSE;
197 if (!src->SuppressOutput)
198 settings->SuppressOutput = FALSE;
208static BOOL rdp_read_general_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
210 UINT16 extraFlags = 0;
211 BYTE refreshRectSupport = 0;
212 BYTE suppressOutputSupport = 0;
214 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 20))
217 WINPR_ASSERT(settings);
218 Stream_Read_UINT16(s, settings->OsMajorType);
219 Stream_Read_UINT16(s, settings->OsMinorType);
221 Stream_Read_UINT16(s, settings->CapsProtocolVersion);
222 if (settings->CapsProtocolVersion != TS_CAPS_PROTOCOLVERSION)
224 WLog_Print(log, WLOG_ERROR,
225 "TS_GENERAL_CAPABILITYSET::protocolVersion(0x%04" PRIx16
226 ") != TS_CAPS_PROTOCOLVERSION(0x%04" PRIx32
")",
227 settings->CapsProtocolVersion,
228 WINPR_CXX_COMPAT_CAST(UINT32, TS_CAPS_PROTOCOLVERSION));
229 if (settings->CapsProtocolVersion == 0x0000)
231 WLog_Print(log, WLOG_WARN,
232 "TS_GENERAL_CAPABILITYSET::protocolVersion(0x%04" PRIx16
233 " assuming old FreeRDP, ignoring protocol violation, correcting value.",
234 settings->CapsProtocolVersion);
235 settings->CapsProtocolVersion = TS_CAPS_PROTOCOLVERSION;
240 Stream_Seek_UINT16(s);
242 s, settings->CapsGeneralCompressionTypes);
243 Stream_Read_UINT16(s, extraFlags);
244 Stream_Read_UINT16(s, settings->CapsUpdateCapabilityFlag);
245 Stream_Read_UINT16(s, settings->CapsRemoteUnshareFlag);
247 s, settings->CapsGeneralCompressionLevel);
248 Stream_Read_UINT8(s, refreshRectSupport);
249 Stream_Read_UINT8(s, suppressOutputSupport);
250 settings->NoBitmapCompressionHeader = (extraFlags & NO_BITMAP_COMPRESSION_HDR) != 0;
251 settings->LongCredentialsSupported = (extraFlags & LONG_CREDENTIALS_SUPPORTED) != 0;
253 settings->AutoReconnectionPacketSupported = (extraFlags & AUTORECONNECT_SUPPORTED) != 0;
254 settings->FastPathOutput = (extraFlags & FASTPATH_OUTPUT_SUPPORTED) != 0;
255 settings->SaltedChecksum = (extraFlags & ENC_SALTED_CHECKSUM) != 0;
256 settings->RefreshRect = refreshRectSupport;
257 settings->SuppressOutput = suppressOutputSupport;
267static BOOL rdp_write_general_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
269 if (!Stream_EnsureRemainingCapacity(s, 64))
272 const size_t header = rdp_capability_set_start(log, s);
273 UINT16 extraFlags = 0;
275 WINPR_ASSERT(settings);
276 if (settings->LongCredentialsSupported)
277 extraFlags |= LONG_CREDENTIALS_SUPPORTED;
279 if (settings->NoBitmapCompressionHeader)
280 extraFlags |= NO_BITMAP_COMPRESSION_HDR;
282 if (settings->AutoReconnectionPacketSupported)
283 extraFlags |= AUTORECONNECT_SUPPORTED;
285 if (settings->FastPathOutput)
286 extraFlags |= FASTPATH_OUTPUT_SUPPORTED;
288 if (settings->SaltedChecksum)
289 extraFlags |= ENC_SALTED_CHECKSUM;
291 if ((settings->OsMajorType > UINT16_MAX) || (settings->OsMinorType > UINT16_MAX))
293 WLog_Print(log, WLOG_ERROR,
294 "OsMajorType=%08" PRIx32
", OsMinorType=%08" PRIx32
295 " they need to be smaller %04" PRIx32,
296 settings->OsMajorType, settings->OsMinorType,
297 WINPR_CXX_COMPAT_CAST(UINT32, UINT16_MAX));
300 if (settings->CapsProtocolVersion != TS_CAPS_PROTOCOLVERSION)
302 WLog_Print(log, WLOG_ERROR,
303 "TS_GENERAL_CAPABILITYSET::protocolVersion(0x%04" PRIx16
304 ") != TS_CAPS_PROTOCOLVERSION(0x%04" PRIx32
")",
305 settings->CapsProtocolVersion,
306 WINPR_CXX_COMPAT_CAST(UINT32, TS_CAPS_PROTOCOLVERSION));
309 Stream_Write_UINT16(s, (UINT16)settings->OsMajorType);
310 Stream_Write_UINT16(s, (UINT16)settings->OsMinorType);
311 Stream_Write_UINT16(s, settings->CapsProtocolVersion);
312 Stream_Write_UINT16(s, 0);
314 s, settings->CapsGeneralCompressionTypes);
315 Stream_Write_UINT16(s, extraFlags);
316 Stream_Write_UINT16(s, settings->CapsUpdateCapabilityFlag);
317 Stream_Write_UINT16(s, settings->CapsRemoteUnshareFlag);
319 s, settings->CapsGeneralCompressionLevel);
320 Stream_Write_UINT8(s, settings->RefreshRect ? 1 : 0);
321 Stream_Write_UINT8(s, settings->SuppressOutput ? 1 : 0);
322 return rdp_capability_set_finish(s, header, CAPSET_TYPE_GENERAL);
325#ifdef WITH_DEBUG_CAPABILITIES
327static BOOL rdp_print_general_capability_set(wLog* log,
wStream* s)
329 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 20))
332 WLog_Print(log, WLOG_TRACE,
333 "GeneralCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
334 const uint16_t osMinorType = Stream_Get_UINT16(s);
335 const uint16_t osMajorType = Stream_Get_UINT16(s);
336 const uint16_t protocolVersion = Stream_Get_UINT16(s);
337 const uint16_t pad2OctetsA = Stream_Get_UINT16(s);
338 const uint16_t generalCompressionTypes =
339 Stream_Get_UINT16(s);
340 const uint16_t extraFlags = Stream_Get_UINT16(s);
341 const uint16_t updateCapabilityFlag = Stream_Get_UINT16(s);
342 const uint16_t remoteUnshareFlag = Stream_Get_UINT16(s);
343 const uint16_t generalCompressionLevel =
344 Stream_Get_UINT16(s);
345 const uint8_t refreshRectSupport = Stream_Get_UINT8(s);
346 const uint8_t suppressOutputSupport = Stream_Get_UINT8(s);
347 WLog_Print(log, WLOG_TRACE,
"\tosMajorType: 0x%04" PRIX16
"", osMajorType);
348 WLog_Print(log, WLOG_TRACE,
"\tosMinorType: 0x%04" PRIX16
"", osMinorType);
349 WLog_Print(log, WLOG_TRACE,
"\tprotocolVersion: 0x%04" PRIX16
"", protocolVersion);
350 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
351 WLog_Print(log, WLOG_TRACE,
"\tgeneralCompressionTypes: 0x%04" PRIX16
"",
352 generalCompressionTypes);
353 WLog_Print(log, WLOG_TRACE,
"\textraFlags: 0x%04" PRIX16
"", extraFlags);
354 WLog_Print(log, WLOG_TRACE,
"\tupdateCapabilityFlag: 0x%04" PRIX16
"", updateCapabilityFlag);
355 WLog_Print(log, WLOG_TRACE,
"\tremoteUnshareFlag: 0x%04" PRIX16
"", remoteUnshareFlag);
356 WLog_Print(log, WLOG_TRACE,
"\tgeneralCompressionLevel: 0x%04" PRIX16
"",
357 generalCompressionLevel);
358 WLog_Print(log, WLOG_TRACE,
"\trefreshRectSupport: 0x%02" PRIX8
"", refreshRectSupport);
359 WLog_Print(log, WLOG_TRACE,
"\tsuppressOutputSupport: 0x%02" PRIX8
"", suppressOutputSupport);
365static BOOL rdp_apply_bitmap_capability_set(rdpSettings* settings,
const rdpSettings* src)
367 WINPR_ASSERT(settings);
370 if (!settings->ServerMode)
377 if (!src->DesktopResize)
378 settings->DesktopResize = FALSE;
380 if (!settings->ServerMode && settings->DesktopResize)
384 settings->DesktopWidth = src->DesktopWidth;
385 settings->DesktopHeight = src->DesktopHeight;
388 if (settings->DrawAllowSkipAlpha)
389 settings->DrawAllowSkipAlpha = src->DrawAllowSkipAlpha;
391 if (settings->DrawAllowDynamicColorFidelity)
392 settings->DrawAllowDynamicColorFidelity = src->DrawAllowDynamicColorFidelity;
394 if (settings->DrawAllowColorSubsampling)
395 settings->DrawAllowColorSubsampling = src->DrawAllowColorSubsampling;
405static BOOL rdp_read_bitmap_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
407 BYTE drawingFlags = 0;
408 UINT16 desktopWidth = 0;
409 UINT16 desktopHeight = 0;
410 UINT16 desktopResizeFlag = 0;
411 UINT16 preferredBitsPerPixel = 0;
413 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 24))
416 Stream_Read_UINT16(s, preferredBitsPerPixel);
417 Stream_Seek_UINT16(s);
418 Stream_Seek_UINT16(s);
419 Stream_Seek_UINT16(s);
420 Stream_Read_UINT16(s, desktopWidth);
421 Stream_Read_UINT16(s, desktopHeight);
422 Stream_Seek_UINT16(s);
423 Stream_Read_UINT16(s, desktopResizeFlag);
424 Stream_Seek_UINT16(s);
425 Stream_Seek_UINT8(s);
426 Stream_Read_UINT8(s, drawingFlags);
427 Stream_Seek_UINT16(s);
428 Stream_Seek_UINT16(s);
432 settings->DesktopResize = desktopResizeFlag;
433 settings->DesktopWidth = desktopWidth;
434 settings->DesktopHeight = desktopHeight;
435 settings->DrawAllowSkipAlpha = (drawingFlags & DRAW_ALLOW_SKIP_ALPHA) != 0;
436 settings->DrawAllowDynamicColorFidelity =
437 (drawingFlags & DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY) != 0;
438 settings->DrawAllowColorSubsampling = (drawingFlags & DRAW_ALLOW_COLOR_SUBSAMPLING) != 0;
448static BOOL rdp_write_bitmap_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
450 BYTE drawingFlags = 0;
451 UINT16 preferredBitsPerPixel = 0;
453 if (!Stream_EnsureRemainingCapacity(s, 64))
456 const size_t header = rdp_capability_set_start(log, s);
458 WINPR_ASSERT(settings);
459 if (settings->DrawAllowSkipAlpha)
460 drawingFlags |= DRAW_ALLOW_SKIP_ALPHA;
462 if (settings->DrawAllowDynamicColorFidelity)
463 drawingFlags |= DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY;
465 if (settings->DrawAllowColorSubsampling)
466 drawingFlags |= DRAW_ALLOW_COLOR_SUBSAMPLING;
478 (settings->DesktopWidth > UINT16_MAX) || (settings->DesktopHeight > UINT16_MAX))
481 if (settings->RdpVersion >= RDP_VERSION_5_PLUS)
484 preferredBitsPerPixel = 8;
486 Stream_Write_UINT16(s, preferredBitsPerPixel);
487 Stream_Write_UINT16(s, 1);
488 Stream_Write_UINT16(s, 1);
489 Stream_Write_UINT16(s, 1);
490 Stream_Write_UINT16(s, (UINT16)settings->DesktopWidth);
491 Stream_Write_UINT16(s, (UINT16)settings->DesktopHeight);
492 Stream_Write_UINT16(s, 0);
493 Stream_Write_UINT16(s, (UINT16)settings->DesktopResize);
494 Stream_Write_UINT16(s, 1);
495 Stream_Write_UINT8(s, 0);
496 Stream_Write_UINT8(s, drawingFlags);
497 Stream_Write_UINT16(s, 1);
498 Stream_Write_UINT16(s, 0);
499 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP);
502#ifdef WITH_DEBUG_CAPABILITIES
504static BOOL rdp_print_bitmap_capability_set(wLog* log,
wStream* s)
506 UINT16 preferredBitsPerPixel = 0;
507 UINT16 receive1BitPerPixel = 0;
508 UINT16 receive4BitsPerPixel = 0;
509 UINT16 receive8BitsPerPixel = 0;
510 UINT16 desktopWidth = 0;
511 UINT16 desktopHeight = 0;
512 UINT16 pad2Octets = 0;
513 UINT16 desktopResizeFlag = 0;
514 UINT16 bitmapCompressionFlag = 0;
515 BYTE highColorFlags = 0;
516 BYTE drawingFlags = 0;
517 UINT16 multipleRectangleSupport = 0;
518 UINT16 pad2OctetsB = 0;
519 WLog_Print(log, WLOG_TRACE,
520 "BitmapCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
522 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 24))
525 Stream_Read_UINT16(s, preferredBitsPerPixel);
526 Stream_Read_UINT16(s, receive1BitPerPixel);
527 Stream_Read_UINT16(s, receive4BitsPerPixel);
528 Stream_Read_UINT16(s, receive8BitsPerPixel);
529 Stream_Read_UINT16(s, desktopWidth);
530 Stream_Read_UINT16(s, desktopHeight);
531 Stream_Read_UINT16(s, pad2Octets);
532 Stream_Read_UINT16(s, desktopResizeFlag);
533 Stream_Read_UINT16(s, bitmapCompressionFlag);
534 Stream_Read_UINT8(s, highColorFlags);
535 Stream_Read_UINT8(s, drawingFlags);
536 Stream_Read_UINT16(s, multipleRectangleSupport);
537 Stream_Read_UINT16(s, pad2OctetsB);
538 WLog_Print(log, WLOG_TRACE,
"\tpreferredBitsPerPixel: 0x%04" PRIX16
"", preferredBitsPerPixel);
539 WLog_Print(log, WLOG_TRACE,
"\treceive1BitPerPixel: 0x%04" PRIX16
"", receive1BitPerPixel);
540 WLog_Print(log, WLOG_TRACE,
"\treceive4BitsPerPixel: 0x%04" PRIX16
"", receive4BitsPerPixel);
541 WLog_Print(log, WLOG_TRACE,
"\treceive8BitsPerPixel: 0x%04" PRIX16
"", receive8BitsPerPixel);
542 WLog_Print(log, WLOG_TRACE,
"\tdesktopWidth: 0x%04" PRIX16
"", desktopWidth);
543 WLog_Print(log, WLOG_TRACE,
"\tdesktopHeight: 0x%04" PRIX16
"", desktopHeight);
544 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
545 WLog_Print(log, WLOG_TRACE,
"\tdesktopResizeFlag: 0x%04" PRIX16
"", desktopResizeFlag);
546 WLog_Print(log, WLOG_TRACE,
"\tbitmapCompressionFlag: 0x%04" PRIX16
"", bitmapCompressionFlag);
547 WLog_Print(log, WLOG_TRACE,
"\thighColorFlags: 0x%02" PRIX8
"", highColorFlags);
548 WLog_Print(log, WLOG_TRACE,
"\tdrawingFlags: 0x%02" PRIX8
"", drawingFlags);
549 WLog_Print(log, WLOG_TRACE,
"\tmultipleRectangleSupport: 0x%04" PRIX16
"",
550 multipleRectangleSupport);
551 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsB: 0x%04" PRIX16
"", pad2OctetsB);
557static BOOL rdp_apply_order_capability_set(rdpSettings* settings,
const rdpSettings* src)
559 WINPR_ASSERT(settings);
562 BOOL BitmapCacheV3Enabled = FALSE;
563 BOOL FrameMarkerCommandEnabled = FALSE;
565 for (
size_t i = 0; i < 32; i++)
567 if (!src->OrderSupport[i])
568 settings->OrderSupport[i] = FALSE;
571 if (src->OrderSupportFlags & ORDER_FLAGS_EXTRA_SUPPORT)
573 if (src->OrderSupportFlagsEx & CACHE_BITMAP_V3_SUPPORT)
574 BitmapCacheV3Enabled = TRUE;
576 if (src->OrderSupportFlagsEx & ALTSEC_FRAME_MARKER_SUPPORT)
577 FrameMarkerCommandEnabled = TRUE;
580 if (BitmapCacheV3Enabled && settings->BitmapCacheV3Enabled)
582 settings->BitmapCacheV3Enabled = src->BitmapCacheV3Enabled;
583 settings->BitmapCacheVersion = src->BitmapCacheVersion;
586 settings->BitmapCacheV3Enabled = FALSE;
588 settings->FrameMarkerCommandEnabled =
589 (FrameMarkerCommandEnabled && src->FrameMarkerCommandEnabled);
599static BOOL rdp_read_order_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
601 char terminalDescriptor[17] = WINPR_C_ARRAY_INIT;
602 BYTE orderSupport[32] = WINPR_C_ARRAY_INIT;
603 BOOL BitmapCacheV3Enabled = FALSE;
604 BOOL FrameMarkerCommandEnabled = FALSE;
606 WINPR_ASSERT(settings);
607 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 84))
610 Stream_Read(s, terminalDescriptor, 16);
611 Stream_Seek_UINT32(s);
612 Stream_Seek_UINT16(s);
613 Stream_Seek_UINT16(s);
614 Stream_Seek_UINT16(s);
615 Stream_Seek_UINT16(s);
616 Stream_Seek_UINT16(s);
617 Stream_Read_UINT16(s, settings->OrderSupportFlags);
618 Stream_Read(s, orderSupport, 32);
619 Stream_Seek_UINT16(s);
620 Stream_Read_UINT16(s, settings->OrderSupportFlagsEx);
621 Stream_Seek_UINT32(s);
622 Stream_Seek_UINT32(s);
623 Stream_Seek_UINT16(s);
624 Stream_Seek_UINT16(s);
625 Stream_Read_UINT16(s, settings->TextANSICodePage);
626 Stream_Seek_UINT16(s);
631 for (
size_t i = 0; i < ARRAYSIZE(orderSupport); i++)
632 settings->OrderSupport[i] = orderSupport[i];
634 if (settings->OrderSupportFlags & ORDER_FLAGS_EXTRA_SUPPORT)
636 BitmapCacheV3Enabled = (settings->OrderSupportFlagsEx & CACHE_BITMAP_V3_SUPPORT) != 0;
637 FrameMarkerCommandEnabled =
638 (settings->OrderSupportFlagsEx & ALTSEC_FRAME_MARKER_SUPPORT) != 0;
641 settings->BitmapCacheV3Enabled = BitmapCacheV3Enabled;
642 if (BitmapCacheV3Enabled)
643 settings->BitmapCacheVersion = 3;
645 settings->FrameMarkerCommandEnabled = FrameMarkerCommandEnabled;
655static BOOL rdp_write_order_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
657 char terminalDescriptor[16] = WINPR_C_ARRAY_INIT;
659 WINPR_ASSERT(settings);
660 if (!Stream_EnsureRemainingCapacity(s, 64))
663 const size_t header = rdp_capability_set_start(log, s);
665 UINT16 orderSupportExFlags = settings->OrderSupportFlagsEx;
666 UINT16 orderFlags = settings->OrderSupportFlags;
668 if (settings->BitmapCacheV3Enabled)
670 if ((orderSupportExFlags & CACHE_BITMAP_V3_SUPPORT) == 0)
672 WLog_Print(log, WLOG_WARN,
673 "rdpSettings::BitmapCacheV3Enabled=TRUE, but CACHE_BITMAP_V3_SUPPORT not "
674 "set in rdpSettings::OrderSupportEx, aborting.");
676 if ((orderFlags & ORDER_FLAGS_EXTRA_SUPPORT) == 0)
678 WLog_Print(log, WLOG_WARN,
679 "rdpSettings::BitmapCacheV3Enabled=TRUE, but ORDER_FLAGS_EXTRA_SUPPORT not "
680 "set in rdpSettings::OrderSupport, aborting.");
684 if (settings->FrameMarkerCommandEnabled)
686 if ((orderSupportExFlags & ALTSEC_FRAME_MARKER_SUPPORT) == 0)
690 "rdpSettings::FrameMarkerCommandEnabled=TRUE, but "
691 "ALTSEC_FRAME_MARKER_SUPPORT not set in rdpSettings::OrderSupportEx, aborting.");
693 if ((orderFlags & ORDER_FLAGS_EXTRA_SUPPORT) == 0)
695 WLog_Print(log, WLOG_WARN,
696 "rdpSettings::FrameMarkerCommandEnabled=TRUE, but ORDER_FLAGS_EXTRA_SUPPORT "
697 "not set in rdpSettings::OrderSupport, aborting.");
704 const size_t len = strnlen(dsc, ARRAYSIZE(terminalDescriptor));
705 strncpy(terminalDescriptor, dsc, len);
707 Stream_Write(s, terminalDescriptor,
708 sizeof(terminalDescriptor));
709 Stream_Write_UINT32(s, 0);
710 Stream_Write_UINT16(s, 1);
711 Stream_Write_UINT16(s, 20);
712 Stream_Write_UINT16(s, 0);
713 Stream_Write_UINT16(s, 1);
714 Stream_Write_UINT16(s, 0);
715 Stream_Write_UINT16(s, orderFlags);
716 Stream_Write(s, settings->OrderSupport, 32);
717 Stream_Write_UINT16(s, 0);
718 Stream_Write_UINT16(s, orderSupportExFlags);
719 Stream_Write_UINT32(s, 0);
720 Stream_Write_UINT32(s, 230400);
721 Stream_Write_UINT16(s, 0);
722 Stream_Write_UINT16(s, 0);
723 Stream_Write_UINT16(s, settings->TextANSICodePage);
724 Stream_Write_UINT16(s, 0);
725 return rdp_capability_set_finish(s, header, CAPSET_TYPE_ORDER);
728#ifdef WITH_DEBUG_CAPABILITIES
730static BOOL rdp_print_order_capability_set(wLog* log,
wStream* s)
732 BYTE terminalDescriptor[16];
733 UINT32 pad4OctetsA = 0;
734 UINT16 desktopSaveXGranularity = 0;
735 UINT16 desktopSaveYGranularity = 0;
736 UINT16 pad2OctetsA = 0;
737 UINT16 maximumOrderLevel = 0;
738 UINT16 numberFonts = 0;
739 UINT16 orderFlags = 0;
740 BYTE orderSupport[32];
741 UINT16 textFlags = 0;
742 UINT16 orderSupportExFlags = 0;
743 UINT32 pad4OctetsB = 0;
744 UINT32 desktopSaveSize = 0;
745 UINT16 pad2OctetsC = 0;
746 UINT16 pad2OctetsD = 0;
747 UINT16 textANSICodePage = 0;
748 UINT16 pad2OctetsE = 0;
749 WLog_Print(log, WLOG_TRACE,
750 "OrderCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
752 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 84))
755 Stream_Read(s, terminalDescriptor, 16);
756 Stream_Read_UINT32(s, pad4OctetsA);
757 Stream_Read_UINT16(s, desktopSaveXGranularity);
758 Stream_Read_UINT16(s, desktopSaveYGranularity);
759 Stream_Read_UINT16(s, pad2OctetsA);
760 Stream_Read_UINT16(s, maximumOrderLevel);
761 Stream_Read_UINT16(s, numberFonts);
762 Stream_Read_UINT16(s, orderFlags);
763 Stream_Read(s, orderSupport, 32);
764 Stream_Read_UINT16(s, textFlags);
765 Stream_Read_UINT16(s, orderSupportExFlags);
766 Stream_Read_UINT32(s, pad4OctetsB);
767 Stream_Read_UINT32(s, desktopSaveSize);
768 Stream_Read_UINT16(s, pad2OctetsC);
769 Stream_Read_UINT16(s, pad2OctetsD);
770 Stream_Read_UINT16(s, textANSICodePage);
771 Stream_Read_UINT16(s, pad2OctetsE);
772 WLog_Print(log, WLOG_TRACE,
"\tpad4OctetsA: 0x%08" PRIX32
"", pad4OctetsA);
773 WLog_Print(log, WLOG_TRACE,
"\tdesktopSaveXGranularity: 0x%04" PRIX16
"",
774 desktopSaveXGranularity);
775 WLog_Print(log, WLOG_TRACE,
"\tdesktopSaveYGranularity: 0x%04" PRIX16
"",
776 desktopSaveYGranularity);
777 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
778 WLog_Print(log, WLOG_TRACE,
"\tmaximumOrderLevel: 0x%04" PRIX16
"", maximumOrderLevel);
779 WLog_Print(log, WLOG_TRACE,
"\tnumberFonts: 0x%04" PRIX16
"", numberFonts);
780 WLog_Print(log, WLOG_TRACE,
"\torderFlags: 0x%04" PRIX16
"", orderFlags);
781 WLog_Print(log, WLOG_TRACE,
"\torderSupport:");
782 WLog_Print(log, WLOG_TRACE,
"\t\tDSTBLT: %" PRIu8
"", orderSupport[NEG_DSTBLT_INDEX]);
783 WLog_Print(log, WLOG_TRACE,
"\t\tPATBLT: %" PRIu8
"", orderSupport[NEG_PATBLT_INDEX]);
784 WLog_Print(log, WLOG_TRACE,
"\t\tSCRBLT: %" PRIu8
"", orderSupport[NEG_SCRBLT_INDEX]);
785 WLog_Print(log, WLOG_TRACE,
"\t\tMEMBLT: %" PRIu8
"", orderSupport[NEG_MEMBLT_INDEX]);
786 WLog_Print(log, WLOG_TRACE,
"\t\tMEM3BLT: %" PRIu8
"", orderSupport[NEG_MEM3BLT_INDEX]);
787 WLog_Print(log, WLOG_TRACE,
"\t\tATEXTOUT: %" PRIu8
"", orderSupport[NEG_ATEXTOUT_INDEX]);
788 WLog_Print(log, WLOG_TRACE,
"\t\tAEXTTEXTOUT: %" PRIu8
"", orderSupport[NEG_AEXTTEXTOUT_INDEX]);
789 WLog_Print(log, WLOG_TRACE,
"\t\tDRAWNINEGRID: %" PRIu8
"",
790 orderSupport[NEG_DRAWNINEGRID_INDEX]);
791 WLog_Print(log, WLOG_TRACE,
"\t\tLINETO: %" PRIu8
"", orderSupport[NEG_LINETO_INDEX]);
792 WLog_Print(log, WLOG_TRACE,
"\t\tMULTI_DRAWNINEGRID: %" PRIu8
"",
793 orderSupport[NEG_MULTI_DRAWNINEGRID_INDEX]);
794 WLog_Print(log, WLOG_TRACE,
"\t\tOPAQUE_RECT: %" PRIu8
"", orderSupport[NEG_OPAQUE_RECT_INDEX]);
795 WLog_Print(log, WLOG_TRACE,
"\t\tSAVEBITMAP: %" PRIu8
"", orderSupport[NEG_SAVEBITMAP_INDEX]);
796 WLog_Print(log, WLOG_TRACE,
"\t\tWTEXTOUT: %" PRIu8
"", orderSupport[NEG_WTEXTOUT_INDEX]);
797 WLog_Print(log, WLOG_TRACE,
"\t\tMEMBLT_V2: %" PRIu8
"", orderSupport[NEG_MEMBLT_V2_INDEX]);
798 WLog_Print(log, WLOG_TRACE,
"\t\tMEM3BLT_V2: %" PRIu8
"", orderSupport[NEG_MEM3BLT_V2_INDEX]);
799 WLog_Print(log, WLOG_TRACE,
"\t\tMULTIDSTBLT: %" PRIu8
"", orderSupport[NEG_MULTIDSTBLT_INDEX]);
800 WLog_Print(log, WLOG_TRACE,
"\t\tMULTIPATBLT: %" PRIu8
"", orderSupport[NEG_MULTIPATBLT_INDEX]);
801 WLog_Print(log, WLOG_TRACE,
"\t\tMULTISCRBLT: %" PRIu8
"", orderSupport[NEG_MULTISCRBLT_INDEX]);
802 WLog_Print(log, WLOG_TRACE,
"\t\tMULTIOPAQUERECT: %" PRIu8
"",
803 orderSupport[NEG_MULTIOPAQUERECT_INDEX]);
804 WLog_Print(log, WLOG_TRACE,
"\t\tFAST_INDEX: %" PRIu8
"", orderSupport[NEG_FAST_INDEX_INDEX]);
805 WLog_Print(log, WLOG_TRACE,
"\t\tPOLYGON_SC: %" PRIu8
"", orderSupport[NEG_POLYGON_SC_INDEX]);
806 WLog_Print(log, WLOG_TRACE,
"\t\tPOLYGON_CB: %" PRIu8
"", orderSupport[NEG_POLYGON_CB_INDEX]);
807 WLog_Print(log, WLOG_TRACE,
"\t\tPOLYLINE: %" PRIu8
"", orderSupport[NEG_POLYLINE_INDEX]);
808 WLog_Print(log, WLOG_TRACE,
"\t\tUNUSED23: %" PRIu8
"", orderSupport[NEG_UNUSED23_INDEX]);
809 WLog_Print(log, WLOG_TRACE,
"\t\tFAST_GLYPH: %" PRIu8
"", orderSupport[NEG_FAST_GLYPH_INDEX]);
810 WLog_Print(log, WLOG_TRACE,
"\t\tELLIPSE_SC: %" PRIu8
"", orderSupport[NEG_ELLIPSE_SC_INDEX]);
811 WLog_Print(log, WLOG_TRACE,
"\t\tELLIPSE_CB: %" PRIu8
"", orderSupport[NEG_ELLIPSE_CB_INDEX]);
812 WLog_Print(log, WLOG_TRACE,
"\t\tGLYPH_INDEX: %" PRIu8
"", orderSupport[NEG_GLYPH_INDEX_INDEX]);
813 WLog_Print(log, WLOG_TRACE,
"\t\tGLYPH_WEXTTEXTOUT: %" PRIu8
"",
814 orderSupport[NEG_GLYPH_WEXTTEXTOUT_INDEX]);
815 WLog_Print(log, WLOG_TRACE,
"\t\tGLYPH_WLONGTEXTOUT: %" PRIu8
"",
816 orderSupport[NEG_GLYPH_WLONGTEXTOUT_INDEX]);
817 WLog_Print(log, WLOG_TRACE,
"\t\tGLYPH_WLONGEXTTEXTOUT: %" PRIu8
"",
818 orderSupport[NEG_GLYPH_WLONGEXTTEXTOUT_INDEX]);
819 WLog_Print(log, WLOG_TRACE,
"\t\tUNUSED31: %" PRIu8
"", orderSupport[NEG_UNUSED31_INDEX]);
820 WLog_Print(log, WLOG_TRACE,
"\ttextFlags: 0x%04" PRIX16
"", textFlags);
821 WLog_Print(log, WLOG_TRACE,
"\torderSupportExFlags: 0x%04" PRIX16
"", orderSupportExFlags);
822 WLog_Print(log, WLOG_TRACE,
"\tpad4OctetsB: 0x%08" PRIX32
"", pad4OctetsB);
823 WLog_Print(log, WLOG_TRACE,
"\tdesktopSaveSize: 0x%08" PRIX32
"", desktopSaveSize);
824 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsC: 0x%04" PRIX16
"", pad2OctetsC);
825 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsD: 0x%04" PRIX16
"", pad2OctetsD);
826 WLog_Print(log, WLOG_TRACE,
"\ttextANSICodePage: 0x%04" PRIX16
"", textANSICodePage);
827 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsE: 0x%04" PRIX16
"", pad2OctetsE);
833static BOOL rdp_apply_bitmap_cache_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
834 WINPR_ATTR_UNUSED
const rdpSettings* src)
836 WINPR_ASSERT(settings);
846static BOOL rdp_read_bitmap_cache_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
848 WINPR_UNUSED(settings);
849 WINPR_ASSERT(settings);
851 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
854 Stream_Seek_UINT32(s);
855 Stream_Seek_UINT32(s);
856 Stream_Seek_UINT32(s);
857 Stream_Seek_UINT32(s);
858 Stream_Seek_UINT32(s);
859 Stream_Seek_UINT32(s);
860 Stream_Seek_UINT16(s);
861 Stream_Seek_UINT16(s);
862 Stream_Seek_UINT16(s);
863 Stream_Seek_UINT16(s);
864 Stream_Seek_UINT16(s);
865 Stream_Seek_UINT16(s);
874static BOOL rdp_write_bitmap_cache_capability_set(wLog* log,
wStream* s,
875 const rdpSettings* settings)
877 if (!Stream_EnsureRemainingCapacity(s, 64))
880 const size_t header = rdp_capability_set_start(log, s);
882 if (bpp > UINT16_MAX)
884 Stream_Write_UINT32(s, 0);
885 Stream_Write_UINT32(s, 0);
886 Stream_Write_UINT32(s, 0);
887 Stream_Write_UINT32(s, 0);
888 Stream_Write_UINT32(s, 0);
889 Stream_Write_UINT32(s, 0);
890 UINT32 size = bpp * 256;
891 if (size > UINT16_MAX)
893 Stream_Write_UINT16(s, 200);
894 Stream_Write_UINT16(s, (UINT16)size);
896 if (size > UINT16_MAX)
898 Stream_Write_UINT16(s, 600);
899 Stream_Write_UINT16(s, (UINT16)size);
901 if (size > UINT16_MAX)
903 Stream_Write_UINT16(s, 1000);
904 Stream_Write_UINT16(s, (UINT16)size);
905 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE);
908#ifdef WITH_DEBUG_CAPABILITIES
910static BOOL rdp_print_bitmap_cache_capability_set(wLog* log,
wStream* s)
918 UINT16 Cache0Entries = 0;
919 UINT16 Cache0MaximumCellSize = 0;
920 UINT16 Cache1Entries = 0;
921 UINT16 Cache1MaximumCellSize = 0;
922 UINT16 Cache2Entries = 0;
923 UINT16 Cache2MaximumCellSize = 0;
924 WLog_Print(log, WLOG_TRACE,
925 "BitmapCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
927 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
930 Stream_Read_UINT32(s, pad1);
931 Stream_Read_UINT32(s, pad2);
932 Stream_Read_UINT32(s, pad3);
933 Stream_Read_UINT32(s, pad4);
934 Stream_Read_UINT32(s, pad5);
935 Stream_Read_UINT32(s, pad6);
936 Stream_Read_UINT16(s, Cache0Entries);
937 Stream_Read_UINT16(s, Cache0MaximumCellSize);
938 Stream_Read_UINT16(s, Cache1Entries);
939 Stream_Read_UINT16(s, Cache1MaximumCellSize);
940 Stream_Read_UINT16(s, Cache2Entries);
941 Stream_Read_UINT16(s, Cache2MaximumCellSize);
942 WLog_Print(log, WLOG_TRACE,
"\tpad1: 0x%08" PRIX32
"", pad1);
943 WLog_Print(log, WLOG_TRACE,
"\tpad2: 0x%08" PRIX32
"", pad2);
944 WLog_Print(log, WLOG_TRACE,
"\tpad3: 0x%08" PRIX32
"", pad3);
945 WLog_Print(log, WLOG_TRACE,
"\tpad4: 0x%08" PRIX32
"", pad4);
946 WLog_Print(log, WLOG_TRACE,
"\tpad5: 0x%08" PRIX32
"", pad5);
947 WLog_Print(log, WLOG_TRACE,
"\tpad6: 0x%08" PRIX32
"", pad6);
948 WLog_Print(log, WLOG_TRACE,
"\tCache0Entries: 0x%04" PRIX16
"", Cache0Entries);
949 WLog_Print(log, WLOG_TRACE,
"\tCache0MaximumCellSize: 0x%04" PRIX16
"", Cache0MaximumCellSize);
950 WLog_Print(log, WLOG_TRACE,
"\tCache1Entries: 0x%04" PRIX16
"", Cache1Entries);
951 WLog_Print(log, WLOG_TRACE,
"\tCache1MaximumCellSize: 0x%04" PRIX16
"", Cache1MaximumCellSize);
952 WLog_Print(log, WLOG_TRACE,
"\tCache2Entries: 0x%04" PRIX16
"", Cache2Entries);
953 WLog_Print(log, WLOG_TRACE,
"\tCache2MaximumCellSize: 0x%04" PRIX16
"", Cache2MaximumCellSize);
959static BOOL rdp_apply_control_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
960 WINPR_ATTR_UNUSED
const rdpSettings* src)
962 WINPR_ASSERT(settings);
973static BOOL rdp_read_control_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
975 WINPR_UNUSED(settings);
976 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
979 Stream_Seek_UINT16(s);
980 Stream_Seek_UINT16(s);
981 Stream_Seek_UINT16(s);
982 Stream_Seek_UINT16(s);
991static BOOL rdp_write_control_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
993 WINPR_UNUSED(settings);
994 if (!Stream_EnsureRemainingCapacity(s, 32))
997 const size_t header = rdp_capability_set_start(log, s);
998 Stream_Write_UINT16(s, 0);
999 Stream_Write_UINT16(s, 0);
1000 Stream_Write_UINT16(s, 2);
1001 Stream_Write_UINT16(s, 2);
1002 return rdp_capability_set_finish(s, header, CAPSET_TYPE_CONTROL);
1005#ifdef WITH_DEBUG_CAPABILITIES
1007static BOOL rdp_print_control_capability_set(wLog* log,
wStream* s)
1009 UINT16 controlFlags = 0;
1010 UINT16 remoteDetachFlag = 0;
1011 UINT16 controlInterest = 0;
1012 UINT16 detachInterest = 0;
1013 WLog_Print(log, WLOG_TRACE,
1014 "ControlCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1016 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1019 Stream_Read_UINT16(s, controlFlags);
1020 Stream_Read_UINT16(s, remoteDetachFlag);
1021 Stream_Read_UINT16(s, controlInterest);
1022 Stream_Read_UINT16(s, detachInterest);
1023 WLog_Print(log, WLOG_TRACE,
"\tcontrolFlags: 0x%04" PRIX16
"", controlFlags);
1024 WLog_Print(log, WLOG_TRACE,
"\tremoteDetachFlag: 0x%04" PRIX16
"", remoteDetachFlag);
1025 WLog_Print(log, WLOG_TRACE,
"\tcontrolInterest: 0x%04" PRIX16
"", controlInterest);
1026 WLog_Print(log, WLOG_TRACE,
"\tdetachInterest: 0x%04" PRIX16
"", detachInterest);
1032static BOOL rdp_apply_window_activation_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
1033 WINPR_ATTR_UNUSED
const rdpSettings* src)
1035 WINPR_ASSERT(settings);
1046static BOOL rdp_read_window_activation_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1048 WINPR_UNUSED(settings);
1049 WINPR_ASSERT(settings);
1050 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1053 Stream_Seek_UINT16(s);
1054 Stream_Seek_UINT16(s);
1055 Stream_Seek_UINT16(s);
1056 Stream_Seek_UINT16(s);
1065static BOOL rdp_write_window_activation_capability_set(wLog* log,
wStream* s,
1066 const rdpSettings* settings)
1068 WINPR_UNUSED(settings);
1069 WINPR_ASSERT(settings);
1070 if (!Stream_EnsureRemainingCapacity(s, 32))
1073 const size_t header = rdp_capability_set_start(log, s);
1074 Stream_Write_UINT16(s, 0);
1075 Stream_Write_UINT16(s, 0);
1076 Stream_Write_UINT16(s, 0);
1077 Stream_Write_UINT16(s, 0);
1078 return rdp_capability_set_finish(s, header, CAPSET_TYPE_ACTIVATION);
1081#ifdef WITH_DEBUG_CAPABILITIES
1083static BOOL rdp_print_window_activation_capability_set(wLog* log,
wStream* s)
1085 UINT16 helpKeyFlag = 0;
1086 UINT16 helpKeyIndexFlag = 0;
1087 UINT16 helpExtendedKeyFlag = 0;
1088 UINT16 windowManagerKeyFlag = 0;
1089 WLog_Print(log, WLOG_TRACE,
1090 "WindowActivationCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1092 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1095 Stream_Read_UINT16(s, helpKeyFlag);
1096 Stream_Read_UINT16(s, helpKeyIndexFlag);
1097 Stream_Read_UINT16(s, helpExtendedKeyFlag);
1098 Stream_Read_UINT16(s, windowManagerKeyFlag);
1099 WLog_Print(log, WLOG_TRACE,
"\thelpKeyFlag: 0x%04" PRIX16
"", helpKeyFlag);
1100 WLog_Print(log, WLOG_TRACE,
"\thelpKeyIndexFlag: 0x%04" PRIX16
"", helpKeyIndexFlag);
1101 WLog_Print(log, WLOG_TRACE,
"\thelpExtendedKeyFlag: 0x%04" PRIX16
"", helpExtendedKeyFlag);
1102 WLog_Print(log, WLOG_TRACE,
"\twindowManagerKeyFlag: 0x%04" PRIX16
"", windowManagerKeyFlag);
1107static BOOL rdp_apply_pointer_capability_set(rdpSettings* settings,
const rdpSettings* src)
1109 WINPR_ASSERT(settings);
1113 const UINT32 colorPointerCacheSize =
1115 const UINT32 dstPointerCacheSize =
1117 const UINT32 dstColorPointerCacheSize =
1121 const UINT32 actualPointerCacheSize = MIN(pointerCacheSize, dstPointerCacheSize);
1122 const UINT32 actualColorPointerCacheSize = MIN(colorPointerCacheSize, dstColorPointerCacheSize);
1127 actualColorPointerCacheSize));
1135static BOOL rdp_read_pointer_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1137 UINT16 colorPointerFlag = 0;
1138 UINT16 colorPointerCacheSize = 0;
1139 UINT16 pointerCacheSize = 0;
1141 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1144 Stream_Read_UINT16(s, colorPointerFlag);
1145 Stream_Read_UINT16(s, colorPointerCacheSize);
1147 if (colorPointerFlag == 0)
1149 WLog_Print(log, WLOG_WARN,
1150 "[MS-RDPBCGR] 2.2.7.1.5 Pointer Capability Set "
1151 "(TS_POINTER_CAPABILITYSET)::colorPointerFlag received is %" PRIu16
1152 ". Value is ignored and always assumed to be TRUE",
1157 if (Stream_GetRemainingLength(s) >= 2)
1158 Stream_Read_UINT16(s, pointerCacheSize);
1160 WINPR_ASSERT(settings);
1161 settings->PointerCacheSize = pointerCacheSize;
1162 settings->ColorPointerCacheSize = colorPointerCacheSize;
1172static BOOL rdp_write_pointer_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1174 if (!Stream_EnsureRemainingCapacity(s, 32))
1177 const size_t header = rdp_capability_set_start(log, s);
1178 if (settings->PointerCacheSize > UINT16_MAX)
1180 if (settings->ColorPointerCacheSize > UINT16_MAX)
1183 WINPR_ASSERT(settings);
1184 const UINT32 colorPointerFlag =
1187 Stream_Write_UINT16(s, colorPointerFlag);
1188 Stream_Write_UINT16(
1189 s, (UINT16)settings->ColorPointerCacheSize);
1190 Stream_Write_UINT16(s, (UINT16)settings->PointerCacheSize);
1192 return rdp_capability_set_finish(s, header, CAPSET_TYPE_POINTER);
1195#ifdef WITH_DEBUG_CAPABILITIES
1197static BOOL rdp_print_pointer_capability_set(wLog* log,
wStream* s)
1199 UINT16 colorPointerFlag = 0;
1200 UINT16 colorPointerCacheSize = 0;
1201 UINT16 pointerCacheSize = 0;
1203 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 6))
1206 WLog_Print(log, WLOG_TRACE,
1207 "PointerCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1208 Stream_Read_UINT16(s, colorPointerFlag);
1209 Stream_Read_UINT16(s, colorPointerCacheSize);
1210 Stream_Read_UINT16(s, pointerCacheSize);
1211 WLog_Print(log, WLOG_TRACE,
"\tcolorPointerFlag: 0x%04" PRIX16
"", colorPointerFlag);
1212 WLog_Print(log, WLOG_TRACE,
"\tcolorPointerCacheSize: 0x%04" PRIX16
"", colorPointerCacheSize);
1213 WLog_Print(log, WLOG_TRACE,
"\tpointerCacheSize: 0x%04" PRIX16
"", pointerCacheSize);
1219static BOOL rdp_apply_share_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
1220 WINPR_ATTR_UNUSED
const rdpSettings* src)
1222 WINPR_ASSERT(settings);
1233static BOOL rdp_read_share_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1235 WINPR_UNUSED(settings);
1236 WINPR_ASSERT(settings);
1238 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1241 Stream_Seek_UINT16(s);
1242 Stream_Seek_UINT16(s);
1251static BOOL rdp_write_share_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1253 if (!Stream_EnsureRemainingCapacity(s, 32))
1256 const size_t header = rdp_capability_set_start(log, s);
1258 WINPR_ASSERT(settings);
1259 const UINT16 nodeId = (settings->ServerMode) ? 0x03EA : 0;
1260 Stream_Write_UINT16(s, nodeId);
1261 Stream_Write_UINT16(s, 0);
1262 return rdp_capability_set_finish(s, header, CAPSET_TYPE_SHARE);
1265#ifdef WITH_DEBUG_CAPABILITIES
1267static BOOL rdp_print_share_capability_set(wLog* log,
wStream* s)
1270 UINT16 pad2Octets = 0;
1271 WLog_Print(log, WLOG_TRACE,
1272 "ShareCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1274 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1277 Stream_Read_UINT16(s, nodeId);
1278 Stream_Read_UINT16(s, pad2Octets);
1279 WLog_Print(log, WLOG_TRACE,
"\tnodeId: 0x%04" PRIX16
"", nodeId);
1280 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1286static BOOL rdp_apply_color_cache_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
1287 WINPR_ATTR_UNUSED
const rdpSettings* src)
1289 WINPR_ASSERT(settings);
1299static BOOL rdp_read_color_cache_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1301 WINPR_UNUSED(settings);
1302 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1305 Stream_Seek_UINT16(s);
1306 Stream_Seek_UINT16(s);
1315static BOOL rdp_write_color_cache_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1317 WINPR_UNUSED(settings);
1318 if (!Stream_EnsureRemainingCapacity(s, 32))
1321 const size_t header = rdp_capability_set_start(log, s);
1322 Stream_Write_UINT16(s, 6);
1323 Stream_Write_UINT16(s, 0);
1324 return rdp_capability_set_finish(s, header, CAPSET_TYPE_COLOR_CACHE);
1327#ifdef WITH_DEBUG_CAPABILITIES
1329static BOOL rdp_print_color_cache_capability_set(wLog* log,
wStream* s)
1331 UINT16 colorTableCacheSize = 0;
1332 UINT16 pad2Octets = 0;
1333 WLog_Print(log, WLOG_TRACE,
1334 "ColorCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1336 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1339 Stream_Read_UINT16(s, colorTableCacheSize);
1340 Stream_Read_UINT16(s, pad2Octets);
1341 WLog_Print(log, WLOG_TRACE,
"\tcolorTableCacheSize: 0x%04" PRIX16
"", colorTableCacheSize);
1342 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1348static BOOL rdp_apply_sound_capability_set(rdpSettings* settings,
const rdpSettings* src)
1350 WINPR_ASSERT(settings);
1353 settings->SoundBeepsEnabled = src->SoundBeepsEnabled;
1363static BOOL rdp_read_sound_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1365 UINT16 soundFlags = 0;
1367 WINPR_ASSERT(settings);
1368 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1371 Stream_Read_UINT16(s, soundFlags);
1372 Stream_Seek_UINT16(s);
1373 settings->SoundBeepsEnabled = (soundFlags & SOUND_BEEPS_FLAG) != 0;
1382static BOOL rdp_write_sound_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1384 WINPR_ASSERT(settings);
1385 if (!Stream_EnsureRemainingCapacity(s, 32))
1388 const size_t header = rdp_capability_set_start(log, s);
1389 const UINT16 soundFlags = (settings->SoundBeepsEnabled) ? SOUND_BEEPS_FLAG : 0;
1390 Stream_Write_UINT16(s, soundFlags);
1391 Stream_Write_UINT16(s, 0);
1392 return rdp_capability_set_finish(s, header, CAPSET_TYPE_SOUND);
1395#ifdef WITH_DEBUG_CAPABILITIES
1397static BOOL rdp_print_sound_capability_set(wLog* log,
wStream* s)
1399 UINT16 soundFlags = 0;
1400 UINT16 pad2OctetsA = 0;
1401 WLog_Print(log, WLOG_TRACE,
1402 "SoundCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1404 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1407 Stream_Read_UINT16(s, soundFlags);
1408 Stream_Read_UINT16(s, pad2OctetsA);
1409 WLog_Print(log, WLOG_TRACE,
"\tsoundFlags: 0x%04" PRIX16
"", soundFlags);
1410 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
1416static BOOL rdp_apply_input_capability_set(rdpSettings* settings,
const rdpSettings* src)
1418 WINPR_ASSERT(settings);
1421 if (settings->ServerMode)
1423 settings->KeyboardLayout = src->KeyboardLayout;
1424 settings->KeyboardType = src->KeyboardType;
1425 settings->KeyboardSubType = src->KeyboardSubType;
1426 settings->KeyboardFunctionKey = src->KeyboardFunctionKey;
1432 if (!settings->ServerMode)
1434 settings->FastPathInput = src->FastPathInput;
1440 if (settings->HasHorizontalWheel)
1441 settings->HasHorizontalWheel = src->HasHorizontalWheel;
1449 if (settings->HasExtendedMouseEvent)
1450 settings->HasExtendedMouseEvent = src->HasExtendedMouseEvent;
1451 if (settings->HasRelativeMouseEvent)
1452 settings->HasRelativeMouseEvent = src->HasRelativeMouseEvent;
1464static BOOL rdp_read_input_capability_set(wLog* log,
wStream* s, rdpSettings* settings,
1467 UINT16 inputFlags = 0;
1469 WINPR_ASSERT(settings);
1470 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 84))
1473 Stream_Read_UINT16(s, inputFlags);
1474 Stream_Seek_UINT16(s);
1476 Stream_Read_UINT32(s, settings->KeyboardLayout);
1477 Stream_Read_UINT32(s, settings->KeyboardType);
1478 Stream_Read_UINT32(s, settings->KeyboardSubType);
1479 Stream_Read_UINT32(s, settings->KeyboardFunctionKey);
1485 freerdp_settings_sanitize_keyboard_type(log, settings,
"TS_INPUT_CAPABILITYSET");
1488 WCHAR wstr[32] = WINPR_C_ARRAY_INIT;
1489 char str[65] = WINPR_C_ARRAY_INIT;
1495 if (!Stream_Read_UTF16_String(s, wstr, ARRAYSIZE(wstr)))
1498 if (ConvertWCharNToUtf8(wstr, ARRAYSIZE(wstr), str, ARRAYSIZE(str)) < 0)
1499 memset(str, 0,
sizeof(str));
1507 (INPUT_FLAG_FASTPATH_INPUT | INPUT_FLAG_FASTPATH_INPUT2)))
1510 (inputFlags & TS_INPUT_FLAG_MOUSE_HWHEEL) != 0))
1513 (inputFlags & INPUT_FLAG_UNICODE) != 0))
1516 (inputFlags & INPUT_FLAG_MOUSE_RELATIVE) != 0))
1519 (inputFlags & INPUT_FLAG_MOUSEX) != 0))
1522 (inputFlags & TS_INPUT_FLAG_QOE_TIMESTAMPS) != 0))
1533static BOOL rdp_write_input_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1535 WINPR_ASSERT(settings);
1536 if (!Stream_EnsureRemainingCapacity(s, 128))
1539 const size_t header = rdp_capability_set_start(log, s);
1540 UINT16 inputFlags = INPUT_FLAG_SCANCODES;
1542 if (settings->FastPathInput)
1544 inputFlags |= INPUT_FLAG_FASTPATH_INPUT;
1545 inputFlags |= INPUT_FLAG_FASTPATH_INPUT2;
1549 inputFlags |= INPUT_FLAG_MOUSE_RELATIVE;
1552 inputFlags |= TS_INPUT_FLAG_MOUSE_HWHEEL;
1555 inputFlags |= INPUT_FLAG_UNICODE;
1558 inputFlags |= TS_INPUT_FLAG_QOE_TIMESTAMPS;
1560 if (settings->HasExtendedMouseEvent)
1561 inputFlags |= INPUT_FLAG_MOUSEX;
1563 Stream_Write_UINT16(s, inputFlags);
1564 Stream_Write_UINT16(s, 0);
1565 Stream_Write_UINT32(s, settings->KeyboardLayout);
1566 Stream_Write_UINT32(s, settings->KeyboardType);
1567 Stream_Write_UINT32(s, settings->KeyboardSubType);
1568 Stream_Write_UINT32(s, settings->KeyboardFunctionKey);
1570 return rdp_capability_set_finish(s, header, CAPSET_TYPE_INPUT);
1573#ifdef WITH_DEBUG_CAPABILITIES
1575static BOOL rdp_print_input_capability_set(wLog* log,
wStream* s)
1577 UINT16 inputFlags = 0;
1578 UINT16 pad2OctetsA = 0;
1579 UINT32 keyboardLayout = 0;
1580 UINT32 keyboardType = 0;
1581 UINT32 keyboardSubType = 0;
1582 UINT32 keyboardFunctionKey = 0;
1583 WLog_Print(log, WLOG_TRACE,
"InputCapabilitySet (length %" PRIuz
")",
1584 Stream_GetRemainingLength(s));
1586 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 84))
1589 Stream_Read_UINT16(s, inputFlags);
1590 Stream_Read_UINT16(s, pad2OctetsA);
1591 Stream_Read_UINT32(s, keyboardLayout);
1592 Stream_Read_UINT32(s, keyboardType);
1593 Stream_Read_UINT32(s, keyboardSubType);
1594 Stream_Read_UINT32(s, keyboardFunctionKey);
1596 WLog_Print(log, WLOG_TRACE,
"\tinputFlags: 0x%04" PRIX16
"", inputFlags);
1597 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
1598 WLog_Print(log, WLOG_TRACE,
"\tkeyboardLayout: 0x%08" PRIX32
"", keyboardLayout);
1599 WLog_Print(log, WLOG_TRACE,
"\tkeyboardType: 0x%08" PRIX32
"", keyboardType);
1600 WLog_Print(log, WLOG_TRACE,
"\tkeyboardSubType: 0x%08" PRIX32
"", keyboardSubType);
1601 WLog_Print(log, WLOG_TRACE,
"\tkeyboardFunctionKey: 0x%08" PRIX32
"", keyboardFunctionKey);
1607static BOOL rdp_apply_font_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
1608 WINPR_ATTR_UNUSED
const rdpSettings* src)
1610 WINPR_ASSERT(settings);
1620static BOOL rdp_read_font_capability_set(WINPR_ATTR_UNUSED wLog* log,
wStream* s,
1621 rdpSettings* settings)
1623 WINPR_UNUSED(settings);
1624 if (Stream_GetRemainingLength(s) >= 2)
1625 Stream_Seek_UINT16(s);
1627 if (Stream_GetRemainingLength(s) >= 2)
1628 Stream_Seek_UINT16(s);
1638static BOOL rdp_write_font_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1640 WINPR_UNUSED(settings);
1641 if (!Stream_EnsureRemainingCapacity(s, 32))
1644 const size_t header = rdp_capability_set_start(log, s);
1645 Stream_Write_UINT16(s, FONTSUPPORT_FONTLIST);
1646 Stream_Write_UINT16(s, 0);
1647 return rdp_capability_set_finish(s, header, CAPSET_TYPE_FONT);
1650#ifdef WITH_DEBUG_CAPABILITIES
1652static BOOL rdp_print_font_capability_set(wLog* log,
wStream* s)
1654 UINT16 fontSupportFlags = 0;
1655 UINT16 pad2Octets = 0;
1656 WLog_Print(log, WLOG_TRACE,
1657 "FontCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1659 if (Stream_GetRemainingLength(s) >= 2)
1660 Stream_Read_UINT16(s, fontSupportFlags);
1662 if (Stream_GetRemainingLength(s) >= 2)
1663 Stream_Read_UINT16(s, pad2Octets);
1665 WLog_Print(log, WLOG_TRACE,
"\tfontSupportFlags: 0x%04" PRIX16
"", fontSupportFlags);
1666 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1672static BOOL rdp_apply_brush_capability_set(rdpSettings* settings,
const rdpSettings* src)
1674 WINPR_ASSERT(settings);
1678 settings->BrushSupportLevel = src->BrushSupportLevel;
1687static BOOL rdp_read_brush_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1689 WINPR_UNUSED(settings);
1690 WINPR_ASSERT(settings);
1692 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1694 Stream_Read_UINT32(s, settings->BrushSupportLevel);
1703static BOOL rdp_write_brush_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1705 WINPR_ASSERT(settings);
1706 if (!Stream_EnsureRemainingCapacity(s, 32))
1709 const size_t header = rdp_capability_set_start(log, s);
1710 Stream_Write_UINT32(s, settings->BrushSupportLevel);
1711 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BRUSH);
1714#ifdef WITH_DEBUG_CAPABILITIES
1716static BOOL rdp_print_brush_capability_set(wLog* log,
wStream* s)
1718 UINT32 brushSupportLevel = 0;
1719 WLog_Print(log, WLOG_TRACE,
1720 "BrushCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1722 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1725 Stream_Read_UINT32(s, brushSupportLevel);
1726 WLog_Print(log, WLOG_TRACE,
"\tbrushSupportLevel: 0x%08" PRIX32
"", brushSupportLevel);
1737 WINPR_ASSERT(cache_definition);
1738 Stream_Read_UINT16(s, cache_definition->cacheEntries);
1739 Stream_Read_UINT16(s,
1740 cache_definition->cacheMaximumCellSize);
1749 WINPR_ASSERT(cache_definition);
1750 Stream_Write_UINT16(s, cache_definition->cacheEntries);
1751 Stream_Write_UINT16(
1752 s, cache_definition->cacheMaximumCellSize);
1756static BOOL rdp_apply_glyph_cache_capability_set(rdpSettings* settings,
const rdpSettings* src)
1758 WINPR_ASSERT(settings);
1761 WINPR_ASSERT(src->GlyphCache);
1762 WINPR_ASSERT(settings->GlyphCache);
1763 for (
size_t x = 0; x < 10; x++)
1764 settings->GlyphCache[x] = src->GlyphCache[x];
1766 WINPR_ASSERT(src->FragCache);
1767 WINPR_ASSERT(settings->FragCache);
1768 settings->FragCache[0] = src->FragCache[0];
1769 settings->GlyphSupportLevel = src->GlyphSupportLevel;
1779static BOOL rdp_read_glyph_cache_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1781 WINPR_ASSERT(settings);
1782 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 48))
1786 for (
size_t x = 0; x < 10; x++)
1787 rdp_read_cache_definition(s, &(settings->GlyphCache[x]));
1788 rdp_read_cache_definition(s, settings->FragCache);
1789 Stream_Read_UINT16(s, settings->GlyphSupportLevel);
1790 Stream_Seek_UINT16(s);
1799static BOOL rdp_write_glyph_cache_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1801 WINPR_ASSERT(settings);
1802 if (!Stream_EnsureRemainingCapacity(s, 64))
1805 const size_t header = rdp_capability_set_start(log, s);
1806 if (settings->GlyphSupportLevel > UINT16_MAX)
1809 for (
size_t x = 0; x < 10; x++)
1810 rdp_write_cache_definition(s, &(settings->GlyphCache[x]));
1811 rdp_write_cache_definition(s, settings->FragCache);
1812 Stream_Write_UINT16(s, (UINT16)settings->GlyphSupportLevel);
1813 Stream_Write_UINT16(s, 0);
1814 return rdp_capability_set_finish(s, header, CAPSET_TYPE_GLYPH_CACHE);
1817#ifdef WITH_DEBUG_CAPABILITIES
1819static BOOL rdp_print_glyph_cache_capability_set(wLog* log,
wStream* s)
1823 UINT16 glyphSupportLevel = 0;
1824 UINT16 pad2Octets = 0;
1825 WLog_Print(log, WLOG_TRACE,
1826 "GlyphCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1828 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 48))
1832 rdp_read_cache_definition(s, &glyphCache[0]);
1833 rdp_read_cache_definition(s, &glyphCache[1]);
1834 rdp_read_cache_definition(s, &glyphCache[2]);
1835 rdp_read_cache_definition(s, &glyphCache[3]);
1836 rdp_read_cache_definition(s, &glyphCache[4]);
1837 rdp_read_cache_definition(s, &glyphCache[5]);
1838 rdp_read_cache_definition(s, &glyphCache[6]);
1839 rdp_read_cache_definition(s, &glyphCache[7]);
1840 rdp_read_cache_definition(s, &glyphCache[8]);
1841 rdp_read_cache_definition(s, &glyphCache[9]);
1842 rdp_read_cache_definition(s, &fragCache);
1843 Stream_Read_UINT16(s, glyphSupportLevel);
1844 Stream_Read_UINT16(s, pad2Octets);
1845 WLog_Print(log, WLOG_TRACE,
"\tglyphCache0: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1846 glyphCache[0].cacheEntries, glyphCache[0].cacheMaximumCellSize);
1847 WLog_Print(log, WLOG_TRACE,
"\tglyphCache1: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1848 glyphCache[1].cacheEntries, glyphCache[1].cacheMaximumCellSize);
1849 WLog_Print(log, WLOG_TRACE,
"\tglyphCache2: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1850 glyphCache[2].cacheEntries, glyphCache[2].cacheMaximumCellSize);
1851 WLog_Print(log, WLOG_TRACE,
"\tglyphCache3: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1852 glyphCache[3].cacheEntries, glyphCache[3].cacheMaximumCellSize);
1853 WLog_Print(log, WLOG_TRACE,
"\tglyphCache4: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1854 glyphCache[4].cacheEntries, glyphCache[4].cacheMaximumCellSize);
1855 WLog_Print(log, WLOG_TRACE,
"\tglyphCache5: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1856 glyphCache[5].cacheEntries, glyphCache[5].cacheMaximumCellSize);
1857 WLog_Print(log, WLOG_TRACE,
"\tglyphCache6: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1858 glyphCache[6].cacheEntries, glyphCache[6].cacheMaximumCellSize);
1859 WLog_Print(log, WLOG_TRACE,
"\tglyphCache7: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1860 glyphCache[7].cacheEntries, glyphCache[7].cacheMaximumCellSize);
1861 WLog_Print(log, WLOG_TRACE,
"\tglyphCache8: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1862 glyphCache[8].cacheEntries, glyphCache[8].cacheMaximumCellSize);
1863 WLog_Print(log, WLOG_TRACE,
"\tglyphCache9: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1864 glyphCache[9].cacheEntries, glyphCache[9].cacheMaximumCellSize);
1865 WLog_Print(log, WLOG_TRACE,
"\tfragCache: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1866 fragCache.cacheEntries, fragCache.cacheMaximumCellSize);
1867 WLog_Print(log, WLOG_TRACE,
"\tglyphSupportLevel: 0x%04" PRIX16
"", glyphSupportLevel);
1868 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1873static BOOL rdp_apply_offscreen_bitmap_cache_capability_set(rdpSettings* settings,
1874 const rdpSettings* src)
1876 WINPR_ASSERT(settings);
1879 settings->OffscreenCacheSize = src->OffscreenCacheSize;
1880 settings->OffscreenCacheEntries = src->OffscreenCacheEntries;
1881 settings->OffscreenSupportLevel = src->OffscreenSupportLevel;
1891static BOOL rdp_read_offscreen_bitmap_cache_capability_set(wLog* log,
wStream* s,
1892 rdpSettings* settings)
1894 UINT32 offscreenSupportLevel = 0;
1896 WINPR_ASSERT(settings);
1897 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1900 Stream_Read_UINT32(s, offscreenSupportLevel);
1901 Stream_Read_UINT16(s, settings->OffscreenCacheSize);
1902 Stream_Read_UINT16(s, settings->OffscreenCacheEntries);
1904 settings->OffscreenSupportLevel = offscreenSupportLevel & 0x01;
1914static BOOL rdp_write_offscreen_bitmap_cache_capability_set(wLog* log,
wStream* s,
1915 const rdpSettings* settings)
1917 UINT32 offscreenSupportLevel = 0x00;
1919 WINPR_ASSERT(settings);
1920 if (!Stream_EnsureRemainingCapacity(s, 32))
1923 const size_t header = rdp_capability_set_start(log, s);
1924 if (settings->OffscreenSupportLevel)
1926 offscreenSupportLevel = 0x01;
1927 Stream_Write_UINT32(s, offscreenSupportLevel);
1928 Stream_Write_UINT16(
1929 s, WINPR_ASSERTING_INT_CAST(
1930 uint16_t, settings->OffscreenCacheSize));
1931 Stream_Write_UINT16(
1933 WINPR_ASSERTING_INT_CAST(
1934 uint16_t, settings->OffscreenCacheEntries));
1939 return rdp_capability_set_finish(s, header, CAPSET_TYPE_OFFSCREEN_CACHE);
1942#ifdef WITH_DEBUG_CAPABILITIES
1944static BOOL rdp_print_offscreen_bitmap_cache_capability_set(wLog* log,
wStream* s)
1946 UINT32 offscreenSupportLevel = 0;
1947 UINT16 offscreenCacheSize = 0;
1948 UINT16 offscreenCacheEntries = 0;
1949 WLog_Print(log, WLOG_TRACE,
"OffscreenBitmapCacheCapabilitySet (length %" PRIuz
"):",
1950 Stream_GetRemainingLength(s));
1952 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1955 Stream_Read_UINT32(s, offscreenSupportLevel);
1956 Stream_Read_UINT16(s, offscreenCacheSize);
1957 Stream_Read_UINT16(s, offscreenCacheEntries);
1958 WLog_Print(log, WLOG_TRACE,
"\toffscreenSupportLevel: 0x%08" PRIX32
"", offscreenSupportLevel);
1959 WLog_Print(log, WLOG_TRACE,
"\toffscreenCacheSize: 0x%04" PRIX16
"", offscreenCacheSize);
1960 WLog_Print(log, WLOG_TRACE,
"\toffscreenCacheEntries: 0x%04" PRIX16
"", offscreenCacheEntries);
1966static BOOL rdp_apply_bitmap_cache_host_support_capability_set(rdpSettings* settings,
1967 const rdpSettings* src)
1979static BOOL rdp_read_bitmap_cache_host_support_capability_set(wLog* log,
wStream* s,
1980 rdpSettings* settings)
1982 BYTE cacheVersion = 0;
1984 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1987 Stream_Read_UINT8(s, cacheVersion);
1988 Stream_Seek_UINT8(s);
1989 Stream_Seek_UINT16(s);
1992 cacheVersion & BITMAP_CACHE_V2);
2000static BOOL rdp_write_bitmap_cache_host_support_capability_set(wLog* log,
wStream* s,
2001 const rdpSettings* settings)
2003 UINT8 cacheVersion = 0;
2006 cacheVersion |= BITMAP_CACHE_V2;
2008 if (!Stream_EnsureRemainingCapacity(s, 32))
2011 const size_t header = rdp_capability_set_start(log, s);
2012 Stream_Write_UINT8(s, cacheVersion);
2013 Stream_Write_UINT8(s, 0);
2014 Stream_Write_UINT16(s, 0);
2015 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT);
2018#ifdef WITH_DEBUG_CAPABILITIES
2020static BOOL rdp_print_bitmap_cache_host_support_capability_set(wLog* log,
wStream* s)
2022 BYTE cacheVersion = 0;
2025 WLog_Print(log, WLOG_TRACE,
"BitmapCacheHostSupportCapabilitySet (length %" PRIuz
"):",
2026 Stream_GetRemainingLength(s));
2028 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2031 Stream_Read_UINT8(s, cacheVersion);
2032 Stream_Read_UINT8(s, pad1);
2033 Stream_Read_UINT16(s, pad2);
2034 WLog_Print(log, WLOG_TRACE,
"\tcacheVersion: 0x%02" PRIX8
"", cacheVersion);
2035 WLog_Print(log, WLOG_TRACE,
"\tpad1: 0x%02" PRIX8
"", pad1);
2036 WLog_Print(log, WLOG_TRACE,
"\tpad2: 0x%04" PRIX16
"", pad2);
2042static BOOL rdp_read_bitmap_cache_cell_info(wLog* log,
wStream* s,
2047 WINPR_ASSERT(cellInfo);
2048 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2055 Stream_Read_UINT32(s, info);
2057 cellInfo->numEntries = (info & 0x7FFFFFFF);
2058 if (cellInfo->numEntries > limit)
2060 WLog_Print(log, WLOG_ERROR,
2061 "BITMAP_CACHE_V2_CELL_INFO::numEntries (%" PRIu32
") > limit(%" PRIuz
")",
2062 cellInfo->numEntries, limit);
2064 cellInfo->persistent = (info & 0x80000000) ? 1 : 0;
2075 WINPR_ASSERT(cellInfo);
2077 (cellInfo->numEntries | (((UINT32)cellInfo->persistent << 31) & 0xFF000000));
2078 if (!Stream_EnsureRemainingCapacity(s, 4))
2080 Stream_Write_UINT32(s, info);
2085static BOOL rdp_apply_bitmap_cache_v2_capability_set(rdpSettings* settings,
const rdpSettings* src)
2087 const FreeRDP_Settings_Keys_Bool keys[] = { FreeRDP_BitmapCacheEnabled,
2088 FreeRDP_BitmapCachePersistEnabled };
2090 for (
size_t x = 0; x < ARRAYSIZE(keys); x++)
2092 const FreeRDP_Settings_Keys_Bool
id = keys[x];
2099 const UINT32 BitmapCacheV2NumCells =
2102 BitmapCacheV2NumCells))
2105 for (
size_t x = 0; x < BitmapCacheV2NumCells; x++)
2108 freerdp_settings_get_pointer_array(src, FreeRDP_BitmapCacheV2CellInfo, x);
2109 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_BitmapCacheV2CellInfo, x,
2123static BOOL rdp_read_bitmap_cache_v2_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2125 UINT16 cacheFlags = 0;
2126 WINPR_UNUSED(settings);
2127 WINPR_ASSERT(settings);
2129 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
2132 Stream_Read_UINT16(s, cacheFlags);
2137 cacheFlags & PERSISTENT_KEYS_EXPECTED_FLAG))
2140 Stream_Seek_UINT8(s);
2141 Stream_Read_UINT8(s, settings->BitmapCacheV2NumCells);
2142 if (settings->BitmapCacheV2NumCells > 5)
2144 WLog_Print(log, WLOG_ERROR,
2145 "Invalid TS_BITMAPCACHE_CAPABILITYSET_REV2::numCellCaches %" PRIu32
" > 5",
2146 settings->BitmapCacheV2NumCells);
2150 for (
size_t x = 0; x < settings->BitmapCacheV2NumCells; x++)
2153 freerdp_settings_get_pointer_array_writable(settings, FreeRDP_BitmapCacheV2CellInfo, x);
2154 if (!rdp_read_bitmap_cache_cell_info(log, s, info, bitmapCacheV2CellInfoLimits[x]))
2159 for (
size_t x = settings->BitmapCacheV2NumCells; x < 5; x++)
2161 if (!Stream_SafeSeek(s, 4))
2173static BOOL rdp_write_bitmap_cache_v2_capability_set(wLog* log,
wStream* s,
2174 const rdpSettings* settings)
2176 WINPR_ASSERT(settings);
2177 if (!Stream_EnsureRemainingCapacity(s, 64))
2180 const UINT32 BitmapCacheV2NumCells =
2184 const size_t header = rdp_capability_set_start(log, s);
2185 UINT16 cacheFlags = ALLOW_CACHE_WAITING_LIST_FLAG;
2189 cacheFlags |= PERSISTENT_KEYS_EXPECTED_FLAG;
2191 for (UINT32 x = 0; x < BitmapCacheV2NumCells; x++)
2195 cur->persistent = 1;
2199 Stream_Write_UINT16(s, cacheFlags);
2200 Stream_Write_UINT8(s, 0);
2202 s, WINPR_ASSERTING_INT_CAST(uint8_t,
2203 settings->BitmapCacheV2NumCells));
2205 for (UINT32 x = 0; x < ARRAYSIZE(CellInfo); x++)
2207 if (!rdp_write_bitmap_cache_cell_info(s, &CellInfo[x]))
2211 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_V2);
2214#ifdef WITH_DEBUG_CAPABILITIES
2216static BOOL rdp_print_bitmap_cache_v2_capability_set(wLog* log,
wStream* s)
2219 WLog_Print(log, WLOG_TRACE,
2220 "BitmapCacheV2CapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2222 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
2225 const UINT16 cacheFlags = Stream_Get_UINT16(s);
2226 const UINT8 pad2 = Stream_Get_UINT8(s);
2227 const UINT8 numCellCaches = Stream_Get_UINT8(s);
2229 for (
size_t x = 0; x < ARRAYSIZE(bitmapCacheV2CellInfo); x++)
2231 if (!rdp_read_bitmap_cache_cell_info(
2232 log, s, &bitmapCacheV2CellInfo[x],
2233 bitmapCacheV2CellInfoLimits[x]))
2237 if (!Stream_SafeSeek(s, 12))
2240 WLog_Print(log, WLOG_TRACE,
"\tcacheFlags: 0x%04" PRIX16
"", cacheFlags);
2241 WLog_Print(log, WLOG_TRACE,
"\tpad2: 0x%02" PRIX8
"", pad2);
2242 WLog_Print(log, WLOG_TRACE,
"\tnumCellCaches: 0x%02" PRIX8
"", numCellCaches);
2243 for (
size_t x = 0; x < ARRAYSIZE(bitmapCacheV2CellInfo); x++)
2246 WLog_Print(log, WLOG_TRACE,
2247 "\tbitmapCache%" PRIuz
"CellInfo: numEntries: %" PRIu32
" persistent: %" PRId32
2249 x, info->numEntries, info->persistent);
2256static BOOL rdp_apply_virtual_channel_capability_set(rdpSettings* settings,
const rdpSettings* src)
2258 WINPR_ASSERT(settings);
2262 if (settings->ServerMode && (settings->VCFlags & VCCAPS_COMPR_SC) &&
2263 (src->VCFlags & VCCAPS_COMPR_SC))
2264 settings->VCFlags |= VCCAPS_COMPR_SC;
2266 settings->VCFlags &= (uint32_t)~VCCAPS_COMPR_SC;
2268 if (!settings->ServerMode && (settings->VCFlags & VCCAPS_COMPR_CS_8K) &&
2269 (src->VCFlags & VCCAPS_COMPR_CS_8K))
2270 settings->VCFlags |= VCCAPS_COMPR_CS_8K;
2272 settings->VCFlags &= (uint32_t)~VCCAPS_COMPR_CS_8K;
2279 if (!settings->ServerMode)
2281 if ((src->VCChunkSize > CHANNEL_CHUNK_MAX_LENGTH) || (src->VCChunkSize == 0))
2282 settings->VCChunkSize = CHANNEL_CHUNK_LENGTH;
2285 settings->VCChunkSize = src->VCChunkSize;
2297static BOOL rdp_read_virtual_channel_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2300 UINT32 VCChunkSize = 0;
2302 WINPR_ASSERT(settings);
2303 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2306 Stream_Read_UINT32(s, flags);
2308 if (Stream_GetRemainingLength(s) >= 4)
2309 Stream_Read_UINT32(s, VCChunkSize);
2311 VCChunkSize = UINT32_MAX;
2313 settings->VCFlags = flags;
2314 settings->VCChunkSize = VCChunkSize;
2324static BOOL rdp_write_virtual_channel_capability_set(wLog* log,
wStream* s,
2325 const rdpSettings* settings)
2327 WINPR_ASSERT(settings);
2328 if (!Stream_EnsureRemainingCapacity(s, 32))
2331 const size_t header = rdp_capability_set_start(log, s);
2332 Stream_Write_UINT32(s, settings->VCFlags);
2333 Stream_Write_UINT32(s, settings->VCChunkSize);
2334 return rdp_capability_set_finish(s, header, CAPSET_TYPE_VIRTUAL_CHANNEL);
2337#ifdef WITH_DEBUG_CAPABILITIES
2339static BOOL rdp_print_virtual_channel_capability_set(wLog* log,
wStream* s)
2342 UINT32 VCChunkSize = 0;
2343 WLog_Print(log, WLOG_TRACE,
2344 "VirtualChannelCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2346 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2349 Stream_Read_UINT32(s, flags);
2351 if (Stream_GetRemainingLength(s) >= 4)
2352 Stream_Read_UINT32(s, VCChunkSize);
2356 WLog_Print(log, WLOG_TRACE,
"\tflags: 0x%08" PRIX32
"", flags);
2357 WLog_Print(log, WLOG_TRACE,
"\tVCChunkSize: 0x%08" PRIX32
"", VCChunkSize);
2363static BOOL rdp_apply_draw_nine_grid_cache_capability_set(rdpSettings* settings,
2364 const rdpSettings* src)
2366 WINPR_ASSERT(settings);
2369 settings->DrawNineGridCacheSize = src->DrawNineGridCacheSize;
2370 settings->DrawNineGridCacheEntries = src->DrawNineGridCacheEntries;
2371 settings->DrawNineGridEnabled = src->DrawNineGridEnabled;
2381static BOOL rdp_read_draw_nine_grid_cache_capability_set(wLog* log,
wStream* s,
2382 rdpSettings* settings)
2384 UINT32 drawNineGridSupportLevel = 0;
2386 WINPR_ASSERT(settings);
2387 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
2390 Stream_Read_UINT32(s, drawNineGridSupportLevel);
2391 Stream_Read_UINT16(s, settings->DrawNineGridCacheSize);
2392 Stream_Read_UINT16(s,
2393 settings->DrawNineGridCacheEntries);
2395 settings->DrawNineGridEnabled =
2396 (drawNineGridSupportLevel & (DRAW_NINEGRID_SUPPORTED | DRAW_NINEGRID_SUPPORTED_V2)) != 0;
2406static BOOL rdp_write_draw_nine_grid_cache_capability_set(wLog* log,
wStream* s,
2407 const rdpSettings* settings)
2409 WINPR_ASSERT(settings);
2410 if (!Stream_EnsureRemainingCapacity(s, 32))
2413 const size_t header = rdp_capability_set_start(log, s);
2414 const UINT32 drawNineGridSupportLevel =
2415 (settings->DrawNineGridEnabled) ? DRAW_NINEGRID_SUPPORTED_V2 : DRAW_NINEGRID_NO_SUPPORT;
2416 Stream_Write_UINT32(s, drawNineGridSupportLevel);
2417 Stream_Write_UINT16(
2418 s, WINPR_ASSERTING_INT_CAST(
2419 uint16_t, settings->DrawNineGridCacheSize));
2420 Stream_Write_UINT16(
2422 WINPR_ASSERTING_INT_CAST(
2423 uint16_t, settings->DrawNineGridCacheEntries));
2424 return rdp_capability_set_finish(s, header, CAPSET_TYPE_DRAW_NINE_GRID_CACHE);
2427#ifdef WITH_DEBUG_CAPABILITIES
2429static BOOL rdp_print_draw_nine_grid_cache_capability_set(wLog* log,
wStream* s)
2431 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
2434 const uint32_t drawNineGridSupportLevel =
2435 Stream_Get_UINT32(s);
2436 const uint32_t DrawNineGridCacheSize =
2437 Stream_Get_UINT16(s);
2438 const uint32_t DrawNineGridCacheEntries =
2439 Stream_Get_UINT16(s);
2441 WLog_Print(log, WLOG_TRACE,
2442 "DrawNineGridCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2443 WLog_Print(log, WLOG_TRACE,
"drawNineGridSupportLevel=0x%08" PRIx32, drawNineGridSupportLevel);
2444 WLog_Print(log, WLOG_TRACE,
"DrawNineGridCacheSize=0x%08" PRIx32, DrawNineGridCacheSize);
2445 WLog_Print(log, WLOG_TRACE,
"DrawNineGridCacheEntries=0x%08" PRIx32, DrawNineGridCacheEntries);
2451static BOOL rdp_apply_draw_gdiplus_cache_capability_set(rdpSettings* settings,
2452 const rdpSettings* src)
2454 WINPR_ASSERT(settings);
2457 if (src->DrawGdiPlusEnabled)
2458 settings->DrawGdiPlusEnabled = TRUE;
2460 if (src->DrawGdiPlusCacheEnabled)
2461 settings->DrawGdiPlusCacheEnabled = TRUE;
2471static BOOL rdp_read_draw_gdiplus_cache_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2473 UINT32 drawGDIPlusSupportLevel = 0;
2474 UINT32 drawGdiplusCacheLevel = 0;
2476 WINPR_ASSERT(settings);
2477 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
2480 Stream_Read_UINT32(s, drawGDIPlusSupportLevel);
2481 Stream_Seek_UINT32(s);
2482 Stream_Read_UINT32(s, drawGdiplusCacheLevel);
2487 settings->DrawGdiPlusEnabled = (drawGDIPlusSupportLevel & DRAW_GDIPLUS_SUPPORTED) != 0;
2488 settings->DrawGdiPlusCacheEnabled = (drawGdiplusCacheLevel & DRAW_GDIPLUS_CACHE_LEVEL_ONE) != 0;
2493#ifdef WITH_DEBUG_CAPABILITIES
2495static BOOL rdp_print_draw_gdiplus_cache_capability_set(wLog* log,
wStream* s)
2497 WLog_Print(log, WLOG_TRACE,
2498 "DrawGdiPlusCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2500 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
2503 const uint32_t drawGdiPlusSupportLevel =
2504 Stream_Get_UINT32(s);
2505 const uint32_t GdipVersion = Stream_Get_UINT32(s);
2506 const uint32_t drawGdiplusCacheLevel =
2507 Stream_Get_UINT32(s);
2508 WLog_Print(log, WLOG_TRACE,
2509 "drawGdiPlusSupportLevel=0x%08" PRIx32
", GdipVersion=0x%08" PRIx32
2510 ", drawGdiplusdrawGdiplusCacheLevelCacheLevel=0x%08" PRIx32,
2511 drawGdiPlusSupportLevel, GdipVersion, drawGdiplusCacheLevel);
2513 const uint16_t GdipGraphicsCacheEntries = Stream_Get_UINT16(s);
2514 const uint16_t GdipBrushCacheEntries = Stream_Get_UINT16(s);
2515 const uint16_t GdipPenCacheEntries = Stream_Get_UINT16(s);
2516 const uint16_t GdipImageCacheEntries = Stream_Get_UINT16(s);
2517 const uint16_t GdipImageAttributesCacheEntries = Stream_Get_UINT16(s);
2518 WLog_Print(log, WLOG_TRACE,
2519 "GdipGraphicsCacheEntries=0x%04" PRIx16
", GdipBrushCacheEntries=0x%04" PRIx16
2520 ", GdipPenCacheEntries=0x%04" PRIx16
", GdipImageCacheEntries=0x%04" PRIx16
2521 ", GdipImageAttributesCacheEntries=0x%04" PRIx16,
2522 GdipGraphicsCacheEntries, GdipBrushCacheEntries, GdipPenCacheEntries,
2523 GdipImageCacheEntries, GdipImageAttributesCacheEntries);
2525 const uint16_t GdipGraphicsCacheChunkSize = Stream_Get_UINT16(s);
2526 const uint16_t GdipObjectBrushCacheChunkSize = Stream_Get_UINT16(s);
2527 const uint16_t GdipObjectPenCacheChunkSize = Stream_Get_UINT16(s);
2528 const uint16_t GdipObjectImageAttributesCacheChunkSize = Stream_Get_UINT16(s);
2529 WLog_Print(log, WLOG_TRACE,
2530 "GdipGraphicsCacheChunkSize=0x%04" PRIx16
2531 ", GdipObjectBrushCacheChunkSize=0x%04" PRIx16
2532 ", GdipObjectPenCacheChunkSize=0x%04" PRIx16
2533 ",GdipObjectImageAttributesCacheChunkSize=0x%04" PRIx16,
2534 GdipGraphicsCacheChunkSize, GdipObjectBrushCacheChunkSize,
2535 GdipObjectPenCacheChunkSize, GdipObjectImageAttributesCacheChunkSize);
2537 const uint16_t GdipObjectImageCacheChunkSize = Stream_Get_UINT16(s);
2538 const uint16_t GdipObjectImageCacheTotalSize = Stream_Get_UINT16(s);
2539 const uint16_t GdipObjectImageCacheMaxSize = Stream_Get_UINT16(s);
2542 "GdipObjectImageCacheChunkSize=0x%04" PRIx16
", GdipObjectImageCacheTotalSize=0x%04" PRIx16
2543 ", GdipObjectImageCacheMaxSize=0x%04" PRIx16,
2544 GdipObjectImageCacheChunkSize, GdipObjectImageCacheTotalSize, GdipObjectImageCacheMaxSize);
2550static BOOL rdp_apply_remote_programs_capability_set(rdpSettings* settings,
const rdpSettings* src)
2552 WINPR_ASSERT(settings);
2555 if (settings->RemoteApplicationMode)
2556 settings->RemoteApplicationMode = src->RemoteApplicationMode;
2561 UINT32 supportLevel = src->RemoteApplicationSupportLevel;
2562 if (settings->RemoteApplicationMode)
2563 supportLevel |= RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED;
2565 settings->RemoteApplicationSupportLevel = supportLevel & settings->RemoteApplicationSupportMask;
2575static BOOL rdp_read_remote_programs_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2577 UINT32 railSupportLevel = 0;
2579 WINPR_ASSERT(settings);
2580 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2583 Stream_Read_UINT32(s, railSupportLevel);
2585 settings->RemoteApplicationMode = (railSupportLevel & RAIL_LEVEL_SUPPORTED) != 0;
2586 settings->RemoteApplicationSupportLevel = railSupportLevel;
2595static BOOL rdp_write_remote_programs_capability_set(wLog* log,
wStream* s,
2596 const rdpSettings* settings)
2598 WINPR_ASSERT(settings);
2599 if (!Stream_EnsureRemainingCapacity(s, 64))
2602 const size_t header = rdp_capability_set_start(log, s);
2603 UINT32 railSupportLevel = RAIL_LEVEL_SUPPORTED;
2605 if (settings->RemoteApplicationSupportLevel & RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED)
2607 if (settings->RemoteAppLanguageBarSupported)
2608 railSupportLevel |= RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED;
2611 railSupportLevel |= RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED;
2612 railSupportLevel |= RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED;
2613 railSupportLevel |= RAIL_LEVEL_SERVER_TO_CLIENT_IME_SYNC_SUPPORTED;
2614 railSupportLevel |= RAIL_LEVEL_HIDE_MINIMIZED_APPS_SUPPORTED;
2615 railSupportLevel |= RAIL_LEVEL_WINDOW_CLOAKING_SUPPORTED;
2616 railSupportLevel |= RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED;
2618 railSupportLevel &= settings->RemoteApplicationSupportLevel;
2619 Stream_Write_UINT32(s, railSupportLevel);
2620 return rdp_capability_set_finish(s, header, CAPSET_TYPE_RAIL);
2623#ifdef WITH_DEBUG_CAPABILITIES
2625static BOOL rdp_print_remote_programs_capability_set(wLog* log,
wStream* s)
2627 UINT32 railSupportLevel = 0;
2628 WLog_Print(log, WLOG_TRACE,
2629 "RemoteProgramsCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2631 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2634 Stream_Read_UINT32(s, railSupportLevel);
2635 WLog_Print(log, WLOG_TRACE,
"\trailSupportLevel: 0x%08" PRIX32
"", railSupportLevel);
2641static BOOL rdp_apply_window_list_capability_set(rdpSettings* settings,
const rdpSettings* src)
2643 WINPR_ASSERT(settings);
2646 settings->RemoteWndSupportLevel = src->RemoteWndSupportLevel;
2647 settings->RemoteAppNumIconCaches = src->RemoteAppNumIconCaches;
2648 settings->RemoteAppNumIconCacheEntries = src->RemoteAppNumIconCacheEntries;
2658static BOOL rdp_read_window_list_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2660 WINPR_ASSERT(settings);
2661 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 7))
2664 Stream_Read_UINT32(s, settings->RemoteWndSupportLevel);
2665 Stream_Read_UINT8(s, settings->RemoteAppNumIconCaches);
2666 Stream_Read_UINT16(s,
2667 settings->RemoteAppNumIconCacheEntries);
2676static BOOL rdp_write_window_list_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
2678 WINPR_ASSERT(settings);
2679 if (!Stream_EnsureRemainingCapacity(s, 32))
2682 const size_t header = rdp_capability_set_start(log, s);
2683 Stream_Write_UINT32(s, settings->RemoteWndSupportLevel);
2685 s, WINPR_ASSERTING_INT_CAST(uint8_t,
2686 settings->RemoteAppNumIconCaches));
2687 Stream_Write_UINT16(
2689 WINPR_ASSERTING_INT_CAST(
2690 uint16_t, settings->RemoteAppNumIconCacheEntries));
2691 return rdp_capability_set_finish(s, header, CAPSET_TYPE_WINDOW);
2694#ifdef WITH_DEBUG_CAPABILITIES
2696static BOOL rdp_print_window_list_capability_set(wLog* log,
wStream* s)
2698 UINT32 wndSupportLevel = 0;
2699 BYTE numIconCaches = 0;
2700 UINT16 numIconCacheEntries = 0;
2701 WLog_Print(log, WLOG_TRACE,
2702 "WindowListCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2704 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 7))
2707 Stream_Read_UINT32(s, wndSupportLevel);
2708 Stream_Read_UINT8(s, numIconCaches);
2709 Stream_Read_UINT16(s, numIconCacheEntries);
2710 WLog_Print(log, WLOG_TRACE,
"\twndSupportLevel: 0x%08" PRIX32
"", wndSupportLevel);
2711 WLog_Print(log, WLOG_TRACE,
"\tnumIconCaches: 0x%02" PRIX8
"", numIconCaches);
2712 WLog_Print(log, WLOG_TRACE,
"\tnumIconCacheEntries: 0x%04" PRIX16
"", numIconCacheEntries);
2718static BOOL rdp_apply_desktop_composition_capability_set(rdpSettings* settings,
2719 const rdpSettings* src)
2721 WINPR_ASSERT(settings);
2724 settings->CompDeskSupportLevel = src->CompDeskSupportLevel;
2733static BOOL rdp_read_desktop_composition_capability_set(wLog* log,
wStream* s,
2734 rdpSettings* settings)
2736 WINPR_UNUSED(settings);
2737 WINPR_ASSERT(settings);
2739 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 2))
2742 Stream_Read_UINT16(s, settings->CompDeskSupportLevel);
2751static BOOL rdp_write_desktop_composition_capability_set(wLog* log,
wStream* s,
2752 const rdpSettings* settings)
2754 WINPR_ASSERT(settings);
2756 if (!Stream_EnsureRemainingCapacity(s, 32))
2759 const size_t header = rdp_capability_set_start(log, s);
2760 const UINT16 compDeskSupportLevel =
2761 (settings->AllowDesktopComposition) ? COMPDESK_SUPPORTED : COMPDESK_NOT_SUPPORTED;
2762 Stream_Write_UINT16(s, compDeskSupportLevel);
2763 return rdp_capability_set_finish(s, header, CAPSET_TYPE_COMP_DESK);
2766#ifdef WITH_DEBUG_CAPABILITIES
2768static BOOL rdp_print_desktop_composition_capability_set(wLog* log,
wStream* s)
2770 UINT16 compDeskSupportLevel = 0;
2771 WLog_Print(log, WLOG_TRACE,
"DesktopCompositionCapabilitySet (length %" PRIuz
"):",
2772 Stream_GetRemainingLength(s));
2774 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 2))
2777 Stream_Read_UINT16(s, compDeskSupportLevel);
2778 WLog_Print(log, WLOG_TRACE,
"\tcompDeskSupportLevel: 0x%04" PRIX16
"", compDeskSupportLevel);
2784static BOOL rdp_apply_multifragment_update_capability_set(rdpSettings* settings,
2785 const rdpSettings* src)
2787 WINPR_ASSERT(settings);
2790 UINT32 multifragMaxRequestSize =
2793 if (settings->ServerMode)
2803 if (multifragMaxRequestSize < FASTPATH_MAX_PACKET_SIZE)
2804 multifragMaxRequestSize = FASTPATH_FRAGMENT_SAFE_SIZE;
2806 if (settings->RemoteFxCodec)
2813 if (multifragMaxRequestSize <
2820 settings->RemoteFxCodec = FALSE;
2822 multifragMaxRequestSize))
2833 multifragMaxRequestSize))
2844 if (multifragMaxRequestSize >
2848 multifragMaxRequestSize))
2860static BOOL rdp_read_multifragment_update_capability_set(wLog* log,
wStream* s,
2861 rdpSettings* settings)
2863 WINPR_ASSERT(settings);
2864 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2867 const UINT32 multifragMaxRequestSize = Stream_Get_UINT32(s);
2869 multifragMaxRequestSize);
2877static BOOL rdp_write_multifragment_update_capability_set(wLog* log,
wStream* s,
2878 rdpSettings* settings)
2880 WINPR_ASSERT(settings);
2881 if (settings->ServerMode &&
2895 const UINT32 tileNumX = (settings->DesktopWidth + 63) / 64;
2896 const UINT32 tileNumY = (settings->DesktopHeight + 63) / 64;
2897 const UINT32 limit = UINT32_MAX / 16384u;
2899 if (tileNumX >= limit / tileNumY)
2901 WLog_Print(log, WLOG_ERROR,
2902 "(DesktopWidth * DesktopHeigth) / 64 exceed limit of %" PRIu32, limit);
2905 if (tileNumY >= limit / tileNumX)
2907 WLog_Print(log, WLOG_ERROR,
2908 "(DesktopWidth * DesktopHeigth) / 64 exceed limit of %" PRIu32, limit);
2913 const UINT32 MultifragMaxRequestSize = (tileNumX * tileNumY + 1u) * 16384u;
2916 MultifragMaxRequestSize))
2920 if (!Stream_EnsureRemainingCapacity(s, 32))
2922 const size_t header = rdp_capability_set_start(log, s);
2923 Stream_Write_UINT32(s, settings->MultifragMaxRequestSize);
2924 return rdp_capability_set_finish(s, header, CAPSET_TYPE_MULTI_FRAGMENT_UPDATE);
2927#ifdef WITH_DEBUG_CAPABILITIES
2929static BOOL rdp_print_multifragment_update_capability_set(wLog* log,
wStream* s)
2931 UINT32 maxRequestSize = 0;
2932 WLog_Print(log, WLOG_TRACE,
"MultifragmentUpdateCapabilitySet (length %" PRIuz
"):",
2933 Stream_GetRemainingLength(s));
2935 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2938 Stream_Read_UINT32(s, maxRequestSize);
2939 WLog_Print(log, WLOG_TRACE,
"\tmaxRequestSize: 0x%08" PRIX32
"", maxRequestSize);
2945static BOOL rdp_apply_large_pointer_capability_set(rdpSettings* settings,
const rdpSettings* src)
2947 WINPR_ASSERT(settings);
2950 settings->LargePointerFlag = src->LargePointerFlag;
2959static BOOL rdp_read_large_pointer_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2961 UINT16 largePointerSupportFlags = 0;
2963 WINPR_ASSERT(settings);
2964 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 2))
2967 Stream_Read_UINT16(s, largePointerSupportFlags);
2968 settings->LargePointerFlag &= largePointerSupportFlags;
2969 if ((largePointerSupportFlags & ~(LARGE_POINTER_FLAG_96x96 | LARGE_POINTER_FLAG_384x384)) != 0)
2973 "TS_LARGE_POINTER_CAPABILITYSET with unsupported flags %04X (all flags %04X) received",
2974 WINPR_CXX_COMPAT_CAST(UINT32, largePointerSupportFlags & ~(LARGE_POINTER_FLAG_96x96 |
2975 LARGE_POINTER_FLAG_384x384)),
2976 largePointerSupportFlags);
2986static BOOL rdp_write_large_pointer_capability_set(wLog* log,
wStream* s,
2987 const rdpSettings* settings)
2989 WINPR_ASSERT(settings);
2990 if (!Stream_EnsureRemainingCapacity(s, 32))
2993 const size_t header = rdp_capability_set_start(log, s);
2994 const UINT16 largePointerSupportFlags =
2995 settings->LargePointerFlag & (LARGE_POINTER_FLAG_96x96 | LARGE_POINTER_FLAG_384x384);
2996 Stream_Write_UINT16(s, largePointerSupportFlags);
2997 return rdp_capability_set_finish(s, header, CAPSET_TYPE_LARGE_POINTER);
3000#ifdef WITH_DEBUG_CAPABILITIES
3002static BOOL rdp_print_large_pointer_capability_set(wLog* log,
wStream* s)
3004 UINT16 largePointerSupportFlags = 0;
3005 WLog_Print(log, WLOG_TRACE,
3006 "LargePointerCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
3008 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 2))
3011 Stream_Read_UINT16(s, largePointerSupportFlags);
3012 WLog_Print(log, WLOG_TRACE,
"\tlargePointerSupportFlags: 0x%04" PRIX16
"",
3013 largePointerSupportFlags);
3019static BOOL rdp_apply_surface_commands_capability_set(rdpSettings* settings,
const rdpSettings* src)
3021 WINPR_ASSERT(settings);
3028 if (src->FastPathOutput)
3030 settings->SurfaceCommandsSupported &= src->SurfaceCommandsSupported;
3031 settings->SurfaceCommandsEnabled = src->SurfaceCommandsEnabled;
3032 settings->SurfaceFrameMarkerEnabled = src->SurfaceFrameMarkerEnabled;
3036 settings->SurfaceCommandsSupported = 0;
3037 settings->SurfaceCommandsEnabled = FALSE;
3038 settings->SurfaceFrameMarkerEnabled = FALSE;
3049static BOOL rdp_read_surface_commands_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
3051 UINT32 cmdFlags = 0;
3053 WINPR_ASSERT(settings);
3054 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
3057 Stream_Read_UINT32(s, cmdFlags);
3058 Stream_Seek_UINT32(s);
3059 settings->SurfaceCommandsSupported = cmdFlags;
3060 settings->SurfaceCommandsEnabled =
3061 (cmdFlags & (SURFCMDS_SET_SURFACE_BITS | SURFCMDS_STREAM_SURFACE_BITS)) != 0;
3062 settings->SurfaceFrameMarkerEnabled = (cmdFlags & SURFCMDS_FRAME_MARKER) != 0;
3071static BOOL rdp_write_surface_commands_capability_set(wLog* log,
wStream* s,
3072 const rdpSettings* settings)
3074 WINPR_ASSERT(settings);
3075 if (!Stream_EnsureRemainingCapacity(s, 32))
3078 const size_t header = rdp_capability_set_start(log, s);
3082 if (settings->SurfaceFrameMarkerEnabled)
3083 cmdFlags |= SURFCMDS_FRAME_MARKER;
3085 Stream_Write_UINT32(s, cmdFlags);
3086 Stream_Write_UINT32(s, 0);
3087 return rdp_capability_set_finish(s, header, CAPSET_TYPE_SURFACE_COMMANDS);
3091static bool sUuidEqual(
const UUID* Uuid1,
const UUID* Uuid2)
3093 if (!Uuid1 && !Uuid2)
3096 if (Uuid1 && !Uuid2)
3099 if (!Uuid1 && Uuid2)
3102 if (Uuid1->Data1 != Uuid2->Data1)
3105 if (Uuid1->Data2 != Uuid2->Data2)
3108 if (Uuid1->Data3 != Uuid2->Data3)
3111 for (
int index = 0; index < 8; index++)
3113 if (Uuid1->Data4[index] != Uuid2->Data4[index])
3120#ifdef WITH_DEBUG_CAPABILITIES
3122static BOOL rdp_print_surface_commands_capability_set(wLog* log,
wStream* s)
3124 UINT32 cmdFlags = 0;
3125 UINT32 reserved = 0;
3127 WLog_Print(log, WLOG_TRACE,
3128 "SurfaceCommandsCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
3130 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
3133 Stream_Read_UINT32(s, cmdFlags);
3134 Stream_Read_UINT32(s, reserved);
3135 WLog_Print(log, WLOG_TRACE,
"\tcmdFlags: 0x%08" PRIX32
"", cmdFlags);
3136 WLog_Print(log, WLOG_TRACE,
"\treserved: 0x%08" PRIX32
"", reserved);
3140static void rdp_print_bitmap_codec_guid(wLog* log,
const GUID* guid)
3143 WLog_Print(log, WLOG_TRACE,
3144 "%08" PRIX32
"%04" PRIX16
"%04" PRIX16
"%02" PRIX8
"%02" PRIX8
"%02" PRIX8
3145 "%02" PRIX8
"%02" PRIX8
"%02" PRIX8
"%02" PRIX8
"%02" PRIX8
"",
3146 guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], guid->Data4[1],
3147 guid->Data4[2], guid->Data4[3], guid->Data4[4], guid->Data4[5], guid->Data4[6],
3152static char* rdp_get_bitmap_codec_guid_name(
const GUID* guid)
3155 if (sUuidEqual(guid, &CODEC_GUID_REMOTEFX))
3156 return "CODEC_GUID_REMOTEFX";
3157 else if (sUuidEqual(guid, &CODEC_GUID_NSCODEC))
3158 return "CODEC_GUID_NSCODEC";
3159 else if (sUuidEqual(guid, &CODEC_GUID_IGNORE))
3160 return "CODEC_GUID_IGNORE";
3161 else if (sUuidEqual(guid, &CODEC_GUID_IMAGE_REMOTEFX))
3162 return "CODEC_GUID_IMAGE_REMOTEFX";
3164#if defined(WITH_JPEG)
3165 else if (sUuidEqual(guid, &CODEC_GUID_JPEG))
3166 return "CODEC_GUID_JPEG";
3169 return "CODEC_GUID_UNKNOWN";
3174static BOOL rdp_read_bitmap_codec_guid(wLog* log,
wStream* s, GUID* guid)
3176 BYTE g[16] = WINPR_C_ARRAY_INIT;
3179 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 16))
3181 Stream_Read(s, g, 16);
3182 guid->Data1 = ((UINT32)g[3] << 24U) | ((UINT32)g[2] << 16U) | (UINT32)(g[1] << 8U) | g[0];
3183 guid->Data2 = ((g[5] << 8U) | g[4]) & 0xFFFF;
3184 guid->Data3 = ((g[7] << 8U) | g[6]) & 0xFFFF;
3185 guid->Data4[0] = g[8];
3186 guid->Data4[1] = g[9];
3187 guid->Data4[2] = g[10];
3188 guid->Data4[3] = g[11];
3189 guid->Data4[4] = g[12];
3190 guid->Data4[5] = g[13];
3191 guid->Data4[6] = g[14];
3192 guid->Data4[7] = g[15];
3196static void rdp_write_bitmap_codec_guid(
wStream* s,
const GUID* guid)
3198 BYTE g[16] = WINPR_C_ARRAY_INIT;
3200 g[0] = guid->Data1 & 0xFF;
3201 g[1] = (guid->Data1 >> 8) & 0xFF;
3202 g[2] = (guid->Data1 >> 16) & 0xFF;
3203 g[3] = (guid->Data1 >> 24) & 0xFF;
3204 g[4] = (guid->Data2) & 0xFF;
3205 g[5] = (guid->Data2 >> 8) & 0xFF;
3206 g[6] = (guid->Data3) & 0xFF;
3207 g[7] = (guid->Data3 >> 8) & 0xFF;
3208 g[8] = guid->Data4[0];
3209 g[9] = guid->Data4[1];
3210 g[10] = guid->Data4[2];
3211 g[11] = guid->Data4[3];
3212 g[12] = guid->Data4[4];
3213 g[13] = guid->Data4[5];
3214 g[14] = guid->Data4[6];
3215 g[15] = guid->Data4[7];
3216 Stream_Write(s, g, 16);
3220static BOOL rdp_apply_bitmap_codecs_capability_set(rdpSettings* settings,
const rdpSettings* src)
3222 WINPR_ASSERT(settings);
3225 if (settings->ServerMode)
3228 settings->RemoteFxCodecId = src->RemoteFxCodecId;
3229 settings->RemoteFxCaptureFlags = src->RemoteFxCaptureFlags;
3230 settings->RemoteFxOnly = src->RemoteFxOnly;
3231 settings->RemoteFxRlgrMode = src->RemoteFxRlgrMode;
3232 settings->RemoteFxCodecMode = src->RemoteFxCodecMode;
3233 settings->NSCodecId = src->NSCodecId;
3234 settings->NSCodecAllowDynamicColorFidelity = src->NSCodecAllowDynamicColorFidelity;
3235 settings->NSCodecAllowSubsampling = src->NSCodecAllowSubsampling;
3236 settings->NSCodecColorLossLevel = src->NSCodecColorLossLevel;
3239 settings->RemoteFxCodec = settings->RemoteFxCodec && src->RemoteFxCodecId;
3240 settings->RemoteFxImageCodec = settings->RemoteFxImageCodec && src->RemoteFxImageCodec;
3242 settings->NSCodec && src->NSCodec))
3244 settings->JpegCodec = src->JpegCodec;
3250static BOOL rdp_read_codec_ts_rfx_icap(wLog* log,
wStream* sub, rdpSettings* settings,
3254 UINT16 tileSize = 0;
3255 BYTE codecFlags = 0;
3256 BYTE colConvBits = 0;
3257 BYTE transformBits = 0;
3258 BYTE entropyBits = 0;
3262 WLog_Print(log, WLOG_ERROR,
3263 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP size %" PRIu16
3264 " unsupported, expecting size %" PRIu16
" not supported",
3269 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 8))
3272 Stream_Read_UINT16(sub, version);
3273 Stream_Read_UINT16(sub, tileSize);
3274 Stream_Read_UINT8(sub, codecFlags);
3275 Stream_Read_UINT8(sub, colConvBits);
3276 Stream_Read_UINT8(sub, transformBits);
3277 Stream_Read_UINT8(sub, entropyBits);
3279 if (version == 0x0009)
3282 if (tileSize != 0x0080)
3284 WLog_Print(log, WLOG_ERROR,
3285 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::version %" PRIu16
3286 " tile size %" PRIu16
" not supported",
3291 else if (version == 0x0100)
3294 if (tileSize != 0x0040)
3296 WLog_Print(log, WLOG_ERROR,
3297 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::version %" PRIu16
3298 " tile size %" PRIu16
" not supported",
3305 WLog_Print(log, WLOG_ERROR,
3306 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::version %" PRIu16
" not supported",
3312 if (colConvBits != 1)
3314 WLog_Print(log, WLOG_ERROR,
3315 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::colConvBits %" PRIu8
3316 " not supported, must be CLW_COL_CONV_ICT (0x1)",
3322 if (transformBits != 1)
3324 WLog_Print(log, WLOG_ERROR,
3325 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::transformBits %" PRIu8
3326 " not supported, must be CLW_XFORM_DWT_53_A (0x1)",
3331 const UINT8 CODEC_MODE = 0x02;
3335 if ((codecFlags & CODEC_MODE) != 0)
3340 else if ((codecFlags & ~CODEC_MODE) != 0)
3341 WLog_Print(log, WLOG_WARN,
3342 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::flags unknown value "
3344 WINPR_CXX_COMPAT_CAST(UINT32, (codecFlags & ~CODEC_MODE)));
3346 switch (entropyBits)
3348 case CLW_ENTROPY_RLGR1:
3352 case CLW_ENTROPY_RLGR3:
3357 WLog_Print(log, WLOG_ERROR,
3358 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::entropyBits "
3359 "unsupported value 0x%02" PRIx8
3360 ", must be CLW_ENTROPY_RLGR1 (0x01) or CLW_ENTROPY_RLGR3 "
3369static BOOL rdp_read_codec_ts_rfx_capset(wLog* log,
wStream* s, rdpSettings* settings)
3371 UINT16 blockType = 0;
3372 UINT32 blockLen = 0;
3373 BYTE rfxCodecId = 0;
3374 UINT16 capsetType = 0;
3375 UINT16 numIcaps = 0;
3378 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 6))
3382 Stream_Read_UINT16(s, blockType);
3383 Stream_Read_UINT32(s, blockLen);
3384 if (blockType != 0xCBC1)
3386 WLog_Print(log, WLOG_ERROR,
3387 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::blockType[0x%04" PRIx16
3388 "] != CBY_CAPSET (0xCBC1)",
3392 if (blockLen < 6ull)
3394 WLog_Print(log, WLOG_ERROR,
3395 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::blockLen[%" PRIu32
"] < 6", blockLen);
3398 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, blockLen - 6ull))
3401 wStream sbuffer = WINPR_C_ARRAY_INIT;
3402 wStream* sub = Stream_StaticConstInit(&sbuffer, Stream_Pointer(s), blockLen - 6ull);
3405 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 7))
3408 Stream_Read_UINT8(sub, rfxCodecId);
3409 Stream_Read_UINT16(sub, capsetType);
3410 Stream_Read_UINT16(sub, numIcaps);
3411 Stream_Read_UINT16(sub, icapLen);
3413 if (rfxCodecId != 1)
3415 WLog_Print(log, WLOG_ERROR,
3416 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::codecId[%" PRIu16
"] != 1", rfxCodecId);
3420 if (capsetType != 0xCFC0)
3422 WLog_Print(log, WLOG_ERROR,
3423 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::capsetType[0x%04" PRIx16
3424 "] != CLY_CAPSET (0xCFC0)",
3431 if (!rdp_read_codec_ts_rfx_icap(log, sub, settings, icapLen))
3438static BOOL rdp_read_codec_ts_rfx_caps(wLog* log,
wStream* sub, rdpSettings* settings)
3440 if (Stream_GetRemainingLength(sub) == 0)
3443 UINT16 blockType = 0;
3444 UINT32 blockLen = 0;
3445 UINT16 numCapsets = 0;
3448 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 8))
3450 Stream_Read_UINT16(sub, blockType);
3451 Stream_Read_UINT32(sub, blockLen);
3452 Stream_Read_UINT16(sub, numCapsets);
3454 if (blockType != 0xCBC0)
3456 WLog_Print(log, WLOG_ERROR,
3457 "[MS_RDPRFX] 2.2.1.1.1 TS_RFX_CAPS::blockType[0x%04" PRIx16
3458 "] != CBY_CAPS (0xCBC0)",
3465 WLog_Print(log, WLOG_ERROR,
"[MS_RDPRFX] 2.2.1.1.1 TS_RFX_CAPS::blockLen[%" PRIu16
"] != 8",
3470 if (numCapsets != 1)
3472 WLog_Print(log, WLOG_ERROR,
3473 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::numIcaps[%" PRIu16
"] != 1", numCapsets);
3477 for (UINT16 x = 0; x < numCapsets; x++)
3479 if (!rdp_read_codec_ts_rfx_capset(log, sub, settings))
3487static BOOL rdp_read_codec_ts_rfx_clnt_caps_container(wLog* log,
wStream* s, rdpSettings* settings)
3489 UINT32 rfxCapsLength = 0;
3490 UINT32 rfxPropsLength = 0;
3491 UINT32 captureFlags = 0;
3494 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
3496 Stream_Read_UINT32(s, rfxPropsLength);
3497 if (rfxPropsLength < 4)
3499 WLog_Print(log, WLOG_ERROR,
3500 "[MS_RDPRFX] 2.2.1.1 TS_RFX_CLNT_CAPS_CONTAINER::length %" PRIu32
3501 " too short, require at least 4 bytes",
3505 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, rfxPropsLength - 4ull))
3508 wStream sbuffer = WINPR_C_ARRAY_INIT;
3509 wStream* sub = Stream_StaticConstInit(&sbuffer, Stream_Pointer(s), rfxPropsLength - 4ull);
3512 Stream_Seek(s, rfxPropsLength - 4ull);
3514 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 8))
3517 Stream_Read_UINT32(sub, captureFlags);
3518 Stream_Read_UINT32(sub, rfxCapsLength);
3519 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, rfxCapsLength))
3522 settings->RemoteFxCaptureFlags = captureFlags;
3523 settings->RemoteFxOnly = !(captureFlags & CARDP_CAPS_CAPTURE_NON_CAC);
3526 wStream tsbuffer = WINPR_C_ARRAY_INIT;
3527 wStream* ts_sub = Stream_StaticConstInit(&tsbuffer, Stream_Pointer(sub), rfxCapsLength);
3528 WINPR_ASSERT(ts_sub);
3529 return rdp_read_codec_ts_rfx_caps(log, ts_sub, settings);
3537static BOOL rdp_read_bitmap_codecs_capability_set(wLog* log,
wStream* s, rdpSettings* settings,
3541 GUID codecGuid = WINPR_C_ARRAY_INIT;
3542 BYTE bitmapCodecCount = 0;
3543 UINT16 codecPropertiesLength = 0;
3545 BOOL guidNSCodec = FALSE;
3546 BOOL guidRemoteFx = FALSE;
3547 BOOL guidRemoteFxImage = FALSE;
3549 WINPR_ASSERT(settings);
3550 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 1))
3553 Stream_Read_UINT8(s, bitmapCodecCount);
3555 while (bitmapCodecCount > 0)
3557 wStream subbuffer = WINPR_C_ARRAY_INIT;
3559 if (!rdp_read_bitmap_codec_guid(log, s, &codecGuid))
3561 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 3))
3563 Stream_Read_UINT8(s, codecId);
3564 Stream_Read_UINT16(s, codecPropertiesLength);
3566 wStream* sub = Stream_StaticInit(&subbuffer, Stream_Pointer(s), codecPropertiesLength);
3567 if (!Stream_SafeSeek(s, codecPropertiesLength))
3572 if (sUuidEqual(&codecGuid, &CODEC_GUID_REMOTEFX))
3574 guidRemoteFx = TRUE;
3575 settings->RemoteFxCodecId = codecId;
3576 if (!rdp_read_codec_ts_rfx_clnt_caps_container(log, sub, settings))
3579 else if (sUuidEqual(&codecGuid, &CODEC_GUID_IMAGE_REMOTEFX))
3582 guidRemoteFxImage = TRUE;
3583 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3586 else if (sUuidEqual(&codecGuid, &CODEC_GUID_NSCODEC))
3588 BYTE colorLossLevel = 0;
3589 BYTE fAllowSubsampling = 0;
3590 BYTE fAllowDynamicFidelity = 0;
3592 settings->NSCodecId = codecId;
3593 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 3))
3595 Stream_Read_UINT8(sub, fAllowDynamicFidelity);
3596 Stream_Read_UINT8(sub, fAllowSubsampling);
3597 Stream_Read_UINT8(sub, colorLossLevel);
3599 if (colorLossLevel < 1)
3602 if (colorLossLevel > 7)
3605 settings->NSCodecAllowDynamicColorFidelity = fAllowDynamicFidelity;
3606 settings->NSCodecAllowSubsampling = fAllowSubsampling;
3607 settings->NSCodecColorLossLevel = colorLossLevel;
3609 else if (sUuidEqual(&codecGuid, &CODEC_GUID_IGNORE))
3611 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3616 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3622 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3626 const size_t rest = Stream_GetRemainingLength(sub);
3629 WLog_Print(log, WLOG_ERROR,
3630 "error while reading codec properties: actual size: %" PRIuz
3631 " expected size: %" PRIu32
"",
3632 rest + codecPropertiesLength, codecPropertiesLength);
3654static BOOL rdp_write_rfx_client_capability_container(
wStream* s,
const rdpSettings* settings)
3656 WINPR_ASSERT(settings);
3657 if (!Stream_EnsureRemainingCapacity(s, 64))
3660 const UINT32 captureFlags = settings->RemoteFxOnly ? 0 : CARDP_CAPS_CAPTURE_NON_CAC;
3662 WINPR_ASSERT(settings->RemoteFxCodecMode <= UINT8_MAX);
3663 const UINT8 codecMode = (UINT8)settings->RemoteFxCodecMode;
3664 Stream_Write_UINT16(s, 49);
3666 Stream_Write_UINT32(s, 49);
3667 Stream_Write_UINT32(s, captureFlags);
3668 Stream_Write_UINT32(s, 37);
3670 Stream_Write_UINT16(s, CBY_CAPS);
3671 Stream_Write_UINT32(s, 8);
3672 Stream_Write_UINT16(s, 1);
3674 Stream_Write_UINT16(s, CBY_CAPSET);
3675 Stream_Write_UINT32(s, 29);
3676 Stream_Write_UINT8(s, 0x01);
3677 Stream_Write_UINT16(s, CLY_CAPSET);
3678 Stream_Write_UINT16(s, 2);
3679 Stream_Write_UINT16(s, 8);
3681 Stream_Write_UINT16(s, CLW_VERSION_1_0);
3682 Stream_Write_UINT16(s, CT_TILE_64x64);
3683 Stream_Write_UINT8(s, codecMode);
3684 Stream_Write_UINT8(s, CLW_COL_CONV_ICT);
3685 Stream_Write_UINT8(s, CLW_XFORM_DWT_53_A);
3686 Stream_Write_UINT8(s, CLW_ENTROPY_RLGR1);
3688 Stream_Write_UINT16(s, CLW_VERSION_1_0);
3689 Stream_Write_UINT16(s, CT_TILE_64x64);
3690 Stream_Write_UINT8(s, codecMode);
3691 Stream_Write_UINT8(s, CLW_COL_CONV_ICT);
3692 Stream_Write_UINT8(s, CLW_XFORM_DWT_53_A);
3693 Stream_Write_UINT8(s, CLW_ENTROPY_RLGR3);
3701static BOOL rdp_write_nsc_client_capability_container(
wStream* s,
const rdpSettings* settings)
3703 WINPR_ASSERT(settings);
3705 const BOOL fAllowDynamicFidelity = settings->NSCodecAllowDynamicColorFidelity;
3706 const BOOL fAllowSubsampling = settings->NSCodecAllowSubsampling;
3707 UINT32 colorLossLevel = settings->NSCodecColorLossLevel;
3709 if (colorLossLevel < 1)
3712 if (colorLossLevel > 7)
3715 if (!Stream_EnsureRemainingCapacity(s, 8))
3718 Stream_Write_UINT16(s, 3);
3720 Stream_Write_UINT8(s, fAllowDynamicFidelity != 0);
3721 Stream_Write_UINT8(s, fAllowSubsampling != 0);
3722 Stream_Write_UINT8(s, (UINT8)colorLossLevel);
3726#if defined(WITH_JPEG)
3728static BOOL rdp_write_jpeg_client_capability_container(
wStream* s,
const rdpSettings* settings)
3730 WINPR_ASSERT(settings);
3731 if (!Stream_EnsureRemainingCapacity(s, 8))
3734 Stream_Write_UINT16(s, 1);
3737 Stream_Write_UINT8(s, WINPR_ASSERTING_INT_CAST(UINT8, q));
3746static BOOL rdp_write_rfx_server_capability_container(
wStream* s,
const rdpSettings* settings)
3748 WINPR_UNUSED(settings);
3749 WINPR_ASSERT(settings);
3751 if (!Stream_EnsureRemainingCapacity(s, 8))
3754 Stream_Write_UINT16(s, 4);
3755 Stream_Write_UINT32(s, 0);
3759#if defined(WITH_JPEG)
3761static BOOL rdp_write_jpeg_server_capability_container(
wStream* s,
const rdpSettings* settings)
3763 WINPR_UNUSED(settings);
3764 WINPR_ASSERT(settings);
3766 if (!Stream_EnsureRemainingCapacity(s, 8))
3769 Stream_Write_UINT16(s, 1);
3770 Stream_Write_UINT8(s, 75);
3779static BOOL rdp_write_nsc_server_capability_container(
wStream* s,
const rdpSettings* settings)
3781 WINPR_UNUSED(settings);
3782 WINPR_ASSERT(settings);
3784 if (!Stream_EnsureRemainingCapacity(s, 8))
3787 Stream_Write_UINT16(s, 4);
3788 Stream_Write_UINT32(s, 0);
3798static BOOL rdp_write_bitmap_codecs_capability_set(wLog* log,
wStream* s,
3799 const rdpSettings* settings)
3801 WINPR_ASSERT(settings);
3802 if (!Stream_EnsureRemainingCapacity(s, 64))
3805 const size_t header = rdp_capability_set_start(log, s);
3806 BYTE bitmapCodecCount = 0;
3808 if (settings->RemoteFxCodec)
3814#if defined(WITH_JPEG)
3816 if (settings->JpegCodec)
3821 if (settings->RemoteFxImageCodec)
3824 Stream_Write_UINT8(s, bitmapCodecCount);
3826 if (settings->RemoteFxCodec)
3828 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_REMOTEFX);
3830 if (settings->ServerMode)
3832 Stream_Write_UINT8(s, 0);
3834 if (!rdp_write_rfx_server_capability_container(s, settings))
3839 Stream_Write_UINT8(s, RDP_CODEC_ID_REMOTEFX);
3841 if (!rdp_write_rfx_client_capability_container(s, settings))
3848 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_NSCODEC);
3850 if (settings->ServerMode)
3852 Stream_Write_UINT8(s, 0);
3854 if (!rdp_write_nsc_server_capability_container(s, settings))
3859 Stream_Write_UINT8(s, RDP_CODEC_ID_NSCODEC);
3861 if (!rdp_write_nsc_client_capability_container(s, settings))
3866#if defined(WITH_JPEG)
3868 if (settings->JpegCodec)
3870 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_JPEG);
3872 if (settings->ServerMode)
3874 Stream_Write_UINT8(s, 0);
3876 if (!rdp_write_jpeg_server_capability_container(s, settings))
3881 Stream_Write_UINT8(s, RDP_CODEC_ID_JPEG);
3883 if (!rdp_write_jpeg_client_capability_container(s, settings))
3890 if (settings->RemoteFxImageCodec)
3892 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_IMAGE_REMOTEFX);
3894 if (settings->ServerMode)
3896 Stream_Write_UINT8(s, 0);
3898 if (!rdp_write_rfx_server_capability_container(s, settings))
3903 Stream_Write_UINT8(s, RDP_CODEC_ID_IMAGE_REMOTEFX);
3905 if (!rdp_write_rfx_client_capability_container(s, settings))
3910 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CODECS);
3913#ifdef WITH_DEBUG_CAPABILITIES
3915static BOOL rdp_print_bitmap_codecs_capability_set(wLog* log,
wStream* s)
3917 GUID codecGuid = WINPR_C_ARRAY_INIT;
3918 BYTE bitmapCodecCount = 0;
3920 UINT16 codecPropertiesLength = 0;
3922 WLog_Print(log, WLOG_TRACE,
3923 "BitmapCodecsCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
3925 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 1))
3928 Stream_Read_UINT8(s, bitmapCodecCount);
3929 WLog_Print(log, WLOG_TRACE,
"\tbitmapCodecCount: %" PRIu8
"", bitmapCodecCount);
3931 while (bitmapCodecCount > 0)
3933 if (!rdp_read_bitmap_codec_guid(log, s, &codecGuid))
3935 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 3))
3937 Stream_Read_UINT8(s, codecId);
3938 WLog_Print(log, WLOG_TRACE,
"\tcodecGuid: 0x");
3939 rdp_print_bitmap_codec_guid(log, &codecGuid);
3940 WLog_Print(log, WLOG_TRACE,
" (%s)", rdp_get_bitmap_codec_guid_name(&codecGuid));
3941 WLog_Print(log, WLOG_TRACE,
"\tcodecId: %" PRIu8
"", codecId);
3942 Stream_Read_UINT16(s, codecPropertiesLength);
3943 WLog_Print(log, WLOG_TRACE,
"\tcodecPropertiesLength: %" PRIu16
"", codecPropertiesLength);
3945 if (!Stream_SafeSeek(s, codecPropertiesLength))
3955static BOOL rdp_apply_frame_acknowledge_capability_set(rdpSettings* settings,
3956 const rdpSettings* src)
3958 WINPR_ASSERT(settings);
3961 if (settings->ServerMode)
3962 settings->FrameAcknowledge = src->FrameAcknowledge;
3971static BOOL rdp_read_frame_acknowledge_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
3973 WINPR_ASSERT(settings);
3974 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
3977 Stream_Read_UINT32(s, settings->FrameAcknowledge);
3986static BOOL rdp_write_frame_acknowledge_capability_set(wLog* log,
wStream* s,
3987 const rdpSettings* settings)
3989 WINPR_ASSERT(settings);
3990 if (!Stream_EnsureRemainingCapacity(s, 32))
3993 const size_t header = rdp_capability_set_start(log, s);
3994 Stream_Write_UINT32(s, settings->FrameAcknowledge);
3995 return rdp_capability_set_finish(s, header, CAPSET_TYPE_FRAME_ACKNOWLEDGE);
3998#ifdef WITH_DEBUG_CAPABILITIES
4000static BOOL rdp_print_frame_acknowledge_capability_set(wLog* log,
wStream* s)
4002 UINT32 frameAcknowledge = 0;
4003 WLog_Print(log, WLOG_TRACE,
4004 "FrameAcknowledgeCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
4006 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
4009 Stream_Read_UINT32(s, frameAcknowledge);
4010 WLog_Print(log, WLOG_TRACE,
"\tframeAcknowledge: 0x%08" PRIX32
"", frameAcknowledge);
4016static BOOL rdp_apply_bitmap_cache_v3_codec_id_capability_set(rdpSettings* settings,
4017 const rdpSettings* src)
4019 WINPR_ASSERT(settings);
4022 settings->BitmapCacheV3CodecId = src->BitmapCacheV3CodecId;
4027static BOOL rdp_read_bitmap_cache_v3_codec_id_capability_set(wLog* log,
wStream* s,
4028 rdpSettings* settings)
4030 BYTE bitmapCacheV3CodecId = 0;
4032 WINPR_ASSERT(settings);
4033 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 1))
4036 Stream_Read_UINT8(s, bitmapCacheV3CodecId);
4037 settings->BitmapCacheV3CodecId = bitmapCacheV3CodecId;
4042static BOOL rdp_write_bitmap_cache_v3_codec_id_capability_set(wLog* log,
wStream* s,
4043 const rdpSettings* settings)
4045 WINPR_ASSERT(settings);
4046 if (!Stream_EnsureRemainingCapacity(s, 32))
4049 const size_t header = rdp_capability_set_start(log, s);
4050 if (settings->BitmapCacheV3CodecId > UINT8_MAX)
4052 Stream_Write_UINT8(s, (UINT8)settings->BitmapCacheV3CodecId);
4053 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID);
4056#ifdef WITH_DEBUG_CAPABILITIES
4058static BOOL rdp_print_bitmap_cache_v3_codec_id_capability_set(wLog* log,
wStream* s)
4060 BYTE bitmapCacheV3CodecId = 0;
4061 WLog_Print(log, WLOG_TRACE,
"BitmapCacheV3CodecIdCapabilitySet (length %" PRIuz
"):",
4062 Stream_GetRemainingLength(s));
4064 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 1))
4067 Stream_Read_UINT8(s, bitmapCacheV3CodecId);
4068 WLog_Print(log, WLOG_TRACE,
"\tbitmapCacheV3CodecId: 0x%02" PRIX8
"", bitmapCacheV3CodecId);
4072BOOL rdp_print_capability_sets(wLog* log,
wStream* s,
size_t start, BOOL receiving)
4077 UINT16 numberCapabilities = 0;
4079 size_t pos = Stream_GetPosition(s);
4081 if (!Stream_SetPosition(s, start))
4086 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
4091 if (!Stream_CheckAndLogRequiredCapacityWLog(log, (s), 4))
4095 Stream_Read_UINT16(s, numberCapabilities);
4098 while (numberCapabilities > 0)
4104 if (!rdp_read_capability_set_header(log, s, &length, &type))
4107 WLog_Print(log, WLOG_TRACE,
"%s ", receiving ?
"Receiving" :
"Sending");
4108 sub = Stream_StaticInit(&subBuffer, Stream_Pointer(s), length - 4);
4109 if (!Stream_SafeSeek(s, length - 4))
4114 case CAPSET_TYPE_GENERAL:
4115 if (!rdp_print_general_capability_set(log, sub))
4120 case CAPSET_TYPE_BITMAP:
4121 if (!rdp_print_bitmap_capability_set(log, sub))
4126 case CAPSET_TYPE_ORDER:
4127 if (!rdp_print_order_capability_set(log, sub))
4132 case CAPSET_TYPE_BITMAP_CACHE:
4133 if (!rdp_print_bitmap_cache_capability_set(log, sub))
4138 case CAPSET_TYPE_CONTROL:
4139 if (!rdp_print_control_capability_set(log, sub))
4144 case CAPSET_TYPE_ACTIVATION:
4145 if (!rdp_print_window_activation_capability_set(log, sub))
4150 case CAPSET_TYPE_POINTER:
4151 if (!rdp_print_pointer_capability_set(log, sub))
4156 case CAPSET_TYPE_SHARE:
4157 if (!rdp_print_share_capability_set(log, sub))
4162 case CAPSET_TYPE_COLOR_CACHE:
4163 if (!rdp_print_color_cache_capability_set(log, sub))
4168 case CAPSET_TYPE_SOUND:
4169 if (!rdp_print_sound_capability_set(log, sub))
4174 case CAPSET_TYPE_INPUT:
4175 if (!rdp_print_input_capability_set(log, sub))
4180 case CAPSET_TYPE_FONT:
4181 if (!rdp_print_font_capability_set(log, sub))
4186 case CAPSET_TYPE_BRUSH:
4187 if (!rdp_print_brush_capability_set(log, sub))
4192 case CAPSET_TYPE_GLYPH_CACHE:
4193 if (!rdp_print_glyph_cache_capability_set(log, sub))
4198 case CAPSET_TYPE_OFFSCREEN_CACHE:
4199 if (!rdp_print_offscreen_bitmap_cache_capability_set(log, sub))
4204 case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
4205 if (!rdp_print_bitmap_cache_host_support_capability_set(log, sub))
4210 case CAPSET_TYPE_BITMAP_CACHE_V2:
4211 if (!rdp_print_bitmap_cache_v2_capability_set(log, sub))
4216 case CAPSET_TYPE_VIRTUAL_CHANNEL:
4217 if (!rdp_print_virtual_channel_capability_set(log, sub))
4222 case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
4223 if (!rdp_print_draw_nine_grid_cache_capability_set(log, sub))
4228 case CAPSET_TYPE_DRAW_GDI_PLUS:
4229 if (!rdp_print_draw_gdiplus_cache_capability_set(log, sub))
4234 case CAPSET_TYPE_RAIL:
4235 if (!rdp_print_remote_programs_capability_set(log, sub))
4240 case CAPSET_TYPE_WINDOW:
4241 if (!rdp_print_window_list_capability_set(log, sub))
4246 case CAPSET_TYPE_COMP_DESK:
4247 if (!rdp_print_desktop_composition_capability_set(log, sub))
4252 case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
4253 if (!rdp_print_multifragment_update_capability_set(log, sub))
4258 case CAPSET_TYPE_LARGE_POINTER:
4259 if (!rdp_print_large_pointer_capability_set(log, sub))
4264 case CAPSET_TYPE_SURFACE_COMMANDS:
4265 if (!rdp_print_surface_commands_capability_set(log, sub))
4270 case CAPSET_TYPE_BITMAP_CODECS:
4271 if (!rdp_print_bitmap_codecs_capability_set(log, sub))
4276 case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
4277 if (!rdp_print_frame_acknowledge_capability_set(log, sub))
4282 case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID:
4283 if (!rdp_print_bitmap_cache_v3_codec_id_capability_set(log, sub))
4289 WLog_Print(log, WLOG_ERROR,
"unknown capability type %" PRIu16
"", type);
4293 rest = Stream_GetRemainingLength(sub);
4296 WLog_Print(log, WLOG_WARN,
4297 "incorrect capability offset, type:0x%04" PRIX16
" %" PRIu16
4298 " bytes expected, %" PRIuz
"bytes remaining",
4299 type, length, rest);
4302 numberCapabilities--;
4307 if (!Stream_SetPosition(s, pos))
4315static BOOL rdp_apply_from_received(UINT16 type, rdpSettings* dst,
const rdpSettings* src)
4319 case CAPSET_TYPE_GENERAL:
4320 return rdp_apply_general_capability_set(dst, src);
4321 case CAPSET_TYPE_BITMAP:
4322 return rdp_apply_bitmap_capability_set(dst, src);
4323 case CAPSET_TYPE_ORDER:
4324 return rdp_apply_order_capability_set(dst, src);
4325 case CAPSET_TYPE_POINTER:
4326 return rdp_apply_pointer_capability_set(dst, src);
4327 case CAPSET_TYPE_INPUT:
4328 return rdp_apply_input_capability_set(dst, src);
4329 case CAPSET_TYPE_VIRTUAL_CHANNEL:
4330 return rdp_apply_virtual_channel_capability_set(dst, src);
4331 case CAPSET_TYPE_SHARE:
4332 return rdp_apply_share_capability_set(dst, src);
4333 case CAPSET_TYPE_COLOR_CACHE:
4334 return rdp_apply_color_cache_capability_set(dst, src);
4335 case CAPSET_TYPE_FONT:
4336 return rdp_apply_font_capability_set(dst, src);
4337 case CAPSET_TYPE_DRAW_GDI_PLUS:
4338 return rdp_apply_draw_gdiplus_cache_capability_set(dst, src);
4339 case CAPSET_TYPE_RAIL:
4340 return rdp_apply_remote_programs_capability_set(dst, src);
4341 case CAPSET_TYPE_WINDOW:
4342 return rdp_apply_window_list_capability_set(dst, src);
4343 case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
4344 return rdp_apply_multifragment_update_capability_set(dst, src);
4345 case CAPSET_TYPE_LARGE_POINTER:
4346 return rdp_apply_large_pointer_capability_set(dst, src);
4347 case CAPSET_TYPE_COMP_DESK:
4348 return rdp_apply_desktop_composition_capability_set(dst, src);
4349 case CAPSET_TYPE_SURFACE_COMMANDS:
4350 return rdp_apply_surface_commands_capability_set(dst, src);
4351 case CAPSET_TYPE_BITMAP_CODECS:
4352 return rdp_apply_bitmap_codecs_capability_set(dst, src);
4353 case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
4354 return rdp_apply_frame_acknowledge_capability_set(dst, src);
4355 case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID:
4356 return rdp_apply_bitmap_cache_v3_codec_id_capability_set(dst, src);
4357 case CAPSET_TYPE_BITMAP_CACHE:
4358 return rdp_apply_bitmap_cache_capability_set(dst, src);
4359 case CAPSET_TYPE_BITMAP_CACHE_V2:
4360 return rdp_apply_bitmap_cache_v2_capability_set(dst, src);
4361 case CAPSET_TYPE_BRUSH:
4362 return rdp_apply_brush_capability_set(dst, src);
4363 case CAPSET_TYPE_GLYPH_CACHE:
4364 return rdp_apply_glyph_cache_capability_set(dst, src);
4365 case CAPSET_TYPE_OFFSCREEN_CACHE:
4366 return rdp_apply_offscreen_bitmap_cache_capability_set(dst, src);
4367 case CAPSET_TYPE_SOUND:
4368 return rdp_apply_sound_capability_set(dst, src);
4369 case CAPSET_TYPE_CONTROL:
4370 return rdp_apply_control_capability_set(dst, src);
4371 case CAPSET_TYPE_ACTIVATION:
4372 return rdp_apply_window_activation_capability_set(dst, src);
4373 case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
4374 return rdp_apply_draw_nine_grid_cache_capability_set(dst, src);
4375 case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
4376 return rdp_apply_bitmap_cache_host_support_capability_set(dst, src);
4382BOOL rdp_read_capability_set(wLog* log,
wStream* sub, UINT16 type, rdpSettings* settings,
4385 WINPR_ASSERT(settings);
4387 if (type <= CAPSET_TYPE_FRAME_ACKNOWLEDGE)
4389 const size_t size = Stream_Length(sub);
4390 if (size > UINT32_MAX)
4393 WINPR_ASSERT(settings->ReceivedCapabilities);
4394 settings->ReceivedCapabilities[type] = TRUE;
4396 WINPR_ASSERT(settings->ReceivedCapabilityDataSizes);
4397 settings->ReceivedCapabilityDataSizes[type] = (UINT32)size;
4399 WINPR_ASSERT(settings->ReceivedCapabilityData);
4400 void* tmp = realloc(settings->ReceivedCapabilityData[type], size);
4401 if (!tmp && (size > 0))
4404 memcpy(tmp, Stream_Buffer(sub), size);
4405 settings->ReceivedCapabilityData[type] = tmp;
4408 WLog_Print(log, WLOG_WARN,
"not handling capability type %" PRIu16
" yet", type);
4410 BOOL treated = TRUE;
4414 case CAPSET_TYPE_GENERAL:
4415 if (!rdp_read_general_capability_set(log, sub, settings))
4420 case CAPSET_TYPE_BITMAP:
4421 if (!rdp_read_bitmap_capability_set(log, sub, settings))
4426 case CAPSET_TYPE_ORDER:
4427 if (!rdp_read_order_capability_set(log, sub, settings))
4432 case CAPSET_TYPE_POINTER:
4433 if (!rdp_read_pointer_capability_set(log, sub, settings))
4438 case CAPSET_TYPE_INPUT:
4439 if (!rdp_read_input_capability_set(log, sub, settings, isServer))
4444 case CAPSET_TYPE_VIRTUAL_CHANNEL:
4445 if (!rdp_read_virtual_channel_capability_set(log, sub, settings))
4450 case CAPSET_TYPE_SHARE:
4451 if (!rdp_read_share_capability_set(log, sub, settings))
4456 case CAPSET_TYPE_COLOR_CACHE:
4457 if (!rdp_read_color_cache_capability_set(log, sub, settings))
4462 case CAPSET_TYPE_FONT:
4463 if (!rdp_read_font_capability_set(log, sub, settings))
4468 case CAPSET_TYPE_DRAW_GDI_PLUS:
4469 if (!rdp_read_draw_gdiplus_cache_capability_set(log, sub, settings))
4474 case CAPSET_TYPE_RAIL:
4475 if (!rdp_read_remote_programs_capability_set(log, sub, settings))
4480 case CAPSET_TYPE_WINDOW:
4481 if (!rdp_read_window_list_capability_set(log, sub, settings))
4486 case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
4487 if (!rdp_read_multifragment_update_capability_set(log, sub, settings))
4492 case CAPSET_TYPE_LARGE_POINTER:
4493 if (!rdp_read_large_pointer_capability_set(log, sub, settings))
4498 case CAPSET_TYPE_COMP_DESK:
4499 if (!rdp_read_desktop_composition_capability_set(log, sub, settings))
4504 case CAPSET_TYPE_SURFACE_COMMANDS:
4505 if (!rdp_read_surface_commands_capability_set(log, sub, settings))
4510 case CAPSET_TYPE_BITMAP_CODECS:
4511 if (!rdp_read_bitmap_codecs_capability_set(log, sub, settings, isServer))
4516 case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
4517 if (!rdp_read_frame_acknowledge_capability_set(log, sub, settings))
4522 case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID:
4523 if (!rdp_read_bitmap_cache_v3_codec_id_capability_set(log, sub, settings))
4540 case CAPSET_TYPE_BITMAP_CACHE:
4541 if (!rdp_read_bitmap_cache_capability_set(log, sub, settings))
4546 case CAPSET_TYPE_BITMAP_CACHE_V2:
4547 if (!rdp_read_bitmap_cache_v2_capability_set(log, sub, settings))
4552 case CAPSET_TYPE_BRUSH:
4553 if (!rdp_read_brush_capability_set(log, sub, settings))
4558 case CAPSET_TYPE_GLYPH_CACHE:
4559 if (!rdp_read_glyph_cache_capability_set(log, sub, settings))
4564 case CAPSET_TYPE_OFFSCREEN_CACHE:
4565 if (!rdp_read_offscreen_bitmap_cache_capability_set(log, sub, settings))
4570 case CAPSET_TYPE_SOUND:
4571 if (!rdp_read_sound_capability_set(log, sub, settings))
4576 case CAPSET_TYPE_CONTROL:
4577 if (!rdp_read_control_capability_set(log, sub, settings))
4582 case CAPSET_TYPE_ACTIVATION:
4583 if (!rdp_read_window_activation_capability_set(log, sub, settings))
4588 case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
4589 if (!rdp_read_draw_nine_grid_cache_capability_set(log, sub, settings))
4595 WLog_Print(log, WLOG_ERROR,
4596 "capability %s(%" PRIu16
") not expected from client",
4597 get_capability_name(type), type);
4606 case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
4607 if (!rdp_read_bitmap_cache_host_support_capability_set(log, sub, settings))
4613 WLog_Print(log, WLOG_ERROR,
4614 "capability %s(%" PRIu16
") not expected from server",
4615 get_capability_name(type), type);
4621 const size_t rest = Stream_GetRemainingLength(sub);
4624 const size_t length = Stream_Capacity(sub);
4625 WLog_Print(log, WLOG_ERROR,
4626 "incorrect offset, type:0x%04" PRIx16
" actual:%" PRIuz
" expected:%" PRIuz
"",
4627 type, length - rest, length);
4633static BOOL rdp_read_capability_sets(wLog* log,
wStream* s, rdpSettings* settings,
4634 rdpSettings* rcvSettings, UINT16 totalLength)
4640 UINT16 numberCapabilities = 0;
4643#ifdef WITH_DEBUG_CAPABILITIES
4644 const size_t capstart = Stream_GetPosition(s);
4648 WINPR_ASSERT(settings);
4650 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
4653 Stream_Read_UINT16(s, numberCapabilities);
4655 count = numberCapabilities;
4657 start = Stream_GetPosition(s);
4658 while (numberCapabilities > 0 && Stream_GetRemainingLength(s) >= 4)
4665 if (!rdp_read_capability_set_header(log, s, &length, &type))
4667 sub = Stream_StaticInit(&subbuffer, Stream_Pointer(s), length - 4);
4668 if (!Stream_SafeSeek(s, length - 4))
4671 if (!rdp_read_capability_set(log, sub, type, rcvSettings, settings->ServerMode))
4674 if (!rdp_apply_from_received(type, settings, rcvSettings))
4676 numberCapabilities--;
4679 end = Stream_GetPosition(s);
4682 if (numberCapabilities)
4684 WLog_Print(log, WLOG_ERROR,
4685 "strange we haven't read the number of announced capacity sets, read=%d "
4686 "expected=%" PRIu16
"",
4687 count - numberCapabilities, count);
4690#ifdef WITH_DEBUG_CAPABILITIES
4691 rdp_print_capability_sets(log, s, capstart, TRUE);
4694 if (len > totalLength)
4696 WLog_Print(log, WLOG_ERROR,
"Capability length expected %" PRIu16
", actual %" PRIuz,
4700 rc = freerdp_capability_buffer_copy(settings, rcvSettings);
4705BOOL rdp_recv_get_active_header(rdpRdp* rdp,
wStream* s, UINT16* pChannelId, UINT16* length)
4708 WINPR_ASSERT(rdp->context);
4710 if (!rdp_read_header(rdp, s, length, pChannelId))
4713 if (freerdp_shall_disconnect_context(rdp->context))
4716 if (*pChannelId != MCS_GLOBAL_CHANNEL_ID)
4718 UINT16 mcsMessageChannelId = rdp->mcs->messageChannelId;
4720 if ((mcsMessageChannelId == 0) || (*pChannelId != mcsMessageChannelId))
4722 WLog_Print(rdp->log, WLOG_ERROR,
"unexpected MCS channel id %04" PRIx16
" received",
4731BOOL rdp_recv_demand_active(rdpRdp* rdp,
wStream* s, UINT16 pduSource, UINT16 length)
4733 UINT16 lengthSourceDescriptor = 0;
4734 UINT16 lengthCombinedCapabilities = 0;
4737 WINPR_ASSERT(rdp->settings);
4738 WINPR_ASSERT(rdp->context);
4741 rdp->settings->PduSource = pduSource;
4743 if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 8))
4746 Stream_Read_UINT32(s, rdp->settings->ShareId);
4747 Stream_Read_UINT16(s, lengthSourceDescriptor);
4748 Stream_Read_UINT16(s, lengthCombinedCapabilities);
4750 if (!Stream_SafeSeek(s, lengthSourceDescriptor) ||
4751 !Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 4))
4755 if (!rdp_read_capability_sets(rdp->log, s, rdp->settings, rdp->remoteSettings,
4756 lengthCombinedCapabilities))
4758 WLog_Print(rdp->log, WLOG_ERROR,
"rdp_read_capability_sets failed");
4762 if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 4))
4767 Stream_Seek_UINT32(s);
4771 secondary->glyph_v2 = (rdp->settings->GlyphSupportLevel > GLYPH_SUPPORT_FULL);
4774 return tpkt_ensure_stream_consumed(rdp->log, s, length);
4778static BOOL rdp_write_demand_active(wLog* log,
wStream* s, rdpSettings* settings)
4783 UINT16 numberCapabilities = 0;
4784 size_t lengthCombinedCapabilities = 0;
4786 if (!Stream_EnsureRemainingCapacity(s, 64))
4789 Stream_Write_UINT32(s, settings->ShareId);
4790 Stream_Write_UINT16(s, 4);
4791 lm = Stream_GetPosition(s);
4792 Stream_Seek_UINT16(s);
4793 Stream_Write(s,
"RDP", 4);
4794 bm = Stream_GetPosition(s);
4795 Stream_Seek_UINT16(s);
4796 Stream_Write_UINT16(s, 0);
4797 numberCapabilities = 14;
4799 if (!rdp_write_general_capability_set(log, s, settings) ||
4800 !rdp_write_bitmap_capability_set(log, s, settings) ||
4801 !rdp_write_order_capability_set(log, s, settings) ||
4802 !rdp_write_pointer_capability_set(log, s, settings) ||
4803 !rdp_write_input_capability_set(log, s, settings) ||
4804 !rdp_write_virtual_channel_capability_set(log, s, settings) ||
4805 !rdp_write_share_capability_set(log, s, settings) ||
4806 !rdp_write_font_capability_set(log, s, settings) ||
4807 !rdp_write_multifragment_update_capability_set(log, s, settings) ||
4808 !rdp_write_large_pointer_capability_set(log, s, settings) ||
4809 !rdp_write_desktop_composition_capability_set(log, s, settings) ||
4810 !rdp_write_surface_commands_capability_set(log, s, settings) ||
4811 !rdp_write_bitmap_codecs_capability_set(log, s, settings) ||
4812 !rdp_write_frame_acknowledge_capability_set(log, s, settings))
4819 numberCapabilities++;
4821 if (!rdp_write_bitmap_cache_host_support_capability_set(log, s, settings))
4825 if (settings->RemoteApplicationMode)
4827 numberCapabilities += 2;
4829 if (!rdp_write_remote_programs_capability_set(log, s, settings) ||
4830 !rdp_write_window_list_capability_set(log, s, settings))
4834 em = Stream_GetPosition(s);
4835 if (!Stream_SetPosition(s, lm))
4837 lengthCombinedCapabilities = (em - bm);
4838 if (lengthCombinedCapabilities > UINT16_MAX)
4840 Stream_Write_UINT16(
4841 s, (UINT16)lengthCombinedCapabilities);
4842 if (!Stream_SetPosition(s, bm))
4844 Stream_Write_UINT16(s, numberCapabilities);
4845#ifdef WITH_DEBUG_CAPABILITIES
4846 rdp_print_capability_sets(log, s, bm, FALSE);
4848 if (!Stream_SetPosition(s, em))
4850 Stream_Write_UINT32(s, 0);
4854BOOL rdp_send_demand_active(rdpRdp* rdp)
4856 UINT16 sec_flags = 0;
4857 wStream* s = rdp_send_stream_pdu_init(rdp, &sec_flags);
4863 rdp->settings->ShareId = 0x10000 + rdp->mcs->userId;
4864 status = rdp_write_demand_active(rdp->log, s, rdp->settings) &&
4865 rdp_send_pdu(rdp, s, PDU_TYPE_DEMAND_ACTIVE, rdp->mcs->userId, sec_flags);
4870BOOL rdp_recv_confirm_active(rdpRdp* rdp,
wStream* s, UINT16 pduLength)
4872 rdpSettings* settings =
nullptr;
4873 UINT16 lengthSourceDescriptor = 0;
4874 UINT16 lengthCombinedCapabilities = 0;
4878 settings = rdp->settings;
4879 WINPR_ASSERT(settings);
4881 if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 10))
4884 Stream_Seek_UINT32(s);
4885 Stream_Seek_UINT16(s);
4886 Stream_Read_UINT16(s, lengthSourceDescriptor);
4887 Stream_Read_UINT16(s, lengthCombinedCapabilities);
4889 if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, lengthSourceDescriptor + 4U))
4892 Stream_Seek(s, lengthSourceDescriptor);
4893 if (!rdp_read_capability_sets(rdp->log, s, rdp->settings, rdp->remoteSettings,
4894 lengthCombinedCapabilities))
4897 if (!settings->ReceivedCapabilities[CAPSET_TYPE_SURFACE_COMMANDS])
4900 settings->SurfaceCommandsEnabled = FALSE;
4901 settings->SurfaceFrameMarkerEnabled = FALSE;
4904 if (!settings->ReceivedCapabilities[CAPSET_TYPE_FRAME_ACKNOWLEDGE])
4907 settings->FrameAcknowledge = 0;
4910 if (!settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID])
4913 settings->BitmapCacheV3Enabled = FALSE;
4916 if (!settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CODECS])
4927 if (!settings->ReceivedCapabilities[CAPSET_TYPE_MULTI_FRAGMENT_UPDATE])
4931 FASTPATH_FRAGMENT_SAFE_SIZE))
4935 if (!settings->ReceivedCapabilities[CAPSET_TYPE_LARGE_POINTER])
4938 settings->LargePointerFlag = 0;
4941 return tpkt_ensure_stream_consumed(rdp->log, s, pduLength);
4945static BOOL rdp_write_confirm_active(wLog* log,
wStream* s, rdpSettings* settings)
4950 UINT16 numberCapabilities = 0;
4951 UINT16 lengthSourceDescriptor = 0;
4952 size_t lengthCombinedCapabilities = 0;
4955 WINPR_ASSERT(settings);
4957 lengthSourceDescriptor =
sizeof(SOURCE_DESCRIPTOR);
4958 Stream_Write_UINT32(s, settings->ShareId);
4959 Stream_Write_UINT16(s, 0x03EA);
4960 Stream_Write_UINT16(s, lengthSourceDescriptor);
4961 lm = Stream_GetPosition(s);
4962 Stream_Seek_UINT16(s);
4963 Stream_Write(s, SOURCE_DESCRIPTOR, lengthSourceDescriptor);
4964 bm = Stream_GetPosition(s);
4965 Stream_Seek_UINT16(s);
4966 Stream_Write_UINT16(s, 0);
4968 numberCapabilities = 15;
4970 if (!rdp_write_general_capability_set(log, s, settings) ||
4971 !rdp_write_bitmap_capability_set(log, s, settings) ||
4972 !rdp_write_order_capability_set(log, s, settings))
4975 if (settings->RdpVersion >= RDP_VERSION_5_PLUS)
4976 ret = rdp_write_bitmap_cache_v2_capability_set(log, s, settings);
4978 ret = rdp_write_bitmap_cache_capability_set(log, s, settings);
4983 if (!rdp_write_pointer_capability_set(log, s, settings) ||
4984 !rdp_write_input_capability_set(log, s, settings) ||
4985 !rdp_write_brush_capability_set(log, s, settings) ||
4986 !rdp_write_glyph_cache_capability_set(log, s, settings) ||
4987 !rdp_write_virtual_channel_capability_set(log, s, settings) ||
4988 !rdp_write_sound_capability_set(log, s, settings) ||
4989 !rdp_write_share_capability_set(log, s, settings) ||
4990 !rdp_write_font_capability_set(log, s, settings) ||
4991 !rdp_write_control_capability_set(log, s, settings) ||
4992 !rdp_write_color_cache_capability_set(log, s, settings) ||
4993 !rdp_write_window_activation_capability_set(log, s, settings))
4999 numberCapabilities++;
5001 if (!rdp_write_offscreen_bitmap_cache_capability_set(log, s, settings))
5005 if (settings->DrawNineGridEnabled)
5007 numberCapabilities++;
5009 if (!rdp_write_draw_nine_grid_cache_capability_set(log, s, settings))
5013 if (settings->ReceivedCapabilities[CAPSET_TYPE_LARGE_POINTER])
5015 if (settings->LargePointerFlag)
5017 numberCapabilities++;
5019 if (!rdp_write_large_pointer_capability_set(log, s, settings))
5024 if (settings->RemoteApplicationMode)
5026 numberCapabilities += 2;
5028 if (!rdp_write_remote_programs_capability_set(log, s, settings) ||
5029 !rdp_write_window_list_capability_set(log, s, settings))
5033 if (settings->ReceivedCapabilities[CAPSET_TYPE_MULTI_FRAGMENT_UPDATE])
5035 numberCapabilities++;
5037 if (!rdp_write_multifragment_update_capability_set(log, s, settings))
5041 if (settings->ReceivedCapabilities[CAPSET_TYPE_SURFACE_COMMANDS])
5043 numberCapabilities++;
5045 if (!rdp_write_surface_commands_capability_set(log, s, settings))
5049 if (settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CODECS])
5051 numberCapabilities++;
5053 if (!rdp_write_bitmap_codecs_capability_set(log, s, settings))
5057 if (!settings->ReceivedCapabilities[CAPSET_TYPE_FRAME_ACKNOWLEDGE])
5058 settings->FrameAcknowledge = 0;
5060 if (settings->FrameAcknowledge)
5062 numberCapabilities++;
5064 if (!rdp_write_frame_acknowledge_capability_set(log, s, settings))
5068 if (settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID])
5070 if (settings->BitmapCacheV3CodecId != 0)
5072 numberCapabilities++;
5074 if (!rdp_write_bitmap_cache_v3_codec_id_capability_set(log, s, settings))
5079 em = Stream_GetPosition(s);
5080 if (!Stream_SetPosition(s, lm))
5082 lengthCombinedCapabilities = (em - bm);
5083 if (lengthCombinedCapabilities > UINT16_MAX)
5085 Stream_Write_UINT16(
5086 s, (UINT16)lengthCombinedCapabilities);
5087 if (!Stream_SetPosition(s, bm))
5089 Stream_Write_UINT16(s, numberCapabilities);
5090#ifdef WITH_DEBUG_CAPABILITIES
5091 rdp_print_capability_sets(log, s, bm, FALSE);
5093 return Stream_SetPosition(s, em);
5096BOOL rdp_send_confirm_active(rdpRdp* rdp)
5098 UINT16 sec_flags = 0;
5099 wStream* s = rdp_send_stream_pdu_init(rdp, &sec_flags);
5105 status = rdp_write_confirm_active(rdp->log, s, rdp->settings) &&
5106 rdp_send_pdu(rdp, s, PDU_TYPE_CONFIRM_ACTIVE, rdp->mcs->userId, sec_flags);
5111const char* rdp_input_flag_string(UINT16 flags,
char* buffer,
size_t len)
5113 char prefix[16] = WINPR_C_ARRAY_INIT;
5115 (void)_snprintf(prefix,
sizeof(prefix),
"[0x%04" PRIx16
"][", flags);
5116 winpr_str_append(prefix, buffer, len,
"");
5117 if ((flags & INPUT_FLAG_SCANCODES) != 0)
5118 winpr_str_append(
"INPUT_FLAG_SCANCODES", buffer, len,
"|");
5119 if ((flags & INPUT_FLAG_MOUSEX) != 0)
5120 winpr_str_append(
"INPUT_FLAG_MOUSEX", buffer, len,
"|");
5121 if ((flags & INPUT_FLAG_FASTPATH_INPUT) != 0)
5122 winpr_str_append(
"INPUT_FLAG_FASTPATH_INPUT", buffer, len,
"|");
5123 if ((flags & INPUT_FLAG_UNICODE) != 0)
5124 winpr_str_append(
"INPUT_FLAG_UNICODE", buffer, len,
"|");
5125 if ((flags & INPUT_FLAG_FASTPATH_INPUT2) != 0)
5126 winpr_str_append(
"INPUT_FLAG_FASTPATH_INPUT2", buffer, len,
"|");
5127 if ((flags & INPUT_FLAG_UNUSED1) != 0)
5128 winpr_str_append(
"INPUT_FLAG_UNUSED1", buffer, len,
"|");
5129 if ((flags & INPUT_FLAG_MOUSE_RELATIVE) != 0)
5130 winpr_str_append(
"INPUT_FLAG_MOUSE_RELATIVE", buffer, len,
"|");
5131 if ((flags & TS_INPUT_FLAG_MOUSE_HWHEEL) != 0)
5132 winpr_str_append(
"TS_INPUT_FLAG_MOUSE_HWHEEL", buffer, len,
"|");
5133 if ((flags & TS_INPUT_FLAG_QOE_TIMESTAMPS) != 0)
5134 winpr_str_append(
"TS_INPUT_FLAG_QOE_TIMESTAMPS", buffer, len,
"|");
5135 winpr_str_append(
"]", buffer, len,
"");
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.
WINPR_ATTR_NODISCARD 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 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.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_set_uint32(rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id, UINT32 val)
Sets a UINT32 settings value.
WINPR_ATTR_NODISCARD 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_set_string(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const char *val)
Sets a string settings value. The param is copied.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.