20#include <winpr/wtsapi.h>
21#include <winpr/assert.h>
22#include <winpr/cast.h>
23#include <freerdp/config.h>
26#include "capabilities.h"
32#include <freerdp/log.h>
34static const char*
const CAPSET_TYPE_STRINGS[] = {
"Unknown",
51 "Offscreen Bitmap Cache",
52 "Bitmap Cache Host Support",
59 "Desktop Composition",
60 "Multifragment Update",
64 "Frame Acknowledge" };
66static const char* get_capability_name(UINT16 type)
68 if (type > CAPSET_TYPE_FRAME_ACKNOWLEDGE)
71 return CAPSET_TYPE_STRINGS[type];
74#ifdef WITH_DEBUG_CAPABILITIES
75static BOOL rdp_print_capability_sets(wLog* log,
wStream* s,
size_t start, BOOL receiving);
80static const GUID CODEC_GUID_REMOTEFX = {
81 0x76772F12, 0xBD72, 0x4463, { 0xAF, 0xB3, 0xB7, 0x3C, 0x9C, 0x6F, 0x78, 0x86 }
86static const GUID CODEC_GUID_NSCODEC = {
87 0xCA8D1BB9, 0x000F, 0x154F, { 0x58, 0x9F, 0xAE, 0x2D, 0x1A, 0x87, 0xE2, 0xD6 }
92static const GUID CODEC_GUID_IGNORE = {
93 0x9C4351A6, 0x3535, 0x42AE, { 0x91, 0x0C, 0xCD, 0xFC, 0xE5, 0x76, 0x0B, 0x58 }
98static const GUID CODEC_GUID_IMAGE_REMOTEFX = {
99 0x2744CCD4, 0x9D8A, 0x4E74, { 0x80, 0x3C, 0x0E, 0xCB, 0xEE, 0xA1, 0x9C, 0x54 }
102#if defined(WITH_JPEG)
105static const GUID CODEC_GUID_JPEG = {
106 0x430C9EED, 0x1BAF, 0x4CE6, { 0x86, 0x9A, 0xCB, 0x8B, 0x37, 0xB6, 0x62, 0x37 }
110static BOOL rdp_read_capability_set_header(wLog* log,
wStream* s, UINT16* length, UINT16* type)
113 WINPR_ASSERT(length);
116 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
118 Stream_Read_UINT16(s, *type);
119 Stream_Read_UINT16(s, *length);
120 return (*length >= 4);
123static void rdp_write_capability_set_header(
wStream* s, UINT16 length, UINT16 type)
126 WINPR_ASSERT(Stream_GetRemainingCapacity(s) >= 4);
127 Stream_Write_UINT16(s, type);
128 Stream_Write_UINT16(s, length);
131static size_t rdp_capability_set_start(wLog* log,
wStream* s)
133 size_t header = Stream_GetPosition(s);
134 if (!Stream_CheckAndLogRequiredCapacityWLog(log, (s), CAPSET_HEADER_LENGTH))
136 Stream_Zero(s, CAPSET_HEADER_LENGTH);
140static BOOL rdp_capability_set_finish(
wStream* s,
size_t header, UINT16 type)
142 const size_t footer = Stream_GetPosition(s);
145 if (header > UINT16_MAX)
147 const size_t length = footer - header;
148 if ((Stream_Capacity(s) < header + 4ULL) || (length > UINT16_MAX))
150 if (!Stream_SetPosition(s, header))
152 rdp_write_capability_set_header(s, (UINT16)length, type);
153 return Stream_SetPosition(s, footer);
156static BOOL rdp_apply_general_capability_set(rdpSettings* settings,
const rdpSettings* src)
158 WINPR_ASSERT(settings);
161 if (settings->ServerMode)
163 settings->OsMajorType = src->OsMajorType;
164 settings->OsMinorType = src->OsMinorType;
167 settings->CapsProtocolVersion = src->CapsProtocolVersion;
168 settings->NoBitmapCompressionHeader = src->NoBitmapCompressionHeader;
169 settings->LongCredentialsSupported = src->LongCredentialsSupported;
170 settings->AutoReconnectionPacketSupported = src->AutoReconnectionPacketSupported;
171 if (!src->FastPathOutput)
172 settings->FastPathOutput = FALSE;
174 if (!src->SaltedChecksum)
175 settings->SaltedChecksum = FALSE;
177 if (!settings->ServerMode)
184 if (!src->RefreshRect)
185 settings->RefreshRect = FALSE;
187 if (!src->SuppressOutput)
188 settings->SuppressOutput = FALSE;
198static BOOL rdp_read_general_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
200 UINT16 extraFlags = 0;
201 BYTE refreshRectSupport = 0;
202 BYTE suppressOutputSupport = 0;
204 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 20))
207 WINPR_ASSERT(settings);
208 Stream_Read_UINT16(s, settings->OsMajorType);
209 Stream_Read_UINT16(s, settings->OsMinorType);
211 Stream_Read_UINT16(s, settings->CapsProtocolVersion);
212 if (settings->CapsProtocolVersion != TS_CAPS_PROTOCOLVERSION)
214 WLog_Print(log, WLOG_ERROR,
215 "TS_GENERAL_CAPABILITYSET::protocolVersion(0x%04" PRIx16
216 ") != TS_CAPS_PROTOCOLVERSION(0x%04" PRIx32
")",
217 settings->CapsProtocolVersion,
218 WINPR_CXX_COMPAT_CAST(UINT32, TS_CAPS_PROTOCOLVERSION));
219 if (settings->CapsProtocolVersion == 0x0000)
221 WLog_Print(log, WLOG_WARN,
222 "TS_GENERAL_CAPABILITYSET::protocolVersion(0x%04" PRIx16
223 " assuming old FreeRDP, ignoring protocol violation, correcting value.",
224 settings->CapsProtocolVersion);
225 settings->CapsProtocolVersion = TS_CAPS_PROTOCOLVERSION;
230 Stream_Seek_UINT16(s);
232 s, settings->CapsGeneralCompressionTypes);
233 Stream_Read_UINT16(s, extraFlags);
234 Stream_Read_UINT16(s, settings->CapsUpdateCapabilityFlag);
235 Stream_Read_UINT16(s, settings->CapsRemoteUnshareFlag);
237 s, settings->CapsGeneralCompressionLevel);
238 Stream_Read_UINT8(s, refreshRectSupport);
239 Stream_Read_UINT8(s, suppressOutputSupport);
240 settings->NoBitmapCompressionHeader = (extraFlags & NO_BITMAP_COMPRESSION_HDR) != 0;
241 settings->LongCredentialsSupported = (extraFlags & LONG_CREDENTIALS_SUPPORTED) != 0;
243 settings->AutoReconnectionPacketSupported = (extraFlags & AUTORECONNECT_SUPPORTED) != 0;
244 settings->FastPathOutput = (extraFlags & FASTPATH_OUTPUT_SUPPORTED) != 0;
245 settings->SaltedChecksum = (extraFlags & ENC_SALTED_CHECKSUM) != 0;
246 settings->RefreshRect = refreshRectSupport;
247 settings->SuppressOutput = suppressOutputSupport;
257static BOOL rdp_write_general_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
259 if (!Stream_EnsureRemainingCapacity(s, 64))
262 const size_t header = rdp_capability_set_start(log, s);
263 UINT16 extraFlags = 0;
265 WINPR_ASSERT(settings);
266 if (settings->LongCredentialsSupported)
267 extraFlags |= LONG_CREDENTIALS_SUPPORTED;
269 if (settings->NoBitmapCompressionHeader)
270 extraFlags |= NO_BITMAP_COMPRESSION_HDR;
272 if (settings->AutoReconnectionPacketSupported)
273 extraFlags |= AUTORECONNECT_SUPPORTED;
275 if (settings->FastPathOutput)
276 extraFlags |= FASTPATH_OUTPUT_SUPPORTED;
278 if (settings->SaltedChecksum)
279 extraFlags |= ENC_SALTED_CHECKSUM;
281 if ((settings->OsMajorType > UINT16_MAX) || (settings->OsMinorType > UINT16_MAX))
283 WLog_Print(log, WLOG_ERROR,
284 "OsMajorType=%08" PRIx32
", OsMinorType=%08" PRIx32
285 " they need to be smaller %04" PRIx32,
286 settings->OsMajorType, settings->OsMinorType,
287 WINPR_CXX_COMPAT_CAST(UINT32, UINT16_MAX));
290 if (settings->CapsProtocolVersion != TS_CAPS_PROTOCOLVERSION)
292 WLog_Print(log, WLOG_ERROR,
293 "TS_GENERAL_CAPABILITYSET::protocolVersion(0x%04" PRIx16
294 ") != TS_CAPS_PROTOCOLVERSION(0x%04" PRIx32
")",
295 settings->CapsProtocolVersion,
296 WINPR_CXX_COMPAT_CAST(UINT32, TS_CAPS_PROTOCOLVERSION));
299 Stream_Write_UINT16(s, (UINT16)settings->OsMajorType);
300 Stream_Write_UINT16(s, (UINT16)settings->OsMinorType);
301 Stream_Write_UINT16(s, settings->CapsProtocolVersion);
302 Stream_Write_UINT16(s, 0);
304 s, settings->CapsGeneralCompressionTypes);
305 Stream_Write_UINT16(s, extraFlags);
306 Stream_Write_UINT16(s, settings->CapsUpdateCapabilityFlag);
307 Stream_Write_UINT16(s, settings->CapsRemoteUnshareFlag);
309 s, settings->CapsGeneralCompressionLevel);
310 Stream_Write_UINT8(s, settings->RefreshRect ? 1 : 0);
311 Stream_Write_UINT8(s, settings->SuppressOutput ? 1 : 0);
312 return rdp_capability_set_finish(s, header, CAPSET_TYPE_GENERAL);
315#ifdef WITH_DEBUG_CAPABILITIES
316static BOOL rdp_print_general_capability_set(wLog* log,
wStream* s)
318 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 20))
321 WLog_Print(log, WLOG_TRACE,
322 "GeneralCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
323 const uint16_t osMinorType = Stream_Get_UINT16(s);
324 const uint16_t osMajorType = Stream_Get_UINT16(s);
325 const uint16_t protocolVersion = Stream_Get_UINT16(s);
326 const uint16_t pad2OctetsA = Stream_Get_UINT16(s);
327 const uint16_t generalCompressionTypes =
328 Stream_Get_UINT16(s);
329 const uint16_t extraFlags = Stream_Get_UINT16(s);
330 const uint16_t updateCapabilityFlag = Stream_Get_UINT16(s);
331 const uint16_t remoteUnshareFlag = Stream_Get_UINT16(s);
332 const uint16_t generalCompressionLevel =
333 Stream_Get_UINT16(s);
334 const uint8_t refreshRectSupport = Stream_Get_UINT8(s);
335 const uint8_t suppressOutputSupport = Stream_Get_UINT8(s);
336 WLog_Print(log, WLOG_TRACE,
"\tosMajorType: 0x%04" PRIX16
"", osMajorType);
337 WLog_Print(log, WLOG_TRACE,
"\tosMinorType: 0x%04" PRIX16
"", osMinorType);
338 WLog_Print(log, WLOG_TRACE,
"\tprotocolVersion: 0x%04" PRIX16
"", protocolVersion);
339 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
340 WLog_Print(log, WLOG_TRACE,
"\tgeneralCompressionTypes: 0x%04" PRIX16
"",
341 generalCompressionTypes);
342 WLog_Print(log, WLOG_TRACE,
"\textraFlags: 0x%04" PRIX16
"", extraFlags);
343 WLog_Print(log, WLOG_TRACE,
"\tupdateCapabilityFlag: 0x%04" PRIX16
"", updateCapabilityFlag);
344 WLog_Print(log, WLOG_TRACE,
"\tremoteUnshareFlag: 0x%04" PRIX16
"", remoteUnshareFlag);
345 WLog_Print(log, WLOG_TRACE,
"\tgeneralCompressionLevel: 0x%04" PRIX16
"",
346 generalCompressionLevel);
347 WLog_Print(log, WLOG_TRACE,
"\trefreshRectSupport: 0x%02" PRIX8
"", refreshRectSupport);
348 WLog_Print(log, WLOG_TRACE,
"\tsuppressOutputSupport: 0x%02" PRIX8
"", suppressOutputSupport);
352static BOOL rdp_apply_bitmap_capability_set(rdpSettings* settings,
const rdpSettings* src)
354 WINPR_ASSERT(settings);
357 if (!settings->ServerMode)
364 if (!src->DesktopResize)
365 settings->DesktopResize = FALSE;
367 if (!settings->ServerMode && settings->DesktopResize)
371 settings->DesktopWidth = src->DesktopWidth;
372 settings->DesktopHeight = src->DesktopHeight;
375 if (settings->DrawAllowSkipAlpha)
376 settings->DrawAllowSkipAlpha = src->DrawAllowSkipAlpha;
378 if (settings->DrawAllowDynamicColorFidelity)
379 settings->DrawAllowDynamicColorFidelity = src->DrawAllowDynamicColorFidelity;
381 if (settings->DrawAllowColorSubsampling)
382 settings->DrawAllowColorSubsampling = src->DrawAllowColorSubsampling;
392static BOOL rdp_read_bitmap_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
394 BYTE drawingFlags = 0;
395 UINT16 desktopWidth = 0;
396 UINT16 desktopHeight = 0;
397 UINT16 desktopResizeFlag = 0;
398 UINT16 preferredBitsPerPixel = 0;
400 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 24))
403 Stream_Read_UINT16(s, preferredBitsPerPixel);
404 Stream_Seek_UINT16(s);
405 Stream_Seek_UINT16(s);
406 Stream_Seek_UINT16(s);
407 Stream_Read_UINT16(s, desktopWidth);
408 Stream_Read_UINT16(s, desktopHeight);
409 Stream_Seek_UINT16(s);
410 Stream_Read_UINT16(s, desktopResizeFlag);
411 Stream_Seek_UINT16(s);
412 Stream_Seek_UINT8(s);
413 Stream_Read_UINT8(s, drawingFlags);
414 Stream_Seek_UINT16(s);
415 Stream_Seek_UINT16(s);
419 settings->DesktopResize = desktopResizeFlag;
420 settings->DesktopWidth = desktopWidth;
421 settings->DesktopHeight = desktopHeight;
422 settings->DrawAllowSkipAlpha = (drawingFlags & DRAW_ALLOW_SKIP_ALPHA) != 0;
423 settings->DrawAllowDynamicColorFidelity =
424 (drawingFlags & DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY) != 0;
425 settings->DrawAllowColorSubsampling = (drawingFlags & DRAW_ALLOW_COLOR_SUBSAMPLING) != 0;
435static BOOL rdp_write_bitmap_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
437 BYTE drawingFlags = 0;
438 UINT16 preferredBitsPerPixel = 0;
440 if (!Stream_EnsureRemainingCapacity(s, 64))
443 const size_t header = rdp_capability_set_start(log, s);
445 WINPR_ASSERT(settings);
446 if (settings->DrawAllowSkipAlpha)
447 drawingFlags |= DRAW_ALLOW_SKIP_ALPHA;
449 if (settings->DrawAllowDynamicColorFidelity)
450 drawingFlags |= DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY;
452 if (settings->DrawAllowColorSubsampling)
453 drawingFlags |= DRAW_ALLOW_COLOR_SUBSAMPLING;
465 (settings->DesktopWidth > UINT16_MAX) || (settings->DesktopHeight > UINT16_MAX))
468 if (settings->RdpVersion >= RDP_VERSION_5_PLUS)
471 preferredBitsPerPixel = 8;
473 Stream_Write_UINT16(s, preferredBitsPerPixel);
474 Stream_Write_UINT16(s, 1);
475 Stream_Write_UINT16(s, 1);
476 Stream_Write_UINT16(s, 1);
477 Stream_Write_UINT16(s, (UINT16)settings->DesktopWidth);
478 Stream_Write_UINT16(s, (UINT16)settings->DesktopHeight);
479 Stream_Write_UINT16(s, 0);
480 Stream_Write_UINT16(s, (UINT16)settings->DesktopResize);
481 Stream_Write_UINT16(s, 1);
482 Stream_Write_UINT8(s, 0);
483 Stream_Write_UINT8(s, drawingFlags);
484 Stream_Write_UINT16(s, 1);
485 Stream_Write_UINT16(s, 0);
486 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP);
489#ifdef WITH_DEBUG_CAPABILITIES
490static BOOL rdp_print_bitmap_capability_set(wLog* log,
wStream* s)
492 UINT16 preferredBitsPerPixel = 0;
493 UINT16 receive1BitPerPixel = 0;
494 UINT16 receive4BitsPerPixel = 0;
495 UINT16 receive8BitsPerPixel = 0;
496 UINT16 desktopWidth = 0;
497 UINT16 desktopHeight = 0;
498 UINT16 pad2Octets = 0;
499 UINT16 desktopResizeFlag = 0;
500 UINT16 bitmapCompressionFlag = 0;
501 BYTE highColorFlags = 0;
502 BYTE drawingFlags = 0;
503 UINT16 multipleRectangleSupport = 0;
504 UINT16 pad2OctetsB = 0;
505 WLog_Print(log, WLOG_TRACE,
506 "BitmapCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
508 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 24))
511 Stream_Read_UINT16(s, preferredBitsPerPixel);
512 Stream_Read_UINT16(s, receive1BitPerPixel);
513 Stream_Read_UINT16(s, receive4BitsPerPixel);
514 Stream_Read_UINT16(s, receive8BitsPerPixel);
515 Stream_Read_UINT16(s, desktopWidth);
516 Stream_Read_UINT16(s, desktopHeight);
517 Stream_Read_UINT16(s, pad2Octets);
518 Stream_Read_UINT16(s, desktopResizeFlag);
519 Stream_Read_UINT16(s, bitmapCompressionFlag);
520 Stream_Read_UINT8(s, highColorFlags);
521 Stream_Read_UINT8(s, drawingFlags);
522 Stream_Read_UINT16(s, multipleRectangleSupport);
523 Stream_Read_UINT16(s, pad2OctetsB);
524 WLog_Print(log, WLOG_TRACE,
"\tpreferredBitsPerPixel: 0x%04" PRIX16
"", preferredBitsPerPixel);
525 WLog_Print(log, WLOG_TRACE,
"\treceive1BitPerPixel: 0x%04" PRIX16
"", receive1BitPerPixel);
526 WLog_Print(log, WLOG_TRACE,
"\treceive4BitsPerPixel: 0x%04" PRIX16
"", receive4BitsPerPixel);
527 WLog_Print(log, WLOG_TRACE,
"\treceive8BitsPerPixel: 0x%04" PRIX16
"", receive8BitsPerPixel);
528 WLog_Print(log, WLOG_TRACE,
"\tdesktopWidth: 0x%04" PRIX16
"", desktopWidth);
529 WLog_Print(log, WLOG_TRACE,
"\tdesktopHeight: 0x%04" PRIX16
"", desktopHeight);
530 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
531 WLog_Print(log, WLOG_TRACE,
"\tdesktopResizeFlag: 0x%04" PRIX16
"", desktopResizeFlag);
532 WLog_Print(log, WLOG_TRACE,
"\tbitmapCompressionFlag: 0x%04" PRIX16
"", bitmapCompressionFlag);
533 WLog_Print(log, WLOG_TRACE,
"\thighColorFlags: 0x%02" PRIX8
"", highColorFlags);
534 WLog_Print(log, WLOG_TRACE,
"\tdrawingFlags: 0x%02" PRIX8
"", drawingFlags);
535 WLog_Print(log, WLOG_TRACE,
"\tmultipleRectangleSupport: 0x%04" PRIX16
"",
536 multipleRectangleSupport);
537 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsB: 0x%04" PRIX16
"", pad2OctetsB);
541static BOOL rdp_apply_order_capability_set(rdpSettings* settings,
const rdpSettings* src)
543 WINPR_ASSERT(settings);
546 BOOL BitmapCacheV3Enabled = FALSE;
547 BOOL FrameMarkerCommandEnabled = FALSE;
549 for (
size_t i = 0; i < 32; i++)
551 if (!src->OrderSupport[i])
552 settings->OrderSupport[i] = FALSE;
555 if (src->OrderSupportFlags & ORDER_FLAGS_EXTRA_SUPPORT)
557 if (src->OrderSupportFlagsEx & CACHE_BITMAP_V3_SUPPORT)
558 BitmapCacheV3Enabled = TRUE;
560 if (src->OrderSupportFlagsEx & ALTSEC_FRAME_MARKER_SUPPORT)
561 FrameMarkerCommandEnabled = TRUE;
564 if (BitmapCacheV3Enabled && settings->BitmapCacheV3Enabled)
566 settings->BitmapCacheV3Enabled = src->BitmapCacheV3Enabled;
567 settings->BitmapCacheVersion = src->BitmapCacheVersion;
570 settings->BitmapCacheV3Enabled = FALSE;
572 settings->FrameMarkerCommandEnabled =
573 (FrameMarkerCommandEnabled && src->FrameMarkerCommandEnabled);
583static BOOL rdp_read_order_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
585 char terminalDescriptor[17] = WINPR_C_ARRAY_INIT;
586 BYTE orderSupport[32] = WINPR_C_ARRAY_INIT;
587 BOOL BitmapCacheV3Enabled = FALSE;
588 BOOL FrameMarkerCommandEnabled = FALSE;
590 WINPR_ASSERT(settings);
591 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 84))
594 Stream_Read(s, terminalDescriptor, 16);
595 Stream_Seek_UINT32(s);
596 Stream_Seek_UINT16(s);
597 Stream_Seek_UINT16(s);
598 Stream_Seek_UINT16(s);
599 Stream_Seek_UINT16(s);
600 Stream_Seek_UINT16(s);
601 Stream_Read_UINT16(s, settings->OrderSupportFlags);
602 Stream_Read(s, orderSupport, 32);
603 Stream_Seek_UINT16(s);
604 Stream_Read_UINT16(s, settings->OrderSupportFlagsEx);
605 Stream_Seek_UINT32(s);
606 Stream_Seek_UINT32(s);
607 Stream_Seek_UINT16(s);
608 Stream_Seek_UINT16(s);
609 Stream_Read_UINT16(s, settings->TextANSICodePage);
610 Stream_Seek_UINT16(s);
615 for (
size_t i = 0; i < ARRAYSIZE(orderSupport); i++)
616 settings->OrderSupport[i] = orderSupport[i];
618 if (settings->OrderSupportFlags & ORDER_FLAGS_EXTRA_SUPPORT)
620 BitmapCacheV3Enabled = (settings->OrderSupportFlagsEx & CACHE_BITMAP_V3_SUPPORT) != 0;
621 FrameMarkerCommandEnabled =
622 (settings->OrderSupportFlagsEx & ALTSEC_FRAME_MARKER_SUPPORT) != 0;
625 settings->BitmapCacheV3Enabled = BitmapCacheV3Enabled;
626 if (BitmapCacheV3Enabled)
627 settings->BitmapCacheVersion = 3;
629 settings->FrameMarkerCommandEnabled = FrameMarkerCommandEnabled;
639static BOOL rdp_write_order_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
641 char terminalDescriptor[16] = WINPR_C_ARRAY_INIT;
643 WINPR_ASSERT(settings);
644 if (!Stream_EnsureRemainingCapacity(s, 64))
647 const size_t header = rdp_capability_set_start(log, s);
649 UINT16 orderSupportExFlags = settings->OrderSupportFlagsEx;
650 UINT16 orderFlags = settings->OrderSupportFlags;
652 if (settings->BitmapCacheV3Enabled)
654 if ((orderSupportExFlags & CACHE_BITMAP_V3_SUPPORT) == 0)
656 WLog_Print(log, WLOG_WARN,
657 "rdpSettings::BitmapCacheV3Enabled=TRUE, but CACHE_BITMAP_V3_SUPPORT not "
658 "set in rdpSettings::OrderSupportEx, aborting.");
660 if ((orderFlags & ORDER_FLAGS_EXTRA_SUPPORT) == 0)
662 WLog_Print(log, WLOG_WARN,
663 "rdpSettings::BitmapCacheV3Enabled=TRUE, but ORDER_FLAGS_EXTRA_SUPPORT not "
664 "set in rdpSettings::OrderSupport, aborting.");
668 if (settings->FrameMarkerCommandEnabled)
670 if ((orderSupportExFlags & ALTSEC_FRAME_MARKER_SUPPORT) == 0)
674 "rdpSettings::FrameMarkerCommandEnabled=TRUE, but "
675 "ALTSEC_FRAME_MARKER_SUPPORT not set in rdpSettings::OrderSupportEx, aborting.");
677 if ((orderFlags & ORDER_FLAGS_EXTRA_SUPPORT) == 0)
679 WLog_Print(log, WLOG_WARN,
680 "rdpSettings::FrameMarkerCommandEnabled=TRUE, but ORDER_FLAGS_EXTRA_SUPPORT "
681 "not set in rdpSettings::OrderSupport, aborting.");
688 const size_t len = strnlen(dsc, ARRAYSIZE(terminalDescriptor));
689 strncpy(terminalDescriptor, dsc, len);
691 Stream_Write(s, terminalDescriptor,
692 sizeof(terminalDescriptor));
693 Stream_Write_UINT32(s, 0);
694 Stream_Write_UINT16(s, 1);
695 Stream_Write_UINT16(s, 20);
696 Stream_Write_UINT16(s, 0);
697 Stream_Write_UINT16(s, 1);
698 Stream_Write_UINT16(s, 0);
699 Stream_Write_UINT16(s, orderFlags);
700 Stream_Write(s, settings->OrderSupport, 32);
701 Stream_Write_UINT16(s, 0);
702 Stream_Write_UINT16(s, orderSupportExFlags);
703 Stream_Write_UINT32(s, 0);
704 Stream_Write_UINT32(s, 230400);
705 Stream_Write_UINT16(s, 0);
706 Stream_Write_UINT16(s, 0);
707 Stream_Write_UINT16(s, settings->TextANSICodePage);
708 Stream_Write_UINT16(s, 0);
709 return rdp_capability_set_finish(s, header, CAPSET_TYPE_ORDER);
712#ifdef WITH_DEBUG_CAPABILITIES
713static BOOL rdp_print_order_capability_set(wLog* log,
wStream* s)
715 BYTE terminalDescriptor[16];
716 UINT32 pad4OctetsA = 0;
717 UINT16 desktopSaveXGranularity = 0;
718 UINT16 desktopSaveYGranularity = 0;
719 UINT16 pad2OctetsA = 0;
720 UINT16 maximumOrderLevel = 0;
721 UINT16 numberFonts = 0;
722 UINT16 orderFlags = 0;
723 BYTE orderSupport[32];
724 UINT16 textFlags = 0;
725 UINT16 orderSupportExFlags = 0;
726 UINT32 pad4OctetsB = 0;
727 UINT32 desktopSaveSize = 0;
728 UINT16 pad2OctetsC = 0;
729 UINT16 pad2OctetsD = 0;
730 UINT16 textANSICodePage = 0;
731 UINT16 pad2OctetsE = 0;
732 WLog_Print(log, WLOG_TRACE,
733 "OrderCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
735 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 84))
738 Stream_Read(s, terminalDescriptor, 16);
739 Stream_Read_UINT32(s, pad4OctetsA);
740 Stream_Read_UINT16(s, desktopSaveXGranularity);
741 Stream_Read_UINT16(s, desktopSaveYGranularity);
742 Stream_Read_UINT16(s, pad2OctetsA);
743 Stream_Read_UINT16(s, maximumOrderLevel);
744 Stream_Read_UINT16(s, numberFonts);
745 Stream_Read_UINT16(s, orderFlags);
746 Stream_Read(s, orderSupport, 32);
747 Stream_Read_UINT16(s, textFlags);
748 Stream_Read_UINT16(s, orderSupportExFlags);
749 Stream_Read_UINT32(s, pad4OctetsB);
750 Stream_Read_UINT32(s, desktopSaveSize);
751 Stream_Read_UINT16(s, pad2OctetsC);
752 Stream_Read_UINT16(s, pad2OctetsD);
753 Stream_Read_UINT16(s, textANSICodePage);
754 Stream_Read_UINT16(s, pad2OctetsE);
755 WLog_Print(log, WLOG_TRACE,
"\tpad4OctetsA: 0x%08" PRIX32
"", pad4OctetsA);
756 WLog_Print(log, WLOG_TRACE,
"\tdesktopSaveXGranularity: 0x%04" PRIX16
"",
757 desktopSaveXGranularity);
758 WLog_Print(log, WLOG_TRACE,
"\tdesktopSaveYGranularity: 0x%04" PRIX16
"",
759 desktopSaveYGranularity);
760 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
761 WLog_Print(log, WLOG_TRACE,
"\tmaximumOrderLevel: 0x%04" PRIX16
"", maximumOrderLevel);
762 WLog_Print(log, WLOG_TRACE,
"\tnumberFonts: 0x%04" PRIX16
"", numberFonts);
763 WLog_Print(log, WLOG_TRACE,
"\torderFlags: 0x%04" PRIX16
"", orderFlags);
764 WLog_Print(log, WLOG_TRACE,
"\torderSupport:");
765 WLog_Print(log, WLOG_TRACE,
"\t\tDSTBLT: %" PRIu8
"", orderSupport[NEG_DSTBLT_INDEX]);
766 WLog_Print(log, WLOG_TRACE,
"\t\tPATBLT: %" PRIu8
"", orderSupport[NEG_PATBLT_INDEX]);
767 WLog_Print(log, WLOG_TRACE,
"\t\tSCRBLT: %" PRIu8
"", orderSupport[NEG_SCRBLT_INDEX]);
768 WLog_Print(log, WLOG_TRACE,
"\t\tMEMBLT: %" PRIu8
"", orderSupport[NEG_MEMBLT_INDEX]);
769 WLog_Print(log, WLOG_TRACE,
"\t\tMEM3BLT: %" PRIu8
"", orderSupport[NEG_MEM3BLT_INDEX]);
770 WLog_Print(log, WLOG_TRACE,
"\t\tATEXTOUT: %" PRIu8
"", orderSupport[NEG_ATEXTOUT_INDEX]);
771 WLog_Print(log, WLOG_TRACE,
"\t\tAEXTTEXTOUT: %" PRIu8
"", orderSupport[NEG_AEXTTEXTOUT_INDEX]);
772 WLog_Print(log, WLOG_TRACE,
"\t\tDRAWNINEGRID: %" PRIu8
"",
773 orderSupport[NEG_DRAWNINEGRID_INDEX]);
774 WLog_Print(log, WLOG_TRACE,
"\t\tLINETO: %" PRIu8
"", orderSupport[NEG_LINETO_INDEX]);
775 WLog_Print(log, WLOG_TRACE,
"\t\tMULTI_DRAWNINEGRID: %" PRIu8
"",
776 orderSupport[NEG_MULTI_DRAWNINEGRID_INDEX]);
777 WLog_Print(log, WLOG_TRACE,
"\t\tOPAQUE_RECT: %" PRIu8
"", orderSupport[NEG_OPAQUE_RECT_INDEX]);
778 WLog_Print(log, WLOG_TRACE,
"\t\tSAVEBITMAP: %" PRIu8
"", orderSupport[NEG_SAVEBITMAP_INDEX]);
779 WLog_Print(log, WLOG_TRACE,
"\t\tWTEXTOUT: %" PRIu8
"", orderSupport[NEG_WTEXTOUT_INDEX]);
780 WLog_Print(log, WLOG_TRACE,
"\t\tMEMBLT_V2: %" PRIu8
"", orderSupport[NEG_MEMBLT_V2_INDEX]);
781 WLog_Print(log, WLOG_TRACE,
"\t\tMEM3BLT_V2: %" PRIu8
"", orderSupport[NEG_MEM3BLT_V2_INDEX]);
782 WLog_Print(log, WLOG_TRACE,
"\t\tMULTIDSTBLT: %" PRIu8
"", orderSupport[NEG_MULTIDSTBLT_INDEX]);
783 WLog_Print(log, WLOG_TRACE,
"\t\tMULTIPATBLT: %" PRIu8
"", orderSupport[NEG_MULTIPATBLT_INDEX]);
784 WLog_Print(log, WLOG_TRACE,
"\t\tMULTISCRBLT: %" PRIu8
"", orderSupport[NEG_MULTISCRBLT_INDEX]);
785 WLog_Print(log, WLOG_TRACE,
"\t\tMULTIOPAQUERECT: %" PRIu8
"",
786 orderSupport[NEG_MULTIOPAQUERECT_INDEX]);
787 WLog_Print(log, WLOG_TRACE,
"\t\tFAST_INDEX: %" PRIu8
"", orderSupport[NEG_FAST_INDEX_INDEX]);
788 WLog_Print(log, WLOG_TRACE,
"\t\tPOLYGON_SC: %" PRIu8
"", orderSupport[NEG_POLYGON_SC_INDEX]);
789 WLog_Print(log, WLOG_TRACE,
"\t\tPOLYGON_CB: %" PRIu8
"", orderSupport[NEG_POLYGON_CB_INDEX]);
790 WLog_Print(log, WLOG_TRACE,
"\t\tPOLYLINE: %" PRIu8
"", orderSupport[NEG_POLYLINE_INDEX]);
791 WLog_Print(log, WLOG_TRACE,
"\t\tUNUSED23: %" PRIu8
"", orderSupport[NEG_UNUSED23_INDEX]);
792 WLog_Print(log, WLOG_TRACE,
"\t\tFAST_GLYPH: %" PRIu8
"", orderSupport[NEG_FAST_GLYPH_INDEX]);
793 WLog_Print(log, WLOG_TRACE,
"\t\tELLIPSE_SC: %" PRIu8
"", orderSupport[NEG_ELLIPSE_SC_INDEX]);
794 WLog_Print(log, WLOG_TRACE,
"\t\tELLIPSE_CB: %" PRIu8
"", orderSupport[NEG_ELLIPSE_CB_INDEX]);
795 WLog_Print(log, WLOG_TRACE,
"\t\tGLYPH_INDEX: %" PRIu8
"", orderSupport[NEG_GLYPH_INDEX_INDEX]);
796 WLog_Print(log, WLOG_TRACE,
"\t\tGLYPH_WEXTTEXTOUT: %" PRIu8
"",
797 orderSupport[NEG_GLYPH_WEXTTEXTOUT_INDEX]);
798 WLog_Print(log, WLOG_TRACE,
"\t\tGLYPH_WLONGTEXTOUT: %" PRIu8
"",
799 orderSupport[NEG_GLYPH_WLONGTEXTOUT_INDEX]);
800 WLog_Print(log, WLOG_TRACE,
"\t\tGLYPH_WLONGEXTTEXTOUT: %" PRIu8
"",
801 orderSupport[NEG_GLYPH_WLONGEXTTEXTOUT_INDEX]);
802 WLog_Print(log, WLOG_TRACE,
"\t\tUNUSED31: %" PRIu8
"", orderSupport[NEG_UNUSED31_INDEX]);
803 WLog_Print(log, WLOG_TRACE,
"\ttextFlags: 0x%04" PRIX16
"", textFlags);
804 WLog_Print(log, WLOG_TRACE,
"\torderSupportExFlags: 0x%04" PRIX16
"", orderSupportExFlags);
805 WLog_Print(log, WLOG_TRACE,
"\tpad4OctetsB: 0x%08" PRIX32
"", pad4OctetsB);
806 WLog_Print(log, WLOG_TRACE,
"\tdesktopSaveSize: 0x%08" PRIX32
"", desktopSaveSize);
807 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsC: 0x%04" PRIX16
"", pad2OctetsC);
808 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsD: 0x%04" PRIX16
"", pad2OctetsD);
809 WLog_Print(log, WLOG_TRACE,
"\ttextANSICodePage: 0x%04" PRIX16
"", textANSICodePage);
810 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsE: 0x%04" PRIX16
"", pad2OctetsE);
815static BOOL rdp_apply_bitmap_cache_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
816 WINPR_ATTR_UNUSED
const rdpSettings* src)
818 WINPR_ASSERT(settings);
828static BOOL rdp_read_bitmap_cache_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
830 WINPR_UNUSED(settings);
831 WINPR_ASSERT(settings);
833 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
836 Stream_Seek_UINT32(s);
837 Stream_Seek_UINT32(s);
838 Stream_Seek_UINT32(s);
839 Stream_Seek_UINT32(s);
840 Stream_Seek_UINT32(s);
841 Stream_Seek_UINT32(s);
842 Stream_Seek_UINT16(s);
843 Stream_Seek_UINT16(s);
844 Stream_Seek_UINT16(s);
845 Stream_Seek_UINT16(s);
846 Stream_Seek_UINT16(s);
847 Stream_Seek_UINT16(s);
856static BOOL rdp_write_bitmap_cache_capability_set(wLog* log,
wStream* s,
857 const rdpSettings* settings)
859 if (!Stream_EnsureRemainingCapacity(s, 64))
862 const size_t header = rdp_capability_set_start(log, s);
864 if (bpp > UINT16_MAX)
866 Stream_Write_UINT32(s, 0);
867 Stream_Write_UINT32(s, 0);
868 Stream_Write_UINT32(s, 0);
869 Stream_Write_UINT32(s, 0);
870 Stream_Write_UINT32(s, 0);
871 Stream_Write_UINT32(s, 0);
872 UINT32 size = bpp * 256;
873 if (size > UINT16_MAX)
875 Stream_Write_UINT16(s, 200);
876 Stream_Write_UINT16(s, (UINT16)size);
878 if (size > UINT16_MAX)
880 Stream_Write_UINT16(s, 600);
881 Stream_Write_UINT16(s, (UINT16)size);
883 if (size > UINT16_MAX)
885 Stream_Write_UINT16(s, 1000);
886 Stream_Write_UINT16(s, (UINT16)size);
887 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE);
890#ifdef WITH_DEBUG_CAPABILITIES
891static BOOL rdp_print_bitmap_cache_capability_set(wLog* log,
wStream* s)
899 UINT16 Cache0Entries = 0;
900 UINT16 Cache0MaximumCellSize = 0;
901 UINT16 Cache1Entries = 0;
902 UINT16 Cache1MaximumCellSize = 0;
903 UINT16 Cache2Entries = 0;
904 UINT16 Cache2MaximumCellSize = 0;
905 WLog_Print(log, WLOG_TRACE,
906 "BitmapCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
908 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
911 Stream_Read_UINT32(s, pad1);
912 Stream_Read_UINT32(s, pad2);
913 Stream_Read_UINT32(s, pad3);
914 Stream_Read_UINT32(s, pad4);
915 Stream_Read_UINT32(s, pad5);
916 Stream_Read_UINT32(s, pad6);
917 Stream_Read_UINT16(s, Cache0Entries);
918 Stream_Read_UINT16(s, Cache0MaximumCellSize);
919 Stream_Read_UINT16(s, Cache1Entries);
920 Stream_Read_UINT16(s, Cache1MaximumCellSize);
921 Stream_Read_UINT16(s, Cache2Entries);
922 Stream_Read_UINT16(s, Cache2MaximumCellSize);
923 WLog_Print(log, WLOG_TRACE,
"\tpad1: 0x%08" PRIX32
"", pad1);
924 WLog_Print(log, WLOG_TRACE,
"\tpad2: 0x%08" PRIX32
"", pad2);
925 WLog_Print(log, WLOG_TRACE,
"\tpad3: 0x%08" PRIX32
"", pad3);
926 WLog_Print(log, WLOG_TRACE,
"\tpad4: 0x%08" PRIX32
"", pad4);
927 WLog_Print(log, WLOG_TRACE,
"\tpad5: 0x%08" PRIX32
"", pad5);
928 WLog_Print(log, WLOG_TRACE,
"\tpad6: 0x%08" PRIX32
"", pad6);
929 WLog_Print(log, WLOG_TRACE,
"\tCache0Entries: 0x%04" PRIX16
"", Cache0Entries);
930 WLog_Print(log, WLOG_TRACE,
"\tCache0MaximumCellSize: 0x%04" PRIX16
"", Cache0MaximumCellSize);
931 WLog_Print(log, WLOG_TRACE,
"\tCache1Entries: 0x%04" PRIX16
"", Cache1Entries);
932 WLog_Print(log, WLOG_TRACE,
"\tCache1MaximumCellSize: 0x%04" PRIX16
"", Cache1MaximumCellSize);
933 WLog_Print(log, WLOG_TRACE,
"\tCache2Entries: 0x%04" PRIX16
"", Cache2Entries);
934 WLog_Print(log, WLOG_TRACE,
"\tCache2MaximumCellSize: 0x%04" PRIX16
"", Cache2MaximumCellSize);
939static BOOL rdp_apply_control_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
940 WINPR_ATTR_UNUSED
const rdpSettings* src)
942 WINPR_ASSERT(settings);
953static BOOL rdp_read_control_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
955 WINPR_UNUSED(settings);
956 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
959 Stream_Seek_UINT16(s);
960 Stream_Seek_UINT16(s);
961 Stream_Seek_UINT16(s);
962 Stream_Seek_UINT16(s);
971static BOOL rdp_write_control_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
973 WINPR_UNUSED(settings);
974 if (!Stream_EnsureRemainingCapacity(s, 32))
977 const size_t header = rdp_capability_set_start(log, s);
978 Stream_Write_UINT16(s, 0);
979 Stream_Write_UINT16(s, 0);
980 Stream_Write_UINT16(s, 2);
981 Stream_Write_UINT16(s, 2);
982 return rdp_capability_set_finish(s, header, CAPSET_TYPE_CONTROL);
985#ifdef WITH_DEBUG_CAPABILITIES
986static BOOL rdp_print_control_capability_set(wLog* log,
wStream* s)
988 UINT16 controlFlags = 0;
989 UINT16 remoteDetachFlag = 0;
990 UINT16 controlInterest = 0;
991 UINT16 detachInterest = 0;
992 WLog_Print(log, WLOG_TRACE,
993 "ControlCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
995 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
998 Stream_Read_UINT16(s, controlFlags);
999 Stream_Read_UINT16(s, remoteDetachFlag);
1000 Stream_Read_UINT16(s, controlInterest);
1001 Stream_Read_UINT16(s, detachInterest);
1002 WLog_Print(log, WLOG_TRACE,
"\tcontrolFlags: 0x%04" PRIX16
"", controlFlags);
1003 WLog_Print(log, WLOG_TRACE,
"\tremoteDetachFlag: 0x%04" PRIX16
"", remoteDetachFlag);
1004 WLog_Print(log, WLOG_TRACE,
"\tcontrolInterest: 0x%04" PRIX16
"", controlInterest);
1005 WLog_Print(log, WLOG_TRACE,
"\tdetachInterest: 0x%04" PRIX16
"", detachInterest);
1010static BOOL rdp_apply_window_activation_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
1011 WINPR_ATTR_UNUSED
const rdpSettings* src)
1013 WINPR_ASSERT(settings);
1024static BOOL rdp_read_window_activation_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1026 WINPR_UNUSED(settings);
1027 WINPR_ASSERT(settings);
1028 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1031 Stream_Seek_UINT16(s);
1032 Stream_Seek_UINT16(s);
1033 Stream_Seek_UINT16(s);
1034 Stream_Seek_UINT16(s);
1043static BOOL rdp_write_window_activation_capability_set(wLog* log,
wStream* s,
1044 const rdpSettings* settings)
1046 WINPR_UNUSED(settings);
1047 WINPR_ASSERT(settings);
1048 if (!Stream_EnsureRemainingCapacity(s, 32))
1051 const size_t header = rdp_capability_set_start(log, s);
1052 Stream_Write_UINT16(s, 0);
1053 Stream_Write_UINT16(s, 0);
1054 Stream_Write_UINT16(s, 0);
1055 Stream_Write_UINT16(s, 0);
1056 return rdp_capability_set_finish(s, header, CAPSET_TYPE_ACTIVATION);
1059#ifdef WITH_DEBUG_CAPABILITIES
1060static BOOL rdp_print_window_activation_capability_set(wLog* log,
wStream* s)
1062 UINT16 helpKeyFlag = 0;
1063 UINT16 helpKeyIndexFlag = 0;
1064 UINT16 helpExtendedKeyFlag = 0;
1065 UINT16 windowManagerKeyFlag = 0;
1066 WLog_Print(log, WLOG_TRACE,
1067 "WindowActivationCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1069 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1072 Stream_Read_UINT16(s, helpKeyFlag);
1073 Stream_Read_UINT16(s, helpKeyIndexFlag);
1074 Stream_Read_UINT16(s, helpExtendedKeyFlag);
1075 Stream_Read_UINT16(s, windowManagerKeyFlag);
1076 WLog_Print(log, WLOG_TRACE,
"\thelpKeyFlag: 0x%04" PRIX16
"", helpKeyFlag);
1077 WLog_Print(log, WLOG_TRACE,
"\thelpKeyIndexFlag: 0x%04" PRIX16
"", helpKeyIndexFlag);
1078 WLog_Print(log, WLOG_TRACE,
"\thelpExtendedKeyFlag: 0x%04" PRIX16
"", helpExtendedKeyFlag);
1079 WLog_Print(log, WLOG_TRACE,
"\twindowManagerKeyFlag: 0x%04" PRIX16
"", windowManagerKeyFlag);
1084static BOOL rdp_apply_pointer_capability_set(rdpSettings* settings,
const rdpSettings* src)
1086 WINPR_ASSERT(settings);
1090 const UINT32 colorPointerCacheSize =
1092 const UINT32 dstPointerCacheSize =
1094 const UINT32 dstColorPointerCacheSize =
1098 const UINT32 actualPointerCacheSize = MIN(pointerCacheSize, dstPointerCacheSize);
1099 const UINT32 actualColorPointerCacheSize = MIN(colorPointerCacheSize, dstColorPointerCacheSize);
1104 actualColorPointerCacheSize));
1112static BOOL rdp_read_pointer_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1114 UINT16 colorPointerFlag = 0;
1115 UINT16 colorPointerCacheSize = 0;
1116 UINT16 pointerCacheSize = 0;
1118 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1121 Stream_Read_UINT16(s, colorPointerFlag);
1122 Stream_Read_UINT16(s, colorPointerCacheSize);
1124 if (colorPointerFlag == 0)
1126 WLog_Print(log, WLOG_WARN,
1127 "[MS-RDPBCGR] 2.2.7.1.5 Pointer Capability Set "
1128 "(TS_POINTER_CAPABILITYSET)::colorPointerFlag received is %" PRIu16
1129 ". Value is ignored and always assumed to be TRUE",
1134 if (Stream_GetRemainingLength(s) >= 2)
1135 Stream_Read_UINT16(s, pointerCacheSize);
1137 WINPR_ASSERT(settings);
1138 settings->PointerCacheSize = pointerCacheSize;
1139 settings->ColorPointerCacheSize = colorPointerCacheSize;
1149static BOOL rdp_write_pointer_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1151 if (!Stream_EnsureRemainingCapacity(s, 32))
1154 const size_t header = rdp_capability_set_start(log, s);
1155 if (settings->PointerCacheSize > UINT16_MAX)
1157 if (settings->ColorPointerCacheSize > UINT16_MAX)
1160 WINPR_ASSERT(settings);
1161 const UINT32 colorPointerFlag =
1164 Stream_Write_UINT16(s, colorPointerFlag);
1165 Stream_Write_UINT16(
1166 s, (UINT16)settings->ColorPointerCacheSize);
1167 Stream_Write_UINT16(s, (UINT16)settings->PointerCacheSize);
1169 return rdp_capability_set_finish(s, header, CAPSET_TYPE_POINTER);
1172#ifdef WITH_DEBUG_CAPABILITIES
1173static BOOL rdp_print_pointer_capability_set(wLog* log,
wStream* s)
1175 UINT16 colorPointerFlag = 0;
1176 UINT16 colorPointerCacheSize = 0;
1177 UINT16 pointerCacheSize = 0;
1179 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 6))
1182 WLog_Print(log, WLOG_TRACE,
1183 "PointerCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1184 Stream_Read_UINT16(s, colorPointerFlag);
1185 Stream_Read_UINT16(s, colorPointerCacheSize);
1186 Stream_Read_UINT16(s, pointerCacheSize);
1187 WLog_Print(log, WLOG_TRACE,
"\tcolorPointerFlag: 0x%04" PRIX16
"", colorPointerFlag);
1188 WLog_Print(log, WLOG_TRACE,
"\tcolorPointerCacheSize: 0x%04" PRIX16
"", colorPointerCacheSize);
1189 WLog_Print(log, WLOG_TRACE,
"\tpointerCacheSize: 0x%04" PRIX16
"", pointerCacheSize);
1194static BOOL rdp_apply_share_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
1195 WINPR_ATTR_UNUSED
const rdpSettings* src)
1197 WINPR_ASSERT(settings);
1208static BOOL rdp_read_share_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1210 WINPR_UNUSED(settings);
1211 WINPR_ASSERT(settings);
1213 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1216 Stream_Seek_UINT16(s);
1217 Stream_Seek_UINT16(s);
1226static BOOL rdp_write_share_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1228 if (!Stream_EnsureRemainingCapacity(s, 32))
1231 const size_t header = rdp_capability_set_start(log, s);
1233 WINPR_ASSERT(settings);
1234 const UINT16 nodeId = (settings->ServerMode) ? 0x03EA : 0;
1235 Stream_Write_UINT16(s, nodeId);
1236 Stream_Write_UINT16(s, 0);
1237 return rdp_capability_set_finish(s, header, CAPSET_TYPE_SHARE);
1240#ifdef WITH_DEBUG_CAPABILITIES
1241static BOOL rdp_print_share_capability_set(wLog* log,
wStream* s)
1244 UINT16 pad2Octets = 0;
1245 WLog_Print(log, WLOG_TRACE,
1246 "ShareCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1248 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1251 Stream_Read_UINT16(s, nodeId);
1252 Stream_Read_UINT16(s, pad2Octets);
1253 WLog_Print(log, WLOG_TRACE,
"\tnodeId: 0x%04" PRIX16
"", nodeId);
1254 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1259static BOOL rdp_apply_color_cache_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
1260 WINPR_ATTR_UNUSED
const rdpSettings* src)
1262 WINPR_ASSERT(settings);
1272static BOOL rdp_read_color_cache_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1274 WINPR_UNUSED(settings);
1275 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1278 Stream_Seek_UINT16(s);
1279 Stream_Seek_UINT16(s);
1288static BOOL rdp_write_color_cache_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1290 WINPR_UNUSED(settings);
1291 if (!Stream_EnsureRemainingCapacity(s, 32))
1294 const size_t header = rdp_capability_set_start(log, s);
1295 Stream_Write_UINT16(s, 6);
1296 Stream_Write_UINT16(s, 0);
1297 return rdp_capability_set_finish(s, header, CAPSET_TYPE_COLOR_CACHE);
1300#ifdef WITH_DEBUG_CAPABILITIES
1301static BOOL rdp_print_color_cache_capability_set(wLog* log,
wStream* s)
1303 UINT16 colorTableCacheSize = 0;
1304 UINT16 pad2Octets = 0;
1305 WLog_Print(log, WLOG_TRACE,
1306 "ColorCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1308 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1311 Stream_Read_UINT16(s, colorTableCacheSize);
1312 Stream_Read_UINT16(s, pad2Octets);
1313 WLog_Print(log, WLOG_TRACE,
"\tcolorTableCacheSize: 0x%04" PRIX16
"", colorTableCacheSize);
1314 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1319static BOOL rdp_apply_sound_capability_set(rdpSettings* settings,
const rdpSettings* src)
1321 WINPR_ASSERT(settings);
1324 settings->SoundBeepsEnabled = src->SoundBeepsEnabled;
1334static BOOL rdp_read_sound_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1336 UINT16 soundFlags = 0;
1338 WINPR_ASSERT(settings);
1339 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1342 Stream_Read_UINT16(s, soundFlags);
1343 Stream_Seek_UINT16(s);
1344 settings->SoundBeepsEnabled = (soundFlags & SOUND_BEEPS_FLAG) != 0;
1353static BOOL rdp_write_sound_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1355 WINPR_ASSERT(settings);
1356 if (!Stream_EnsureRemainingCapacity(s, 32))
1359 const size_t header = rdp_capability_set_start(log, s);
1360 const UINT16 soundFlags = (settings->SoundBeepsEnabled) ? SOUND_BEEPS_FLAG : 0;
1361 Stream_Write_UINT16(s, soundFlags);
1362 Stream_Write_UINT16(s, 0);
1363 return rdp_capability_set_finish(s, header, CAPSET_TYPE_SOUND);
1366#ifdef WITH_DEBUG_CAPABILITIES
1367static BOOL rdp_print_sound_capability_set(wLog* log,
wStream* s)
1369 UINT16 soundFlags = 0;
1370 UINT16 pad2OctetsA = 0;
1371 WLog_Print(log, WLOG_TRACE,
1372 "SoundCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1374 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1377 Stream_Read_UINT16(s, soundFlags);
1378 Stream_Read_UINT16(s, pad2OctetsA);
1379 WLog_Print(log, WLOG_TRACE,
"\tsoundFlags: 0x%04" PRIX16
"", soundFlags);
1380 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
1385static BOOL rdp_apply_input_capability_set(rdpSettings* settings,
const rdpSettings* src)
1387 WINPR_ASSERT(settings);
1390 if (settings->ServerMode)
1392 settings->KeyboardLayout = src->KeyboardLayout;
1393 settings->KeyboardType = src->KeyboardType;
1394 settings->KeyboardSubType = src->KeyboardSubType;
1395 settings->KeyboardFunctionKey = src->KeyboardFunctionKey;
1401 if (!settings->ServerMode)
1403 settings->FastPathInput = src->FastPathInput;
1409 if (settings->HasHorizontalWheel)
1410 settings->HasHorizontalWheel = src->HasHorizontalWheel;
1418 if (settings->HasExtendedMouseEvent)
1419 settings->HasExtendedMouseEvent = src->HasExtendedMouseEvent;
1420 if (settings->HasRelativeMouseEvent)
1421 settings->HasRelativeMouseEvent = src->HasRelativeMouseEvent;
1433static BOOL rdp_read_input_capability_set(wLog* log,
wStream* s, rdpSettings* settings,
1436 UINT16 inputFlags = 0;
1438 WINPR_ASSERT(settings);
1439 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 84))
1442 Stream_Read_UINT16(s, inputFlags);
1443 Stream_Seek_UINT16(s);
1445 Stream_Read_UINT32(s, settings->KeyboardLayout);
1446 Stream_Read_UINT32(s, settings->KeyboardType);
1447 Stream_Read_UINT32(s, settings->KeyboardSubType);
1448 Stream_Read_UINT32(s, settings->KeyboardFunctionKey);
1454 freerdp_settings_sanitize_keyboard_type(log, settings,
"TS_INPUT_CAPABILITYSET");
1457 WCHAR wstr[32] = WINPR_C_ARRAY_INIT;
1458 char str[65] = WINPR_C_ARRAY_INIT;
1464 if (!Stream_Read_UTF16_String(s, wstr, ARRAYSIZE(wstr)))
1467 if (ConvertWCharNToUtf8(wstr, ARRAYSIZE(wstr), str, ARRAYSIZE(str)) < 0)
1468 memset(str, 0,
sizeof(str));
1476 (INPUT_FLAG_FASTPATH_INPUT | INPUT_FLAG_FASTPATH_INPUT2)))
1479 (inputFlags & TS_INPUT_FLAG_MOUSE_HWHEEL) != 0))
1482 (inputFlags & INPUT_FLAG_UNICODE) != 0))
1485 (inputFlags & INPUT_FLAG_MOUSE_RELATIVE) != 0))
1488 (inputFlags & INPUT_FLAG_MOUSEX) != 0))
1491 (inputFlags & TS_INPUT_FLAG_QOE_TIMESTAMPS) != 0))
1502static BOOL rdp_write_input_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1504 WINPR_ASSERT(settings);
1505 if (!Stream_EnsureRemainingCapacity(s, 128))
1508 const size_t header = rdp_capability_set_start(log, s);
1509 UINT16 inputFlags = INPUT_FLAG_SCANCODES;
1511 if (settings->FastPathInput)
1513 inputFlags |= INPUT_FLAG_FASTPATH_INPUT;
1514 inputFlags |= INPUT_FLAG_FASTPATH_INPUT2;
1518 inputFlags |= INPUT_FLAG_MOUSE_RELATIVE;
1521 inputFlags |= TS_INPUT_FLAG_MOUSE_HWHEEL;
1524 inputFlags |= INPUT_FLAG_UNICODE;
1527 inputFlags |= TS_INPUT_FLAG_QOE_TIMESTAMPS;
1529 if (settings->HasExtendedMouseEvent)
1530 inputFlags |= INPUT_FLAG_MOUSEX;
1532 Stream_Write_UINT16(s, inputFlags);
1533 Stream_Write_UINT16(s, 0);
1534 Stream_Write_UINT32(s, settings->KeyboardLayout);
1535 Stream_Write_UINT32(s, settings->KeyboardType);
1536 Stream_Write_UINT32(s, settings->KeyboardSubType);
1537 Stream_Write_UINT32(s, settings->KeyboardFunctionKey);
1539 return rdp_capability_set_finish(s, header, CAPSET_TYPE_INPUT);
1542#ifdef WITH_DEBUG_CAPABILITIES
1543static BOOL rdp_print_input_capability_set(wLog* log,
wStream* s)
1545 UINT16 inputFlags = 0;
1546 UINT16 pad2OctetsA = 0;
1547 UINT32 keyboardLayout = 0;
1548 UINT32 keyboardType = 0;
1549 UINT32 keyboardSubType = 0;
1550 UINT32 keyboardFunctionKey = 0;
1551 WLog_Print(log, WLOG_TRACE,
"InputCapabilitySet (length %" PRIuz
")",
1552 Stream_GetRemainingLength(s));
1554 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 84))
1557 Stream_Read_UINT16(s, inputFlags);
1558 Stream_Read_UINT16(s, pad2OctetsA);
1559 Stream_Read_UINT32(s, keyboardLayout);
1560 Stream_Read_UINT32(s, keyboardType);
1561 Stream_Read_UINT32(s, keyboardSubType);
1562 Stream_Read_UINT32(s, keyboardFunctionKey);
1564 WLog_Print(log, WLOG_TRACE,
"\tinputFlags: 0x%04" PRIX16
"", inputFlags);
1565 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
1566 WLog_Print(log, WLOG_TRACE,
"\tkeyboardLayout: 0x%08" PRIX32
"", keyboardLayout);
1567 WLog_Print(log, WLOG_TRACE,
"\tkeyboardType: 0x%08" PRIX32
"", keyboardType);
1568 WLog_Print(log, WLOG_TRACE,
"\tkeyboardSubType: 0x%08" PRIX32
"", keyboardSubType);
1569 WLog_Print(log, WLOG_TRACE,
"\tkeyboardFunctionKey: 0x%08" PRIX32
"", keyboardFunctionKey);
1574static BOOL rdp_apply_font_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
1575 WINPR_ATTR_UNUSED
const rdpSettings* src)
1577 WINPR_ASSERT(settings);
1587static BOOL rdp_read_font_capability_set(WINPR_ATTR_UNUSED wLog* log,
wStream* s,
1588 rdpSettings* settings)
1590 WINPR_UNUSED(settings);
1591 if (Stream_GetRemainingLength(s) >= 2)
1592 Stream_Seek_UINT16(s);
1594 if (Stream_GetRemainingLength(s) >= 2)
1595 Stream_Seek_UINT16(s);
1605static BOOL rdp_write_font_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1607 WINPR_UNUSED(settings);
1608 if (!Stream_EnsureRemainingCapacity(s, 32))
1611 const size_t header = rdp_capability_set_start(log, s);
1612 Stream_Write_UINT16(s, FONTSUPPORT_FONTLIST);
1613 Stream_Write_UINT16(s, 0);
1614 return rdp_capability_set_finish(s, header, CAPSET_TYPE_FONT);
1617#ifdef WITH_DEBUG_CAPABILITIES
1618static BOOL rdp_print_font_capability_set(wLog* log,
wStream* s)
1620 UINT16 fontSupportFlags = 0;
1621 UINT16 pad2Octets = 0;
1622 WLog_Print(log, WLOG_TRACE,
1623 "FontCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1625 if (Stream_GetRemainingLength(s) >= 2)
1626 Stream_Read_UINT16(s, fontSupportFlags);
1628 if (Stream_GetRemainingLength(s) >= 2)
1629 Stream_Read_UINT16(s, pad2Octets);
1631 WLog_Print(log, WLOG_TRACE,
"\tfontSupportFlags: 0x%04" PRIX16
"", fontSupportFlags);
1632 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1637static BOOL rdp_apply_brush_capability_set(rdpSettings* settings,
const rdpSettings* src)
1639 WINPR_ASSERT(settings);
1643 settings->BrushSupportLevel = src->BrushSupportLevel;
1652static BOOL rdp_read_brush_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1654 WINPR_UNUSED(settings);
1655 WINPR_ASSERT(settings);
1657 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1659 Stream_Read_UINT32(s, settings->BrushSupportLevel);
1668static BOOL rdp_write_brush_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1670 WINPR_ASSERT(settings);
1671 if (!Stream_EnsureRemainingCapacity(s, 32))
1674 const size_t header = rdp_capability_set_start(log, s);
1675 Stream_Write_UINT32(s, settings->BrushSupportLevel);
1676 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BRUSH);
1679#ifdef WITH_DEBUG_CAPABILITIES
1680static BOOL rdp_print_brush_capability_set(wLog* log,
wStream* s)
1682 UINT32 brushSupportLevel = 0;
1683 WLog_Print(log, WLOG_TRACE,
1684 "BrushCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1686 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1689 Stream_Read_UINT32(s, brushSupportLevel);
1690 WLog_Print(log, WLOG_TRACE,
"\tbrushSupportLevel: 0x%08" PRIX32
"", brushSupportLevel);
1701 WINPR_ASSERT(cache_definition);
1702 Stream_Read_UINT16(s, cache_definition->cacheEntries);
1703 Stream_Read_UINT16(s,
1704 cache_definition->cacheMaximumCellSize);
1713 WINPR_ASSERT(cache_definition);
1714 Stream_Write_UINT16(s, cache_definition->cacheEntries);
1715 Stream_Write_UINT16(
1716 s, cache_definition->cacheMaximumCellSize);
1719static BOOL rdp_apply_glyph_cache_capability_set(rdpSettings* settings,
const rdpSettings* src)
1721 WINPR_ASSERT(settings);
1724 WINPR_ASSERT(src->GlyphCache);
1725 WINPR_ASSERT(settings->GlyphCache);
1726 for (
size_t x = 0; x < 10; x++)
1727 settings->GlyphCache[x] = src->GlyphCache[x];
1729 WINPR_ASSERT(src->FragCache);
1730 WINPR_ASSERT(settings->FragCache);
1731 settings->FragCache[0] = src->FragCache[0];
1732 settings->GlyphSupportLevel = src->GlyphSupportLevel;
1742static BOOL rdp_read_glyph_cache_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1744 WINPR_ASSERT(settings);
1745 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 48))
1749 for (
size_t x = 0; x < 10; x++)
1750 rdp_read_cache_definition(s, &(settings->GlyphCache[x]));
1751 rdp_read_cache_definition(s, settings->FragCache);
1752 Stream_Read_UINT16(s, settings->GlyphSupportLevel);
1753 Stream_Seek_UINT16(s);
1762static BOOL rdp_write_glyph_cache_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1764 WINPR_ASSERT(settings);
1765 if (!Stream_EnsureRemainingCapacity(s, 64))
1768 const size_t header = rdp_capability_set_start(log, s);
1769 if (settings->GlyphSupportLevel > UINT16_MAX)
1772 for (
size_t x = 0; x < 10; x++)
1773 rdp_write_cache_definition(s, &(settings->GlyphCache[x]));
1774 rdp_write_cache_definition(s, settings->FragCache);
1775 Stream_Write_UINT16(s, (UINT16)settings->GlyphSupportLevel);
1776 Stream_Write_UINT16(s, 0);
1777 return rdp_capability_set_finish(s, header, CAPSET_TYPE_GLYPH_CACHE);
1780#ifdef WITH_DEBUG_CAPABILITIES
1781static BOOL rdp_print_glyph_cache_capability_set(wLog* log,
wStream* s)
1785 UINT16 glyphSupportLevel = 0;
1786 UINT16 pad2Octets = 0;
1787 WLog_Print(log, WLOG_TRACE,
1788 "GlyphCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1790 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 48))
1794 rdp_read_cache_definition(s, &glyphCache[0]);
1795 rdp_read_cache_definition(s, &glyphCache[1]);
1796 rdp_read_cache_definition(s, &glyphCache[2]);
1797 rdp_read_cache_definition(s, &glyphCache[3]);
1798 rdp_read_cache_definition(s, &glyphCache[4]);
1799 rdp_read_cache_definition(s, &glyphCache[5]);
1800 rdp_read_cache_definition(s, &glyphCache[6]);
1801 rdp_read_cache_definition(s, &glyphCache[7]);
1802 rdp_read_cache_definition(s, &glyphCache[8]);
1803 rdp_read_cache_definition(s, &glyphCache[9]);
1804 rdp_read_cache_definition(s, &fragCache);
1805 Stream_Read_UINT16(s, glyphSupportLevel);
1806 Stream_Read_UINT16(s, pad2Octets);
1807 WLog_Print(log, WLOG_TRACE,
"\tglyphCache0: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1808 glyphCache[0].cacheEntries, glyphCache[0].cacheMaximumCellSize);
1809 WLog_Print(log, WLOG_TRACE,
"\tglyphCache1: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1810 glyphCache[1].cacheEntries, glyphCache[1].cacheMaximumCellSize);
1811 WLog_Print(log, WLOG_TRACE,
"\tglyphCache2: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1812 glyphCache[2].cacheEntries, glyphCache[2].cacheMaximumCellSize);
1813 WLog_Print(log, WLOG_TRACE,
"\tglyphCache3: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1814 glyphCache[3].cacheEntries, glyphCache[3].cacheMaximumCellSize);
1815 WLog_Print(log, WLOG_TRACE,
"\tglyphCache4: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1816 glyphCache[4].cacheEntries, glyphCache[4].cacheMaximumCellSize);
1817 WLog_Print(log, WLOG_TRACE,
"\tglyphCache5: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1818 glyphCache[5].cacheEntries, glyphCache[5].cacheMaximumCellSize);
1819 WLog_Print(log, WLOG_TRACE,
"\tglyphCache6: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1820 glyphCache[6].cacheEntries, glyphCache[6].cacheMaximumCellSize);
1821 WLog_Print(log, WLOG_TRACE,
"\tglyphCache7: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1822 glyphCache[7].cacheEntries, glyphCache[7].cacheMaximumCellSize);
1823 WLog_Print(log, WLOG_TRACE,
"\tglyphCache8: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1824 glyphCache[8].cacheEntries, glyphCache[8].cacheMaximumCellSize);
1825 WLog_Print(log, WLOG_TRACE,
"\tglyphCache9: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1826 glyphCache[9].cacheEntries, glyphCache[9].cacheMaximumCellSize);
1827 WLog_Print(log, WLOG_TRACE,
"\tfragCache: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1828 fragCache.cacheEntries, fragCache.cacheMaximumCellSize);
1829 WLog_Print(log, WLOG_TRACE,
"\tglyphSupportLevel: 0x%04" PRIX16
"", glyphSupportLevel);
1830 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1835static BOOL rdp_apply_offscreen_bitmap_cache_capability_set(rdpSettings* settings,
1836 const rdpSettings* src)
1838 WINPR_ASSERT(settings);
1841 settings->OffscreenCacheSize = src->OffscreenCacheSize;
1842 settings->OffscreenCacheEntries = src->OffscreenCacheEntries;
1843 settings->OffscreenSupportLevel = src->OffscreenSupportLevel;
1853static BOOL rdp_read_offscreen_bitmap_cache_capability_set(wLog* log,
wStream* s,
1854 rdpSettings* settings)
1856 UINT32 offscreenSupportLevel = 0;
1858 WINPR_ASSERT(settings);
1859 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1862 Stream_Read_UINT32(s, offscreenSupportLevel);
1863 Stream_Read_UINT16(s, settings->OffscreenCacheSize);
1864 Stream_Read_UINT16(s, settings->OffscreenCacheEntries);
1866 settings->OffscreenSupportLevel = offscreenSupportLevel & 0x01;
1876static BOOL rdp_write_offscreen_bitmap_cache_capability_set(wLog* log,
wStream* s,
1877 const rdpSettings* settings)
1879 UINT32 offscreenSupportLevel = 0x00;
1881 WINPR_ASSERT(settings);
1882 if (!Stream_EnsureRemainingCapacity(s, 32))
1885 const size_t header = rdp_capability_set_start(log, s);
1886 if (settings->OffscreenSupportLevel)
1888 offscreenSupportLevel = 0x01;
1889 Stream_Write_UINT32(s, offscreenSupportLevel);
1890 Stream_Write_UINT16(
1891 s, WINPR_ASSERTING_INT_CAST(
1892 uint16_t, settings->OffscreenCacheSize));
1893 Stream_Write_UINT16(
1895 WINPR_ASSERTING_INT_CAST(
1896 uint16_t, settings->OffscreenCacheEntries));
1901 return rdp_capability_set_finish(s, header, CAPSET_TYPE_OFFSCREEN_CACHE);
1904#ifdef WITH_DEBUG_CAPABILITIES
1905static BOOL rdp_print_offscreen_bitmap_cache_capability_set(wLog* log,
wStream* s)
1907 UINT32 offscreenSupportLevel = 0;
1908 UINT16 offscreenCacheSize = 0;
1909 UINT16 offscreenCacheEntries = 0;
1910 WLog_Print(log, WLOG_TRACE,
"OffscreenBitmapCacheCapabilitySet (length %" PRIuz
"):",
1911 Stream_GetRemainingLength(s));
1913 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1916 Stream_Read_UINT32(s, offscreenSupportLevel);
1917 Stream_Read_UINT16(s, offscreenCacheSize);
1918 Stream_Read_UINT16(s, offscreenCacheEntries);
1919 WLog_Print(log, WLOG_TRACE,
"\toffscreenSupportLevel: 0x%08" PRIX32
"", offscreenSupportLevel);
1920 WLog_Print(log, WLOG_TRACE,
"\toffscreenCacheSize: 0x%04" PRIX16
"", offscreenCacheSize);
1921 WLog_Print(log, WLOG_TRACE,
"\toffscreenCacheEntries: 0x%04" PRIX16
"", offscreenCacheEntries);
1926static BOOL rdp_apply_bitmap_cache_host_support_capability_set(rdpSettings* settings,
1927 const rdpSettings* src)
1939static BOOL rdp_read_bitmap_cache_host_support_capability_set(wLog* log,
wStream* s,
1940 rdpSettings* settings)
1942 BYTE cacheVersion = 0;
1944 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1947 Stream_Read_UINT8(s, cacheVersion);
1948 Stream_Seek_UINT8(s);
1949 Stream_Seek_UINT16(s);
1952 cacheVersion & BITMAP_CACHE_V2);
1960static BOOL rdp_write_bitmap_cache_host_support_capability_set(wLog* log,
wStream* s,
1961 const rdpSettings* settings)
1963 UINT8 cacheVersion = 0;
1966 cacheVersion |= BITMAP_CACHE_V2;
1968 if (!Stream_EnsureRemainingCapacity(s, 32))
1971 const size_t header = rdp_capability_set_start(log, s);
1972 Stream_Write_UINT8(s, cacheVersion);
1973 Stream_Write_UINT8(s, 0);
1974 Stream_Write_UINT16(s, 0);
1975 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT);
1978#ifdef WITH_DEBUG_CAPABILITIES
1979static BOOL rdp_print_bitmap_cache_host_support_capability_set(wLog* log,
wStream* s)
1981 BYTE cacheVersion = 0;
1984 WLog_Print(log, WLOG_TRACE,
"BitmapCacheHostSupportCapabilitySet (length %" PRIuz
"):",
1985 Stream_GetRemainingLength(s));
1987 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1990 Stream_Read_UINT8(s, cacheVersion);
1991 Stream_Read_UINT8(s, pad1);
1992 Stream_Read_UINT16(s, pad2);
1993 WLog_Print(log, WLOG_TRACE,
"\tcacheVersion: 0x%02" PRIX8
"", cacheVersion);
1994 WLog_Print(log, WLOG_TRACE,
"\tpad1: 0x%02" PRIX8
"", pad1);
1995 WLog_Print(log, WLOG_TRACE,
"\tpad2: 0x%04" PRIX16
"", pad2);
2000static BOOL rdp_read_bitmap_cache_cell_info(wLog* log,
wStream* s,
2005 WINPR_ASSERT(cellInfo);
2006 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2013 Stream_Read_UINT32(s, info);
2014 cellInfo->numEntries = (info & 0x7FFFFFFF);
2015 cellInfo->persistent = (info & 0x80000000) ? 1 : 0;
2026 WINPR_ASSERT(cellInfo);
2027 info = (cellInfo->numEntries | (((UINT32)cellInfo->persistent << 31) & 0xFF000000));
2028 Stream_Write_UINT32(s, info);
2031static BOOL rdp_apply_bitmap_cache_v2_capability_set(rdpSettings* settings,
const rdpSettings* src)
2033 const FreeRDP_Settings_Keys_Bool keys[] = { FreeRDP_BitmapCacheEnabled,
2034 FreeRDP_BitmapCachePersistEnabled };
2036 for (
size_t x = 0; x < ARRAYSIZE(keys); x++)
2038 const FreeRDP_Settings_Keys_Bool
id = keys[x];
2045 const UINT32 BitmapCacheV2NumCells =
2048 BitmapCacheV2NumCells))
2051 for (
size_t x = 0; x < BitmapCacheV2NumCells; x++)
2054 freerdp_settings_get_pointer_array(src, FreeRDP_BitmapCacheV2CellInfo, x);
2055 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_BitmapCacheV2CellInfo, x,
2069static BOOL rdp_read_bitmap_cache_v2_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2071 UINT16 cacheFlags = 0;
2072 WINPR_UNUSED(settings);
2073 WINPR_ASSERT(settings);
2075 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
2078 Stream_Read_UINT16(s, cacheFlags);
2083 cacheFlags & PERSISTENT_KEYS_EXPECTED_FLAG))
2086 Stream_Seek_UINT8(s);
2087 Stream_Read_UINT8(s, settings->BitmapCacheV2NumCells);
2088 if (settings->BitmapCacheV2NumCells > 5)
2090 WLog_Print(log, WLOG_ERROR,
2091 "Invalid TS_BITMAPCACHE_CAPABILITYSET_REV2::numCellCaches %" PRIu32
" > 5",
2092 settings->BitmapCacheV2NumCells);
2096 for (
size_t x = 0; x < settings->BitmapCacheV2NumCells; x++)
2099 freerdp_settings_get_pointer_array_writable(settings, FreeRDP_BitmapCacheV2CellInfo, x);
2100 if (!rdp_read_bitmap_cache_cell_info(log, s, info))
2105 for (
size_t x = settings->BitmapCacheV2NumCells; x < 5; x++)
2107 if (!Stream_SafeSeek(s, 4))
2119static BOOL rdp_write_bitmap_cache_v2_capability_set(wLog* log,
wStream* s,
2120 const rdpSettings* settings)
2122 WINPR_ASSERT(settings);
2123 if (!Stream_EnsureRemainingCapacity(s, 64))
2126 const size_t header = rdp_capability_set_start(log, s);
2127 UINT16 cacheFlags = ALLOW_CACHE_WAITING_LIST_FLAG;
2131 cacheFlags |= PERSISTENT_KEYS_EXPECTED_FLAG;
2132 settings->BitmapCacheV2CellInfo[0].persistent = 1;
2133 settings->BitmapCacheV2CellInfo[1].persistent = 1;
2134 settings->BitmapCacheV2CellInfo[2].persistent = 1;
2135 settings->BitmapCacheV2CellInfo[3].persistent = 1;
2136 settings->BitmapCacheV2CellInfo[4].persistent = 1;
2139 Stream_Write_UINT16(s, cacheFlags);
2140 Stream_Write_UINT8(s, 0);
2142 s, WINPR_ASSERTING_INT_CAST(uint8_t,
2143 settings->BitmapCacheV2NumCells));
2144 rdp_write_bitmap_cache_cell_info(
2145 s, &settings->BitmapCacheV2CellInfo[0]);
2146 rdp_write_bitmap_cache_cell_info(
2147 s, &settings->BitmapCacheV2CellInfo[1]);
2148 rdp_write_bitmap_cache_cell_info(
2149 s, &settings->BitmapCacheV2CellInfo[2]);
2150 rdp_write_bitmap_cache_cell_info(
2151 s, &settings->BitmapCacheV2CellInfo[3]);
2152 rdp_write_bitmap_cache_cell_info(
2153 s, &settings->BitmapCacheV2CellInfo[4]);
2155 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_V2);
2158#ifdef WITH_DEBUG_CAPABILITIES
2159static BOOL rdp_print_bitmap_cache_v2_capability_set(wLog* log,
wStream* s)
2162 WLog_Print(log, WLOG_TRACE,
2163 "BitmapCacheV2CapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2165 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
2168 const UINT16 cacheFlags = Stream_Get_UINT16(s);
2169 const UINT8 pad2 = Stream_Get_UINT8(s);
2170 const UINT8 numCellCaches = Stream_Get_UINT8(s);
2172 for (
size_t x = 0; x < ARRAYSIZE(bitmapCacheV2CellInfo); x++)
2174 if (!rdp_read_bitmap_cache_cell_info(
2175 log, s, &bitmapCacheV2CellInfo[x]))
2179 if (!Stream_SafeSeek(s, 12))
2182 WLog_Print(log, WLOG_TRACE,
"\tcacheFlags: 0x%04" PRIX16
"", cacheFlags);
2183 WLog_Print(log, WLOG_TRACE,
"\tpad2: 0x%02" PRIX8
"", pad2);
2184 WLog_Print(log, WLOG_TRACE,
"\tnumCellCaches: 0x%02" PRIX8
"", numCellCaches);
2185 for (
size_t x = 0; x < ARRAYSIZE(bitmapCacheV2CellInfo); x++)
2188 WLog_Print(log, WLOG_TRACE,
2189 "\tbitmapCache%" PRIuz
"CellInfo: numEntries: %" PRIu32
" persistent: %" PRId32
2191 x, info->numEntries, info->persistent);
2197static BOOL rdp_apply_virtual_channel_capability_set(rdpSettings* settings,
const rdpSettings* src)
2199 WINPR_ASSERT(settings);
2203 if (settings->ServerMode && (settings->VCFlags & VCCAPS_COMPR_SC) &&
2204 (src->VCFlags & VCCAPS_COMPR_SC))
2205 settings->VCFlags |= VCCAPS_COMPR_SC;
2207 settings->VCFlags &= (uint32_t)~VCCAPS_COMPR_SC;
2209 if (!settings->ServerMode && (settings->VCFlags & VCCAPS_COMPR_CS_8K) &&
2210 (src->VCFlags & VCCAPS_COMPR_CS_8K))
2211 settings->VCFlags |= VCCAPS_COMPR_CS_8K;
2213 settings->VCFlags &= (uint32_t)~VCCAPS_COMPR_CS_8K;
2220 if (!settings->ServerMode)
2222 if ((src->VCChunkSize > CHANNEL_CHUNK_MAX_LENGTH) || (src->VCChunkSize == 0))
2223 settings->VCChunkSize = CHANNEL_CHUNK_LENGTH;
2226 settings->VCChunkSize = src->VCChunkSize;
2238static BOOL rdp_read_virtual_channel_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2241 UINT32 VCChunkSize = 0;
2243 WINPR_ASSERT(settings);
2244 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2247 Stream_Read_UINT32(s, flags);
2249 if (Stream_GetRemainingLength(s) >= 4)
2250 Stream_Read_UINT32(s, VCChunkSize);
2252 VCChunkSize = UINT32_MAX;
2254 settings->VCFlags = flags;
2255 settings->VCChunkSize = VCChunkSize;
2265static BOOL rdp_write_virtual_channel_capability_set(wLog* log,
wStream* s,
2266 const rdpSettings* settings)
2268 WINPR_ASSERT(settings);
2269 if (!Stream_EnsureRemainingCapacity(s, 32))
2272 const size_t header = rdp_capability_set_start(log, s);
2273 Stream_Write_UINT32(s, settings->VCFlags);
2274 Stream_Write_UINT32(s, settings->VCChunkSize);
2275 return rdp_capability_set_finish(s, header, CAPSET_TYPE_VIRTUAL_CHANNEL);
2278#ifdef WITH_DEBUG_CAPABILITIES
2279static BOOL rdp_print_virtual_channel_capability_set(wLog* log,
wStream* s)
2282 UINT32 VCChunkSize = 0;
2283 WLog_Print(log, WLOG_TRACE,
2284 "VirtualChannelCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2286 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2289 Stream_Read_UINT32(s, flags);
2291 if (Stream_GetRemainingLength(s) >= 4)
2292 Stream_Read_UINT32(s, VCChunkSize);
2296 WLog_Print(log, WLOG_TRACE,
"\tflags: 0x%08" PRIX32
"", flags);
2297 WLog_Print(log, WLOG_TRACE,
"\tVCChunkSize: 0x%08" PRIX32
"", VCChunkSize);
2302static BOOL rdp_apply_draw_nine_grid_cache_capability_set(rdpSettings* settings,
2303 const rdpSettings* src)
2305 WINPR_ASSERT(settings);
2308 settings->DrawNineGridCacheSize = src->DrawNineGridCacheSize;
2309 settings->DrawNineGridCacheEntries = src->DrawNineGridCacheEntries;
2310 settings->DrawNineGridEnabled = src->DrawNineGridEnabled;
2320static BOOL rdp_read_draw_nine_grid_cache_capability_set(wLog* log,
wStream* s,
2321 rdpSettings* settings)
2323 UINT32 drawNineGridSupportLevel = 0;
2325 WINPR_ASSERT(settings);
2326 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
2329 Stream_Read_UINT32(s, drawNineGridSupportLevel);
2330 Stream_Read_UINT16(s, settings->DrawNineGridCacheSize);
2331 Stream_Read_UINT16(s,
2332 settings->DrawNineGridCacheEntries);
2334 settings->DrawNineGridEnabled =
2335 (drawNineGridSupportLevel & (DRAW_NINEGRID_SUPPORTED | DRAW_NINEGRID_SUPPORTED_V2)) != 0;
2345static BOOL rdp_write_draw_nine_grid_cache_capability_set(wLog* log,
wStream* s,
2346 const rdpSettings* settings)
2348 WINPR_ASSERT(settings);
2349 if (!Stream_EnsureRemainingCapacity(s, 32))
2352 const size_t header = rdp_capability_set_start(log, s);
2353 const UINT32 drawNineGridSupportLevel =
2354 (settings->DrawNineGridEnabled) ? DRAW_NINEGRID_SUPPORTED_V2 : DRAW_NINEGRID_NO_SUPPORT;
2355 Stream_Write_UINT32(s, drawNineGridSupportLevel);
2356 Stream_Write_UINT16(
2357 s, WINPR_ASSERTING_INT_CAST(
2358 uint16_t, settings->DrawNineGridCacheSize));
2359 Stream_Write_UINT16(
2361 WINPR_ASSERTING_INT_CAST(
2362 uint16_t, settings->DrawNineGridCacheEntries));
2363 return rdp_capability_set_finish(s, header, CAPSET_TYPE_DRAW_NINE_GRID_CACHE);
2366#ifdef WITH_DEBUG_CAPABILITIES
2367static BOOL rdp_print_draw_nine_grid_cache_capability_set(wLog* log,
wStream* s)
2369 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
2372 const uint32_t drawNineGridSupportLevel =
2373 Stream_Get_UINT32(s);
2374 const uint32_t DrawNineGridCacheSize =
2375 Stream_Get_UINT16(s);
2376 const uint32_t DrawNineGridCacheEntries =
2377 Stream_Get_UINT16(s);
2379 WLog_Print(log, WLOG_TRACE,
2380 "DrawNineGridCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2381 WLog_Print(log, WLOG_TRACE,
"drawNineGridSupportLevel=0x%08" PRIx32, drawNineGridSupportLevel);
2382 WLog_Print(log, WLOG_TRACE,
"DrawNineGridCacheSize=0x%08" PRIx32, DrawNineGridCacheSize);
2383 WLog_Print(log, WLOG_TRACE,
"DrawNineGridCacheEntries=0x%08" PRIx32, DrawNineGridCacheEntries);
2388static BOOL rdp_apply_draw_gdiplus_cache_capability_set(rdpSettings* settings,
2389 const rdpSettings* src)
2391 WINPR_ASSERT(settings);
2394 if (src->DrawGdiPlusEnabled)
2395 settings->DrawGdiPlusEnabled = TRUE;
2397 if (src->DrawGdiPlusCacheEnabled)
2398 settings->DrawGdiPlusCacheEnabled = TRUE;
2408static BOOL rdp_read_draw_gdiplus_cache_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2410 UINT32 drawGDIPlusSupportLevel = 0;
2411 UINT32 drawGdiplusCacheLevel = 0;
2413 WINPR_ASSERT(settings);
2414 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
2417 Stream_Read_UINT32(s, drawGDIPlusSupportLevel);
2418 Stream_Seek_UINT32(s);
2419 Stream_Read_UINT32(s, drawGdiplusCacheLevel);
2424 settings->DrawGdiPlusEnabled = (drawGDIPlusSupportLevel & DRAW_GDIPLUS_SUPPORTED) != 0;
2425 settings->DrawGdiPlusCacheEnabled = (drawGdiplusCacheLevel & DRAW_GDIPLUS_CACHE_LEVEL_ONE) != 0;
2430#ifdef WITH_DEBUG_CAPABILITIES
2431static BOOL rdp_print_draw_gdiplus_cache_capability_set(wLog* log,
wStream* s)
2433 WLog_Print(log, WLOG_TRACE,
2434 "DrawGdiPlusCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2436 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
2439 const uint32_t drawGdiPlusSupportLevel =
2440 Stream_Get_UINT32(s);
2441 const uint32_t GdipVersion = Stream_Get_UINT32(s);
2442 const uint32_t drawGdiplusCacheLevel =
2443 Stream_Get_UINT32(s);
2444 WLog_Print(log, WLOG_TRACE,
2445 "drawGdiPlusSupportLevel=0x%08" PRIx32
", GdipVersion=0x%08" PRIx32
2446 ", drawGdiplusdrawGdiplusCacheLevelCacheLevel=0x%08" PRIx32,
2447 drawGdiPlusSupportLevel, GdipVersion, drawGdiplusCacheLevel);
2449 const uint16_t GdipGraphicsCacheEntries = Stream_Get_UINT16(s);
2450 const uint16_t GdipBrushCacheEntries = Stream_Get_UINT16(s);
2451 const uint16_t GdipPenCacheEntries = Stream_Get_UINT16(s);
2452 const uint16_t GdipImageCacheEntries = Stream_Get_UINT16(s);
2453 const uint16_t GdipImageAttributesCacheEntries = Stream_Get_UINT16(s);
2454 WLog_Print(log, WLOG_TRACE,
2455 "GdipGraphicsCacheEntries=0x%04" PRIx16
", GdipBrushCacheEntries=0x%04" PRIx16
2456 ", GdipPenCacheEntries=0x%04" PRIx16
", GdipImageCacheEntries=0x%04" PRIx16
2457 ", GdipImageAttributesCacheEntries=0x%04" PRIx16,
2458 GdipGraphicsCacheEntries, GdipBrushCacheEntries, GdipPenCacheEntries,
2459 GdipImageCacheEntries, GdipImageAttributesCacheEntries);
2461 const uint16_t GdipGraphicsCacheChunkSize = Stream_Get_UINT16(s);
2462 const uint16_t GdipObjectBrushCacheChunkSize = Stream_Get_UINT16(s);
2463 const uint16_t GdipObjectPenCacheChunkSize = Stream_Get_UINT16(s);
2464 const uint16_t GdipObjectImageAttributesCacheChunkSize = Stream_Get_UINT16(s);
2465 WLog_Print(log, WLOG_TRACE,
2466 "GdipGraphicsCacheChunkSize=0x%04" PRIx16
2467 ", GdipObjectBrushCacheChunkSize=0x%04" PRIx16
2468 ", GdipObjectPenCacheChunkSize=0x%04" PRIx16
2469 ",GdipObjectImageAttributesCacheChunkSize=0x%04" PRIx16,
2470 GdipGraphicsCacheChunkSize, GdipObjectBrushCacheChunkSize,
2471 GdipObjectPenCacheChunkSize, GdipObjectImageAttributesCacheChunkSize);
2473 const uint16_t GdipObjectImageCacheChunkSize = Stream_Get_UINT16(s);
2474 const uint16_t GdipObjectImageCacheTotalSize = Stream_Get_UINT16(s);
2475 const uint16_t GdipObjectImageCacheMaxSize = Stream_Get_UINT16(s);
2478 "GdipObjectImageCacheChunkSize=0x%04" PRIx16
", GdipObjectImageCacheTotalSize=0x%04" PRIx16
2479 ", GdipObjectImageCacheMaxSize=0x%04" PRIx16,
2480 GdipObjectImageCacheChunkSize, GdipObjectImageCacheTotalSize, GdipObjectImageCacheMaxSize);
2485static BOOL rdp_apply_remote_programs_capability_set(rdpSettings* settings,
const rdpSettings* src)
2487 WINPR_ASSERT(settings);
2490 if (settings->RemoteApplicationMode)
2491 settings->RemoteApplicationMode = src->RemoteApplicationMode;
2496 UINT32 supportLevel = src->RemoteApplicationSupportLevel;
2497 if (settings->RemoteApplicationMode)
2498 supportLevel |= RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED;
2500 settings->RemoteApplicationSupportLevel = supportLevel & settings->RemoteApplicationSupportMask;
2510static BOOL rdp_read_remote_programs_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2512 UINT32 railSupportLevel = 0;
2514 WINPR_ASSERT(settings);
2515 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2518 Stream_Read_UINT32(s, railSupportLevel);
2520 settings->RemoteApplicationMode = (railSupportLevel & RAIL_LEVEL_SUPPORTED) != 0;
2521 settings->RemoteApplicationSupportLevel = railSupportLevel;
2530static BOOL rdp_write_remote_programs_capability_set(wLog* log,
wStream* s,
2531 const rdpSettings* settings)
2533 WINPR_ASSERT(settings);
2534 if (!Stream_EnsureRemainingCapacity(s, 64))
2537 const size_t header = rdp_capability_set_start(log, s);
2538 UINT32 railSupportLevel = RAIL_LEVEL_SUPPORTED;
2540 if (settings->RemoteApplicationSupportLevel & RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED)
2542 if (settings->RemoteAppLanguageBarSupported)
2543 railSupportLevel |= RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED;
2546 railSupportLevel |= RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED;
2547 railSupportLevel |= RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED;
2548 railSupportLevel |= RAIL_LEVEL_SERVER_TO_CLIENT_IME_SYNC_SUPPORTED;
2549 railSupportLevel |= RAIL_LEVEL_HIDE_MINIMIZED_APPS_SUPPORTED;
2550 railSupportLevel |= RAIL_LEVEL_WINDOW_CLOAKING_SUPPORTED;
2551 railSupportLevel |= RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED;
2553 railSupportLevel &= settings->RemoteApplicationSupportLevel;
2554 Stream_Write_UINT32(s, railSupportLevel);
2555 return rdp_capability_set_finish(s, header, CAPSET_TYPE_RAIL);
2558#ifdef WITH_DEBUG_CAPABILITIES
2559static BOOL rdp_print_remote_programs_capability_set(wLog* log,
wStream* s)
2561 UINT32 railSupportLevel = 0;
2562 WLog_Print(log, WLOG_TRACE,
2563 "RemoteProgramsCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2565 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2568 Stream_Read_UINT32(s, railSupportLevel);
2569 WLog_Print(log, WLOG_TRACE,
"\trailSupportLevel: 0x%08" PRIX32
"", railSupportLevel);
2574static BOOL rdp_apply_window_list_capability_set(rdpSettings* settings,
const rdpSettings* src)
2576 WINPR_ASSERT(settings);
2579 settings->RemoteWndSupportLevel = src->RemoteWndSupportLevel;
2580 settings->RemoteAppNumIconCaches = src->RemoteAppNumIconCaches;
2581 settings->RemoteAppNumIconCacheEntries = src->RemoteAppNumIconCacheEntries;
2591static BOOL rdp_read_window_list_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2593 WINPR_ASSERT(settings);
2594 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 7))
2597 Stream_Read_UINT32(s, settings->RemoteWndSupportLevel);
2598 Stream_Read_UINT8(s, settings->RemoteAppNumIconCaches);
2599 Stream_Read_UINT16(s,
2600 settings->RemoteAppNumIconCacheEntries);
2609static BOOL rdp_write_window_list_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
2611 WINPR_ASSERT(settings);
2612 if (!Stream_EnsureRemainingCapacity(s, 32))
2615 const size_t header = rdp_capability_set_start(log, s);
2616 Stream_Write_UINT32(s, settings->RemoteWndSupportLevel);
2618 s, WINPR_ASSERTING_INT_CAST(uint8_t,
2619 settings->RemoteAppNumIconCaches));
2620 Stream_Write_UINT16(
2622 WINPR_ASSERTING_INT_CAST(
2623 uint16_t, settings->RemoteAppNumIconCacheEntries));
2624 return rdp_capability_set_finish(s, header, CAPSET_TYPE_WINDOW);
2627#ifdef WITH_DEBUG_CAPABILITIES
2628static BOOL rdp_print_window_list_capability_set(wLog* log,
wStream* s)
2630 UINT32 wndSupportLevel = 0;
2631 BYTE numIconCaches = 0;
2632 UINT16 numIconCacheEntries = 0;
2633 WLog_Print(log, WLOG_TRACE,
2634 "WindowListCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2636 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 7))
2639 Stream_Read_UINT32(s, wndSupportLevel);
2640 Stream_Read_UINT8(s, numIconCaches);
2641 Stream_Read_UINT16(s, numIconCacheEntries);
2642 WLog_Print(log, WLOG_TRACE,
"\twndSupportLevel: 0x%08" PRIX32
"", wndSupportLevel);
2643 WLog_Print(log, WLOG_TRACE,
"\tnumIconCaches: 0x%02" PRIX8
"", numIconCaches);
2644 WLog_Print(log, WLOG_TRACE,
"\tnumIconCacheEntries: 0x%04" PRIX16
"", numIconCacheEntries);
2649static BOOL rdp_apply_desktop_composition_capability_set(rdpSettings* settings,
2650 const rdpSettings* src)
2652 WINPR_ASSERT(settings);
2655 settings->CompDeskSupportLevel = src->CompDeskSupportLevel;
2664static BOOL rdp_read_desktop_composition_capability_set(wLog* log,
wStream* s,
2665 rdpSettings* settings)
2667 WINPR_UNUSED(settings);
2668 WINPR_ASSERT(settings);
2670 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 2))
2673 Stream_Read_UINT16(s, settings->CompDeskSupportLevel);
2682static BOOL rdp_write_desktop_composition_capability_set(wLog* log,
wStream* s,
2683 const rdpSettings* settings)
2685 WINPR_ASSERT(settings);
2687 if (!Stream_EnsureRemainingCapacity(s, 32))
2690 const size_t header = rdp_capability_set_start(log, s);
2691 const UINT16 compDeskSupportLevel =
2692 (settings->AllowDesktopComposition) ? COMPDESK_SUPPORTED : COMPDESK_NOT_SUPPORTED;
2693 Stream_Write_UINT16(s, compDeskSupportLevel);
2694 return rdp_capability_set_finish(s, header, CAPSET_TYPE_COMP_DESK);
2697#ifdef WITH_DEBUG_CAPABILITIES
2698static BOOL rdp_print_desktop_composition_capability_set(wLog* log,
wStream* s)
2700 UINT16 compDeskSupportLevel = 0;
2701 WLog_Print(log, WLOG_TRACE,
"DesktopCompositionCapabilitySet (length %" PRIuz
"):",
2702 Stream_GetRemainingLength(s));
2704 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 2))
2707 Stream_Read_UINT16(s, compDeskSupportLevel);
2708 WLog_Print(log, WLOG_TRACE,
"\tcompDeskSupportLevel: 0x%04" PRIX16
"", compDeskSupportLevel);
2713static BOOL rdp_apply_multifragment_update_capability_set(rdpSettings* settings,
2714 const rdpSettings* src)
2716 WINPR_ASSERT(settings);
2719 UINT32 multifragMaxRequestSize =
2722 if (settings->ServerMode)
2732 if (multifragMaxRequestSize < FASTPATH_MAX_PACKET_SIZE)
2733 multifragMaxRequestSize = FASTPATH_FRAGMENT_SAFE_SIZE;
2735 if (settings->RemoteFxCodec)
2742 if (multifragMaxRequestSize <
2749 settings->RemoteFxCodec = FALSE;
2751 multifragMaxRequestSize))
2762 multifragMaxRequestSize))
2773 if (multifragMaxRequestSize >
2777 multifragMaxRequestSize))
2789static BOOL rdp_read_multifragment_update_capability_set(wLog* log,
wStream* s,
2790 rdpSettings* settings)
2792 WINPR_ASSERT(settings);
2793 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2796 const UINT32 multifragMaxRequestSize = Stream_Get_UINT32(s);
2798 multifragMaxRequestSize);
2806static BOOL rdp_write_multifragment_update_capability_set(wLog* log,
wStream* s,
2807 rdpSettings* settings)
2809 WINPR_ASSERT(settings);
2810 if (settings->ServerMode &&
2824 const UINT32 tileNumX = (settings->DesktopWidth + 63) / 64;
2825 const UINT32 tileNumY = (settings->DesktopHeight + 63) / 64;
2826 const UINT32 limit = UINT32_MAX / 16384u;
2828 if (tileNumX >= limit / tileNumY)
2830 WLog_Print(log, WLOG_ERROR,
2831 "(DesktopWidth * DesktopHeigth) / 64 exceed limit of %" PRIu32, limit);
2834 if (tileNumY >= limit / tileNumX)
2836 WLog_Print(log, WLOG_ERROR,
2837 "(DesktopWidth * DesktopHeigth) / 64 exceed limit of %" PRIu32, limit);
2842 const UINT32 MultifragMaxRequestSize = (tileNumX * tileNumY + 1u) * 16384u;
2845 MultifragMaxRequestSize))
2849 if (!Stream_EnsureRemainingCapacity(s, 32))
2851 const size_t header = rdp_capability_set_start(log, s);
2852 Stream_Write_UINT32(s, settings->MultifragMaxRequestSize);
2853 return rdp_capability_set_finish(s, header, CAPSET_TYPE_MULTI_FRAGMENT_UPDATE);
2856#ifdef WITH_DEBUG_CAPABILITIES
2857static BOOL rdp_print_multifragment_update_capability_set(wLog* log,
wStream* s)
2859 UINT32 maxRequestSize = 0;
2860 WLog_Print(log, WLOG_TRACE,
"MultifragmentUpdateCapabilitySet (length %" PRIuz
"):",
2861 Stream_GetRemainingLength(s));
2863 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2866 Stream_Read_UINT32(s, maxRequestSize);
2867 WLog_Print(log, WLOG_TRACE,
"\tmaxRequestSize: 0x%08" PRIX32
"", maxRequestSize);
2872static BOOL rdp_apply_large_pointer_capability_set(rdpSettings* settings,
const rdpSettings* src)
2874 WINPR_ASSERT(settings);
2877 settings->LargePointerFlag = src->LargePointerFlag;
2886static BOOL rdp_read_large_pointer_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2888 UINT16 largePointerSupportFlags = 0;
2890 WINPR_ASSERT(settings);
2891 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 2))
2894 Stream_Read_UINT16(s, largePointerSupportFlags);
2895 settings->LargePointerFlag &= largePointerSupportFlags;
2896 if ((largePointerSupportFlags & ~(LARGE_POINTER_FLAG_96x96 | LARGE_POINTER_FLAG_384x384)) != 0)
2900 "TS_LARGE_POINTER_CAPABILITYSET with unsupported flags %04X (all flags %04X) received",
2901 WINPR_CXX_COMPAT_CAST(UINT32, largePointerSupportFlags & ~(LARGE_POINTER_FLAG_96x96 |
2902 LARGE_POINTER_FLAG_384x384)),
2903 largePointerSupportFlags);
2913static BOOL rdp_write_large_pointer_capability_set(wLog* log,
wStream* s,
2914 const rdpSettings* settings)
2916 WINPR_ASSERT(settings);
2917 if (!Stream_EnsureRemainingCapacity(s, 32))
2920 const size_t header = rdp_capability_set_start(log, s);
2921 const UINT16 largePointerSupportFlags =
2922 settings->LargePointerFlag & (LARGE_POINTER_FLAG_96x96 | LARGE_POINTER_FLAG_384x384);
2923 Stream_Write_UINT16(s, largePointerSupportFlags);
2924 return rdp_capability_set_finish(s, header, CAPSET_TYPE_LARGE_POINTER);
2927#ifdef WITH_DEBUG_CAPABILITIES
2928static BOOL rdp_print_large_pointer_capability_set(wLog* log,
wStream* s)
2930 UINT16 largePointerSupportFlags = 0;
2931 WLog_Print(log, WLOG_TRACE,
2932 "LargePointerCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2934 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 2))
2937 Stream_Read_UINT16(s, largePointerSupportFlags);
2938 WLog_Print(log, WLOG_TRACE,
"\tlargePointerSupportFlags: 0x%04" PRIX16
"",
2939 largePointerSupportFlags);
2944static BOOL rdp_apply_surface_commands_capability_set(rdpSettings* settings,
const rdpSettings* src)
2946 WINPR_ASSERT(settings);
2953 if (src->FastPathOutput)
2955 settings->SurfaceCommandsSupported &= src->SurfaceCommandsSupported;
2956 settings->SurfaceCommandsEnabled = src->SurfaceCommandsEnabled;
2957 settings->SurfaceFrameMarkerEnabled = src->SurfaceFrameMarkerEnabled;
2961 settings->SurfaceCommandsSupported = 0;
2962 settings->SurfaceCommandsEnabled = FALSE;
2963 settings->SurfaceFrameMarkerEnabled = FALSE;
2974static BOOL rdp_read_surface_commands_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2976 UINT32 cmdFlags = 0;
2978 WINPR_ASSERT(settings);
2979 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
2982 Stream_Read_UINT32(s, cmdFlags);
2983 Stream_Seek_UINT32(s);
2984 settings->SurfaceCommandsSupported = cmdFlags;
2985 settings->SurfaceCommandsEnabled =
2986 (cmdFlags & (SURFCMDS_SET_SURFACE_BITS | SURFCMDS_STREAM_SURFACE_BITS)) != 0;
2987 settings->SurfaceFrameMarkerEnabled = (cmdFlags & SURFCMDS_FRAME_MARKER) != 0;
2996static BOOL rdp_write_surface_commands_capability_set(wLog* log,
wStream* s,
2997 const rdpSettings* settings)
2999 WINPR_ASSERT(settings);
3000 if (!Stream_EnsureRemainingCapacity(s, 32))
3003 const size_t header = rdp_capability_set_start(log, s);
3007 if (settings->SurfaceFrameMarkerEnabled)
3008 cmdFlags |= SURFCMDS_FRAME_MARKER;
3010 Stream_Write_UINT32(s, cmdFlags);
3011 Stream_Write_UINT32(s, 0);
3012 return rdp_capability_set_finish(s, header, CAPSET_TYPE_SURFACE_COMMANDS);
3015static bool sUuidEqual(
const UUID* Uuid1,
const UUID* Uuid2)
3017 if (!Uuid1 && !Uuid2)
3020 if (Uuid1 && !Uuid2)
3023 if (!Uuid1 && Uuid2)
3026 if (Uuid1->Data1 != Uuid2->Data1)
3029 if (Uuid1->Data2 != Uuid2->Data2)
3032 if (Uuid1->Data3 != Uuid2->Data3)
3035 for (
int index = 0; index < 8; index++)
3037 if (Uuid1->Data4[index] != Uuid2->Data4[index])
3044#ifdef WITH_DEBUG_CAPABILITIES
3045static BOOL rdp_print_surface_commands_capability_set(wLog* log,
wStream* s)
3047 UINT32 cmdFlags = 0;
3048 UINT32 reserved = 0;
3050 WLog_Print(log, WLOG_TRACE,
3051 "SurfaceCommandsCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
3053 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
3056 Stream_Read_UINT32(s, cmdFlags);
3057 Stream_Read_UINT32(s, reserved);
3058 WLog_Print(log, WLOG_TRACE,
"\tcmdFlags: 0x%08" PRIX32
"", cmdFlags);
3059 WLog_Print(log, WLOG_TRACE,
"\treserved: 0x%08" PRIX32
"", reserved);
3063static void rdp_print_bitmap_codec_guid(wLog* log,
const GUID* guid)
3066 WLog_Print(log, WLOG_TRACE,
3067 "%08" PRIX32
"%04" PRIX16
"%04" PRIX16
"%02" PRIX8
"%02" PRIX8
"%02" PRIX8
3068 "%02" PRIX8
"%02" PRIX8
"%02" PRIX8
"%02" PRIX8
"%02" PRIX8
"",
3069 guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], guid->Data4[1],
3070 guid->Data4[2], guid->Data4[3], guid->Data4[4], guid->Data4[5], guid->Data4[6],
3074static char* rdp_get_bitmap_codec_guid_name(
const GUID* guid)
3077 if (sUuidEqual(guid, &CODEC_GUID_REMOTEFX))
3078 return "CODEC_GUID_REMOTEFX";
3079 else if (sUuidEqual(guid, &CODEC_GUID_NSCODEC))
3080 return "CODEC_GUID_NSCODEC";
3081 else if (sUuidEqual(guid, &CODEC_GUID_IGNORE))
3082 return "CODEC_GUID_IGNORE";
3083 else if (sUuidEqual(guid, &CODEC_GUID_IMAGE_REMOTEFX))
3084 return "CODEC_GUID_IMAGE_REMOTEFX";
3086#if defined(WITH_JPEG)
3087 else if (sUuidEqual(guid, &CODEC_GUID_JPEG))
3088 return "CODEC_GUID_JPEG";
3091 return "CODEC_GUID_UNKNOWN";
3095static BOOL rdp_read_bitmap_codec_guid(wLog* log,
wStream* s, GUID* guid)
3097 BYTE g[16] = WINPR_C_ARRAY_INIT;
3100 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 16))
3102 Stream_Read(s, g, 16);
3103 guid->Data1 = ((UINT32)g[3] << 24U) | ((UINT32)g[2] << 16U) | (UINT32)(g[1] << 8U) | g[0];
3104 guid->Data2 = ((g[5] << 8U) | g[4]) & 0xFFFF;
3105 guid->Data3 = ((g[7] << 8U) | g[6]) & 0xFFFF;
3106 guid->Data4[0] = g[8];
3107 guid->Data4[1] = g[9];
3108 guid->Data4[2] = g[10];
3109 guid->Data4[3] = g[11];
3110 guid->Data4[4] = g[12];
3111 guid->Data4[5] = g[13];
3112 guid->Data4[6] = g[14];
3113 guid->Data4[7] = g[15];
3117static void rdp_write_bitmap_codec_guid(
wStream* s,
const GUID* guid)
3119 BYTE g[16] = WINPR_C_ARRAY_INIT;
3121 g[0] = guid->Data1 & 0xFF;
3122 g[1] = (guid->Data1 >> 8) & 0xFF;
3123 g[2] = (guid->Data1 >> 16) & 0xFF;
3124 g[3] = (guid->Data1 >> 24) & 0xFF;
3125 g[4] = (guid->Data2) & 0xFF;
3126 g[5] = (guid->Data2 >> 8) & 0xFF;
3127 g[6] = (guid->Data3) & 0xFF;
3128 g[7] = (guid->Data3 >> 8) & 0xFF;
3129 g[8] = guid->Data4[0];
3130 g[9] = guid->Data4[1];
3131 g[10] = guid->Data4[2];
3132 g[11] = guid->Data4[3];
3133 g[12] = guid->Data4[4];
3134 g[13] = guid->Data4[5];
3135 g[14] = guid->Data4[6];
3136 g[15] = guid->Data4[7];
3137 Stream_Write(s, g, 16);
3140static BOOL rdp_apply_bitmap_codecs_capability_set(rdpSettings* settings,
const rdpSettings* src)
3142 WINPR_ASSERT(settings);
3145 if (settings->ServerMode)
3148 settings->RemoteFxCodecId = src->RemoteFxCodecId;
3149 settings->RemoteFxCaptureFlags = src->RemoteFxCaptureFlags;
3150 settings->RemoteFxOnly = src->RemoteFxOnly;
3151 settings->RemoteFxRlgrMode = src->RemoteFxRlgrMode;
3152 settings->RemoteFxCodecMode = src->RemoteFxCodecMode;
3153 settings->NSCodecId = src->NSCodecId;
3154 settings->NSCodecAllowDynamicColorFidelity = src->NSCodecAllowDynamicColorFidelity;
3155 settings->NSCodecAllowSubsampling = src->NSCodecAllowSubsampling;
3156 settings->NSCodecColorLossLevel = src->NSCodecColorLossLevel;
3159 settings->RemoteFxCodec = settings->RemoteFxCodec && src->RemoteFxCodecId;
3160 settings->RemoteFxImageCodec = settings->RemoteFxImageCodec && src->RemoteFxImageCodec;
3162 settings->NSCodec && src->NSCodec))
3164 settings->JpegCodec = src->JpegCodec;
3169static BOOL rdp_read_codec_ts_rfx_icap(wLog* log,
wStream* sub, rdpSettings* settings,
3173 UINT16 tileSize = 0;
3174 BYTE codecFlags = 0;
3175 BYTE colConvBits = 0;
3176 BYTE transformBits = 0;
3177 BYTE entropyBits = 0;
3181 WLog_Print(log, WLOG_ERROR,
3182 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP size %" PRIu16
3183 " unsupported, expecting size %" PRIu16
" not supported",
3188 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 8))
3191 Stream_Read_UINT16(sub, version);
3192 Stream_Read_UINT16(sub, tileSize);
3193 Stream_Read_UINT8(sub, codecFlags);
3194 Stream_Read_UINT8(sub, colConvBits);
3195 Stream_Read_UINT8(sub, transformBits);
3196 Stream_Read_UINT8(sub, entropyBits);
3198 if (version == 0x0009)
3201 if (tileSize != 0x0080)
3203 WLog_Print(log, WLOG_ERROR,
3204 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::version %" PRIu16
3205 " tile size %" PRIu16
" not supported",
3210 else if (version == 0x0100)
3213 if (tileSize != 0x0040)
3215 WLog_Print(log, WLOG_ERROR,
3216 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::version %" PRIu16
3217 " tile size %" PRIu16
" not supported",
3224 WLog_Print(log, WLOG_ERROR,
3225 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::version %" PRIu16
" not supported",
3231 if (colConvBits != 1)
3233 WLog_Print(log, WLOG_ERROR,
3234 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::colConvBits %" PRIu8
3235 " not supported, must be CLW_COL_CONV_ICT (0x1)",
3241 if (transformBits != 1)
3243 WLog_Print(log, WLOG_ERROR,
3244 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::transformBits %" PRIu8
3245 " not supported, must be CLW_XFORM_DWT_53_A (0x1)",
3250 const UINT8 CODEC_MODE = 0x02;
3254 if ((codecFlags & CODEC_MODE) != 0)
3259 else if ((codecFlags & ~CODEC_MODE) != 0)
3260 WLog_Print(log, WLOG_WARN,
3261 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::flags unknown value "
3263 WINPR_CXX_COMPAT_CAST(UINT32, (codecFlags & ~CODEC_MODE)));
3265 switch (entropyBits)
3267 case CLW_ENTROPY_RLGR1:
3271 case CLW_ENTROPY_RLGR3:
3276 WLog_Print(log, WLOG_ERROR,
3277 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::entropyBits "
3278 "unsupported value 0x%02" PRIx8
3279 ", must be CLW_ENTROPY_RLGR1 (0x01) or CLW_ENTROPY_RLGR3 "
3287static BOOL rdp_read_codec_ts_rfx_capset(wLog* log,
wStream* s, rdpSettings* settings)
3289 UINT16 blockType = 0;
3290 UINT32 blockLen = 0;
3291 BYTE rfxCodecId = 0;
3292 UINT16 capsetType = 0;
3293 UINT16 numIcaps = 0;
3296 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 6))
3300 Stream_Read_UINT16(s, blockType);
3301 Stream_Read_UINT32(s, blockLen);
3302 if (blockType != 0xCBC1)
3304 WLog_Print(log, WLOG_ERROR,
3305 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::blockType[0x%04" PRIx16
3306 "] != CBY_CAPSET (0xCBC1)",
3310 if (blockLen < 6ull)
3312 WLog_Print(log, WLOG_ERROR,
3313 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::blockLen[%" PRIu32
"] < 6", blockLen);
3316 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, blockLen - 6ull))
3319 wStream sbuffer = WINPR_C_ARRAY_INIT;
3320 wStream* sub = Stream_StaticConstInit(&sbuffer, Stream_Pointer(s), blockLen - 6ull);
3323 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 7))
3326 Stream_Read_UINT8(sub, rfxCodecId);
3327 Stream_Read_UINT16(sub, capsetType);
3328 Stream_Read_UINT16(sub, numIcaps);
3329 Stream_Read_UINT16(sub, icapLen);
3331 if (rfxCodecId != 1)
3333 WLog_Print(log, WLOG_ERROR,
3334 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::codecId[%" PRIu16
"] != 1", rfxCodecId);
3338 if (capsetType != 0xCFC0)
3340 WLog_Print(log, WLOG_ERROR,
3341 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::capsetType[0x%04" PRIx16
3342 "] != CLY_CAPSET (0xCFC0)",
3349 if (!rdp_read_codec_ts_rfx_icap(log, sub, settings, icapLen))
3355static BOOL rdp_read_codec_ts_rfx_caps(wLog* log,
wStream* sub, rdpSettings* settings)
3357 if (Stream_GetRemainingLength(sub) == 0)
3360 UINT16 blockType = 0;
3361 UINT32 blockLen = 0;
3362 UINT16 numCapsets = 0;
3365 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 8))
3367 Stream_Read_UINT16(sub, blockType);
3368 Stream_Read_UINT32(sub, blockLen);
3369 Stream_Read_UINT16(sub, numCapsets);
3371 if (blockType != 0xCBC0)
3373 WLog_Print(log, WLOG_ERROR,
3374 "[MS_RDPRFX] 2.2.1.1.1 TS_RFX_CAPS::blockType[0x%04" PRIx16
3375 "] != CBY_CAPS (0xCBC0)",
3382 WLog_Print(log, WLOG_ERROR,
"[MS_RDPRFX] 2.2.1.1.1 TS_RFX_CAPS::blockLen[%" PRIu16
"] != 8",
3387 if (numCapsets != 1)
3389 WLog_Print(log, WLOG_ERROR,
3390 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::numIcaps[%" PRIu16
"] != 1", numCapsets);
3394 for (UINT16 x = 0; x < numCapsets; x++)
3396 if (!rdp_read_codec_ts_rfx_capset(log, sub, settings))
3403static BOOL rdp_read_codec_ts_rfx_clnt_caps_container(wLog* log,
wStream* s, rdpSettings* settings)
3405 UINT32 rfxCapsLength = 0;
3406 UINT32 rfxPropsLength = 0;
3407 UINT32 captureFlags = 0;
3410 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
3412 Stream_Read_UINT32(s, rfxPropsLength);
3413 if (rfxPropsLength < 4)
3415 WLog_Print(log, WLOG_ERROR,
3416 "[MS_RDPRFX] 2.2.1.1 TS_RFX_CLNT_CAPS_CONTAINER::length %" PRIu32
3417 " too short, require at least 4 bytes",
3421 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, rfxPropsLength - 4ull))
3424 wStream sbuffer = WINPR_C_ARRAY_INIT;
3425 wStream* sub = Stream_StaticConstInit(&sbuffer, Stream_Pointer(s), rfxPropsLength - 4ull);
3428 Stream_Seek(s, rfxPropsLength - 4ull);
3430 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 8))
3433 Stream_Read_UINT32(sub, captureFlags);
3434 Stream_Read_UINT32(sub, rfxCapsLength);
3435 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, rfxCapsLength))
3438 settings->RemoteFxCaptureFlags = captureFlags;
3439 settings->RemoteFxOnly = !(captureFlags & CARDP_CAPS_CAPTURE_NON_CAC);
3442 wStream tsbuffer = WINPR_C_ARRAY_INIT;
3443 wStream* ts_sub = Stream_StaticConstInit(&tsbuffer, Stream_Pointer(sub), rfxCapsLength);
3444 WINPR_ASSERT(ts_sub);
3445 return rdp_read_codec_ts_rfx_caps(log, ts_sub, settings);
3453static BOOL rdp_read_bitmap_codecs_capability_set(wLog* log,
wStream* s, rdpSettings* settings,
3457 GUID codecGuid = WINPR_C_ARRAY_INIT;
3458 BYTE bitmapCodecCount = 0;
3459 UINT16 codecPropertiesLength = 0;
3461 BOOL guidNSCodec = FALSE;
3462 BOOL guidRemoteFx = FALSE;
3463 BOOL guidRemoteFxImage = FALSE;
3465 WINPR_ASSERT(settings);
3466 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 1))
3469 Stream_Read_UINT8(s, bitmapCodecCount);
3471 while (bitmapCodecCount > 0)
3473 wStream subbuffer = WINPR_C_ARRAY_INIT;
3475 if (!rdp_read_bitmap_codec_guid(log, s, &codecGuid))
3477 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 3))
3479 Stream_Read_UINT8(s, codecId);
3480 Stream_Read_UINT16(s, codecPropertiesLength);
3482 wStream* sub = Stream_StaticInit(&subbuffer, Stream_Pointer(s), codecPropertiesLength);
3483 if (!Stream_SafeSeek(s, codecPropertiesLength))
3488 if (sUuidEqual(&codecGuid, &CODEC_GUID_REMOTEFX))
3490 guidRemoteFx = TRUE;
3491 settings->RemoteFxCodecId = codecId;
3492 if (!rdp_read_codec_ts_rfx_clnt_caps_container(log, sub, settings))
3495 else if (sUuidEqual(&codecGuid, &CODEC_GUID_IMAGE_REMOTEFX))
3498 guidRemoteFxImage = TRUE;
3499 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3502 else if (sUuidEqual(&codecGuid, &CODEC_GUID_NSCODEC))
3504 BYTE colorLossLevel = 0;
3505 BYTE fAllowSubsampling = 0;
3506 BYTE fAllowDynamicFidelity = 0;
3508 settings->NSCodecId = codecId;
3509 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 3))
3511 Stream_Read_UINT8(sub, fAllowDynamicFidelity);
3512 Stream_Read_UINT8(sub, fAllowSubsampling);
3513 Stream_Read_UINT8(sub, colorLossLevel);
3515 if (colorLossLevel < 1)
3518 if (colorLossLevel > 7)
3521 settings->NSCodecAllowDynamicColorFidelity = fAllowDynamicFidelity;
3522 settings->NSCodecAllowSubsampling = fAllowSubsampling;
3523 settings->NSCodecColorLossLevel = colorLossLevel;
3525 else if (sUuidEqual(&codecGuid, &CODEC_GUID_IGNORE))
3527 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3532 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3538 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3542 const size_t rest = Stream_GetRemainingLength(sub);
3545 WLog_Print(log, WLOG_ERROR,
3546 "error while reading codec properties: actual size: %" PRIuz
3547 " expected size: %" PRIu32
"",
3548 rest + codecPropertiesLength, codecPropertiesLength);
3569static BOOL rdp_write_rfx_client_capability_container(
wStream* s,
const rdpSettings* settings)
3571 WINPR_ASSERT(settings);
3572 if (!Stream_EnsureRemainingCapacity(s, 64))
3575 const UINT32 captureFlags = settings->RemoteFxOnly ? 0 : CARDP_CAPS_CAPTURE_NON_CAC;
3577 WINPR_ASSERT(settings->RemoteFxCodecMode <= UINT8_MAX);
3578 const UINT8 codecMode = (UINT8)settings->RemoteFxCodecMode;
3579 Stream_Write_UINT16(s, 49);
3581 Stream_Write_UINT32(s, 49);
3582 Stream_Write_UINT32(s, captureFlags);
3583 Stream_Write_UINT32(s, 37);
3585 Stream_Write_UINT16(s, CBY_CAPS);
3586 Stream_Write_UINT32(s, 8);
3587 Stream_Write_UINT16(s, 1);
3589 Stream_Write_UINT16(s, CBY_CAPSET);
3590 Stream_Write_UINT32(s, 29);
3591 Stream_Write_UINT8(s, 0x01);
3592 Stream_Write_UINT16(s, CLY_CAPSET);
3593 Stream_Write_UINT16(s, 2);
3594 Stream_Write_UINT16(s, 8);
3596 Stream_Write_UINT16(s, CLW_VERSION_1_0);
3597 Stream_Write_UINT16(s, CT_TILE_64x64);
3598 Stream_Write_UINT8(s, codecMode);
3599 Stream_Write_UINT8(s, CLW_COL_CONV_ICT);
3600 Stream_Write_UINT8(s, CLW_XFORM_DWT_53_A);
3601 Stream_Write_UINT8(s, CLW_ENTROPY_RLGR1);
3603 Stream_Write_UINT16(s, CLW_VERSION_1_0);
3604 Stream_Write_UINT16(s, CT_TILE_64x64);
3605 Stream_Write_UINT8(s, codecMode);
3606 Stream_Write_UINT8(s, CLW_COL_CONV_ICT);
3607 Stream_Write_UINT8(s, CLW_XFORM_DWT_53_A);
3608 Stream_Write_UINT8(s, CLW_ENTROPY_RLGR3);
3615static BOOL rdp_write_nsc_client_capability_container(
wStream* s,
const rdpSettings* settings)
3617 WINPR_ASSERT(settings);
3619 const BOOL fAllowDynamicFidelity = settings->NSCodecAllowDynamicColorFidelity;
3620 const BOOL fAllowSubsampling = settings->NSCodecAllowSubsampling;
3621 UINT32 colorLossLevel = settings->NSCodecColorLossLevel;
3623 if (colorLossLevel < 1)
3626 if (colorLossLevel > 7)
3629 if (!Stream_EnsureRemainingCapacity(s, 8))
3632 Stream_Write_UINT16(s, 3);
3634 Stream_Write_UINT8(s, fAllowDynamicFidelity != 0);
3635 Stream_Write_UINT8(s, fAllowSubsampling != 0);
3636 Stream_Write_UINT8(s, (UINT8)colorLossLevel);
3640#if defined(WITH_JPEG)
3641static BOOL rdp_write_jpeg_client_capability_container(
wStream* s,
const rdpSettings* settings)
3643 WINPR_ASSERT(settings);
3644 if (!Stream_EnsureRemainingCapacity(s, 8))
3647 Stream_Write_UINT16(s, 1);
3650 Stream_Write_UINT8(s, WINPR_ASSERTING_INT_CAST(UINT8, q));
3658static BOOL rdp_write_rfx_server_capability_container(
wStream* s,
const rdpSettings* settings)
3660 WINPR_UNUSED(settings);
3661 WINPR_ASSERT(settings);
3663 if (!Stream_EnsureRemainingCapacity(s, 8))
3666 Stream_Write_UINT16(s, 4);
3667 Stream_Write_UINT32(s, 0);
3671#if defined(WITH_JPEG)
3672static BOOL rdp_write_jpeg_server_capability_container(
wStream* s,
const rdpSettings* settings)
3674 WINPR_UNUSED(settings);
3675 WINPR_ASSERT(settings);
3677 if (!Stream_EnsureRemainingCapacity(s, 8))
3680 Stream_Write_UINT16(s, 1);
3681 Stream_Write_UINT8(s, 75);
3689static BOOL rdp_write_nsc_server_capability_container(
wStream* s,
const rdpSettings* settings)
3691 WINPR_UNUSED(settings);
3692 WINPR_ASSERT(settings);
3694 if (!Stream_EnsureRemainingCapacity(s, 8))
3697 Stream_Write_UINT16(s, 4);
3698 Stream_Write_UINT32(s, 0);
3707static BOOL rdp_write_bitmap_codecs_capability_set(wLog* log,
wStream* s,
3708 const rdpSettings* settings)
3710 WINPR_ASSERT(settings);
3711 if (!Stream_EnsureRemainingCapacity(s, 64))
3714 const size_t header = rdp_capability_set_start(log, s);
3715 BYTE bitmapCodecCount = 0;
3717 if (settings->RemoteFxCodec)
3723#if defined(WITH_JPEG)
3725 if (settings->JpegCodec)
3730 if (settings->RemoteFxImageCodec)
3733 Stream_Write_UINT8(s, bitmapCodecCount);
3735 if (settings->RemoteFxCodec)
3737 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_REMOTEFX);
3739 if (settings->ServerMode)
3741 Stream_Write_UINT8(s, 0);
3743 if (!rdp_write_rfx_server_capability_container(s, settings))
3748 Stream_Write_UINT8(s, RDP_CODEC_ID_REMOTEFX);
3750 if (!rdp_write_rfx_client_capability_container(s, settings))
3757 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_NSCODEC);
3759 if (settings->ServerMode)
3761 Stream_Write_UINT8(s, 0);
3763 if (!rdp_write_nsc_server_capability_container(s, settings))
3768 Stream_Write_UINT8(s, RDP_CODEC_ID_NSCODEC);
3770 if (!rdp_write_nsc_client_capability_container(s, settings))
3775#if defined(WITH_JPEG)
3777 if (settings->JpegCodec)
3779 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_JPEG);
3781 if (settings->ServerMode)
3783 Stream_Write_UINT8(s, 0);
3785 if (!rdp_write_jpeg_server_capability_container(s, settings))
3790 Stream_Write_UINT8(s, RDP_CODEC_ID_JPEG);
3792 if (!rdp_write_jpeg_client_capability_container(s, settings))
3799 if (settings->RemoteFxImageCodec)
3801 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_IMAGE_REMOTEFX);
3803 if (settings->ServerMode)
3805 Stream_Write_UINT8(s, 0);
3807 if (!rdp_write_rfx_server_capability_container(s, settings))
3812 Stream_Write_UINT8(s, RDP_CODEC_ID_IMAGE_REMOTEFX);
3814 if (!rdp_write_rfx_client_capability_container(s, settings))
3819 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CODECS);
3822#ifdef WITH_DEBUG_CAPABILITIES
3823static BOOL rdp_print_bitmap_codecs_capability_set(wLog* log,
wStream* s)
3825 GUID codecGuid = WINPR_C_ARRAY_INIT;
3826 BYTE bitmapCodecCount = 0;
3828 UINT16 codecPropertiesLength = 0;
3830 WLog_Print(log, WLOG_TRACE,
3831 "BitmapCodecsCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
3833 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 1))
3836 Stream_Read_UINT8(s, bitmapCodecCount);
3837 WLog_Print(log, WLOG_TRACE,
"\tbitmapCodecCount: %" PRIu8
"", bitmapCodecCount);
3839 while (bitmapCodecCount > 0)
3841 if (!rdp_read_bitmap_codec_guid(log, s, &codecGuid))
3843 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 3))
3845 Stream_Read_UINT8(s, codecId);
3846 WLog_Print(log, WLOG_TRACE,
"\tcodecGuid: 0x");
3847 rdp_print_bitmap_codec_guid(log, &codecGuid);
3848 WLog_Print(log, WLOG_TRACE,
" (%s)", rdp_get_bitmap_codec_guid_name(&codecGuid));
3849 WLog_Print(log, WLOG_TRACE,
"\tcodecId: %" PRIu8
"", codecId);
3850 Stream_Read_UINT16(s, codecPropertiesLength);
3851 WLog_Print(log, WLOG_TRACE,
"\tcodecPropertiesLength: %" PRIu16
"", codecPropertiesLength);
3853 if (!Stream_SafeSeek(s, codecPropertiesLength))
3862static BOOL rdp_apply_frame_acknowledge_capability_set(rdpSettings* settings,
3863 const rdpSettings* src)
3865 WINPR_ASSERT(settings);
3868 if (settings->ServerMode)
3869 settings->FrameAcknowledge = src->FrameAcknowledge;
3878static BOOL rdp_read_frame_acknowledge_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
3880 WINPR_ASSERT(settings);
3881 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
3884 Stream_Read_UINT32(s, settings->FrameAcknowledge);
3893static BOOL rdp_write_frame_acknowledge_capability_set(wLog* log,
wStream* s,
3894 const rdpSettings* settings)
3896 WINPR_ASSERT(settings);
3897 if (!Stream_EnsureRemainingCapacity(s, 32))
3900 const size_t header = rdp_capability_set_start(log, s);
3901 Stream_Write_UINT32(s, settings->FrameAcknowledge);
3902 return rdp_capability_set_finish(s, header, CAPSET_TYPE_FRAME_ACKNOWLEDGE);
3905#ifdef WITH_DEBUG_CAPABILITIES
3906static BOOL rdp_print_frame_acknowledge_capability_set(wLog* log,
wStream* s)
3908 UINT32 frameAcknowledge = 0;
3909 WLog_Print(log, WLOG_TRACE,
3910 "FrameAcknowledgeCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
3912 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
3915 Stream_Read_UINT32(s, frameAcknowledge);
3916 WLog_Print(log, WLOG_TRACE,
"\tframeAcknowledge: 0x%08" PRIX32
"", frameAcknowledge);
3921static BOOL rdp_apply_bitmap_cache_v3_codec_id_capability_set(rdpSettings* settings,
3922 const rdpSettings* src)
3924 WINPR_ASSERT(settings);
3927 settings->BitmapCacheV3CodecId = src->BitmapCacheV3CodecId;
3931static BOOL rdp_read_bitmap_cache_v3_codec_id_capability_set(wLog* log,
wStream* s,
3932 rdpSettings* settings)
3934 BYTE bitmapCacheV3CodecId = 0;
3936 WINPR_ASSERT(settings);
3937 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 1))
3940 Stream_Read_UINT8(s, bitmapCacheV3CodecId);
3941 settings->BitmapCacheV3CodecId = bitmapCacheV3CodecId;
3945static BOOL rdp_write_bitmap_cache_v3_codec_id_capability_set(wLog* log,
wStream* s,
3946 const rdpSettings* settings)
3948 WINPR_ASSERT(settings);
3949 if (!Stream_EnsureRemainingCapacity(s, 32))
3952 const size_t header = rdp_capability_set_start(log, s);
3953 if (settings->BitmapCacheV3CodecId > UINT8_MAX)
3955 Stream_Write_UINT8(s, (UINT8)settings->BitmapCacheV3CodecId);
3956 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID);
3959#ifdef WITH_DEBUG_CAPABILITIES
3960static BOOL rdp_print_bitmap_cache_v3_codec_id_capability_set(wLog* log,
wStream* s)
3962 BYTE bitmapCacheV3CodecId = 0;
3963 WLog_Print(log, WLOG_TRACE,
"BitmapCacheV3CodecIdCapabilitySet (length %" PRIuz
"):",
3964 Stream_GetRemainingLength(s));
3966 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 1))
3969 Stream_Read_UINT8(s, bitmapCacheV3CodecId);
3970 WLog_Print(log, WLOG_TRACE,
"\tbitmapCacheV3CodecId: 0x%02" PRIX8
"", bitmapCacheV3CodecId);
3974BOOL rdp_print_capability_sets(wLog* log,
wStream* s,
size_t start, BOOL receiving)
3979 UINT16 numberCapabilities = 0;
3981 size_t pos = Stream_GetPosition(s);
3983 if (!Stream_SetPosition(s, start))
3988 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
3993 if (!Stream_CheckAndLogRequiredCapacityWLog(log, (s), 4))
3997 Stream_Read_UINT16(s, numberCapabilities);
4000 while (numberCapabilities > 0)
4006 if (!rdp_read_capability_set_header(log, s, &length, &type))
4009 WLog_Print(log, WLOG_TRACE,
"%s ", receiving ?
"Receiving" :
"Sending");
4010 sub = Stream_StaticInit(&subBuffer, Stream_Pointer(s), length - 4);
4011 if (!Stream_SafeSeek(s, length - 4))
4016 case CAPSET_TYPE_GENERAL:
4017 if (!rdp_print_general_capability_set(log, sub))
4022 case CAPSET_TYPE_BITMAP:
4023 if (!rdp_print_bitmap_capability_set(log, sub))
4028 case CAPSET_TYPE_ORDER:
4029 if (!rdp_print_order_capability_set(log, sub))
4034 case CAPSET_TYPE_BITMAP_CACHE:
4035 if (!rdp_print_bitmap_cache_capability_set(log, sub))
4040 case CAPSET_TYPE_CONTROL:
4041 if (!rdp_print_control_capability_set(log, sub))
4046 case CAPSET_TYPE_ACTIVATION:
4047 if (!rdp_print_window_activation_capability_set(log, sub))
4052 case CAPSET_TYPE_POINTER:
4053 if (!rdp_print_pointer_capability_set(log, sub))
4058 case CAPSET_TYPE_SHARE:
4059 if (!rdp_print_share_capability_set(log, sub))
4064 case CAPSET_TYPE_COLOR_CACHE:
4065 if (!rdp_print_color_cache_capability_set(log, sub))
4070 case CAPSET_TYPE_SOUND:
4071 if (!rdp_print_sound_capability_set(log, sub))
4076 case CAPSET_TYPE_INPUT:
4077 if (!rdp_print_input_capability_set(log, sub))
4082 case CAPSET_TYPE_FONT:
4083 if (!rdp_print_font_capability_set(log, sub))
4088 case CAPSET_TYPE_BRUSH:
4089 if (!rdp_print_brush_capability_set(log, sub))
4094 case CAPSET_TYPE_GLYPH_CACHE:
4095 if (!rdp_print_glyph_cache_capability_set(log, sub))
4100 case CAPSET_TYPE_OFFSCREEN_CACHE:
4101 if (!rdp_print_offscreen_bitmap_cache_capability_set(log, sub))
4106 case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
4107 if (!rdp_print_bitmap_cache_host_support_capability_set(log, sub))
4112 case CAPSET_TYPE_BITMAP_CACHE_V2:
4113 if (!rdp_print_bitmap_cache_v2_capability_set(log, sub))
4118 case CAPSET_TYPE_VIRTUAL_CHANNEL:
4119 if (!rdp_print_virtual_channel_capability_set(log, sub))
4124 case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
4125 if (!rdp_print_draw_nine_grid_cache_capability_set(log, sub))
4130 case CAPSET_TYPE_DRAW_GDI_PLUS:
4131 if (!rdp_print_draw_gdiplus_cache_capability_set(log, sub))
4136 case CAPSET_TYPE_RAIL:
4137 if (!rdp_print_remote_programs_capability_set(log, sub))
4142 case CAPSET_TYPE_WINDOW:
4143 if (!rdp_print_window_list_capability_set(log, sub))
4148 case CAPSET_TYPE_COMP_DESK:
4149 if (!rdp_print_desktop_composition_capability_set(log, sub))
4154 case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
4155 if (!rdp_print_multifragment_update_capability_set(log, sub))
4160 case CAPSET_TYPE_LARGE_POINTER:
4161 if (!rdp_print_large_pointer_capability_set(log, sub))
4166 case CAPSET_TYPE_SURFACE_COMMANDS:
4167 if (!rdp_print_surface_commands_capability_set(log, sub))
4172 case CAPSET_TYPE_BITMAP_CODECS:
4173 if (!rdp_print_bitmap_codecs_capability_set(log, sub))
4178 case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
4179 if (!rdp_print_frame_acknowledge_capability_set(log, sub))
4184 case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID:
4185 if (!rdp_print_bitmap_cache_v3_codec_id_capability_set(log, sub))
4191 WLog_Print(log, WLOG_ERROR,
"unknown capability type %" PRIu16
"", type);
4195 rest = Stream_GetRemainingLength(sub);
4198 WLog_Print(log, WLOG_WARN,
4199 "incorrect capability offset, type:0x%04" PRIX16
" %" PRIu16
4200 " bytes expected, %" PRIuz
"bytes remaining",
4201 type, length, rest);
4204 numberCapabilities--;
4209 if (!Stream_SetPosition(s, pos))
4216static BOOL rdp_apply_from_received(UINT16 type, rdpSettings* dst,
const rdpSettings* src)
4220 case CAPSET_TYPE_GENERAL:
4221 return rdp_apply_general_capability_set(dst, src);
4222 case CAPSET_TYPE_BITMAP:
4223 return rdp_apply_bitmap_capability_set(dst, src);
4224 case CAPSET_TYPE_ORDER:
4225 return rdp_apply_order_capability_set(dst, src);
4226 case CAPSET_TYPE_POINTER:
4227 return rdp_apply_pointer_capability_set(dst, src);
4228 case CAPSET_TYPE_INPUT:
4229 return rdp_apply_input_capability_set(dst, src);
4230 case CAPSET_TYPE_VIRTUAL_CHANNEL:
4231 return rdp_apply_virtual_channel_capability_set(dst, src);
4232 case CAPSET_TYPE_SHARE:
4233 return rdp_apply_share_capability_set(dst, src);
4234 case CAPSET_TYPE_COLOR_CACHE:
4235 return rdp_apply_color_cache_capability_set(dst, src);
4236 case CAPSET_TYPE_FONT:
4237 return rdp_apply_font_capability_set(dst, src);
4238 case CAPSET_TYPE_DRAW_GDI_PLUS:
4239 return rdp_apply_draw_gdiplus_cache_capability_set(dst, src);
4240 case CAPSET_TYPE_RAIL:
4241 return rdp_apply_remote_programs_capability_set(dst, src);
4242 case CAPSET_TYPE_WINDOW:
4243 return rdp_apply_window_list_capability_set(dst, src);
4244 case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
4245 return rdp_apply_multifragment_update_capability_set(dst, src);
4246 case CAPSET_TYPE_LARGE_POINTER:
4247 return rdp_apply_large_pointer_capability_set(dst, src);
4248 case CAPSET_TYPE_COMP_DESK:
4249 return rdp_apply_desktop_composition_capability_set(dst, src);
4250 case CAPSET_TYPE_SURFACE_COMMANDS:
4251 return rdp_apply_surface_commands_capability_set(dst, src);
4252 case CAPSET_TYPE_BITMAP_CODECS:
4253 return rdp_apply_bitmap_codecs_capability_set(dst, src);
4254 case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
4255 return rdp_apply_frame_acknowledge_capability_set(dst, src);
4256 case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID:
4257 return rdp_apply_bitmap_cache_v3_codec_id_capability_set(dst, src);
4258 case CAPSET_TYPE_BITMAP_CACHE:
4259 return rdp_apply_bitmap_cache_capability_set(dst, src);
4260 case CAPSET_TYPE_BITMAP_CACHE_V2:
4261 return rdp_apply_bitmap_cache_v2_capability_set(dst, src);
4262 case CAPSET_TYPE_BRUSH:
4263 return rdp_apply_brush_capability_set(dst, src);
4264 case CAPSET_TYPE_GLYPH_CACHE:
4265 return rdp_apply_glyph_cache_capability_set(dst, src);
4266 case CAPSET_TYPE_OFFSCREEN_CACHE:
4267 return rdp_apply_offscreen_bitmap_cache_capability_set(dst, src);
4268 case CAPSET_TYPE_SOUND:
4269 return rdp_apply_sound_capability_set(dst, src);
4270 case CAPSET_TYPE_CONTROL:
4271 return rdp_apply_control_capability_set(dst, src);
4272 case CAPSET_TYPE_ACTIVATION:
4273 return rdp_apply_window_activation_capability_set(dst, src);
4274 case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
4275 return rdp_apply_draw_nine_grid_cache_capability_set(dst, src);
4276 case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
4277 return rdp_apply_bitmap_cache_host_support_capability_set(dst, src);
4283BOOL rdp_read_capability_set(wLog* log,
wStream* sub, UINT16 type, rdpSettings* settings,
4286 WINPR_ASSERT(settings);
4288 if (type <= CAPSET_TYPE_FRAME_ACKNOWLEDGE)
4290 const size_t size = Stream_Length(sub);
4291 if (size > UINT32_MAX)
4294 WINPR_ASSERT(settings->ReceivedCapabilities);
4295 settings->ReceivedCapabilities[type] = TRUE;
4297 WINPR_ASSERT(settings->ReceivedCapabilityDataSizes);
4298 settings->ReceivedCapabilityDataSizes[type] = (UINT32)size;
4300 WINPR_ASSERT(settings->ReceivedCapabilityData);
4301 void* tmp = realloc(settings->ReceivedCapabilityData[type], size);
4302 if (!tmp && (size > 0))
4305 memcpy(tmp, Stream_Buffer(sub), size);
4306 settings->ReceivedCapabilityData[type] = tmp;
4309 WLog_Print(log, WLOG_WARN,
"not handling capability type %" PRIu16
" yet", type);
4311 BOOL treated = TRUE;
4315 case CAPSET_TYPE_GENERAL:
4316 if (!rdp_read_general_capability_set(log, sub, settings))
4321 case CAPSET_TYPE_BITMAP:
4322 if (!rdp_read_bitmap_capability_set(log, sub, settings))
4327 case CAPSET_TYPE_ORDER:
4328 if (!rdp_read_order_capability_set(log, sub, settings))
4333 case CAPSET_TYPE_POINTER:
4334 if (!rdp_read_pointer_capability_set(log, sub, settings))
4339 case CAPSET_TYPE_INPUT:
4340 if (!rdp_read_input_capability_set(log, sub, settings, isServer))
4345 case CAPSET_TYPE_VIRTUAL_CHANNEL:
4346 if (!rdp_read_virtual_channel_capability_set(log, sub, settings))
4351 case CAPSET_TYPE_SHARE:
4352 if (!rdp_read_share_capability_set(log, sub, settings))
4357 case CAPSET_TYPE_COLOR_CACHE:
4358 if (!rdp_read_color_cache_capability_set(log, sub, settings))
4363 case CAPSET_TYPE_FONT:
4364 if (!rdp_read_font_capability_set(log, sub, settings))
4369 case CAPSET_TYPE_DRAW_GDI_PLUS:
4370 if (!rdp_read_draw_gdiplus_cache_capability_set(log, sub, settings))
4375 case CAPSET_TYPE_RAIL:
4376 if (!rdp_read_remote_programs_capability_set(log, sub, settings))
4381 case CAPSET_TYPE_WINDOW:
4382 if (!rdp_read_window_list_capability_set(log, sub, settings))
4387 case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
4388 if (!rdp_read_multifragment_update_capability_set(log, sub, settings))
4393 case CAPSET_TYPE_LARGE_POINTER:
4394 if (!rdp_read_large_pointer_capability_set(log, sub, settings))
4399 case CAPSET_TYPE_COMP_DESK:
4400 if (!rdp_read_desktop_composition_capability_set(log, sub, settings))
4405 case CAPSET_TYPE_SURFACE_COMMANDS:
4406 if (!rdp_read_surface_commands_capability_set(log, sub, settings))
4411 case CAPSET_TYPE_BITMAP_CODECS:
4412 if (!rdp_read_bitmap_codecs_capability_set(log, sub, settings, isServer))
4417 case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
4418 if (!rdp_read_frame_acknowledge_capability_set(log, sub, settings))
4423 case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID:
4424 if (!rdp_read_bitmap_cache_v3_codec_id_capability_set(log, sub, settings))
4441 case CAPSET_TYPE_BITMAP_CACHE:
4442 if (!rdp_read_bitmap_cache_capability_set(log, sub, settings))
4447 case CAPSET_TYPE_BITMAP_CACHE_V2:
4448 if (!rdp_read_bitmap_cache_v2_capability_set(log, sub, settings))
4453 case CAPSET_TYPE_BRUSH:
4454 if (!rdp_read_brush_capability_set(log, sub, settings))
4459 case CAPSET_TYPE_GLYPH_CACHE:
4460 if (!rdp_read_glyph_cache_capability_set(log, sub, settings))
4465 case CAPSET_TYPE_OFFSCREEN_CACHE:
4466 if (!rdp_read_offscreen_bitmap_cache_capability_set(log, sub, settings))
4471 case CAPSET_TYPE_SOUND:
4472 if (!rdp_read_sound_capability_set(log, sub, settings))
4477 case CAPSET_TYPE_CONTROL:
4478 if (!rdp_read_control_capability_set(log, sub, settings))
4483 case CAPSET_TYPE_ACTIVATION:
4484 if (!rdp_read_window_activation_capability_set(log, sub, settings))
4489 case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
4490 if (!rdp_read_draw_nine_grid_cache_capability_set(log, sub, settings))
4496 WLog_Print(log, WLOG_ERROR,
4497 "capability %s(%" PRIu16
") not expected from client",
4498 get_capability_name(type), type);
4507 case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
4508 if (!rdp_read_bitmap_cache_host_support_capability_set(log, sub, settings))
4514 WLog_Print(log, WLOG_ERROR,
4515 "capability %s(%" PRIu16
") not expected from server",
4516 get_capability_name(type), type);
4522 const size_t rest = Stream_GetRemainingLength(sub);
4525 const size_t length = Stream_Capacity(sub);
4526 WLog_Print(log, WLOG_ERROR,
4527 "incorrect offset, type:0x%04" PRIx16
" actual:%" PRIuz
" expected:%" PRIuz
"",
4528 type, length - rest, length);
4533static BOOL rdp_read_capability_sets(wLog* log,
wStream* s, rdpSettings* settings,
4534 rdpSettings* rcvSettings, UINT16 totalLength)
4540 UINT16 numberCapabilities = 0;
4543#ifdef WITH_DEBUG_CAPABILITIES
4544 const size_t capstart = Stream_GetPosition(s);
4548 WINPR_ASSERT(settings);
4550 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
4553 Stream_Read_UINT16(s, numberCapabilities);
4555 count = numberCapabilities;
4557 start = Stream_GetPosition(s);
4558 while (numberCapabilities > 0 && Stream_GetRemainingLength(s) >= 4)
4565 if (!rdp_read_capability_set_header(log, s, &length, &type))
4567 sub = Stream_StaticInit(&subbuffer, Stream_Pointer(s), length - 4);
4568 if (!Stream_SafeSeek(s, length - 4))
4571 if (!rdp_read_capability_set(log, sub, type, rcvSettings, settings->ServerMode))
4574 if (!rdp_apply_from_received(type, settings, rcvSettings))
4576 numberCapabilities--;
4579 end = Stream_GetPosition(s);
4582 if (numberCapabilities)
4584 WLog_Print(log, WLOG_ERROR,
4585 "strange we haven't read the number of announced capacity sets, read=%d "
4586 "expected=%" PRIu16
"",
4587 count - numberCapabilities, count);
4590#ifdef WITH_DEBUG_CAPABILITIES
4591 rdp_print_capability_sets(log, s, capstart, TRUE);
4594 if (len > totalLength)
4596 WLog_Print(log, WLOG_ERROR,
"Capability length expected %" PRIu16
", actual %" PRIuz,
4600 rc = freerdp_capability_buffer_copy(settings, rcvSettings);
4605BOOL rdp_recv_get_active_header(rdpRdp* rdp,
wStream* s, UINT16* pChannelId, UINT16* length)
4608 WINPR_ASSERT(rdp->context);
4610 if (!rdp_read_header(rdp, s, length, pChannelId))
4613 if (freerdp_shall_disconnect_context(rdp->context))
4616 if (*pChannelId != MCS_GLOBAL_CHANNEL_ID)
4618 UINT16 mcsMessageChannelId = rdp->mcs->messageChannelId;
4620 if ((mcsMessageChannelId == 0) || (*pChannelId != mcsMessageChannelId))
4622 WLog_Print(rdp->log, WLOG_ERROR,
"unexpected MCS channel id %04" PRIx16
" received",
4631BOOL rdp_recv_demand_active(rdpRdp* rdp,
wStream* s, UINT16 pduSource, UINT16 length)
4633 UINT16 lengthSourceDescriptor = 0;
4634 UINT16 lengthCombinedCapabilities = 0;
4637 WINPR_ASSERT(rdp->settings);
4638 WINPR_ASSERT(rdp->context);
4641 rdp->settings->PduSource = pduSource;
4643 if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 8))
4646 Stream_Read_UINT32(s, rdp->settings->ShareId);
4647 Stream_Read_UINT16(s, lengthSourceDescriptor);
4648 Stream_Read_UINT16(s, lengthCombinedCapabilities);
4650 if (!Stream_SafeSeek(s, lengthSourceDescriptor) ||
4651 !Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 4))
4655 if (!rdp_read_capability_sets(rdp->log, s, rdp->settings, rdp->remoteSettings,
4656 lengthCombinedCapabilities))
4658 WLog_Print(rdp->log, WLOG_ERROR,
"rdp_read_capability_sets failed");
4662 if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 4))
4667 Stream_Seek_UINT32(s);
4671 secondary->glyph_v2 = (rdp->settings->GlyphSupportLevel > GLYPH_SUPPORT_FULL);
4674 return tpkt_ensure_stream_consumed(rdp->log, s, length);
4677static BOOL rdp_write_demand_active(wLog* log,
wStream* s, rdpSettings* settings)
4682 UINT16 numberCapabilities = 0;
4683 size_t lengthCombinedCapabilities = 0;
4685 if (!Stream_EnsureRemainingCapacity(s, 64))
4688 Stream_Write_UINT32(s, settings->ShareId);
4689 Stream_Write_UINT16(s, 4);
4690 lm = Stream_GetPosition(s);
4691 Stream_Seek_UINT16(s);
4692 Stream_Write(s,
"RDP", 4);
4693 bm = Stream_GetPosition(s);
4694 Stream_Seek_UINT16(s);
4695 Stream_Write_UINT16(s, 0);
4696 numberCapabilities = 14;
4698 if (!rdp_write_general_capability_set(log, s, settings) ||
4699 !rdp_write_bitmap_capability_set(log, s, settings) ||
4700 !rdp_write_order_capability_set(log, s, settings) ||
4701 !rdp_write_pointer_capability_set(log, s, settings) ||
4702 !rdp_write_input_capability_set(log, s, settings) ||
4703 !rdp_write_virtual_channel_capability_set(log, s, settings) ||
4704 !rdp_write_share_capability_set(log, s, settings) ||
4705 !rdp_write_font_capability_set(log, s, settings) ||
4706 !rdp_write_multifragment_update_capability_set(log, s, settings) ||
4707 !rdp_write_large_pointer_capability_set(log, s, settings) ||
4708 !rdp_write_desktop_composition_capability_set(log, s, settings) ||
4709 !rdp_write_surface_commands_capability_set(log, s, settings) ||
4710 !rdp_write_bitmap_codecs_capability_set(log, s, settings) ||
4711 !rdp_write_frame_acknowledge_capability_set(log, s, settings))
4718 numberCapabilities++;
4720 if (!rdp_write_bitmap_cache_host_support_capability_set(log, s, settings))
4724 if (settings->RemoteApplicationMode)
4726 numberCapabilities += 2;
4728 if (!rdp_write_remote_programs_capability_set(log, s, settings) ||
4729 !rdp_write_window_list_capability_set(log, s, settings))
4733 em = Stream_GetPosition(s);
4734 if (!Stream_SetPosition(s, lm))
4736 lengthCombinedCapabilities = (em - bm);
4737 if (lengthCombinedCapabilities > UINT16_MAX)
4739 Stream_Write_UINT16(
4740 s, (UINT16)lengthCombinedCapabilities);
4741 if (!Stream_SetPosition(s, bm))
4743 Stream_Write_UINT16(s, numberCapabilities);
4744#ifdef WITH_DEBUG_CAPABILITIES
4745 rdp_print_capability_sets(log, s, bm, FALSE);
4747 if (!Stream_SetPosition(s, em))
4749 Stream_Write_UINT32(s, 0);
4753BOOL rdp_send_demand_active(rdpRdp* rdp)
4755 UINT16 sec_flags = 0;
4756 wStream* s = rdp_send_stream_pdu_init(rdp, &sec_flags);
4762 rdp->settings->ShareId = 0x10000 + rdp->mcs->userId;
4763 status = rdp_write_demand_active(rdp->log, s, rdp->settings) &&
4764 rdp_send_pdu(rdp, s, PDU_TYPE_DEMAND_ACTIVE, rdp->mcs->userId, sec_flags);
4769BOOL rdp_recv_confirm_active(rdpRdp* rdp,
wStream* s, UINT16 pduLength)
4771 rdpSettings* settings =
nullptr;
4772 UINT16 lengthSourceDescriptor = 0;
4773 UINT16 lengthCombinedCapabilities = 0;
4777 settings = rdp->settings;
4778 WINPR_ASSERT(settings);
4780 if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 10))
4783 Stream_Seek_UINT32(s);
4784 Stream_Seek_UINT16(s);
4785 Stream_Read_UINT16(s, lengthSourceDescriptor);
4786 Stream_Read_UINT16(s, lengthCombinedCapabilities);
4788 if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, lengthSourceDescriptor + 4U))
4791 Stream_Seek(s, lengthSourceDescriptor);
4792 if (!rdp_read_capability_sets(rdp->log, s, rdp->settings, rdp->remoteSettings,
4793 lengthCombinedCapabilities))
4796 if (!settings->ReceivedCapabilities[CAPSET_TYPE_SURFACE_COMMANDS])
4799 settings->SurfaceCommandsEnabled = FALSE;
4800 settings->SurfaceFrameMarkerEnabled = FALSE;
4803 if (!settings->ReceivedCapabilities[CAPSET_TYPE_FRAME_ACKNOWLEDGE])
4806 settings->FrameAcknowledge = 0;
4809 if (!settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID])
4812 settings->BitmapCacheV3Enabled = FALSE;
4815 if (!settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CODECS])
4826 if (!settings->ReceivedCapabilities[CAPSET_TYPE_MULTI_FRAGMENT_UPDATE])
4830 FASTPATH_FRAGMENT_SAFE_SIZE))
4834 if (!settings->ReceivedCapabilities[CAPSET_TYPE_LARGE_POINTER])
4837 settings->LargePointerFlag = 0;
4840 return tpkt_ensure_stream_consumed(rdp->log, s, pduLength);
4843static BOOL rdp_write_confirm_active(wLog* log,
wStream* s, rdpSettings* settings)
4848 UINT16 numberCapabilities = 0;
4849 UINT16 lengthSourceDescriptor = 0;
4850 size_t lengthCombinedCapabilities = 0;
4853 WINPR_ASSERT(settings);
4855 lengthSourceDescriptor =
sizeof(SOURCE_DESCRIPTOR);
4856 Stream_Write_UINT32(s, settings->ShareId);
4857 Stream_Write_UINT16(s, 0x03EA);
4858 Stream_Write_UINT16(s, lengthSourceDescriptor);
4859 lm = Stream_GetPosition(s);
4860 Stream_Seek_UINT16(s);
4861 Stream_Write(s, SOURCE_DESCRIPTOR, lengthSourceDescriptor);
4862 bm = Stream_GetPosition(s);
4863 Stream_Seek_UINT16(s);
4864 Stream_Write_UINT16(s, 0);
4866 numberCapabilities = 15;
4868 if (!rdp_write_general_capability_set(log, s, settings) ||
4869 !rdp_write_bitmap_capability_set(log, s, settings) ||
4870 !rdp_write_order_capability_set(log, s, settings))
4873 if (settings->RdpVersion >= RDP_VERSION_5_PLUS)
4874 ret = rdp_write_bitmap_cache_v2_capability_set(log, s, settings);
4876 ret = rdp_write_bitmap_cache_capability_set(log, s, settings);
4881 if (!rdp_write_pointer_capability_set(log, s, settings) ||
4882 !rdp_write_input_capability_set(log, s, settings) ||
4883 !rdp_write_brush_capability_set(log, s, settings) ||
4884 !rdp_write_glyph_cache_capability_set(log, s, settings) ||
4885 !rdp_write_virtual_channel_capability_set(log, s, settings) ||
4886 !rdp_write_sound_capability_set(log, s, settings) ||
4887 !rdp_write_share_capability_set(log, s, settings) ||
4888 !rdp_write_font_capability_set(log, s, settings) ||
4889 !rdp_write_control_capability_set(log, s, settings) ||
4890 !rdp_write_color_cache_capability_set(log, s, settings) ||
4891 !rdp_write_window_activation_capability_set(log, s, settings))
4897 numberCapabilities++;
4899 if (!rdp_write_offscreen_bitmap_cache_capability_set(log, s, settings))
4903 if (settings->DrawNineGridEnabled)
4905 numberCapabilities++;
4907 if (!rdp_write_draw_nine_grid_cache_capability_set(log, s, settings))
4911 if (settings->ReceivedCapabilities[CAPSET_TYPE_LARGE_POINTER])
4913 if (settings->LargePointerFlag)
4915 numberCapabilities++;
4917 if (!rdp_write_large_pointer_capability_set(log, s, settings))
4922 if (settings->RemoteApplicationMode)
4924 numberCapabilities += 2;
4926 if (!rdp_write_remote_programs_capability_set(log, s, settings) ||
4927 !rdp_write_window_list_capability_set(log, s, settings))
4931 if (settings->ReceivedCapabilities[CAPSET_TYPE_MULTI_FRAGMENT_UPDATE])
4933 numberCapabilities++;
4935 if (!rdp_write_multifragment_update_capability_set(log, s, settings))
4939 if (settings->ReceivedCapabilities[CAPSET_TYPE_SURFACE_COMMANDS])
4941 numberCapabilities++;
4943 if (!rdp_write_surface_commands_capability_set(log, s, settings))
4947 if (settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CODECS])
4949 numberCapabilities++;
4951 if (!rdp_write_bitmap_codecs_capability_set(log, s, settings))
4955 if (!settings->ReceivedCapabilities[CAPSET_TYPE_FRAME_ACKNOWLEDGE])
4956 settings->FrameAcknowledge = 0;
4958 if (settings->FrameAcknowledge)
4960 numberCapabilities++;
4962 if (!rdp_write_frame_acknowledge_capability_set(log, s, settings))
4966 if (settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID])
4968 if (settings->BitmapCacheV3CodecId != 0)
4970 numberCapabilities++;
4972 if (!rdp_write_bitmap_cache_v3_codec_id_capability_set(log, s, settings))
4977 em = Stream_GetPosition(s);
4978 if (!Stream_SetPosition(s, lm))
4980 lengthCombinedCapabilities = (em - bm);
4981 if (lengthCombinedCapabilities > UINT16_MAX)
4983 Stream_Write_UINT16(
4984 s, (UINT16)lengthCombinedCapabilities);
4985 if (!Stream_SetPosition(s, bm))
4987 Stream_Write_UINT16(s, numberCapabilities);
4988#ifdef WITH_DEBUG_CAPABILITIES
4989 rdp_print_capability_sets(log, s, bm, FALSE);
4991 return Stream_SetPosition(s, em);
4994BOOL rdp_send_confirm_active(rdpRdp* rdp)
4996 UINT16 sec_flags = 0;
4997 wStream* s = rdp_send_stream_pdu_init(rdp, &sec_flags);
5003 status = rdp_write_confirm_active(rdp->log, s, rdp->settings) &&
5004 rdp_send_pdu(rdp, s, PDU_TYPE_CONFIRM_ACTIVE, rdp->mcs->userId, sec_flags);
5009const char* rdp_input_flag_string(UINT16 flags,
char* buffer,
size_t len)
5011 char prefix[16] = WINPR_C_ARRAY_INIT;
5013 (void)_snprintf(prefix,
sizeof(prefix),
"[0x%04" PRIx16
"][", flags);
5014 winpr_str_append(prefix, buffer, len,
"");
5015 if ((flags & INPUT_FLAG_SCANCODES) != 0)
5016 winpr_str_append(
"INPUT_FLAG_SCANCODES", buffer, len,
"|");
5017 if ((flags & INPUT_FLAG_MOUSEX) != 0)
5018 winpr_str_append(
"INPUT_FLAG_MOUSEX", buffer, len,
"|");
5019 if ((flags & INPUT_FLAG_FASTPATH_INPUT) != 0)
5020 winpr_str_append(
"INPUT_FLAG_FASTPATH_INPUT", buffer, len,
"|");
5021 if ((flags & INPUT_FLAG_UNICODE) != 0)
5022 winpr_str_append(
"INPUT_FLAG_UNICODE", buffer, len,
"|");
5023 if ((flags & INPUT_FLAG_FASTPATH_INPUT2) != 0)
5024 winpr_str_append(
"INPUT_FLAG_FASTPATH_INPUT2", buffer, len,
"|");
5025 if ((flags & INPUT_FLAG_UNUSED1) != 0)
5026 winpr_str_append(
"INPUT_FLAG_UNUSED1", buffer, len,
"|");
5027 if ((flags & INPUT_FLAG_MOUSE_RELATIVE) != 0)
5028 winpr_str_append(
"INPUT_FLAG_MOUSE_RELATIVE", buffer, len,
"|");
5029 if ((flags & TS_INPUT_FLAG_MOUSE_HWHEEL) != 0)
5030 winpr_str_append(
"TS_INPUT_FLAG_MOUSE_HWHEEL", buffer, len,
"|");
5031 if ((flags & TS_INPUT_FLAG_QOE_TIMESTAMPS) != 0)
5032 winpr_str_append(
"TS_INPUT_FLAG_QOE_TIMESTAMPS", buffer, len,
"|");
5033 winpr_str_append(
"]", buffer, len,
"");
WINPR_ATTR_NODISCARD FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_set_bool(rdpSettings *settings, FreeRDP_Settings_Keys_Bool id, BOOL val)
Sets a BOOL settings value.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_set_string_len(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const char *val, size_t len)
Sets a string settings value. The val is copied.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_set_uint32(rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id, UINT32 val)
Sets a UINT32 settings value.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_set_pointer_len(rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id, const void *data, size_t len)
Set a pointer to value data.
WINPR_ATTR_NODISCARD FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_set_string(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const char *val)
Sets a string settings value. The param is copied.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.