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);
125static void rdp_write_capability_set_header(
wStream* s, UINT16 length, UINT16 type)
128 WINPR_ASSERT(Stream_GetRemainingCapacity(s) >= 4);
129 Stream_Write_UINT16(s, type);
130 Stream_Write_UINT16(s, length);
133static size_t rdp_capability_set_start(wLog* log,
wStream* s)
135 size_t header = Stream_GetPosition(s);
136 if (!Stream_CheckAndLogRequiredCapacityWLog(log, (s), CAPSET_HEADER_LENGTH))
138 Stream_Zero(s, CAPSET_HEADER_LENGTH);
142static BOOL rdp_capability_set_finish(
wStream* s,
size_t header, UINT16 type)
144 const size_t footer = Stream_GetPosition(s);
147 if (header > UINT16_MAX)
149 const size_t length = footer - header;
150 if ((Stream_Capacity(s) < header + 4ULL) || (length > UINT16_MAX))
152 Stream_SetPosition(s, header);
153 rdp_write_capability_set_header(s, (UINT16)length, type);
154 Stream_SetPosition(s, footer);
158static BOOL rdp_apply_general_capability_set(rdpSettings* settings,
const rdpSettings* src)
160 WINPR_ASSERT(settings);
163 if (settings->ServerMode)
165 settings->OsMajorType = src->OsMajorType;
166 settings->OsMinorType = src->OsMinorType;
169 settings->CapsProtocolVersion = src->CapsProtocolVersion;
170 settings->NoBitmapCompressionHeader = src->NoBitmapCompressionHeader;
171 settings->LongCredentialsSupported = src->LongCredentialsSupported;
172 settings->AutoReconnectionPacketSupported = src->AutoReconnectionPacketSupported;
173 if (!src->FastPathOutput)
174 settings->FastPathOutput = FALSE;
176 if (!src->SaltedChecksum)
177 settings->SaltedChecksum = FALSE;
179 if (!settings->ServerMode)
186 if (!src->RefreshRect)
187 settings->RefreshRect = FALSE;
189 if (!src->SuppressOutput)
190 settings->SuppressOutput = FALSE;
200static BOOL rdp_read_general_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
202 UINT16 extraFlags = 0;
203 BYTE refreshRectSupport = 0;
204 BYTE suppressOutputSupport = 0;
206 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 20))
209 WINPR_ASSERT(settings);
210 Stream_Read_UINT16(s, settings->OsMajorType);
211 Stream_Read_UINT16(s, settings->OsMinorType);
213 Stream_Read_UINT16(s, settings->CapsProtocolVersion);
214 if (settings->CapsProtocolVersion != TS_CAPS_PROTOCOLVERSION)
216 WLog_Print(log, WLOG_ERROR,
217 "TS_GENERAL_CAPABILITYSET::protocolVersion(0x%04" PRIx16
218 ") != TS_CAPS_PROTOCOLVERSION(0x%04" PRIx32
")",
219 settings->CapsProtocolVersion,
220 WINPR_CXX_COMPAT_CAST(UINT32, TS_CAPS_PROTOCOLVERSION));
221 if (settings->CapsProtocolVersion == 0x0000)
223 WLog_Print(log, WLOG_WARN,
224 "TS_GENERAL_CAPABILITYSET::protocolVersion(0x%04" PRIx16
225 " assuming old FreeRDP, ignoring protocol violation, correcting value.",
226 settings->CapsProtocolVersion);
227 settings->CapsProtocolVersion = TS_CAPS_PROTOCOLVERSION;
232 Stream_Seek_UINT16(s);
234 s, settings->CapsGeneralCompressionTypes);
235 Stream_Read_UINT16(s, extraFlags);
236 Stream_Read_UINT16(s, settings->CapsUpdateCapabilityFlag);
237 Stream_Read_UINT16(s, settings->CapsRemoteUnshareFlag);
239 s, settings->CapsGeneralCompressionLevel);
240 Stream_Read_UINT8(s, refreshRectSupport);
241 Stream_Read_UINT8(s, suppressOutputSupport);
242 settings->NoBitmapCompressionHeader = (extraFlags & NO_BITMAP_COMPRESSION_HDR) ? TRUE : FALSE;
243 settings->LongCredentialsSupported = (extraFlags & LONG_CREDENTIALS_SUPPORTED) ? TRUE : FALSE;
245 settings->AutoReconnectionPacketSupported =
246 (extraFlags & AUTORECONNECT_SUPPORTED) ? TRUE : FALSE;
247 settings->FastPathOutput = (extraFlags & FASTPATH_OUTPUT_SUPPORTED) ? TRUE : FALSE;
248 settings->SaltedChecksum = (extraFlags & ENC_SALTED_CHECKSUM) ? TRUE : FALSE;
249 settings->RefreshRect = refreshRectSupport;
250 settings->SuppressOutput = suppressOutputSupport;
260static BOOL rdp_write_general_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
262 if (!Stream_EnsureRemainingCapacity(s, 64))
265 const size_t header = rdp_capability_set_start(log, s);
266 UINT16 extraFlags = 0;
268 WINPR_ASSERT(settings);
269 if (settings->LongCredentialsSupported)
270 extraFlags |= LONG_CREDENTIALS_SUPPORTED;
272 if (settings->NoBitmapCompressionHeader)
273 extraFlags |= NO_BITMAP_COMPRESSION_HDR;
275 if (settings->AutoReconnectionPacketSupported)
276 extraFlags |= AUTORECONNECT_SUPPORTED;
278 if (settings->FastPathOutput)
279 extraFlags |= FASTPATH_OUTPUT_SUPPORTED;
281 if (settings->SaltedChecksum)
282 extraFlags |= ENC_SALTED_CHECKSUM;
284 if ((settings->OsMajorType > UINT16_MAX) || (settings->OsMinorType > UINT16_MAX))
286 WLog_Print(log, WLOG_ERROR,
287 "OsMajorType=%08" PRIx32
", OsMinorType=%08" PRIx32
288 " they need to be smaller %04" PRIx32,
289 settings->OsMajorType, settings->OsMinorType,
290 WINPR_CXX_COMPAT_CAST(UINT32, UINT16_MAX));
293 if (settings->CapsProtocolVersion != TS_CAPS_PROTOCOLVERSION)
295 WLog_Print(log, WLOG_ERROR,
296 "TS_GENERAL_CAPABILITYSET::protocolVersion(0x%04" PRIx16
297 ") != TS_CAPS_PROTOCOLVERSION(0x%04" PRIx32
")",
298 settings->CapsProtocolVersion,
299 WINPR_CXX_COMPAT_CAST(UINT32, TS_CAPS_PROTOCOLVERSION));
302 Stream_Write_UINT16(s, (UINT16)settings->OsMajorType);
303 Stream_Write_UINT16(s, (UINT16)settings->OsMinorType);
304 Stream_Write_UINT16(s, settings->CapsProtocolVersion);
305 Stream_Write_UINT16(s, 0);
307 s, settings->CapsGeneralCompressionTypes);
308 Stream_Write_UINT16(s, extraFlags);
309 Stream_Write_UINT16(s, settings->CapsUpdateCapabilityFlag);
310 Stream_Write_UINT16(s, settings->CapsRemoteUnshareFlag);
312 s, settings->CapsGeneralCompressionLevel);
313 Stream_Write_UINT8(s, settings->RefreshRect ? 1 : 0);
314 Stream_Write_UINT8(s, settings->SuppressOutput ? 1 : 0);
315 return rdp_capability_set_finish(s, header, CAPSET_TYPE_GENERAL);
318#ifdef WITH_DEBUG_CAPABILITIES
319static BOOL rdp_print_general_capability_set(wLog* log,
wStream* s)
321 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 20))
324 WLog_Print(log, WLOG_TRACE,
325 "GeneralCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
326 const uint16_t osMinorType = Stream_Get_UINT16(s);
327 const uint16_t osMajorType = Stream_Get_UINT16(s);
328 const uint16_t protocolVersion = Stream_Get_UINT16(s);
329 const uint16_t pad2OctetsA = Stream_Get_UINT16(s);
330 const uint16_t generalCompressionTypes =
331 Stream_Get_UINT16(s);
332 const uint16_t extraFlags = Stream_Get_UINT16(s);
333 const uint16_t updateCapabilityFlag = Stream_Get_UINT16(s);
334 const uint16_t remoteUnshareFlag = Stream_Get_UINT16(s);
335 const uint16_t generalCompressionLevel =
336 Stream_Get_UINT16(s);
337 const uint8_t refreshRectSupport = Stream_Get_UINT8(s);
338 const uint8_t suppressOutputSupport = Stream_Get_UINT8(s);
339 WLog_Print(log, WLOG_TRACE,
"\tosMajorType: 0x%04" PRIX16
"", osMajorType);
340 WLog_Print(log, WLOG_TRACE,
"\tosMinorType: 0x%04" PRIX16
"", osMinorType);
341 WLog_Print(log, WLOG_TRACE,
"\tprotocolVersion: 0x%04" PRIX16
"", protocolVersion);
342 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
343 WLog_Print(log, WLOG_TRACE,
"\tgeneralCompressionTypes: 0x%04" PRIX16
"",
344 generalCompressionTypes);
345 WLog_Print(log, WLOG_TRACE,
"\textraFlags: 0x%04" PRIX16
"", extraFlags);
346 WLog_Print(log, WLOG_TRACE,
"\tupdateCapabilityFlag: 0x%04" PRIX16
"", updateCapabilityFlag);
347 WLog_Print(log, WLOG_TRACE,
"\tremoteUnshareFlag: 0x%04" PRIX16
"", remoteUnshareFlag);
348 WLog_Print(log, WLOG_TRACE,
"\tgeneralCompressionLevel: 0x%04" PRIX16
"",
349 generalCompressionLevel);
350 WLog_Print(log, WLOG_TRACE,
"\trefreshRectSupport: 0x%02" PRIX8
"", refreshRectSupport);
351 WLog_Print(log, WLOG_TRACE,
"\tsuppressOutputSupport: 0x%02" PRIX8
"", suppressOutputSupport);
355static BOOL rdp_apply_bitmap_capability_set(rdpSettings* settings,
const rdpSettings* src)
357 WINPR_ASSERT(settings);
360 if (!settings->ServerMode)
367 if (!src->DesktopResize)
368 settings->DesktopResize = FALSE;
370 if (!settings->ServerMode && settings->DesktopResize)
374 settings->DesktopWidth = src->DesktopWidth;
375 settings->DesktopHeight = src->DesktopHeight;
378 if (settings->DrawAllowSkipAlpha)
379 settings->DrawAllowSkipAlpha = src->DrawAllowSkipAlpha;
381 if (settings->DrawAllowDynamicColorFidelity)
382 settings->DrawAllowDynamicColorFidelity = src->DrawAllowDynamicColorFidelity;
384 if (settings->DrawAllowColorSubsampling)
385 settings->DrawAllowColorSubsampling = src->DrawAllowColorSubsampling;
395static BOOL rdp_read_bitmap_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
397 BYTE drawingFlags = 0;
398 UINT16 desktopWidth = 0;
399 UINT16 desktopHeight = 0;
400 UINT16 desktopResizeFlag = 0;
401 UINT16 preferredBitsPerPixel = 0;
403 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 24))
406 Stream_Read_UINT16(s, preferredBitsPerPixel);
407 Stream_Seek_UINT16(s);
408 Stream_Seek_UINT16(s);
409 Stream_Seek_UINT16(s);
410 Stream_Read_UINT16(s, desktopWidth);
411 Stream_Read_UINT16(s, desktopHeight);
412 Stream_Seek_UINT16(s);
413 Stream_Read_UINT16(s, desktopResizeFlag);
414 Stream_Seek_UINT16(s);
415 Stream_Seek_UINT8(s);
416 Stream_Read_UINT8(s, drawingFlags);
417 Stream_Seek_UINT16(s);
418 Stream_Seek_UINT16(s);
422 settings->DesktopResize = desktopResizeFlag;
423 settings->DesktopWidth = desktopWidth;
424 settings->DesktopHeight = desktopHeight;
425 settings->DrawAllowSkipAlpha = (drawingFlags & DRAW_ALLOW_SKIP_ALPHA) ? TRUE : FALSE;
426 settings->DrawAllowDynamicColorFidelity =
427 (drawingFlags & DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY) ? TRUE : FALSE;
428 settings->DrawAllowColorSubsampling =
429 (drawingFlags & DRAW_ALLOW_COLOR_SUBSAMPLING) ? TRUE : FALSE;
439static BOOL rdp_write_bitmap_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
441 BYTE drawingFlags = 0;
442 UINT16 preferredBitsPerPixel = 0;
444 if (!Stream_EnsureRemainingCapacity(s, 64))
447 const size_t header = rdp_capability_set_start(log, s);
449 WINPR_ASSERT(settings);
450 if (settings->DrawAllowSkipAlpha)
451 drawingFlags |= DRAW_ALLOW_SKIP_ALPHA;
453 if (settings->DrawAllowDynamicColorFidelity)
454 drawingFlags |= DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY;
456 if (settings->DrawAllowColorSubsampling)
457 drawingFlags |= DRAW_ALLOW_COLOR_SUBSAMPLING;
469 (settings->DesktopWidth > UINT16_MAX) || (settings->DesktopHeight > UINT16_MAX))
472 if (settings->RdpVersion >= RDP_VERSION_5_PLUS)
475 preferredBitsPerPixel = 8;
477 Stream_Write_UINT16(s, preferredBitsPerPixel);
478 Stream_Write_UINT16(s, 1);
479 Stream_Write_UINT16(s, 1);
480 Stream_Write_UINT16(s, 1);
481 Stream_Write_UINT16(s, (UINT16)settings->DesktopWidth);
482 Stream_Write_UINT16(s, (UINT16)settings->DesktopHeight);
483 Stream_Write_UINT16(s, 0);
484 Stream_Write_UINT16(s, (UINT16)settings->DesktopResize);
485 Stream_Write_UINT16(s, 1);
486 Stream_Write_UINT8(s, 0);
487 Stream_Write_UINT8(s, drawingFlags);
488 Stream_Write_UINT16(s, 1);
489 Stream_Write_UINT16(s, 0);
490 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP);
493#ifdef WITH_DEBUG_CAPABILITIES
494static BOOL rdp_print_bitmap_capability_set(wLog* log,
wStream* s)
496 UINT16 preferredBitsPerPixel = 0;
497 UINT16 receive1BitPerPixel = 0;
498 UINT16 receive4BitsPerPixel = 0;
499 UINT16 receive8BitsPerPixel = 0;
500 UINT16 desktopWidth = 0;
501 UINT16 desktopHeight = 0;
502 UINT16 pad2Octets = 0;
503 UINT16 desktopResizeFlag = 0;
504 UINT16 bitmapCompressionFlag = 0;
505 BYTE highColorFlags = 0;
506 BYTE drawingFlags = 0;
507 UINT16 multipleRectangleSupport = 0;
508 UINT16 pad2OctetsB = 0;
509 WLog_Print(log, WLOG_TRACE,
510 "BitmapCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
512 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 24))
515 Stream_Read_UINT16(s, preferredBitsPerPixel);
516 Stream_Read_UINT16(s, receive1BitPerPixel);
517 Stream_Read_UINT16(s, receive4BitsPerPixel);
518 Stream_Read_UINT16(s, receive8BitsPerPixel);
519 Stream_Read_UINT16(s, desktopWidth);
520 Stream_Read_UINT16(s, desktopHeight);
521 Stream_Read_UINT16(s, pad2Octets);
522 Stream_Read_UINT16(s, desktopResizeFlag);
523 Stream_Read_UINT16(s, bitmapCompressionFlag);
524 Stream_Read_UINT8(s, highColorFlags);
525 Stream_Read_UINT8(s, drawingFlags);
526 Stream_Read_UINT16(s, multipleRectangleSupport);
527 Stream_Read_UINT16(s, pad2OctetsB);
528 WLog_Print(log, WLOG_TRACE,
"\tpreferredBitsPerPixel: 0x%04" PRIX16
"", preferredBitsPerPixel);
529 WLog_Print(log, WLOG_TRACE,
"\treceive1BitPerPixel: 0x%04" PRIX16
"", receive1BitPerPixel);
530 WLog_Print(log, WLOG_TRACE,
"\treceive4BitsPerPixel: 0x%04" PRIX16
"", receive4BitsPerPixel);
531 WLog_Print(log, WLOG_TRACE,
"\treceive8BitsPerPixel: 0x%04" PRIX16
"", receive8BitsPerPixel);
532 WLog_Print(log, WLOG_TRACE,
"\tdesktopWidth: 0x%04" PRIX16
"", desktopWidth);
533 WLog_Print(log, WLOG_TRACE,
"\tdesktopHeight: 0x%04" PRIX16
"", desktopHeight);
534 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
535 WLog_Print(log, WLOG_TRACE,
"\tdesktopResizeFlag: 0x%04" PRIX16
"", desktopResizeFlag);
536 WLog_Print(log, WLOG_TRACE,
"\tbitmapCompressionFlag: 0x%04" PRIX16
"", bitmapCompressionFlag);
537 WLog_Print(log, WLOG_TRACE,
"\thighColorFlags: 0x%02" PRIX8
"", highColorFlags);
538 WLog_Print(log, WLOG_TRACE,
"\tdrawingFlags: 0x%02" PRIX8
"", drawingFlags);
539 WLog_Print(log, WLOG_TRACE,
"\tmultipleRectangleSupport: 0x%04" PRIX16
"",
540 multipleRectangleSupport);
541 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsB: 0x%04" PRIX16
"", pad2OctetsB);
545static BOOL rdp_apply_order_capability_set(rdpSettings* settings,
const rdpSettings* src)
547 WINPR_ASSERT(settings);
550 BOOL BitmapCacheV3Enabled = FALSE;
551 BOOL FrameMarkerCommandEnabled = FALSE;
553 for (
size_t i = 0; i < 32; i++)
555 if (!src->OrderSupport[i])
556 settings->OrderSupport[i] = FALSE;
559 if (src->OrderSupportFlags & ORDER_FLAGS_EXTRA_SUPPORT)
561 if (src->OrderSupportFlagsEx & CACHE_BITMAP_V3_SUPPORT)
562 BitmapCacheV3Enabled = TRUE;
564 if (src->OrderSupportFlagsEx & ALTSEC_FRAME_MARKER_SUPPORT)
565 FrameMarkerCommandEnabled = TRUE;
568 if (BitmapCacheV3Enabled && settings->BitmapCacheV3Enabled)
570 settings->BitmapCacheV3Enabled = src->BitmapCacheV3Enabled;
571 settings->BitmapCacheVersion = src->BitmapCacheVersion;
574 settings->BitmapCacheV3Enabled = FALSE;
576 if (FrameMarkerCommandEnabled && src->FrameMarkerCommandEnabled)
577 settings->FrameMarkerCommandEnabled = TRUE;
579 settings->FrameMarkerCommandEnabled = FALSE;
589static BOOL rdp_read_order_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
591 char terminalDescriptor[17] = { 0 };
592 BYTE orderSupport[32] = { 0 };
593 BOOL BitmapCacheV3Enabled = FALSE;
594 BOOL FrameMarkerCommandEnabled = FALSE;
596 WINPR_ASSERT(settings);
597 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 84))
600 Stream_Read(s, terminalDescriptor, 16);
601 Stream_Seek_UINT32(s);
602 Stream_Seek_UINT16(s);
603 Stream_Seek_UINT16(s);
604 Stream_Seek_UINT16(s);
605 Stream_Seek_UINT16(s);
606 Stream_Seek_UINT16(s);
607 Stream_Read_UINT16(s, settings->OrderSupportFlags);
608 Stream_Read(s, orderSupport, 32);
609 Stream_Seek_UINT16(s);
610 Stream_Read_UINT16(s, settings->OrderSupportFlagsEx);
611 Stream_Seek_UINT32(s);
612 Stream_Seek_UINT32(s);
613 Stream_Seek_UINT16(s);
614 Stream_Seek_UINT16(s);
615 Stream_Read_UINT16(s, settings->TextANSICodePage);
616 Stream_Seek_UINT16(s);
621 for (
size_t i = 0; i < ARRAYSIZE(orderSupport); i++)
622 settings->OrderSupport[i] = orderSupport[i];
624 if (settings->OrderSupportFlags & ORDER_FLAGS_EXTRA_SUPPORT)
626 BitmapCacheV3Enabled =
627 (settings->OrderSupportFlagsEx & CACHE_BITMAP_V3_SUPPORT) ? TRUE : FALSE;
628 FrameMarkerCommandEnabled =
629 (settings->OrderSupportFlagsEx & ALTSEC_FRAME_MARKER_SUPPORT) ? TRUE : FALSE;
632 settings->BitmapCacheV3Enabled = BitmapCacheV3Enabled;
633 if (BitmapCacheV3Enabled)
634 settings->BitmapCacheVersion = 3;
636 settings->FrameMarkerCommandEnabled = FrameMarkerCommandEnabled;
646static BOOL rdp_write_order_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
648 char terminalDescriptor[16] = { 0 };
650 WINPR_ASSERT(settings);
651 if (!Stream_EnsureRemainingCapacity(s, 64))
654 const size_t header = rdp_capability_set_start(log, s);
656 UINT16 orderSupportExFlags = settings->OrderSupportFlagsEx;
657 UINT16 orderFlags = settings->OrderSupportFlags;
659 if (settings->BitmapCacheV3Enabled)
661 if ((orderSupportExFlags & CACHE_BITMAP_V3_SUPPORT) == 0)
663 WLog_Print(log, WLOG_WARN,
664 "rdpSettings::BitmapCacheV3Enabled=TRUE, but CACHE_BITMAP_V3_SUPPORT not "
665 "set in rdpSettings::OrderSupportEx, aborting.");
667 if ((orderFlags & ORDER_FLAGS_EXTRA_SUPPORT) == 0)
669 WLog_Print(log, WLOG_WARN,
670 "rdpSettings::BitmapCacheV3Enabled=TRUE, but ORDER_FLAGS_EXTRA_SUPPORT not "
671 "set in rdpSettings::OrderSupport, aborting.");
675 if (settings->FrameMarkerCommandEnabled)
677 if ((orderSupportExFlags & ALTSEC_FRAME_MARKER_SUPPORT) == 0)
681 "rdpSettings::FrameMarkerCommandEnabled=TRUE, but "
682 "ALTSEC_FRAME_MARKER_SUPPORT not set in rdpSettings::OrderSupportEx, aborting.");
684 if ((orderFlags & ORDER_FLAGS_EXTRA_SUPPORT) == 0)
686 WLog_Print(log, WLOG_WARN,
687 "rdpSettings::FrameMarkerCommandEnabled=TRUE, but ORDER_FLAGS_EXTRA_SUPPORT "
688 "not set in rdpSettings::OrderSupport, aborting.");
695 const size_t len = strnlen(dsc, ARRAYSIZE(terminalDescriptor));
696 strncpy(terminalDescriptor, dsc, len);
698 Stream_Write(s, terminalDescriptor,
699 sizeof(terminalDescriptor));
700 Stream_Write_UINT32(s, 0);
701 Stream_Write_UINT16(s, 1);
702 Stream_Write_UINT16(s, 20);
703 Stream_Write_UINT16(s, 0);
704 Stream_Write_UINT16(s, 1);
705 Stream_Write_UINT16(s, 0);
706 Stream_Write_UINT16(s, orderFlags);
707 Stream_Write(s, settings->OrderSupport, 32);
708 Stream_Write_UINT16(s, 0);
709 Stream_Write_UINT16(s, orderSupportExFlags);
710 Stream_Write_UINT32(s, 0);
711 Stream_Write_UINT32(s, 230400);
712 Stream_Write_UINT16(s, 0);
713 Stream_Write_UINT16(s, 0);
714 Stream_Write_UINT16(s, settings->TextANSICodePage);
715 Stream_Write_UINT16(s, 0);
716 return rdp_capability_set_finish(s, header, CAPSET_TYPE_ORDER);
719#ifdef WITH_DEBUG_CAPABILITIES
720static BOOL rdp_print_order_capability_set(wLog* log,
wStream* s)
722 BYTE terminalDescriptor[16];
723 UINT32 pad4OctetsA = 0;
724 UINT16 desktopSaveXGranularity = 0;
725 UINT16 desktopSaveYGranularity = 0;
726 UINT16 pad2OctetsA = 0;
727 UINT16 maximumOrderLevel = 0;
728 UINT16 numberFonts = 0;
729 UINT16 orderFlags = 0;
730 BYTE orderSupport[32];
731 UINT16 textFlags = 0;
732 UINT16 orderSupportExFlags = 0;
733 UINT32 pad4OctetsB = 0;
734 UINT32 desktopSaveSize = 0;
735 UINT16 pad2OctetsC = 0;
736 UINT16 pad2OctetsD = 0;
737 UINT16 textANSICodePage = 0;
738 UINT16 pad2OctetsE = 0;
739 WLog_Print(log, WLOG_TRACE,
740 "OrderCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
742 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 84))
745 Stream_Read(s, terminalDescriptor, 16);
746 Stream_Read_UINT32(s, pad4OctetsA);
747 Stream_Read_UINT16(s, desktopSaveXGranularity);
748 Stream_Read_UINT16(s, desktopSaveYGranularity);
749 Stream_Read_UINT16(s, pad2OctetsA);
750 Stream_Read_UINT16(s, maximumOrderLevel);
751 Stream_Read_UINT16(s, numberFonts);
752 Stream_Read_UINT16(s, orderFlags);
753 Stream_Read(s, orderSupport, 32);
754 Stream_Read_UINT16(s, textFlags);
755 Stream_Read_UINT16(s, orderSupportExFlags);
756 Stream_Read_UINT32(s, pad4OctetsB);
757 Stream_Read_UINT32(s, desktopSaveSize);
758 Stream_Read_UINT16(s, pad2OctetsC);
759 Stream_Read_UINT16(s, pad2OctetsD);
760 Stream_Read_UINT16(s, textANSICodePage);
761 Stream_Read_UINT16(s, pad2OctetsE);
762 WLog_Print(log, WLOG_TRACE,
"\tpad4OctetsA: 0x%08" PRIX32
"", pad4OctetsA);
763 WLog_Print(log, WLOG_TRACE,
"\tdesktopSaveXGranularity: 0x%04" PRIX16
"",
764 desktopSaveXGranularity);
765 WLog_Print(log, WLOG_TRACE,
"\tdesktopSaveYGranularity: 0x%04" PRIX16
"",
766 desktopSaveYGranularity);
767 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
768 WLog_Print(log, WLOG_TRACE,
"\tmaximumOrderLevel: 0x%04" PRIX16
"", maximumOrderLevel);
769 WLog_Print(log, WLOG_TRACE,
"\tnumberFonts: 0x%04" PRIX16
"", numberFonts);
770 WLog_Print(log, WLOG_TRACE,
"\torderFlags: 0x%04" PRIX16
"", orderFlags);
771 WLog_Print(log, WLOG_TRACE,
"\torderSupport:");
772 WLog_Print(log, WLOG_TRACE,
"\t\tDSTBLT: %" PRIu8
"", orderSupport[NEG_DSTBLT_INDEX]);
773 WLog_Print(log, WLOG_TRACE,
"\t\tPATBLT: %" PRIu8
"", orderSupport[NEG_PATBLT_INDEX]);
774 WLog_Print(log, WLOG_TRACE,
"\t\tSCRBLT: %" PRIu8
"", orderSupport[NEG_SCRBLT_INDEX]);
775 WLog_Print(log, WLOG_TRACE,
"\t\tMEMBLT: %" PRIu8
"", orderSupport[NEG_MEMBLT_INDEX]);
776 WLog_Print(log, WLOG_TRACE,
"\t\tMEM3BLT: %" PRIu8
"", orderSupport[NEG_MEM3BLT_INDEX]);
777 WLog_Print(log, WLOG_TRACE,
"\t\tATEXTOUT: %" PRIu8
"", orderSupport[NEG_ATEXTOUT_INDEX]);
778 WLog_Print(log, WLOG_TRACE,
"\t\tAEXTTEXTOUT: %" PRIu8
"", orderSupport[NEG_AEXTTEXTOUT_INDEX]);
779 WLog_Print(log, WLOG_TRACE,
"\t\tDRAWNINEGRID: %" PRIu8
"",
780 orderSupport[NEG_DRAWNINEGRID_INDEX]);
781 WLog_Print(log, WLOG_TRACE,
"\t\tLINETO: %" PRIu8
"", orderSupport[NEG_LINETO_INDEX]);
782 WLog_Print(log, WLOG_TRACE,
"\t\tMULTI_DRAWNINEGRID: %" PRIu8
"",
783 orderSupport[NEG_MULTI_DRAWNINEGRID_INDEX]);
784 WLog_Print(log, WLOG_TRACE,
"\t\tOPAQUE_RECT: %" PRIu8
"", orderSupport[NEG_OPAQUE_RECT_INDEX]);
785 WLog_Print(log, WLOG_TRACE,
"\t\tSAVEBITMAP: %" PRIu8
"", orderSupport[NEG_SAVEBITMAP_INDEX]);
786 WLog_Print(log, WLOG_TRACE,
"\t\tWTEXTOUT: %" PRIu8
"", orderSupport[NEG_WTEXTOUT_INDEX]);
787 WLog_Print(log, WLOG_TRACE,
"\t\tMEMBLT_V2: %" PRIu8
"", orderSupport[NEG_MEMBLT_V2_INDEX]);
788 WLog_Print(log, WLOG_TRACE,
"\t\tMEM3BLT_V2: %" PRIu8
"", orderSupport[NEG_MEM3BLT_V2_INDEX]);
789 WLog_Print(log, WLOG_TRACE,
"\t\tMULTIDSTBLT: %" PRIu8
"", orderSupport[NEG_MULTIDSTBLT_INDEX]);
790 WLog_Print(log, WLOG_TRACE,
"\t\tMULTIPATBLT: %" PRIu8
"", orderSupport[NEG_MULTIPATBLT_INDEX]);
791 WLog_Print(log, WLOG_TRACE,
"\t\tMULTISCRBLT: %" PRIu8
"", orderSupport[NEG_MULTISCRBLT_INDEX]);
792 WLog_Print(log, WLOG_TRACE,
"\t\tMULTIOPAQUERECT: %" PRIu8
"",
793 orderSupport[NEG_MULTIOPAQUERECT_INDEX]);
794 WLog_Print(log, WLOG_TRACE,
"\t\tFAST_INDEX: %" PRIu8
"", orderSupport[NEG_FAST_INDEX_INDEX]);
795 WLog_Print(log, WLOG_TRACE,
"\t\tPOLYGON_SC: %" PRIu8
"", orderSupport[NEG_POLYGON_SC_INDEX]);
796 WLog_Print(log, WLOG_TRACE,
"\t\tPOLYGON_CB: %" PRIu8
"", orderSupport[NEG_POLYGON_CB_INDEX]);
797 WLog_Print(log, WLOG_TRACE,
"\t\tPOLYLINE: %" PRIu8
"", orderSupport[NEG_POLYLINE_INDEX]);
798 WLog_Print(log, WLOG_TRACE,
"\t\tUNUSED23: %" PRIu8
"", orderSupport[NEG_UNUSED23_INDEX]);
799 WLog_Print(log, WLOG_TRACE,
"\t\tFAST_GLYPH: %" PRIu8
"", orderSupport[NEG_FAST_GLYPH_INDEX]);
800 WLog_Print(log, WLOG_TRACE,
"\t\tELLIPSE_SC: %" PRIu8
"", orderSupport[NEG_ELLIPSE_SC_INDEX]);
801 WLog_Print(log, WLOG_TRACE,
"\t\tELLIPSE_CB: %" PRIu8
"", orderSupport[NEG_ELLIPSE_CB_INDEX]);
802 WLog_Print(log, WLOG_TRACE,
"\t\tGLYPH_INDEX: %" PRIu8
"", orderSupport[NEG_GLYPH_INDEX_INDEX]);
803 WLog_Print(log, WLOG_TRACE,
"\t\tGLYPH_WEXTTEXTOUT: %" PRIu8
"",
804 orderSupport[NEG_GLYPH_WEXTTEXTOUT_INDEX]);
805 WLog_Print(log, WLOG_TRACE,
"\t\tGLYPH_WLONGTEXTOUT: %" PRIu8
"",
806 orderSupport[NEG_GLYPH_WLONGTEXTOUT_INDEX]);
807 WLog_Print(log, WLOG_TRACE,
"\t\tGLYPH_WLONGEXTTEXTOUT: %" PRIu8
"",
808 orderSupport[NEG_GLYPH_WLONGEXTTEXTOUT_INDEX]);
809 WLog_Print(log, WLOG_TRACE,
"\t\tUNUSED31: %" PRIu8
"", orderSupport[NEG_UNUSED31_INDEX]);
810 WLog_Print(log, WLOG_TRACE,
"\ttextFlags: 0x%04" PRIX16
"", textFlags);
811 WLog_Print(log, WLOG_TRACE,
"\torderSupportExFlags: 0x%04" PRIX16
"", orderSupportExFlags);
812 WLog_Print(log, WLOG_TRACE,
"\tpad4OctetsB: 0x%08" PRIX32
"", pad4OctetsB);
813 WLog_Print(log, WLOG_TRACE,
"\tdesktopSaveSize: 0x%08" PRIX32
"", desktopSaveSize);
814 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsC: 0x%04" PRIX16
"", pad2OctetsC);
815 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsD: 0x%04" PRIX16
"", pad2OctetsD);
816 WLog_Print(log, WLOG_TRACE,
"\ttextANSICodePage: 0x%04" PRIX16
"", textANSICodePage);
817 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsE: 0x%04" PRIX16
"", pad2OctetsE);
822static BOOL rdp_apply_bitmap_cache_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
823 WINPR_ATTR_UNUSED
const rdpSettings* src)
825 WINPR_ASSERT(settings);
835static BOOL rdp_read_bitmap_cache_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
837 WINPR_UNUSED(settings);
838 WINPR_ASSERT(settings);
840 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
843 Stream_Seek_UINT32(s);
844 Stream_Seek_UINT32(s);
845 Stream_Seek_UINT32(s);
846 Stream_Seek_UINT32(s);
847 Stream_Seek_UINT32(s);
848 Stream_Seek_UINT32(s);
849 Stream_Seek_UINT16(s);
850 Stream_Seek_UINT16(s);
851 Stream_Seek_UINT16(s);
852 Stream_Seek_UINT16(s);
853 Stream_Seek_UINT16(s);
854 Stream_Seek_UINT16(s);
863static BOOL rdp_write_bitmap_cache_capability_set(wLog* log,
wStream* s,
864 const rdpSettings* settings)
866 if (!Stream_EnsureRemainingCapacity(s, 64))
869 const size_t header = rdp_capability_set_start(log, s);
871 if (bpp > UINT16_MAX)
873 Stream_Write_UINT32(s, 0);
874 Stream_Write_UINT32(s, 0);
875 Stream_Write_UINT32(s, 0);
876 Stream_Write_UINT32(s, 0);
877 Stream_Write_UINT32(s, 0);
878 Stream_Write_UINT32(s, 0);
879 UINT32 size = bpp * 256;
880 if (size > UINT16_MAX)
882 Stream_Write_UINT16(s, 200);
883 Stream_Write_UINT16(s, (UINT16)size);
885 if (size > UINT16_MAX)
887 Stream_Write_UINT16(s, 600);
888 Stream_Write_UINT16(s, (UINT16)size);
890 if (size > UINT16_MAX)
892 Stream_Write_UINT16(s, 1000);
893 Stream_Write_UINT16(s, (UINT16)size);
894 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE);
897#ifdef WITH_DEBUG_CAPABILITIES
898static BOOL rdp_print_bitmap_cache_capability_set(wLog* log,
wStream* s)
906 UINT16 Cache0Entries = 0;
907 UINT16 Cache0MaximumCellSize = 0;
908 UINT16 Cache1Entries = 0;
909 UINT16 Cache1MaximumCellSize = 0;
910 UINT16 Cache2Entries = 0;
911 UINT16 Cache2MaximumCellSize = 0;
912 WLog_Print(log, WLOG_TRACE,
913 "BitmapCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
915 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
918 Stream_Read_UINT32(s, pad1);
919 Stream_Read_UINT32(s, pad2);
920 Stream_Read_UINT32(s, pad3);
921 Stream_Read_UINT32(s, pad4);
922 Stream_Read_UINT32(s, pad5);
923 Stream_Read_UINT32(s, pad6);
924 Stream_Read_UINT16(s, Cache0Entries);
925 Stream_Read_UINT16(s, Cache0MaximumCellSize);
926 Stream_Read_UINT16(s, Cache1Entries);
927 Stream_Read_UINT16(s, Cache1MaximumCellSize);
928 Stream_Read_UINT16(s, Cache2Entries);
929 Stream_Read_UINT16(s, Cache2MaximumCellSize);
930 WLog_Print(log, WLOG_TRACE,
"\tpad1: 0x%08" PRIX32
"", pad1);
931 WLog_Print(log, WLOG_TRACE,
"\tpad2: 0x%08" PRIX32
"", pad2);
932 WLog_Print(log, WLOG_TRACE,
"\tpad3: 0x%08" PRIX32
"", pad3);
933 WLog_Print(log, WLOG_TRACE,
"\tpad4: 0x%08" PRIX32
"", pad4);
934 WLog_Print(log, WLOG_TRACE,
"\tpad5: 0x%08" PRIX32
"", pad5);
935 WLog_Print(log, WLOG_TRACE,
"\tpad6: 0x%08" PRIX32
"", pad6);
936 WLog_Print(log, WLOG_TRACE,
"\tCache0Entries: 0x%04" PRIX16
"", Cache0Entries);
937 WLog_Print(log, WLOG_TRACE,
"\tCache0MaximumCellSize: 0x%04" PRIX16
"", Cache0MaximumCellSize);
938 WLog_Print(log, WLOG_TRACE,
"\tCache1Entries: 0x%04" PRIX16
"", Cache1Entries);
939 WLog_Print(log, WLOG_TRACE,
"\tCache1MaximumCellSize: 0x%04" PRIX16
"", Cache1MaximumCellSize);
940 WLog_Print(log, WLOG_TRACE,
"\tCache2Entries: 0x%04" PRIX16
"", Cache2Entries);
941 WLog_Print(log, WLOG_TRACE,
"\tCache2MaximumCellSize: 0x%04" PRIX16
"", Cache2MaximumCellSize);
946static BOOL rdp_apply_control_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
947 WINPR_ATTR_UNUSED
const rdpSettings* src)
949 WINPR_ASSERT(settings);
960static BOOL rdp_read_control_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
962 WINPR_UNUSED(settings);
963 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
966 Stream_Seek_UINT16(s);
967 Stream_Seek_UINT16(s);
968 Stream_Seek_UINT16(s);
969 Stream_Seek_UINT16(s);
978static BOOL rdp_write_control_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
980 WINPR_UNUSED(settings);
981 if (!Stream_EnsureRemainingCapacity(s, 32))
984 const size_t header = rdp_capability_set_start(log, s);
985 Stream_Write_UINT16(s, 0);
986 Stream_Write_UINT16(s, 0);
987 Stream_Write_UINT16(s, 2);
988 Stream_Write_UINT16(s, 2);
989 return rdp_capability_set_finish(s, header, CAPSET_TYPE_CONTROL);
992#ifdef WITH_DEBUG_CAPABILITIES
993static BOOL rdp_print_control_capability_set(wLog* log,
wStream* s)
995 UINT16 controlFlags = 0;
996 UINT16 remoteDetachFlag = 0;
997 UINT16 controlInterest = 0;
998 UINT16 detachInterest = 0;
999 WLog_Print(log, WLOG_TRACE,
1000 "ControlCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1002 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1005 Stream_Read_UINT16(s, controlFlags);
1006 Stream_Read_UINT16(s, remoteDetachFlag);
1007 Stream_Read_UINT16(s, controlInterest);
1008 Stream_Read_UINT16(s, detachInterest);
1009 WLog_Print(log, WLOG_TRACE,
"\tcontrolFlags: 0x%04" PRIX16
"", controlFlags);
1010 WLog_Print(log, WLOG_TRACE,
"\tremoteDetachFlag: 0x%04" PRIX16
"", remoteDetachFlag);
1011 WLog_Print(log, WLOG_TRACE,
"\tcontrolInterest: 0x%04" PRIX16
"", controlInterest);
1012 WLog_Print(log, WLOG_TRACE,
"\tdetachInterest: 0x%04" PRIX16
"", detachInterest);
1017static BOOL rdp_apply_window_activation_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
1018 WINPR_ATTR_UNUSED
const rdpSettings* src)
1020 WINPR_ASSERT(settings);
1031static BOOL rdp_read_window_activation_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1033 WINPR_UNUSED(settings);
1034 WINPR_ASSERT(settings);
1035 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1038 Stream_Seek_UINT16(s);
1039 Stream_Seek_UINT16(s);
1040 Stream_Seek_UINT16(s);
1041 Stream_Seek_UINT16(s);
1050static BOOL rdp_write_window_activation_capability_set(wLog* log,
wStream* s,
1051 const rdpSettings* settings)
1053 WINPR_UNUSED(settings);
1054 WINPR_ASSERT(settings);
1055 if (!Stream_EnsureRemainingCapacity(s, 32))
1058 const size_t header = rdp_capability_set_start(log, s);
1059 Stream_Write_UINT16(s, 0);
1060 Stream_Write_UINT16(s, 0);
1061 Stream_Write_UINT16(s, 0);
1062 Stream_Write_UINT16(s, 0);
1063 return rdp_capability_set_finish(s, header, CAPSET_TYPE_ACTIVATION);
1066#ifdef WITH_DEBUG_CAPABILITIES
1067static BOOL rdp_print_window_activation_capability_set(wLog* log,
wStream* s)
1069 UINT16 helpKeyFlag = 0;
1070 UINT16 helpKeyIndexFlag = 0;
1071 UINT16 helpExtendedKeyFlag = 0;
1072 UINT16 windowManagerKeyFlag = 0;
1073 WLog_Print(log, WLOG_TRACE,
1074 "WindowActivationCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1076 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1079 Stream_Read_UINT16(s, helpKeyFlag);
1080 Stream_Read_UINT16(s, helpKeyIndexFlag);
1081 Stream_Read_UINT16(s, helpExtendedKeyFlag);
1082 Stream_Read_UINT16(s, windowManagerKeyFlag);
1083 WLog_Print(log, WLOG_TRACE,
"\thelpKeyFlag: 0x%04" PRIX16
"", helpKeyFlag);
1084 WLog_Print(log, WLOG_TRACE,
"\thelpKeyIndexFlag: 0x%04" PRIX16
"", helpKeyIndexFlag);
1085 WLog_Print(log, WLOG_TRACE,
"\thelpExtendedKeyFlag: 0x%04" PRIX16
"", helpExtendedKeyFlag);
1086 WLog_Print(log, WLOG_TRACE,
"\twindowManagerKeyFlag: 0x%04" PRIX16
"", windowManagerKeyFlag);
1091static BOOL rdp_apply_pointer_capability_set(rdpSettings* settings,
const rdpSettings* src)
1093 WINPR_ASSERT(settings);
1097 const UINT32 colorPointerCacheSize =
1099 const UINT32 dstPointerCacheSize =
1101 const UINT32 dstColorPointerCacheSize =
1105 const UINT32 actualPointerCacheSize = MIN(pointerCacheSize, dstPointerCacheSize);
1106 const UINT32 actualColorPointerCacheSize = MIN(colorPointerCacheSize, dstColorPointerCacheSize);
1110 actualColorPointerCacheSize))
1121static BOOL rdp_read_pointer_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1123 UINT16 colorPointerFlag = 0;
1124 UINT16 colorPointerCacheSize = 0;
1125 UINT16 pointerCacheSize = 0;
1127 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1130 Stream_Read_UINT16(s, colorPointerFlag);
1131 Stream_Read_UINT16(s, colorPointerCacheSize);
1133 if (colorPointerFlag == 0)
1135 WLog_Print(log, WLOG_WARN,
1136 "[MS-RDPBCGR] 2.2.7.1.5 Pointer Capability Set "
1137 "(TS_POINTER_CAPABILITYSET)::colorPointerFlag received is %" PRIu16
1138 ". Value is ignored and always assumed to be TRUE",
1143 if (Stream_GetRemainingLength(s) >= 2)
1144 Stream_Read_UINT16(s, pointerCacheSize);
1146 WINPR_ASSERT(settings);
1147 settings->PointerCacheSize = pointerCacheSize;
1148 settings->ColorPointerCacheSize = colorPointerCacheSize;
1158static BOOL rdp_write_pointer_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1160 if (!Stream_EnsureRemainingCapacity(s, 32))
1163 const size_t header = rdp_capability_set_start(log, s);
1164 if (settings->PointerCacheSize > UINT16_MAX)
1166 if (settings->ColorPointerCacheSize > UINT16_MAX)
1169 WINPR_ASSERT(settings);
1170 const UINT32 colorPointerFlag =
1173 Stream_Write_UINT16(s, colorPointerFlag);
1174 Stream_Write_UINT16(
1175 s, (UINT16)settings->ColorPointerCacheSize);
1176 Stream_Write_UINT16(s, (UINT16)settings->PointerCacheSize);
1178 return rdp_capability_set_finish(s, header, CAPSET_TYPE_POINTER);
1181#ifdef WITH_DEBUG_CAPABILITIES
1182static BOOL rdp_print_pointer_capability_set(wLog* log,
wStream* s)
1184 UINT16 colorPointerFlag = 0;
1185 UINT16 colorPointerCacheSize = 0;
1186 UINT16 pointerCacheSize = 0;
1188 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 6))
1191 WLog_Print(log, WLOG_TRACE,
1192 "PointerCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1193 Stream_Read_UINT16(s, colorPointerFlag);
1194 Stream_Read_UINT16(s, colorPointerCacheSize);
1195 Stream_Read_UINT16(s, pointerCacheSize);
1196 WLog_Print(log, WLOG_TRACE,
"\tcolorPointerFlag: 0x%04" PRIX16
"", colorPointerFlag);
1197 WLog_Print(log, WLOG_TRACE,
"\tcolorPointerCacheSize: 0x%04" PRIX16
"", colorPointerCacheSize);
1198 WLog_Print(log, WLOG_TRACE,
"\tpointerCacheSize: 0x%04" PRIX16
"", pointerCacheSize);
1203static BOOL rdp_apply_share_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
1204 WINPR_ATTR_UNUSED
const rdpSettings* src)
1206 WINPR_ASSERT(settings);
1217static BOOL rdp_read_share_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1219 WINPR_UNUSED(settings);
1220 WINPR_ASSERT(settings);
1222 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1225 Stream_Seek_UINT16(s);
1226 Stream_Seek_UINT16(s);
1235static BOOL rdp_write_share_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1237 if (!Stream_EnsureRemainingCapacity(s, 32))
1240 const size_t header = rdp_capability_set_start(log, s);
1242 WINPR_ASSERT(settings);
1243 const UINT16 nodeId = (settings->ServerMode) ? 0x03EA : 0;
1244 Stream_Write_UINT16(s, nodeId);
1245 Stream_Write_UINT16(s, 0);
1246 return rdp_capability_set_finish(s, header, CAPSET_TYPE_SHARE);
1249#ifdef WITH_DEBUG_CAPABILITIES
1250static BOOL rdp_print_share_capability_set(wLog* log,
wStream* s)
1253 UINT16 pad2Octets = 0;
1254 WLog_Print(log, WLOG_TRACE,
1255 "ShareCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1257 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1260 Stream_Read_UINT16(s, nodeId);
1261 Stream_Read_UINT16(s, pad2Octets);
1262 WLog_Print(log, WLOG_TRACE,
"\tnodeId: 0x%04" PRIX16
"", nodeId);
1263 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1268static BOOL rdp_apply_color_cache_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
1269 WINPR_ATTR_UNUSED
const rdpSettings* src)
1271 WINPR_ASSERT(settings);
1281static BOOL rdp_read_color_cache_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1283 WINPR_UNUSED(settings);
1284 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1287 Stream_Seek_UINT16(s);
1288 Stream_Seek_UINT16(s);
1297static BOOL rdp_write_color_cache_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1299 WINPR_UNUSED(settings);
1300 if (!Stream_EnsureRemainingCapacity(s, 32))
1303 const size_t header = rdp_capability_set_start(log, s);
1304 Stream_Write_UINT16(s, 6);
1305 Stream_Write_UINT16(s, 0);
1306 return rdp_capability_set_finish(s, header, CAPSET_TYPE_COLOR_CACHE);
1309#ifdef WITH_DEBUG_CAPABILITIES
1310static BOOL rdp_print_color_cache_capability_set(wLog* log,
wStream* s)
1312 UINT16 colorTableCacheSize = 0;
1313 UINT16 pad2Octets = 0;
1314 WLog_Print(log, WLOG_TRACE,
1315 "ColorCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1317 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1320 Stream_Read_UINT16(s, colorTableCacheSize);
1321 Stream_Read_UINT16(s, pad2Octets);
1322 WLog_Print(log, WLOG_TRACE,
"\tcolorTableCacheSize: 0x%04" PRIX16
"", colorTableCacheSize);
1323 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1328static BOOL rdp_apply_sound_capability_set(rdpSettings* settings,
const rdpSettings* src)
1330 WINPR_ASSERT(settings);
1333 settings->SoundBeepsEnabled = src->SoundBeepsEnabled;
1343static BOOL rdp_read_sound_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1345 UINT16 soundFlags = 0;
1347 WINPR_ASSERT(settings);
1348 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1351 Stream_Read_UINT16(s, soundFlags);
1352 Stream_Seek_UINT16(s);
1353 settings->SoundBeepsEnabled = (soundFlags & SOUND_BEEPS_FLAG) ? TRUE : FALSE;
1362static BOOL rdp_write_sound_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1364 WINPR_ASSERT(settings);
1365 if (!Stream_EnsureRemainingCapacity(s, 32))
1368 const size_t header = rdp_capability_set_start(log, s);
1369 const UINT16 soundFlags = (settings->SoundBeepsEnabled) ? SOUND_BEEPS_FLAG : 0;
1370 Stream_Write_UINT16(s, soundFlags);
1371 Stream_Write_UINT16(s, 0);
1372 return rdp_capability_set_finish(s, header, CAPSET_TYPE_SOUND);
1375#ifdef WITH_DEBUG_CAPABILITIES
1376static BOOL rdp_print_sound_capability_set(wLog* log,
wStream* s)
1378 UINT16 soundFlags = 0;
1379 UINT16 pad2OctetsA = 0;
1380 WLog_Print(log, WLOG_TRACE,
1381 "SoundCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1383 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1386 Stream_Read_UINT16(s, soundFlags);
1387 Stream_Read_UINT16(s, pad2OctetsA);
1388 WLog_Print(log, WLOG_TRACE,
"\tsoundFlags: 0x%04" PRIX16
"", soundFlags);
1389 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
1394static BOOL rdp_apply_input_capability_set(rdpSettings* settings,
const rdpSettings* src)
1396 WINPR_ASSERT(settings);
1399 if (settings->ServerMode)
1401 settings->KeyboardLayout = src->KeyboardLayout;
1402 settings->KeyboardType = src->KeyboardType;
1403 settings->KeyboardSubType = src->KeyboardSubType;
1404 settings->KeyboardFunctionKey = src->KeyboardFunctionKey;
1410 if (!settings->ServerMode)
1412 settings->FastPathInput = src->FastPathInput;
1418 if (settings->HasHorizontalWheel)
1419 settings->HasHorizontalWheel = src->HasHorizontalWheel;
1427 if (settings->HasExtendedMouseEvent)
1428 settings->HasExtendedMouseEvent = src->HasExtendedMouseEvent;
1429 if (settings->HasRelativeMouseEvent)
1430 settings->HasRelativeMouseEvent = src->HasRelativeMouseEvent;
1442static BOOL rdp_read_input_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1444 UINT16 inputFlags = 0;
1446 WINPR_ASSERT(settings);
1447 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 84))
1450 Stream_Read_UINT16(s, inputFlags);
1451 Stream_Seek_UINT16(s);
1453 Stream_Read_UINT32(s, settings->KeyboardLayout);
1454 Stream_Read_UINT32(s, settings->KeyboardType);
1455 Stream_Read_UINT32(s, settings->KeyboardSubType);
1456 Stream_Read_UINT32(s, settings->KeyboardFunctionKey);
1459 WCHAR wstr[32] = { 0 };
1460 char str[65] = { 0 };
1466 if (!Stream_Read_UTF16_String(s, wstr, ARRAYSIZE(wstr)))
1469 if (ConvertWCharNToUtf8(wstr, ARRAYSIZE(wstr), str, ARRAYSIZE(str)) < 0)
1470 memset(str, 0,
sizeof(str));
1478 (INPUT_FLAG_FASTPATH_INPUT | INPUT_FLAG_FASTPATH_INPUT2)))
1481 (inputFlags & TS_INPUT_FLAG_MOUSE_HWHEEL) ? TRUE : FALSE))
1484 (inputFlags & INPUT_FLAG_UNICODE) ? TRUE : FALSE))
1487 (inputFlags & INPUT_FLAG_MOUSE_RELATIVE) ? TRUE : FALSE))
1490 (inputFlags & INPUT_FLAG_MOUSEX) ? TRUE : FALSE))
1493 (inputFlags & TS_INPUT_FLAG_QOE_TIMESTAMPS) ? TRUE : FALSE))
1504static BOOL rdp_write_input_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1506 WINPR_ASSERT(settings);
1507 if (!Stream_EnsureRemainingCapacity(s, 128))
1510 const size_t header = rdp_capability_set_start(log, s);
1511 UINT16 inputFlags = INPUT_FLAG_SCANCODES;
1513 if (settings->FastPathInput)
1515 inputFlags |= INPUT_FLAG_FASTPATH_INPUT;
1516 inputFlags |= INPUT_FLAG_FASTPATH_INPUT2;
1520 inputFlags |= INPUT_FLAG_MOUSE_RELATIVE;
1523 inputFlags |= TS_INPUT_FLAG_MOUSE_HWHEEL;
1526 inputFlags |= INPUT_FLAG_UNICODE;
1529 inputFlags |= TS_INPUT_FLAG_QOE_TIMESTAMPS;
1531 if (settings->HasExtendedMouseEvent)
1532 inputFlags |= INPUT_FLAG_MOUSEX;
1534 Stream_Write_UINT16(s, inputFlags);
1535 Stream_Write_UINT16(s, 0);
1536 Stream_Write_UINT32(s, settings->KeyboardLayout);
1537 Stream_Write_UINT32(s, settings->KeyboardType);
1538 Stream_Write_UINT32(s, settings->KeyboardSubType);
1539 Stream_Write_UINT32(s, settings->KeyboardFunctionKey);
1541 return rdp_capability_set_finish(s, header, CAPSET_TYPE_INPUT);
1544#ifdef WITH_DEBUG_CAPABILITIES
1545static BOOL rdp_print_input_capability_set(wLog* log,
wStream* s)
1547 UINT16 inputFlags = 0;
1548 UINT16 pad2OctetsA = 0;
1549 UINT32 keyboardLayout = 0;
1550 UINT32 keyboardType = 0;
1551 UINT32 keyboardSubType = 0;
1552 UINT32 keyboardFunctionKey = 0;
1553 WLog_Print(log, WLOG_TRACE,
"InputCapabilitySet (length %" PRIuz
")",
1554 Stream_GetRemainingLength(s));
1556 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 84))
1559 Stream_Read_UINT16(s, inputFlags);
1560 Stream_Read_UINT16(s, pad2OctetsA);
1561 Stream_Read_UINT32(s, keyboardLayout);
1562 Stream_Read_UINT32(s, keyboardType);
1563 Stream_Read_UINT32(s, keyboardSubType);
1564 Stream_Read_UINT32(s, keyboardFunctionKey);
1566 WLog_Print(log, WLOG_TRACE,
"\tinputFlags: 0x%04" PRIX16
"", inputFlags);
1567 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
1568 WLog_Print(log, WLOG_TRACE,
"\tkeyboardLayout: 0x%08" PRIX32
"", keyboardLayout);
1569 WLog_Print(log, WLOG_TRACE,
"\tkeyboardType: 0x%08" PRIX32
"", keyboardType);
1570 WLog_Print(log, WLOG_TRACE,
"\tkeyboardSubType: 0x%08" PRIX32
"", keyboardSubType);
1571 WLog_Print(log, WLOG_TRACE,
"\tkeyboardFunctionKey: 0x%08" PRIX32
"", keyboardFunctionKey);
1576static BOOL rdp_apply_font_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
1577 WINPR_ATTR_UNUSED
const rdpSettings* src)
1579 WINPR_ASSERT(settings);
1589static BOOL rdp_read_font_capability_set(WINPR_ATTR_UNUSED wLog* log,
wStream* s,
1590 rdpSettings* settings)
1592 WINPR_UNUSED(settings);
1593 if (Stream_GetRemainingLength(s) >= 2)
1594 Stream_Seek_UINT16(s);
1596 if (Stream_GetRemainingLength(s) >= 2)
1597 Stream_Seek_UINT16(s);
1607static BOOL rdp_write_font_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1609 WINPR_UNUSED(settings);
1610 if (!Stream_EnsureRemainingCapacity(s, 32))
1613 const size_t header = rdp_capability_set_start(log, s);
1614 Stream_Write_UINT16(s, FONTSUPPORT_FONTLIST);
1615 Stream_Write_UINT16(s, 0);
1616 return rdp_capability_set_finish(s, header, CAPSET_TYPE_FONT);
1619#ifdef WITH_DEBUG_CAPABILITIES
1620static BOOL rdp_print_font_capability_set(wLog* log,
wStream* s)
1622 UINT16 fontSupportFlags = 0;
1623 UINT16 pad2Octets = 0;
1624 WLog_Print(log, WLOG_TRACE,
1625 "FontCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1627 if (Stream_GetRemainingLength(s) >= 2)
1628 Stream_Read_UINT16(s, fontSupportFlags);
1630 if (Stream_GetRemainingLength(s) >= 2)
1631 Stream_Read_UINT16(s, pad2Octets);
1633 WLog_Print(log, WLOG_TRACE,
"\tfontSupportFlags: 0x%04" PRIX16
"", fontSupportFlags);
1634 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1639static BOOL rdp_apply_brush_capability_set(rdpSettings* settings,
const rdpSettings* src)
1641 WINPR_ASSERT(settings);
1645 settings->BrushSupportLevel = src->BrushSupportLevel;
1654static BOOL rdp_read_brush_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1656 WINPR_UNUSED(settings);
1657 WINPR_ASSERT(settings);
1659 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1661 Stream_Read_UINT32(s, settings->BrushSupportLevel);
1670static BOOL rdp_write_brush_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1672 WINPR_ASSERT(settings);
1673 if (!Stream_EnsureRemainingCapacity(s, 32))
1676 const size_t header = rdp_capability_set_start(log, s);
1677 Stream_Write_UINT32(s, settings->BrushSupportLevel);
1678 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BRUSH);
1681#ifdef WITH_DEBUG_CAPABILITIES
1682static BOOL rdp_print_brush_capability_set(wLog* log,
wStream* s)
1684 UINT32 brushSupportLevel = 0;
1685 WLog_Print(log, WLOG_TRACE,
1686 "BrushCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1688 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1691 Stream_Read_UINT32(s, brushSupportLevel);
1692 WLog_Print(log, WLOG_TRACE,
"\tbrushSupportLevel: 0x%08" PRIX32
"", brushSupportLevel);
1703 WINPR_ASSERT(cache_definition);
1704 Stream_Read_UINT16(s, cache_definition->cacheEntries);
1705 Stream_Read_UINT16(s,
1706 cache_definition->cacheMaximumCellSize);
1715 WINPR_ASSERT(cache_definition);
1716 Stream_Write_UINT16(s, cache_definition->cacheEntries);
1717 Stream_Write_UINT16(
1718 s, cache_definition->cacheMaximumCellSize);
1721static BOOL rdp_apply_glyph_cache_capability_set(rdpSettings* settings,
const rdpSettings* src)
1723 WINPR_ASSERT(settings);
1726 WINPR_ASSERT(src->GlyphCache);
1727 WINPR_ASSERT(settings->GlyphCache);
1728 for (
size_t x = 0; x < 10; x++)
1729 settings->GlyphCache[x] = src->GlyphCache[x];
1731 WINPR_ASSERT(src->FragCache);
1732 WINPR_ASSERT(settings->FragCache);
1733 settings->FragCache[0] = src->FragCache[0];
1734 settings->GlyphSupportLevel = src->GlyphSupportLevel;
1744static BOOL rdp_read_glyph_cache_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1746 WINPR_ASSERT(settings);
1747 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 48))
1751 for (
size_t x = 0; x < 10; x++)
1752 rdp_read_cache_definition(s, &(settings->GlyphCache[x]));
1753 rdp_read_cache_definition(s, settings->FragCache);
1754 Stream_Read_UINT16(s, settings->GlyphSupportLevel);
1755 Stream_Seek_UINT16(s);
1764static BOOL rdp_write_glyph_cache_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1766 WINPR_ASSERT(settings);
1767 if (!Stream_EnsureRemainingCapacity(s, 64))
1770 const size_t header = rdp_capability_set_start(log, s);
1771 if (settings->GlyphSupportLevel > UINT16_MAX)
1774 for (
size_t x = 0; x < 10; x++)
1775 rdp_write_cache_definition(s, &(settings->GlyphCache[x]));
1776 rdp_write_cache_definition(s, settings->FragCache);
1777 Stream_Write_UINT16(s, (UINT16)settings->GlyphSupportLevel);
1778 Stream_Write_UINT16(s, 0);
1779 return rdp_capability_set_finish(s, header, CAPSET_TYPE_GLYPH_CACHE);
1782#ifdef WITH_DEBUG_CAPABILITIES
1783static BOOL rdp_print_glyph_cache_capability_set(wLog* log,
wStream* s)
1787 UINT16 glyphSupportLevel = 0;
1788 UINT16 pad2Octets = 0;
1789 WLog_Print(log, WLOG_TRACE,
1790 "GlyphCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1792 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 48))
1796 rdp_read_cache_definition(s, &glyphCache[0]);
1797 rdp_read_cache_definition(s, &glyphCache[1]);
1798 rdp_read_cache_definition(s, &glyphCache[2]);
1799 rdp_read_cache_definition(s, &glyphCache[3]);
1800 rdp_read_cache_definition(s, &glyphCache[4]);
1801 rdp_read_cache_definition(s, &glyphCache[5]);
1802 rdp_read_cache_definition(s, &glyphCache[6]);
1803 rdp_read_cache_definition(s, &glyphCache[7]);
1804 rdp_read_cache_definition(s, &glyphCache[8]);
1805 rdp_read_cache_definition(s, &glyphCache[9]);
1806 rdp_read_cache_definition(s, &fragCache);
1807 Stream_Read_UINT16(s, glyphSupportLevel);
1808 Stream_Read_UINT16(s, pad2Octets);
1809 WLog_Print(log, WLOG_TRACE,
"\tglyphCache0: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1810 glyphCache[0].cacheEntries, glyphCache[0].cacheMaximumCellSize);
1811 WLog_Print(log, WLOG_TRACE,
"\tglyphCache1: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1812 glyphCache[1].cacheEntries, glyphCache[1].cacheMaximumCellSize);
1813 WLog_Print(log, WLOG_TRACE,
"\tglyphCache2: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1814 glyphCache[2].cacheEntries, glyphCache[2].cacheMaximumCellSize);
1815 WLog_Print(log, WLOG_TRACE,
"\tglyphCache3: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1816 glyphCache[3].cacheEntries, glyphCache[3].cacheMaximumCellSize);
1817 WLog_Print(log, WLOG_TRACE,
"\tglyphCache4: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1818 glyphCache[4].cacheEntries, glyphCache[4].cacheMaximumCellSize);
1819 WLog_Print(log, WLOG_TRACE,
"\tglyphCache5: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1820 glyphCache[5].cacheEntries, glyphCache[5].cacheMaximumCellSize);
1821 WLog_Print(log, WLOG_TRACE,
"\tglyphCache6: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1822 glyphCache[6].cacheEntries, glyphCache[6].cacheMaximumCellSize);
1823 WLog_Print(log, WLOG_TRACE,
"\tglyphCache7: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1824 glyphCache[7].cacheEntries, glyphCache[7].cacheMaximumCellSize);
1825 WLog_Print(log, WLOG_TRACE,
"\tglyphCache8: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1826 glyphCache[8].cacheEntries, glyphCache[8].cacheMaximumCellSize);
1827 WLog_Print(log, WLOG_TRACE,
"\tglyphCache9: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1828 glyphCache[9].cacheEntries, glyphCache[9].cacheMaximumCellSize);
1829 WLog_Print(log, WLOG_TRACE,
"\tfragCache: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1830 fragCache.cacheEntries, fragCache.cacheMaximumCellSize);
1831 WLog_Print(log, WLOG_TRACE,
"\tglyphSupportLevel: 0x%04" PRIX16
"", glyphSupportLevel);
1832 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1837static BOOL rdp_apply_offscreen_bitmap_cache_capability_set(rdpSettings* settings,
1838 const rdpSettings* src)
1840 WINPR_ASSERT(settings);
1843 settings->OffscreenCacheSize = src->OffscreenCacheSize;
1844 settings->OffscreenCacheEntries = src->OffscreenCacheEntries;
1845 settings->OffscreenSupportLevel = src->OffscreenSupportLevel;
1855static BOOL rdp_read_offscreen_bitmap_cache_capability_set(wLog* log,
wStream* s,
1856 rdpSettings* settings)
1858 UINT32 offscreenSupportLevel = 0;
1860 WINPR_ASSERT(settings);
1861 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1864 Stream_Read_UINT32(s, offscreenSupportLevel);
1865 Stream_Read_UINT16(s, settings->OffscreenCacheSize);
1866 Stream_Read_UINT16(s, settings->OffscreenCacheEntries);
1868 settings->OffscreenSupportLevel = offscreenSupportLevel & 0x01;
1878static BOOL rdp_write_offscreen_bitmap_cache_capability_set(wLog* log,
wStream* s,
1879 const rdpSettings* settings)
1881 UINT32 offscreenSupportLevel = 0x00;
1883 WINPR_ASSERT(settings);
1884 if (!Stream_EnsureRemainingCapacity(s, 32))
1887 const size_t header = rdp_capability_set_start(log, s);
1888 if (settings->OffscreenSupportLevel)
1890 offscreenSupportLevel = 0x01;
1891 Stream_Write_UINT32(s, offscreenSupportLevel);
1892 Stream_Write_UINT16(
1893 s, WINPR_ASSERTING_INT_CAST(
1894 uint16_t, settings->OffscreenCacheSize));
1895 Stream_Write_UINT16(
1897 WINPR_ASSERTING_INT_CAST(
1898 uint16_t, settings->OffscreenCacheEntries));
1903 return rdp_capability_set_finish(s, header, CAPSET_TYPE_OFFSCREEN_CACHE);
1906#ifdef WITH_DEBUG_CAPABILITIES
1907static BOOL rdp_print_offscreen_bitmap_cache_capability_set(wLog* log,
wStream* s)
1909 UINT32 offscreenSupportLevel = 0;
1910 UINT16 offscreenCacheSize = 0;
1911 UINT16 offscreenCacheEntries = 0;
1912 WLog_Print(log, WLOG_TRACE,
"OffscreenBitmapCacheCapabilitySet (length %" PRIuz
"):",
1913 Stream_GetRemainingLength(s));
1915 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1918 Stream_Read_UINT32(s, offscreenSupportLevel);
1919 Stream_Read_UINT16(s, offscreenCacheSize);
1920 Stream_Read_UINT16(s, offscreenCacheEntries);
1921 WLog_Print(log, WLOG_TRACE,
"\toffscreenSupportLevel: 0x%08" PRIX32
"", offscreenSupportLevel);
1922 WLog_Print(log, WLOG_TRACE,
"\toffscreenCacheSize: 0x%04" PRIX16
"", offscreenCacheSize);
1923 WLog_Print(log, WLOG_TRACE,
"\toffscreenCacheEntries: 0x%04" PRIX16
"", offscreenCacheEntries);
1928static BOOL rdp_apply_bitmap_cache_host_support_capability_set(rdpSettings* settings,
1929 const rdpSettings* src)
1941static BOOL rdp_read_bitmap_cache_host_support_capability_set(wLog* log,
wStream* s,
1942 rdpSettings* settings)
1944 BYTE cacheVersion = 0;
1946 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1949 Stream_Read_UINT8(s, cacheVersion);
1950 Stream_Seek_UINT8(s);
1951 Stream_Seek_UINT16(s);
1954 cacheVersion & BITMAP_CACHE_V2);
1962static BOOL rdp_write_bitmap_cache_host_support_capability_set(wLog* log,
wStream* s,
1963 const rdpSettings* settings)
1965 UINT8 cacheVersion = 0;
1968 cacheVersion |= BITMAP_CACHE_V2;
1970 if (!Stream_EnsureRemainingCapacity(s, 32))
1973 const size_t header = rdp_capability_set_start(log, s);
1974 Stream_Write_UINT8(s, cacheVersion);
1975 Stream_Write_UINT8(s, 0);
1976 Stream_Write_UINT16(s, 0);
1977 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT);
1980#ifdef WITH_DEBUG_CAPABILITIES
1981static BOOL rdp_print_bitmap_cache_host_support_capability_set(wLog* log,
wStream* s)
1983 BYTE cacheVersion = 0;
1986 WLog_Print(log, WLOG_TRACE,
"BitmapCacheHostSupportCapabilitySet (length %" PRIuz
"):",
1987 Stream_GetRemainingLength(s));
1989 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1992 Stream_Read_UINT8(s, cacheVersion);
1993 Stream_Read_UINT8(s, pad1);
1994 Stream_Read_UINT16(s, pad2);
1995 WLog_Print(log, WLOG_TRACE,
"\tcacheVersion: 0x%02" PRIX8
"", cacheVersion);
1996 WLog_Print(log, WLOG_TRACE,
"\tpad1: 0x%02" PRIX8
"", pad1);
1997 WLog_Print(log, WLOG_TRACE,
"\tpad2: 0x%04" PRIX16
"", pad2);
2002static BOOL rdp_read_bitmap_cache_cell_info(wLog* log,
wStream* s,
2007 WINPR_ASSERT(cellInfo);
2008 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2015 Stream_Read_UINT32(s, info);
2016 cellInfo->numEntries = (info & 0x7FFFFFFF);
2017 cellInfo->persistent = (info & 0x80000000) ? 1 : 0;
2028 WINPR_ASSERT(cellInfo);
2029 info = (cellInfo->numEntries | (((UINT32)cellInfo->persistent << 31) & 0xFF000000));
2030 Stream_Write_UINT32(s, info);
2033static BOOL rdp_apply_bitmap_cache_v2_capability_set(rdpSettings* settings,
const rdpSettings* src)
2035 const FreeRDP_Settings_Keys_Bool keys[] = { FreeRDP_BitmapCacheEnabled,
2036 FreeRDP_BitmapCachePersistEnabled };
2038 for (
size_t x = 0; x < ARRAYSIZE(keys); x++)
2040 const FreeRDP_Settings_Keys_Bool
id = keys[x];
2047 const UINT32 BitmapCacheV2NumCells =
2050 BitmapCacheV2NumCells))
2053 for (
size_t x = 0; x < BitmapCacheV2NumCells; x++)
2056 freerdp_settings_get_pointer_array(src, FreeRDP_BitmapCacheV2CellInfo, x);
2057 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_BitmapCacheV2CellInfo, x,
2071static BOOL rdp_read_bitmap_cache_v2_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2073 UINT16 cacheFlags = 0;
2074 WINPR_UNUSED(settings);
2075 WINPR_ASSERT(settings);
2077 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
2080 Stream_Read_UINT16(s, cacheFlags);
2085 cacheFlags & PERSISTENT_KEYS_EXPECTED_FLAG))
2088 Stream_Seek_UINT8(s);
2089 Stream_Read_UINT8(s, settings->BitmapCacheV2NumCells);
2090 if (settings->BitmapCacheV2NumCells > 5)
2092 WLog_Print(log, WLOG_ERROR,
2093 "Invalid TS_BITMAPCACHE_CAPABILITYSET_REV2::numCellCaches %" PRIu32
" > 5",
2094 settings->BitmapCacheV2NumCells);
2098 for (
size_t x = 0; x < settings->BitmapCacheV2NumCells; x++)
2101 freerdp_settings_get_pointer_array_writable(settings, FreeRDP_BitmapCacheV2CellInfo, x);
2102 if (!rdp_read_bitmap_cache_cell_info(log, s, info))
2107 for (
size_t x = settings->BitmapCacheV2NumCells; x < 5; x++)
2109 if (!Stream_SafeSeek(s, 4))
2121static BOOL rdp_write_bitmap_cache_v2_capability_set(wLog* log,
wStream* s,
2122 const rdpSettings* settings)
2124 WINPR_ASSERT(settings);
2125 if (!Stream_EnsureRemainingCapacity(s, 64))
2128 const size_t header = rdp_capability_set_start(log, s);
2129 UINT16 cacheFlags = ALLOW_CACHE_WAITING_LIST_FLAG;
2133 cacheFlags |= PERSISTENT_KEYS_EXPECTED_FLAG;
2134 settings->BitmapCacheV2CellInfo[0].persistent = 1;
2135 settings->BitmapCacheV2CellInfo[1].persistent = 1;
2136 settings->BitmapCacheV2CellInfo[2].persistent = 1;
2137 settings->BitmapCacheV2CellInfo[3].persistent = 1;
2138 settings->BitmapCacheV2CellInfo[4].persistent = 1;
2141 Stream_Write_UINT16(s, cacheFlags);
2142 Stream_Write_UINT8(s, 0);
2144 s, WINPR_ASSERTING_INT_CAST(uint8_t,
2145 settings->BitmapCacheV2NumCells));
2146 rdp_write_bitmap_cache_cell_info(
2147 s, &settings->BitmapCacheV2CellInfo[0]);
2148 rdp_write_bitmap_cache_cell_info(
2149 s, &settings->BitmapCacheV2CellInfo[1]);
2150 rdp_write_bitmap_cache_cell_info(
2151 s, &settings->BitmapCacheV2CellInfo[2]);
2152 rdp_write_bitmap_cache_cell_info(
2153 s, &settings->BitmapCacheV2CellInfo[3]);
2154 rdp_write_bitmap_cache_cell_info(
2155 s, &settings->BitmapCacheV2CellInfo[4]);
2157 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_V2);
2160#ifdef WITH_DEBUG_CAPABILITIES
2161static BOOL rdp_print_bitmap_cache_v2_capability_set(wLog* log,
wStream* s)
2164 WLog_Print(log, WLOG_TRACE,
2165 "BitmapCacheV2CapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2167 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
2170 const UINT16 cacheFlags = Stream_Get_UINT16(s);
2171 const UINT8 pad2 = Stream_Get_UINT8(s);
2172 const UINT8 numCellCaches = Stream_Get_UINT8(s);
2174 for (
size_t x = 0; x < ARRAYSIZE(bitmapCacheV2CellInfo); x++)
2176 if (!rdp_read_bitmap_cache_cell_info(
2177 log, s, &bitmapCacheV2CellInfo[x]))
2181 if (!Stream_SafeSeek(s, 12))
2184 WLog_Print(log, WLOG_TRACE,
"\tcacheFlags: 0x%04" PRIX16
"", cacheFlags);
2185 WLog_Print(log, WLOG_TRACE,
"\tpad2: 0x%02" PRIX8
"", pad2);
2186 WLog_Print(log, WLOG_TRACE,
"\tnumCellCaches: 0x%02" PRIX8
"", numCellCaches);
2187 for (
size_t x = 0; x < ARRAYSIZE(bitmapCacheV2CellInfo); x++)
2190 WLog_Print(log, WLOG_TRACE,
2191 "\tbitmapCache%" PRIuz
"CellInfo: numEntries: %" PRIu32
" persistent: %" PRId32
2193 x, info->numEntries, info->persistent);
2199static BOOL rdp_apply_virtual_channel_capability_set(rdpSettings* settings,
const rdpSettings* src)
2201 WINPR_ASSERT(settings);
2205 if (settings->ServerMode && (settings->VCFlags & VCCAPS_COMPR_SC) &&
2206 (src->VCFlags & VCCAPS_COMPR_SC))
2207 settings->VCFlags |= VCCAPS_COMPR_SC;
2209 settings->VCFlags &= (uint32_t)~VCCAPS_COMPR_SC;
2211 if (!settings->ServerMode && (settings->VCFlags & VCCAPS_COMPR_CS_8K) &&
2212 (src->VCFlags & VCCAPS_COMPR_CS_8K))
2213 settings->VCFlags |= VCCAPS_COMPR_CS_8K;
2215 settings->VCFlags &= (uint32_t)~VCCAPS_COMPR_CS_8K;
2222 if (!settings->ServerMode)
2224 if ((src->VCChunkSize > CHANNEL_CHUNK_MAX_LENGTH) || (src->VCChunkSize == 0))
2225 settings->VCChunkSize = CHANNEL_CHUNK_LENGTH;
2228 settings->VCChunkSize = src->VCChunkSize;
2240static BOOL rdp_read_virtual_channel_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2243 UINT32 VCChunkSize = 0;
2245 WINPR_ASSERT(settings);
2246 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2249 Stream_Read_UINT32(s, flags);
2251 if (Stream_GetRemainingLength(s) >= 4)
2252 Stream_Read_UINT32(s, VCChunkSize);
2254 VCChunkSize = UINT32_MAX;
2256 settings->VCFlags = flags;
2257 settings->VCChunkSize = VCChunkSize;
2267static BOOL rdp_write_virtual_channel_capability_set(wLog* log,
wStream* s,
2268 const rdpSettings* settings)
2270 WINPR_ASSERT(settings);
2271 if (!Stream_EnsureRemainingCapacity(s, 32))
2274 const size_t header = rdp_capability_set_start(log, s);
2275 Stream_Write_UINT32(s, settings->VCFlags);
2276 Stream_Write_UINT32(s, settings->VCChunkSize);
2277 return rdp_capability_set_finish(s, header, CAPSET_TYPE_VIRTUAL_CHANNEL);
2280#ifdef WITH_DEBUG_CAPABILITIES
2281static BOOL rdp_print_virtual_channel_capability_set(wLog* log,
wStream* s)
2284 UINT32 VCChunkSize = 0;
2285 WLog_Print(log, WLOG_TRACE,
2286 "VirtualChannelCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2288 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2291 Stream_Read_UINT32(s, flags);
2293 if (Stream_GetRemainingLength(s) >= 4)
2294 Stream_Read_UINT32(s, VCChunkSize);
2298 WLog_Print(log, WLOG_TRACE,
"\tflags: 0x%08" PRIX32
"", flags);
2299 WLog_Print(log, WLOG_TRACE,
"\tVCChunkSize: 0x%08" PRIX32
"", VCChunkSize);
2304static BOOL rdp_apply_draw_nine_grid_cache_capability_set(rdpSettings* settings,
2305 const rdpSettings* src)
2307 WINPR_ASSERT(settings);
2310 settings->DrawNineGridCacheSize = src->DrawNineGridCacheSize;
2311 settings->DrawNineGridCacheEntries = src->DrawNineGridCacheEntries;
2312 settings->DrawNineGridEnabled = src->DrawNineGridEnabled;
2322static BOOL rdp_read_draw_nine_grid_cache_capability_set(wLog* log,
wStream* s,
2323 rdpSettings* settings)
2325 UINT32 drawNineGridSupportLevel = 0;
2327 WINPR_ASSERT(settings);
2328 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
2331 Stream_Read_UINT32(s, drawNineGridSupportLevel);
2332 Stream_Read_UINT16(s, settings->DrawNineGridCacheSize);
2333 Stream_Read_UINT16(s,
2334 settings->DrawNineGridCacheEntries);
2336 settings->DrawNineGridEnabled =
2337 (drawNineGridSupportLevel & (DRAW_NINEGRID_SUPPORTED | DRAW_NINEGRID_SUPPORTED_V2)) ? TRUE
2348static BOOL rdp_write_draw_nine_grid_cache_capability_set(wLog* log,
wStream* s,
2349 const rdpSettings* settings)
2351 WINPR_ASSERT(settings);
2352 if (!Stream_EnsureRemainingCapacity(s, 32))
2355 const size_t header = rdp_capability_set_start(log, s);
2356 const UINT32 drawNineGridSupportLevel =
2357 (settings->DrawNineGridEnabled) ? DRAW_NINEGRID_SUPPORTED_V2 : DRAW_NINEGRID_NO_SUPPORT;
2358 Stream_Write_UINT32(s, drawNineGridSupportLevel);
2359 Stream_Write_UINT16(
2360 s, WINPR_ASSERTING_INT_CAST(
2361 uint16_t, settings->DrawNineGridCacheSize));
2362 Stream_Write_UINT16(
2364 WINPR_ASSERTING_INT_CAST(
2365 uint16_t, settings->DrawNineGridCacheEntries));
2366 return rdp_capability_set_finish(s, header, CAPSET_TYPE_DRAW_NINE_GRID_CACHE);
2369#ifdef WITH_DEBUG_CAPABILITIES
2370static BOOL rdp_print_draw_nine_grid_cache_capability_set(wLog* log,
wStream* s)
2372 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
2375 const uint32_t drawNineGridSupportLevel =
2376 Stream_Get_UINT32(s);
2377 const uint32_t DrawNineGridCacheSize =
2378 Stream_Get_UINT16(s);
2379 const uint32_t DrawNineGridCacheEntries =
2380 Stream_Get_UINT16(s);
2382 WLog_Print(log, WLOG_TRACE,
2383 "DrawNineGridCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2384 WLog_Print(log, WLOG_TRACE,
"drawNineGridSupportLevel=0x%08" PRIx32, drawNineGridSupportLevel);
2385 WLog_Print(log, WLOG_TRACE,
"DrawNineGridCacheSize=0x%08" PRIx32, DrawNineGridCacheSize);
2386 WLog_Print(log, WLOG_TRACE,
"DrawNineGridCacheEntries=0x%08" PRIx32, DrawNineGridCacheEntries);
2391static BOOL rdp_apply_draw_gdiplus_cache_capability_set(rdpSettings* settings,
2392 const rdpSettings* src)
2394 WINPR_ASSERT(settings);
2397 if (src->DrawGdiPlusEnabled)
2398 settings->DrawGdiPlusEnabled = TRUE;
2400 if (src->DrawGdiPlusCacheEnabled)
2401 settings->DrawGdiPlusCacheEnabled = TRUE;
2411static BOOL rdp_read_draw_gdiplus_cache_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2413 UINT32 drawGDIPlusSupportLevel = 0;
2414 UINT32 drawGdiplusCacheLevel = 0;
2416 WINPR_ASSERT(settings);
2417 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
2420 Stream_Read_UINT32(s, drawGDIPlusSupportLevel);
2421 Stream_Seek_UINT32(s);
2422 Stream_Read_UINT32(s, drawGdiplusCacheLevel);
2427 settings->DrawGdiPlusEnabled =
2428 (drawGDIPlusSupportLevel & DRAW_GDIPLUS_SUPPORTED) ? TRUE : FALSE;
2429 settings->DrawGdiPlusCacheEnabled =
2430 (drawGdiplusCacheLevel & DRAW_GDIPLUS_CACHE_LEVEL_ONE) ? TRUE : FALSE;
2435#ifdef WITH_DEBUG_CAPABILITIES
2436static BOOL rdp_print_draw_gdiplus_cache_capability_set(wLog* log,
wStream* s)
2438 WLog_Print(log, WLOG_TRACE,
2439 "DrawGdiPlusCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2441 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
2444 const uint32_t drawGdiPlusSupportLevel =
2445 Stream_Get_UINT32(s);
2446 const uint32_t GdipVersion = Stream_Get_UINT32(s);
2447 const uint32_t drawGdiplusCacheLevel =
2448 Stream_Get_UINT32(s);
2449 WLog_Print(log, WLOG_TRACE,
2450 "drawGdiPlusSupportLevel=0x%08" PRIx32
", GdipVersion=0x%08" PRIx32
2451 ", drawGdiplusdrawGdiplusCacheLevelCacheLevel=0x%08" PRIx32,
2452 drawGdiPlusSupportLevel, GdipVersion, drawGdiplusCacheLevel);
2454 const uint16_t GdipGraphicsCacheEntries = Stream_Get_UINT16(s);
2455 const uint16_t GdipBrushCacheEntries = Stream_Get_UINT16(s);
2456 const uint16_t GdipPenCacheEntries = Stream_Get_UINT16(s);
2457 const uint16_t GdipImageCacheEntries = Stream_Get_UINT16(s);
2458 const uint16_t GdipImageAttributesCacheEntries = Stream_Get_UINT16(s);
2459 WLog_Print(log, WLOG_TRACE,
2460 "GdipGraphicsCacheEntries=0x%04" PRIx16
", GdipBrushCacheEntries=0x%04" PRIx16
2461 ", GdipPenCacheEntries=0x%04" PRIx16
", GdipImageCacheEntries=0x%04" PRIx16
2462 ", GdipImageAttributesCacheEntries=0x%04" PRIx16,
2463 GdipGraphicsCacheEntries, GdipBrushCacheEntries, GdipPenCacheEntries,
2464 GdipImageCacheEntries, GdipImageAttributesCacheEntries);
2466 const uint16_t GdipGraphicsCacheChunkSize = Stream_Get_UINT16(s);
2467 const uint16_t GdipObjectBrushCacheChunkSize = Stream_Get_UINT16(s);
2468 const uint16_t GdipObjectPenCacheChunkSize = Stream_Get_UINT16(s);
2469 const uint16_t GdipObjectImageAttributesCacheChunkSize = Stream_Get_UINT16(s);
2470 WLog_Print(log, WLOG_TRACE,
2471 "GdipGraphicsCacheChunkSize=0x%04" PRIx16
2472 ", GdipObjectBrushCacheChunkSize=0x%04" PRIx16
2473 ", GdipObjectPenCacheChunkSize=0x%04" PRIx16
2474 ",GdipObjectImageAttributesCacheChunkSize=0x%04" PRIx16,
2475 GdipGraphicsCacheChunkSize, GdipObjectBrushCacheChunkSize,
2476 GdipObjectPenCacheChunkSize, GdipObjectImageAttributesCacheChunkSize);
2478 const uint16_t GdipObjectImageCacheChunkSize = Stream_Get_UINT16(s);
2479 const uint16_t GdipObjectImageCacheTotalSize = Stream_Get_UINT16(s);
2480 const uint16_t GdipObjectImageCacheMaxSize = Stream_Get_UINT16(s);
2483 "GdipObjectImageCacheChunkSize=0x%04" PRIx16
", GdipObjectImageCacheTotalSize=0x%04" PRIx16
2484 ", GdipObjectImageCacheMaxSize=0x%04" PRIx16,
2485 GdipObjectImageCacheChunkSize, GdipObjectImageCacheTotalSize, GdipObjectImageCacheMaxSize);
2490static BOOL rdp_apply_remote_programs_capability_set(rdpSettings* settings,
const rdpSettings* src)
2492 WINPR_ASSERT(settings);
2495 if (settings->RemoteApplicationMode)
2496 settings->RemoteApplicationMode = src->RemoteApplicationMode;
2501 UINT32 supportLevel = src->RemoteApplicationSupportLevel;
2502 if (settings->RemoteApplicationMode)
2503 supportLevel |= RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED;
2505 settings->RemoteApplicationSupportLevel = supportLevel & settings->RemoteApplicationSupportMask;
2515static BOOL rdp_read_remote_programs_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2517 UINT32 railSupportLevel = 0;
2519 WINPR_ASSERT(settings);
2520 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2523 Stream_Read_UINT32(s, railSupportLevel);
2525 settings->RemoteApplicationMode = (railSupportLevel & RAIL_LEVEL_SUPPORTED) ? TRUE : FALSE;
2526 settings->RemoteApplicationSupportLevel = railSupportLevel;
2535static BOOL rdp_write_remote_programs_capability_set(wLog* log,
wStream* s,
2536 const rdpSettings* settings)
2538 WINPR_ASSERT(settings);
2539 if (!Stream_EnsureRemainingCapacity(s, 64))
2542 const size_t header = rdp_capability_set_start(log, s);
2543 UINT32 railSupportLevel = RAIL_LEVEL_SUPPORTED;
2545 if (settings->RemoteApplicationSupportLevel & RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED)
2547 if (settings->RemoteAppLanguageBarSupported)
2548 railSupportLevel |= RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED;
2551 railSupportLevel |= RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED;
2552 railSupportLevel |= RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED;
2553 railSupportLevel |= RAIL_LEVEL_SERVER_TO_CLIENT_IME_SYNC_SUPPORTED;
2554 railSupportLevel |= RAIL_LEVEL_HIDE_MINIMIZED_APPS_SUPPORTED;
2555 railSupportLevel |= RAIL_LEVEL_WINDOW_CLOAKING_SUPPORTED;
2556 railSupportLevel |= RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED;
2558 railSupportLevel &= settings->RemoteApplicationSupportLevel;
2559 Stream_Write_UINT32(s, railSupportLevel);
2560 return rdp_capability_set_finish(s, header, CAPSET_TYPE_RAIL);
2563#ifdef WITH_DEBUG_CAPABILITIES
2564static BOOL rdp_print_remote_programs_capability_set(wLog* log,
wStream* s)
2566 UINT32 railSupportLevel = 0;
2567 WLog_Print(log, WLOG_TRACE,
2568 "RemoteProgramsCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2570 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2573 Stream_Read_UINT32(s, railSupportLevel);
2574 WLog_Print(log, WLOG_TRACE,
"\trailSupportLevel: 0x%08" PRIX32
"", railSupportLevel);
2579static BOOL rdp_apply_window_list_capability_set(rdpSettings* settings,
const rdpSettings* src)
2581 WINPR_ASSERT(settings);
2584 settings->RemoteWndSupportLevel = src->RemoteWndSupportLevel;
2585 settings->RemoteAppNumIconCaches = src->RemoteAppNumIconCaches;
2586 settings->RemoteAppNumIconCacheEntries = src->RemoteAppNumIconCacheEntries;
2596static BOOL rdp_read_window_list_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2598 WINPR_ASSERT(settings);
2599 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 7))
2602 Stream_Read_UINT32(s, settings->RemoteWndSupportLevel);
2603 Stream_Read_UINT8(s, settings->RemoteAppNumIconCaches);
2604 Stream_Read_UINT16(s,
2605 settings->RemoteAppNumIconCacheEntries);
2614static BOOL rdp_write_window_list_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
2616 WINPR_ASSERT(settings);
2617 if (!Stream_EnsureRemainingCapacity(s, 32))
2620 const size_t header = rdp_capability_set_start(log, s);
2621 Stream_Write_UINT32(s, settings->RemoteWndSupportLevel);
2623 s, WINPR_ASSERTING_INT_CAST(uint8_t,
2624 settings->RemoteAppNumIconCaches));
2625 Stream_Write_UINT16(
2627 WINPR_ASSERTING_INT_CAST(
2628 uint16_t, settings->RemoteAppNumIconCacheEntries));
2629 return rdp_capability_set_finish(s, header, CAPSET_TYPE_WINDOW);
2632#ifdef WITH_DEBUG_CAPABILITIES
2633static BOOL rdp_print_window_list_capability_set(wLog* log,
wStream* s)
2635 UINT32 wndSupportLevel = 0;
2636 BYTE numIconCaches = 0;
2637 UINT16 numIconCacheEntries = 0;
2638 WLog_Print(log, WLOG_TRACE,
2639 "WindowListCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2641 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 7))
2644 Stream_Read_UINT32(s, wndSupportLevel);
2645 Stream_Read_UINT8(s, numIconCaches);
2646 Stream_Read_UINT16(s, numIconCacheEntries);
2647 WLog_Print(log, WLOG_TRACE,
"\twndSupportLevel: 0x%08" PRIX32
"", wndSupportLevel);
2648 WLog_Print(log, WLOG_TRACE,
"\tnumIconCaches: 0x%02" PRIX8
"", numIconCaches);
2649 WLog_Print(log, WLOG_TRACE,
"\tnumIconCacheEntries: 0x%04" PRIX16
"", numIconCacheEntries);
2654static BOOL rdp_apply_desktop_composition_capability_set(rdpSettings* settings,
2655 const rdpSettings* src)
2657 WINPR_ASSERT(settings);
2660 settings->CompDeskSupportLevel = src->CompDeskSupportLevel;
2669static BOOL rdp_read_desktop_composition_capability_set(wLog* log,
wStream* s,
2670 rdpSettings* settings)
2672 WINPR_UNUSED(settings);
2673 WINPR_ASSERT(settings);
2675 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 2))
2678 Stream_Read_UINT16(s, settings->CompDeskSupportLevel);
2687static BOOL rdp_write_desktop_composition_capability_set(wLog* log,
wStream* s,
2688 const rdpSettings* settings)
2690 WINPR_ASSERT(settings);
2692 if (!Stream_EnsureRemainingCapacity(s, 32))
2695 const size_t header = rdp_capability_set_start(log, s);
2696 const UINT16 compDeskSupportLevel =
2697 (settings->AllowDesktopComposition) ? COMPDESK_SUPPORTED : COMPDESK_NOT_SUPPORTED;
2698 Stream_Write_UINT16(s, compDeskSupportLevel);
2699 return rdp_capability_set_finish(s, header, CAPSET_TYPE_COMP_DESK);
2702#ifdef WITH_DEBUG_CAPABILITIES
2703static BOOL rdp_print_desktop_composition_capability_set(wLog* log,
wStream* s)
2705 UINT16 compDeskSupportLevel = 0;
2706 WLog_Print(log, WLOG_TRACE,
"DesktopCompositionCapabilitySet (length %" PRIuz
"):",
2707 Stream_GetRemainingLength(s));
2709 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 2))
2712 Stream_Read_UINT16(s, compDeskSupportLevel);
2713 WLog_Print(log, WLOG_TRACE,
"\tcompDeskSupportLevel: 0x%04" PRIX16
"", compDeskSupportLevel);
2718static BOOL rdp_apply_multifragment_update_capability_set(rdpSettings* settings,
2719 const rdpSettings* src)
2721 UINT32 multifragMaxRequestSize = 0;
2723 WINPR_ASSERT(settings);
2726 multifragMaxRequestSize = src->MultifragMaxRequestSize;
2728 if (settings->ServerMode)
2738 if (multifragMaxRequestSize < FASTPATH_MAX_PACKET_SIZE)
2739 multifragMaxRequestSize = FASTPATH_FRAGMENT_SAFE_SIZE;
2741 if (settings->RemoteFxCodec)
2748 if (multifragMaxRequestSize < settings->MultifragMaxRequestSize)
2754 settings->RemoteFxCodec = FALSE;
2755 settings->MultifragMaxRequestSize = multifragMaxRequestSize;
2764 settings->MultifragMaxRequestSize = multifragMaxRequestSize;
2774 if (multifragMaxRequestSize > settings->MultifragMaxRequestSize)
2775 settings->MultifragMaxRequestSize = multifragMaxRequestSize;
2785static BOOL rdp_read_multifragment_update_capability_set(wLog* log,
wStream* s,
2786 rdpSettings* settings)
2788 UINT32 multifragMaxRequestSize = 0;
2790 WINPR_ASSERT(settings);
2791 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2794 Stream_Read_UINT32(s, multifragMaxRequestSize);
2795 settings->MultifragMaxRequestSize = multifragMaxRequestSize;
2805static BOOL rdp_write_multifragment_update_capability_set(wLog* log,
wStream* s,
2806 rdpSettings* settings)
2808 WINPR_ASSERT(settings);
2809 if (settings->ServerMode && settings->MultifragMaxRequestSize == 0)
2822 UINT32 tileNumX = (settings->DesktopWidth + 63) / 64;
2823 UINT32 tileNumY = (settings->DesktopHeight + 63) / 64;
2824 settings->MultifragMaxRequestSize = tileNumX * tileNumY * 16384;
2826 settings->MultifragMaxRequestSize += 16384;
2829 if (!Stream_EnsureRemainingCapacity(s, 32))
2831 const size_t header = rdp_capability_set_start(log, s);
2832 Stream_Write_UINT32(s, settings->MultifragMaxRequestSize);
2833 return rdp_capability_set_finish(s, header, CAPSET_TYPE_MULTI_FRAGMENT_UPDATE);
2836#ifdef WITH_DEBUG_CAPABILITIES
2837static BOOL rdp_print_multifragment_update_capability_set(wLog* log,
wStream* s)
2839 UINT32 maxRequestSize = 0;
2840 WLog_Print(log, WLOG_TRACE,
"MultifragmentUpdateCapabilitySet (length %" PRIuz
"):",
2841 Stream_GetRemainingLength(s));
2843 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2846 Stream_Read_UINT32(s, maxRequestSize);
2847 WLog_Print(log, WLOG_TRACE,
"\tmaxRequestSize: 0x%08" PRIX32
"", maxRequestSize);
2852static BOOL rdp_apply_large_pointer_capability_set(rdpSettings* settings,
const rdpSettings* src)
2854 WINPR_ASSERT(settings);
2857 settings->LargePointerFlag = src->LargePointerFlag;
2866static BOOL rdp_read_large_pointer_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2868 UINT16 largePointerSupportFlags = 0;
2870 WINPR_ASSERT(settings);
2871 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 2))
2874 Stream_Read_UINT16(s, largePointerSupportFlags);
2875 settings->LargePointerFlag &= largePointerSupportFlags;
2876 if ((largePointerSupportFlags & ~(LARGE_POINTER_FLAG_96x96 | LARGE_POINTER_FLAG_384x384)) != 0)
2880 "TS_LARGE_POINTER_CAPABILITYSET with unsupported flags %04X (all flags %04X) received",
2881 WINPR_CXX_COMPAT_CAST(UINT32, largePointerSupportFlags & ~(LARGE_POINTER_FLAG_96x96 |
2882 LARGE_POINTER_FLAG_384x384)),
2883 largePointerSupportFlags);
2893static BOOL rdp_write_large_pointer_capability_set(wLog* log,
wStream* s,
2894 const rdpSettings* settings)
2896 WINPR_ASSERT(settings);
2897 if (!Stream_EnsureRemainingCapacity(s, 32))
2900 const size_t header = rdp_capability_set_start(log, s);
2901 const UINT16 largePointerSupportFlags =
2902 settings->LargePointerFlag & (LARGE_POINTER_FLAG_96x96 | LARGE_POINTER_FLAG_384x384);
2903 Stream_Write_UINT16(s, largePointerSupportFlags);
2904 return rdp_capability_set_finish(s, header, CAPSET_TYPE_LARGE_POINTER);
2907#ifdef WITH_DEBUG_CAPABILITIES
2908static BOOL rdp_print_large_pointer_capability_set(wLog* log,
wStream* s)
2910 UINT16 largePointerSupportFlags = 0;
2911 WLog_Print(log, WLOG_TRACE,
2912 "LargePointerCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2914 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 2))
2917 Stream_Read_UINT16(s, largePointerSupportFlags);
2918 WLog_Print(log, WLOG_TRACE,
"\tlargePointerSupportFlags: 0x%04" PRIX16
"",
2919 largePointerSupportFlags);
2924static BOOL rdp_apply_surface_commands_capability_set(rdpSettings* settings,
const rdpSettings* src)
2926 WINPR_ASSERT(settings);
2933 if (src->FastPathOutput)
2935 settings->SurfaceCommandsSupported &= src->SurfaceCommandsSupported;
2936 settings->SurfaceCommandsEnabled = src->SurfaceCommandsEnabled;
2937 settings->SurfaceFrameMarkerEnabled = src->SurfaceFrameMarkerEnabled;
2941 settings->SurfaceCommandsSupported = 0;
2942 settings->SurfaceCommandsEnabled = FALSE;
2943 settings->SurfaceFrameMarkerEnabled = FALSE;
2954static BOOL rdp_read_surface_commands_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2956 UINT32 cmdFlags = 0;
2958 WINPR_ASSERT(settings);
2959 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
2962 Stream_Read_UINT32(s, cmdFlags);
2963 Stream_Seek_UINT32(s);
2964 settings->SurfaceCommandsSupported = cmdFlags;
2965 settings->SurfaceCommandsEnabled =
2966 (cmdFlags & (SURFCMDS_SET_SURFACE_BITS | SURFCMDS_STREAM_SURFACE_BITS)) ? TRUE : FALSE;
2967 settings->SurfaceFrameMarkerEnabled = (cmdFlags & SURFCMDS_FRAME_MARKER) ? TRUE : FALSE;
2976static BOOL rdp_write_surface_commands_capability_set(wLog* log,
wStream* s,
2977 const rdpSettings* settings)
2979 WINPR_ASSERT(settings);
2980 if (!Stream_EnsureRemainingCapacity(s, 32))
2983 const size_t header = rdp_capability_set_start(log, s);
2987 if (settings->SurfaceFrameMarkerEnabled)
2988 cmdFlags |= SURFCMDS_FRAME_MARKER;
2990 Stream_Write_UINT32(s, cmdFlags);
2991 Stream_Write_UINT32(s, 0);
2992 return rdp_capability_set_finish(s, header, CAPSET_TYPE_SURFACE_COMMANDS);
2995static bool sUuidEqual(
const UUID* Uuid1,
const UUID* Uuid2)
2997 if (!Uuid1 && !Uuid2)
3000 if (Uuid1 && !Uuid2)
3003 if (!Uuid1 && Uuid2)
3006 if (Uuid1->Data1 != Uuid2->Data1)
3009 if (Uuid1->Data2 != Uuid2->Data2)
3012 if (Uuid1->Data3 != Uuid2->Data3)
3015 for (
int index = 0; index < 8; index++)
3017 if (Uuid1->Data4[index] != Uuid2->Data4[index])
3024#ifdef WITH_DEBUG_CAPABILITIES
3025static BOOL rdp_print_surface_commands_capability_set(wLog* log,
wStream* s)
3027 UINT32 cmdFlags = 0;
3028 UINT32 reserved = 0;
3030 WLog_Print(log, WLOG_TRACE,
3031 "SurfaceCommandsCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
3033 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
3036 Stream_Read_UINT32(s, cmdFlags);
3037 Stream_Read_UINT32(s, reserved);
3038 WLog_Print(log, WLOG_TRACE,
"\tcmdFlags: 0x%08" PRIX32
"", cmdFlags);
3039 WLog_Print(log, WLOG_TRACE,
"\treserved: 0x%08" PRIX32
"", reserved);
3043static void rdp_print_bitmap_codec_guid(wLog* log,
const GUID* guid)
3046 WLog_Print(log, WLOG_TRACE,
3047 "%08" PRIX32
"%04" PRIX16
"%04" PRIX16
"%02" PRIX8
"%02" PRIX8
"%02" PRIX8
3048 "%02" PRIX8
"%02" PRIX8
"%02" PRIX8
"%02" PRIX8
"%02" PRIX8
"",
3049 guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], guid->Data4[1],
3050 guid->Data4[2], guid->Data4[3], guid->Data4[4], guid->Data4[5], guid->Data4[6],
3054static char* rdp_get_bitmap_codec_guid_name(
const GUID* guid)
3057 if (sUuidEqual(guid, &CODEC_GUID_REMOTEFX))
3058 return "CODEC_GUID_REMOTEFX";
3059 else if (sUuidEqual(guid, &CODEC_GUID_NSCODEC))
3060 return "CODEC_GUID_NSCODEC";
3061 else if (sUuidEqual(guid, &CODEC_GUID_IGNORE))
3062 return "CODEC_GUID_IGNORE";
3063 else if (sUuidEqual(guid, &CODEC_GUID_IMAGE_REMOTEFX))
3064 return "CODEC_GUID_IMAGE_REMOTEFX";
3066#if defined(WITH_JPEG)
3067 else if (sUuidEqual(guid, &CODEC_GUID_JPEG))
3068 return "CODEC_GUID_JPEG";
3071 return "CODEC_GUID_UNKNOWN";
3075static BOOL rdp_read_bitmap_codec_guid(wLog* log,
wStream* s, GUID* guid)
3080 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 16))
3082 Stream_Read(s, g, 16);
3083 guid->Data1 = ((UINT32)g[3] << 24U) | ((UINT32)g[2] << 16U) | (UINT32)(g[1] << 8U) | g[0];
3084 guid->Data2 = ((g[5] << 8U) | g[4]) & 0xFFFF;
3085 guid->Data3 = ((g[7] << 8U) | g[6]) & 0xFFFF;
3086 guid->Data4[0] = g[8];
3087 guid->Data4[1] = g[9];
3088 guid->Data4[2] = g[10];
3089 guid->Data4[3] = g[11];
3090 guid->Data4[4] = g[12];
3091 guid->Data4[5] = g[13];
3092 guid->Data4[6] = g[14];
3093 guid->Data4[7] = g[15];
3097static void rdp_write_bitmap_codec_guid(
wStream* s,
const GUID* guid)
3101 g[0] = guid->Data1 & 0xFF;
3102 g[1] = (guid->Data1 >> 8) & 0xFF;
3103 g[2] = (guid->Data1 >> 16) & 0xFF;
3104 g[3] = (guid->Data1 >> 24) & 0xFF;
3105 g[4] = (guid->Data2) & 0xFF;
3106 g[5] = (guid->Data2 >> 8) & 0xFF;
3107 g[6] = (guid->Data3) & 0xFF;
3108 g[7] = (guid->Data3 >> 8) & 0xFF;
3109 g[8] = guid->Data4[0];
3110 g[9] = guid->Data4[1];
3111 g[10] = guid->Data4[2];
3112 g[11] = guid->Data4[3];
3113 g[12] = guid->Data4[4];
3114 g[13] = guid->Data4[5];
3115 g[14] = guid->Data4[6];
3116 g[15] = guid->Data4[7];
3117 Stream_Write(s, g, 16);
3120static BOOL rdp_apply_bitmap_codecs_capability_set(rdpSettings* settings,
const rdpSettings* src)
3122 WINPR_ASSERT(settings);
3125 if (settings->ServerMode)
3128 settings->RemoteFxCodecId = src->RemoteFxCodecId;
3129 settings->RemoteFxCaptureFlags = src->RemoteFxCaptureFlags;
3130 settings->RemoteFxOnly = src->RemoteFxOnly;
3131 settings->RemoteFxRlgrMode = src->RemoteFxRlgrMode;
3132 settings->RemoteFxCodecMode = src->RemoteFxCodecMode;
3133 settings->NSCodecId = src->NSCodecId;
3134 settings->NSCodecAllowDynamicColorFidelity = src->NSCodecAllowDynamicColorFidelity;
3135 settings->NSCodecAllowSubsampling = src->NSCodecAllowSubsampling;
3136 settings->NSCodecColorLossLevel = src->NSCodecColorLossLevel;
3139 settings->RemoteFxCodec = settings->RemoteFxCodec && src->RemoteFxCodecId;
3140 settings->RemoteFxImageCodec = settings->RemoteFxImageCodec && src->RemoteFxImageCodec;
3142 settings->NSCodec && src->NSCodec))
3144 settings->JpegCodec = src->JpegCodec;
3149static BOOL rdp_read_codec_ts_rfx_icap(wLog* log,
wStream* sub, rdpSettings* settings,
3153 UINT16 tileSize = 0;
3154 BYTE codecFlags = 0;
3155 BYTE colConvBits = 0;
3156 BYTE transformBits = 0;
3157 BYTE entropyBits = 0;
3161 WLog_Print(log, WLOG_ERROR,
3162 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP size %" PRIu16
3163 " unsupported, expecting size %" PRIu16
" not supported",
3168 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 8))
3171 Stream_Read_UINT16(sub, version);
3172 Stream_Read_UINT16(sub, tileSize);
3173 Stream_Read_UINT8(sub, codecFlags);
3174 Stream_Read_UINT8(sub, colConvBits);
3175 Stream_Read_UINT8(sub, transformBits);
3176 Stream_Read_UINT8(sub, entropyBits);
3178 if (version == 0x0009)
3181 if (tileSize != 0x0080)
3183 WLog_Print(log, WLOG_ERROR,
3184 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::version %" PRIu16
3185 " tile size %" PRIu16
" not supported",
3190 else if (version == 0x0100)
3193 if (tileSize != 0x0040)
3195 WLog_Print(log, WLOG_ERROR,
3196 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::version %" PRIu16
3197 " tile size %" PRIu16
" not supported",
3204 WLog_Print(log, WLOG_ERROR,
3205 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::version %" PRIu16
" not supported",
3211 if (colConvBits != 1)
3213 WLog_Print(log, WLOG_ERROR,
3214 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::colConvBits %" PRIu8
3215 " not supported, must be CLW_COL_CONV_ICT (0x1)",
3221 if (transformBits != 1)
3223 WLog_Print(log, WLOG_ERROR,
3224 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::transformBits %" PRIu8
3225 " not supported, must be CLW_XFORM_DWT_53_A (0x1)",
3230 const UINT8 CODEC_MODE = 0x02;
3234 if ((codecFlags & CODEC_MODE) != 0)
3239 else if ((codecFlags & ~CODEC_MODE) != 0)
3240 WLog_Print(log, WLOG_WARN,
3241 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::flags unknown value "
3243 WINPR_CXX_COMPAT_CAST(UINT32, (codecFlags & ~CODEC_MODE)));
3245 switch (entropyBits)
3247 case CLW_ENTROPY_RLGR1:
3251 case CLW_ENTROPY_RLGR3:
3256 WLog_Print(log, WLOG_ERROR,
3257 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::entropyBits "
3258 "unsupported value 0x%02" PRIx8
3259 ", must be CLW_ENTROPY_RLGR1 (0x01) or CLW_ENTROPY_RLGR3 "
3267static BOOL rdp_read_codec_ts_rfx_capset(wLog* log,
wStream* s, rdpSettings* settings)
3269 UINT16 blockType = 0;
3270 UINT32 blockLen = 0;
3271 BYTE rfxCodecId = 0;
3272 UINT16 capsetType = 0;
3273 UINT16 numIcaps = 0;
3276 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 6))
3280 Stream_Read_UINT16(s, blockType);
3281 Stream_Read_UINT32(s, blockLen);
3282 if (blockType != 0xCBC1)
3284 WLog_Print(log, WLOG_ERROR,
3285 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::blockType[0x%04" PRIx16
3286 "] != CBY_CAPSET (0xCBC1)",
3290 if (blockLen < 6ull)
3292 WLog_Print(log, WLOG_ERROR,
3293 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::blockLen[%" PRIu16
"] < 6", blockLen);
3296 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, blockLen - 6ull))
3300 wStream* sub = Stream_StaticConstInit(&sbuffer, Stream_Pointer(s), blockLen - 6ull);
3303 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 7))
3306 Stream_Read_UINT8(sub, rfxCodecId);
3307 Stream_Read_UINT16(sub, capsetType);
3308 Stream_Read_UINT16(sub, numIcaps);
3309 Stream_Read_UINT16(sub, icapLen);
3311 if (rfxCodecId != 1)
3313 WLog_Print(log, WLOG_ERROR,
3314 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::codecId[%" PRIu16
"] != 1", rfxCodecId);
3318 if (capsetType != 0xCFC0)
3320 WLog_Print(log, WLOG_ERROR,
3321 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::capsetType[0x%04" PRIx16
3322 "] != CLY_CAPSET (0xCFC0)",
3329 if (!rdp_read_codec_ts_rfx_icap(log, sub, settings, icapLen))
3335static BOOL rdp_read_codec_ts_rfx_caps(wLog* log,
wStream* sub, rdpSettings* settings)
3337 if (Stream_GetRemainingLength(sub) == 0)
3340 UINT16 blockType = 0;
3341 UINT32 blockLen = 0;
3342 UINT16 numCapsets = 0;
3345 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 8))
3347 Stream_Read_UINT16(sub, blockType);
3348 Stream_Read_UINT32(sub, blockLen);
3349 Stream_Read_UINT16(sub, numCapsets);
3351 if (blockType != 0xCBC0)
3353 WLog_Print(log, WLOG_ERROR,
3354 "[MS_RDPRFX] 2.2.1.1.1 TS_RFX_CAPS::blockType[0x%04" PRIx16
3355 "] != CBY_CAPS (0xCBC0)",
3362 WLog_Print(log, WLOG_ERROR,
"[MS_RDPRFX] 2.2.1.1.1 TS_RFX_CAPS::blockLen[%" PRIu16
"] != 8",
3367 if (numCapsets != 1)
3369 WLog_Print(log, WLOG_ERROR,
3370 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::numIcaps[%" PRIu16
"] != 1", numCapsets);
3374 for (UINT16 x = 0; x < numCapsets; x++)
3376 if (!rdp_read_codec_ts_rfx_capset(log, sub, settings))
3383static BOOL rdp_read_codec_ts_rfx_clnt_caps_container(wLog* log,
wStream* s, rdpSettings* settings)
3385 UINT32 rfxCapsLength = 0;
3386 UINT32 rfxPropsLength = 0;
3387 UINT32 captureFlags = 0;
3390 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
3392 Stream_Read_UINT32(s, rfxPropsLength);
3393 if (rfxPropsLength < 4)
3395 WLog_Print(log, WLOG_ERROR,
3396 "[MS_RDPRFX] 2.2.1.1 TS_RFX_CLNT_CAPS_CONTAINER::length %" PRIu32
3397 " too short, require at least 4 bytes",
3401 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, rfxPropsLength - 4ull))
3405 wStream* sub = Stream_StaticConstInit(&sbuffer, Stream_Pointer(s), rfxPropsLength - 4ull);
3408 Stream_Seek(s, rfxPropsLength - 4ull);
3410 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 8))
3413 Stream_Read_UINT32(sub, captureFlags);
3414 Stream_Read_UINT32(sub, rfxCapsLength);
3415 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, rfxCapsLength))
3418 settings->RemoteFxCaptureFlags = captureFlags;
3419 settings->RemoteFxOnly = (captureFlags & CARDP_CAPS_CAPTURE_NON_CAC) ? FALSE : TRUE;
3423 wStream* ts_sub = Stream_StaticConstInit(&tsbuffer, Stream_Pointer(sub), rfxCapsLength);
3424 WINPR_ASSERT(ts_sub);
3425 return rdp_read_codec_ts_rfx_caps(log, ts_sub, settings);
3433static BOOL rdp_read_bitmap_codecs_capability_set(wLog* log,
wStream* s, rdpSettings* settings,
3437 GUID codecGuid = { 0 };
3438 BYTE bitmapCodecCount = 0;
3439 UINT16 codecPropertiesLength = 0;
3441 BOOL guidNSCodec = FALSE;
3442 BOOL guidRemoteFx = FALSE;
3443 BOOL guidRemoteFxImage = FALSE;
3445 WINPR_ASSERT(settings);
3446 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 1))
3449 Stream_Read_UINT8(s, bitmapCodecCount);
3451 while (bitmapCodecCount > 0)
3455 if (!rdp_read_bitmap_codec_guid(log, s, &codecGuid))
3457 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 3))
3459 Stream_Read_UINT8(s, codecId);
3460 Stream_Read_UINT16(s, codecPropertiesLength);
3462 wStream* sub = Stream_StaticInit(&subbuffer, Stream_Pointer(s), codecPropertiesLength);
3463 if (!Stream_SafeSeek(s, codecPropertiesLength))
3468 if (sUuidEqual(&codecGuid, &CODEC_GUID_REMOTEFX))
3470 guidRemoteFx = TRUE;
3471 settings->RemoteFxCodecId = codecId;
3472 if (!rdp_read_codec_ts_rfx_clnt_caps_container(log, sub, settings))
3475 else if (sUuidEqual(&codecGuid, &CODEC_GUID_IMAGE_REMOTEFX))
3478 guidRemoteFxImage = TRUE;
3479 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3482 else if (sUuidEqual(&codecGuid, &CODEC_GUID_NSCODEC))
3484 BYTE colorLossLevel = 0;
3485 BYTE fAllowSubsampling = 0;
3486 BYTE fAllowDynamicFidelity = 0;
3488 settings->NSCodecId = codecId;
3489 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 3))
3491 Stream_Read_UINT8(sub, fAllowDynamicFidelity);
3492 Stream_Read_UINT8(sub, fAllowSubsampling);
3493 Stream_Read_UINT8(sub, colorLossLevel);
3495 if (colorLossLevel < 1)
3498 if (colorLossLevel > 7)
3501 settings->NSCodecAllowDynamicColorFidelity = fAllowDynamicFidelity;
3502 settings->NSCodecAllowSubsampling = fAllowSubsampling;
3503 settings->NSCodecColorLossLevel = colorLossLevel;
3505 else if (sUuidEqual(&codecGuid, &CODEC_GUID_IGNORE))
3507 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3512 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3518 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3522 const size_t rest = Stream_GetRemainingLength(sub);
3525 WLog_Print(log, WLOG_ERROR,
3526 "error while reading codec properties: actual size: %" PRIuz
3527 " expected size: %" PRIu32
"",
3528 rest + codecPropertiesLength, codecPropertiesLength);
3549static BOOL rdp_write_rfx_client_capability_container(
wStream* s,
const rdpSettings* settings)
3551 WINPR_ASSERT(settings);
3552 if (!Stream_EnsureRemainingCapacity(s, 64))
3555 const UINT32 captureFlags = settings->RemoteFxOnly ? 0 : CARDP_CAPS_CAPTURE_NON_CAC;
3557 WINPR_ASSERT(settings->RemoteFxCodecMode <= UINT8_MAX);
3558 const UINT8 codecMode = (UINT8)settings->RemoteFxCodecMode;
3559 Stream_Write_UINT16(s, 49);
3561 Stream_Write_UINT32(s, 49);
3562 Stream_Write_UINT32(s, captureFlags);
3563 Stream_Write_UINT32(s, 37);
3565 Stream_Write_UINT16(s, CBY_CAPS);
3566 Stream_Write_UINT32(s, 8);
3567 Stream_Write_UINT16(s, 1);
3569 Stream_Write_UINT16(s, CBY_CAPSET);
3570 Stream_Write_UINT32(s, 29);
3571 Stream_Write_UINT8(s, 0x01);
3572 Stream_Write_UINT16(s, CLY_CAPSET);
3573 Stream_Write_UINT16(s, 2);
3574 Stream_Write_UINT16(s, 8);
3576 Stream_Write_UINT16(s, CLW_VERSION_1_0);
3577 Stream_Write_UINT16(s, CT_TILE_64x64);
3578 Stream_Write_UINT8(s, codecMode);
3579 Stream_Write_UINT8(s, CLW_COL_CONV_ICT);
3580 Stream_Write_UINT8(s, CLW_XFORM_DWT_53_A);
3581 Stream_Write_UINT8(s, CLW_ENTROPY_RLGR1);
3583 Stream_Write_UINT16(s, CLW_VERSION_1_0);
3584 Stream_Write_UINT16(s, CT_TILE_64x64);
3585 Stream_Write_UINT8(s, codecMode);
3586 Stream_Write_UINT8(s, CLW_COL_CONV_ICT);
3587 Stream_Write_UINT8(s, CLW_XFORM_DWT_53_A);
3588 Stream_Write_UINT8(s, CLW_ENTROPY_RLGR3);
3595static BOOL rdp_write_nsc_client_capability_container(
wStream* s,
const rdpSettings* settings)
3597 WINPR_ASSERT(settings);
3599 const BOOL fAllowDynamicFidelity = settings->NSCodecAllowDynamicColorFidelity;
3600 const BOOL fAllowSubsampling = settings->NSCodecAllowSubsampling;
3601 UINT32 colorLossLevel = settings->NSCodecColorLossLevel;
3603 if (colorLossLevel < 1)
3606 if (colorLossLevel > 7)
3609 if (!Stream_EnsureRemainingCapacity(s, 8))
3612 Stream_Write_UINT16(s, 3);
3614 Stream_Write_UINT8(s,
3615 fAllowDynamicFidelity ? TRUE : FALSE);
3616 Stream_Write_UINT8(s, fAllowSubsampling ? TRUE : FALSE);
3617 Stream_Write_UINT8(s, (UINT8)colorLossLevel);
3621#if defined(WITH_JPEG)
3622static BOOL rdp_write_jpeg_client_capability_container(
wStream* s,
const rdpSettings* settings)
3624 WINPR_ASSERT(settings);
3625 if (!Stream_EnsureRemainingCapacity(s, 8))
3628 Stream_Write_UINT16(s, 1);
3629 Stream_Write_UINT8(s, settings->JpegQuality);
3637static BOOL rdp_write_rfx_server_capability_container(
wStream* s,
const rdpSettings* settings)
3639 WINPR_UNUSED(settings);
3640 WINPR_ASSERT(settings);
3642 if (!Stream_EnsureRemainingCapacity(s, 8))
3645 Stream_Write_UINT16(s, 4);
3646 Stream_Write_UINT32(s, 0);
3650#if defined(WITH_JPEG)
3651static BOOL rdp_write_jpeg_server_capability_container(
wStream* s,
const rdpSettings* settings)
3653 WINPR_UNUSED(settings);
3654 WINPR_ASSERT(settings);
3656 if (!Stream_EnsureRemainingCapacity(s, 8))
3659 Stream_Write_UINT16(s, 1);
3660 Stream_Write_UINT8(s, 75);
3668static BOOL rdp_write_nsc_server_capability_container(
wStream* s,
const rdpSettings* settings)
3670 WINPR_UNUSED(settings);
3671 WINPR_ASSERT(settings);
3673 if (!Stream_EnsureRemainingCapacity(s, 8))
3676 Stream_Write_UINT16(s, 4);
3677 Stream_Write_UINT32(s, 0);
3686static BOOL rdp_write_bitmap_codecs_capability_set(wLog* log,
wStream* s,
3687 const rdpSettings* settings)
3689 WINPR_ASSERT(settings);
3690 if (!Stream_EnsureRemainingCapacity(s, 64))
3693 const size_t header = rdp_capability_set_start(log, s);
3694 BYTE bitmapCodecCount = 0;
3696 if (settings->RemoteFxCodec)
3702#if defined(WITH_JPEG)
3704 if (settings->JpegCodec)
3709 if (settings->RemoteFxImageCodec)
3712 Stream_Write_UINT8(s, bitmapCodecCount);
3714 if (settings->RemoteFxCodec)
3716 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_REMOTEFX);
3718 if (settings->ServerMode)
3720 Stream_Write_UINT8(s, 0);
3722 if (!rdp_write_rfx_server_capability_container(s, settings))
3727 Stream_Write_UINT8(s, RDP_CODEC_ID_REMOTEFX);
3729 if (!rdp_write_rfx_client_capability_container(s, settings))
3736 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_NSCODEC);
3738 if (settings->ServerMode)
3740 Stream_Write_UINT8(s, 0);
3742 if (!rdp_write_nsc_server_capability_container(s, settings))
3747 Stream_Write_UINT8(s, RDP_CODEC_ID_NSCODEC);
3749 if (!rdp_write_nsc_client_capability_container(s, settings))
3754#if defined(WITH_JPEG)
3756 if (settings->JpegCodec)
3758 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_JPEG);
3760 if (settings->ServerMode)
3762 Stream_Write_UINT8(s, 0);
3764 if (!rdp_write_jpeg_server_capability_container(s, settings))
3769 Stream_Write_UINT8(s, RDP_CODEC_ID_JPEG);
3771 if (!rdp_write_jpeg_client_capability_container(s, settings))
3778 if (settings->RemoteFxImageCodec)
3780 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_IMAGE_REMOTEFX);
3782 if (settings->ServerMode)
3784 Stream_Write_UINT8(s, 0);
3786 if (!rdp_write_rfx_server_capability_container(s, settings))
3791 Stream_Write_UINT8(s, RDP_CODEC_ID_IMAGE_REMOTEFX);
3793 if (!rdp_write_rfx_client_capability_container(s, settings))
3798 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CODECS);
3801#ifdef WITH_DEBUG_CAPABILITIES
3802static BOOL rdp_print_bitmap_codecs_capability_set(wLog* log,
wStream* s)
3804 GUID codecGuid = { 0 };
3805 BYTE bitmapCodecCount = 0;
3807 UINT16 codecPropertiesLength = 0;
3809 WLog_Print(log, WLOG_TRACE,
3810 "BitmapCodecsCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
3812 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 1))
3815 Stream_Read_UINT8(s, bitmapCodecCount);
3816 WLog_Print(log, WLOG_TRACE,
"\tbitmapCodecCount: %" PRIu8
"", bitmapCodecCount);
3818 while (bitmapCodecCount > 0)
3820 if (!rdp_read_bitmap_codec_guid(log, s, &codecGuid))
3822 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 3))
3824 Stream_Read_UINT8(s, codecId);
3825 WLog_Print(log, WLOG_TRACE,
"\tcodecGuid: 0x");
3826 rdp_print_bitmap_codec_guid(log, &codecGuid);
3827 WLog_Print(log, WLOG_TRACE,
" (%s)", rdp_get_bitmap_codec_guid_name(&codecGuid));
3828 WLog_Print(log, WLOG_TRACE,
"\tcodecId: %" PRIu8
"", codecId);
3829 Stream_Read_UINT16(s, codecPropertiesLength);
3830 WLog_Print(log, WLOG_TRACE,
"\tcodecPropertiesLength: %" PRIu16
"", codecPropertiesLength);
3832 if (!Stream_SafeSeek(s, codecPropertiesLength))
3841static BOOL rdp_apply_frame_acknowledge_capability_set(rdpSettings* settings,
3842 const rdpSettings* src)
3844 WINPR_ASSERT(settings);
3847 if (settings->ServerMode)
3848 settings->FrameAcknowledge = src->FrameAcknowledge;
3857static BOOL rdp_read_frame_acknowledge_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
3859 WINPR_ASSERT(settings);
3860 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
3863 Stream_Read_UINT32(s, settings->FrameAcknowledge);
3872static BOOL rdp_write_frame_acknowledge_capability_set(wLog* log,
wStream* s,
3873 const rdpSettings* settings)
3875 WINPR_ASSERT(settings);
3876 if (!Stream_EnsureRemainingCapacity(s, 32))
3879 const size_t header = rdp_capability_set_start(log, s);
3880 Stream_Write_UINT32(s, settings->FrameAcknowledge);
3881 return rdp_capability_set_finish(s, header, CAPSET_TYPE_FRAME_ACKNOWLEDGE);
3884#ifdef WITH_DEBUG_CAPABILITIES
3885static BOOL rdp_print_frame_acknowledge_capability_set(wLog* log,
wStream* s)
3887 UINT32 frameAcknowledge = 0;
3888 WLog_Print(log, WLOG_TRACE,
3889 "FrameAcknowledgeCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
3891 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
3894 Stream_Read_UINT32(s, frameAcknowledge);
3895 WLog_Print(log, WLOG_TRACE,
"\tframeAcknowledge: 0x%08" PRIX32
"", frameAcknowledge);
3900static BOOL rdp_apply_bitmap_cache_v3_codec_id_capability_set(rdpSettings* settings,
3901 const rdpSettings* src)
3903 WINPR_ASSERT(settings);
3906 settings->BitmapCacheV3CodecId = src->BitmapCacheV3CodecId;
3910static BOOL rdp_read_bitmap_cache_v3_codec_id_capability_set(wLog* log,
wStream* s,
3911 rdpSettings* settings)
3913 BYTE bitmapCacheV3CodecId = 0;
3915 WINPR_ASSERT(settings);
3916 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 1))
3919 Stream_Read_UINT8(s, bitmapCacheV3CodecId);
3920 settings->BitmapCacheV3CodecId = bitmapCacheV3CodecId;
3924static BOOL rdp_write_bitmap_cache_v3_codec_id_capability_set(wLog* log,
wStream* s,
3925 const rdpSettings* settings)
3927 WINPR_ASSERT(settings);
3928 if (!Stream_EnsureRemainingCapacity(s, 32))
3931 const size_t header = rdp_capability_set_start(log, s);
3932 if (settings->BitmapCacheV3CodecId > UINT8_MAX)
3934 Stream_Write_UINT8(s, (UINT8)settings->BitmapCacheV3CodecId);
3935 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID);
3938#ifdef WITH_DEBUG_CAPABILITIES
3939static BOOL rdp_print_bitmap_cache_v3_codec_id_capability_set(wLog* log,
wStream* s)
3941 BYTE bitmapCacheV3CodecId = 0;
3942 WLog_Print(log, WLOG_TRACE,
"BitmapCacheV3CodecIdCapabilitySet (length %" PRIuz
"):",
3943 Stream_GetRemainingLength(s));
3945 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 1))
3948 Stream_Read_UINT8(s, bitmapCacheV3CodecId);
3949 WLog_Print(log, WLOG_TRACE,
"\tbitmapCacheV3CodecId: 0x%02" PRIX8
"", bitmapCacheV3CodecId);
3953BOOL rdp_print_capability_sets(wLog* log,
wStream* s,
size_t start, BOOL receiving)
3958 UINT16 numberCapabilities = 0;
3960 size_t pos = Stream_GetPosition(s);
3962 Stream_SetPosition(s, start);
3965 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
3970 if (!Stream_CheckAndLogRequiredCapacityWLog(log, (s), 4))
3974 Stream_Read_UINT16(s, numberCapabilities);
3977 while (numberCapabilities > 0)
3983 if (!rdp_read_capability_set_header(log, s, &length, &type))
3986 WLog_Print(log, WLOG_TRACE,
"%s ", receiving ?
"Receiving" :
"Sending");
3987 sub = Stream_StaticInit(&subBuffer, Stream_Pointer(s), length - 4);
3988 if (!Stream_SafeSeek(s, length - 4))
3993 case CAPSET_TYPE_GENERAL:
3994 if (!rdp_print_general_capability_set(log, sub))
3999 case CAPSET_TYPE_BITMAP:
4000 if (!rdp_print_bitmap_capability_set(log, sub))
4005 case CAPSET_TYPE_ORDER:
4006 if (!rdp_print_order_capability_set(log, sub))
4011 case CAPSET_TYPE_BITMAP_CACHE:
4012 if (!rdp_print_bitmap_cache_capability_set(log, sub))
4017 case CAPSET_TYPE_CONTROL:
4018 if (!rdp_print_control_capability_set(log, sub))
4023 case CAPSET_TYPE_ACTIVATION:
4024 if (!rdp_print_window_activation_capability_set(log, sub))
4029 case CAPSET_TYPE_POINTER:
4030 if (!rdp_print_pointer_capability_set(log, sub))
4035 case CAPSET_TYPE_SHARE:
4036 if (!rdp_print_share_capability_set(log, sub))
4041 case CAPSET_TYPE_COLOR_CACHE:
4042 if (!rdp_print_color_cache_capability_set(log, sub))
4047 case CAPSET_TYPE_SOUND:
4048 if (!rdp_print_sound_capability_set(log, sub))
4053 case CAPSET_TYPE_INPUT:
4054 if (!rdp_print_input_capability_set(log, sub))
4059 case CAPSET_TYPE_FONT:
4060 if (!rdp_print_font_capability_set(log, sub))
4065 case CAPSET_TYPE_BRUSH:
4066 if (!rdp_print_brush_capability_set(log, sub))
4071 case CAPSET_TYPE_GLYPH_CACHE:
4072 if (!rdp_print_glyph_cache_capability_set(log, sub))
4077 case CAPSET_TYPE_OFFSCREEN_CACHE:
4078 if (!rdp_print_offscreen_bitmap_cache_capability_set(log, sub))
4083 case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
4084 if (!rdp_print_bitmap_cache_host_support_capability_set(log, sub))
4089 case CAPSET_TYPE_BITMAP_CACHE_V2:
4090 if (!rdp_print_bitmap_cache_v2_capability_set(log, sub))
4095 case CAPSET_TYPE_VIRTUAL_CHANNEL:
4096 if (!rdp_print_virtual_channel_capability_set(log, sub))
4101 case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
4102 if (!rdp_print_draw_nine_grid_cache_capability_set(log, sub))
4107 case CAPSET_TYPE_DRAW_GDI_PLUS:
4108 if (!rdp_print_draw_gdiplus_cache_capability_set(log, sub))
4113 case CAPSET_TYPE_RAIL:
4114 if (!rdp_print_remote_programs_capability_set(log, sub))
4119 case CAPSET_TYPE_WINDOW:
4120 if (!rdp_print_window_list_capability_set(log, sub))
4125 case CAPSET_TYPE_COMP_DESK:
4126 if (!rdp_print_desktop_composition_capability_set(log, sub))
4131 case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
4132 if (!rdp_print_multifragment_update_capability_set(log, sub))
4137 case CAPSET_TYPE_LARGE_POINTER:
4138 if (!rdp_print_large_pointer_capability_set(log, sub))
4143 case CAPSET_TYPE_SURFACE_COMMANDS:
4144 if (!rdp_print_surface_commands_capability_set(log, sub))
4149 case CAPSET_TYPE_BITMAP_CODECS:
4150 if (!rdp_print_bitmap_codecs_capability_set(log, sub))
4155 case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
4156 if (!rdp_print_frame_acknowledge_capability_set(log, sub))
4161 case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID:
4162 if (!rdp_print_bitmap_cache_v3_codec_id_capability_set(log, sub))
4168 WLog_Print(log, WLOG_ERROR,
"unknown capability type %" PRIu16
"", type);
4172 rest = Stream_GetRemainingLength(sub);
4175 WLog_Print(log, WLOG_WARN,
4176 "incorrect capability offset, type:0x%04" PRIX16
" %" PRIu16
4177 " bytes expected, %" PRIuz
"bytes remaining",
4178 type, length, rest);
4181 numberCapabilities--;
4186 Stream_SetPosition(s, pos);
4191static BOOL rdp_apply_from_received(UINT16 type, rdpSettings* dst,
const rdpSettings* src)
4195 case CAPSET_TYPE_GENERAL:
4196 return rdp_apply_general_capability_set(dst, src);
4197 case CAPSET_TYPE_BITMAP:
4198 return rdp_apply_bitmap_capability_set(dst, src);
4199 case CAPSET_TYPE_ORDER:
4200 return rdp_apply_order_capability_set(dst, src);
4201 case CAPSET_TYPE_POINTER:
4202 return rdp_apply_pointer_capability_set(dst, src);
4203 case CAPSET_TYPE_INPUT:
4204 return rdp_apply_input_capability_set(dst, src);
4205 case CAPSET_TYPE_VIRTUAL_CHANNEL:
4206 return rdp_apply_virtual_channel_capability_set(dst, src);
4207 case CAPSET_TYPE_SHARE:
4208 return rdp_apply_share_capability_set(dst, src);
4209 case CAPSET_TYPE_COLOR_CACHE:
4210 return rdp_apply_color_cache_capability_set(dst, src);
4211 case CAPSET_TYPE_FONT:
4212 return rdp_apply_font_capability_set(dst, src);
4213 case CAPSET_TYPE_DRAW_GDI_PLUS:
4214 return rdp_apply_draw_gdiplus_cache_capability_set(dst, src);
4215 case CAPSET_TYPE_RAIL:
4216 return rdp_apply_remote_programs_capability_set(dst, src);
4217 case CAPSET_TYPE_WINDOW:
4218 return rdp_apply_window_list_capability_set(dst, src);
4219 case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
4220 return rdp_apply_multifragment_update_capability_set(dst, src);
4221 case CAPSET_TYPE_LARGE_POINTER:
4222 return rdp_apply_large_pointer_capability_set(dst, src);
4223 case CAPSET_TYPE_COMP_DESK:
4224 return rdp_apply_desktop_composition_capability_set(dst, src);
4225 case CAPSET_TYPE_SURFACE_COMMANDS:
4226 return rdp_apply_surface_commands_capability_set(dst, src);
4227 case CAPSET_TYPE_BITMAP_CODECS:
4228 return rdp_apply_bitmap_codecs_capability_set(dst, src);
4229 case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
4230 return rdp_apply_frame_acknowledge_capability_set(dst, src);
4231 case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID:
4232 return rdp_apply_bitmap_cache_v3_codec_id_capability_set(dst, src);
4233 case CAPSET_TYPE_BITMAP_CACHE:
4234 return rdp_apply_bitmap_cache_capability_set(dst, src);
4235 case CAPSET_TYPE_BITMAP_CACHE_V2:
4236 return rdp_apply_bitmap_cache_v2_capability_set(dst, src);
4237 case CAPSET_TYPE_BRUSH:
4238 return rdp_apply_brush_capability_set(dst, src);
4239 case CAPSET_TYPE_GLYPH_CACHE:
4240 return rdp_apply_glyph_cache_capability_set(dst, src);
4241 case CAPSET_TYPE_OFFSCREEN_CACHE:
4242 return rdp_apply_offscreen_bitmap_cache_capability_set(dst, src);
4243 case CAPSET_TYPE_SOUND:
4244 return rdp_apply_sound_capability_set(dst, src);
4245 case CAPSET_TYPE_CONTROL:
4246 return rdp_apply_control_capability_set(dst, src);
4247 case CAPSET_TYPE_ACTIVATION:
4248 return rdp_apply_window_activation_capability_set(dst, src);
4249 case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
4250 return rdp_apply_draw_nine_grid_cache_capability_set(dst, src);
4251 case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
4252 return rdp_apply_bitmap_cache_host_support_capability_set(dst, src);
4258BOOL rdp_read_capability_set(wLog* log,
wStream* sub, UINT16 type, rdpSettings* settings,
4261 WINPR_ASSERT(settings);
4263 if (type <= CAPSET_TYPE_FRAME_ACKNOWLEDGE)
4265 const size_t size = Stream_Length(sub);
4266 if (size > UINT32_MAX)
4269 WINPR_ASSERT(settings->ReceivedCapabilities);
4270 settings->ReceivedCapabilities[type] = TRUE;
4272 WINPR_ASSERT(settings->ReceivedCapabilityDataSizes);
4273 settings->ReceivedCapabilityDataSizes[type] = (UINT32)size;
4275 WINPR_ASSERT(settings->ReceivedCapabilityData);
4276 void* tmp = realloc(settings->ReceivedCapabilityData[type], size);
4277 if (!tmp && (size > 0))
4279 memcpy(tmp, Stream_Buffer(sub), size);
4280 settings->ReceivedCapabilityData[type] = tmp;
4283 WLog_Print(log, WLOG_WARN,
"not handling capability type %" PRIu16
" yet", type);
4285 BOOL treated = TRUE;
4289 case CAPSET_TYPE_GENERAL:
4290 if (!rdp_read_general_capability_set(log, sub, settings))
4295 case CAPSET_TYPE_BITMAP:
4296 if (!rdp_read_bitmap_capability_set(log, sub, settings))
4301 case CAPSET_TYPE_ORDER:
4302 if (!rdp_read_order_capability_set(log, sub, settings))
4307 case CAPSET_TYPE_POINTER:
4308 if (!rdp_read_pointer_capability_set(log, sub, settings))
4313 case CAPSET_TYPE_INPUT:
4314 if (!rdp_read_input_capability_set(log, sub, settings))
4319 case CAPSET_TYPE_VIRTUAL_CHANNEL:
4320 if (!rdp_read_virtual_channel_capability_set(log, sub, settings))
4325 case CAPSET_TYPE_SHARE:
4326 if (!rdp_read_share_capability_set(log, sub, settings))
4331 case CAPSET_TYPE_COLOR_CACHE:
4332 if (!rdp_read_color_cache_capability_set(log, sub, settings))
4337 case CAPSET_TYPE_FONT:
4338 if (!rdp_read_font_capability_set(log, sub, settings))
4343 case CAPSET_TYPE_DRAW_GDI_PLUS:
4344 if (!rdp_read_draw_gdiplus_cache_capability_set(log, sub, settings))
4349 case CAPSET_TYPE_RAIL:
4350 if (!rdp_read_remote_programs_capability_set(log, sub, settings))
4355 case CAPSET_TYPE_WINDOW:
4356 if (!rdp_read_window_list_capability_set(log, sub, settings))
4361 case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
4362 if (!rdp_read_multifragment_update_capability_set(log, sub, settings))
4367 case CAPSET_TYPE_LARGE_POINTER:
4368 if (!rdp_read_large_pointer_capability_set(log, sub, settings))
4373 case CAPSET_TYPE_COMP_DESK:
4374 if (!rdp_read_desktop_composition_capability_set(log, sub, settings))
4379 case CAPSET_TYPE_SURFACE_COMMANDS:
4380 if (!rdp_read_surface_commands_capability_set(log, sub, settings))
4385 case CAPSET_TYPE_BITMAP_CODECS:
4386 if (!rdp_read_bitmap_codecs_capability_set(log, sub, settings, isServer))
4391 case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
4392 if (!rdp_read_frame_acknowledge_capability_set(log, sub, settings))
4397 case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID:
4398 if (!rdp_read_bitmap_cache_v3_codec_id_capability_set(log, sub, settings))
4415 case CAPSET_TYPE_BITMAP_CACHE:
4416 if (!rdp_read_bitmap_cache_capability_set(log, sub, settings))
4421 case CAPSET_TYPE_BITMAP_CACHE_V2:
4422 if (!rdp_read_bitmap_cache_v2_capability_set(log, sub, settings))
4427 case CAPSET_TYPE_BRUSH:
4428 if (!rdp_read_brush_capability_set(log, sub, settings))
4433 case CAPSET_TYPE_GLYPH_CACHE:
4434 if (!rdp_read_glyph_cache_capability_set(log, sub, settings))
4439 case CAPSET_TYPE_OFFSCREEN_CACHE:
4440 if (!rdp_read_offscreen_bitmap_cache_capability_set(log, sub, settings))
4445 case CAPSET_TYPE_SOUND:
4446 if (!rdp_read_sound_capability_set(log, sub, settings))
4451 case CAPSET_TYPE_CONTROL:
4452 if (!rdp_read_control_capability_set(log, sub, settings))
4457 case CAPSET_TYPE_ACTIVATION:
4458 if (!rdp_read_window_activation_capability_set(log, sub, settings))
4463 case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
4464 if (!rdp_read_draw_nine_grid_cache_capability_set(log, sub, settings))
4470 WLog_Print(log, WLOG_ERROR,
4471 "capability %s(%" PRIu16
") not expected from client",
4472 get_capability_name(type), type);
4481 case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
4482 if (!rdp_read_bitmap_cache_host_support_capability_set(log, sub, settings))
4488 WLog_Print(log, WLOG_ERROR,
4489 "capability %s(%" PRIu16
") not expected from server",
4490 get_capability_name(type), type);
4496 const size_t rest = Stream_GetRemainingLength(sub);
4499 const size_t length = Stream_Capacity(sub);
4500 WLog_Print(log, WLOG_ERROR,
4501 "incorrect offset, type:0x%04" PRIx16
" actual:%" PRIuz
" expected:%" PRIuz
"",
4502 type, length - rest, length);
4507static BOOL rdp_read_capability_sets(wLog* log,
wStream* s, rdpSettings* settings,
4508 rdpSettings* rcvSettings, UINT16 totalLength)
4514 UINT16 numberCapabilities = 0;
4517#ifdef WITH_DEBUG_CAPABILITIES
4518 const size_t capstart = Stream_GetPosition(s);
4522 WINPR_ASSERT(settings);
4524 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
4527 Stream_Read_UINT16(s, numberCapabilities);
4529 count = numberCapabilities;
4531 start = Stream_GetPosition(s);
4532 while (numberCapabilities > 0 && Stream_GetRemainingLength(s) >= 4)
4539 if (!rdp_read_capability_set_header(log, s, &length, &type))
4541 sub = Stream_StaticInit(&subbuffer, Stream_Pointer(s), length - 4);
4542 if (!Stream_SafeSeek(s, length - 4))
4545 if (!rdp_read_capability_set(log, sub, type, rcvSettings, settings->ServerMode))
4548 if (!rdp_apply_from_received(type, settings, rcvSettings))
4550 numberCapabilities--;
4553 end = Stream_GetPosition(s);
4556 if (numberCapabilities)
4558 WLog_Print(log, WLOG_ERROR,
4559 "strange we haven't read the number of announced capacity sets, read=%d "
4560 "expected=%" PRIu16
"",
4561 count - numberCapabilities, count);
4564#ifdef WITH_DEBUG_CAPABILITIES
4565 rdp_print_capability_sets(log, s, capstart, TRUE);
4568 if (len > totalLength)
4570 WLog_Print(log, WLOG_ERROR,
"Capability length expected %" PRIu16
", actual %" PRIuz,
4574 rc = freerdp_capability_buffer_copy(settings, rcvSettings);
4579BOOL rdp_recv_get_active_header(rdpRdp* rdp,
wStream* s, UINT16* pChannelId, UINT16* length)
4582 WINPR_ASSERT(rdp->context);
4584 if (!rdp_read_header(rdp, s, length, pChannelId))
4587 if (freerdp_shall_disconnect_context(rdp->context))
4590 if (*pChannelId != MCS_GLOBAL_CHANNEL_ID)
4592 UINT16 mcsMessageChannelId = rdp->mcs->messageChannelId;
4594 if ((mcsMessageChannelId == 0) || (*pChannelId != mcsMessageChannelId))
4596 WLog_Print(rdp->log, WLOG_ERROR,
"unexpected MCS channel id %04" PRIx16
" received",
4605BOOL rdp_recv_demand_active(rdpRdp* rdp,
wStream* s, UINT16 pduSource, UINT16 length)
4607 UINT16 lengthSourceDescriptor = 0;
4608 UINT16 lengthCombinedCapabilities = 0;
4611 WINPR_ASSERT(rdp->settings);
4612 WINPR_ASSERT(rdp->context);
4615 rdp->settings->PduSource = pduSource;
4617 if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 8))
4620 Stream_Read_UINT32(s, rdp->settings->ShareId);
4621 Stream_Read_UINT16(s, lengthSourceDescriptor);
4622 Stream_Read_UINT16(s, lengthCombinedCapabilities);
4624 if (!Stream_SafeSeek(s, lengthSourceDescriptor) ||
4625 !Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 4))
4629 if (!rdp_read_capability_sets(rdp->log, s, rdp->settings, rdp->remoteSettings,
4630 lengthCombinedCapabilities))
4632 WLog_Print(rdp->log, WLOG_ERROR,
"rdp_read_capability_sets failed");
4636 if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 4))
4641 Stream_Seek_UINT32(s);
4645 secondary->glyph_v2 = (rdp->settings->GlyphSupportLevel > GLYPH_SUPPORT_FULL);
4648 return tpkt_ensure_stream_consumed(rdp->log, s, length);
4651static BOOL rdp_write_demand_active(wLog* log,
wStream* s, rdpSettings* settings)
4656 UINT16 numberCapabilities = 0;
4657 size_t lengthCombinedCapabilities = 0;
4659 if (!Stream_EnsureRemainingCapacity(s, 64))
4662 Stream_Write_UINT32(s, settings->ShareId);
4663 Stream_Write_UINT16(s, 4);
4664 lm = Stream_GetPosition(s);
4665 Stream_Seek_UINT16(s);
4666 Stream_Write(s,
"RDP", 4);
4667 bm = Stream_GetPosition(s);
4668 Stream_Seek_UINT16(s);
4669 Stream_Write_UINT16(s, 0);
4670 numberCapabilities = 14;
4672 if (!rdp_write_general_capability_set(log, s, settings) ||
4673 !rdp_write_bitmap_capability_set(log, s, settings) ||
4674 !rdp_write_order_capability_set(log, s, settings) ||
4675 !rdp_write_pointer_capability_set(log, s, settings) ||
4676 !rdp_write_input_capability_set(log, s, settings) ||
4677 !rdp_write_virtual_channel_capability_set(log, s, settings) ||
4678 !rdp_write_share_capability_set(log, s, settings) ||
4679 !rdp_write_font_capability_set(log, s, settings) ||
4680 !rdp_write_multifragment_update_capability_set(log, s, settings) ||
4681 !rdp_write_large_pointer_capability_set(log, s, settings) ||
4682 !rdp_write_desktop_composition_capability_set(log, s, settings) ||
4683 !rdp_write_surface_commands_capability_set(log, s, settings) ||
4684 !rdp_write_bitmap_codecs_capability_set(log, s, settings) ||
4685 !rdp_write_frame_acknowledge_capability_set(log, s, settings))
4692 numberCapabilities++;
4694 if (!rdp_write_bitmap_cache_host_support_capability_set(log, s, settings))
4698 if (settings->RemoteApplicationMode)
4700 numberCapabilities += 2;
4702 if (!rdp_write_remote_programs_capability_set(log, s, settings) ||
4703 !rdp_write_window_list_capability_set(log, s, settings))
4707 em = Stream_GetPosition(s);
4708 Stream_SetPosition(s, lm);
4709 lengthCombinedCapabilities = (em - bm);
4710 if (lengthCombinedCapabilities > UINT16_MAX)
4712 Stream_Write_UINT16(
4713 s, (UINT16)lengthCombinedCapabilities);
4714 Stream_SetPosition(s, bm);
4715 Stream_Write_UINT16(s, numberCapabilities);
4716#ifdef WITH_DEBUG_CAPABILITIES
4717 rdp_print_capability_sets(log, s, bm, FALSE);
4719 Stream_SetPosition(s, em);
4720 Stream_Write_UINT32(s, 0);
4724BOOL rdp_send_demand_active(rdpRdp* rdp)
4726 UINT16 sec_flags = 0;
4727 wStream* s = rdp_send_stream_pdu_init(rdp, &sec_flags);
4733 rdp->settings->ShareId = 0x10000 + rdp->mcs->userId;
4734 status = rdp_write_demand_active(rdp->log, s, rdp->settings) &&
4735 rdp_send_pdu(rdp, s, PDU_TYPE_DEMAND_ACTIVE, rdp->mcs->userId, sec_flags);
4740BOOL rdp_recv_confirm_active(rdpRdp* rdp,
wStream* s, UINT16 pduLength)
4742 rdpSettings* settings = NULL;
4743 UINT16 lengthSourceDescriptor = 0;
4744 UINT16 lengthCombinedCapabilities = 0;
4748 settings = rdp->settings;
4749 WINPR_ASSERT(settings);
4751 if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 10))
4754 Stream_Seek_UINT32(s);
4755 Stream_Seek_UINT16(s);
4756 Stream_Read_UINT16(s, lengthSourceDescriptor);
4757 Stream_Read_UINT16(s, lengthCombinedCapabilities);
4759 if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, lengthSourceDescriptor + 4U))
4762 Stream_Seek(s, lengthSourceDescriptor);
4763 if (!rdp_read_capability_sets(rdp->log, s, rdp->settings, rdp->remoteSettings,
4764 lengthCombinedCapabilities))
4767 if (!settings->ReceivedCapabilities[CAPSET_TYPE_SURFACE_COMMANDS])
4770 settings->SurfaceCommandsEnabled = FALSE;
4771 settings->SurfaceFrameMarkerEnabled = FALSE;
4774 if (!settings->ReceivedCapabilities[CAPSET_TYPE_FRAME_ACKNOWLEDGE])
4777 settings->FrameAcknowledge = 0;
4780 if (!settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID])
4783 settings->BitmapCacheV3Enabled = FALSE;
4786 if (!settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CODECS])
4797 if (!settings->ReceivedCapabilities[CAPSET_TYPE_MULTI_FRAGMENT_UPDATE])
4800 settings->MultifragMaxRequestSize = FASTPATH_FRAGMENT_SAFE_SIZE;
4803 if (!settings->ReceivedCapabilities[CAPSET_TYPE_LARGE_POINTER])
4806 settings->LargePointerFlag = 0;
4809 return tpkt_ensure_stream_consumed(rdp->log, s, pduLength);
4812static BOOL rdp_write_confirm_active(wLog* log,
wStream* s, rdpSettings* settings)
4817 UINT16 numberCapabilities = 0;
4818 UINT16 lengthSourceDescriptor = 0;
4819 size_t lengthCombinedCapabilities = 0;
4822 WINPR_ASSERT(settings);
4824 lengthSourceDescriptor =
sizeof(SOURCE_DESCRIPTOR);
4825 Stream_Write_UINT32(s, settings->ShareId);
4826 Stream_Write_UINT16(s, 0x03EA);
4827 Stream_Write_UINT16(s, lengthSourceDescriptor);
4828 lm = Stream_GetPosition(s);
4829 Stream_Seek_UINT16(s);
4830 Stream_Write(s, SOURCE_DESCRIPTOR, lengthSourceDescriptor);
4831 bm = Stream_GetPosition(s);
4832 Stream_Seek_UINT16(s);
4833 Stream_Write_UINT16(s, 0);
4835 numberCapabilities = 15;
4837 if (!rdp_write_general_capability_set(log, s, settings) ||
4838 !rdp_write_bitmap_capability_set(log, s, settings) ||
4839 !rdp_write_order_capability_set(log, s, settings))
4842 if (settings->RdpVersion >= RDP_VERSION_5_PLUS)
4843 ret = rdp_write_bitmap_cache_v2_capability_set(log, s, settings);
4845 ret = rdp_write_bitmap_cache_capability_set(log, s, settings);
4850 if (!rdp_write_pointer_capability_set(log, s, settings) ||
4851 !rdp_write_input_capability_set(log, s, settings) ||
4852 !rdp_write_brush_capability_set(log, s, settings) ||
4853 !rdp_write_glyph_cache_capability_set(log, s, settings) ||
4854 !rdp_write_virtual_channel_capability_set(log, s, settings) ||
4855 !rdp_write_sound_capability_set(log, s, settings) ||
4856 !rdp_write_share_capability_set(log, s, settings) ||
4857 !rdp_write_font_capability_set(log, s, settings) ||
4858 !rdp_write_control_capability_set(log, s, settings) ||
4859 !rdp_write_color_cache_capability_set(log, s, settings) ||
4860 !rdp_write_window_activation_capability_set(log, s, settings))
4866 numberCapabilities++;
4868 if (!rdp_write_offscreen_bitmap_cache_capability_set(log, s, settings))
4872 if (settings->DrawNineGridEnabled)
4874 numberCapabilities++;
4876 if (!rdp_write_draw_nine_grid_cache_capability_set(log, s, settings))
4880 if (settings->ReceivedCapabilities[CAPSET_TYPE_LARGE_POINTER])
4882 if (settings->LargePointerFlag)
4884 numberCapabilities++;
4886 if (!rdp_write_large_pointer_capability_set(log, s, settings))
4891 if (settings->RemoteApplicationMode)
4893 numberCapabilities += 2;
4895 if (!rdp_write_remote_programs_capability_set(log, s, settings) ||
4896 !rdp_write_window_list_capability_set(log, s, settings))
4900 if (settings->ReceivedCapabilities[CAPSET_TYPE_MULTI_FRAGMENT_UPDATE])
4902 numberCapabilities++;
4904 if (!rdp_write_multifragment_update_capability_set(log, s, settings))
4908 if (settings->ReceivedCapabilities[CAPSET_TYPE_SURFACE_COMMANDS])
4910 numberCapabilities++;
4912 if (!rdp_write_surface_commands_capability_set(log, s, settings))
4916 if (settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CODECS])
4918 numberCapabilities++;
4920 if (!rdp_write_bitmap_codecs_capability_set(log, s, settings))
4924 if (!settings->ReceivedCapabilities[CAPSET_TYPE_FRAME_ACKNOWLEDGE])
4925 settings->FrameAcknowledge = 0;
4927 if (settings->FrameAcknowledge)
4929 numberCapabilities++;
4931 if (!rdp_write_frame_acknowledge_capability_set(log, s, settings))
4935 if (settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID])
4937 if (settings->BitmapCacheV3CodecId != 0)
4939 numberCapabilities++;
4941 if (!rdp_write_bitmap_cache_v3_codec_id_capability_set(log, s, settings))
4946 em = Stream_GetPosition(s);
4947 Stream_SetPosition(s, lm);
4948 lengthCombinedCapabilities = (em - bm);
4949 if (lengthCombinedCapabilities > UINT16_MAX)
4951 Stream_Write_UINT16(
4952 s, (UINT16)lengthCombinedCapabilities);
4953 Stream_SetPosition(s, bm);
4954 Stream_Write_UINT16(s, numberCapabilities);
4955#ifdef WITH_DEBUG_CAPABILITIES
4956 rdp_print_capability_sets(log, s, bm, FALSE);
4958 Stream_SetPosition(s, em);
4963BOOL rdp_send_confirm_active(rdpRdp* rdp)
4965 UINT16 sec_flags = 0;
4966 wStream* s = rdp_send_stream_pdu_init(rdp, &sec_flags);
4972 status = rdp_write_confirm_active(rdp->log, s, rdp->settings) &&
4973 rdp_send_pdu(rdp, s, PDU_TYPE_CONFIRM_ACTIVE, rdp->mcs->userId, sec_flags);
4978const char* rdp_input_flag_string(UINT16 flags,
char* buffer,
size_t len)
4980 char prefix[16] = { 0 };
4982 (void)_snprintf(prefix,
sizeof(prefix),
"[0x%04" PRIx16
"][", flags);
4983 winpr_str_append(prefix, buffer, len,
"");
4984 if ((flags & INPUT_FLAG_SCANCODES) != 0)
4985 winpr_str_append(
"INPUT_FLAG_SCANCODES", buffer, len,
"|");
4986 if ((flags & INPUT_FLAG_MOUSEX) != 0)
4987 winpr_str_append(
"INPUT_FLAG_MOUSEX", buffer, len,
"|");
4988 if ((flags & INPUT_FLAG_FASTPATH_INPUT) != 0)
4989 winpr_str_append(
"INPUT_FLAG_FASTPATH_INPUT", buffer, len,
"|");
4990 if ((flags & INPUT_FLAG_UNICODE) != 0)
4991 winpr_str_append(
"INPUT_FLAG_UNICODE", buffer, len,
"|");
4992 if ((flags & INPUT_FLAG_FASTPATH_INPUT2) != 0)
4993 winpr_str_append(
"INPUT_FLAG_FASTPATH_INPUT2", buffer, len,
"|");
4994 if ((flags & INPUT_FLAG_UNUSED1) != 0)
4995 winpr_str_append(
"INPUT_FLAG_UNUSED1", buffer, len,
"|");
4996 if ((flags & INPUT_FLAG_MOUSE_RELATIVE) != 0)
4997 winpr_str_append(
"INPUT_FLAG_MOUSE_RELATIVE", buffer, len,
"|");
4998 if ((flags & TS_INPUT_FLAG_MOUSE_HWHEEL) != 0)
4999 winpr_str_append(
"TS_INPUT_FLAG_MOUSE_HWHEEL", buffer, len,
"|");
5000 if ((flags & TS_INPUT_FLAG_QOE_TIMESTAMPS) != 0)
5001 winpr_str_append(
"TS_INPUT_FLAG_QOE_TIMESTAMPS", buffer, len,
"|");
5002 winpr_str_append(
"]", buffer, len,
"");
FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
FREERDP_API BOOL freerdp_settings_set_string(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const char *param)
Sets a string settings value. The param is copied.
FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.
FREERDP_API BOOL freerdp_settings_set_pointer_len(rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id, const void *data, size_t len)
Set a pointer to value data.
FREERDP_API BOOL freerdp_settings_set_string_len(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const char *param, size_t len)
Sets a string settings value. The param is copied.
FREERDP_API BOOL freerdp_settings_set_uint32(rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id, UINT32 param)
Sets a UINT32 settings value.
FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.
FREERDP_API BOOL freerdp_settings_set_bool(rdpSettings *settings, FreeRDP_Settings_Keys_Bool id, BOOL param)
Sets a BOOL settings value.