20#include <winpr/wtsapi.h>
21#include <winpr/assert.h>
22#include <winpr/cast.h>
23#include <freerdp/config.h>
26#include "capabilities.h"
32#include <freerdp/log.h>
34static const char*
const CAPSET_TYPE_STRINGS[] = {
"Unknown",
51 "Offscreen Bitmap Cache",
52 "Bitmap Cache Host Support",
59 "Desktop Composition",
60 "Multifragment Update",
64 "Frame Acknowledge" };
66static const char* get_capability_name(UINT16 type)
68 if (type > CAPSET_TYPE_FRAME_ACKNOWLEDGE)
71 return CAPSET_TYPE_STRINGS[type];
74#ifdef WITH_DEBUG_CAPABILITIES
75static BOOL rdp_print_capability_sets(wLog* log,
wStream* s,
size_t start, BOOL receiving);
80static const GUID CODEC_GUID_REMOTEFX = {
81 0x76772F12, 0xBD72, 0x4463, { 0xAF, 0xB3, 0xB7, 0x3C, 0x9C, 0x6F, 0x78, 0x86 }
86static const GUID CODEC_GUID_NSCODEC = {
87 0xCA8D1BB9, 0x000F, 0x154F, { 0x58, 0x9F, 0xAE, 0x2D, 0x1A, 0x87, 0xE2, 0xD6 }
92static const GUID CODEC_GUID_IGNORE = {
93 0x9C4351A6, 0x3535, 0x42AE, { 0x91, 0x0C, 0xCD, 0xFC, 0xE5, 0x76, 0x0B, 0x58 }
98static const GUID CODEC_GUID_IMAGE_REMOTEFX = {
99 0x2744CCD4, 0x9D8A, 0x4E74, { 0x80, 0x3C, 0x0E, 0xCB, 0xEE, 0xA1, 0x9C, 0x54 }
102#if defined(WITH_JPEG)
105static const GUID CODEC_GUID_JPEG = {
106 0x430C9EED, 0x1BAF, 0x4CE6, { 0x86, 0x9A, 0xCB, 0x8B, 0x37, 0xB6, 0x62, 0x37 }
110static BOOL rdp_read_capability_set_header(wLog* log,
wStream* s, UINT16* length, UINT16* type)
113 WINPR_ASSERT(length);
116 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
118 Stream_Read_UINT16(s, *type);
119 Stream_Read_UINT16(s, *length);
120 return (*length >= 4);
123static void rdp_write_capability_set_header(
wStream* s, UINT16 length, UINT16 type)
126 WINPR_ASSERT(Stream_GetRemainingCapacity(s) >= 4);
127 Stream_Write_UINT16(s, type);
128 Stream_Write_UINT16(s, length);
131static size_t rdp_capability_set_start(wLog* log,
wStream* s)
133 size_t header = Stream_GetPosition(s);
134 if (!Stream_CheckAndLogRequiredCapacityWLog(log, (s), CAPSET_HEADER_LENGTH))
136 Stream_Zero(s, CAPSET_HEADER_LENGTH);
140static BOOL rdp_capability_set_finish(
wStream* s,
size_t header, UINT16 type)
142 const size_t footer = Stream_GetPosition(s);
145 if (header > UINT16_MAX)
147 const size_t length = footer - header;
148 if ((Stream_Capacity(s) < header + 4ULL) || (length > UINT16_MAX))
150 Stream_SetPosition(s, header);
151 rdp_write_capability_set_header(s, (UINT16)length, type);
152 Stream_SetPosition(s, footer);
156static BOOL rdp_apply_general_capability_set(rdpSettings* settings,
const rdpSettings* src)
158 WINPR_ASSERT(settings);
161 if (settings->ServerMode)
163 settings->OsMajorType = src->OsMajorType;
164 settings->OsMinorType = src->OsMinorType;
167 settings->CapsProtocolVersion = src->CapsProtocolVersion;
168 settings->NoBitmapCompressionHeader = src->NoBitmapCompressionHeader;
169 settings->LongCredentialsSupported = src->LongCredentialsSupported;
170 settings->AutoReconnectionPacketSupported = src->AutoReconnectionPacketSupported;
171 if (!src->FastPathOutput)
172 settings->FastPathOutput = FALSE;
174 if (!src->SaltedChecksum)
175 settings->SaltedChecksum = FALSE;
177 if (!settings->ServerMode)
184 if (!src->RefreshRect)
185 settings->RefreshRect = FALSE;
187 if (!src->SuppressOutput)
188 settings->SuppressOutput = FALSE;
198static BOOL rdp_read_general_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
200 UINT16 extraFlags = 0;
201 BYTE refreshRectSupport = 0;
202 BYTE suppressOutputSupport = 0;
204 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 20))
207 WINPR_ASSERT(settings);
208 Stream_Read_UINT16(s, settings->OsMajorType);
209 Stream_Read_UINT16(s, settings->OsMinorType);
211 Stream_Read_UINT16(s, settings->CapsProtocolVersion);
212 if (settings->CapsProtocolVersion != TS_CAPS_PROTOCOLVERSION)
214 WLog_Print(log, WLOG_ERROR,
215 "TS_GENERAL_CAPABILITYSET::protocolVersion(0x%04" PRIx16
216 ") != TS_CAPS_PROTOCOLVERSION(0x%04" PRIx32
")",
217 settings->CapsProtocolVersion,
218 WINPR_CXX_COMPAT_CAST(UINT32, TS_CAPS_PROTOCOLVERSION));
219 if (settings->CapsProtocolVersion == 0x0000)
221 WLog_Print(log, WLOG_WARN,
222 "TS_GENERAL_CAPABILITYSET::protocolVersion(0x%04" PRIx16
223 " assuming old FreeRDP, ignoring protocol violation, correcting value.",
224 settings->CapsProtocolVersion);
225 settings->CapsProtocolVersion = TS_CAPS_PROTOCOLVERSION;
230 Stream_Seek_UINT16(s);
232 s, settings->CapsGeneralCompressionTypes);
233 Stream_Read_UINT16(s, extraFlags);
234 Stream_Read_UINT16(s, settings->CapsUpdateCapabilityFlag);
235 Stream_Read_UINT16(s, settings->CapsRemoteUnshareFlag);
237 s, settings->CapsGeneralCompressionLevel);
238 Stream_Read_UINT8(s, refreshRectSupport);
239 Stream_Read_UINT8(s, suppressOutputSupport);
240 settings->NoBitmapCompressionHeader = (extraFlags & NO_BITMAP_COMPRESSION_HDR) != 0;
241 settings->LongCredentialsSupported = (extraFlags & LONG_CREDENTIALS_SUPPORTED) != 0;
243 settings->AutoReconnectionPacketSupported = (extraFlags & AUTORECONNECT_SUPPORTED) != 0;
244 settings->FastPathOutput = (extraFlags & FASTPATH_OUTPUT_SUPPORTED) != 0;
245 settings->SaltedChecksum = (extraFlags & ENC_SALTED_CHECKSUM) != 0;
246 settings->RefreshRect = refreshRectSupport;
247 settings->SuppressOutput = suppressOutputSupport;
257static BOOL rdp_write_general_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
259 if (!Stream_EnsureRemainingCapacity(s, 64))
262 const size_t header = rdp_capability_set_start(log, s);
263 UINT16 extraFlags = 0;
265 WINPR_ASSERT(settings);
266 if (settings->LongCredentialsSupported)
267 extraFlags |= LONG_CREDENTIALS_SUPPORTED;
269 if (settings->NoBitmapCompressionHeader)
270 extraFlags |= NO_BITMAP_COMPRESSION_HDR;
272 if (settings->AutoReconnectionPacketSupported)
273 extraFlags |= AUTORECONNECT_SUPPORTED;
275 if (settings->FastPathOutput)
276 extraFlags |= FASTPATH_OUTPUT_SUPPORTED;
278 if (settings->SaltedChecksum)
279 extraFlags |= ENC_SALTED_CHECKSUM;
281 if ((settings->OsMajorType > UINT16_MAX) || (settings->OsMinorType > UINT16_MAX))
283 WLog_Print(log, WLOG_ERROR,
284 "OsMajorType=%08" PRIx32
", OsMinorType=%08" PRIx32
285 " they need to be smaller %04" PRIx32,
286 settings->OsMajorType, settings->OsMinorType,
287 WINPR_CXX_COMPAT_CAST(UINT32, UINT16_MAX));
290 if (settings->CapsProtocolVersion != TS_CAPS_PROTOCOLVERSION)
292 WLog_Print(log, WLOG_ERROR,
293 "TS_GENERAL_CAPABILITYSET::protocolVersion(0x%04" PRIx16
294 ") != TS_CAPS_PROTOCOLVERSION(0x%04" PRIx32
")",
295 settings->CapsProtocolVersion,
296 WINPR_CXX_COMPAT_CAST(UINT32, TS_CAPS_PROTOCOLVERSION));
299 Stream_Write_UINT16(s, (UINT16)settings->OsMajorType);
300 Stream_Write_UINT16(s, (UINT16)settings->OsMinorType);
301 Stream_Write_UINT16(s, settings->CapsProtocolVersion);
302 Stream_Write_UINT16(s, 0);
304 s, settings->CapsGeneralCompressionTypes);
305 Stream_Write_UINT16(s, extraFlags);
306 Stream_Write_UINT16(s, settings->CapsUpdateCapabilityFlag);
307 Stream_Write_UINT16(s, settings->CapsRemoteUnshareFlag);
309 s, settings->CapsGeneralCompressionLevel);
310 Stream_Write_UINT8(s, settings->RefreshRect ? 1 : 0);
311 Stream_Write_UINT8(s, settings->SuppressOutput ? 1 : 0);
312 return rdp_capability_set_finish(s, header, CAPSET_TYPE_GENERAL);
315#ifdef WITH_DEBUG_CAPABILITIES
316static BOOL rdp_print_general_capability_set(wLog* log,
wStream* s)
318 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 20))
321 WLog_Print(log, WLOG_TRACE,
322 "GeneralCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
323 const uint16_t osMinorType = Stream_Get_UINT16(s);
324 const uint16_t osMajorType = Stream_Get_UINT16(s);
325 const uint16_t protocolVersion = Stream_Get_UINT16(s);
326 const uint16_t pad2OctetsA = Stream_Get_UINT16(s);
327 const uint16_t generalCompressionTypes =
328 Stream_Get_UINT16(s);
329 const uint16_t extraFlags = Stream_Get_UINT16(s);
330 const uint16_t updateCapabilityFlag = Stream_Get_UINT16(s);
331 const uint16_t remoteUnshareFlag = Stream_Get_UINT16(s);
332 const uint16_t generalCompressionLevel =
333 Stream_Get_UINT16(s);
334 const uint8_t refreshRectSupport = Stream_Get_UINT8(s);
335 const uint8_t suppressOutputSupport = Stream_Get_UINT8(s);
336 WLog_Print(log, WLOG_TRACE,
"\tosMajorType: 0x%04" PRIX16
"", osMajorType);
337 WLog_Print(log, WLOG_TRACE,
"\tosMinorType: 0x%04" PRIX16
"", osMinorType);
338 WLog_Print(log, WLOG_TRACE,
"\tprotocolVersion: 0x%04" PRIX16
"", protocolVersion);
339 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
340 WLog_Print(log, WLOG_TRACE,
"\tgeneralCompressionTypes: 0x%04" PRIX16
"",
341 generalCompressionTypes);
342 WLog_Print(log, WLOG_TRACE,
"\textraFlags: 0x%04" PRIX16
"", extraFlags);
343 WLog_Print(log, WLOG_TRACE,
"\tupdateCapabilityFlag: 0x%04" PRIX16
"", updateCapabilityFlag);
344 WLog_Print(log, WLOG_TRACE,
"\tremoteUnshareFlag: 0x%04" PRIX16
"", remoteUnshareFlag);
345 WLog_Print(log, WLOG_TRACE,
"\tgeneralCompressionLevel: 0x%04" PRIX16
"",
346 generalCompressionLevel);
347 WLog_Print(log, WLOG_TRACE,
"\trefreshRectSupport: 0x%02" PRIX8
"", refreshRectSupport);
348 WLog_Print(log, WLOG_TRACE,
"\tsuppressOutputSupport: 0x%02" PRIX8
"", suppressOutputSupport);
352static BOOL rdp_apply_bitmap_capability_set(rdpSettings* settings,
const rdpSettings* src)
354 WINPR_ASSERT(settings);
357 if (!settings->ServerMode)
364 if (!src->DesktopResize)
365 settings->DesktopResize = FALSE;
367 if (!settings->ServerMode && settings->DesktopResize)
371 settings->DesktopWidth = src->DesktopWidth;
372 settings->DesktopHeight = src->DesktopHeight;
375 if (settings->DrawAllowSkipAlpha)
376 settings->DrawAllowSkipAlpha = src->DrawAllowSkipAlpha;
378 if (settings->DrawAllowDynamicColorFidelity)
379 settings->DrawAllowDynamicColorFidelity = src->DrawAllowDynamicColorFidelity;
381 if (settings->DrawAllowColorSubsampling)
382 settings->DrawAllowColorSubsampling = src->DrawAllowColorSubsampling;
392static BOOL rdp_read_bitmap_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
394 BYTE drawingFlags = 0;
395 UINT16 desktopWidth = 0;
396 UINT16 desktopHeight = 0;
397 UINT16 desktopResizeFlag = 0;
398 UINT16 preferredBitsPerPixel = 0;
400 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 24))
403 Stream_Read_UINT16(s, preferredBitsPerPixel);
404 Stream_Seek_UINT16(s);
405 Stream_Seek_UINT16(s);
406 Stream_Seek_UINT16(s);
407 Stream_Read_UINT16(s, desktopWidth);
408 Stream_Read_UINT16(s, desktopHeight);
409 Stream_Seek_UINT16(s);
410 Stream_Read_UINT16(s, desktopResizeFlag);
411 Stream_Seek_UINT16(s);
412 Stream_Seek_UINT8(s);
413 Stream_Read_UINT8(s, drawingFlags);
414 Stream_Seek_UINT16(s);
415 Stream_Seek_UINT16(s);
419 settings->DesktopResize = desktopResizeFlag;
420 settings->DesktopWidth = desktopWidth;
421 settings->DesktopHeight = desktopHeight;
422 settings->DrawAllowSkipAlpha = (drawingFlags & DRAW_ALLOW_SKIP_ALPHA) != 0;
423 settings->DrawAllowDynamicColorFidelity =
424 (drawingFlags & DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY) != 0;
425 settings->DrawAllowColorSubsampling = (drawingFlags & DRAW_ALLOW_COLOR_SUBSAMPLING) != 0;
435static BOOL rdp_write_bitmap_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
437 BYTE drawingFlags = 0;
438 UINT16 preferredBitsPerPixel = 0;
440 if (!Stream_EnsureRemainingCapacity(s, 64))
443 const size_t header = rdp_capability_set_start(log, s);
445 WINPR_ASSERT(settings);
446 if (settings->DrawAllowSkipAlpha)
447 drawingFlags |= DRAW_ALLOW_SKIP_ALPHA;
449 if (settings->DrawAllowDynamicColorFidelity)
450 drawingFlags |= DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY;
452 if (settings->DrawAllowColorSubsampling)
453 drawingFlags |= DRAW_ALLOW_COLOR_SUBSAMPLING;
465 (settings->DesktopWidth > UINT16_MAX) || (settings->DesktopHeight > UINT16_MAX))
468 if (settings->RdpVersion >= RDP_VERSION_5_PLUS)
471 preferredBitsPerPixel = 8;
473 Stream_Write_UINT16(s, preferredBitsPerPixel);
474 Stream_Write_UINT16(s, 1);
475 Stream_Write_UINT16(s, 1);
476 Stream_Write_UINT16(s, 1);
477 Stream_Write_UINT16(s, (UINT16)settings->DesktopWidth);
478 Stream_Write_UINT16(s, (UINT16)settings->DesktopHeight);
479 Stream_Write_UINT16(s, 0);
480 Stream_Write_UINT16(s, (UINT16)settings->DesktopResize);
481 Stream_Write_UINT16(s, 1);
482 Stream_Write_UINT8(s, 0);
483 Stream_Write_UINT8(s, drawingFlags);
484 Stream_Write_UINT16(s, 1);
485 Stream_Write_UINT16(s, 0);
486 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP);
489#ifdef WITH_DEBUG_CAPABILITIES
490static BOOL rdp_print_bitmap_capability_set(wLog* log,
wStream* s)
492 UINT16 preferredBitsPerPixel = 0;
493 UINT16 receive1BitPerPixel = 0;
494 UINT16 receive4BitsPerPixel = 0;
495 UINT16 receive8BitsPerPixel = 0;
496 UINT16 desktopWidth = 0;
497 UINT16 desktopHeight = 0;
498 UINT16 pad2Octets = 0;
499 UINT16 desktopResizeFlag = 0;
500 UINT16 bitmapCompressionFlag = 0;
501 BYTE highColorFlags = 0;
502 BYTE drawingFlags = 0;
503 UINT16 multipleRectangleSupport = 0;
504 UINT16 pad2OctetsB = 0;
505 WLog_Print(log, WLOG_TRACE,
506 "BitmapCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
508 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 24))
511 Stream_Read_UINT16(s, preferredBitsPerPixel);
512 Stream_Read_UINT16(s, receive1BitPerPixel);
513 Stream_Read_UINT16(s, receive4BitsPerPixel);
514 Stream_Read_UINT16(s, receive8BitsPerPixel);
515 Stream_Read_UINT16(s, desktopWidth);
516 Stream_Read_UINT16(s, desktopHeight);
517 Stream_Read_UINT16(s, pad2Octets);
518 Stream_Read_UINT16(s, desktopResizeFlag);
519 Stream_Read_UINT16(s, bitmapCompressionFlag);
520 Stream_Read_UINT8(s, highColorFlags);
521 Stream_Read_UINT8(s, drawingFlags);
522 Stream_Read_UINT16(s, multipleRectangleSupport);
523 Stream_Read_UINT16(s, pad2OctetsB);
524 WLog_Print(log, WLOG_TRACE,
"\tpreferredBitsPerPixel: 0x%04" PRIX16
"", preferredBitsPerPixel);
525 WLog_Print(log, WLOG_TRACE,
"\treceive1BitPerPixel: 0x%04" PRIX16
"", receive1BitPerPixel);
526 WLog_Print(log, WLOG_TRACE,
"\treceive4BitsPerPixel: 0x%04" PRIX16
"", receive4BitsPerPixel);
527 WLog_Print(log, WLOG_TRACE,
"\treceive8BitsPerPixel: 0x%04" PRIX16
"", receive8BitsPerPixel);
528 WLog_Print(log, WLOG_TRACE,
"\tdesktopWidth: 0x%04" PRIX16
"", desktopWidth);
529 WLog_Print(log, WLOG_TRACE,
"\tdesktopHeight: 0x%04" PRIX16
"", desktopHeight);
530 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
531 WLog_Print(log, WLOG_TRACE,
"\tdesktopResizeFlag: 0x%04" PRIX16
"", desktopResizeFlag);
532 WLog_Print(log, WLOG_TRACE,
"\tbitmapCompressionFlag: 0x%04" PRIX16
"", bitmapCompressionFlag);
533 WLog_Print(log, WLOG_TRACE,
"\thighColorFlags: 0x%02" PRIX8
"", highColorFlags);
534 WLog_Print(log, WLOG_TRACE,
"\tdrawingFlags: 0x%02" PRIX8
"", drawingFlags);
535 WLog_Print(log, WLOG_TRACE,
"\tmultipleRectangleSupport: 0x%04" PRIX16
"",
536 multipleRectangleSupport);
537 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsB: 0x%04" PRIX16
"", pad2OctetsB);
541static BOOL rdp_apply_order_capability_set(rdpSettings* settings,
const rdpSettings* src)
543 WINPR_ASSERT(settings);
546 BOOL BitmapCacheV3Enabled = FALSE;
547 BOOL FrameMarkerCommandEnabled = FALSE;
549 for (
size_t i = 0; i < 32; i++)
551 if (!src->OrderSupport[i])
552 settings->OrderSupport[i] = FALSE;
555 if (src->OrderSupportFlags & ORDER_FLAGS_EXTRA_SUPPORT)
557 if (src->OrderSupportFlagsEx & CACHE_BITMAP_V3_SUPPORT)
558 BitmapCacheV3Enabled = TRUE;
560 if (src->OrderSupportFlagsEx & ALTSEC_FRAME_MARKER_SUPPORT)
561 FrameMarkerCommandEnabled = TRUE;
564 if (BitmapCacheV3Enabled && settings->BitmapCacheV3Enabled)
566 settings->BitmapCacheV3Enabled = src->BitmapCacheV3Enabled;
567 settings->BitmapCacheVersion = src->BitmapCacheVersion;
570 settings->BitmapCacheV3Enabled = FALSE;
572 settings->FrameMarkerCommandEnabled =
573 (FrameMarkerCommandEnabled && src->FrameMarkerCommandEnabled);
583static BOOL rdp_read_order_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
585 char terminalDescriptor[17] = WINPR_C_ARRAY_INIT;
586 BYTE orderSupport[32] = WINPR_C_ARRAY_INIT;
587 BOOL BitmapCacheV3Enabled = FALSE;
588 BOOL FrameMarkerCommandEnabled = FALSE;
590 WINPR_ASSERT(settings);
591 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 84))
594 Stream_Read(s, terminalDescriptor, 16);
595 Stream_Seek_UINT32(s);
596 Stream_Seek_UINT16(s);
597 Stream_Seek_UINT16(s);
598 Stream_Seek_UINT16(s);
599 Stream_Seek_UINT16(s);
600 Stream_Seek_UINT16(s);
601 Stream_Read_UINT16(s, settings->OrderSupportFlags);
602 Stream_Read(s, orderSupport, 32);
603 Stream_Seek_UINT16(s);
604 Stream_Read_UINT16(s, settings->OrderSupportFlagsEx);
605 Stream_Seek_UINT32(s);
606 Stream_Seek_UINT32(s);
607 Stream_Seek_UINT16(s);
608 Stream_Seek_UINT16(s);
609 Stream_Read_UINT16(s, settings->TextANSICodePage);
610 Stream_Seek_UINT16(s);
615 for (
size_t i = 0; i < ARRAYSIZE(orderSupport); i++)
616 settings->OrderSupport[i] = orderSupport[i];
618 if (settings->OrderSupportFlags & ORDER_FLAGS_EXTRA_SUPPORT)
620 BitmapCacheV3Enabled = (settings->OrderSupportFlagsEx & CACHE_BITMAP_V3_SUPPORT) != 0;
621 FrameMarkerCommandEnabled =
622 (settings->OrderSupportFlagsEx & ALTSEC_FRAME_MARKER_SUPPORT) != 0;
625 settings->BitmapCacheV3Enabled = BitmapCacheV3Enabled;
626 if (BitmapCacheV3Enabled)
627 settings->BitmapCacheVersion = 3;
629 settings->FrameMarkerCommandEnabled = FrameMarkerCommandEnabled;
639static BOOL rdp_write_order_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
641 char terminalDescriptor[16] = WINPR_C_ARRAY_INIT;
643 WINPR_ASSERT(settings);
644 if (!Stream_EnsureRemainingCapacity(s, 64))
647 const size_t header = rdp_capability_set_start(log, s);
649 UINT16 orderSupportExFlags = settings->OrderSupportFlagsEx;
650 UINT16 orderFlags = settings->OrderSupportFlags;
652 if (settings->BitmapCacheV3Enabled)
654 if ((orderSupportExFlags & CACHE_BITMAP_V3_SUPPORT) == 0)
656 WLog_Print(log, WLOG_WARN,
657 "rdpSettings::BitmapCacheV3Enabled=TRUE, but CACHE_BITMAP_V3_SUPPORT not "
658 "set in rdpSettings::OrderSupportEx, aborting.");
660 if ((orderFlags & ORDER_FLAGS_EXTRA_SUPPORT) == 0)
662 WLog_Print(log, WLOG_WARN,
663 "rdpSettings::BitmapCacheV3Enabled=TRUE, but ORDER_FLAGS_EXTRA_SUPPORT not "
664 "set in rdpSettings::OrderSupport, aborting.");
668 if (settings->FrameMarkerCommandEnabled)
670 if ((orderSupportExFlags & ALTSEC_FRAME_MARKER_SUPPORT) == 0)
674 "rdpSettings::FrameMarkerCommandEnabled=TRUE, but "
675 "ALTSEC_FRAME_MARKER_SUPPORT not set in rdpSettings::OrderSupportEx, aborting.");
677 if ((orderFlags & ORDER_FLAGS_EXTRA_SUPPORT) == 0)
679 WLog_Print(log, WLOG_WARN,
680 "rdpSettings::FrameMarkerCommandEnabled=TRUE, but ORDER_FLAGS_EXTRA_SUPPORT "
681 "not set in rdpSettings::OrderSupport, aborting.");
688 const size_t len = strnlen(dsc, ARRAYSIZE(terminalDescriptor));
689 strncpy(terminalDescriptor, dsc, len);
691 Stream_Write(s, terminalDescriptor,
692 sizeof(terminalDescriptor));
693 Stream_Write_UINT32(s, 0);
694 Stream_Write_UINT16(s, 1);
695 Stream_Write_UINT16(s, 20);
696 Stream_Write_UINT16(s, 0);
697 Stream_Write_UINT16(s, 1);
698 Stream_Write_UINT16(s, 0);
699 Stream_Write_UINT16(s, orderFlags);
700 Stream_Write(s, settings->OrderSupport, 32);
701 Stream_Write_UINT16(s, 0);
702 Stream_Write_UINT16(s, orderSupportExFlags);
703 Stream_Write_UINT32(s, 0);
704 Stream_Write_UINT32(s, 230400);
705 Stream_Write_UINT16(s, 0);
706 Stream_Write_UINT16(s, 0);
707 Stream_Write_UINT16(s, settings->TextANSICodePage);
708 Stream_Write_UINT16(s, 0);
709 return rdp_capability_set_finish(s, header, CAPSET_TYPE_ORDER);
712#ifdef WITH_DEBUG_CAPABILITIES
713static BOOL rdp_print_order_capability_set(wLog* log,
wStream* s)
715 BYTE terminalDescriptor[16];
716 UINT32 pad4OctetsA = 0;
717 UINT16 desktopSaveXGranularity = 0;
718 UINT16 desktopSaveYGranularity = 0;
719 UINT16 pad2OctetsA = 0;
720 UINT16 maximumOrderLevel = 0;
721 UINT16 numberFonts = 0;
722 UINT16 orderFlags = 0;
723 BYTE orderSupport[32];
724 UINT16 textFlags = 0;
725 UINT16 orderSupportExFlags = 0;
726 UINT32 pad4OctetsB = 0;
727 UINT32 desktopSaveSize = 0;
728 UINT16 pad2OctetsC = 0;
729 UINT16 pad2OctetsD = 0;
730 UINT16 textANSICodePage = 0;
731 UINT16 pad2OctetsE = 0;
732 WLog_Print(log, WLOG_TRACE,
733 "OrderCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
735 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 84))
738 Stream_Read(s, terminalDescriptor, 16);
739 Stream_Read_UINT32(s, pad4OctetsA);
740 Stream_Read_UINT16(s, desktopSaveXGranularity);
741 Stream_Read_UINT16(s, desktopSaveYGranularity);
742 Stream_Read_UINT16(s, pad2OctetsA);
743 Stream_Read_UINT16(s, maximumOrderLevel);
744 Stream_Read_UINT16(s, numberFonts);
745 Stream_Read_UINT16(s, orderFlags);
746 Stream_Read(s, orderSupport, 32);
747 Stream_Read_UINT16(s, textFlags);
748 Stream_Read_UINT16(s, orderSupportExFlags);
749 Stream_Read_UINT32(s, pad4OctetsB);
750 Stream_Read_UINT32(s, desktopSaveSize);
751 Stream_Read_UINT16(s, pad2OctetsC);
752 Stream_Read_UINT16(s, pad2OctetsD);
753 Stream_Read_UINT16(s, textANSICodePage);
754 Stream_Read_UINT16(s, pad2OctetsE);
755 WLog_Print(log, WLOG_TRACE,
"\tpad4OctetsA: 0x%08" PRIX32
"", pad4OctetsA);
756 WLog_Print(log, WLOG_TRACE,
"\tdesktopSaveXGranularity: 0x%04" PRIX16
"",
757 desktopSaveXGranularity);
758 WLog_Print(log, WLOG_TRACE,
"\tdesktopSaveYGranularity: 0x%04" PRIX16
"",
759 desktopSaveYGranularity);
760 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
761 WLog_Print(log, WLOG_TRACE,
"\tmaximumOrderLevel: 0x%04" PRIX16
"", maximumOrderLevel);
762 WLog_Print(log, WLOG_TRACE,
"\tnumberFonts: 0x%04" PRIX16
"", numberFonts);
763 WLog_Print(log, WLOG_TRACE,
"\torderFlags: 0x%04" PRIX16
"", orderFlags);
764 WLog_Print(log, WLOG_TRACE,
"\torderSupport:");
765 WLog_Print(log, WLOG_TRACE,
"\t\tDSTBLT: %" PRIu8
"", orderSupport[NEG_DSTBLT_INDEX]);
766 WLog_Print(log, WLOG_TRACE,
"\t\tPATBLT: %" PRIu8
"", orderSupport[NEG_PATBLT_INDEX]);
767 WLog_Print(log, WLOG_TRACE,
"\t\tSCRBLT: %" PRIu8
"", orderSupport[NEG_SCRBLT_INDEX]);
768 WLog_Print(log, WLOG_TRACE,
"\t\tMEMBLT: %" PRIu8
"", orderSupport[NEG_MEMBLT_INDEX]);
769 WLog_Print(log, WLOG_TRACE,
"\t\tMEM3BLT: %" PRIu8
"", orderSupport[NEG_MEM3BLT_INDEX]);
770 WLog_Print(log, WLOG_TRACE,
"\t\tATEXTOUT: %" PRIu8
"", orderSupport[NEG_ATEXTOUT_INDEX]);
771 WLog_Print(log, WLOG_TRACE,
"\t\tAEXTTEXTOUT: %" PRIu8
"", orderSupport[NEG_AEXTTEXTOUT_INDEX]);
772 WLog_Print(log, WLOG_TRACE,
"\t\tDRAWNINEGRID: %" PRIu8
"",
773 orderSupport[NEG_DRAWNINEGRID_INDEX]);
774 WLog_Print(log, WLOG_TRACE,
"\t\tLINETO: %" PRIu8
"", orderSupport[NEG_LINETO_INDEX]);
775 WLog_Print(log, WLOG_TRACE,
"\t\tMULTI_DRAWNINEGRID: %" PRIu8
"",
776 orderSupport[NEG_MULTI_DRAWNINEGRID_INDEX]);
777 WLog_Print(log, WLOG_TRACE,
"\t\tOPAQUE_RECT: %" PRIu8
"", orderSupport[NEG_OPAQUE_RECT_INDEX]);
778 WLog_Print(log, WLOG_TRACE,
"\t\tSAVEBITMAP: %" PRIu8
"", orderSupport[NEG_SAVEBITMAP_INDEX]);
779 WLog_Print(log, WLOG_TRACE,
"\t\tWTEXTOUT: %" PRIu8
"", orderSupport[NEG_WTEXTOUT_INDEX]);
780 WLog_Print(log, WLOG_TRACE,
"\t\tMEMBLT_V2: %" PRIu8
"", orderSupport[NEG_MEMBLT_V2_INDEX]);
781 WLog_Print(log, WLOG_TRACE,
"\t\tMEM3BLT_V2: %" PRIu8
"", orderSupport[NEG_MEM3BLT_V2_INDEX]);
782 WLog_Print(log, WLOG_TRACE,
"\t\tMULTIDSTBLT: %" PRIu8
"", orderSupport[NEG_MULTIDSTBLT_INDEX]);
783 WLog_Print(log, WLOG_TRACE,
"\t\tMULTIPATBLT: %" PRIu8
"", orderSupport[NEG_MULTIPATBLT_INDEX]);
784 WLog_Print(log, WLOG_TRACE,
"\t\tMULTISCRBLT: %" PRIu8
"", orderSupport[NEG_MULTISCRBLT_INDEX]);
785 WLog_Print(log, WLOG_TRACE,
"\t\tMULTIOPAQUERECT: %" PRIu8
"",
786 orderSupport[NEG_MULTIOPAQUERECT_INDEX]);
787 WLog_Print(log, WLOG_TRACE,
"\t\tFAST_INDEX: %" PRIu8
"", orderSupport[NEG_FAST_INDEX_INDEX]);
788 WLog_Print(log, WLOG_TRACE,
"\t\tPOLYGON_SC: %" PRIu8
"", orderSupport[NEG_POLYGON_SC_INDEX]);
789 WLog_Print(log, WLOG_TRACE,
"\t\tPOLYGON_CB: %" PRIu8
"", orderSupport[NEG_POLYGON_CB_INDEX]);
790 WLog_Print(log, WLOG_TRACE,
"\t\tPOLYLINE: %" PRIu8
"", orderSupport[NEG_POLYLINE_INDEX]);
791 WLog_Print(log, WLOG_TRACE,
"\t\tUNUSED23: %" PRIu8
"", orderSupport[NEG_UNUSED23_INDEX]);
792 WLog_Print(log, WLOG_TRACE,
"\t\tFAST_GLYPH: %" PRIu8
"", orderSupport[NEG_FAST_GLYPH_INDEX]);
793 WLog_Print(log, WLOG_TRACE,
"\t\tELLIPSE_SC: %" PRIu8
"", orderSupport[NEG_ELLIPSE_SC_INDEX]);
794 WLog_Print(log, WLOG_TRACE,
"\t\tELLIPSE_CB: %" PRIu8
"", orderSupport[NEG_ELLIPSE_CB_INDEX]);
795 WLog_Print(log, WLOG_TRACE,
"\t\tGLYPH_INDEX: %" PRIu8
"", orderSupport[NEG_GLYPH_INDEX_INDEX]);
796 WLog_Print(log, WLOG_TRACE,
"\t\tGLYPH_WEXTTEXTOUT: %" PRIu8
"",
797 orderSupport[NEG_GLYPH_WEXTTEXTOUT_INDEX]);
798 WLog_Print(log, WLOG_TRACE,
"\t\tGLYPH_WLONGTEXTOUT: %" PRIu8
"",
799 orderSupport[NEG_GLYPH_WLONGTEXTOUT_INDEX]);
800 WLog_Print(log, WLOG_TRACE,
"\t\tGLYPH_WLONGEXTTEXTOUT: %" PRIu8
"",
801 orderSupport[NEG_GLYPH_WLONGEXTTEXTOUT_INDEX]);
802 WLog_Print(log, WLOG_TRACE,
"\t\tUNUSED31: %" PRIu8
"", orderSupport[NEG_UNUSED31_INDEX]);
803 WLog_Print(log, WLOG_TRACE,
"\ttextFlags: 0x%04" PRIX16
"", textFlags);
804 WLog_Print(log, WLOG_TRACE,
"\torderSupportExFlags: 0x%04" PRIX16
"", orderSupportExFlags);
805 WLog_Print(log, WLOG_TRACE,
"\tpad4OctetsB: 0x%08" PRIX32
"", pad4OctetsB);
806 WLog_Print(log, WLOG_TRACE,
"\tdesktopSaveSize: 0x%08" PRIX32
"", desktopSaveSize);
807 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsC: 0x%04" PRIX16
"", pad2OctetsC);
808 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsD: 0x%04" PRIX16
"", pad2OctetsD);
809 WLog_Print(log, WLOG_TRACE,
"\ttextANSICodePage: 0x%04" PRIX16
"", textANSICodePage);
810 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsE: 0x%04" PRIX16
"", pad2OctetsE);
815static BOOL rdp_apply_bitmap_cache_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
816 WINPR_ATTR_UNUSED
const rdpSettings* src)
818 WINPR_ASSERT(settings);
828static BOOL rdp_read_bitmap_cache_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
830 WINPR_UNUSED(settings);
831 WINPR_ASSERT(settings);
833 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
836 Stream_Seek_UINT32(s);
837 Stream_Seek_UINT32(s);
838 Stream_Seek_UINT32(s);
839 Stream_Seek_UINT32(s);
840 Stream_Seek_UINT32(s);
841 Stream_Seek_UINT32(s);
842 Stream_Seek_UINT16(s);
843 Stream_Seek_UINT16(s);
844 Stream_Seek_UINT16(s);
845 Stream_Seek_UINT16(s);
846 Stream_Seek_UINT16(s);
847 Stream_Seek_UINT16(s);
856static BOOL rdp_write_bitmap_cache_capability_set(wLog* log,
wStream* s,
857 const rdpSettings* settings)
859 if (!Stream_EnsureRemainingCapacity(s, 64))
862 const size_t header = rdp_capability_set_start(log, s);
864 if (bpp > UINT16_MAX)
866 Stream_Write_UINT32(s, 0);
867 Stream_Write_UINT32(s, 0);
868 Stream_Write_UINT32(s, 0);
869 Stream_Write_UINT32(s, 0);
870 Stream_Write_UINT32(s, 0);
871 Stream_Write_UINT32(s, 0);
872 UINT32 size = bpp * 256;
873 if (size > UINT16_MAX)
875 Stream_Write_UINT16(s, 200);
876 Stream_Write_UINT16(s, (UINT16)size);
878 if (size > UINT16_MAX)
880 Stream_Write_UINT16(s, 600);
881 Stream_Write_UINT16(s, (UINT16)size);
883 if (size > UINT16_MAX)
885 Stream_Write_UINT16(s, 1000);
886 Stream_Write_UINT16(s, (UINT16)size);
887 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE);
890#ifdef WITH_DEBUG_CAPABILITIES
891static BOOL rdp_print_bitmap_cache_capability_set(wLog* log,
wStream* s)
899 UINT16 Cache0Entries = 0;
900 UINT16 Cache0MaximumCellSize = 0;
901 UINT16 Cache1Entries = 0;
902 UINT16 Cache1MaximumCellSize = 0;
903 UINT16 Cache2Entries = 0;
904 UINT16 Cache2MaximumCellSize = 0;
905 WLog_Print(log, WLOG_TRACE,
906 "BitmapCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
908 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
911 Stream_Read_UINT32(s, pad1);
912 Stream_Read_UINT32(s, pad2);
913 Stream_Read_UINT32(s, pad3);
914 Stream_Read_UINT32(s, pad4);
915 Stream_Read_UINT32(s, pad5);
916 Stream_Read_UINT32(s, pad6);
917 Stream_Read_UINT16(s, Cache0Entries);
918 Stream_Read_UINT16(s, Cache0MaximumCellSize);
919 Stream_Read_UINT16(s, Cache1Entries);
920 Stream_Read_UINT16(s, Cache1MaximumCellSize);
921 Stream_Read_UINT16(s, Cache2Entries);
922 Stream_Read_UINT16(s, Cache2MaximumCellSize);
923 WLog_Print(log, WLOG_TRACE,
"\tpad1: 0x%08" PRIX32
"", pad1);
924 WLog_Print(log, WLOG_TRACE,
"\tpad2: 0x%08" PRIX32
"", pad2);
925 WLog_Print(log, WLOG_TRACE,
"\tpad3: 0x%08" PRIX32
"", pad3);
926 WLog_Print(log, WLOG_TRACE,
"\tpad4: 0x%08" PRIX32
"", pad4);
927 WLog_Print(log, WLOG_TRACE,
"\tpad5: 0x%08" PRIX32
"", pad5);
928 WLog_Print(log, WLOG_TRACE,
"\tpad6: 0x%08" PRIX32
"", pad6);
929 WLog_Print(log, WLOG_TRACE,
"\tCache0Entries: 0x%04" PRIX16
"", Cache0Entries);
930 WLog_Print(log, WLOG_TRACE,
"\tCache0MaximumCellSize: 0x%04" PRIX16
"", Cache0MaximumCellSize);
931 WLog_Print(log, WLOG_TRACE,
"\tCache1Entries: 0x%04" PRIX16
"", Cache1Entries);
932 WLog_Print(log, WLOG_TRACE,
"\tCache1MaximumCellSize: 0x%04" PRIX16
"", Cache1MaximumCellSize);
933 WLog_Print(log, WLOG_TRACE,
"\tCache2Entries: 0x%04" PRIX16
"", Cache2Entries);
934 WLog_Print(log, WLOG_TRACE,
"\tCache2MaximumCellSize: 0x%04" PRIX16
"", Cache2MaximumCellSize);
939static BOOL rdp_apply_control_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
940 WINPR_ATTR_UNUSED
const rdpSettings* src)
942 WINPR_ASSERT(settings);
953static BOOL rdp_read_control_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
955 WINPR_UNUSED(settings);
956 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
959 Stream_Seek_UINT16(s);
960 Stream_Seek_UINT16(s);
961 Stream_Seek_UINT16(s);
962 Stream_Seek_UINT16(s);
971static BOOL rdp_write_control_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
973 WINPR_UNUSED(settings);
974 if (!Stream_EnsureRemainingCapacity(s, 32))
977 const size_t header = rdp_capability_set_start(log, s);
978 Stream_Write_UINT16(s, 0);
979 Stream_Write_UINT16(s, 0);
980 Stream_Write_UINT16(s, 2);
981 Stream_Write_UINT16(s, 2);
982 return rdp_capability_set_finish(s, header, CAPSET_TYPE_CONTROL);
985#ifdef WITH_DEBUG_CAPABILITIES
986static BOOL rdp_print_control_capability_set(wLog* log,
wStream* s)
988 UINT16 controlFlags = 0;
989 UINT16 remoteDetachFlag = 0;
990 UINT16 controlInterest = 0;
991 UINT16 detachInterest = 0;
992 WLog_Print(log, WLOG_TRACE,
993 "ControlCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
995 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
998 Stream_Read_UINT16(s, controlFlags);
999 Stream_Read_UINT16(s, remoteDetachFlag);
1000 Stream_Read_UINT16(s, controlInterest);
1001 Stream_Read_UINT16(s, detachInterest);
1002 WLog_Print(log, WLOG_TRACE,
"\tcontrolFlags: 0x%04" PRIX16
"", controlFlags);
1003 WLog_Print(log, WLOG_TRACE,
"\tremoteDetachFlag: 0x%04" PRIX16
"", remoteDetachFlag);
1004 WLog_Print(log, WLOG_TRACE,
"\tcontrolInterest: 0x%04" PRIX16
"", controlInterest);
1005 WLog_Print(log, WLOG_TRACE,
"\tdetachInterest: 0x%04" PRIX16
"", detachInterest);
1010static BOOL rdp_apply_window_activation_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
1011 WINPR_ATTR_UNUSED
const rdpSettings* src)
1013 WINPR_ASSERT(settings);
1024static BOOL rdp_read_window_activation_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1026 WINPR_UNUSED(settings);
1027 WINPR_ASSERT(settings);
1028 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1031 Stream_Seek_UINT16(s);
1032 Stream_Seek_UINT16(s);
1033 Stream_Seek_UINT16(s);
1034 Stream_Seek_UINT16(s);
1043static BOOL rdp_write_window_activation_capability_set(wLog* log,
wStream* s,
1044 const rdpSettings* settings)
1046 WINPR_UNUSED(settings);
1047 WINPR_ASSERT(settings);
1048 if (!Stream_EnsureRemainingCapacity(s, 32))
1051 const size_t header = rdp_capability_set_start(log, s);
1052 Stream_Write_UINT16(s, 0);
1053 Stream_Write_UINT16(s, 0);
1054 Stream_Write_UINT16(s, 0);
1055 Stream_Write_UINT16(s, 0);
1056 return rdp_capability_set_finish(s, header, CAPSET_TYPE_ACTIVATION);
1059#ifdef WITH_DEBUG_CAPABILITIES
1060static BOOL rdp_print_window_activation_capability_set(wLog* log,
wStream* s)
1062 UINT16 helpKeyFlag = 0;
1063 UINT16 helpKeyIndexFlag = 0;
1064 UINT16 helpExtendedKeyFlag = 0;
1065 UINT16 windowManagerKeyFlag = 0;
1066 WLog_Print(log, WLOG_TRACE,
1067 "WindowActivationCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1069 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1072 Stream_Read_UINT16(s, helpKeyFlag);
1073 Stream_Read_UINT16(s, helpKeyIndexFlag);
1074 Stream_Read_UINT16(s, helpExtendedKeyFlag);
1075 Stream_Read_UINT16(s, windowManagerKeyFlag);
1076 WLog_Print(log, WLOG_TRACE,
"\thelpKeyFlag: 0x%04" PRIX16
"", helpKeyFlag);
1077 WLog_Print(log, WLOG_TRACE,
"\thelpKeyIndexFlag: 0x%04" PRIX16
"", helpKeyIndexFlag);
1078 WLog_Print(log, WLOG_TRACE,
"\thelpExtendedKeyFlag: 0x%04" PRIX16
"", helpExtendedKeyFlag);
1079 WLog_Print(log, WLOG_TRACE,
"\twindowManagerKeyFlag: 0x%04" PRIX16
"", windowManagerKeyFlag);
1084static BOOL rdp_apply_pointer_capability_set(rdpSettings* settings,
const rdpSettings* src)
1086 WINPR_ASSERT(settings);
1090 const UINT32 colorPointerCacheSize =
1092 const UINT32 dstPointerCacheSize =
1094 const UINT32 dstColorPointerCacheSize =
1098 const UINT32 actualPointerCacheSize = MIN(pointerCacheSize, dstPointerCacheSize);
1099 const UINT32 actualColorPointerCacheSize = MIN(colorPointerCacheSize, dstColorPointerCacheSize);
1104 actualColorPointerCacheSize));
1112static BOOL rdp_read_pointer_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1114 UINT16 colorPointerFlag = 0;
1115 UINT16 colorPointerCacheSize = 0;
1116 UINT16 pointerCacheSize = 0;
1118 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1121 Stream_Read_UINT16(s, colorPointerFlag);
1122 Stream_Read_UINT16(s, colorPointerCacheSize);
1124 if (colorPointerFlag == 0)
1126 WLog_Print(log, WLOG_WARN,
1127 "[MS-RDPBCGR] 2.2.7.1.5 Pointer Capability Set "
1128 "(TS_POINTER_CAPABILITYSET)::colorPointerFlag received is %" PRIu16
1129 ". Value is ignored and always assumed to be TRUE",
1134 if (Stream_GetRemainingLength(s) >= 2)
1135 Stream_Read_UINT16(s, pointerCacheSize);
1137 WINPR_ASSERT(settings);
1138 settings->PointerCacheSize = pointerCacheSize;
1139 settings->ColorPointerCacheSize = colorPointerCacheSize;
1149static BOOL rdp_write_pointer_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1151 if (!Stream_EnsureRemainingCapacity(s, 32))
1154 const size_t header = rdp_capability_set_start(log, s);
1155 if (settings->PointerCacheSize > UINT16_MAX)
1157 if (settings->ColorPointerCacheSize > UINT16_MAX)
1160 WINPR_ASSERT(settings);
1161 const UINT32 colorPointerFlag =
1164 Stream_Write_UINT16(s, colorPointerFlag);
1165 Stream_Write_UINT16(
1166 s, (UINT16)settings->ColorPointerCacheSize);
1167 Stream_Write_UINT16(s, (UINT16)settings->PointerCacheSize);
1169 return rdp_capability_set_finish(s, header, CAPSET_TYPE_POINTER);
1172#ifdef WITH_DEBUG_CAPABILITIES
1173static BOOL rdp_print_pointer_capability_set(wLog* log,
wStream* s)
1175 UINT16 colorPointerFlag = 0;
1176 UINT16 colorPointerCacheSize = 0;
1177 UINT16 pointerCacheSize = 0;
1179 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 6))
1182 WLog_Print(log, WLOG_TRACE,
1183 "PointerCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1184 Stream_Read_UINT16(s, colorPointerFlag);
1185 Stream_Read_UINT16(s, colorPointerCacheSize);
1186 Stream_Read_UINT16(s, pointerCacheSize);
1187 WLog_Print(log, WLOG_TRACE,
"\tcolorPointerFlag: 0x%04" PRIX16
"", colorPointerFlag);
1188 WLog_Print(log, WLOG_TRACE,
"\tcolorPointerCacheSize: 0x%04" PRIX16
"", colorPointerCacheSize);
1189 WLog_Print(log, WLOG_TRACE,
"\tpointerCacheSize: 0x%04" PRIX16
"", pointerCacheSize);
1194static BOOL rdp_apply_share_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
1195 WINPR_ATTR_UNUSED
const rdpSettings* src)
1197 WINPR_ASSERT(settings);
1208static BOOL rdp_read_share_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1210 WINPR_UNUSED(settings);
1211 WINPR_ASSERT(settings);
1213 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1216 Stream_Seek_UINT16(s);
1217 Stream_Seek_UINT16(s);
1226static BOOL rdp_write_share_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1228 if (!Stream_EnsureRemainingCapacity(s, 32))
1231 const size_t header = rdp_capability_set_start(log, s);
1233 WINPR_ASSERT(settings);
1234 const UINT16 nodeId = (settings->ServerMode) ? 0x03EA : 0;
1235 Stream_Write_UINT16(s, nodeId);
1236 Stream_Write_UINT16(s, 0);
1237 return rdp_capability_set_finish(s, header, CAPSET_TYPE_SHARE);
1240#ifdef WITH_DEBUG_CAPABILITIES
1241static BOOL rdp_print_share_capability_set(wLog* log,
wStream* s)
1244 UINT16 pad2Octets = 0;
1245 WLog_Print(log, WLOG_TRACE,
1246 "ShareCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1248 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1251 Stream_Read_UINT16(s, nodeId);
1252 Stream_Read_UINT16(s, pad2Octets);
1253 WLog_Print(log, WLOG_TRACE,
"\tnodeId: 0x%04" PRIX16
"", nodeId);
1254 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1259static BOOL rdp_apply_color_cache_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
1260 WINPR_ATTR_UNUSED
const rdpSettings* src)
1262 WINPR_ASSERT(settings);
1272static BOOL rdp_read_color_cache_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1274 WINPR_UNUSED(settings);
1275 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1278 Stream_Seek_UINT16(s);
1279 Stream_Seek_UINT16(s);
1288static BOOL rdp_write_color_cache_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1290 WINPR_UNUSED(settings);
1291 if (!Stream_EnsureRemainingCapacity(s, 32))
1294 const size_t header = rdp_capability_set_start(log, s);
1295 Stream_Write_UINT16(s, 6);
1296 Stream_Write_UINT16(s, 0);
1297 return rdp_capability_set_finish(s, header, CAPSET_TYPE_COLOR_CACHE);
1300#ifdef WITH_DEBUG_CAPABILITIES
1301static BOOL rdp_print_color_cache_capability_set(wLog* log,
wStream* s)
1303 UINT16 colorTableCacheSize = 0;
1304 UINT16 pad2Octets = 0;
1305 WLog_Print(log, WLOG_TRACE,
1306 "ColorCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1308 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1311 Stream_Read_UINT16(s, colorTableCacheSize);
1312 Stream_Read_UINT16(s, pad2Octets);
1313 WLog_Print(log, WLOG_TRACE,
"\tcolorTableCacheSize: 0x%04" PRIX16
"", colorTableCacheSize);
1314 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1319static BOOL rdp_apply_sound_capability_set(rdpSettings* settings,
const rdpSettings* src)
1321 WINPR_ASSERT(settings);
1324 settings->SoundBeepsEnabled = src->SoundBeepsEnabled;
1334static BOOL rdp_read_sound_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1336 UINT16 soundFlags = 0;
1338 WINPR_ASSERT(settings);
1339 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1342 Stream_Read_UINT16(s, soundFlags);
1343 Stream_Seek_UINT16(s);
1344 settings->SoundBeepsEnabled = (soundFlags & SOUND_BEEPS_FLAG) != 0;
1353static BOOL rdp_write_sound_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1355 WINPR_ASSERT(settings);
1356 if (!Stream_EnsureRemainingCapacity(s, 32))
1359 const size_t header = rdp_capability_set_start(log, s);
1360 const UINT16 soundFlags = (settings->SoundBeepsEnabled) ? SOUND_BEEPS_FLAG : 0;
1361 Stream_Write_UINT16(s, soundFlags);
1362 Stream_Write_UINT16(s, 0);
1363 return rdp_capability_set_finish(s, header, CAPSET_TYPE_SOUND);
1366#ifdef WITH_DEBUG_CAPABILITIES
1367static BOOL rdp_print_sound_capability_set(wLog* log,
wStream* s)
1369 UINT16 soundFlags = 0;
1370 UINT16 pad2OctetsA = 0;
1371 WLog_Print(log, WLOG_TRACE,
1372 "SoundCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1374 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1377 Stream_Read_UINT16(s, soundFlags);
1378 Stream_Read_UINT16(s, pad2OctetsA);
1379 WLog_Print(log, WLOG_TRACE,
"\tsoundFlags: 0x%04" PRIX16
"", soundFlags);
1380 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
1385static BOOL rdp_apply_input_capability_set(rdpSettings* settings,
const rdpSettings* src)
1387 WINPR_ASSERT(settings);
1390 if (settings->ServerMode)
1392 settings->KeyboardLayout = src->KeyboardLayout;
1393 settings->KeyboardType = src->KeyboardType;
1394 settings->KeyboardSubType = src->KeyboardSubType;
1395 settings->KeyboardFunctionKey = src->KeyboardFunctionKey;
1401 if (!settings->ServerMode)
1403 settings->FastPathInput = src->FastPathInput;
1409 if (settings->HasHorizontalWheel)
1410 settings->HasHorizontalWheel = src->HasHorizontalWheel;
1418 if (settings->HasExtendedMouseEvent)
1419 settings->HasExtendedMouseEvent = src->HasExtendedMouseEvent;
1420 if (settings->HasRelativeMouseEvent)
1421 settings->HasRelativeMouseEvent = src->HasRelativeMouseEvent;
1433static BOOL rdp_read_input_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1435 UINT16 inputFlags = 0;
1437 WINPR_ASSERT(settings);
1438 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 84))
1441 Stream_Read_UINT16(s, inputFlags);
1442 Stream_Seek_UINT16(s);
1444 Stream_Read_UINT32(s, settings->KeyboardLayout);
1445 Stream_Read_UINT32(s, settings->KeyboardType);
1446 Stream_Read_UINT32(s, settings->KeyboardSubType);
1447 Stream_Read_UINT32(s, settings->KeyboardFunctionKey);
1450 WCHAR wstr[32] = WINPR_C_ARRAY_INIT;
1451 char str[65] = WINPR_C_ARRAY_INIT;
1457 if (!Stream_Read_UTF16_String(s, wstr, ARRAYSIZE(wstr)))
1460 if (ConvertWCharNToUtf8(wstr, ARRAYSIZE(wstr), str, ARRAYSIZE(str)) < 0)
1461 memset(str, 0,
sizeof(str));
1469 (INPUT_FLAG_FASTPATH_INPUT | INPUT_FLAG_FASTPATH_INPUT2)))
1472 (inputFlags & TS_INPUT_FLAG_MOUSE_HWHEEL) != 0))
1475 (inputFlags & INPUT_FLAG_UNICODE) != 0))
1478 (inputFlags & INPUT_FLAG_MOUSE_RELATIVE) != 0))
1481 (inputFlags & INPUT_FLAG_MOUSEX) != 0))
1484 (inputFlags & TS_INPUT_FLAG_QOE_TIMESTAMPS) != 0))
1495static BOOL rdp_write_input_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1497 WINPR_ASSERT(settings);
1498 if (!Stream_EnsureRemainingCapacity(s, 128))
1501 const size_t header = rdp_capability_set_start(log, s);
1502 UINT16 inputFlags = INPUT_FLAG_SCANCODES;
1504 if (settings->FastPathInput)
1506 inputFlags |= INPUT_FLAG_FASTPATH_INPUT;
1507 inputFlags |= INPUT_FLAG_FASTPATH_INPUT2;
1511 inputFlags |= INPUT_FLAG_MOUSE_RELATIVE;
1514 inputFlags |= TS_INPUT_FLAG_MOUSE_HWHEEL;
1517 inputFlags |= INPUT_FLAG_UNICODE;
1520 inputFlags |= TS_INPUT_FLAG_QOE_TIMESTAMPS;
1522 if (settings->HasExtendedMouseEvent)
1523 inputFlags |= INPUT_FLAG_MOUSEX;
1525 Stream_Write_UINT16(s, inputFlags);
1526 Stream_Write_UINT16(s, 0);
1527 Stream_Write_UINT32(s, settings->KeyboardLayout);
1528 Stream_Write_UINT32(s, settings->KeyboardType);
1529 Stream_Write_UINT32(s, settings->KeyboardSubType);
1530 Stream_Write_UINT32(s, settings->KeyboardFunctionKey);
1532 return rdp_capability_set_finish(s, header, CAPSET_TYPE_INPUT);
1535#ifdef WITH_DEBUG_CAPABILITIES
1536static BOOL rdp_print_input_capability_set(wLog* log,
wStream* s)
1538 UINT16 inputFlags = 0;
1539 UINT16 pad2OctetsA = 0;
1540 UINT32 keyboardLayout = 0;
1541 UINT32 keyboardType = 0;
1542 UINT32 keyboardSubType = 0;
1543 UINT32 keyboardFunctionKey = 0;
1544 WLog_Print(log, WLOG_TRACE,
"InputCapabilitySet (length %" PRIuz
")",
1545 Stream_GetRemainingLength(s));
1547 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 84))
1550 Stream_Read_UINT16(s, inputFlags);
1551 Stream_Read_UINT16(s, pad2OctetsA);
1552 Stream_Read_UINT32(s, keyboardLayout);
1553 Stream_Read_UINT32(s, keyboardType);
1554 Stream_Read_UINT32(s, keyboardSubType);
1555 Stream_Read_UINT32(s, keyboardFunctionKey);
1557 WLog_Print(log, WLOG_TRACE,
"\tinputFlags: 0x%04" PRIX16
"", inputFlags);
1558 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
1559 WLog_Print(log, WLOG_TRACE,
"\tkeyboardLayout: 0x%08" PRIX32
"", keyboardLayout);
1560 WLog_Print(log, WLOG_TRACE,
"\tkeyboardType: 0x%08" PRIX32
"", keyboardType);
1561 WLog_Print(log, WLOG_TRACE,
"\tkeyboardSubType: 0x%08" PRIX32
"", keyboardSubType);
1562 WLog_Print(log, WLOG_TRACE,
"\tkeyboardFunctionKey: 0x%08" PRIX32
"", keyboardFunctionKey);
1567static BOOL rdp_apply_font_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
1568 WINPR_ATTR_UNUSED
const rdpSettings* src)
1570 WINPR_ASSERT(settings);
1580static BOOL rdp_read_font_capability_set(WINPR_ATTR_UNUSED wLog* log,
wStream* s,
1581 rdpSettings* settings)
1583 WINPR_UNUSED(settings);
1584 if (Stream_GetRemainingLength(s) >= 2)
1585 Stream_Seek_UINT16(s);
1587 if (Stream_GetRemainingLength(s) >= 2)
1588 Stream_Seek_UINT16(s);
1598static BOOL rdp_write_font_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1600 WINPR_UNUSED(settings);
1601 if (!Stream_EnsureRemainingCapacity(s, 32))
1604 const size_t header = rdp_capability_set_start(log, s);
1605 Stream_Write_UINT16(s, FONTSUPPORT_FONTLIST);
1606 Stream_Write_UINT16(s, 0);
1607 return rdp_capability_set_finish(s, header, CAPSET_TYPE_FONT);
1610#ifdef WITH_DEBUG_CAPABILITIES
1611static BOOL rdp_print_font_capability_set(wLog* log,
wStream* s)
1613 UINT16 fontSupportFlags = 0;
1614 UINT16 pad2Octets = 0;
1615 WLog_Print(log, WLOG_TRACE,
1616 "FontCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1618 if (Stream_GetRemainingLength(s) >= 2)
1619 Stream_Read_UINT16(s, fontSupportFlags);
1621 if (Stream_GetRemainingLength(s) >= 2)
1622 Stream_Read_UINT16(s, pad2Octets);
1624 WLog_Print(log, WLOG_TRACE,
"\tfontSupportFlags: 0x%04" PRIX16
"", fontSupportFlags);
1625 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1630static BOOL rdp_apply_brush_capability_set(rdpSettings* settings,
const rdpSettings* src)
1632 WINPR_ASSERT(settings);
1636 settings->BrushSupportLevel = src->BrushSupportLevel;
1645static BOOL rdp_read_brush_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1647 WINPR_UNUSED(settings);
1648 WINPR_ASSERT(settings);
1650 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1652 Stream_Read_UINT32(s, settings->BrushSupportLevel);
1661static BOOL rdp_write_brush_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1663 WINPR_ASSERT(settings);
1664 if (!Stream_EnsureRemainingCapacity(s, 32))
1667 const size_t header = rdp_capability_set_start(log, s);
1668 Stream_Write_UINT32(s, settings->BrushSupportLevel);
1669 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BRUSH);
1672#ifdef WITH_DEBUG_CAPABILITIES
1673static BOOL rdp_print_brush_capability_set(wLog* log,
wStream* s)
1675 UINT32 brushSupportLevel = 0;
1676 WLog_Print(log, WLOG_TRACE,
1677 "BrushCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1679 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1682 Stream_Read_UINT32(s, brushSupportLevel);
1683 WLog_Print(log, WLOG_TRACE,
"\tbrushSupportLevel: 0x%08" PRIX32
"", brushSupportLevel);
1694 WINPR_ASSERT(cache_definition);
1695 Stream_Read_UINT16(s, cache_definition->cacheEntries);
1696 Stream_Read_UINT16(s,
1697 cache_definition->cacheMaximumCellSize);
1706 WINPR_ASSERT(cache_definition);
1707 Stream_Write_UINT16(s, cache_definition->cacheEntries);
1708 Stream_Write_UINT16(
1709 s, cache_definition->cacheMaximumCellSize);
1712static BOOL rdp_apply_glyph_cache_capability_set(rdpSettings* settings,
const rdpSettings* src)
1714 WINPR_ASSERT(settings);
1717 WINPR_ASSERT(src->GlyphCache);
1718 WINPR_ASSERT(settings->GlyphCache);
1719 for (
size_t x = 0; x < 10; x++)
1720 settings->GlyphCache[x] = src->GlyphCache[x];
1722 WINPR_ASSERT(src->FragCache);
1723 WINPR_ASSERT(settings->FragCache);
1724 settings->FragCache[0] = src->FragCache[0];
1725 settings->GlyphSupportLevel = src->GlyphSupportLevel;
1735static BOOL rdp_read_glyph_cache_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1737 WINPR_ASSERT(settings);
1738 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 48))
1742 for (
size_t x = 0; x < 10; x++)
1743 rdp_read_cache_definition(s, &(settings->GlyphCache[x]));
1744 rdp_read_cache_definition(s, settings->FragCache);
1745 Stream_Read_UINT16(s, settings->GlyphSupportLevel);
1746 Stream_Seek_UINT16(s);
1755static BOOL rdp_write_glyph_cache_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1757 WINPR_ASSERT(settings);
1758 if (!Stream_EnsureRemainingCapacity(s, 64))
1761 const size_t header = rdp_capability_set_start(log, s);
1762 if (settings->GlyphSupportLevel > UINT16_MAX)
1765 for (
size_t x = 0; x < 10; x++)
1766 rdp_write_cache_definition(s, &(settings->GlyphCache[x]));
1767 rdp_write_cache_definition(s, settings->FragCache);
1768 Stream_Write_UINT16(s, (UINT16)settings->GlyphSupportLevel);
1769 Stream_Write_UINT16(s, 0);
1770 return rdp_capability_set_finish(s, header, CAPSET_TYPE_GLYPH_CACHE);
1773#ifdef WITH_DEBUG_CAPABILITIES
1774static BOOL rdp_print_glyph_cache_capability_set(wLog* log,
wStream* s)
1778 UINT16 glyphSupportLevel = 0;
1779 UINT16 pad2Octets = 0;
1780 WLog_Print(log, WLOG_TRACE,
1781 "GlyphCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1783 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 48))
1787 rdp_read_cache_definition(s, &glyphCache[0]);
1788 rdp_read_cache_definition(s, &glyphCache[1]);
1789 rdp_read_cache_definition(s, &glyphCache[2]);
1790 rdp_read_cache_definition(s, &glyphCache[3]);
1791 rdp_read_cache_definition(s, &glyphCache[4]);
1792 rdp_read_cache_definition(s, &glyphCache[5]);
1793 rdp_read_cache_definition(s, &glyphCache[6]);
1794 rdp_read_cache_definition(s, &glyphCache[7]);
1795 rdp_read_cache_definition(s, &glyphCache[8]);
1796 rdp_read_cache_definition(s, &glyphCache[9]);
1797 rdp_read_cache_definition(s, &fragCache);
1798 Stream_Read_UINT16(s, glyphSupportLevel);
1799 Stream_Read_UINT16(s, pad2Octets);
1800 WLog_Print(log, WLOG_TRACE,
"\tglyphCache0: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1801 glyphCache[0].cacheEntries, glyphCache[0].cacheMaximumCellSize);
1802 WLog_Print(log, WLOG_TRACE,
"\tglyphCache1: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1803 glyphCache[1].cacheEntries, glyphCache[1].cacheMaximumCellSize);
1804 WLog_Print(log, WLOG_TRACE,
"\tglyphCache2: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1805 glyphCache[2].cacheEntries, glyphCache[2].cacheMaximumCellSize);
1806 WLog_Print(log, WLOG_TRACE,
"\tglyphCache3: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1807 glyphCache[3].cacheEntries, glyphCache[3].cacheMaximumCellSize);
1808 WLog_Print(log, WLOG_TRACE,
"\tglyphCache4: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1809 glyphCache[4].cacheEntries, glyphCache[4].cacheMaximumCellSize);
1810 WLog_Print(log, WLOG_TRACE,
"\tglyphCache5: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1811 glyphCache[5].cacheEntries, glyphCache[5].cacheMaximumCellSize);
1812 WLog_Print(log, WLOG_TRACE,
"\tglyphCache6: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1813 glyphCache[6].cacheEntries, glyphCache[6].cacheMaximumCellSize);
1814 WLog_Print(log, WLOG_TRACE,
"\tglyphCache7: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1815 glyphCache[7].cacheEntries, glyphCache[7].cacheMaximumCellSize);
1816 WLog_Print(log, WLOG_TRACE,
"\tglyphCache8: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1817 glyphCache[8].cacheEntries, glyphCache[8].cacheMaximumCellSize);
1818 WLog_Print(log, WLOG_TRACE,
"\tglyphCache9: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1819 glyphCache[9].cacheEntries, glyphCache[9].cacheMaximumCellSize);
1820 WLog_Print(log, WLOG_TRACE,
"\tfragCache: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1821 fragCache.cacheEntries, fragCache.cacheMaximumCellSize);
1822 WLog_Print(log, WLOG_TRACE,
"\tglyphSupportLevel: 0x%04" PRIX16
"", glyphSupportLevel);
1823 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1828static BOOL rdp_apply_offscreen_bitmap_cache_capability_set(rdpSettings* settings,
1829 const rdpSettings* src)
1831 WINPR_ASSERT(settings);
1834 settings->OffscreenCacheSize = src->OffscreenCacheSize;
1835 settings->OffscreenCacheEntries = src->OffscreenCacheEntries;
1836 settings->OffscreenSupportLevel = src->OffscreenSupportLevel;
1846static BOOL rdp_read_offscreen_bitmap_cache_capability_set(wLog* log,
wStream* s,
1847 rdpSettings* settings)
1849 UINT32 offscreenSupportLevel = 0;
1851 WINPR_ASSERT(settings);
1852 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1855 Stream_Read_UINT32(s, offscreenSupportLevel);
1856 Stream_Read_UINT16(s, settings->OffscreenCacheSize);
1857 Stream_Read_UINT16(s, settings->OffscreenCacheEntries);
1859 settings->OffscreenSupportLevel = offscreenSupportLevel & 0x01;
1869static BOOL rdp_write_offscreen_bitmap_cache_capability_set(wLog* log,
wStream* s,
1870 const rdpSettings* settings)
1872 UINT32 offscreenSupportLevel = 0x00;
1874 WINPR_ASSERT(settings);
1875 if (!Stream_EnsureRemainingCapacity(s, 32))
1878 const size_t header = rdp_capability_set_start(log, s);
1879 if (settings->OffscreenSupportLevel)
1881 offscreenSupportLevel = 0x01;
1882 Stream_Write_UINT32(s, offscreenSupportLevel);
1883 Stream_Write_UINT16(
1884 s, WINPR_ASSERTING_INT_CAST(
1885 uint16_t, settings->OffscreenCacheSize));
1886 Stream_Write_UINT16(
1888 WINPR_ASSERTING_INT_CAST(
1889 uint16_t, settings->OffscreenCacheEntries));
1894 return rdp_capability_set_finish(s, header, CAPSET_TYPE_OFFSCREEN_CACHE);
1897#ifdef WITH_DEBUG_CAPABILITIES
1898static BOOL rdp_print_offscreen_bitmap_cache_capability_set(wLog* log,
wStream* s)
1900 UINT32 offscreenSupportLevel = 0;
1901 UINT16 offscreenCacheSize = 0;
1902 UINT16 offscreenCacheEntries = 0;
1903 WLog_Print(log, WLOG_TRACE,
"OffscreenBitmapCacheCapabilitySet (length %" PRIuz
"):",
1904 Stream_GetRemainingLength(s));
1906 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1909 Stream_Read_UINT32(s, offscreenSupportLevel);
1910 Stream_Read_UINT16(s, offscreenCacheSize);
1911 Stream_Read_UINT16(s, offscreenCacheEntries);
1912 WLog_Print(log, WLOG_TRACE,
"\toffscreenSupportLevel: 0x%08" PRIX32
"", offscreenSupportLevel);
1913 WLog_Print(log, WLOG_TRACE,
"\toffscreenCacheSize: 0x%04" PRIX16
"", offscreenCacheSize);
1914 WLog_Print(log, WLOG_TRACE,
"\toffscreenCacheEntries: 0x%04" PRIX16
"", offscreenCacheEntries);
1919static BOOL rdp_apply_bitmap_cache_host_support_capability_set(rdpSettings* settings,
1920 const rdpSettings* src)
1932static BOOL rdp_read_bitmap_cache_host_support_capability_set(wLog* log,
wStream* s,
1933 rdpSettings* settings)
1935 BYTE cacheVersion = 0;
1937 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1940 Stream_Read_UINT8(s, cacheVersion);
1941 Stream_Seek_UINT8(s);
1942 Stream_Seek_UINT16(s);
1945 cacheVersion & BITMAP_CACHE_V2);
1953static BOOL rdp_write_bitmap_cache_host_support_capability_set(wLog* log,
wStream* s,
1954 const rdpSettings* settings)
1956 UINT8 cacheVersion = 0;
1959 cacheVersion |= BITMAP_CACHE_V2;
1961 if (!Stream_EnsureRemainingCapacity(s, 32))
1964 const size_t header = rdp_capability_set_start(log, s);
1965 Stream_Write_UINT8(s, cacheVersion);
1966 Stream_Write_UINT8(s, 0);
1967 Stream_Write_UINT16(s, 0);
1968 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT);
1971#ifdef WITH_DEBUG_CAPABILITIES
1972static BOOL rdp_print_bitmap_cache_host_support_capability_set(wLog* log,
wStream* s)
1974 BYTE cacheVersion = 0;
1977 WLog_Print(log, WLOG_TRACE,
"BitmapCacheHostSupportCapabilitySet (length %" PRIuz
"):",
1978 Stream_GetRemainingLength(s));
1980 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1983 Stream_Read_UINT8(s, cacheVersion);
1984 Stream_Read_UINT8(s, pad1);
1985 Stream_Read_UINT16(s, pad2);
1986 WLog_Print(log, WLOG_TRACE,
"\tcacheVersion: 0x%02" PRIX8
"", cacheVersion);
1987 WLog_Print(log, WLOG_TRACE,
"\tpad1: 0x%02" PRIX8
"", pad1);
1988 WLog_Print(log, WLOG_TRACE,
"\tpad2: 0x%04" PRIX16
"", pad2);
1993static BOOL rdp_read_bitmap_cache_cell_info(wLog* log,
wStream* s,
1998 WINPR_ASSERT(cellInfo);
1999 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2006 Stream_Read_UINT32(s, info);
2007 cellInfo->numEntries = (info & 0x7FFFFFFF);
2008 cellInfo->persistent = (info & 0x80000000) ? 1 : 0;
2019 WINPR_ASSERT(cellInfo);
2020 info = (cellInfo->numEntries | (((UINT32)cellInfo->persistent << 31) & 0xFF000000));
2021 Stream_Write_UINT32(s, info);
2024static BOOL rdp_apply_bitmap_cache_v2_capability_set(rdpSettings* settings,
const rdpSettings* src)
2026 const FreeRDP_Settings_Keys_Bool keys[] = { FreeRDP_BitmapCacheEnabled,
2027 FreeRDP_BitmapCachePersistEnabled };
2029 for (
size_t x = 0; x < ARRAYSIZE(keys); x++)
2031 const FreeRDP_Settings_Keys_Bool
id = keys[x];
2038 const UINT32 BitmapCacheV2NumCells =
2041 BitmapCacheV2NumCells))
2044 for (
size_t x = 0; x < BitmapCacheV2NumCells; x++)
2047 freerdp_settings_get_pointer_array(src, FreeRDP_BitmapCacheV2CellInfo, x);
2048 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_BitmapCacheV2CellInfo, x,
2062static BOOL rdp_read_bitmap_cache_v2_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2064 UINT16 cacheFlags = 0;
2065 WINPR_UNUSED(settings);
2066 WINPR_ASSERT(settings);
2068 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
2071 Stream_Read_UINT16(s, cacheFlags);
2076 cacheFlags & PERSISTENT_KEYS_EXPECTED_FLAG))
2079 Stream_Seek_UINT8(s);
2080 Stream_Read_UINT8(s, settings->BitmapCacheV2NumCells);
2081 if (settings->BitmapCacheV2NumCells > 5)
2083 WLog_Print(log, WLOG_ERROR,
2084 "Invalid TS_BITMAPCACHE_CAPABILITYSET_REV2::numCellCaches %" PRIu32
" > 5",
2085 settings->BitmapCacheV2NumCells);
2089 for (
size_t x = 0; x < settings->BitmapCacheV2NumCells; x++)
2092 freerdp_settings_get_pointer_array_writable(settings, FreeRDP_BitmapCacheV2CellInfo, x);
2093 if (!rdp_read_bitmap_cache_cell_info(log, s, info))
2098 for (
size_t x = settings->BitmapCacheV2NumCells; x < 5; x++)
2100 if (!Stream_SafeSeek(s, 4))
2112static BOOL rdp_write_bitmap_cache_v2_capability_set(wLog* log,
wStream* s,
2113 const rdpSettings* settings)
2115 WINPR_ASSERT(settings);
2116 if (!Stream_EnsureRemainingCapacity(s, 64))
2119 const size_t header = rdp_capability_set_start(log, s);
2120 UINT16 cacheFlags = ALLOW_CACHE_WAITING_LIST_FLAG;
2124 cacheFlags |= PERSISTENT_KEYS_EXPECTED_FLAG;
2125 settings->BitmapCacheV2CellInfo[0].persistent = 1;
2126 settings->BitmapCacheV2CellInfo[1].persistent = 1;
2127 settings->BitmapCacheV2CellInfo[2].persistent = 1;
2128 settings->BitmapCacheV2CellInfo[3].persistent = 1;
2129 settings->BitmapCacheV2CellInfo[4].persistent = 1;
2132 Stream_Write_UINT16(s, cacheFlags);
2133 Stream_Write_UINT8(s, 0);
2135 s, WINPR_ASSERTING_INT_CAST(uint8_t,
2136 settings->BitmapCacheV2NumCells));
2137 rdp_write_bitmap_cache_cell_info(
2138 s, &settings->BitmapCacheV2CellInfo[0]);
2139 rdp_write_bitmap_cache_cell_info(
2140 s, &settings->BitmapCacheV2CellInfo[1]);
2141 rdp_write_bitmap_cache_cell_info(
2142 s, &settings->BitmapCacheV2CellInfo[2]);
2143 rdp_write_bitmap_cache_cell_info(
2144 s, &settings->BitmapCacheV2CellInfo[3]);
2145 rdp_write_bitmap_cache_cell_info(
2146 s, &settings->BitmapCacheV2CellInfo[4]);
2148 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_V2);
2151#ifdef WITH_DEBUG_CAPABILITIES
2152static BOOL rdp_print_bitmap_cache_v2_capability_set(wLog* log,
wStream* s)
2155 WLog_Print(log, WLOG_TRACE,
2156 "BitmapCacheV2CapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2158 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
2161 const UINT16 cacheFlags = Stream_Get_UINT16(s);
2162 const UINT8 pad2 = Stream_Get_UINT8(s);
2163 const UINT8 numCellCaches = Stream_Get_UINT8(s);
2165 for (
size_t x = 0; x < ARRAYSIZE(bitmapCacheV2CellInfo); x++)
2167 if (!rdp_read_bitmap_cache_cell_info(
2168 log, s, &bitmapCacheV2CellInfo[x]))
2172 if (!Stream_SafeSeek(s, 12))
2175 WLog_Print(log, WLOG_TRACE,
"\tcacheFlags: 0x%04" PRIX16
"", cacheFlags);
2176 WLog_Print(log, WLOG_TRACE,
"\tpad2: 0x%02" PRIX8
"", pad2);
2177 WLog_Print(log, WLOG_TRACE,
"\tnumCellCaches: 0x%02" PRIX8
"", numCellCaches);
2178 for (
size_t x = 0; x < ARRAYSIZE(bitmapCacheV2CellInfo); x++)
2181 WLog_Print(log, WLOG_TRACE,
2182 "\tbitmapCache%" PRIuz
"CellInfo: numEntries: %" PRIu32
" persistent: %" PRId32
2184 x, info->numEntries, info->persistent);
2190static BOOL rdp_apply_virtual_channel_capability_set(rdpSettings* settings,
const rdpSettings* src)
2192 WINPR_ASSERT(settings);
2196 if (settings->ServerMode && (settings->VCFlags & VCCAPS_COMPR_SC) &&
2197 (src->VCFlags & VCCAPS_COMPR_SC))
2198 settings->VCFlags |= VCCAPS_COMPR_SC;
2200 settings->VCFlags &= (uint32_t)~VCCAPS_COMPR_SC;
2202 if (!settings->ServerMode && (settings->VCFlags & VCCAPS_COMPR_CS_8K) &&
2203 (src->VCFlags & VCCAPS_COMPR_CS_8K))
2204 settings->VCFlags |= VCCAPS_COMPR_CS_8K;
2206 settings->VCFlags &= (uint32_t)~VCCAPS_COMPR_CS_8K;
2213 if (!settings->ServerMode)
2215 if ((src->VCChunkSize > CHANNEL_CHUNK_MAX_LENGTH) || (src->VCChunkSize == 0))
2216 settings->VCChunkSize = CHANNEL_CHUNK_LENGTH;
2219 settings->VCChunkSize = src->VCChunkSize;
2231static BOOL rdp_read_virtual_channel_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2234 UINT32 VCChunkSize = 0;
2236 WINPR_ASSERT(settings);
2237 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2240 Stream_Read_UINT32(s, flags);
2242 if (Stream_GetRemainingLength(s) >= 4)
2243 Stream_Read_UINT32(s, VCChunkSize);
2245 VCChunkSize = UINT32_MAX;
2247 settings->VCFlags = flags;
2248 settings->VCChunkSize = VCChunkSize;
2258static BOOL rdp_write_virtual_channel_capability_set(wLog* log,
wStream* s,
2259 const rdpSettings* settings)
2261 WINPR_ASSERT(settings);
2262 if (!Stream_EnsureRemainingCapacity(s, 32))
2265 const size_t header = rdp_capability_set_start(log, s);
2266 Stream_Write_UINT32(s, settings->VCFlags);
2267 Stream_Write_UINT32(s, settings->VCChunkSize);
2268 return rdp_capability_set_finish(s, header, CAPSET_TYPE_VIRTUAL_CHANNEL);
2271#ifdef WITH_DEBUG_CAPABILITIES
2272static BOOL rdp_print_virtual_channel_capability_set(wLog* log,
wStream* s)
2275 UINT32 VCChunkSize = 0;
2276 WLog_Print(log, WLOG_TRACE,
2277 "VirtualChannelCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2279 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2282 Stream_Read_UINT32(s, flags);
2284 if (Stream_GetRemainingLength(s) >= 4)
2285 Stream_Read_UINT32(s, VCChunkSize);
2289 WLog_Print(log, WLOG_TRACE,
"\tflags: 0x%08" PRIX32
"", flags);
2290 WLog_Print(log, WLOG_TRACE,
"\tVCChunkSize: 0x%08" PRIX32
"", VCChunkSize);
2295static BOOL rdp_apply_draw_nine_grid_cache_capability_set(rdpSettings* settings,
2296 const rdpSettings* src)
2298 WINPR_ASSERT(settings);
2301 settings->DrawNineGridCacheSize = src->DrawNineGridCacheSize;
2302 settings->DrawNineGridCacheEntries = src->DrawNineGridCacheEntries;
2303 settings->DrawNineGridEnabled = src->DrawNineGridEnabled;
2313static BOOL rdp_read_draw_nine_grid_cache_capability_set(wLog* log,
wStream* s,
2314 rdpSettings* settings)
2316 UINT32 drawNineGridSupportLevel = 0;
2318 WINPR_ASSERT(settings);
2319 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
2322 Stream_Read_UINT32(s, drawNineGridSupportLevel);
2323 Stream_Read_UINT16(s, settings->DrawNineGridCacheSize);
2324 Stream_Read_UINT16(s,
2325 settings->DrawNineGridCacheEntries);
2327 settings->DrawNineGridEnabled =
2328 (drawNineGridSupportLevel & (DRAW_NINEGRID_SUPPORTED | DRAW_NINEGRID_SUPPORTED_V2)) != 0;
2338static BOOL rdp_write_draw_nine_grid_cache_capability_set(wLog* log,
wStream* s,
2339 const rdpSettings* settings)
2341 WINPR_ASSERT(settings);
2342 if (!Stream_EnsureRemainingCapacity(s, 32))
2345 const size_t header = rdp_capability_set_start(log, s);
2346 const UINT32 drawNineGridSupportLevel =
2347 (settings->DrawNineGridEnabled) ? DRAW_NINEGRID_SUPPORTED_V2 : DRAW_NINEGRID_NO_SUPPORT;
2348 Stream_Write_UINT32(s, drawNineGridSupportLevel);
2349 Stream_Write_UINT16(
2350 s, WINPR_ASSERTING_INT_CAST(
2351 uint16_t, settings->DrawNineGridCacheSize));
2352 Stream_Write_UINT16(
2354 WINPR_ASSERTING_INT_CAST(
2355 uint16_t, settings->DrawNineGridCacheEntries));
2356 return rdp_capability_set_finish(s, header, CAPSET_TYPE_DRAW_NINE_GRID_CACHE);
2359#ifdef WITH_DEBUG_CAPABILITIES
2360static BOOL rdp_print_draw_nine_grid_cache_capability_set(wLog* log,
wStream* s)
2362 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
2365 const uint32_t drawNineGridSupportLevel =
2366 Stream_Get_UINT32(s);
2367 const uint32_t DrawNineGridCacheSize =
2368 Stream_Get_UINT16(s);
2369 const uint32_t DrawNineGridCacheEntries =
2370 Stream_Get_UINT16(s);
2372 WLog_Print(log, WLOG_TRACE,
2373 "DrawNineGridCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2374 WLog_Print(log, WLOG_TRACE,
"drawNineGridSupportLevel=0x%08" PRIx32, drawNineGridSupportLevel);
2375 WLog_Print(log, WLOG_TRACE,
"DrawNineGridCacheSize=0x%08" PRIx32, DrawNineGridCacheSize);
2376 WLog_Print(log, WLOG_TRACE,
"DrawNineGridCacheEntries=0x%08" PRIx32, DrawNineGridCacheEntries);
2381static BOOL rdp_apply_draw_gdiplus_cache_capability_set(rdpSettings* settings,
2382 const rdpSettings* src)
2384 WINPR_ASSERT(settings);
2387 if (src->DrawGdiPlusEnabled)
2388 settings->DrawGdiPlusEnabled = TRUE;
2390 if (src->DrawGdiPlusCacheEnabled)
2391 settings->DrawGdiPlusCacheEnabled = TRUE;
2401static BOOL rdp_read_draw_gdiplus_cache_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2403 UINT32 drawGDIPlusSupportLevel = 0;
2404 UINT32 drawGdiplusCacheLevel = 0;
2406 WINPR_ASSERT(settings);
2407 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
2410 Stream_Read_UINT32(s, drawGDIPlusSupportLevel);
2411 Stream_Seek_UINT32(s);
2412 Stream_Read_UINT32(s, drawGdiplusCacheLevel);
2417 settings->DrawGdiPlusEnabled = (drawGDIPlusSupportLevel & DRAW_GDIPLUS_SUPPORTED) != 0;
2418 settings->DrawGdiPlusCacheEnabled = (drawGdiplusCacheLevel & DRAW_GDIPLUS_CACHE_LEVEL_ONE) != 0;
2423#ifdef WITH_DEBUG_CAPABILITIES
2424static BOOL rdp_print_draw_gdiplus_cache_capability_set(wLog* log,
wStream* s)
2426 WLog_Print(log, WLOG_TRACE,
2427 "DrawGdiPlusCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2429 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
2432 const uint32_t drawGdiPlusSupportLevel =
2433 Stream_Get_UINT32(s);
2434 const uint32_t GdipVersion = Stream_Get_UINT32(s);
2435 const uint32_t drawGdiplusCacheLevel =
2436 Stream_Get_UINT32(s);
2437 WLog_Print(log, WLOG_TRACE,
2438 "drawGdiPlusSupportLevel=0x%08" PRIx32
", GdipVersion=0x%08" PRIx32
2439 ", drawGdiplusdrawGdiplusCacheLevelCacheLevel=0x%08" PRIx32,
2440 drawGdiPlusSupportLevel, GdipVersion, drawGdiplusCacheLevel);
2442 const uint16_t GdipGraphicsCacheEntries = Stream_Get_UINT16(s);
2443 const uint16_t GdipBrushCacheEntries = Stream_Get_UINT16(s);
2444 const uint16_t GdipPenCacheEntries = Stream_Get_UINT16(s);
2445 const uint16_t GdipImageCacheEntries = Stream_Get_UINT16(s);
2446 const uint16_t GdipImageAttributesCacheEntries = Stream_Get_UINT16(s);
2447 WLog_Print(log, WLOG_TRACE,
2448 "GdipGraphicsCacheEntries=0x%04" PRIx16
", GdipBrushCacheEntries=0x%04" PRIx16
2449 ", GdipPenCacheEntries=0x%04" PRIx16
", GdipImageCacheEntries=0x%04" PRIx16
2450 ", GdipImageAttributesCacheEntries=0x%04" PRIx16,
2451 GdipGraphicsCacheEntries, GdipBrushCacheEntries, GdipPenCacheEntries,
2452 GdipImageCacheEntries, GdipImageAttributesCacheEntries);
2454 const uint16_t GdipGraphicsCacheChunkSize = Stream_Get_UINT16(s);
2455 const uint16_t GdipObjectBrushCacheChunkSize = Stream_Get_UINT16(s);
2456 const uint16_t GdipObjectPenCacheChunkSize = Stream_Get_UINT16(s);
2457 const uint16_t GdipObjectImageAttributesCacheChunkSize = Stream_Get_UINT16(s);
2458 WLog_Print(log, WLOG_TRACE,
2459 "GdipGraphicsCacheChunkSize=0x%04" PRIx16
2460 ", GdipObjectBrushCacheChunkSize=0x%04" PRIx16
2461 ", GdipObjectPenCacheChunkSize=0x%04" PRIx16
2462 ",GdipObjectImageAttributesCacheChunkSize=0x%04" PRIx16,
2463 GdipGraphicsCacheChunkSize, GdipObjectBrushCacheChunkSize,
2464 GdipObjectPenCacheChunkSize, GdipObjectImageAttributesCacheChunkSize);
2466 const uint16_t GdipObjectImageCacheChunkSize = Stream_Get_UINT16(s);
2467 const uint16_t GdipObjectImageCacheTotalSize = Stream_Get_UINT16(s);
2468 const uint16_t GdipObjectImageCacheMaxSize = Stream_Get_UINT16(s);
2471 "GdipObjectImageCacheChunkSize=0x%04" PRIx16
", GdipObjectImageCacheTotalSize=0x%04" PRIx16
2472 ", GdipObjectImageCacheMaxSize=0x%04" PRIx16,
2473 GdipObjectImageCacheChunkSize, GdipObjectImageCacheTotalSize, GdipObjectImageCacheMaxSize);
2478static BOOL rdp_apply_remote_programs_capability_set(rdpSettings* settings,
const rdpSettings* src)
2480 WINPR_ASSERT(settings);
2483 if (settings->RemoteApplicationMode)
2484 settings->RemoteApplicationMode = src->RemoteApplicationMode;
2489 UINT32 supportLevel = src->RemoteApplicationSupportLevel;
2490 if (settings->RemoteApplicationMode)
2491 supportLevel |= RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED;
2493 settings->RemoteApplicationSupportLevel = supportLevel & settings->RemoteApplicationSupportMask;
2503static BOOL rdp_read_remote_programs_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2505 UINT32 railSupportLevel = 0;
2507 WINPR_ASSERT(settings);
2508 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2511 Stream_Read_UINT32(s, railSupportLevel);
2513 settings->RemoteApplicationMode = (railSupportLevel & RAIL_LEVEL_SUPPORTED) != 0;
2514 settings->RemoteApplicationSupportLevel = railSupportLevel;
2523static BOOL rdp_write_remote_programs_capability_set(wLog* log,
wStream* s,
2524 const rdpSettings* settings)
2526 WINPR_ASSERT(settings);
2527 if (!Stream_EnsureRemainingCapacity(s, 64))
2530 const size_t header = rdp_capability_set_start(log, s);
2531 UINT32 railSupportLevel = RAIL_LEVEL_SUPPORTED;
2533 if (settings->RemoteApplicationSupportLevel & RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED)
2535 if (settings->RemoteAppLanguageBarSupported)
2536 railSupportLevel |= RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED;
2539 railSupportLevel |= RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED;
2540 railSupportLevel |= RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED;
2541 railSupportLevel |= RAIL_LEVEL_SERVER_TO_CLIENT_IME_SYNC_SUPPORTED;
2542 railSupportLevel |= RAIL_LEVEL_HIDE_MINIMIZED_APPS_SUPPORTED;
2543 railSupportLevel |= RAIL_LEVEL_WINDOW_CLOAKING_SUPPORTED;
2544 railSupportLevel |= RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED;
2546 railSupportLevel &= settings->RemoteApplicationSupportLevel;
2547 Stream_Write_UINT32(s, railSupportLevel);
2548 return rdp_capability_set_finish(s, header, CAPSET_TYPE_RAIL);
2551#ifdef WITH_DEBUG_CAPABILITIES
2552static BOOL rdp_print_remote_programs_capability_set(wLog* log,
wStream* s)
2554 UINT32 railSupportLevel = 0;
2555 WLog_Print(log, WLOG_TRACE,
2556 "RemoteProgramsCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2558 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2561 Stream_Read_UINT32(s, railSupportLevel);
2562 WLog_Print(log, WLOG_TRACE,
"\trailSupportLevel: 0x%08" PRIX32
"", railSupportLevel);
2567static BOOL rdp_apply_window_list_capability_set(rdpSettings* settings,
const rdpSettings* src)
2569 WINPR_ASSERT(settings);
2572 settings->RemoteWndSupportLevel = src->RemoteWndSupportLevel;
2573 settings->RemoteAppNumIconCaches = src->RemoteAppNumIconCaches;
2574 settings->RemoteAppNumIconCacheEntries = src->RemoteAppNumIconCacheEntries;
2584static BOOL rdp_read_window_list_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2586 WINPR_ASSERT(settings);
2587 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 7))
2590 Stream_Read_UINT32(s, settings->RemoteWndSupportLevel);
2591 Stream_Read_UINT8(s, settings->RemoteAppNumIconCaches);
2592 Stream_Read_UINT16(s,
2593 settings->RemoteAppNumIconCacheEntries);
2602static BOOL rdp_write_window_list_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
2604 WINPR_ASSERT(settings);
2605 if (!Stream_EnsureRemainingCapacity(s, 32))
2608 const size_t header = rdp_capability_set_start(log, s);
2609 Stream_Write_UINT32(s, settings->RemoteWndSupportLevel);
2611 s, WINPR_ASSERTING_INT_CAST(uint8_t,
2612 settings->RemoteAppNumIconCaches));
2613 Stream_Write_UINT16(
2615 WINPR_ASSERTING_INT_CAST(
2616 uint16_t, settings->RemoteAppNumIconCacheEntries));
2617 return rdp_capability_set_finish(s, header, CAPSET_TYPE_WINDOW);
2620#ifdef WITH_DEBUG_CAPABILITIES
2621static BOOL rdp_print_window_list_capability_set(wLog* log,
wStream* s)
2623 UINT32 wndSupportLevel = 0;
2624 BYTE numIconCaches = 0;
2625 UINT16 numIconCacheEntries = 0;
2626 WLog_Print(log, WLOG_TRACE,
2627 "WindowListCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2629 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 7))
2632 Stream_Read_UINT32(s, wndSupportLevel);
2633 Stream_Read_UINT8(s, numIconCaches);
2634 Stream_Read_UINT16(s, numIconCacheEntries);
2635 WLog_Print(log, WLOG_TRACE,
"\twndSupportLevel: 0x%08" PRIX32
"", wndSupportLevel);
2636 WLog_Print(log, WLOG_TRACE,
"\tnumIconCaches: 0x%02" PRIX8
"", numIconCaches);
2637 WLog_Print(log, WLOG_TRACE,
"\tnumIconCacheEntries: 0x%04" PRIX16
"", numIconCacheEntries);
2642static BOOL rdp_apply_desktop_composition_capability_set(rdpSettings* settings,
2643 const rdpSettings* src)
2645 WINPR_ASSERT(settings);
2648 settings->CompDeskSupportLevel = src->CompDeskSupportLevel;
2657static BOOL rdp_read_desktop_composition_capability_set(wLog* log,
wStream* s,
2658 rdpSettings* settings)
2660 WINPR_UNUSED(settings);
2661 WINPR_ASSERT(settings);
2663 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 2))
2666 Stream_Read_UINT16(s, settings->CompDeskSupportLevel);
2675static BOOL rdp_write_desktop_composition_capability_set(wLog* log,
wStream* s,
2676 const rdpSettings* settings)
2678 WINPR_ASSERT(settings);
2680 if (!Stream_EnsureRemainingCapacity(s, 32))
2683 const size_t header = rdp_capability_set_start(log, s);
2684 const UINT16 compDeskSupportLevel =
2685 (settings->AllowDesktopComposition) ? COMPDESK_SUPPORTED : COMPDESK_NOT_SUPPORTED;
2686 Stream_Write_UINT16(s, compDeskSupportLevel);
2687 return rdp_capability_set_finish(s, header, CAPSET_TYPE_COMP_DESK);
2690#ifdef WITH_DEBUG_CAPABILITIES
2691static BOOL rdp_print_desktop_composition_capability_set(wLog* log,
wStream* s)
2693 UINT16 compDeskSupportLevel = 0;
2694 WLog_Print(log, WLOG_TRACE,
"DesktopCompositionCapabilitySet (length %" PRIuz
"):",
2695 Stream_GetRemainingLength(s));
2697 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 2))
2700 Stream_Read_UINT16(s, compDeskSupportLevel);
2701 WLog_Print(log, WLOG_TRACE,
"\tcompDeskSupportLevel: 0x%04" PRIX16
"", compDeskSupportLevel);
2706static BOOL rdp_apply_multifragment_update_capability_set(rdpSettings* settings,
2707 const rdpSettings* src)
2709 UINT32 multifragMaxRequestSize = 0;
2711 WINPR_ASSERT(settings);
2714 multifragMaxRequestSize = src->MultifragMaxRequestSize;
2716 if (settings->ServerMode)
2726 if (multifragMaxRequestSize < FASTPATH_MAX_PACKET_SIZE)
2727 multifragMaxRequestSize = FASTPATH_FRAGMENT_SAFE_SIZE;
2729 if (settings->RemoteFxCodec)
2736 if (multifragMaxRequestSize < settings->MultifragMaxRequestSize)
2742 settings->RemoteFxCodec = FALSE;
2743 settings->MultifragMaxRequestSize = multifragMaxRequestSize;
2752 settings->MultifragMaxRequestSize = multifragMaxRequestSize;
2762 if (multifragMaxRequestSize > settings->MultifragMaxRequestSize)
2763 settings->MultifragMaxRequestSize = multifragMaxRequestSize;
2773static BOOL rdp_read_multifragment_update_capability_set(wLog* log,
wStream* s,
2774 rdpSettings* settings)
2776 UINT32 multifragMaxRequestSize = 0;
2778 WINPR_ASSERT(settings);
2779 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2782 Stream_Read_UINT32(s, multifragMaxRequestSize);
2783 settings->MultifragMaxRequestSize = multifragMaxRequestSize;
2793static BOOL rdp_write_multifragment_update_capability_set(wLog* log,
wStream* s,
2794 rdpSettings* settings)
2796 WINPR_ASSERT(settings);
2797 if (settings->ServerMode && settings->MultifragMaxRequestSize == 0)
2810 UINT32 tileNumX = (settings->DesktopWidth + 63) / 64;
2811 UINT32 tileNumY = (settings->DesktopHeight + 63) / 64;
2812 settings->MultifragMaxRequestSize = tileNumX * tileNumY * 16384;
2814 settings->MultifragMaxRequestSize += 16384;
2817 if (!Stream_EnsureRemainingCapacity(s, 32))
2819 const size_t header = rdp_capability_set_start(log, s);
2820 Stream_Write_UINT32(s, settings->MultifragMaxRequestSize);
2821 return rdp_capability_set_finish(s, header, CAPSET_TYPE_MULTI_FRAGMENT_UPDATE);
2824#ifdef WITH_DEBUG_CAPABILITIES
2825static BOOL rdp_print_multifragment_update_capability_set(wLog* log,
wStream* s)
2827 UINT32 maxRequestSize = 0;
2828 WLog_Print(log, WLOG_TRACE,
"MultifragmentUpdateCapabilitySet (length %" PRIuz
"):",
2829 Stream_GetRemainingLength(s));
2831 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2834 Stream_Read_UINT32(s, maxRequestSize);
2835 WLog_Print(log, WLOG_TRACE,
"\tmaxRequestSize: 0x%08" PRIX32
"", maxRequestSize);
2840static BOOL rdp_apply_large_pointer_capability_set(rdpSettings* settings,
const rdpSettings* src)
2842 WINPR_ASSERT(settings);
2845 settings->LargePointerFlag = src->LargePointerFlag;
2854static BOOL rdp_read_large_pointer_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2856 UINT16 largePointerSupportFlags = 0;
2858 WINPR_ASSERT(settings);
2859 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 2))
2862 Stream_Read_UINT16(s, largePointerSupportFlags);
2863 settings->LargePointerFlag &= largePointerSupportFlags;
2864 if ((largePointerSupportFlags & ~(LARGE_POINTER_FLAG_96x96 | LARGE_POINTER_FLAG_384x384)) != 0)
2868 "TS_LARGE_POINTER_CAPABILITYSET with unsupported flags %04X (all flags %04X) received",
2869 WINPR_CXX_COMPAT_CAST(UINT32, largePointerSupportFlags & ~(LARGE_POINTER_FLAG_96x96 |
2870 LARGE_POINTER_FLAG_384x384)),
2871 largePointerSupportFlags);
2881static BOOL rdp_write_large_pointer_capability_set(wLog* log,
wStream* s,
2882 const rdpSettings* settings)
2884 WINPR_ASSERT(settings);
2885 if (!Stream_EnsureRemainingCapacity(s, 32))
2888 const size_t header = rdp_capability_set_start(log, s);
2889 const UINT16 largePointerSupportFlags =
2890 settings->LargePointerFlag & (LARGE_POINTER_FLAG_96x96 | LARGE_POINTER_FLAG_384x384);
2891 Stream_Write_UINT16(s, largePointerSupportFlags);
2892 return rdp_capability_set_finish(s, header, CAPSET_TYPE_LARGE_POINTER);
2895#ifdef WITH_DEBUG_CAPABILITIES
2896static BOOL rdp_print_large_pointer_capability_set(wLog* log,
wStream* s)
2898 UINT16 largePointerSupportFlags = 0;
2899 WLog_Print(log, WLOG_TRACE,
2900 "LargePointerCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2902 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 2))
2905 Stream_Read_UINT16(s, largePointerSupportFlags);
2906 WLog_Print(log, WLOG_TRACE,
"\tlargePointerSupportFlags: 0x%04" PRIX16
"",
2907 largePointerSupportFlags);
2912static BOOL rdp_apply_surface_commands_capability_set(rdpSettings* settings,
const rdpSettings* src)
2914 WINPR_ASSERT(settings);
2921 if (src->FastPathOutput)
2923 settings->SurfaceCommandsSupported &= src->SurfaceCommandsSupported;
2924 settings->SurfaceCommandsEnabled = src->SurfaceCommandsEnabled;
2925 settings->SurfaceFrameMarkerEnabled = src->SurfaceFrameMarkerEnabled;
2929 settings->SurfaceCommandsSupported = 0;
2930 settings->SurfaceCommandsEnabled = FALSE;
2931 settings->SurfaceFrameMarkerEnabled = FALSE;
2942static BOOL rdp_read_surface_commands_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2944 UINT32 cmdFlags = 0;
2946 WINPR_ASSERT(settings);
2947 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
2950 Stream_Read_UINT32(s, cmdFlags);
2951 Stream_Seek_UINT32(s);
2952 settings->SurfaceCommandsSupported = cmdFlags;
2953 settings->SurfaceCommandsEnabled =
2954 (cmdFlags & (SURFCMDS_SET_SURFACE_BITS | SURFCMDS_STREAM_SURFACE_BITS)) != 0;
2955 settings->SurfaceFrameMarkerEnabled = (cmdFlags & SURFCMDS_FRAME_MARKER) != 0;
2964static BOOL rdp_write_surface_commands_capability_set(wLog* log,
wStream* s,
2965 const rdpSettings* settings)
2967 WINPR_ASSERT(settings);
2968 if (!Stream_EnsureRemainingCapacity(s, 32))
2971 const size_t header = rdp_capability_set_start(log, s);
2975 if (settings->SurfaceFrameMarkerEnabled)
2976 cmdFlags |= SURFCMDS_FRAME_MARKER;
2978 Stream_Write_UINT32(s, cmdFlags);
2979 Stream_Write_UINT32(s, 0);
2980 return rdp_capability_set_finish(s, header, CAPSET_TYPE_SURFACE_COMMANDS);
2983static bool sUuidEqual(
const UUID* Uuid1,
const UUID* Uuid2)
2985 if (!Uuid1 && !Uuid2)
2988 if (Uuid1 && !Uuid2)
2991 if (!Uuid1 && Uuid2)
2994 if (Uuid1->Data1 != Uuid2->Data1)
2997 if (Uuid1->Data2 != Uuid2->Data2)
3000 if (Uuid1->Data3 != Uuid2->Data3)
3003 for (
int index = 0; index < 8; index++)
3005 if (Uuid1->Data4[index] != Uuid2->Data4[index])
3012#ifdef WITH_DEBUG_CAPABILITIES
3013static BOOL rdp_print_surface_commands_capability_set(wLog* log,
wStream* s)
3015 UINT32 cmdFlags = 0;
3016 UINT32 reserved = 0;
3018 WLog_Print(log, WLOG_TRACE,
3019 "SurfaceCommandsCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
3021 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
3024 Stream_Read_UINT32(s, cmdFlags);
3025 Stream_Read_UINT32(s, reserved);
3026 WLog_Print(log, WLOG_TRACE,
"\tcmdFlags: 0x%08" PRIX32
"", cmdFlags);
3027 WLog_Print(log, WLOG_TRACE,
"\treserved: 0x%08" PRIX32
"", reserved);
3031static void rdp_print_bitmap_codec_guid(wLog* log,
const GUID* guid)
3034 WLog_Print(log, WLOG_TRACE,
3035 "%08" PRIX32
"%04" PRIX16
"%04" PRIX16
"%02" PRIX8
"%02" PRIX8
"%02" PRIX8
3036 "%02" PRIX8
"%02" PRIX8
"%02" PRIX8
"%02" PRIX8
"%02" PRIX8
"",
3037 guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], guid->Data4[1],
3038 guid->Data4[2], guid->Data4[3], guid->Data4[4], guid->Data4[5], guid->Data4[6],
3042static char* rdp_get_bitmap_codec_guid_name(
const GUID* guid)
3045 if (sUuidEqual(guid, &CODEC_GUID_REMOTEFX))
3046 return "CODEC_GUID_REMOTEFX";
3047 else if (sUuidEqual(guid, &CODEC_GUID_NSCODEC))
3048 return "CODEC_GUID_NSCODEC";
3049 else if (sUuidEqual(guid, &CODEC_GUID_IGNORE))
3050 return "CODEC_GUID_IGNORE";
3051 else if (sUuidEqual(guid, &CODEC_GUID_IMAGE_REMOTEFX))
3052 return "CODEC_GUID_IMAGE_REMOTEFX";
3054#if defined(WITH_JPEG)
3055 else if (sUuidEqual(guid, &CODEC_GUID_JPEG))
3056 return "CODEC_GUID_JPEG";
3059 return "CODEC_GUID_UNKNOWN";
3063static BOOL rdp_read_bitmap_codec_guid(wLog* log,
wStream* s, GUID* guid)
3065 BYTE g[16] = WINPR_C_ARRAY_INIT;
3068 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 16))
3070 Stream_Read(s, g, 16);
3071 guid->Data1 = ((UINT32)g[3] << 24U) | ((UINT32)g[2] << 16U) | (UINT32)(g[1] << 8U) | g[0];
3072 guid->Data2 = ((g[5] << 8U) | g[4]) & 0xFFFF;
3073 guid->Data3 = ((g[7] << 8U) | g[6]) & 0xFFFF;
3074 guid->Data4[0] = g[8];
3075 guid->Data4[1] = g[9];
3076 guid->Data4[2] = g[10];
3077 guid->Data4[3] = g[11];
3078 guid->Data4[4] = g[12];
3079 guid->Data4[5] = g[13];
3080 guid->Data4[6] = g[14];
3081 guid->Data4[7] = g[15];
3085static void rdp_write_bitmap_codec_guid(
wStream* s,
const GUID* guid)
3087 BYTE g[16] = WINPR_C_ARRAY_INIT;
3089 g[0] = guid->Data1 & 0xFF;
3090 g[1] = (guid->Data1 >> 8) & 0xFF;
3091 g[2] = (guid->Data1 >> 16) & 0xFF;
3092 g[3] = (guid->Data1 >> 24) & 0xFF;
3093 g[4] = (guid->Data2) & 0xFF;
3094 g[5] = (guid->Data2 >> 8) & 0xFF;
3095 g[6] = (guid->Data3) & 0xFF;
3096 g[7] = (guid->Data3 >> 8) & 0xFF;
3097 g[8] = guid->Data4[0];
3098 g[9] = guid->Data4[1];
3099 g[10] = guid->Data4[2];
3100 g[11] = guid->Data4[3];
3101 g[12] = guid->Data4[4];
3102 g[13] = guid->Data4[5];
3103 g[14] = guid->Data4[6];
3104 g[15] = guid->Data4[7];
3105 Stream_Write(s, g, 16);
3108static BOOL rdp_apply_bitmap_codecs_capability_set(rdpSettings* settings,
const rdpSettings* src)
3110 WINPR_ASSERT(settings);
3113 if (settings->ServerMode)
3116 settings->RemoteFxCodecId = src->RemoteFxCodecId;
3117 settings->RemoteFxCaptureFlags = src->RemoteFxCaptureFlags;
3118 settings->RemoteFxOnly = src->RemoteFxOnly;
3119 settings->RemoteFxRlgrMode = src->RemoteFxRlgrMode;
3120 settings->RemoteFxCodecMode = src->RemoteFxCodecMode;
3121 settings->NSCodecId = src->NSCodecId;
3122 settings->NSCodecAllowDynamicColorFidelity = src->NSCodecAllowDynamicColorFidelity;
3123 settings->NSCodecAllowSubsampling = src->NSCodecAllowSubsampling;
3124 settings->NSCodecColorLossLevel = src->NSCodecColorLossLevel;
3127 settings->RemoteFxCodec = settings->RemoteFxCodec && src->RemoteFxCodecId;
3128 settings->RemoteFxImageCodec = settings->RemoteFxImageCodec && src->RemoteFxImageCodec;
3130 settings->NSCodec && src->NSCodec))
3132 settings->JpegCodec = src->JpegCodec;
3137static BOOL rdp_read_codec_ts_rfx_icap(wLog* log,
wStream* sub, rdpSettings* settings,
3141 UINT16 tileSize = 0;
3142 BYTE codecFlags = 0;
3143 BYTE colConvBits = 0;
3144 BYTE transformBits = 0;
3145 BYTE entropyBits = 0;
3149 WLog_Print(log, WLOG_ERROR,
3150 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP size %" PRIu16
3151 " unsupported, expecting size %" PRIu16
" not supported",
3156 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 8))
3159 Stream_Read_UINT16(sub, version);
3160 Stream_Read_UINT16(sub, tileSize);
3161 Stream_Read_UINT8(sub, codecFlags);
3162 Stream_Read_UINT8(sub, colConvBits);
3163 Stream_Read_UINT8(sub, transformBits);
3164 Stream_Read_UINT8(sub, entropyBits);
3166 if (version == 0x0009)
3169 if (tileSize != 0x0080)
3171 WLog_Print(log, WLOG_ERROR,
3172 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::version %" PRIu16
3173 " tile size %" PRIu16
" not supported",
3178 else if (version == 0x0100)
3181 if (tileSize != 0x0040)
3183 WLog_Print(log, WLOG_ERROR,
3184 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::version %" PRIu16
3185 " tile size %" PRIu16
" not supported",
3192 WLog_Print(log, WLOG_ERROR,
3193 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::version %" PRIu16
" not supported",
3199 if (colConvBits != 1)
3201 WLog_Print(log, WLOG_ERROR,
3202 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::colConvBits %" PRIu8
3203 " not supported, must be CLW_COL_CONV_ICT (0x1)",
3209 if (transformBits != 1)
3211 WLog_Print(log, WLOG_ERROR,
3212 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::transformBits %" PRIu8
3213 " not supported, must be CLW_XFORM_DWT_53_A (0x1)",
3218 const UINT8 CODEC_MODE = 0x02;
3222 if ((codecFlags & CODEC_MODE) != 0)
3227 else if ((codecFlags & ~CODEC_MODE) != 0)
3228 WLog_Print(log, WLOG_WARN,
3229 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::flags unknown value "
3231 WINPR_CXX_COMPAT_CAST(UINT32, (codecFlags & ~CODEC_MODE)));
3233 switch (entropyBits)
3235 case CLW_ENTROPY_RLGR1:
3239 case CLW_ENTROPY_RLGR3:
3244 WLog_Print(log, WLOG_ERROR,
3245 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::entropyBits "
3246 "unsupported value 0x%02" PRIx8
3247 ", must be CLW_ENTROPY_RLGR1 (0x01) or CLW_ENTROPY_RLGR3 "
3255static BOOL rdp_read_codec_ts_rfx_capset(wLog* log,
wStream* s, rdpSettings* settings)
3257 UINT16 blockType = 0;
3258 UINT32 blockLen = 0;
3259 BYTE rfxCodecId = 0;
3260 UINT16 capsetType = 0;
3261 UINT16 numIcaps = 0;
3264 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 6))
3268 Stream_Read_UINT16(s, blockType);
3269 Stream_Read_UINT32(s, blockLen);
3270 if (blockType != 0xCBC1)
3272 WLog_Print(log, WLOG_ERROR,
3273 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::blockType[0x%04" PRIx16
3274 "] != CBY_CAPSET (0xCBC1)",
3278 if (blockLen < 6ull)
3280 WLog_Print(log, WLOG_ERROR,
3281 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::blockLen[%" PRIu16
"] < 6", blockLen);
3284 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, blockLen - 6ull))
3287 wStream sbuffer = WINPR_C_ARRAY_INIT;
3288 wStream* sub = Stream_StaticConstInit(&sbuffer, Stream_Pointer(s), blockLen - 6ull);
3291 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 7))
3294 Stream_Read_UINT8(sub, rfxCodecId);
3295 Stream_Read_UINT16(sub, capsetType);
3296 Stream_Read_UINT16(sub, numIcaps);
3297 Stream_Read_UINT16(sub, icapLen);
3299 if (rfxCodecId != 1)
3301 WLog_Print(log, WLOG_ERROR,
3302 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::codecId[%" PRIu16
"] != 1", rfxCodecId);
3306 if (capsetType != 0xCFC0)
3308 WLog_Print(log, WLOG_ERROR,
3309 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::capsetType[0x%04" PRIx16
3310 "] != CLY_CAPSET (0xCFC0)",
3317 if (!rdp_read_codec_ts_rfx_icap(log, sub, settings, icapLen))
3323static BOOL rdp_read_codec_ts_rfx_caps(wLog* log,
wStream* sub, rdpSettings* settings)
3325 if (Stream_GetRemainingLength(sub) == 0)
3328 UINT16 blockType = 0;
3329 UINT32 blockLen = 0;
3330 UINT16 numCapsets = 0;
3333 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 8))
3335 Stream_Read_UINT16(sub, blockType);
3336 Stream_Read_UINT32(sub, blockLen);
3337 Stream_Read_UINT16(sub, numCapsets);
3339 if (blockType != 0xCBC0)
3341 WLog_Print(log, WLOG_ERROR,
3342 "[MS_RDPRFX] 2.2.1.1.1 TS_RFX_CAPS::blockType[0x%04" PRIx16
3343 "] != CBY_CAPS (0xCBC0)",
3350 WLog_Print(log, WLOG_ERROR,
"[MS_RDPRFX] 2.2.1.1.1 TS_RFX_CAPS::blockLen[%" PRIu16
"] != 8",
3355 if (numCapsets != 1)
3357 WLog_Print(log, WLOG_ERROR,
3358 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::numIcaps[%" PRIu16
"] != 1", numCapsets);
3362 for (UINT16 x = 0; x < numCapsets; x++)
3364 if (!rdp_read_codec_ts_rfx_capset(log, sub, settings))
3371static BOOL rdp_read_codec_ts_rfx_clnt_caps_container(wLog* log,
wStream* s, rdpSettings* settings)
3373 UINT32 rfxCapsLength = 0;
3374 UINT32 rfxPropsLength = 0;
3375 UINT32 captureFlags = 0;
3378 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
3380 Stream_Read_UINT32(s, rfxPropsLength);
3381 if (rfxPropsLength < 4)
3383 WLog_Print(log, WLOG_ERROR,
3384 "[MS_RDPRFX] 2.2.1.1 TS_RFX_CLNT_CAPS_CONTAINER::length %" PRIu32
3385 " too short, require at least 4 bytes",
3389 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, rfxPropsLength - 4ull))
3392 wStream sbuffer = WINPR_C_ARRAY_INIT;
3393 wStream* sub = Stream_StaticConstInit(&sbuffer, Stream_Pointer(s), rfxPropsLength - 4ull);
3396 Stream_Seek(s, rfxPropsLength - 4ull);
3398 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 8))
3401 Stream_Read_UINT32(sub, captureFlags);
3402 Stream_Read_UINT32(sub, rfxCapsLength);
3403 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, rfxCapsLength))
3406 settings->RemoteFxCaptureFlags = captureFlags;
3407 settings->RemoteFxOnly = !(captureFlags & CARDP_CAPS_CAPTURE_NON_CAC);
3410 wStream tsbuffer = WINPR_C_ARRAY_INIT;
3411 wStream* ts_sub = Stream_StaticConstInit(&tsbuffer, Stream_Pointer(sub), rfxCapsLength);
3412 WINPR_ASSERT(ts_sub);
3413 return rdp_read_codec_ts_rfx_caps(log, ts_sub, settings);
3421static BOOL rdp_read_bitmap_codecs_capability_set(wLog* log,
wStream* s, rdpSettings* settings,
3425 GUID codecGuid = WINPR_C_ARRAY_INIT;
3426 BYTE bitmapCodecCount = 0;
3427 UINT16 codecPropertiesLength = 0;
3429 BOOL guidNSCodec = FALSE;
3430 BOOL guidRemoteFx = FALSE;
3431 BOOL guidRemoteFxImage = FALSE;
3433 WINPR_ASSERT(settings);
3434 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 1))
3437 Stream_Read_UINT8(s, bitmapCodecCount);
3439 while (bitmapCodecCount > 0)
3441 wStream subbuffer = WINPR_C_ARRAY_INIT;
3443 if (!rdp_read_bitmap_codec_guid(log, s, &codecGuid))
3445 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 3))
3447 Stream_Read_UINT8(s, codecId);
3448 Stream_Read_UINT16(s, codecPropertiesLength);
3450 wStream* sub = Stream_StaticInit(&subbuffer, Stream_Pointer(s), codecPropertiesLength);
3451 if (!Stream_SafeSeek(s, codecPropertiesLength))
3456 if (sUuidEqual(&codecGuid, &CODEC_GUID_REMOTEFX))
3458 guidRemoteFx = TRUE;
3459 settings->RemoteFxCodecId = codecId;
3460 if (!rdp_read_codec_ts_rfx_clnt_caps_container(log, sub, settings))
3463 else if (sUuidEqual(&codecGuid, &CODEC_GUID_IMAGE_REMOTEFX))
3466 guidRemoteFxImage = TRUE;
3467 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3470 else if (sUuidEqual(&codecGuid, &CODEC_GUID_NSCODEC))
3472 BYTE colorLossLevel = 0;
3473 BYTE fAllowSubsampling = 0;
3474 BYTE fAllowDynamicFidelity = 0;
3476 settings->NSCodecId = codecId;
3477 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 3))
3479 Stream_Read_UINT8(sub, fAllowDynamicFidelity);
3480 Stream_Read_UINT8(sub, fAllowSubsampling);
3481 Stream_Read_UINT8(sub, colorLossLevel);
3483 if (colorLossLevel < 1)
3486 if (colorLossLevel > 7)
3489 settings->NSCodecAllowDynamicColorFidelity = fAllowDynamicFidelity;
3490 settings->NSCodecAllowSubsampling = fAllowSubsampling;
3491 settings->NSCodecColorLossLevel = colorLossLevel;
3493 else if (sUuidEqual(&codecGuid, &CODEC_GUID_IGNORE))
3495 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3500 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3506 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3510 const size_t rest = Stream_GetRemainingLength(sub);
3513 WLog_Print(log, WLOG_ERROR,
3514 "error while reading codec properties: actual size: %" PRIuz
3515 " expected size: %" PRIu32
"",
3516 rest + codecPropertiesLength, codecPropertiesLength);
3537static BOOL rdp_write_rfx_client_capability_container(
wStream* s,
const rdpSettings* settings)
3539 WINPR_ASSERT(settings);
3540 if (!Stream_EnsureRemainingCapacity(s, 64))
3543 const UINT32 captureFlags = settings->RemoteFxOnly ? 0 : CARDP_CAPS_CAPTURE_NON_CAC;
3545 WINPR_ASSERT(settings->RemoteFxCodecMode <= UINT8_MAX);
3546 const UINT8 codecMode = (UINT8)settings->RemoteFxCodecMode;
3547 Stream_Write_UINT16(s, 49);
3549 Stream_Write_UINT32(s, 49);
3550 Stream_Write_UINT32(s, captureFlags);
3551 Stream_Write_UINT32(s, 37);
3553 Stream_Write_UINT16(s, CBY_CAPS);
3554 Stream_Write_UINT32(s, 8);
3555 Stream_Write_UINT16(s, 1);
3557 Stream_Write_UINT16(s, CBY_CAPSET);
3558 Stream_Write_UINT32(s, 29);
3559 Stream_Write_UINT8(s, 0x01);
3560 Stream_Write_UINT16(s, CLY_CAPSET);
3561 Stream_Write_UINT16(s, 2);
3562 Stream_Write_UINT16(s, 8);
3564 Stream_Write_UINT16(s, CLW_VERSION_1_0);
3565 Stream_Write_UINT16(s, CT_TILE_64x64);
3566 Stream_Write_UINT8(s, codecMode);
3567 Stream_Write_UINT8(s, CLW_COL_CONV_ICT);
3568 Stream_Write_UINT8(s, CLW_XFORM_DWT_53_A);
3569 Stream_Write_UINT8(s, CLW_ENTROPY_RLGR1);
3571 Stream_Write_UINT16(s, CLW_VERSION_1_0);
3572 Stream_Write_UINT16(s, CT_TILE_64x64);
3573 Stream_Write_UINT8(s, codecMode);
3574 Stream_Write_UINT8(s, CLW_COL_CONV_ICT);
3575 Stream_Write_UINT8(s, CLW_XFORM_DWT_53_A);
3576 Stream_Write_UINT8(s, CLW_ENTROPY_RLGR3);
3583static BOOL rdp_write_nsc_client_capability_container(
wStream* s,
const rdpSettings* settings)
3585 WINPR_ASSERT(settings);
3587 const BOOL fAllowDynamicFidelity = settings->NSCodecAllowDynamicColorFidelity;
3588 const BOOL fAllowSubsampling = settings->NSCodecAllowSubsampling;
3589 UINT32 colorLossLevel = settings->NSCodecColorLossLevel;
3591 if (colorLossLevel < 1)
3594 if (colorLossLevel > 7)
3597 if (!Stream_EnsureRemainingCapacity(s, 8))
3600 Stream_Write_UINT16(s, 3);
3602 Stream_Write_UINT8(s, fAllowDynamicFidelity != 0);
3603 Stream_Write_UINT8(s, fAllowSubsampling != 0);
3604 Stream_Write_UINT8(s, (UINT8)colorLossLevel);
3608#if defined(WITH_JPEG)
3609static BOOL rdp_write_jpeg_client_capability_container(
wStream* s,
const rdpSettings* settings)
3611 WINPR_ASSERT(settings);
3612 if (!Stream_EnsureRemainingCapacity(s, 8))
3615 Stream_Write_UINT16(s, 1);
3616 Stream_Write_UINT8(s, settings->JpegQuality);
3624static BOOL rdp_write_rfx_server_capability_container(
wStream* s,
const rdpSettings* settings)
3626 WINPR_UNUSED(settings);
3627 WINPR_ASSERT(settings);
3629 if (!Stream_EnsureRemainingCapacity(s, 8))
3632 Stream_Write_UINT16(s, 4);
3633 Stream_Write_UINT32(s, 0);
3637#if defined(WITH_JPEG)
3638static BOOL rdp_write_jpeg_server_capability_container(
wStream* s,
const rdpSettings* settings)
3640 WINPR_UNUSED(settings);
3641 WINPR_ASSERT(settings);
3643 if (!Stream_EnsureRemainingCapacity(s, 8))
3646 Stream_Write_UINT16(s, 1);
3647 Stream_Write_UINT8(s, 75);
3655static BOOL rdp_write_nsc_server_capability_container(
wStream* s,
const rdpSettings* settings)
3657 WINPR_UNUSED(settings);
3658 WINPR_ASSERT(settings);
3660 if (!Stream_EnsureRemainingCapacity(s, 8))
3663 Stream_Write_UINT16(s, 4);
3664 Stream_Write_UINT32(s, 0);
3673static BOOL rdp_write_bitmap_codecs_capability_set(wLog* log,
wStream* s,
3674 const rdpSettings* settings)
3676 WINPR_ASSERT(settings);
3677 if (!Stream_EnsureRemainingCapacity(s, 64))
3680 const size_t header = rdp_capability_set_start(log, s);
3681 BYTE bitmapCodecCount = 0;
3683 if (settings->RemoteFxCodec)
3689#if defined(WITH_JPEG)
3691 if (settings->JpegCodec)
3696 if (settings->RemoteFxImageCodec)
3699 Stream_Write_UINT8(s, bitmapCodecCount);
3701 if (settings->RemoteFxCodec)
3703 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_REMOTEFX);
3705 if (settings->ServerMode)
3707 Stream_Write_UINT8(s, 0);
3709 if (!rdp_write_rfx_server_capability_container(s, settings))
3714 Stream_Write_UINT8(s, RDP_CODEC_ID_REMOTEFX);
3716 if (!rdp_write_rfx_client_capability_container(s, settings))
3723 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_NSCODEC);
3725 if (settings->ServerMode)
3727 Stream_Write_UINT8(s, 0);
3729 if (!rdp_write_nsc_server_capability_container(s, settings))
3734 Stream_Write_UINT8(s, RDP_CODEC_ID_NSCODEC);
3736 if (!rdp_write_nsc_client_capability_container(s, settings))
3741#if defined(WITH_JPEG)
3743 if (settings->JpegCodec)
3745 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_JPEG);
3747 if (settings->ServerMode)
3749 Stream_Write_UINT8(s, 0);
3751 if (!rdp_write_jpeg_server_capability_container(s, settings))
3756 Stream_Write_UINT8(s, RDP_CODEC_ID_JPEG);
3758 if (!rdp_write_jpeg_client_capability_container(s, settings))
3765 if (settings->RemoteFxImageCodec)
3767 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_IMAGE_REMOTEFX);
3769 if (settings->ServerMode)
3771 Stream_Write_UINT8(s, 0);
3773 if (!rdp_write_rfx_server_capability_container(s, settings))
3778 Stream_Write_UINT8(s, RDP_CODEC_ID_IMAGE_REMOTEFX);
3780 if (!rdp_write_rfx_client_capability_container(s, settings))
3785 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CODECS);
3788#ifdef WITH_DEBUG_CAPABILITIES
3789static BOOL rdp_print_bitmap_codecs_capability_set(wLog* log,
wStream* s)
3791 GUID codecGuid = WINPR_C_ARRAY_INIT;
3792 BYTE bitmapCodecCount = 0;
3794 UINT16 codecPropertiesLength = 0;
3796 WLog_Print(log, WLOG_TRACE,
3797 "BitmapCodecsCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
3799 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 1))
3802 Stream_Read_UINT8(s, bitmapCodecCount);
3803 WLog_Print(log, WLOG_TRACE,
"\tbitmapCodecCount: %" PRIu8
"", bitmapCodecCount);
3805 while (bitmapCodecCount > 0)
3807 if (!rdp_read_bitmap_codec_guid(log, s, &codecGuid))
3809 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 3))
3811 Stream_Read_UINT8(s, codecId);
3812 WLog_Print(log, WLOG_TRACE,
"\tcodecGuid: 0x");
3813 rdp_print_bitmap_codec_guid(log, &codecGuid);
3814 WLog_Print(log, WLOG_TRACE,
" (%s)", rdp_get_bitmap_codec_guid_name(&codecGuid));
3815 WLog_Print(log, WLOG_TRACE,
"\tcodecId: %" PRIu8
"", codecId);
3816 Stream_Read_UINT16(s, codecPropertiesLength);
3817 WLog_Print(log, WLOG_TRACE,
"\tcodecPropertiesLength: %" PRIu16
"", codecPropertiesLength);
3819 if (!Stream_SafeSeek(s, codecPropertiesLength))
3828static BOOL rdp_apply_frame_acknowledge_capability_set(rdpSettings* settings,
3829 const rdpSettings* src)
3831 WINPR_ASSERT(settings);
3834 if (settings->ServerMode)
3835 settings->FrameAcknowledge = src->FrameAcknowledge;
3844static BOOL rdp_read_frame_acknowledge_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
3846 WINPR_ASSERT(settings);
3847 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
3850 Stream_Read_UINT32(s, settings->FrameAcknowledge);
3859static BOOL rdp_write_frame_acknowledge_capability_set(wLog* log,
wStream* s,
3860 const rdpSettings* settings)
3862 WINPR_ASSERT(settings);
3863 if (!Stream_EnsureRemainingCapacity(s, 32))
3866 const size_t header = rdp_capability_set_start(log, s);
3867 Stream_Write_UINT32(s, settings->FrameAcknowledge);
3868 return rdp_capability_set_finish(s, header, CAPSET_TYPE_FRAME_ACKNOWLEDGE);
3871#ifdef WITH_DEBUG_CAPABILITIES
3872static BOOL rdp_print_frame_acknowledge_capability_set(wLog* log,
wStream* s)
3874 UINT32 frameAcknowledge = 0;
3875 WLog_Print(log, WLOG_TRACE,
3876 "FrameAcknowledgeCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
3878 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
3881 Stream_Read_UINT32(s, frameAcknowledge);
3882 WLog_Print(log, WLOG_TRACE,
"\tframeAcknowledge: 0x%08" PRIX32
"", frameAcknowledge);
3887static BOOL rdp_apply_bitmap_cache_v3_codec_id_capability_set(rdpSettings* settings,
3888 const rdpSettings* src)
3890 WINPR_ASSERT(settings);
3893 settings->BitmapCacheV3CodecId = src->BitmapCacheV3CodecId;
3897static BOOL rdp_read_bitmap_cache_v3_codec_id_capability_set(wLog* log,
wStream* s,
3898 rdpSettings* settings)
3900 BYTE bitmapCacheV3CodecId = 0;
3902 WINPR_ASSERT(settings);
3903 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 1))
3906 Stream_Read_UINT8(s, bitmapCacheV3CodecId);
3907 settings->BitmapCacheV3CodecId = bitmapCacheV3CodecId;
3911static BOOL rdp_write_bitmap_cache_v3_codec_id_capability_set(wLog* log,
wStream* s,
3912 const rdpSettings* settings)
3914 WINPR_ASSERT(settings);
3915 if (!Stream_EnsureRemainingCapacity(s, 32))
3918 const size_t header = rdp_capability_set_start(log, s);
3919 if (settings->BitmapCacheV3CodecId > UINT8_MAX)
3921 Stream_Write_UINT8(s, (UINT8)settings->BitmapCacheV3CodecId);
3922 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID);
3925#ifdef WITH_DEBUG_CAPABILITIES
3926static BOOL rdp_print_bitmap_cache_v3_codec_id_capability_set(wLog* log,
wStream* s)
3928 BYTE bitmapCacheV3CodecId = 0;
3929 WLog_Print(log, WLOG_TRACE,
"BitmapCacheV3CodecIdCapabilitySet (length %" PRIuz
"):",
3930 Stream_GetRemainingLength(s));
3932 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 1))
3935 Stream_Read_UINT8(s, bitmapCacheV3CodecId);
3936 WLog_Print(log, WLOG_TRACE,
"\tbitmapCacheV3CodecId: 0x%02" PRIX8
"", bitmapCacheV3CodecId);
3940BOOL rdp_print_capability_sets(wLog* log,
wStream* s,
size_t start, BOOL receiving)
3945 UINT16 numberCapabilities = 0;
3947 size_t pos = Stream_GetPosition(s);
3949 Stream_SetPosition(s, start);
3952 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
3957 if (!Stream_CheckAndLogRequiredCapacityWLog(log, (s), 4))
3961 Stream_Read_UINT16(s, numberCapabilities);
3964 while (numberCapabilities > 0)
3970 if (!rdp_read_capability_set_header(log, s, &length, &type))
3973 WLog_Print(log, WLOG_TRACE,
"%s ", receiving ?
"Receiving" :
"Sending");
3974 sub = Stream_StaticInit(&subBuffer, Stream_Pointer(s), length - 4);
3975 if (!Stream_SafeSeek(s, length - 4))
3980 case CAPSET_TYPE_GENERAL:
3981 if (!rdp_print_general_capability_set(log, sub))
3986 case CAPSET_TYPE_BITMAP:
3987 if (!rdp_print_bitmap_capability_set(log, sub))
3992 case CAPSET_TYPE_ORDER:
3993 if (!rdp_print_order_capability_set(log, sub))
3998 case CAPSET_TYPE_BITMAP_CACHE:
3999 if (!rdp_print_bitmap_cache_capability_set(log, sub))
4004 case CAPSET_TYPE_CONTROL:
4005 if (!rdp_print_control_capability_set(log, sub))
4010 case CAPSET_TYPE_ACTIVATION:
4011 if (!rdp_print_window_activation_capability_set(log, sub))
4016 case CAPSET_TYPE_POINTER:
4017 if (!rdp_print_pointer_capability_set(log, sub))
4022 case CAPSET_TYPE_SHARE:
4023 if (!rdp_print_share_capability_set(log, sub))
4028 case CAPSET_TYPE_COLOR_CACHE:
4029 if (!rdp_print_color_cache_capability_set(log, sub))
4034 case CAPSET_TYPE_SOUND:
4035 if (!rdp_print_sound_capability_set(log, sub))
4040 case CAPSET_TYPE_INPUT:
4041 if (!rdp_print_input_capability_set(log, sub))
4046 case CAPSET_TYPE_FONT:
4047 if (!rdp_print_font_capability_set(log, sub))
4052 case CAPSET_TYPE_BRUSH:
4053 if (!rdp_print_brush_capability_set(log, sub))
4058 case CAPSET_TYPE_GLYPH_CACHE:
4059 if (!rdp_print_glyph_cache_capability_set(log, sub))
4064 case CAPSET_TYPE_OFFSCREEN_CACHE:
4065 if (!rdp_print_offscreen_bitmap_cache_capability_set(log, sub))
4070 case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
4071 if (!rdp_print_bitmap_cache_host_support_capability_set(log, sub))
4076 case CAPSET_TYPE_BITMAP_CACHE_V2:
4077 if (!rdp_print_bitmap_cache_v2_capability_set(log, sub))
4082 case CAPSET_TYPE_VIRTUAL_CHANNEL:
4083 if (!rdp_print_virtual_channel_capability_set(log, sub))
4088 case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
4089 if (!rdp_print_draw_nine_grid_cache_capability_set(log, sub))
4094 case CAPSET_TYPE_DRAW_GDI_PLUS:
4095 if (!rdp_print_draw_gdiplus_cache_capability_set(log, sub))
4100 case CAPSET_TYPE_RAIL:
4101 if (!rdp_print_remote_programs_capability_set(log, sub))
4106 case CAPSET_TYPE_WINDOW:
4107 if (!rdp_print_window_list_capability_set(log, sub))
4112 case CAPSET_TYPE_COMP_DESK:
4113 if (!rdp_print_desktop_composition_capability_set(log, sub))
4118 case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
4119 if (!rdp_print_multifragment_update_capability_set(log, sub))
4124 case CAPSET_TYPE_LARGE_POINTER:
4125 if (!rdp_print_large_pointer_capability_set(log, sub))
4130 case CAPSET_TYPE_SURFACE_COMMANDS:
4131 if (!rdp_print_surface_commands_capability_set(log, sub))
4136 case CAPSET_TYPE_BITMAP_CODECS:
4137 if (!rdp_print_bitmap_codecs_capability_set(log, sub))
4142 case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
4143 if (!rdp_print_frame_acknowledge_capability_set(log, sub))
4148 case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID:
4149 if (!rdp_print_bitmap_cache_v3_codec_id_capability_set(log, sub))
4155 WLog_Print(log, WLOG_ERROR,
"unknown capability type %" PRIu16
"", type);
4159 rest = Stream_GetRemainingLength(sub);
4162 WLog_Print(log, WLOG_WARN,
4163 "incorrect capability offset, type:0x%04" PRIX16
" %" PRIu16
4164 " bytes expected, %" PRIuz
"bytes remaining",
4165 type, length, rest);
4168 numberCapabilities--;
4173 Stream_SetPosition(s, pos);
4178static BOOL rdp_apply_from_received(UINT16 type, rdpSettings* dst,
const rdpSettings* src)
4182 case CAPSET_TYPE_GENERAL:
4183 return rdp_apply_general_capability_set(dst, src);
4184 case CAPSET_TYPE_BITMAP:
4185 return rdp_apply_bitmap_capability_set(dst, src);
4186 case CAPSET_TYPE_ORDER:
4187 return rdp_apply_order_capability_set(dst, src);
4188 case CAPSET_TYPE_POINTER:
4189 return rdp_apply_pointer_capability_set(dst, src);
4190 case CAPSET_TYPE_INPUT:
4191 return rdp_apply_input_capability_set(dst, src);
4192 case CAPSET_TYPE_VIRTUAL_CHANNEL:
4193 return rdp_apply_virtual_channel_capability_set(dst, src);
4194 case CAPSET_TYPE_SHARE:
4195 return rdp_apply_share_capability_set(dst, src);
4196 case CAPSET_TYPE_COLOR_CACHE:
4197 return rdp_apply_color_cache_capability_set(dst, src);
4198 case CAPSET_TYPE_FONT:
4199 return rdp_apply_font_capability_set(dst, src);
4200 case CAPSET_TYPE_DRAW_GDI_PLUS:
4201 return rdp_apply_draw_gdiplus_cache_capability_set(dst, src);
4202 case CAPSET_TYPE_RAIL:
4203 return rdp_apply_remote_programs_capability_set(dst, src);
4204 case CAPSET_TYPE_WINDOW:
4205 return rdp_apply_window_list_capability_set(dst, src);
4206 case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
4207 return rdp_apply_multifragment_update_capability_set(dst, src);
4208 case CAPSET_TYPE_LARGE_POINTER:
4209 return rdp_apply_large_pointer_capability_set(dst, src);
4210 case CAPSET_TYPE_COMP_DESK:
4211 return rdp_apply_desktop_composition_capability_set(dst, src);
4212 case CAPSET_TYPE_SURFACE_COMMANDS:
4213 return rdp_apply_surface_commands_capability_set(dst, src);
4214 case CAPSET_TYPE_BITMAP_CODECS:
4215 return rdp_apply_bitmap_codecs_capability_set(dst, src);
4216 case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
4217 return rdp_apply_frame_acknowledge_capability_set(dst, src);
4218 case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID:
4219 return rdp_apply_bitmap_cache_v3_codec_id_capability_set(dst, src);
4220 case CAPSET_TYPE_BITMAP_CACHE:
4221 return rdp_apply_bitmap_cache_capability_set(dst, src);
4222 case CAPSET_TYPE_BITMAP_CACHE_V2:
4223 return rdp_apply_bitmap_cache_v2_capability_set(dst, src);
4224 case CAPSET_TYPE_BRUSH:
4225 return rdp_apply_brush_capability_set(dst, src);
4226 case CAPSET_TYPE_GLYPH_CACHE:
4227 return rdp_apply_glyph_cache_capability_set(dst, src);
4228 case CAPSET_TYPE_OFFSCREEN_CACHE:
4229 return rdp_apply_offscreen_bitmap_cache_capability_set(dst, src);
4230 case CAPSET_TYPE_SOUND:
4231 return rdp_apply_sound_capability_set(dst, src);
4232 case CAPSET_TYPE_CONTROL:
4233 return rdp_apply_control_capability_set(dst, src);
4234 case CAPSET_TYPE_ACTIVATION:
4235 return rdp_apply_window_activation_capability_set(dst, src);
4236 case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
4237 return rdp_apply_draw_nine_grid_cache_capability_set(dst, src);
4238 case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
4239 return rdp_apply_bitmap_cache_host_support_capability_set(dst, src);
4245BOOL rdp_read_capability_set(wLog* log,
wStream* sub, UINT16 type, rdpSettings* settings,
4248 WINPR_ASSERT(settings);
4250 if (type <= CAPSET_TYPE_FRAME_ACKNOWLEDGE)
4252 const size_t size = Stream_Length(sub);
4253 if (size > UINT32_MAX)
4256 WINPR_ASSERT(settings->ReceivedCapabilities);
4257 settings->ReceivedCapabilities[type] = TRUE;
4259 WINPR_ASSERT(settings->ReceivedCapabilityDataSizes);
4260 settings->ReceivedCapabilityDataSizes[type] = (UINT32)size;
4262 WINPR_ASSERT(settings->ReceivedCapabilityData);
4263 void* tmp = realloc(settings->ReceivedCapabilityData[type], size);
4264 if (!tmp && (size > 0))
4266 memcpy(tmp, Stream_Buffer(sub), size);
4267 settings->ReceivedCapabilityData[type] = tmp;
4270 WLog_Print(log, WLOG_WARN,
"not handling capability type %" PRIu16
" yet", type);
4272 BOOL treated = TRUE;
4276 case CAPSET_TYPE_GENERAL:
4277 if (!rdp_read_general_capability_set(log, sub, settings))
4282 case CAPSET_TYPE_BITMAP:
4283 if (!rdp_read_bitmap_capability_set(log, sub, settings))
4288 case CAPSET_TYPE_ORDER:
4289 if (!rdp_read_order_capability_set(log, sub, settings))
4294 case CAPSET_TYPE_POINTER:
4295 if (!rdp_read_pointer_capability_set(log, sub, settings))
4300 case CAPSET_TYPE_INPUT:
4301 if (!rdp_read_input_capability_set(log, sub, settings))
4306 case CAPSET_TYPE_VIRTUAL_CHANNEL:
4307 if (!rdp_read_virtual_channel_capability_set(log, sub, settings))
4312 case CAPSET_TYPE_SHARE:
4313 if (!rdp_read_share_capability_set(log, sub, settings))
4318 case CAPSET_TYPE_COLOR_CACHE:
4319 if (!rdp_read_color_cache_capability_set(log, sub, settings))
4324 case CAPSET_TYPE_FONT:
4325 if (!rdp_read_font_capability_set(log, sub, settings))
4330 case CAPSET_TYPE_DRAW_GDI_PLUS:
4331 if (!rdp_read_draw_gdiplus_cache_capability_set(log, sub, settings))
4336 case CAPSET_TYPE_RAIL:
4337 if (!rdp_read_remote_programs_capability_set(log, sub, settings))
4342 case CAPSET_TYPE_WINDOW:
4343 if (!rdp_read_window_list_capability_set(log, sub, settings))
4348 case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
4349 if (!rdp_read_multifragment_update_capability_set(log, sub, settings))
4354 case CAPSET_TYPE_LARGE_POINTER:
4355 if (!rdp_read_large_pointer_capability_set(log, sub, settings))
4360 case CAPSET_TYPE_COMP_DESK:
4361 if (!rdp_read_desktop_composition_capability_set(log, sub, settings))
4366 case CAPSET_TYPE_SURFACE_COMMANDS:
4367 if (!rdp_read_surface_commands_capability_set(log, sub, settings))
4372 case CAPSET_TYPE_BITMAP_CODECS:
4373 if (!rdp_read_bitmap_codecs_capability_set(log, sub, settings, isServer))
4378 case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
4379 if (!rdp_read_frame_acknowledge_capability_set(log, sub, settings))
4384 case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID:
4385 if (!rdp_read_bitmap_cache_v3_codec_id_capability_set(log, sub, settings))
4402 case CAPSET_TYPE_BITMAP_CACHE:
4403 if (!rdp_read_bitmap_cache_capability_set(log, sub, settings))
4408 case CAPSET_TYPE_BITMAP_CACHE_V2:
4409 if (!rdp_read_bitmap_cache_v2_capability_set(log, sub, settings))
4414 case CAPSET_TYPE_BRUSH:
4415 if (!rdp_read_brush_capability_set(log, sub, settings))
4420 case CAPSET_TYPE_GLYPH_CACHE:
4421 if (!rdp_read_glyph_cache_capability_set(log, sub, settings))
4426 case CAPSET_TYPE_OFFSCREEN_CACHE:
4427 if (!rdp_read_offscreen_bitmap_cache_capability_set(log, sub, settings))
4432 case CAPSET_TYPE_SOUND:
4433 if (!rdp_read_sound_capability_set(log, sub, settings))
4438 case CAPSET_TYPE_CONTROL:
4439 if (!rdp_read_control_capability_set(log, sub, settings))
4444 case CAPSET_TYPE_ACTIVATION:
4445 if (!rdp_read_window_activation_capability_set(log, sub, settings))
4450 case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
4451 if (!rdp_read_draw_nine_grid_cache_capability_set(log, sub, settings))
4457 WLog_Print(log, WLOG_ERROR,
4458 "capability %s(%" PRIu16
") not expected from client",
4459 get_capability_name(type), type);
4468 case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
4469 if (!rdp_read_bitmap_cache_host_support_capability_set(log, sub, settings))
4475 WLog_Print(log, WLOG_ERROR,
4476 "capability %s(%" PRIu16
") not expected from server",
4477 get_capability_name(type), type);
4483 const size_t rest = Stream_GetRemainingLength(sub);
4486 const size_t length = Stream_Capacity(sub);
4487 WLog_Print(log, WLOG_ERROR,
4488 "incorrect offset, type:0x%04" PRIx16
" actual:%" PRIuz
" expected:%" PRIuz
"",
4489 type, length - rest, length);
4494static BOOL rdp_read_capability_sets(wLog* log,
wStream* s, rdpSettings* settings,
4495 rdpSettings* rcvSettings, UINT16 totalLength)
4501 UINT16 numberCapabilities = 0;
4504#ifdef WITH_DEBUG_CAPABILITIES
4505 const size_t capstart = Stream_GetPosition(s);
4509 WINPR_ASSERT(settings);
4511 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
4514 Stream_Read_UINT16(s, numberCapabilities);
4516 count = numberCapabilities;
4518 start = Stream_GetPosition(s);
4519 while (numberCapabilities > 0 && Stream_GetRemainingLength(s) >= 4)
4526 if (!rdp_read_capability_set_header(log, s, &length, &type))
4528 sub = Stream_StaticInit(&subbuffer, Stream_Pointer(s), length - 4);
4529 if (!Stream_SafeSeek(s, length - 4))
4532 if (!rdp_read_capability_set(log, sub, type, rcvSettings, settings->ServerMode))
4535 if (!rdp_apply_from_received(type, settings, rcvSettings))
4537 numberCapabilities--;
4540 end = Stream_GetPosition(s);
4543 if (numberCapabilities)
4545 WLog_Print(log, WLOG_ERROR,
4546 "strange we haven't read the number of announced capacity sets, read=%d "
4547 "expected=%" PRIu16
"",
4548 count - numberCapabilities, count);
4551#ifdef WITH_DEBUG_CAPABILITIES
4552 rdp_print_capability_sets(log, s, capstart, TRUE);
4555 if (len > totalLength)
4557 WLog_Print(log, WLOG_ERROR,
"Capability length expected %" PRIu16
", actual %" PRIuz,
4561 rc = freerdp_capability_buffer_copy(settings, rcvSettings);
4566BOOL rdp_recv_get_active_header(rdpRdp* rdp,
wStream* s, UINT16* pChannelId, UINT16* length)
4569 WINPR_ASSERT(rdp->context);
4571 if (!rdp_read_header(rdp, s, length, pChannelId))
4574 if (freerdp_shall_disconnect_context(rdp->context))
4577 if (*pChannelId != MCS_GLOBAL_CHANNEL_ID)
4579 UINT16 mcsMessageChannelId = rdp->mcs->messageChannelId;
4581 if ((mcsMessageChannelId == 0) || (*pChannelId != mcsMessageChannelId))
4583 WLog_Print(rdp->log, WLOG_ERROR,
"unexpected MCS channel id %04" PRIx16
" received",
4592BOOL rdp_recv_demand_active(rdpRdp* rdp,
wStream* s, UINT16 pduSource, UINT16 length)
4594 UINT16 lengthSourceDescriptor = 0;
4595 UINT16 lengthCombinedCapabilities = 0;
4598 WINPR_ASSERT(rdp->settings);
4599 WINPR_ASSERT(rdp->context);
4602 rdp->settings->PduSource = pduSource;
4604 if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 8))
4607 Stream_Read_UINT32(s, rdp->settings->ShareId);
4608 Stream_Read_UINT16(s, lengthSourceDescriptor);
4609 Stream_Read_UINT16(s, lengthCombinedCapabilities);
4611 if (!Stream_SafeSeek(s, lengthSourceDescriptor) ||
4612 !Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 4))
4616 if (!rdp_read_capability_sets(rdp->log, s, rdp->settings, rdp->remoteSettings,
4617 lengthCombinedCapabilities))
4619 WLog_Print(rdp->log, WLOG_ERROR,
"rdp_read_capability_sets failed");
4623 if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 4))
4628 Stream_Seek_UINT32(s);
4632 secondary->glyph_v2 = (rdp->settings->GlyphSupportLevel > GLYPH_SUPPORT_FULL);
4635 return tpkt_ensure_stream_consumed(rdp->log, s, length);
4638static BOOL rdp_write_demand_active(wLog* log,
wStream* s, rdpSettings* settings)
4643 UINT16 numberCapabilities = 0;
4644 size_t lengthCombinedCapabilities = 0;
4646 if (!Stream_EnsureRemainingCapacity(s, 64))
4649 Stream_Write_UINT32(s, settings->ShareId);
4650 Stream_Write_UINT16(s, 4);
4651 lm = Stream_GetPosition(s);
4652 Stream_Seek_UINT16(s);
4653 Stream_Write(s,
"RDP", 4);
4654 bm = Stream_GetPosition(s);
4655 Stream_Seek_UINT16(s);
4656 Stream_Write_UINT16(s, 0);
4657 numberCapabilities = 14;
4659 if (!rdp_write_general_capability_set(log, s, settings) ||
4660 !rdp_write_bitmap_capability_set(log, s, settings) ||
4661 !rdp_write_order_capability_set(log, s, settings) ||
4662 !rdp_write_pointer_capability_set(log, s, settings) ||
4663 !rdp_write_input_capability_set(log, s, settings) ||
4664 !rdp_write_virtual_channel_capability_set(log, s, settings) ||
4665 !rdp_write_share_capability_set(log, s, settings) ||
4666 !rdp_write_font_capability_set(log, s, settings) ||
4667 !rdp_write_multifragment_update_capability_set(log, s, settings) ||
4668 !rdp_write_large_pointer_capability_set(log, s, settings) ||
4669 !rdp_write_desktop_composition_capability_set(log, s, settings) ||
4670 !rdp_write_surface_commands_capability_set(log, s, settings) ||
4671 !rdp_write_bitmap_codecs_capability_set(log, s, settings) ||
4672 !rdp_write_frame_acknowledge_capability_set(log, s, settings))
4679 numberCapabilities++;
4681 if (!rdp_write_bitmap_cache_host_support_capability_set(log, s, settings))
4685 if (settings->RemoteApplicationMode)
4687 numberCapabilities += 2;
4689 if (!rdp_write_remote_programs_capability_set(log, s, settings) ||
4690 !rdp_write_window_list_capability_set(log, s, settings))
4694 em = Stream_GetPosition(s);
4695 Stream_SetPosition(s, lm);
4696 lengthCombinedCapabilities = (em - bm);
4697 if (lengthCombinedCapabilities > UINT16_MAX)
4699 Stream_Write_UINT16(
4700 s, (UINT16)lengthCombinedCapabilities);
4701 Stream_SetPosition(s, bm);
4702 Stream_Write_UINT16(s, numberCapabilities);
4703#ifdef WITH_DEBUG_CAPABILITIES
4704 rdp_print_capability_sets(log, s, bm, FALSE);
4706 Stream_SetPosition(s, em);
4707 Stream_Write_UINT32(s, 0);
4711BOOL rdp_send_demand_active(rdpRdp* rdp)
4713 UINT16 sec_flags = 0;
4714 wStream* s = rdp_send_stream_pdu_init(rdp, &sec_flags);
4720 rdp->settings->ShareId = 0x10000 + rdp->mcs->userId;
4721 status = rdp_write_demand_active(rdp->log, s, rdp->settings) &&
4722 rdp_send_pdu(rdp, s, PDU_TYPE_DEMAND_ACTIVE, rdp->mcs->userId, sec_flags);
4727BOOL rdp_recv_confirm_active(rdpRdp* rdp,
wStream* s, UINT16 pduLength)
4729 rdpSettings* settings =
nullptr;
4730 UINT16 lengthSourceDescriptor = 0;
4731 UINT16 lengthCombinedCapabilities = 0;
4735 settings = rdp->settings;
4736 WINPR_ASSERT(settings);
4738 if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 10))
4741 Stream_Seek_UINT32(s);
4742 Stream_Seek_UINT16(s);
4743 Stream_Read_UINT16(s, lengthSourceDescriptor);
4744 Stream_Read_UINT16(s, lengthCombinedCapabilities);
4746 if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, lengthSourceDescriptor + 4U))
4749 Stream_Seek(s, lengthSourceDescriptor);
4750 if (!rdp_read_capability_sets(rdp->log, s, rdp->settings, rdp->remoteSettings,
4751 lengthCombinedCapabilities))
4754 if (!settings->ReceivedCapabilities[CAPSET_TYPE_SURFACE_COMMANDS])
4757 settings->SurfaceCommandsEnabled = FALSE;
4758 settings->SurfaceFrameMarkerEnabled = FALSE;
4761 if (!settings->ReceivedCapabilities[CAPSET_TYPE_FRAME_ACKNOWLEDGE])
4764 settings->FrameAcknowledge = 0;
4767 if (!settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID])
4770 settings->BitmapCacheV3Enabled = FALSE;
4773 if (!settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CODECS])
4784 if (!settings->ReceivedCapabilities[CAPSET_TYPE_MULTI_FRAGMENT_UPDATE])
4787 settings->MultifragMaxRequestSize = FASTPATH_FRAGMENT_SAFE_SIZE;
4790 if (!settings->ReceivedCapabilities[CAPSET_TYPE_LARGE_POINTER])
4793 settings->LargePointerFlag = 0;
4796 return tpkt_ensure_stream_consumed(rdp->log, s, pduLength);
4799static BOOL rdp_write_confirm_active(wLog* log,
wStream* s, rdpSettings* settings)
4804 UINT16 numberCapabilities = 0;
4805 UINT16 lengthSourceDescriptor = 0;
4806 size_t lengthCombinedCapabilities = 0;
4809 WINPR_ASSERT(settings);
4811 lengthSourceDescriptor =
sizeof(SOURCE_DESCRIPTOR);
4812 Stream_Write_UINT32(s, settings->ShareId);
4813 Stream_Write_UINT16(s, 0x03EA);
4814 Stream_Write_UINT16(s, lengthSourceDescriptor);
4815 lm = Stream_GetPosition(s);
4816 Stream_Seek_UINT16(s);
4817 Stream_Write(s, SOURCE_DESCRIPTOR, lengthSourceDescriptor);
4818 bm = Stream_GetPosition(s);
4819 Stream_Seek_UINT16(s);
4820 Stream_Write_UINT16(s, 0);
4822 numberCapabilities = 15;
4824 if (!rdp_write_general_capability_set(log, s, settings) ||
4825 !rdp_write_bitmap_capability_set(log, s, settings) ||
4826 !rdp_write_order_capability_set(log, s, settings))
4829 if (settings->RdpVersion >= RDP_VERSION_5_PLUS)
4830 ret = rdp_write_bitmap_cache_v2_capability_set(log, s, settings);
4832 ret = rdp_write_bitmap_cache_capability_set(log, s, settings);
4837 if (!rdp_write_pointer_capability_set(log, s, settings) ||
4838 !rdp_write_input_capability_set(log, s, settings) ||
4839 !rdp_write_brush_capability_set(log, s, settings) ||
4840 !rdp_write_glyph_cache_capability_set(log, s, settings) ||
4841 !rdp_write_virtual_channel_capability_set(log, s, settings) ||
4842 !rdp_write_sound_capability_set(log, s, settings) ||
4843 !rdp_write_share_capability_set(log, s, settings) ||
4844 !rdp_write_font_capability_set(log, s, settings) ||
4845 !rdp_write_control_capability_set(log, s, settings) ||
4846 !rdp_write_color_cache_capability_set(log, s, settings) ||
4847 !rdp_write_window_activation_capability_set(log, s, settings))
4853 numberCapabilities++;
4855 if (!rdp_write_offscreen_bitmap_cache_capability_set(log, s, settings))
4859 if (settings->DrawNineGridEnabled)
4861 numberCapabilities++;
4863 if (!rdp_write_draw_nine_grid_cache_capability_set(log, s, settings))
4867 if (settings->ReceivedCapabilities[CAPSET_TYPE_LARGE_POINTER])
4869 if (settings->LargePointerFlag)
4871 numberCapabilities++;
4873 if (!rdp_write_large_pointer_capability_set(log, s, settings))
4878 if (settings->RemoteApplicationMode)
4880 numberCapabilities += 2;
4882 if (!rdp_write_remote_programs_capability_set(log, s, settings) ||
4883 !rdp_write_window_list_capability_set(log, s, settings))
4887 if (settings->ReceivedCapabilities[CAPSET_TYPE_MULTI_FRAGMENT_UPDATE])
4889 numberCapabilities++;
4891 if (!rdp_write_multifragment_update_capability_set(log, s, settings))
4895 if (settings->ReceivedCapabilities[CAPSET_TYPE_SURFACE_COMMANDS])
4897 numberCapabilities++;
4899 if (!rdp_write_surface_commands_capability_set(log, s, settings))
4903 if (settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CODECS])
4905 numberCapabilities++;
4907 if (!rdp_write_bitmap_codecs_capability_set(log, s, settings))
4911 if (!settings->ReceivedCapabilities[CAPSET_TYPE_FRAME_ACKNOWLEDGE])
4912 settings->FrameAcknowledge = 0;
4914 if (settings->FrameAcknowledge)
4916 numberCapabilities++;
4918 if (!rdp_write_frame_acknowledge_capability_set(log, s, settings))
4922 if (settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID])
4924 if (settings->BitmapCacheV3CodecId != 0)
4926 numberCapabilities++;
4928 if (!rdp_write_bitmap_cache_v3_codec_id_capability_set(log, s, settings))
4933 em = Stream_GetPosition(s);
4934 Stream_SetPosition(s, lm);
4935 lengthCombinedCapabilities = (em - bm);
4936 if (lengthCombinedCapabilities > UINT16_MAX)
4938 Stream_Write_UINT16(
4939 s, (UINT16)lengthCombinedCapabilities);
4940 Stream_SetPosition(s, bm);
4941 Stream_Write_UINT16(s, numberCapabilities);
4942#ifdef WITH_DEBUG_CAPABILITIES
4943 rdp_print_capability_sets(log, s, bm, FALSE);
4945 Stream_SetPosition(s, em);
4950BOOL rdp_send_confirm_active(rdpRdp* rdp)
4952 UINT16 sec_flags = 0;
4953 wStream* s = rdp_send_stream_pdu_init(rdp, &sec_flags);
4959 status = rdp_write_confirm_active(rdp->log, s, rdp->settings) &&
4960 rdp_send_pdu(rdp, s, PDU_TYPE_CONFIRM_ACTIVE, rdp->mcs->userId, sec_flags);
4965const char* rdp_input_flag_string(UINT16 flags,
char* buffer,
size_t len)
4967 char prefix[16] = WINPR_C_ARRAY_INIT;
4969 (void)_snprintf(prefix,
sizeof(prefix),
"[0x%04" PRIx16
"][", flags);
4970 winpr_str_append(prefix, buffer, len,
"");
4971 if ((flags & INPUT_FLAG_SCANCODES) != 0)
4972 winpr_str_append(
"INPUT_FLAG_SCANCODES", buffer, len,
"|");
4973 if ((flags & INPUT_FLAG_MOUSEX) != 0)
4974 winpr_str_append(
"INPUT_FLAG_MOUSEX", buffer, len,
"|");
4975 if ((flags & INPUT_FLAG_FASTPATH_INPUT) != 0)
4976 winpr_str_append(
"INPUT_FLAG_FASTPATH_INPUT", buffer, len,
"|");
4977 if ((flags & INPUT_FLAG_UNICODE) != 0)
4978 winpr_str_append(
"INPUT_FLAG_UNICODE", buffer, len,
"|");
4979 if ((flags & INPUT_FLAG_FASTPATH_INPUT2) != 0)
4980 winpr_str_append(
"INPUT_FLAG_FASTPATH_INPUT2", buffer, len,
"|");
4981 if ((flags & INPUT_FLAG_UNUSED1) != 0)
4982 winpr_str_append(
"INPUT_FLAG_UNUSED1", buffer, len,
"|");
4983 if ((flags & INPUT_FLAG_MOUSE_RELATIVE) != 0)
4984 winpr_str_append(
"INPUT_FLAG_MOUSE_RELATIVE", buffer, len,
"|");
4985 if ((flags & TS_INPUT_FLAG_MOUSE_HWHEEL) != 0)
4986 winpr_str_append(
"TS_INPUT_FLAG_MOUSE_HWHEEL", buffer, len,
"|");
4987 if ((flags & TS_INPUT_FLAG_QOE_TIMESTAMPS) != 0)
4988 winpr_str_append(
"TS_INPUT_FLAG_QOE_TIMESTAMPS", buffer, len,
"|");
4989 winpr_str_append(
"]", buffer, len,
"");
FREERDP_API BOOL freerdp_settings_set_uint32(rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id, UINT32 val)
Sets a UINT32 settings value.
FREERDP_API BOOL freerdp_settings_set_bool(rdpSettings *settings, FreeRDP_Settings_Keys_Bool id, BOOL val)
Sets a BOOL settings value.
WINPR_ATTR_NODISCARD FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.
FREERDP_API BOOL freerdp_settings_set_pointer_len(rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id, const void *data, size_t len)
Set a pointer to value data.
WINPR_ATTR_NODISCARD FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.
FREERDP_API BOOL freerdp_settings_set_string_len(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const char *val, size_t len)
Sets a string settings value. The val is copied.
FREERDP_API BOOL freerdp_settings_set_string(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const char *val)
Sets a string settings value. The param is copied.