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, TS_CAPS_PROTOCOLVERSION);
220 if (settings->CapsProtocolVersion == 0x0000)
222 WLog_Print(log, WLOG_WARN,
223 "TS_GENERAL_CAPABILITYSET::protocolVersion(0x%04" PRIx16
224 " assuming old FreeRDP, ignoring protocol violation, correcting value.",
225 settings->CapsProtocolVersion);
226 settings->CapsProtocolVersion = TS_CAPS_PROTOCOLVERSION;
231 Stream_Seek_UINT16(s);
233 s, settings->CapsGeneralCompressionTypes);
234 Stream_Read_UINT16(s, extraFlags);
235 Stream_Read_UINT16(s, settings->CapsUpdateCapabilityFlag);
236 Stream_Read_UINT16(s, settings->CapsRemoteUnshareFlag);
238 s, settings->CapsGeneralCompressionLevel);
239 Stream_Read_UINT8(s, refreshRectSupport);
240 Stream_Read_UINT8(s, suppressOutputSupport);
241 settings->NoBitmapCompressionHeader = (extraFlags & NO_BITMAP_COMPRESSION_HDR) ? TRUE : FALSE;
242 settings->LongCredentialsSupported = (extraFlags & LONG_CREDENTIALS_SUPPORTED) ? TRUE : FALSE;
244 settings->AutoReconnectionPacketSupported =
245 (extraFlags & AUTORECONNECT_SUPPORTED) ? TRUE : FALSE;
246 settings->FastPathOutput = (extraFlags & FASTPATH_OUTPUT_SUPPORTED) ? TRUE : FALSE;
247 settings->SaltedChecksum = (extraFlags & ENC_SALTED_CHECKSUM) ? TRUE : FALSE;
248 settings->RefreshRect = refreshRectSupport;
249 settings->SuppressOutput = suppressOutputSupport;
259static BOOL rdp_write_general_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
261 if (!Stream_EnsureRemainingCapacity(s, 64))
264 const size_t header = rdp_capability_set_start(log, s);
265 UINT16 extraFlags = 0;
267 WINPR_ASSERT(settings);
268 if (settings->LongCredentialsSupported)
269 extraFlags |= LONG_CREDENTIALS_SUPPORTED;
271 if (settings->NoBitmapCompressionHeader)
272 extraFlags |= NO_BITMAP_COMPRESSION_HDR;
274 if (settings->AutoReconnectionPacketSupported)
275 extraFlags |= AUTORECONNECT_SUPPORTED;
277 if (settings->FastPathOutput)
278 extraFlags |= FASTPATH_OUTPUT_SUPPORTED;
280 if (settings->SaltedChecksum)
281 extraFlags |= ENC_SALTED_CHECKSUM;
283 if ((settings->OsMajorType > UINT16_MAX) || (settings->OsMinorType > UINT16_MAX))
285 WLog_Print(log, WLOG_ERROR,
286 "OsMajorType=%08" PRIx32
", OsMinorType=%08" PRIx32
287 " they need to be smaller %04" PRIx16,
288 settings->OsMajorType, settings->OsMinorType, UINT16_MAX);
291 if (settings->CapsProtocolVersion != TS_CAPS_PROTOCOLVERSION)
293 WLog_Print(log, WLOG_ERROR,
294 "TS_GENERAL_CAPABILITYSET::protocolVersion(0x%04" PRIx16
295 ") != TS_CAPS_PROTOCOLVERSION(0x%04" PRIx32
")",
296 settings->CapsProtocolVersion, TS_CAPS_PROTOCOLVERSION);
299 Stream_Write_UINT16(s, (UINT16)settings->OsMajorType);
300 Stream_Write_UINT16(s, (UINT16)settings->OsMinorType);
301 Stream_Write_UINT16(s, settings->CapsProtocolVersion);
302 Stream_Write_UINT16(s, 0);
304 s, settings->CapsGeneralCompressionTypes);
305 Stream_Write_UINT16(s, extraFlags);
306 Stream_Write_UINT16(s, settings->CapsUpdateCapabilityFlag);
307 Stream_Write_UINT16(s, settings->CapsRemoteUnshareFlag);
309 s, settings->CapsGeneralCompressionLevel);
310 Stream_Write_UINT8(s, settings->RefreshRect ? 1 : 0);
311 Stream_Write_UINT8(s, settings->SuppressOutput ? 1 : 0);
312 return rdp_capability_set_finish(s, header, CAPSET_TYPE_GENERAL);
315#ifdef WITH_DEBUG_CAPABILITIES
316static BOOL rdp_print_general_capability_set(wLog* log,
wStream* s)
318 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 20))
321 WLog_Print(log, WLOG_TRACE,
322 "GeneralCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
323 const uint16_t osMinorType = Stream_Get_UINT16(s);
324 const uint16_t osMajorType = Stream_Get_UINT16(s);
325 const uint16_t protocolVersion = Stream_Get_UINT16(s);
326 const uint16_t pad2OctetsA = Stream_Get_UINT16(s);
327 const uint16_t generalCompressionTypes =
328 Stream_Get_UINT16(s);
329 const uint16_t extraFlags = Stream_Get_UINT16(s);
330 const uint16_t updateCapabilityFlag = Stream_Get_UINT16(s);
331 const uint16_t remoteUnshareFlag = Stream_Get_UINT16(s);
332 const uint16_t generalCompressionLevel =
333 Stream_Get_UINT16(s);
334 const uint8_t refreshRectSupport = Stream_Get_UINT8(s);
335 const uint8_t suppressOutputSupport = Stream_Get_UINT8(s);
336 WLog_Print(log, WLOG_TRACE,
"\tosMajorType: 0x%04" PRIX16
"", osMajorType);
337 WLog_Print(log, WLOG_TRACE,
"\tosMinorType: 0x%04" PRIX16
"", osMinorType);
338 WLog_Print(log, WLOG_TRACE,
"\tprotocolVersion: 0x%04" PRIX16
"", protocolVersion);
339 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
340 WLog_Print(log, WLOG_TRACE,
"\tgeneralCompressionTypes: 0x%04" PRIX16
"",
341 generalCompressionTypes);
342 WLog_Print(log, WLOG_TRACE,
"\textraFlags: 0x%04" PRIX16
"", extraFlags);
343 WLog_Print(log, WLOG_TRACE,
"\tupdateCapabilityFlag: 0x%04" PRIX16
"", updateCapabilityFlag);
344 WLog_Print(log, WLOG_TRACE,
"\tremoteUnshareFlag: 0x%04" PRIX16
"", remoteUnshareFlag);
345 WLog_Print(log, WLOG_TRACE,
"\tgeneralCompressionLevel: 0x%04" PRIX16
"",
346 generalCompressionLevel);
347 WLog_Print(log, WLOG_TRACE,
"\trefreshRectSupport: 0x%02" PRIX8
"", refreshRectSupport);
348 WLog_Print(log, WLOG_TRACE,
"\tsuppressOutputSupport: 0x%02" PRIX8
"", suppressOutputSupport);
352static BOOL rdp_apply_bitmap_capability_set(rdpSettings* settings,
const rdpSettings* src)
354 WINPR_ASSERT(settings);
357 if (!settings->ServerMode)
364 if (!src->DesktopResize)
365 settings->DesktopResize = FALSE;
367 if (!settings->ServerMode && settings->DesktopResize)
371 settings->DesktopWidth = src->DesktopWidth;
372 settings->DesktopHeight = src->DesktopHeight;
375 if (settings->DrawAllowSkipAlpha)
376 settings->DrawAllowSkipAlpha = src->DrawAllowSkipAlpha;
378 if (settings->DrawAllowDynamicColorFidelity)
379 settings->DrawAllowDynamicColorFidelity = src->DrawAllowDynamicColorFidelity;
381 if (settings->DrawAllowColorSubsampling)
382 settings->DrawAllowColorSubsampling = src->DrawAllowColorSubsampling;
392static BOOL rdp_read_bitmap_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
394 BYTE drawingFlags = 0;
395 UINT16 desktopWidth = 0;
396 UINT16 desktopHeight = 0;
397 UINT16 desktopResizeFlag = 0;
398 UINT16 preferredBitsPerPixel = 0;
400 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 24))
403 Stream_Read_UINT16(s, preferredBitsPerPixel);
404 Stream_Seek_UINT16(s);
405 Stream_Seek_UINT16(s);
406 Stream_Seek_UINT16(s);
407 Stream_Read_UINT16(s, desktopWidth);
408 Stream_Read_UINT16(s, desktopHeight);
409 Stream_Seek_UINT16(s);
410 Stream_Read_UINT16(s, desktopResizeFlag);
411 Stream_Seek_UINT16(s);
412 Stream_Seek_UINT8(s);
413 Stream_Read_UINT8(s, drawingFlags);
414 Stream_Seek_UINT16(s);
415 Stream_Seek_UINT16(s);
419 settings->DesktopResize = desktopResizeFlag;
420 settings->DesktopWidth = desktopWidth;
421 settings->DesktopHeight = desktopHeight;
422 settings->DrawAllowSkipAlpha = (drawingFlags & DRAW_ALLOW_SKIP_ALPHA) ? TRUE : FALSE;
423 settings->DrawAllowDynamicColorFidelity =
424 (drawingFlags & DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY) ? TRUE : FALSE;
425 settings->DrawAllowColorSubsampling =
426 (drawingFlags & DRAW_ALLOW_COLOR_SUBSAMPLING) ? TRUE : FALSE;
436static BOOL rdp_write_bitmap_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
438 BYTE drawingFlags = 0;
439 UINT16 preferredBitsPerPixel = 0;
441 if (!Stream_EnsureRemainingCapacity(s, 64))
444 const size_t header = rdp_capability_set_start(log, s);
446 WINPR_ASSERT(settings);
447 if (settings->DrawAllowSkipAlpha)
448 drawingFlags |= DRAW_ALLOW_SKIP_ALPHA;
450 if (settings->DrawAllowDynamicColorFidelity)
451 drawingFlags |= DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY;
453 if (settings->DrawAllowColorSubsampling)
454 drawingFlags |= DRAW_ALLOW_COLOR_SUBSAMPLING;
466 (settings->DesktopWidth > UINT16_MAX) || (settings->DesktopHeight > UINT16_MAX))
469 if (settings->RdpVersion >= RDP_VERSION_5_PLUS)
472 preferredBitsPerPixel = 8;
474 Stream_Write_UINT16(s, preferredBitsPerPixel);
475 Stream_Write_UINT16(s, 1);
476 Stream_Write_UINT16(s, 1);
477 Stream_Write_UINT16(s, 1);
478 Stream_Write_UINT16(s, (UINT16)settings->DesktopWidth);
479 Stream_Write_UINT16(s, (UINT16)settings->DesktopHeight);
480 Stream_Write_UINT16(s, 0);
481 Stream_Write_UINT16(s, (UINT16)settings->DesktopResize);
482 Stream_Write_UINT16(s, 1);
483 Stream_Write_UINT8(s, 0);
484 Stream_Write_UINT8(s, drawingFlags);
485 Stream_Write_UINT16(s, 1);
486 Stream_Write_UINT16(s, 0);
487 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP);
490#ifdef WITH_DEBUG_CAPABILITIES
491static BOOL rdp_print_bitmap_capability_set(wLog* log,
wStream* s)
493 UINT16 preferredBitsPerPixel = 0;
494 UINT16 receive1BitPerPixel = 0;
495 UINT16 receive4BitsPerPixel = 0;
496 UINT16 receive8BitsPerPixel = 0;
497 UINT16 desktopWidth = 0;
498 UINT16 desktopHeight = 0;
499 UINT16 pad2Octets = 0;
500 UINT16 desktopResizeFlag = 0;
501 UINT16 bitmapCompressionFlag = 0;
502 BYTE highColorFlags = 0;
503 BYTE drawingFlags = 0;
504 UINT16 multipleRectangleSupport = 0;
505 UINT16 pad2OctetsB = 0;
506 WLog_Print(log, WLOG_TRACE,
507 "BitmapCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
509 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 24))
512 Stream_Read_UINT16(s, preferredBitsPerPixel);
513 Stream_Read_UINT16(s, receive1BitPerPixel);
514 Stream_Read_UINT16(s, receive4BitsPerPixel);
515 Stream_Read_UINT16(s, receive8BitsPerPixel);
516 Stream_Read_UINT16(s, desktopWidth);
517 Stream_Read_UINT16(s, desktopHeight);
518 Stream_Read_UINT16(s, pad2Octets);
519 Stream_Read_UINT16(s, desktopResizeFlag);
520 Stream_Read_UINT16(s, bitmapCompressionFlag);
521 Stream_Read_UINT8(s, highColorFlags);
522 Stream_Read_UINT8(s, drawingFlags);
523 Stream_Read_UINT16(s, multipleRectangleSupport);
524 Stream_Read_UINT16(s, pad2OctetsB);
525 WLog_Print(log, WLOG_TRACE,
"\tpreferredBitsPerPixel: 0x%04" PRIX16
"", preferredBitsPerPixel);
526 WLog_Print(log, WLOG_TRACE,
"\treceive1BitPerPixel: 0x%04" PRIX16
"", receive1BitPerPixel);
527 WLog_Print(log, WLOG_TRACE,
"\treceive4BitsPerPixel: 0x%04" PRIX16
"", receive4BitsPerPixel);
528 WLog_Print(log, WLOG_TRACE,
"\treceive8BitsPerPixel: 0x%04" PRIX16
"", receive8BitsPerPixel);
529 WLog_Print(log, WLOG_TRACE,
"\tdesktopWidth: 0x%04" PRIX16
"", desktopWidth);
530 WLog_Print(log, WLOG_TRACE,
"\tdesktopHeight: 0x%04" PRIX16
"", desktopHeight);
531 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
532 WLog_Print(log, WLOG_TRACE,
"\tdesktopResizeFlag: 0x%04" PRIX16
"", desktopResizeFlag);
533 WLog_Print(log, WLOG_TRACE,
"\tbitmapCompressionFlag: 0x%04" PRIX16
"", bitmapCompressionFlag);
534 WLog_Print(log, WLOG_TRACE,
"\thighColorFlags: 0x%02" PRIX8
"", highColorFlags);
535 WLog_Print(log, WLOG_TRACE,
"\tdrawingFlags: 0x%02" PRIX8
"", drawingFlags);
536 WLog_Print(log, WLOG_TRACE,
"\tmultipleRectangleSupport: 0x%04" PRIX16
"",
537 multipleRectangleSupport);
538 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsB: 0x%04" PRIX16
"", pad2OctetsB);
542static BOOL rdp_apply_order_capability_set(rdpSettings* settings,
const rdpSettings* src)
544 WINPR_ASSERT(settings);
547 BOOL BitmapCacheV3Enabled = FALSE;
548 BOOL FrameMarkerCommandEnabled = FALSE;
550 for (
size_t i = 0; i < 32; i++)
552 if (!src->OrderSupport[i])
553 settings->OrderSupport[i] = FALSE;
556 if (src->OrderSupportFlags & ORDER_FLAGS_EXTRA_SUPPORT)
558 if (src->OrderSupportFlagsEx & CACHE_BITMAP_V3_SUPPORT)
559 BitmapCacheV3Enabled = TRUE;
561 if (src->OrderSupportFlagsEx & ALTSEC_FRAME_MARKER_SUPPORT)
562 FrameMarkerCommandEnabled = TRUE;
565 if (BitmapCacheV3Enabled && settings->BitmapCacheV3Enabled)
567 settings->BitmapCacheV3Enabled = src->BitmapCacheV3Enabled;
568 settings->BitmapCacheVersion = src->BitmapCacheVersion;
571 settings->BitmapCacheV3Enabled = FALSE;
573 if (FrameMarkerCommandEnabled && src->FrameMarkerCommandEnabled)
574 settings->FrameMarkerCommandEnabled = TRUE;
576 settings->FrameMarkerCommandEnabled = FALSE;
586static BOOL rdp_read_order_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
588 char terminalDescriptor[17] = { 0 };
589 BYTE orderSupport[32] = { 0 };
590 BOOL BitmapCacheV3Enabled = FALSE;
591 BOOL FrameMarkerCommandEnabled = FALSE;
593 WINPR_ASSERT(settings);
594 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 84))
597 Stream_Read(s, terminalDescriptor, 16);
598 Stream_Seek_UINT32(s);
599 Stream_Seek_UINT16(s);
600 Stream_Seek_UINT16(s);
601 Stream_Seek_UINT16(s);
602 Stream_Seek_UINT16(s);
603 Stream_Seek_UINT16(s);
604 Stream_Read_UINT16(s, settings->OrderSupportFlags);
605 Stream_Read(s, orderSupport, 32);
606 Stream_Seek_UINT16(s);
607 Stream_Read_UINT16(s, settings->OrderSupportFlagsEx);
608 Stream_Seek_UINT32(s);
609 Stream_Seek_UINT32(s);
610 Stream_Seek_UINT16(s);
611 Stream_Seek_UINT16(s);
612 Stream_Read_UINT16(s, settings->TextANSICodePage);
613 Stream_Seek_UINT16(s);
618 for (
size_t i = 0; i < ARRAYSIZE(orderSupport); i++)
619 settings->OrderSupport[i] = orderSupport[i];
621 if (settings->OrderSupportFlags & ORDER_FLAGS_EXTRA_SUPPORT)
623 BitmapCacheV3Enabled =
624 (settings->OrderSupportFlagsEx & CACHE_BITMAP_V3_SUPPORT) ? TRUE : FALSE;
625 FrameMarkerCommandEnabled =
626 (settings->OrderSupportFlagsEx & ALTSEC_FRAME_MARKER_SUPPORT) ? TRUE : FALSE;
629 settings->BitmapCacheV3Enabled = BitmapCacheV3Enabled;
630 if (BitmapCacheV3Enabled)
631 settings->BitmapCacheVersion = 3;
633 settings->FrameMarkerCommandEnabled = FrameMarkerCommandEnabled;
643static BOOL rdp_write_order_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
645 char terminalDescriptor[16] = { 0 };
647 WINPR_ASSERT(settings);
648 if (!Stream_EnsureRemainingCapacity(s, 64))
651 const size_t header = rdp_capability_set_start(log, s);
653 UINT16 orderSupportExFlags = settings->OrderSupportFlagsEx;
654 UINT16 orderFlags = settings->OrderSupportFlags;
656 if (settings->BitmapCacheV3Enabled)
658 if ((orderSupportExFlags & CACHE_BITMAP_V3_SUPPORT) == 0)
660 WLog_Print(log, WLOG_WARN,
661 "rdpSettings::BitmapCacheV3Enabled=TRUE, but CACHE_BITMAP_V3_SUPPORT not "
662 "set in rdpSettings::OrderSupportEx, aborting.");
664 if ((orderFlags & ORDER_FLAGS_EXTRA_SUPPORT) == 0)
666 WLog_Print(log, WLOG_WARN,
667 "rdpSettings::BitmapCacheV3Enabled=TRUE, but ORDER_FLAGS_EXTRA_SUPPORT not "
668 "set in rdpSettings::OrderSupport, aborting.");
672 if (settings->FrameMarkerCommandEnabled)
674 if ((orderSupportExFlags & ALTSEC_FRAME_MARKER_SUPPORT) == 0)
678 "rdpSettings::FrameMarkerCommandEnabled=TRUE, but "
679 "ALTSEC_FRAME_MARKER_SUPPORT not set in rdpSettings::OrderSupportEx, aborting.");
681 if ((orderFlags & ORDER_FLAGS_EXTRA_SUPPORT) == 0)
683 WLog_Print(log, WLOG_WARN,
684 "rdpSettings::FrameMarkerCommandEnabled=TRUE, but ORDER_FLAGS_EXTRA_SUPPORT "
685 "not set in rdpSettings::OrderSupport, aborting.");
692 const size_t len = strnlen(dsc, ARRAYSIZE(terminalDescriptor));
693 strncpy(terminalDescriptor, dsc, len);
695 Stream_Write(s, terminalDescriptor,
696 sizeof(terminalDescriptor));
697 Stream_Write_UINT32(s, 0);
698 Stream_Write_UINT16(s, 1);
699 Stream_Write_UINT16(s, 20);
700 Stream_Write_UINT16(s, 0);
701 Stream_Write_UINT16(s, 1);
702 Stream_Write_UINT16(s, 0);
703 Stream_Write_UINT16(s, orderFlags);
704 Stream_Write(s, settings->OrderSupport, 32);
705 Stream_Write_UINT16(s, 0);
706 Stream_Write_UINT16(s, orderSupportExFlags);
707 Stream_Write_UINT32(s, 0);
708 Stream_Write_UINT32(s, 230400);
709 Stream_Write_UINT16(s, 0);
710 Stream_Write_UINT16(s, 0);
711 Stream_Write_UINT16(s, settings->TextANSICodePage);
712 Stream_Write_UINT16(s, 0);
713 return rdp_capability_set_finish(s, header, CAPSET_TYPE_ORDER);
716#ifdef WITH_DEBUG_CAPABILITIES
717static BOOL rdp_print_order_capability_set(wLog* log,
wStream* s)
719 BYTE terminalDescriptor[16];
720 UINT32 pad4OctetsA = 0;
721 UINT16 desktopSaveXGranularity = 0;
722 UINT16 desktopSaveYGranularity = 0;
723 UINT16 pad2OctetsA = 0;
724 UINT16 maximumOrderLevel = 0;
725 UINT16 numberFonts = 0;
726 UINT16 orderFlags = 0;
727 BYTE orderSupport[32];
728 UINT16 textFlags = 0;
729 UINT16 orderSupportExFlags = 0;
730 UINT32 pad4OctetsB = 0;
731 UINT32 desktopSaveSize = 0;
732 UINT16 pad2OctetsC = 0;
733 UINT16 pad2OctetsD = 0;
734 UINT16 textANSICodePage = 0;
735 UINT16 pad2OctetsE = 0;
736 WLog_Print(log, WLOG_TRACE,
737 "OrderCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
739 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 84))
742 Stream_Read(s, terminalDescriptor, 16);
743 Stream_Read_UINT32(s, pad4OctetsA);
744 Stream_Read_UINT16(s, desktopSaveXGranularity);
745 Stream_Read_UINT16(s, desktopSaveYGranularity);
746 Stream_Read_UINT16(s, pad2OctetsA);
747 Stream_Read_UINT16(s, maximumOrderLevel);
748 Stream_Read_UINT16(s, numberFonts);
749 Stream_Read_UINT16(s, orderFlags);
750 Stream_Read(s, orderSupport, 32);
751 Stream_Read_UINT16(s, textFlags);
752 Stream_Read_UINT16(s, orderSupportExFlags);
753 Stream_Read_UINT32(s, pad4OctetsB);
754 Stream_Read_UINT32(s, desktopSaveSize);
755 Stream_Read_UINT16(s, pad2OctetsC);
756 Stream_Read_UINT16(s, pad2OctetsD);
757 Stream_Read_UINT16(s, textANSICodePage);
758 Stream_Read_UINT16(s, pad2OctetsE);
759 WLog_Print(log, WLOG_TRACE,
"\tpad4OctetsA: 0x%08" PRIX32
"", pad4OctetsA);
760 WLog_Print(log, WLOG_TRACE,
"\tdesktopSaveXGranularity: 0x%04" PRIX16
"",
761 desktopSaveXGranularity);
762 WLog_Print(log, WLOG_TRACE,
"\tdesktopSaveYGranularity: 0x%04" PRIX16
"",
763 desktopSaveYGranularity);
764 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
765 WLog_Print(log, WLOG_TRACE,
"\tmaximumOrderLevel: 0x%04" PRIX16
"", maximumOrderLevel);
766 WLog_Print(log, WLOG_TRACE,
"\tnumberFonts: 0x%04" PRIX16
"", numberFonts);
767 WLog_Print(log, WLOG_TRACE,
"\torderFlags: 0x%04" PRIX16
"", orderFlags);
768 WLog_Print(log, WLOG_TRACE,
"\torderSupport:");
769 WLog_Print(log, WLOG_TRACE,
"\t\tDSTBLT: %" PRIu8
"", orderSupport[NEG_DSTBLT_INDEX]);
770 WLog_Print(log, WLOG_TRACE,
"\t\tPATBLT: %" PRIu8
"", orderSupport[NEG_PATBLT_INDEX]);
771 WLog_Print(log, WLOG_TRACE,
"\t\tSCRBLT: %" PRIu8
"", orderSupport[NEG_SCRBLT_INDEX]);
772 WLog_Print(log, WLOG_TRACE,
"\t\tMEMBLT: %" PRIu8
"", orderSupport[NEG_MEMBLT_INDEX]);
773 WLog_Print(log, WLOG_TRACE,
"\t\tMEM3BLT: %" PRIu8
"", orderSupport[NEG_MEM3BLT_INDEX]);
774 WLog_Print(log, WLOG_TRACE,
"\t\tATEXTOUT: %" PRIu8
"", orderSupport[NEG_ATEXTOUT_INDEX]);
775 WLog_Print(log, WLOG_TRACE,
"\t\tAEXTTEXTOUT: %" PRIu8
"", orderSupport[NEG_AEXTTEXTOUT_INDEX]);
776 WLog_Print(log, WLOG_TRACE,
"\t\tDRAWNINEGRID: %" PRIu8
"",
777 orderSupport[NEG_DRAWNINEGRID_INDEX]);
778 WLog_Print(log, WLOG_TRACE,
"\t\tLINETO: %" PRIu8
"", orderSupport[NEG_LINETO_INDEX]);
779 WLog_Print(log, WLOG_TRACE,
"\t\tMULTI_DRAWNINEGRID: %" PRIu8
"",
780 orderSupport[NEG_MULTI_DRAWNINEGRID_INDEX]);
781 WLog_Print(log, WLOG_TRACE,
"\t\tOPAQUE_RECT: %" PRIu8
"", orderSupport[NEG_OPAQUE_RECT_INDEX]);
782 WLog_Print(log, WLOG_TRACE,
"\t\tSAVEBITMAP: %" PRIu8
"", orderSupport[NEG_SAVEBITMAP_INDEX]);
783 WLog_Print(log, WLOG_TRACE,
"\t\tWTEXTOUT: %" PRIu8
"", orderSupport[NEG_WTEXTOUT_INDEX]);
784 WLog_Print(log, WLOG_TRACE,
"\t\tMEMBLT_V2: %" PRIu8
"", orderSupport[NEG_MEMBLT_V2_INDEX]);
785 WLog_Print(log, WLOG_TRACE,
"\t\tMEM3BLT_V2: %" PRIu8
"", orderSupport[NEG_MEM3BLT_V2_INDEX]);
786 WLog_Print(log, WLOG_TRACE,
"\t\tMULTIDSTBLT: %" PRIu8
"", orderSupport[NEG_MULTIDSTBLT_INDEX]);
787 WLog_Print(log, WLOG_TRACE,
"\t\tMULTIPATBLT: %" PRIu8
"", orderSupport[NEG_MULTIPATBLT_INDEX]);
788 WLog_Print(log, WLOG_TRACE,
"\t\tMULTISCRBLT: %" PRIu8
"", orderSupport[NEG_MULTISCRBLT_INDEX]);
789 WLog_Print(log, WLOG_TRACE,
"\t\tMULTIOPAQUERECT: %" PRIu8
"",
790 orderSupport[NEG_MULTIOPAQUERECT_INDEX]);
791 WLog_Print(log, WLOG_TRACE,
"\t\tFAST_INDEX: %" PRIu8
"", orderSupport[NEG_FAST_INDEX_INDEX]);
792 WLog_Print(log, WLOG_TRACE,
"\t\tPOLYGON_SC: %" PRIu8
"", orderSupport[NEG_POLYGON_SC_INDEX]);
793 WLog_Print(log, WLOG_TRACE,
"\t\tPOLYGON_CB: %" PRIu8
"", orderSupport[NEG_POLYGON_CB_INDEX]);
794 WLog_Print(log, WLOG_TRACE,
"\t\tPOLYLINE: %" PRIu8
"", orderSupport[NEG_POLYLINE_INDEX]);
795 WLog_Print(log, WLOG_TRACE,
"\t\tUNUSED23: %" PRIu8
"", orderSupport[NEG_UNUSED23_INDEX]);
796 WLog_Print(log, WLOG_TRACE,
"\t\tFAST_GLYPH: %" PRIu8
"", orderSupport[NEG_FAST_GLYPH_INDEX]);
797 WLog_Print(log, WLOG_TRACE,
"\t\tELLIPSE_SC: %" PRIu8
"", orderSupport[NEG_ELLIPSE_SC_INDEX]);
798 WLog_Print(log, WLOG_TRACE,
"\t\tELLIPSE_CB: %" PRIu8
"", orderSupport[NEG_ELLIPSE_CB_INDEX]);
799 WLog_Print(log, WLOG_TRACE,
"\t\tGLYPH_INDEX: %" PRIu8
"", orderSupport[NEG_GLYPH_INDEX_INDEX]);
800 WLog_Print(log, WLOG_TRACE,
"\t\tGLYPH_WEXTTEXTOUT: %" PRIu8
"",
801 orderSupport[NEG_GLYPH_WEXTTEXTOUT_INDEX]);
802 WLog_Print(log, WLOG_TRACE,
"\t\tGLYPH_WLONGTEXTOUT: %" PRIu8
"",
803 orderSupport[NEG_GLYPH_WLONGTEXTOUT_INDEX]);
804 WLog_Print(log, WLOG_TRACE,
"\t\tGLYPH_WLONGEXTTEXTOUT: %" PRIu8
"",
805 orderSupport[NEG_GLYPH_WLONGEXTTEXTOUT_INDEX]);
806 WLog_Print(log, WLOG_TRACE,
"\t\tUNUSED31: %" PRIu8
"", orderSupport[NEG_UNUSED31_INDEX]);
807 WLog_Print(log, WLOG_TRACE,
"\ttextFlags: 0x%04" PRIX16
"", textFlags);
808 WLog_Print(log, WLOG_TRACE,
"\torderSupportExFlags: 0x%04" PRIX16
"", orderSupportExFlags);
809 WLog_Print(log, WLOG_TRACE,
"\tpad4OctetsB: 0x%08" PRIX32
"", pad4OctetsB);
810 WLog_Print(log, WLOG_TRACE,
"\tdesktopSaveSize: 0x%08" PRIX32
"", desktopSaveSize);
811 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsC: 0x%04" PRIX16
"", pad2OctetsC);
812 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsD: 0x%04" PRIX16
"", pad2OctetsD);
813 WLog_Print(log, WLOG_TRACE,
"\ttextANSICodePage: 0x%04" PRIX16
"", textANSICodePage);
814 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsE: 0x%04" PRIX16
"", pad2OctetsE);
819static BOOL rdp_apply_bitmap_cache_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
820 WINPR_ATTR_UNUSED
const rdpSettings* src)
822 WINPR_ASSERT(settings);
832static BOOL rdp_read_bitmap_cache_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
834 WINPR_UNUSED(settings);
835 WINPR_ASSERT(settings);
837 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
840 Stream_Seek_UINT32(s);
841 Stream_Seek_UINT32(s);
842 Stream_Seek_UINT32(s);
843 Stream_Seek_UINT32(s);
844 Stream_Seek_UINT32(s);
845 Stream_Seek_UINT32(s);
846 Stream_Seek_UINT16(s);
847 Stream_Seek_UINT16(s);
848 Stream_Seek_UINT16(s);
849 Stream_Seek_UINT16(s);
850 Stream_Seek_UINT16(s);
851 Stream_Seek_UINT16(s);
860static BOOL rdp_write_bitmap_cache_capability_set(wLog* log,
wStream* s,
861 const rdpSettings* settings)
863 if (!Stream_EnsureRemainingCapacity(s, 64))
866 const size_t header = rdp_capability_set_start(log, s);
868 if (bpp > UINT16_MAX)
870 Stream_Write_UINT32(s, 0);
871 Stream_Write_UINT32(s, 0);
872 Stream_Write_UINT32(s, 0);
873 Stream_Write_UINT32(s, 0);
874 Stream_Write_UINT32(s, 0);
875 Stream_Write_UINT32(s, 0);
876 UINT32 size = bpp * 256;
877 if (size > UINT16_MAX)
879 Stream_Write_UINT16(s, 200);
880 Stream_Write_UINT16(s, (UINT16)size);
882 if (size > UINT16_MAX)
884 Stream_Write_UINT16(s, 600);
885 Stream_Write_UINT16(s, (UINT16)size);
887 if (size > UINT16_MAX)
889 Stream_Write_UINT16(s, 1000);
890 Stream_Write_UINT16(s, (UINT16)size);
891 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE);
894#ifdef WITH_DEBUG_CAPABILITIES
895static BOOL rdp_print_bitmap_cache_capability_set(wLog* log,
wStream* s)
903 UINT16 Cache0Entries = 0;
904 UINT16 Cache0MaximumCellSize = 0;
905 UINT16 Cache1Entries = 0;
906 UINT16 Cache1MaximumCellSize = 0;
907 UINT16 Cache2Entries = 0;
908 UINT16 Cache2MaximumCellSize = 0;
909 WLog_Print(log, WLOG_TRACE,
910 "BitmapCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
912 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
915 Stream_Read_UINT32(s, pad1);
916 Stream_Read_UINT32(s, pad2);
917 Stream_Read_UINT32(s, pad3);
918 Stream_Read_UINT32(s, pad4);
919 Stream_Read_UINT32(s, pad5);
920 Stream_Read_UINT32(s, pad6);
921 Stream_Read_UINT16(s, Cache0Entries);
922 Stream_Read_UINT16(s, Cache0MaximumCellSize);
923 Stream_Read_UINT16(s, Cache1Entries);
924 Stream_Read_UINT16(s, Cache1MaximumCellSize);
925 Stream_Read_UINT16(s, Cache2Entries);
926 Stream_Read_UINT16(s, Cache2MaximumCellSize);
927 WLog_Print(log, WLOG_TRACE,
"\tpad1: 0x%08" PRIX32
"", pad1);
928 WLog_Print(log, WLOG_TRACE,
"\tpad2: 0x%08" PRIX32
"", pad2);
929 WLog_Print(log, WLOG_TRACE,
"\tpad3: 0x%08" PRIX32
"", pad3);
930 WLog_Print(log, WLOG_TRACE,
"\tpad4: 0x%08" PRIX32
"", pad4);
931 WLog_Print(log, WLOG_TRACE,
"\tpad5: 0x%08" PRIX32
"", pad5);
932 WLog_Print(log, WLOG_TRACE,
"\tpad6: 0x%08" PRIX32
"", pad6);
933 WLog_Print(log, WLOG_TRACE,
"\tCache0Entries: 0x%04" PRIX16
"", Cache0Entries);
934 WLog_Print(log, WLOG_TRACE,
"\tCache0MaximumCellSize: 0x%04" PRIX16
"", Cache0MaximumCellSize);
935 WLog_Print(log, WLOG_TRACE,
"\tCache1Entries: 0x%04" PRIX16
"", Cache1Entries);
936 WLog_Print(log, WLOG_TRACE,
"\tCache1MaximumCellSize: 0x%04" PRIX16
"", Cache1MaximumCellSize);
937 WLog_Print(log, WLOG_TRACE,
"\tCache2Entries: 0x%04" PRIX16
"", Cache2Entries);
938 WLog_Print(log, WLOG_TRACE,
"\tCache2MaximumCellSize: 0x%04" PRIX16
"", Cache2MaximumCellSize);
943static BOOL rdp_apply_control_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
944 WINPR_ATTR_UNUSED
const rdpSettings* src)
946 WINPR_ASSERT(settings);
957static BOOL rdp_read_control_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
959 WINPR_UNUSED(settings);
960 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
963 Stream_Seek_UINT16(s);
964 Stream_Seek_UINT16(s);
965 Stream_Seek_UINT16(s);
966 Stream_Seek_UINT16(s);
975static BOOL rdp_write_control_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
977 WINPR_UNUSED(settings);
978 if (!Stream_EnsureRemainingCapacity(s, 32))
981 const size_t header = rdp_capability_set_start(log, s);
982 Stream_Write_UINT16(s, 0);
983 Stream_Write_UINT16(s, 0);
984 Stream_Write_UINT16(s, 2);
985 Stream_Write_UINT16(s, 2);
986 return rdp_capability_set_finish(s, header, CAPSET_TYPE_CONTROL);
989#ifdef WITH_DEBUG_CAPABILITIES
990static BOOL rdp_print_control_capability_set(wLog* log,
wStream* s)
992 UINT16 controlFlags = 0;
993 UINT16 remoteDetachFlag = 0;
994 UINT16 controlInterest = 0;
995 UINT16 detachInterest = 0;
996 WLog_Print(log, WLOG_TRACE,
997 "ControlCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
999 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1002 Stream_Read_UINT16(s, controlFlags);
1003 Stream_Read_UINT16(s, remoteDetachFlag);
1004 Stream_Read_UINT16(s, controlInterest);
1005 Stream_Read_UINT16(s, detachInterest);
1006 WLog_Print(log, WLOG_TRACE,
"\tcontrolFlags: 0x%04" PRIX16
"", controlFlags);
1007 WLog_Print(log, WLOG_TRACE,
"\tremoteDetachFlag: 0x%04" PRIX16
"", remoteDetachFlag);
1008 WLog_Print(log, WLOG_TRACE,
"\tcontrolInterest: 0x%04" PRIX16
"", controlInterest);
1009 WLog_Print(log, WLOG_TRACE,
"\tdetachInterest: 0x%04" PRIX16
"", detachInterest);
1014static BOOL rdp_apply_window_activation_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
1015 WINPR_ATTR_UNUSED
const rdpSettings* src)
1017 WINPR_ASSERT(settings);
1028static BOOL rdp_read_window_activation_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1030 WINPR_UNUSED(settings);
1031 WINPR_ASSERT(settings);
1032 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1035 Stream_Seek_UINT16(s);
1036 Stream_Seek_UINT16(s);
1037 Stream_Seek_UINT16(s);
1038 Stream_Seek_UINT16(s);
1047static BOOL rdp_write_window_activation_capability_set(wLog* log,
wStream* s,
1048 const rdpSettings* settings)
1050 WINPR_UNUSED(settings);
1051 WINPR_ASSERT(settings);
1052 if (!Stream_EnsureRemainingCapacity(s, 32))
1055 const size_t header = rdp_capability_set_start(log, s);
1056 Stream_Write_UINT16(s, 0);
1057 Stream_Write_UINT16(s, 0);
1058 Stream_Write_UINT16(s, 0);
1059 Stream_Write_UINT16(s, 0);
1060 return rdp_capability_set_finish(s, header, CAPSET_TYPE_ACTIVATION);
1063#ifdef WITH_DEBUG_CAPABILITIES
1064static BOOL rdp_print_window_activation_capability_set(wLog* log,
wStream* s)
1066 UINT16 helpKeyFlag = 0;
1067 UINT16 helpKeyIndexFlag = 0;
1068 UINT16 helpExtendedKeyFlag = 0;
1069 UINT16 windowManagerKeyFlag = 0;
1070 WLog_Print(log, WLOG_TRACE,
1071 "WindowActivationCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1073 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1076 Stream_Read_UINT16(s, helpKeyFlag);
1077 Stream_Read_UINT16(s, helpKeyIndexFlag);
1078 Stream_Read_UINT16(s, helpExtendedKeyFlag);
1079 Stream_Read_UINT16(s, windowManagerKeyFlag);
1080 WLog_Print(log, WLOG_TRACE,
"\thelpKeyFlag: 0x%04" PRIX16
"", helpKeyFlag);
1081 WLog_Print(log, WLOG_TRACE,
"\thelpKeyIndexFlag: 0x%04" PRIX16
"", helpKeyIndexFlag);
1082 WLog_Print(log, WLOG_TRACE,
"\thelpExtendedKeyFlag: 0x%04" PRIX16
"", helpExtendedKeyFlag);
1083 WLog_Print(log, WLOG_TRACE,
"\twindowManagerKeyFlag: 0x%04" PRIX16
"", windowManagerKeyFlag);
1088static BOOL rdp_apply_pointer_capability_set(rdpSettings* settings,
const rdpSettings* src)
1090 WINPR_ASSERT(settings);
1094 const UINT32 colorPointerCacheSize =
1096 const UINT32 dstPointerCacheSize =
1098 const UINT32 dstColorPointerCacheSize =
1102 const UINT32 actualPointerCacheSize = MIN(pointerCacheSize, dstPointerCacheSize);
1103 const UINT32 actualColorPointerCacheSize = MIN(colorPointerCacheSize, dstColorPointerCacheSize);
1107 actualColorPointerCacheSize))
1118static BOOL rdp_read_pointer_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1120 UINT16 colorPointerFlag = 0;
1121 UINT16 colorPointerCacheSize = 0;
1122 UINT16 pointerCacheSize = 0;
1124 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1127 Stream_Read_UINT16(s, colorPointerFlag);
1128 Stream_Read_UINT16(s, colorPointerCacheSize);
1130 if (colorPointerFlag == 0)
1132 WLog_Print(log, WLOG_WARN,
1133 "[MS-RDPBCGR] 2.2.7.1.5 Pointer Capability Set "
1134 "(TS_POINTER_CAPABILITYSET)::colorPointerFlag received is %" PRIu16
1135 ". Value is ignored and always assumed to be TRUE");
1139 if (Stream_GetRemainingLength(s) >= 2)
1140 Stream_Read_UINT16(s, pointerCacheSize);
1142 WINPR_ASSERT(settings);
1143 settings->PointerCacheSize = pointerCacheSize;
1144 settings->ColorPointerCacheSize = colorPointerCacheSize;
1154static BOOL rdp_write_pointer_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1156 if (!Stream_EnsureRemainingCapacity(s, 32))
1159 const size_t header = rdp_capability_set_start(log, s);
1160 if (settings->PointerCacheSize > UINT16_MAX)
1162 if (settings->ColorPointerCacheSize > UINT16_MAX)
1165 WINPR_ASSERT(settings);
1166 const UINT32 colorPointerFlag =
1169 Stream_Write_UINT16(s, colorPointerFlag);
1170 Stream_Write_UINT16(
1171 s, (UINT16)settings->ColorPointerCacheSize);
1172 Stream_Write_UINT16(s, (UINT16)settings->PointerCacheSize);
1174 return rdp_capability_set_finish(s, header, CAPSET_TYPE_POINTER);
1177#ifdef WITH_DEBUG_CAPABILITIES
1178static BOOL rdp_print_pointer_capability_set(wLog* log,
wStream* s)
1180 UINT16 colorPointerFlag = 0;
1181 UINT16 colorPointerCacheSize = 0;
1182 UINT16 pointerCacheSize = 0;
1184 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 6))
1187 WLog_Print(log, WLOG_TRACE,
1188 "PointerCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1189 Stream_Read_UINT16(s, colorPointerFlag);
1190 Stream_Read_UINT16(s, colorPointerCacheSize);
1191 Stream_Read_UINT16(s, pointerCacheSize);
1192 WLog_Print(log, WLOG_TRACE,
"\tcolorPointerFlag: 0x%04" PRIX16
"", colorPointerFlag);
1193 WLog_Print(log, WLOG_TRACE,
"\tcolorPointerCacheSize: 0x%04" PRIX16
"", colorPointerCacheSize);
1194 WLog_Print(log, WLOG_TRACE,
"\tpointerCacheSize: 0x%04" PRIX16
"", pointerCacheSize);
1199static BOOL rdp_apply_share_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
1200 WINPR_ATTR_UNUSED
const rdpSettings* src)
1202 WINPR_ASSERT(settings);
1213static BOOL rdp_read_share_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1215 WINPR_UNUSED(settings);
1216 WINPR_ASSERT(settings);
1218 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1221 Stream_Seek_UINT16(s);
1222 Stream_Seek_UINT16(s);
1231static BOOL rdp_write_share_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1233 if (!Stream_EnsureRemainingCapacity(s, 32))
1236 const size_t header = rdp_capability_set_start(log, s);
1238 WINPR_ASSERT(settings);
1239 const UINT16 nodeId = (settings->ServerMode) ? 0x03EA : 0;
1240 Stream_Write_UINT16(s, nodeId);
1241 Stream_Write_UINT16(s, 0);
1242 return rdp_capability_set_finish(s, header, CAPSET_TYPE_SHARE);
1245#ifdef WITH_DEBUG_CAPABILITIES
1246static BOOL rdp_print_share_capability_set(wLog* log,
wStream* s)
1249 UINT16 pad2Octets = 0;
1250 WLog_Print(log, WLOG_TRACE,
1251 "ShareCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1253 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1256 Stream_Read_UINT16(s, nodeId);
1257 Stream_Read_UINT16(s, pad2Octets);
1258 WLog_Print(log, WLOG_TRACE,
"\tnodeId: 0x%04" PRIX16
"", nodeId);
1259 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1264static BOOL rdp_apply_color_cache_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
1265 WINPR_ATTR_UNUSED
const rdpSettings* src)
1267 WINPR_ASSERT(settings);
1277static BOOL rdp_read_color_cache_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1279 WINPR_UNUSED(settings);
1280 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1283 Stream_Seek_UINT16(s);
1284 Stream_Seek_UINT16(s);
1293static BOOL rdp_write_color_cache_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1295 WINPR_UNUSED(settings);
1296 if (!Stream_EnsureRemainingCapacity(s, 32))
1299 const size_t header = rdp_capability_set_start(log, s);
1300 Stream_Write_UINT16(s, 6);
1301 Stream_Write_UINT16(s, 0);
1302 return rdp_capability_set_finish(s, header, CAPSET_TYPE_COLOR_CACHE);
1305#ifdef WITH_DEBUG_CAPABILITIES
1306static BOOL rdp_print_color_cache_capability_set(wLog* log,
wStream* s)
1308 UINT16 colorTableCacheSize = 0;
1309 UINT16 pad2Octets = 0;
1310 WLog_Print(log, WLOG_TRACE,
1311 "ColorCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1313 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1316 Stream_Read_UINT16(s, colorTableCacheSize);
1317 Stream_Read_UINT16(s, pad2Octets);
1318 WLog_Print(log, WLOG_TRACE,
"\tcolorTableCacheSize: 0x%04" PRIX16
"", colorTableCacheSize);
1319 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1324static BOOL rdp_apply_sound_capability_set(rdpSettings* settings,
const rdpSettings* src)
1326 WINPR_ASSERT(settings);
1329 settings->SoundBeepsEnabled = src->SoundBeepsEnabled;
1339static BOOL rdp_read_sound_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1341 UINT16 soundFlags = 0;
1343 WINPR_ASSERT(settings);
1344 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1347 Stream_Read_UINT16(s, soundFlags);
1348 Stream_Seek_UINT16(s);
1349 settings->SoundBeepsEnabled = (soundFlags & SOUND_BEEPS_FLAG) ? TRUE : FALSE;
1358static BOOL rdp_write_sound_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1360 WINPR_ASSERT(settings);
1361 if (!Stream_EnsureRemainingCapacity(s, 32))
1364 const size_t header = rdp_capability_set_start(log, s);
1365 const UINT16 soundFlags = (settings->SoundBeepsEnabled) ? SOUND_BEEPS_FLAG : 0;
1366 Stream_Write_UINT16(s, soundFlags);
1367 Stream_Write_UINT16(s, 0);
1368 return rdp_capability_set_finish(s, header, CAPSET_TYPE_SOUND);
1371#ifdef WITH_DEBUG_CAPABILITIES
1372static BOOL rdp_print_sound_capability_set(wLog* log,
wStream* s)
1374 UINT16 soundFlags = 0;
1375 UINT16 pad2OctetsA = 0;
1376 WLog_Print(log, WLOG_TRACE,
1377 "SoundCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1379 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1382 Stream_Read_UINT16(s, soundFlags);
1383 Stream_Read_UINT16(s, pad2OctetsA);
1384 WLog_Print(log, WLOG_TRACE,
"\tsoundFlags: 0x%04" PRIX16
"", soundFlags);
1385 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
1390static BOOL rdp_apply_input_capability_set(rdpSettings* settings,
const rdpSettings* src)
1392 WINPR_ASSERT(settings);
1395 if (settings->ServerMode)
1397 settings->KeyboardLayout = src->KeyboardLayout;
1398 settings->KeyboardType = src->KeyboardType;
1399 settings->KeyboardSubType = src->KeyboardSubType;
1400 settings->KeyboardFunctionKey = src->KeyboardFunctionKey;
1406 if (!settings->ServerMode)
1408 settings->FastPathInput = src->FastPathInput;
1414 if (settings->HasHorizontalWheel)
1415 settings->HasHorizontalWheel = src->HasHorizontalWheel;
1423 if (settings->HasExtendedMouseEvent)
1424 settings->HasExtendedMouseEvent = src->HasExtendedMouseEvent;
1425 if (settings->HasRelativeMouseEvent)
1426 settings->HasRelativeMouseEvent = src->HasRelativeMouseEvent;
1438static BOOL rdp_read_input_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1440 UINT16 inputFlags = 0;
1442 WINPR_ASSERT(settings);
1443 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 84))
1446 Stream_Read_UINT16(s, inputFlags);
1447 Stream_Seek_UINT16(s);
1449 Stream_Read_UINT32(s, settings->KeyboardLayout);
1450 Stream_Read_UINT32(s, settings->KeyboardType);
1451 Stream_Read_UINT32(s, settings->KeyboardSubType);
1452 Stream_Read_UINT32(s, settings->KeyboardFunctionKey);
1455 WCHAR wstr[32] = { 0 };
1456 char str[65] = { 0 };
1462 if (!Stream_Read_UTF16_String(s, wstr, ARRAYSIZE(wstr)))
1465 if (ConvertWCharNToUtf8(wstr, ARRAYSIZE(wstr), str, ARRAYSIZE(str)) < 0)
1466 memset(str, 0,
sizeof(str));
1474 (INPUT_FLAG_FASTPATH_INPUT | INPUT_FLAG_FASTPATH_INPUT2)))
1477 (inputFlags & TS_INPUT_FLAG_MOUSE_HWHEEL) ? TRUE : FALSE))
1480 (inputFlags & INPUT_FLAG_UNICODE) ? TRUE : FALSE))
1483 (inputFlags & INPUT_FLAG_MOUSE_RELATIVE) ? TRUE : FALSE))
1486 (inputFlags & INPUT_FLAG_MOUSEX) ? TRUE : FALSE))
1489 (inputFlags & TS_INPUT_FLAG_QOE_TIMESTAMPS) ? TRUE : FALSE))
1500static BOOL rdp_write_input_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1502 WINPR_ASSERT(settings);
1503 if (!Stream_EnsureRemainingCapacity(s, 128))
1506 const size_t header = rdp_capability_set_start(log, s);
1507 UINT16 inputFlags = INPUT_FLAG_SCANCODES;
1509 if (settings->FastPathInput)
1511 inputFlags |= INPUT_FLAG_FASTPATH_INPUT;
1512 inputFlags |= INPUT_FLAG_FASTPATH_INPUT2;
1516 inputFlags |= INPUT_FLAG_MOUSE_RELATIVE;
1519 inputFlags |= TS_INPUT_FLAG_MOUSE_HWHEEL;
1522 inputFlags |= INPUT_FLAG_UNICODE;
1525 inputFlags |= TS_INPUT_FLAG_QOE_TIMESTAMPS;
1527 if (settings->HasExtendedMouseEvent)
1528 inputFlags |= INPUT_FLAG_MOUSEX;
1530 Stream_Write_UINT16(s, inputFlags);
1531 Stream_Write_UINT16(s, 0);
1532 Stream_Write_UINT32(s, settings->KeyboardLayout);
1533 Stream_Write_UINT32(s, settings->KeyboardType);
1534 Stream_Write_UINT32(s, settings->KeyboardSubType);
1535 Stream_Write_UINT32(s, settings->KeyboardFunctionKey);
1537 return rdp_capability_set_finish(s, header, CAPSET_TYPE_INPUT);
1540#ifdef WITH_DEBUG_CAPABILITIES
1541static BOOL rdp_print_input_capability_set(wLog* log,
wStream* s)
1543 UINT16 inputFlags = 0;
1544 UINT16 pad2OctetsA = 0;
1545 UINT32 keyboardLayout = 0;
1546 UINT32 keyboardType = 0;
1547 UINT32 keyboardSubType = 0;
1548 UINT32 keyboardFunctionKey = 0;
1549 WLog_Print(log, WLOG_TRACE,
"InputCapabilitySet (length %" PRIuz
")",
1550 Stream_GetRemainingLength(s));
1552 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 84))
1555 Stream_Read_UINT16(s, inputFlags);
1556 Stream_Read_UINT16(s, pad2OctetsA);
1557 Stream_Read_UINT32(s, keyboardLayout);
1558 Stream_Read_UINT32(s, keyboardType);
1559 Stream_Read_UINT32(s, keyboardSubType);
1560 Stream_Read_UINT32(s, keyboardFunctionKey);
1562 WLog_Print(log, WLOG_TRACE,
"\tinputFlags: 0x%04" PRIX16
"", inputFlags);
1563 WLog_Print(log, WLOG_TRACE,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
1564 WLog_Print(log, WLOG_TRACE,
"\tkeyboardLayout: 0x%08" PRIX32
"", keyboardLayout);
1565 WLog_Print(log, WLOG_TRACE,
"\tkeyboardType: 0x%08" PRIX32
"", keyboardType);
1566 WLog_Print(log, WLOG_TRACE,
"\tkeyboardSubType: 0x%08" PRIX32
"", keyboardSubType);
1567 WLog_Print(log, WLOG_TRACE,
"\tkeyboardFunctionKey: 0x%08" PRIX32
"", keyboardFunctionKey);
1572static BOOL rdp_apply_font_capability_set(WINPR_ATTR_UNUSED rdpSettings* settings,
1573 WINPR_ATTR_UNUSED
const rdpSettings* src)
1575 WINPR_ASSERT(settings);
1585static BOOL rdp_read_font_capability_set(WINPR_ATTR_UNUSED wLog* log,
wStream* s,
1586 rdpSettings* settings)
1588 WINPR_UNUSED(settings);
1589 if (Stream_GetRemainingLength(s) >= 2)
1590 Stream_Seek_UINT16(s);
1592 if (Stream_GetRemainingLength(s) >= 2)
1593 Stream_Seek_UINT16(s);
1603static BOOL rdp_write_font_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1605 WINPR_UNUSED(settings);
1606 if (!Stream_EnsureRemainingCapacity(s, 32))
1609 const size_t header = rdp_capability_set_start(log, s);
1610 Stream_Write_UINT16(s, FONTSUPPORT_FONTLIST);
1611 Stream_Write_UINT16(s, 0);
1612 return rdp_capability_set_finish(s, header, CAPSET_TYPE_FONT);
1615#ifdef WITH_DEBUG_CAPABILITIES
1616static BOOL rdp_print_font_capability_set(wLog* log,
wStream* s)
1618 UINT16 fontSupportFlags = 0;
1619 UINT16 pad2Octets = 0;
1620 WLog_Print(log, WLOG_TRACE,
1621 "FontCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1623 if (Stream_GetRemainingLength(s) >= 2)
1624 Stream_Read_UINT16(s, fontSupportFlags);
1626 if (Stream_GetRemainingLength(s) >= 2)
1627 Stream_Read_UINT16(s, pad2Octets);
1629 WLog_Print(log, WLOG_TRACE,
"\tfontSupportFlags: 0x%04" PRIX16
"", fontSupportFlags);
1630 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1635static BOOL rdp_apply_brush_capability_set(rdpSettings* settings,
const rdpSettings* src)
1637 WINPR_ASSERT(settings);
1641 settings->BrushSupportLevel = src->BrushSupportLevel;
1650static BOOL rdp_read_brush_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1652 WINPR_UNUSED(settings);
1653 WINPR_ASSERT(settings);
1655 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1657 Stream_Read_UINT32(s, settings->BrushSupportLevel);
1666static BOOL rdp_write_brush_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1668 WINPR_ASSERT(settings);
1669 if (!Stream_EnsureRemainingCapacity(s, 32))
1672 const size_t header = rdp_capability_set_start(log, s);
1673 Stream_Write_UINT32(s, settings->BrushSupportLevel);
1674 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BRUSH);
1677#ifdef WITH_DEBUG_CAPABILITIES
1678static BOOL rdp_print_brush_capability_set(wLog* log,
wStream* s)
1680 UINT32 brushSupportLevel = 0;
1681 WLog_Print(log, WLOG_TRACE,
1682 "BrushCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1684 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1687 Stream_Read_UINT32(s, brushSupportLevel);
1688 WLog_Print(log, WLOG_TRACE,
"\tbrushSupportLevel: 0x%08" PRIX32
"", brushSupportLevel);
1699 WINPR_ASSERT(cache_definition);
1700 Stream_Read_UINT16(s, cache_definition->cacheEntries);
1701 Stream_Read_UINT16(s,
1702 cache_definition->cacheMaximumCellSize);
1711 WINPR_ASSERT(cache_definition);
1712 Stream_Write_UINT16(s, cache_definition->cacheEntries);
1713 Stream_Write_UINT16(
1714 s, cache_definition->cacheMaximumCellSize);
1717static BOOL rdp_apply_glyph_cache_capability_set(rdpSettings* settings,
const rdpSettings* src)
1719 WINPR_ASSERT(settings);
1722 WINPR_ASSERT(src->GlyphCache);
1723 WINPR_ASSERT(settings->GlyphCache);
1724 for (
size_t x = 0; x < 10; x++)
1725 settings->GlyphCache[x] = src->GlyphCache[x];
1727 WINPR_ASSERT(src->FragCache);
1728 WINPR_ASSERT(settings->FragCache);
1729 settings->FragCache[0] = src->FragCache[0];
1730 settings->GlyphSupportLevel = src->GlyphSupportLevel;
1740static BOOL rdp_read_glyph_cache_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
1742 WINPR_ASSERT(settings);
1743 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 48))
1747 for (
size_t x = 0; x < 10; x++)
1748 rdp_read_cache_definition(s, &(settings->GlyphCache[x]));
1749 rdp_read_cache_definition(s, settings->FragCache);
1750 Stream_Read_UINT16(s, settings->GlyphSupportLevel);
1751 Stream_Seek_UINT16(s);
1760static BOOL rdp_write_glyph_cache_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
1762 WINPR_ASSERT(settings);
1763 if (!Stream_EnsureRemainingCapacity(s, 64))
1766 const size_t header = rdp_capability_set_start(log, s);
1767 if (settings->GlyphSupportLevel > UINT16_MAX)
1770 for (
size_t x = 0; x < 10; x++)
1771 rdp_write_cache_definition(s, &(settings->GlyphCache[x]));
1772 rdp_write_cache_definition(s, settings->FragCache);
1773 Stream_Write_UINT16(s, (UINT16)settings->GlyphSupportLevel);
1774 Stream_Write_UINT16(s, 0);
1775 return rdp_capability_set_finish(s, header, CAPSET_TYPE_GLYPH_CACHE);
1778#ifdef WITH_DEBUG_CAPABILITIES
1779static BOOL rdp_print_glyph_cache_capability_set(wLog* log,
wStream* s)
1783 UINT16 glyphSupportLevel = 0;
1784 UINT16 pad2Octets = 0;
1785 WLog_Print(log, WLOG_TRACE,
1786 "GlyphCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1788 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 48))
1792 rdp_read_cache_definition(s, &glyphCache[0]);
1793 rdp_read_cache_definition(s, &glyphCache[1]);
1794 rdp_read_cache_definition(s, &glyphCache[2]);
1795 rdp_read_cache_definition(s, &glyphCache[3]);
1796 rdp_read_cache_definition(s, &glyphCache[4]);
1797 rdp_read_cache_definition(s, &glyphCache[5]);
1798 rdp_read_cache_definition(s, &glyphCache[6]);
1799 rdp_read_cache_definition(s, &glyphCache[7]);
1800 rdp_read_cache_definition(s, &glyphCache[8]);
1801 rdp_read_cache_definition(s, &glyphCache[9]);
1802 rdp_read_cache_definition(s, &fragCache);
1803 Stream_Read_UINT16(s, glyphSupportLevel);
1804 Stream_Read_UINT16(s, pad2Octets);
1805 WLog_Print(log, WLOG_TRACE,
"\tglyphCache0: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1806 glyphCache[0].cacheEntries, glyphCache[0].cacheMaximumCellSize);
1807 WLog_Print(log, WLOG_TRACE,
"\tglyphCache1: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1808 glyphCache[1].cacheEntries, glyphCache[1].cacheMaximumCellSize);
1809 WLog_Print(log, WLOG_TRACE,
"\tglyphCache2: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1810 glyphCache[2].cacheEntries, glyphCache[2].cacheMaximumCellSize);
1811 WLog_Print(log, WLOG_TRACE,
"\tglyphCache3: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1812 glyphCache[3].cacheEntries, glyphCache[3].cacheMaximumCellSize);
1813 WLog_Print(log, WLOG_TRACE,
"\tglyphCache4: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1814 glyphCache[4].cacheEntries, glyphCache[4].cacheMaximumCellSize);
1815 WLog_Print(log, WLOG_TRACE,
"\tglyphCache5: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1816 glyphCache[5].cacheEntries, glyphCache[5].cacheMaximumCellSize);
1817 WLog_Print(log, WLOG_TRACE,
"\tglyphCache6: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1818 glyphCache[6].cacheEntries, glyphCache[6].cacheMaximumCellSize);
1819 WLog_Print(log, WLOG_TRACE,
"\tglyphCache7: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1820 glyphCache[7].cacheEntries, glyphCache[7].cacheMaximumCellSize);
1821 WLog_Print(log, WLOG_TRACE,
"\tglyphCache8: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1822 glyphCache[8].cacheEntries, glyphCache[8].cacheMaximumCellSize);
1823 WLog_Print(log, WLOG_TRACE,
"\tglyphCache9: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1824 glyphCache[9].cacheEntries, glyphCache[9].cacheMaximumCellSize);
1825 WLog_Print(log, WLOG_TRACE,
"\tfragCache: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1826 fragCache.cacheEntries, fragCache.cacheMaximumCellSize);
1827 WLog_Print(log, WLOG_TRACE,
"\tglyphSupportLevel: 0x%04" PRIX16
"", glyphSupportLevel);
1828 WLog_Print(log, WLOG_TRACE,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1833static BOOL rdp_apply_offscreen_bitmap_cache_capability_set(rdpSettings* settings,
1834 const rdpSettings* src)
1836 WINPR_ASSERT(settings);
1839 settings->OffscreenCacheSize = src->OffscreenCacheSize;
1840 settings->OffscreenCacheEntries = src->OffscreenCacheEntries;
1841 settings->OffscreenSupportLevel = src->OffscreenSupportLevel;
1851static BOOL rdp_read_offscreen_bitmap_cache_capability_set(wLog* log,
wStream* s,
1852 rdpSettings* settings)
1854 UINT32 offscreenSupportLevel = 0;
1856 WINPR_ASSERT(settings);
1857 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1860 Stream_Read_UINT32(s, offscreenSupportLevel);
1861 Stream_Read_UINT16(s, settings->OffscreenCacheSize);
1862 Stream_Read_UINT16(s, settings->OffscreenCacheEntries);
1864 settings->OffscreenSupportLevel = offscreenSupportLevel & 0x01;
1874static BOOL rdp_write_offscreen_bitmap_cache_capability_set(wLog* log,
wStream* s,
1875 const rdpSettings* settings)
1877 UINT32 offscreenSupportLevel = 0x00;
1879 WINPR_ASSERT(settings);
1880 if (!Stream_EnsureRemainingCapacity(s, 32))
1883 const size_t header = rdp_capability_set_start(log, s);
1884 if (settings->OffscreenSupportLevel)
1886 offscreenSupportLevel = 0x01;
1887 Stream_Write_UINT32(s, offscreenSupportLevel);
1888 Stream_Write_UINT16(
1889 s, WINPR_ASSERTING_INT_CAST(
1890 uint16_t, settings->OffscreenCacheSize));
1891 Stream_Write_UINT16(
1893 WINPR_ASSERTING_INT_CAST(
1894 uint16_t, settings->OffscreenCacheEntries));
1899 return rdp_capability_set_finish(s, header, CAPSET_TYPE_OFFSCREEN_CACHE);
1902#ifdef WITH_DEBUG_CAPABILITIES
1903static BOOL rdp_print_offscreen_bitmap_cache_capability_set(wLog* log,
wStream* s)
1905 UINT32 offscreenSupportLevel = 0;
1906 UINT16 offscreenCacheSize = 0;
1907 UINT16 offscreenCacheEntries = 0;
1908 WLog_Print(log, WLOG_TRACE,
"OffscreenBitmapCacheCapabilitySet (length %" PRIuz
"):",
1909 Stream_GetRemainingLength(s));
1911 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1914 Stream_Read_UINT32(s, offscreenSupportLevel);
1915 Stream_Read_UINT16(s, offscreenCacheSize);
1916 Stream_Read_UINT16(s, offscreenCacheEntries);
1917 WLog_Print(log, WLOG_TRACE,
"\toffscreenSupportLevel: 0x%08" PRIX32
"", offscreenSupportLevel);
1918 WLog_Print(log, WLOG_TRACE,
"\toffscreenCacheSize: 0x%04" PRIX16
"", offscreenCacheSize);
1919 WLog_Print(log, WLOG_TRACE,
"\toffscreenCacheEntries: 0x%04" PRIX16
"", offscreenCacheEntries);
1924static BOOL rdp_apply_bitmap_cache_host_support_capability_set(rdpSettings* settings,
1925 const rdpSettings* src)
1937static BOOL rdp_read_bitmap_cache_host_support_capability_set(wLog* log,
wStream* s,
1938 rdpSettings* settings)
1940 BYTE cacheVersion = 0;
1942 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1945 Stream_Read_UINT8(s, cacheVersion);
1946 Stream_Seek_UINT8(s);
1947 Stream_Seek_UINT16(s);
1950 cacheVersion & BITMAP_CACHE_V2);
1958static BOOL rdp_write_bitmap_cache_host_support_capability_set(wLog* log,
wStream* s,
1959 const rdpSettings* settings)
1961 UINT8 cacheVersion = 0;
1964 cacheVersion |= BITMAP_CACHE_V2;
1966 if (!Stream_EnsureRemainingCapacity(s, 32))
1969 const size_t header = rdp_capability_set_start(log, s);
1970 Stream_Write_UINT8(s, cacheVersion);
1971 Stream_Write_UINT8(s, 0);
1972 Stream_Write_UINT16(s, 0);
1973 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT);
1976#ifdef WITH_DEBUG_CAPABILITIES
1977static BOOL rdp_print_bitmap_cache_host_support_capability_set(wLog* log,
wStream* s)
1979 BYTE cacheVersion = 0;
1982 WLog_Print(log, WLOG_TRACE,
"BitmapCacheHostSupportCapabilitySet (length %" PRIuz
"):",
1983 Stream_GetRemainingLength(s));
1985 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1988 Stream_Read_UINT8(s, cacheVersion);
1989 Stream_Read_UINT8(s, pad1);
1990 Stream_Read_UINT16(s, pad2);
1991 WLog_Print(log, WLOG_TRACE,
"\tcacheVersion: 0x%02" PRIX8
"", cacheVersion);
1992 WLog_Print(log, WLOG_TRACE,
"\tpad1: 0x%02" PRIX8
"", pad1);
1993 WLog_Print(log, WLOG_TRACE,
"\tpad2: 0x%04" PRIX16
"", pad2);
1998static BOOL rdp_read_bitmap_cache_cell_info(wLog* log,
wStream* s,
2003 WINPR_ASSERT(cellInfo);
2004 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2011 Stream_Read_UINT32(s, info);
2012 cellInfo->numEntries = (info & 0x7FFFFFFF);
2013 cellInfo->persistent = (info & 0x80000000) ? 1 : 0;
2024 WINPR_ASSERT(cellInfo);
2025 info = (cellInfo->numEntries | (((UINT32)cellInfo->persistent << 31) & 0xFF000000));
2026 Stream_Write_UINT32(s, info);
2029static BOOL rdp_apply_bitmap_cache_v2_capability_set(rdpSettings* settings,
const rdpSettings* src)
2031 const FreeRDP_Settings_Keys_Bool keys[] = { FreeRDP_BitmapCacheEnabled,
2032 FreeRDP_BitmapCachePersistEnabled };
2034 for (
size_t x = 0; x < ARRAYSIZE(keys); x++)
2036 const FreeRDP_Settings_Keys_Bool
id = keys[x];
2043 const UINT32 BitmapCacheV2NumCells =
2046 BitmapCacheV2NumCells))
2049 for (
size_t x = 0; x < BitmapCacheV2NumCells; x++)
2052 freerdp_settings_get_pointer_array(src, FreeRDP_BitmapCacheV2CellInfo, x);
2053 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_BitmapCacheV2CellInfo, x,
2067static BOOL rdp_read_bitmap_cache_v2_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2069 UINT16 cacheFlags = 0;
2070 WINPR_UNUSED(settings);
2071 WINPR_ASSERT(settings);
2073 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
2076 Stream_Read_UINT16(s, cacheFlags);
2081 cacheFlags & PERSISTENT_KEYS_EXPECTED_FLAG))
2084 Stream_Seek_UINT8(s);
2085 Stream_Read_UINT8(s, settings->BitmapCacheV2NumCells);
2086 if (settings->BitmapCacheV2NumCells > 5)
2088 WLog_Print(log, WLOG_ERROR,
2089 "Invalid TS_BITMAPCACHE_CAPABILITYSET_REV2::numCellCaches %" PRIu32
" > 5",
2090 settings->BitmapCacheV2NumCells);
2094 for (
size_t x = 0; x < settings->BitmapCacheV2NumCells; x++)
2097 freerdp_settings_get_pointer_array_writable(settings, FreeRDP_BitmapCacheV2CellInfo, x);
2098 if (!rdp_read_bitmap_cache_cell_info(log, s, info))
2103 for (
size_t x = settings->BitmapCacheV2NumCells; x < 5; x++)
2105 if (!Stream_SafeSeek(s, 4))
2117static BOOL rdp_write_bitmap_cache_v2_capability_set(wLog* log,
wStream* s,
2118 const rdpSettings* settings)
2120 WINPR_ASSERT(settings);
2121 if (!Stream_EnsureRemainingCapacity(s, 64))
2124 const size_t header = rdp_capability_set_start(log, s);
2125 UINT16 cacheFlags = ALLOW_CACHE_WAITING_LIST_FLAG;
2129 cacheFlags |= PERSISTENT_KEYS_EXPECTED_FLAG;
2130 settings->BitmapCacheV2CellInfo[0].persistent = 1;
2131 settings->BitmapCacheV2CellInfo[1].persistent = 1;
2132 settings->BitmapCacheV2CellInfo[2].persistent = 1;
2133 settings->BitmapCacheV2CellInfo[3].persistent = 1;
2134 settings->BitmapCacheV2CellInfo[4].persistent = 1;
2137 Stream_Write_UINT16(s, cacheFlags);
2138 Stream_Write_UINT8(s, 0);
2140 s, WINPR_ASSERTING_INT_CAST(uint8_t,
2141 settings->BitmapCacheV2NumCells));
2142 rdp_write_bitmap_cache_cell_info(
2143 s, &settings->BitmapCacheV2CellInfo[0]);
2144 rdp_write_bitmap_cache_cell_info(
2145 s, &settings->BitmapCacheV2CellInfo[1]);
2146 rdp_write_bitmap_cache_cell_info(
2147 s, &settings->BitmapCacheV2CellInfo[2]);
2148 rdp_write_bitmap_cache_cell_info(
2149 s, &settings->BitmapCacheV2CellInfo[3]);
2150 rdp_write_bitmap_cache_cell_info(
2151 s, &settings->BitmapCacheV2CellInfo[4]);
2153 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_V2);
2156#ifdef WITH_DEBUG_CAPABILITIES
2157static BOOL rdp_print_bitmap_cache_v2_capability_set(wLog* log,
wStream* s)
2160 WLog_Print(log, WLOG_TRACE,
2161 "BitmapCacheV2CapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2163 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
2166 const UINT16 cacheFlags = Stream_Get_UINT16(s);
2167 const UINT8 pad2 = Stream_Get_UINT8(s);
2168 const UINT8 numCellCaches = Stream_Get_UINT8(s);
2170 for (
size_t x = 0; x < ARRAYSIZE(bitmapCacheV2CellInfo); x++)
2172 if (!rdp_read_bitmap_cache_cell_info(
2173 log, s, &bitmapCacheV2CellInfo[x]))
2177 if (!Stream_SafeSeek(s, 12))
2180 WLog_Print(log, WLOG_TRACE,
"\tcacheFlags: 0x%04" PRIX16
"", cacheFlags);
2181 WLog_Print(log, WLOG_TRACE,
"\tpad2: 0x%02" PRIX8
"", pad2);
2182 WLog_Print(log, WLOG_TRACE,
"\tnumCellCaches: 0x%02" PRIX8
"", numCellCaches);
2183 for (
size_t x = 0; x < ARRAYSIZE(bitmapCacheV2CellInfo); x++)
2186 WLog_Print(log, WLOG_TRACE,
2187 "\tbitmapCache%" PRIuz
"CellInfo: numEntries: %" PRIu32
" persistent: %" PRId32
2189 x, info->numEntries, info->persistent);
2195static BOOL rdp_apply_virtual_channel_capability_set(rdpSettings* settings,
const rdpSettings* src)
2197 WINPR_ASSERT(settings);
2201 if (settings->ServerMode && (settings->VCFlags & VCCAPS_COMPR_SC) &&
2202 (src->VCFlags & VCCAPS_COMPR_SC))
2203 settings->VCFlags |= VCCAPS_COMPR_SC;
2205 settings->VCFlags &= (uint32_t)~VCCAPS_COMPR_SC;
2207 if (!settings->ServerMode && (settings->VCFlags & VCCAPS_COMPR_CS_8K) &&
2208 (src->VCFlags & VCCAPS_COMPR_CS_8K))
2209 settings->VCFlags |= VCCAPS_COMPR_CS_8K;
2211 settings->VCFlags &= (uint32_t)~VCCAPS_COMPR_CS_8K;
2218 if (!settings->ServerMode)
2220 if ((src->VCChunkSize > CHANNEL_CHUNK_MAX_LENGTH) || (src->VCChunkSize == 0))
2221 settings->VCChunkSize = CHANNEL_CHUNK_LENGTH;
2224 settings->VCChunkSize = src->VCChunkSize;
2236static BOOL rdp_read_virtual_channel_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2239 UINT32 VCChunkSize = 0;
2241 WINPR_ASSERT(settings);
2242 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2245 Stream_Read_UINT32(s, flags);
2247 if (Stream_GetRemainingLength(s) >= 4)
2248 Stream_Read_UINT32(s, VCChunkSize);
2250 VCChunkSize = UINT32_MAX;
2252 settings->VCFlags = flags;
2253 settings->VCChunkSize = VCChunkSize;
2263static BOOL rdp_write_virtual_channel_capability_set(wLog* log,
wStream* s,
2264 const rdpSettings* settings)
2266 WINPR_ASSERT(settings);
2267 if (!Stream_EnsureRemainingCapacity(s, 32))
2270 const size_t header = rdp_capability_set_start(log, s);
2271 Stream_Write_UINT32(s, settings->VCFlags);
2272 Stream_Write_UINT32(s, settings->VCChunkSize);
2273 return rdp_capability_set_finish(s, header, CAPSET_TYPE_VIRTUAL_CHANNEL);
2276#ifdef WITH_DEBUG_CAPABILITIES
2277static BOOL rdp_print_virtual_channel_capability_set(wLog* log,
wStream* s)
2280 UINT32 VCChunkSize = 0;
2281 WLog_Print(log, WLOG_TRACE,
2282 "VirtualChannelCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2284 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2287 Stream_Read_UINT32(s, flags);
2289 if (Stream_GetRemainingLength(s) >= 4)
2290 Stream_Read_UINT32(s, VCChunkSize);
2294 WLog_Print(log, WLOG_TRACE,
"\tflags: 0x%08" PRIX32
"", flags);
2295 WLog_Print(log, WLOG_TRACE,
"\tVCChunkSize: 0x%08" PRIX32
"", VCChunkSize);
2300static BOOL rdp_apply_draw_nine_grid_cache_capability_set(rdpSettings* settings,
2301 const rdpSettings* src)
2303 WINPR_ASSERT(settings);
2306 settings->DrawNineGridCacheSize = src->DrawNineGridCacheSize;
2307 settings->DrawNineGridCacheEntries = src->DrawNineGridCacheEntries;
2308 settings->DrawNineGridEnabled = src->DrawNineGridEnabled;
2318static BOOL rdp_read_draw_nine_grid_cache_capability_set(wLog* log,
wStream* s,
2319 rdpSettings* settings)
2321 UINT32 drawNineGridSupportLevel = 0;
2323 WINPR_ASSERT(settings);
2324 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
2327 Stream_Read_UINT32(s, drawNineGridSupportLevel);
2328 Stream_Read_UINT16(s, settings->DrawNineGridCacheSize);
2329 Stream_Read_UINT16(s,
2330 settings->DrawNineGridCacheEntries);
2332 settings->DrawNineGridEnabled =
2333 (drawNineGridSupportLevel & (DRAW_NINEGRID_SUPPORTED | DRAW_NINEGRID_SUPPORTED_V2)) ? TRUE
2344static BOOL rdp_write_draw_nine_grid_cache_capability_set(wLog* log,
wStream* s,
2345 const rdpSettings* settings)
2347 WINPR_ASSERT(settings);
2348 if (!Stream_EnsureRemainingCapacity(s, 32))
2351 const size_t header = rdp_capability_set_start(log, s);
2352 const UINT32 drawNineGridSupportLevel =
2353 (settings->DrawNineGridEnabled) ? DRAW_NINEGRID_SUPPORTED_V2 : DRAW_NINEGRID_NO_SUPPORT;
2354 Stream_Write_UINT32(s, drawNineGridSupportLevel);
2355 Stream_Write_UINT16(
2356 s, WINPR_ASSERTING_INT_CAST(
2357 uint16_t, settings->DrawNineGridCacheSize));
2358 Stream_Write_UINT16(
2360 WINPR_ASSERTING_INT_CAST(
2361 uint16_t, settings->DrawNineGridCacheEntries));
2362 return rdp_capability_set_finish(s, header, CAPSET_TYPE_DRAW_NINE_GRID_CACHE);
2365#ifdef WITH_DEBUG_CAPABILITIES
2366static BOOL rdp_print_draw_nine_grid_cache_capability_set(wLog* log,
wStream* s)
2368 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
2371 const uint32_t drawNineGridSupportLevel =
2372 Stream_Get_UINT32(s);
2373 const uint32_t DrawNineGridCacheSize =
2374 Stream_Get_UINT16(s);
2375 const uint32_t DrawNineGridCacheEntries =
2376 Stream_Get_UINT16(s);
2378 WLog_Print(log, WLOG_TRACE,
2379 "DrawNineGridCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2380 WLog_Print(log, WLOG_TRACE,
"drawNineGridSupportLevel=0x%08" PRIx32, drawNineGridSupportLevel);
2381 WLog_Print(log, WLOG_TRACE,
"DrawNineGridCacheSize=0x%08" PRIx32, DrawNineGridCacheSize);
2382 WLog_Print(log, WLOG_TRACE,
"DrawNineGridCacheEntries=0x%08" PRIx32, DrawNineGridCacheEntries);
2387static BOOL rdp_apply_draw_gdiplus_cache_capability_set(rdpSettings* settings,
2388 const rdpSettings* src)
2390 WINPR_ASSERT(settings);
2393 if (src->DrawGdiPlusEnabled)
2394 settings->DrawGdiPlusEnabled = TRUE;
2396 if (src->DrawGdiPlusCacheEnabled)
2397 settings->DrawGdiPlusCacheEnabled = TRUE;
2407static BOOL rdp_read_draw_gdiplus_cache_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2409 UINT32 drawGDIPlusSupportLevel = 0;
2410 UINT32 drawGdiplusCacheLevel = 0;
2412 WINPR_ASSERT(settings);
2413 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
2416 Stream_Read_UINT32(s, drawGDIPlusSupportLevel);
2417 Stream_Seek_UINT32(s);
2418 Stream_Read_UINT32(s, drawGdiplusCacheLevel);
2423 settings->DrawGdiPlusEnabled =
2424 (drawGDIPlusSupportLevel & DRAW_GDIPLUS_SUPPORTED) ? TRUE : FALSE;
2425 settings->DrawGdiPlusCacheEnabled =
2426 (drawGdiplusCacheLevel & DRAW_GDIPLUS_CACHE_LEVEL_ONE) ? TRUE : FALSE;
2431#ifdef WITH_DEBUG_CAPABILITIES
2432static BOOL rdp_print_draw_gdiplus_cache_capability_set(wLog* log,
wStream* s)
2434 WLog_Print(log, WLOG_TRACE,
2435 "DrawGdiPlusCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2437 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 36))
2440 const uint32_t drawGdiPlusSupportLevel =
2441 Stream_Get_UINT32(s);
2442 const uint32_t GdipVersion = Stream_Get_UINT32(s);
2443 const uint32_t drawGdiplusCacheLevel =
2444 Stream_Get_UINT32(s);
2445 WLog_Print(log, WLOG_TRACE,
2446 "drawGdiPlusSupportLevel=0x%08" PRIx32
", GdipVersion=0x%08" PRIx32
2447 ", drawGdiplusdrawGdiplusCacheLevelCacheLevel=0x%08" PRIx32,
2448 drawGdiPlusSupportLevel, GdipVersion, drawGdiplusCacheLevel);
2450 const uint16_t GdipGraphicsCacheEntries = Stream_Get_UINT16(s);
2451 const uint16_t GdipBrushCacheEntries = Stream_Get_UINT16(s);
2452 const uint16_t GdipPenCacheEntries = Stream_Get_UINT16(s);
2453 const uint16_t GdipImageCacheEntries = Stream_Get_UINT16(s);
2454 const uint16_t GdipImageAttributesCacheEntries = Stream_Get_UINT16(s);
2455 WLog_Print(log, WLOG_TRACE,
2456 "GdipGraphicsCacheEntries=0x%04" PRIx16
", GdipBrushCacheEntries=0x%04" PRIx16
2457 ", GdipPenCacheEntries=0x%04" PRIx16
", GdipImageCacheEntries=0x%04" PRIx16
2458 ", GdipImageAttributesCacheEntries=0x%04" PRIx16,
2459 GdipGraphicsCacheEntries, GdipBrushCacheEntries, GdipPenCacheEntries,
2460 GdipImageCacheEntries, GdipImageAttributesCacheEntries);
2462 const uint16_t GdipGraphicsCacheChunkSize = Stream_Get_UINT16(s);
2463 const uint16_t GdipObjectBrushCacheChunkSize = Stream_Get_UINT16(s);
2464 const uint16_t GdipObjectPenCacheChunkSize = Stream_Get_UINT16(s);
2465 const uint16_t GdipObjectImageAttributesCacheChunkSize = Stream_Get_UINT16(s);
2466 WLog_Print(log, WLOG_TRACE,
2467 "GdipGraphicsCacheChunkSize=0x%04" PRIx16
2468 ", GdipObjectBrushCacheChunkSize=0x%04" PRIx16
2469 ", GdipObjectPenCacheChunkSize=0x%04" PRIx16
2470 ",GdipObjectImageAttributesCacheChunkSize=0x%04" PRIx16,
2471 GdipGraphicsCacheChunkSize, GdipObjectBrushCacheChunkSize,
2472 GdipObjectPenCacheChunkSize, GdipObjectImageAttributesCacheChunkSize);
2474 const uint16_t GdipObjectImageCacheChunkSize = Stream_Get_UINT16(s);
2475 const uint16_t GdipObjectImageCacheTotalSize = Stream_Get_UINT16(s);
2476 const uint16_t GdipObjectImageCacheMaxSize = Stream_Get_UINT16(s);
2479 "GdipObjectImageCacheChunkSize=0x%04" PRIx16
", GdipObjectImageCacheTotalSize=0x%04" PRIx16
2480 ", GdipObjectImageCacheMaxSize=0x%04" PRIx16,
2481 GdipObjectImageCacheChunkSize, GdipObjectImageCacheTotalSize, GdipObjectImageCacheMaxSize);
2486static BOOL rdp_apply_remote_programs_capability_set(rdpSettings* settings,
const rdpSettings* src)
2488 WINPR_ASSERT(settings);
2491 if (settings->RemoteApplicationMode)
2492 settings->RemoteApplicationMode = src->RemoteApplicationMode;
2497 UINT32 supportLevel = src->RemoteApplicationSupportLevel;
2498 if (settings->RemoteApplicationMode)
2499 supportLevel |= RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED;
2501 settings->RemoteApplicationSupportLevel = supportLevel & settings->RemoteApplicationSupportMask;
2511static BOOL rdp_read_remote_programs_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2513 UINT32 railSupportLevel = 0;
2515 WINPR_ASSERT(settings);
2516 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2519 Stream_Read_UINT32(s, railSupportLevel);
2521 settings->RemoteApplicationMode = (railSupportLevel & RAIL_LEVEL_SUPPORTED) ? TRUE : FALSE;
2522 settings->RemoteApplicationSupportLevel = railSupportLevel;
2531static BOOL rdp_write_remote_programs_capability_set(wLog* log,
wStream* s,
2532 const rdpSettings* settings)
2534 WINPR_ASSERT(settings);
2535 if (!Stream_EnsureRemainingCapacity(s, 64))
2538 const size_t header = rdp_capability_set_start(log, s);
2539 UINT32 railSupportLevel = RAIL_LEVEL_SUPPORTED;
2541 if (settings->RemoteApplicationSupportLevel & RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED)
2543 if (settings->RemoteAppLanguageBarSupported)
2544 railSupportLevel |= RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED;
2547 railSupportLevel |= RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED;
2548 railSupportLevel |= RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED;
2549 railSupportLevel |= RAIL_LEVEL_SERVER_TO_CLIENT_IME_SYNC_SUPPORTED;
2550 railSupportLevel |= RAIL_LEVEL_HIDE_MINIMIZED_APPS_SUPPORTED;
2551 railSupportLevel |= RAIL_LEVEL_WINDOW_CLOAKING_SUPPORTED;
2552 railSupportLevel |= RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED;
2554 railSupportLevel &= settings->RemoteApplicationSupportLevel;
2555 Stream_Write_UINT32(s, railSupportLevel);
2556 return rdp_capability_set_finish(s, header, CAPSET_TYPE_RAIL);
2559#ifdef WITH_DEBUG_CAPABILITIES
2560static BOOL rdp_print_remote_programs_capability_set(wLog* log,
wStream* s)
2562 UINT32 railSupportLevel = 0;
2563 WLog_Print(log, WLOG_TRACE,
2564 "RemoteProgramsCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2566 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2569 Stream_Read_UINT32(s, railSupportLevel);
2570 WLog_Print(log, WLOG_TRACE,
"\trailSupportLevel: 0x%08" PRIX32
"", railSupportLevel);
2575static BOOL rdp_apply_window_list_capability_set(rdpSettings* settings,
const rdpSettings* src)
2577 WINPR_ASSERT(settings);
2580 settings->RemoteWndSupportLevel = src->RemoteWndSupportLevel;
2581 settings->RemoteAppNumIconCaches = src->RemoteAppNumIconCaches;
2582 settings->RemoteAppNumIconCacheEntries = src->RemoteAppNumIconCacheEntries;
2592static BOOL rdp_read_window_list_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2594 WINPR_ASSERT(settings);
2595 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 7))
2598 Stream_Read_UINT32(s, settings->RemoteWndSupportLevel);
2599 Stream_Read_UINT8(s, settings->RemoteAppNumIconCaches);
2600 Stream_Read_UINT16(s,
2601 settings->RemoteAppNumIconCacheEntries);
2610static BOOL rdp_write_window_list_capability_set(wLog* log,
wStream* s,
const rdpSettings* settings)
2612 WINPR_ASSERT(settings);
2613 if (!Stream_EnsureRemainingCapacity(s, 32))
2616 const size_t header = rdp_capability_set_start(log, s);
2617 Stream_Write_UINT32(s, settings->RemoteWndSupportLevel);
2619 s, WINPR_ASSERTING_INT_CAST(uint8_t,
2620 settings->RemoteAppNumIconCaches));
2621 Stream_Write_UINT16(
2623 WINPR_ASSERTING_INT_CAST(
2624 uint16_t, settings->RemoteAppNumIconCacheEntries));
2625 return rdp_capability_set_finish(s, header, CAPSET_TYPE_WINDOW);
2628#ifdef WITH_DEBUG_CAPABILITIES
2629static BOOL rdp_print_window_list_capability_set(wLog* log,
wStream* s)
2631 UINT32 wndSupportLevel = 0;
2632 BYTE numIconCaches = 0;
2633 UINT16 numIconCacheEntries = 0;
2634 WLog_Print(log, WLOG_TRACE,
2635 "WindowListCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2637 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 7))
2640 Stream_Read_UINT32(s, wndSupportLevel);
2641 Stream_Read_UINT8(s, numIconCaches);
2642 Stream_Read_UINT16(s, numIconCacheEntries);
2643 WLog_Print(log, WLOG_TRACE,
"\twndSupportLevel: 0x%08" PRIX32
"", wndSupportLevel);
2644 WLog_Print(log, WLOG_TRACE,
"\tnumIconCaches: 0x%02" PRIX8
"", numIconCaches);
2645 WLog_Print(log, WLOG_TRACE,
"\tnumIconCacheEntries: 0x%04" PRIX16
"", numIconCacheEntries);
2650static BOOL rdp_apply_desktop_composition_capability_set(rdpSettings* settings,
2651 const rdpSettings* src)
2653 WINPR_ASSERT(settings);
2656 settings->CompDeskSupportLevel = src->CompDeskSupportLevel;
2665static BOOL rdp_read_desktop_composition_capability_set(wLog* log,
wStream* s,
2666 rdpSettings* settings)
2668 WINPR_UNUSED(settings);
2669 WINPR_ASSERT(settings);
2671 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 2))
2674 Stream_Read_UINT16(s, settings->CompDeskSupportLevel);
2683static BOOL rdp_write_desktop_composition_capability_set(wLog* log,
wStream* s,
2684 const rdpSettings* settings)
2686 WINPR_ASSERT(settings);
2688 if (!Stream_EnsureRemainingCapacity(s, 32))
2691 const size_t header = rdp_capability_set_start(log, s);
2692 const UINT16 compDeskSupportLevel =
2693 (settings->AllowDesktopComposition) ? COMPDESK_SUPPORTED : COMPDESK_NOT_SUPPORTED;
2694 Stream_Write_UINT16(s, compDeskSupportLevel);
2695 return rdp_capability_set_finish(s, header, CAPSET_TYPE_COMP_DESK);
2698#ifdef WITH_DEBUG_CAPABILITIES
2699static BOOL rdp_print_desktop_composition_capability_set(wLog* log,
wStream* s)
2701 UINT16 compDeskSupportLevel = 0;
2702 WLog_Print(log, WLOG_TRACE,
"DesktopCompositionCapabilitySet (length %" PRIuz
"):",
2703 Stream_GetRemainingLength(s));
2705 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 2))
2708 Stream_Read_UINT16(s, compDeskSupportLevel);
2709 WLog_Print(log, WLOG_TRACE,
"\tcompDeskSupportLevel: 0x%04" PRIX16
"", compDeskSupportLevel);
2714static BOOL rdp_apply_multifragment_update_capability_set(rdpSettings* settings,
2715 const rdpSettings* src)
2717 UINT32 multifragMaxRequestSize = 0;
2719 WINPR_ASSERT(settings);
2722 multifragMaxRequestSize = src->MultifragMaxRequestSize;
2724 if (settings->ServerMode)
2734 if (multifragMaxRequestSize < FASTPATH_MAX_PACKET_SIZE)
2735 multifragMaxRequestSize = FASTPATH_FRAGMENT_SAFE_SIZE;
2737 if (settings->RemoteFxCodec)
2744 if (multifragMaxRequestSize < settings->MultifragMaxRequestSize)
2750 settings->RemoteFxCodec = FALSE;
2751 settings->MultifragMaxRequestSize = multifragMaxRequestSize;
2760 settings->MultifragMaxRequestSize = multifragMaxRequestSize;
2770 if (multifragMaxRequestSize > settings->MultifragMaxRequestSize)
2771 settings->MultifragMaxRequestSize = multifragMaxRequestSize;
2781static BOOL rdp_read_multifragment_update_capability_set(wLog* log,
wStream* s,
2782 rdpSettings* settings)
2784 UINT32 multifragMaxRequestSize = 0;
2786 WINPR_ASSERT(settings);
2787 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2790 Stream_Read_UINT32(s, multifragMaxRequestSize);
2791 settings->MultifragMaxRequestSize = multifragMaxRequestSize;
2801static BOOL rdp_write_multifragment_update_capability_set(wLog* log,
wStream* s,
2802 rdpSettings* settings)
2804 WINPR_ASSERT(settings);
2805 if (settings->ServerMode && settings->MultifragMaxRequestSize == 0)
2818 UINT32 tileNumX = (settings->DesktopWidth + 63) / 64;
2819 UINT32 tileNumY = (settings->DesktopHeight + 63) / 64;
2820 settings->MultifragMaxRequestSize = tileNumX * tileNumY * 16384;
2822 settings->MultifragMaxRequestSize += 16384;
2825 if (!Stream_EnsureRemainingCapacity(s, 32))
2827 const size_t header = rdp_capability_set_start(log, s);
2828 Stream_Write_UINT32(s, settings->MultifragMaxRequestSize);
2829 return rdp_capability_set_finish(s, header, CAPSET_TYPE_MULTI_FRAGMENT_UPDATE);
2832#ifdef WITH_DEBUG_CAPABILITIES
2833static BOOL rdp_print_multifragment_update_capability_set(wLog* log,
wStream* s)
2835 UINT32 maxRequestSize = 0;
2836 WLog_Print(log, WLOG_TRACE,
"MultifragmentUpdateCapabilitySet (length %" PRIuz
"):",
2837 Stream_GetRemainingLength(s));
2839 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2842 Stream_Read_UINT32(s, maxRequestSize);
2843 WLog_Print(log, WLOG_TRACE,
"\tmaxRequestSize: 0x%08" PRIX32
"", maxRequestSize);
2848static BOOL rdp_apply_large_pointer_capability_set(rdpSettings* settings,
const rdpSettings* src)
2850 WINPR_ASSERT(settings);
2853 settings->LargePointerFlag = src->LargePointerFlag;
2862static BOOL rdp_read_large_pointer_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2864 UINT16 largePointerSupportFlags = 0;
2866 WINPR_ASSERT(settings);
2867 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 2))
2870 Stream_Read_UINT16(s, largePointerSupportFlags);
2871 settings->LargePointerFlag &= largePointerSupportFlags;
2872 if ((largePointerSupportFlags & ~(LARGE_POINTER_FLAG_96x96 | LARGE_POINTER_FLAG_384x384)) != 0)
2876 "TS_LARGE_POINTER_CAPABILITYSET with unsupported flags %04X (all flags %04X) received",
2877 largePointerSupportFlags & ~(LARGE_POINTER_FLAG_96x96 | LARGE_POINTER_FLAG_384x384),
2878 largePointerSupportFlags);
2888static BOOL rdp_write_large_pointer_capability_set(wLog* log,
wStream* s,
2889 const rdpSettings* settings)
2891 WINPR_ASSERT(settings);
2892 if (!Stream_EnsureRemainingCapacity(s, 32))
2895 const size_t header = rdp_capability_set_start(log, s);
2896 const UINT16 largePointerSupportFlags =
2897 settings->LargePointerFlag & (LARGE_POINTER_FLAG_96x96 | LARGE_POINTER_FLAG_384x384);
2898 Stream_Write_UINT16(s, largePointerSupportFlags);
2899 return rdp_capability_set_finish(s, header, CAPSET_TYPE_LARGE_POINTER);
2902#ifdef WITH_DEBUG_CAPABILITIES
2903static BOOL rdp_print_large_pointer_capability_set(wLog* log,
wStream* s)
2905 UINT16 largePointerSupportFlags = 0;
2906 WLog_Print(log, WLOG_TRACE,
2907 "LargePointerCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2909 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 2))
2912 Stream_Read_UINT16(s, largePointerSupportFlags);
2913 WLog_Print(log, WLOG_TRACE,
"\tlargePointerSupportFlags: 0x%04" PRIX16
"",
2914 largePointerSupportFlags);
2919static BOOL rdp_apply_surface_commands_capability_set(rdpSettings* settings,
const rdpSettings* src)
2921 WINPR_ASSERT(settings);
2928 if (src->FastPathOutput)
2930 settings->SurfaceCommandsSupported &= src->SurfaceCommandsSupported;
2931 settings->SurfaceCommandsEnabled = src->SurfaceCommandsEnabled;
2932 settings->SurfaceFrameMarkerEnabled = src->SurfaceFrameMarkerEnabled;
2936 settings->SurfaceCommandsSupported = 0;
2937 settings->SurfaceCommandsEnabled = FALSE;
2938 settings->SurfaceFrameMarkerEnabled = FALSE;
2949static BOOL rdp_read_surface_commands_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
2951 UINT32 cmdFlags = 0;
2953 WINPR_ASSERT(settings);
2954 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
2957 Stream_Read_UINT32(s, cmdFlags);
2958 Stream_Seek_UINT32(s);
2959 settings->SurfaceCommandsSupported = cmdFlags;
2960 settings->SurfaceCommandsEnabled =
2961 (cmdFlags & (SURFCMDS_SET_SURFACE_BITS | SURFCMDS_STREAM_SURFACE_BITS)) ? TRUE : FALSE;
2962 settings->SurfaceFrameMarkerEnabled = (cmdFlags & SURFCMDS_FRAME_MARKER) ? TRUE : FALSE;
2971static BOOL rdp_write_surface_commands_capability_set(wLog* log,
wStream* s,
2972 const rdpSettings* settings)
2974 WINPR_ASSERT(settings);
2975 if (!Stream_EnsureRemainingCapacity(s, 32))
2978 const size_t header = rdp_capability_set_start(log, s);
2982 if (settings->SurfaceFrameMarkerEnabled)
2983 cmdFlags |= SURFCMDS_FRAME_MARKER;
2985 Stream_Write_UINT32(s, cmdFlags);
2986 Stream_Write_UINT32(s, 0);
2987 return rdp_capability_set_finish(s, header, CAPSET_TYPE_SURFACE_COMMANDS);
2990static bool sUuidEqual(
const UUID* Uuid1,
const UUID* Uuid2)
2992 if (!Uuid1 && !Uuid2)
2995 if (Uuid1 && !Uuid2)
2998 if (!Uuid1 && Uuid2)
3001 if (Uuid1->Data1 != Uuid2->Data1)
3004 if (Uuid1->Data2 != Uuid2->Data2)
3007 if (Uuid1->Data3 != Uuid2->Data3)
3010 for (
int index = 0; index < 8; index++)
3012 if (Uuid1->Data4[index] != Uuid2->Data4[index])
3019#ifdef WITH_DEBUG_CAPABILITIES
3020static BOOL rdp_print_surface_commands_capability_set(wLog* log,
wStream* s)
3022 UINT32 cmdFlags = 0;
3023 UINT32 reserved = 0;
3025 WLog_Print(log, WLOG_TRACE,
3026 "SurfaceCommandsCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
3028 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
3031 Stream_Read_UINT32(s, cmdFlags);
3032 Stream_Read_UINT32(s, reserved);
3033 WLog_Print(log, WLOG_TRACE,
"\tcmdFlags: 0x%08" PRIX32
"", cmdFlags);
3034 WLog_Print(log, WLOG_TRACE,
"\treserved: 0x%08" PRIX32
"", reserved);
3038static void rdp_print_bitmap_codec_guid(wLog* log,
const GUID* guid)
3041 WLog_Print(log, WLOG_TRACE,
3042 "%08" PRIX32
"%04" PRIX16
"%04" PRIX16
"%02" PRIX8
"%02" PRIX8
"%02" PRIX8
3043 "%02" PRIX8
"%02" PRIX8
"%02" PRIX8
"%02" PRIX8
"%02" PRIX8
"",
3044 guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], guid->Data4[1],
3045 guid->Data4[2], guid->Data4[3], guid->Data4[4], guid->Data4[5], guid->Data4[6],
3049static char* rdp_get_bitmap_codec_guid_name(
const GUID* guid)
3052 if (sUuidEqual(guid, &CODEC_GUID_REMOTEFX))
3053 return "CODEC_GUID_REMOTEFX";
3054 else if (sUuidEqual(guid, &CODEC_GUID_NSCODEC))
3055 return "CODEC_GUID_NSCODEC";
3056 else if (sUuidEqual(guid, &CODEC_GUID_IGNORE))
3057 return "CODEC_GUID_IGNORE";
3058 else if (sUuidEqual(guid, &CODEC_GUID_IMAGE_REMOTEFX))
3059 return "CODEC_GUID_IMAGE_REMOTEFX";
3061#if defined(WITH_JPEG)
3062 else if (sUuidEqual(guid, &CODEC_GUID_JPEG))
3063 return "CODEC_GUID_JPEG";
3066 return "CODEC_GUID_UNKNOWN";
3070static BOOL rdp_read_bitmap_codec_guid(wLog* log,
wStream* s, GUID* guid)
3075 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 16))
3077 Stream_Read(s, g, 16);
3078 guid->Data1 = ((UINT32)g[3] << 24U) | ((UINT32)g[2] << 16U) | (UINT32)(g[1] << 8U) | g[0];
3079 guid->Data2 = ((g[5] << 8U) | g[4]) & 0xFFFF;
3080 guid->Data3 = ((g[7] << 8U) | g[6]) & 0xFFFF;
3081 guid->Data4[0] = g[8];
3082 guid->Data4[1] = g[9];
3083 guid->Data4[2] = g[10];
3084 guid->Data4[3] = g[11];
3085 guid->Data4[4] = g[12];
3086 guid->Data4[5] = g[13];
3087 guid->Data4[6] = g[14];
3088 guid->Data4[7] = g[15];
3092static void rdp_write_bitmap_codec_guid(
wStream* s,
const GUID* guid)
3096 g[0] = guid->Data1 & 0xFF;
3097 g[1] = (guid->Data1 >> 8) & 0xFF;
3098 g[2] = (guid->Data1 >> 16) & 0xFF;
3099 g[3] = (guid->Data1 >> 24) & 0xFF;
3100 g[4] = (guid->Data2) & 0xFF;
3101 g[5] = (guid->Data2 >> 8) & 0xFF;
3102 g[6] = (guid->Data3) & 0xFF;
3103 g[7] = (guid->Data3 >> 8) & 0xFF;
3104 g[8] = guid->Data4[0];
3105 g[9] = guid->Data4[1];
3106 g[10] = guid->Data4[2];
3107 g[11] = guid->Data4[3];
3108 g[12] = guid->Data4[4];
3109 g[13] = guid->Data4[5];
3110 g[14] = guid->Data4[6];
3111 g[15] = guid->Data4[7];
3112 Stream_Write(s, g, 16);
3115static BOOL rdp_apply_bitmap_codecs_capability_set(rdpSettings* settings,
const rdpSettings* src)
3117 WINPR_ASSERT(settings);
3120 if (settings->ServerMode)
3123 settings->RemoteFxCodecId = src->RemoteFxCodecId;
3124 settings->RemoteFxCaptureFlags = src->RemoteFxCaptureFlags;
3125 settings->RemoteFxOnly = src->RemoteFxOnly;
3126 settings->RemoteFxRlgrMode = src->RemoteFxRlgrMode;
3127 settings->RemoteFxCodecMode = src->RemoteFxCodecMode;
3128 settings->NSCodecId = src->NSCodecId;
3129 settings->NSCodecAllowDynamicColorFidelity = src->NSCodecAllowDynamicColorFidelity;
3130 settings->NSCodecAllowSubsampling = src->NSCodecAllowSubsampling;
3131 settings->NSCodecColorLossLevel = src->NSCodecColorLossLevel;
3134 settings->RemoteFxCodec = settings->RemoteFxCodec && src->RemoteFxCodecId;
3135 settings->RemoteFxImageCodec = settings->RemoteFxImageCodec && src->RemoteFxImageCodec;
3137 settings->NSCodec && src->NSCodec))
3139 settings->JpegCodec = src->JpegCodec;
3144static BOOL rdp_read_codec_ts_rfx_icap(wLog* log,
wStream* sub, rdpSettings* settings,
3148 UINT16 tileSize = 0;
3149 BYTE codecFlags = 0;
3150 BYTE colConvBits = 0;
3151 BYTE transformBits = 0;
3152 BYTE entropyBits = 0;
3156 WLog_Print(log, WLOG_ERROR,
3157 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP size %" PRIu16
3158 " unsupported, expecting size %" PRIu16
" not supported",
3163 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 8))
3166 Stream_Read_UINT16(sub, version);
3167 Stream_Read_UINT16(sub, tileSize);
3168 Stream_Read_UINT8(sub, codecFlags);
3169 Stream_Read_UINT8(sub, colConvBits);
3170 Stream_Read_UINT8(sub, transformBits);
3171 Stream_Read_UINT8(sub, entropyBits);
3173 if (version == 0x0009)
3176 if (tileSize != 0x0080)
3178 WLog_Print(log, WLOG_ERROR,
3179 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::version %" PRIu16
3180 " tile size %" PRIu16
" not supported",
3185 else if (version == 0x0100)
3188 if (tileSize != 0x0040)
3190 WLog_Print(log, WLOG_ERROR,
3191 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::version %" PRIu16
3192 " tile size %" PRIu16
" not supported",
3199 WLog_Print(log, WLOG_ERROR,
3200 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::version %" PRIu16
" not supported",
3206 if (colConvBits != 1)
3208 WLog_Print(log, WLOG_ERROR,
3209 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::colConvBits %" PRIu8
3210 " not supported, must be CLW_COL_CONV_ICT (0x1)",
3216 if (transformBits != 1)
3218 WLog_Print(log, WLOG_ERROR,
3219 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::transformBits %" PRIu8
3220 " not supported, must be CLW_XFORM_DWT_53_A (0x1)",
3225 const UINT8 CODEC_MODE = 0x02;
3229 if ((codecFlags & CODEC_MODE) != 0)
3234 else if ((codecFlags & ~CODEC_MODE) != 0)
3235 WLog_Print(log, WLOG_WARN,
3236 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::flags unknown value "
3238 (codecFlags & ~CODEC_MODE));
3240 switch (entropyBits)
3242 case CLW_ENTROPY_RLGR1:
3246 case CLW_ENTROPY_RLGR3:
3251 WLog_Print(log, WLOG_ERROR,
3252 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::entropyBits "
3253 "unsupported value 0x%02" PRIx8
3254 ", must be CLW_ENTROPY_RLGR1 (0x01) or CLW_ENTROPY_RLGR3 "
3262static BOOL rdp_read_codec_ts_rfx_capset(wLog* log,
wStream* s, rdpSettings* settings)
3264 UINT16 blockType = 0;
3265 UINT32 blockLen = 0;
3266 BYTE rfxCodecId = 0;
3267 UINT16 capsetType = 0;
3268 UINT16 numIcaps = 0;
3271 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 6))
3275 Stream_Read_UINT16(s, blockType);
3276 Stream_Read_UINT32(s, blockLen);
3277 if (blockType != 0xCBC1)
3279 WLog_Print(log, WLOG_ERROR,
3280 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::blockType[0x%04" PRIx16
3281 "] != CBY_CAPSET (0xCBC1)",
3285 if (blockLen < 6ull)
3287 WLog_Print(log, WLOG_ERROR,
3288 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::blockLen[%" PRIu16
"] < 6", blockLen);
3291 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, blockLen - 6ull))
3295 wStream* sub = Stream_StaticConstInit(&sbuffer, Stream_Pointer(s), blockLen - 6ull);
3298 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 7))
3301 Stream_Read_UINT8(sub, rfxCodecId);
3302 Stream_Read_UINT16(sub, capsetType);
3303 Stream_Read_UINT16(sub, numIcaps);
3304 Stream_Read_UINT16(sub, icapLen);
3306 if (rfxCodecId != 1)
3308 WLog_Print(log, WLOG_ERROR,
3309 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::codecId[%" PRIu16
"] != 1", rfxCodecId);
3313 if (capsetType != 0xCFC0)
3315 WLog_Print(log, WLOG_ERROR,
3316 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::capsetType[0x%04" PRIx16
3317 "] != CLY_CAPSET (0xCFC0)",
3324 if (!rdp_read_codec_ts_rfx_icap(log, sub, settings, icapLen))
3330static BOOL rdp_read_codec_ts_rfx_caps(wLog* log,
wStream* sub, rdpSettings* settings)
3332 if (Stream_GetRemainingLength(sub) == 0)
3335 UINT16 blockType = 0;
3336 UINT32 blockLen = 0;
3337 UINT16 numCapsets = 0;
3340 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 8))
3342 Stream_Read_UINT16(sub, blockType);
3343 Stream_Read_UINT32(sub, blockLen);
3344 Stream_Read_UINT16(sub, numCapsets);
3346 if (blockType != 0xCBC0)
3348 WLog_Print(log, WLOG_ERROR,
3349 "[MS_RDPRFX] 2.2.1.1.1 TS_RFX_CAPS::blockType[0x%04" PRIx16
3350 "] != CBY_CAPS (0xCBC0)",
3357 WLog_Print(log, WLOG_ERROR,
"[MS_RDPRFX] 2.2.1.1.1 TS_RFX_CAPS::blockLen[%" PRIu16
"] != 8",
3362 if (numCapsets != 1)
3364 WLog_Print(log, WLOG_ERROR,
3365 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::numIcaps[" PRIu16
"] != 1", numCapsets);
3369 for (UINT16 x = 0; x < numCapsets; x++)
3371 if (!rdp_read_codec_ts_rfx_capset(log, sub, settings))
3378static BOOL rdp_read_codec_ts_rfx_clnt_caps_container(wLog* log,
wStream* s, rdpSettings* settings)
3380 UINT32 rfxCapsLength = 0;
3381 UINT32 rfxPropsLength = 0;
3382 UINT32 captureFlags = 0;
3385 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
3387 Stream_Read_UINT32(s, rfxPropsLength);
3388 if (rfxPropsLength < 4)
3390 WLog_Print(log, WLOG_ERROR,
3391 "[MS_RDPRFX] 2.2.1.1 TS_RFX_CLNT_CAPS_CONTAINER::length %" PRIu32
3392 " too short, require at least 4 bytes",
3396 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, rfxPropsLength - 4ull))
3400 wStream* sub = Stream_StaticConstInit(&sbuffer, Stream_Pointer(s), rfxPropsLength - 4ull);
3403 Stream_Seek(s, rfxPropsLength - 4ull);
3405 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 8))
3408 Stream_Read_UINT32(sub, captureFlags);
3409 Stream_Read_UINT32(sub, rfxCapsLength);
3410 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, rfxCapsLength))
3413 settings->RemoteFxCaptureFlags = captureFlags;
3414 settings->RemoteFxOnly = (captureFlags & CARDP_CAPS_CAPTURE_NON_CAC) ? FALSE : TRUE;
3418 wStream* ts_sub = Stream_StaticConstInit(&tsbuffer, Stream_Pointer(sub), rfxCapsLength);
3419 WINPR_ASSERT(ts_sub);
3420 return rdp_read_codec_ts_rfx_caps(log, ts_sub, settings);
3428static BOOL rdp_read_bitmap_codecs_capability_set(wLog* log,
wStream* s, rdpSettings* settings,
3432 GUID codecGuid = { 0 };
3433 BYTE bitmapCodecCount = 0;
3434 UINT16 codecPropertiesLength = 0;
3436 BOOL guidNSCodec = FALSE;
3437 BOOL guidRemoteFx = FALSE;
3438 BOOL guidRemoteFxImage = FALSE;
3440 WINPR_ASSERT(settings);
3441 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 1))
3444 Stream_Read_UINT8(s, bitmapCodecCount);
3446 while (bitmapCodecCount > 0)
3450 if (!rdp_read_bitmap_codec_guid(log, s, &codecGuid))
3452 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 3))
3454 Stream_Read_UINT8(s, codecId);
3455 Stream_Read_UINT16(s, codecPropertiesLength);
3457 wStream* sub = Stream_StaticInit(&subbuffer, Stream_Pointer(s), codecPropertiesLength);
3458 if (!Stream_SafeSeek(s, codecPropertiesLength))
3463 if (sUuidEqual(&codecGuid, &CODEC_GUID_REMOTEFX))
3465 guidRemoteFx = TRUE;
3466 settings->RemoteFxCodecId = codecId;
3467 if (!rdp_read_codec_ts_rfx_clnt_caps_container(log, sub, settings))
3470 else if (sUuidEqual(&codecGuid, &CODEC_GUID_IMAGE_REMOTEFX))
3473 guidRemoteFxImage = TRUE;
3474 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3477 else if (sUuidEqual(&codecGuid, &CODEC_GUID_NSCODEC))
3479 BYTE colorLossLevel = 0;
3480 BYTE fAllowSubsampling = 0;
3481 BYTE fAllowDynamicFidelity = 0;
3483 settings->NSCodecId = codecId;
3484 if (!Stream_CheckAndLogRequiredLengthWLog(log, sub, 3))
3486 Stream_Read_UINT8(sub, fAllowDynamicFidelity);
3487 Stream_Read_UINT8(sub, fAllowSubsampling);
3488 Stream_Read_UINT8(sub, colorLossLevel);
3490 if (colorLossLevel < 1)
3493 if (colorLossLevel > 7)
3496 settings->NSCodecAllowDynamicColorFidelity = fAllowDynamicFidelity;
3497 settings->NSCodecAllowSubsampling = fAllowSubsampling;
3498 settings->NSCodecColorLossLevel = colorLossLevel;
3500 else if (sUuidEqual(&codecGuid, &CODEC_GUID_IGNORE))
3502 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3507 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3513 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3517 const size_t rest = Stream_GetRemainingLength(sub);
3520 WLog_Print(log, WLOG_ERROR,
3521 "error while reading codec properties: actual size: %" PRIuz
3522 " expected size: %" PRIu32
"",
3523 rest + codecPropertiesLength, codecPropertiesLength);
3544static BOOL rdp_write_rfx_client_capability_container(
wStream* s,
const rdpSettings* settings)
3546 WINPR_ASSERT(settings);
3547 if (!Stream_EnsureRemainingCapacity(s, 64))
3550 const UINT32 captureFlags = settings->RemoteFxOnly ? 0 : CARDP_CAPS_CAPTURE_NON_CAC;
3552 WINPR_ASSERT(settings->RemoteFxCodecMode <= UINT8_MAX);
3553 const UINT8 codecMode = (UINT8)settings->RemoteFxCodecMode;
3554 Stream_Write_UINT16(s, 49);
3556 Stream_Write_UINT32(s, 49);
3557 Stream_Write_UINT32(s, captureFlags);
3558 Stream_Write_UINT32(s, 37);
3560 Stream_Write_UINT16(s, CBY_CAPS);
3561 Stream_Write_UINT32(s, 8);
3562 Stream_Write_UINT16(s, 1);
3564 Stream_Write_UINT16(s, CBY_CAPSET);
3565 Stream_Write_UINT32(s, 29);
3566 Stream_Write_UINT8(s, 0x01);
3567 Stream_Write_UINT16(s, CLY_CAPSET);
3568 Stream_Write_UINT16(s, 2);
3569 Stream_Write_UINT16(s, 8);
3571 Stream_Write_UINT16(s, CLW_VERSION_1_0);
3572 Stream_Write_UINT16(s, CT_TILE_64x64);
3573 Stream_Write_UINT8(s, codecMode);
3574 Stream_Write_UINT8(s, CLW_COL_CONV_ICT);
3575 Stream_Write_UINT8(s, CLW_XFORM_DWT_53_A);
3576 Stream_Write_UINT8(s, CLW_ENTROPY_RLGR1);
3578 Stream_Write_UINT16(s, CLW_VERSION_1_0);
3579 Stream_Write_UINT16(s, CT_TILE_64x64);
3580 Stream_Write_UINT8(s, codecMode);
3581 Stream_Write_UINT8(s, CLW_COL_CONV_ICT);
3582 Stream_Write_UINT8(s, CLW_XFORM_DWT_53_A);
3583 Stream_Write_UINT8(s, CLW_ENTROPY_RLGR3);
3590static BOOL rdp_write_nsc_client_capability_container(
wStream* s,
const rdpSettings* settings)
3592 WINPR_ASSERT(settings);
3594 const BOOL fAllowDynamicFidelity = settings->NSCodecAllowDynamicColorFidelity;
3595 const BOOL fAllowSubsampling = settings->NSCodecAllowSubsampling;
3596 UINT32 colorLossLevel = settings->NSCodecColorLossLevel;
3598 if (colorLossLevel < 1)
3601 if (colorLossLevel > 7)
3604 if (!Stream_EnsureRemainingCapacity(s, 8))
3607 Stream_Write_UINT16(s, 3);
3609 Stream_Write_UINT8(s,
3610 fAllowDynamicFidelity ? TRUE : FALSE);
3611 Stream_Write_UINT8(s, fAllowSubsampling ? TRUE : FALSE);
3612 Stream_Write_UINT8(s, (UINT8)colorLossLevel);
3616#if defined(WITH_JPEG)
3617static BOOL rdp_write_jpeg_client_capability_container(
wStream* s,
const rdpSettings* settings)
3619 WINPR_ASSERT(settings);
3620 if (!Stream_EnsureRemainingCapacity(s, 8))
3623 Stream_Write_UINT16(s, 1);
3624 Stream_Write_UINT8(s, settings->JpegQuality);
3632static BOOL rdp_write_rfx_server_capability_container(
wStream* s,
const rdpSettings* settings)
3634 WINPR_UNUSED(settings);
3635 WINPR_ASSERT(settings);
3637 if (!Stream_EnsureRemainingCapacity(s, 8))
3640 Stream_Write_UINT16(s, 4);
3641 Stream_Write_UINT32(s, 0);
3645#if defined(WITH_JPEG)
3646static BOOL rdp_write_jpeg_server_capability_container(
wStream* s,
const rdpSettings* settings)
3648 WINPR_UNUSED(settings);
3649 WINPR_ASSERT(settings);
3651 if (!Stream_EnsureRemainingCapacity(s, 8))
3654 Stream_Write_UINT16(s, 1);
3655 Stream_Write_UINT8(s, 75);
3663static BOOL rdp_write_nsc_server_capability_container(
wStream* s,
const rdpSettings* settings)
3665 WINPR_UNUSED(settings);
3666 WINPR_ASSERT(settings);
3668 if (!Stream_EnsureRemainingCapacity(s, 8))
3671 Stream_Write_UINT16(s, 4);
3672 Stream_Write_UINT32(s, 0);
3681static BOOL rdp_write_bitmap_codecs_capability_set(wLog* log,
wStream* s,
3682 const rdpSettings* settings)
3684 WINPR_ASSERT(settings);
3685 if (!Stream_EnsureRemainingCapacity(s, 64))
3688 const size_t header = rdp_capability_set_start(log, s);
3689 BYTE bitmapCodecCount = 0;
3691 if (settings->RemoteFxCodec)
3697#if defined(WITH_JPEG)
3699 if (settings->JpegCodec)
3704 if (settings->RemoteFxImageCodec)
3707 Stream_Write_UINT8(s, bitmapCodecCount);
3709 if (settings->RemoteFxCodec)
3711 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_REMOTEFX);
3713 if (settings->ServerMode)
3715 Stream_Write_UINT8(s, 0);
3717 if (!rdp_write_rfx_server_capability_container(s, settings))
3722 Stream_Write_UINT8(s, RDP_CODEC_ID_REMOTEFX);
3724 if (!rdp_write_rfx_client_capability_container(s, settings))
3731 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_NSCODEC);
3733 if (settings->ServerMode)
3735 Stream_Write_UINT8(s, 0);
3737 if (!rdp_write_nsc_server_capability_container(s, settings))
3742 Stream_Write_UINT8(s, RDP_CODEC_ID_NSCODEC);
3744 if (!rdp_write_nsc_client_capability_container(s, settings))
3749#if defined(WITH_JPEG)
3751 if (settings->JpegCodec)
3753 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_JPEG);
3755 if (settings->ServerMode)
3757 Stream_Write_UINT8(s, 0);
3759 if (!rdp_write_jpeg_server_capability_container(s, settings))
3764 Stream_Write_UINT8(s, RDP_CODEC_ID_JPEG);
3766 if (!rdp_write_jpeg_client_capability_container(s, settings))
3773 if (settings->RemoteFxImageCodec)
3775 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_IMAGE_REMOTEFX);
3777 if (settings->ServerMode)
3779 Stream_Write_UINT8(s, 0);
3781 if (!rdp_write_rfx_server_capability_container(s, settings))
3786 Stream_Write_UINT8(s, RDP_CODEC_ID_IMAGE_REMOTEFX);
3788 if (!rdp_write_rfx_client_capability_container(s, settings))
3793 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CODECS);
3796#ifdef WITH_DEBUG_CAPABILITIES
3797static BOOL rdp_print_bitmap_codecs_capability_set(wLog* log,
wStream* s)
3799 GUID codecGuid = { 0 };
3800 BYTE bitmapCodecCount = 0;
3802 UINT16 codecPropertiesLength = 0;
3804 WLog_Print(log, WLOG_TRACE,
3805 "BitmapCodecsCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
3807 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 1))
3810 Stream_Read_UINT8(s, bitmapCodecCount);
3811 WLog_Print(log, WLOG_TRACE,
"\tbitmapCodecCount: %" PRIu8
"", bitmapCodecCount);
3813 while (bitmapCodecCount > 0)
3815 if (!rdp_read_bitmap_codec_guid(log, s, &codecGuid))
3817 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 3))
3819 Stream_Read_UINT8(s, codecId);
3820 WLog_Print(log, WLOG_TRACE,
"\tcodecGuid: 0x");
3821 rdp_print_bitmap_codec_guid(log, &codecGuid);
3822 WLog_Print(log, WLOG_TRACE,
" (%s)", rdp_get_bitmap_codec_guid_name(&codecGuid));
3823 WLog_Print(log, WLOG_TRACE,
"\tcodecId: %" PRIu8
"", codecId);
3824 Stream_Read_UINT16(s, codecPropertiesLength);
3825 WLog_Print(log, WLOG_TRACE,
"\tcodecPropertiesLength: %" PRIu16
"", codecPropertiesLength);
3827 if (!Stream_SafeSeek(s, codecPropertiesLength))
3836static BOOL rdp_apply_frame_acknowledge_capability_set(rdpSettings* settings,
3837 const rdpSettings* src)
3839 WINPR_ASSERT(settings);
3842 if (settings->ServerMode)
3843 settings->FrameAcknowledge = src->FrameAcknowledge;
3852static BOOL rdp_read_frame_acknowledge_capability_set(wLog* log,
wStream* s, rdpSettings* settings)
3854 WINPR_ASSERT(settings);
3855 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
3858 Stream_Read_UINT32(s, settings->FrameAcknowledge);
3867static BOOL rdp_write_frame_acknowledge_capability_set(wLog* log,
wStream* s,
3868 const rdpSettings* settings)
3870 WINPR_ASSERT(settings);
3871 if (!Stream_EnsureRemainingCapacity(s, 32))
3874 const size_t header = rdp_capability_set_start(log, s);
3875 Stream_Write_UINT32(s, settings->FrameAcknowledge);
3876 return rdp_capability_set_finish(s, header, CAPSET_TYPE_FRAME_ACKNOWLEDGE);
3879#ifdef WITH_DEBUG_CAPABILITIES
3880static BOOL rdp_print_frame_acknowledge_capability_set(wLog* log,
wStream* s)
3882 UINT32 frameAcknowledge = 0;
3883 WLog_Print(log, WLOG_TRACE,
3884 "FrameAcknowledgeCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
3886 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
3889 Stream_Read_UINT32(s, frameAcknowledge);
3890 WLog_Print(log, WLOG_TRACE,
"\tframeAcknowledge: 0x%08" PRIX32
"", frameAcknowledge);
3895static BOOL rdp_apply_bitmap_cache_v3_codec_id_capability_set(rdpSettings* settings,
3896 const rdpSettings* src)
3898 WINPR_ASSERT(settings);
3901 settings->BitmapCacheV3CodecId = src->BitmapCacheV3CodecId;
3905static BOOL rdp_read_bitmap_cache_v3_codec_id_capability_set(wLog* log,
wStream* s,
3906 rdpSettings* settings)
3908 BYTE bitmapCacheV3CodecId = 0;
3910 WINPR_ASSERT(settings);
3911 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 1))
3914 Stream_Read_UINT8(s, bitmapCacheV3CodecId);
3915 settings->BitmapCacheV3CodecId = bitmapCacheV3CodecId;
3919static BOOL rdp_write_bitmap_cache_v3_codec_id_capability_set(wLog* log,
wStream* s,
3920 const rdpSettings* settings)
3922 WINPR_ASSERT(settings);
3923 if (!Stream_EnsureRemainingCapacity(s, 32))
3926 const size_t header = rdp_capability_set_start(log, s);
3927 if (settings->BitmapCacheV3CodecId > UINT8_MAX)
3929 Stream_Write_UINT8(s, (UINT8)settings->BitmapCacheV3CodecId);
3930 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID);
3933#ifdef WITH_DEBUG_CAPABILITIES
3934static BOOL rdp_print_bitmap_cache_v3_codec_id_capability_set(wLog* log,
wStream* s)
3936 BYTE bitmapCacheV3CodecId = 0;
3937 WLog_Print(log, WLOG_TRACE,
"BitmapCacheV3CodecIdCapabilitySet (length %" PRIuz
"):",
3938 Stream_GetRemainingLength(s));
3940 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 1))
3943 Stream_Read_UINT8(s, bitmapCacheV3CodecId);
3944 WLog_Print(log, WLOG_TRACE,
"\tbitmapCacheV3CodecId: 0x%02" PRIX8
"", bitmapCacheV3CodecId);
3948BOOL rdp_print_capability_sets(wLog* log,
wStream* s,
size_t start, BOOL receiving)
3953 UINT16 numberCapabilities = 0;
3955 size_t pos = Stream_GetPosition(s);
3957 Stream_SetPosition(s, start);
3960 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
3965 if (!Stream_CheckAndLogRequiredCapacityWLog(log, (s), 4))
3969 Stream_Read_UINT16(s, numberCapabilities);
3972 while (numberCapabilities > 0)
3978 if (!rdp_read_capability_set_header(log, s, &length, &type))
3981 WLog_Print(log, WLOG_TRACE,
"%s ", receiving ?
"Receiving" :
"Sending");
3982 sub = Stream_StaticInit(&subBuffer, Stream_Pointer(s), length - 4);
3983 if (!Stream_SafeSeek(s, length - 4))
3988 case CAPSET_TYPE_GENERAL:
3989 if (!rdp_print_general_capability_set(log, sub))
3994 case CAPSET_TYPE_BITMAP:
3995 if (!rdp_print_bitmap_capability_set(log, sub))
4000 case CAPSET_TYPE_ORDER:
4001 if (!rdp_print_order_capability_set(log, sub))
4006 case CAPSET_TYPE_BITMAP_CACHE:
4007 if (!rdp_print_bitmap_cache_capability_set(log, sub))
4012 case CAPSET_TYPE_CONTROL:
4013 if (!rdp_print_control_capability_set(log, sub))
4018 case CAPSET_TYPE_ACTIVATION:
4019 if (!rdp_print_window_activation_capability_set(log, sub))
4024 case CAPSET_TYPE_POINTER:
4025 if (!rdp_print_pointer_capability_set(log, sub))
4030 case CAPSET_TYPE_SHARE:
4031 if (!rdp_print_share_capability_set(log, sub))
4036 case CAPSET_TYPE_COLOR_CACHE:
4037 if (!rdp_print_color_cache_capability_set(log, sub))
4042 case CAPSET_TYPE_SOUND:
4043 if (!rdp_print_sound_capability_set(log, sub))
4048 case CAPSET_TYPE_INPUT:
4049 if (!rdp_print_input_capability_set(log, sub))
4054 case CAPSET_TYPE_FONT:
4055 if (!rdp_print_font_capability_set(log, sub))
4060 case CAPSET_TYPE_BRUSH:
4061 if (!rdp_print_brush_capability_set(log, sub))
4066 case CAPSET_TYPE_GLYPH_CACHE:
4067 if (!rdp_print_glyph_cache_capability_set(log, sub))
4072 case CAPSET_TYPE_OFFSCREEN_CACHE:
4073 if (!rdp_print_offscreen_bitmap_cache_capability_set(log, sub))
4078 case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
4079 if (!rdp_print_bitmap_cache_host_support_capability_set(log, sub))
4084 case CAPSET_TYPE_BITMAP_CACHE_V2:
4085 if (!rdp_print_bitmap_cache_v2_capability_set(log, sub))
4090 case CAPSET_TYPE_VIRTUAL_CHANNEL:
4091 if (!rdp_print_virtual_channel_capability_set(log, sub))
4096 case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
4097 if (!rdp_print_draw_nine_grid_cache_capability_set(log, sub))
4102 case CAPSET_TYPE_DRAW_GDI_PLUS:
4103 if (!rdp_print_draw_gdiplus_cache_capability_set(log, sub))
4108 case CAPSET_TYPE_RAIL:
4109 if (!rdp_print_remote_programs_capability_set(log, sub))
4114 case CAPSET_TYPE_WINDOW:
4115 if (!rdp_print_window_list_capability_set(log, sub))
4120 case CAPSET_TYPE_COMP_DESK:
4121 if (!rdp_print_desktop_composition_capability_set(log, sub))
4126 case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
4127 if (!rdp_print_multifragment_update_capability_set(log, sub))
4132 case CAPSET_TYPE_LARGE_POINTER:
4133 if (!rdp_print_large_pointer_capability_set(log, sub))
4138 case CAPSET_TYPE_SURFACE_COMMANDS:
4139 if (!rdp_print_surface_commands_capability_set(log, sub))
4144 case CAPSET_TYPE_BITMAP_CODECS:
4145 if (!rdp_print_bitmap_codecs_capability_set(log, sub))
4150 case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
4151 if (!rdp_print_frame_acknowledge_capability_set(log, sub))
4156 case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID:
4157 if (!rdp_print_bitmap_cache_v3_codec_id_capability_set(log, sub))
4163 WLog_Print(log, WLOG_ERROR,
"unknown capability type %" PRIu16
"", type);
4167 rest = Stream_GetRemainingLength(sub);
4170 WLog_Print(log, WLOG_WARN,
4171 "incorrect capability offset, type:0x%04" PRIX16
" %" PRIu16
4172 " bytes expected, %" PRIuz
"bytes remaining",
4173 type, length, rest);
4176 numberCapabilities--;
4181 Stream_SetPosition(s, pos);
4186static BOOL rdp_apply_from_received(UINT16 type, rdpSettings* dst,
const rdpSettings* src)
4190 case CAPSET_TYPE_GENERAL:
4191 return rdp_apply_general_capability_set(dst, src);
4192 case CAPSET_TYPE_BITMAP:
4193 return rdp_apply_bitmap_capability_set(dst, src);
4194 case CAPSET_TYPE_ORDER:
4195 return rdp_apply_order_capability_set(dst, src);
4196 case CAPSET_TYPE_POINTER:
4197 return rdp_apply_pointer_capability_set(dst, src);
4198 case CAPSET_TYPE_INPUT:
4199 return rdp_apply_input_capability_set(dst, src);
4200 case CAPSET_TYPE_VIRTUAL_CHANNEL:
4201 return rdp_apply_virtual_channel_capability_set(dst, src);
4202 case CAPSET_TYPE_SHARE:
4203 return rdp_apply_share_capability_set(dst, src);
4204 case CAPSET_TYPE_COLOR_CACHE:
4205 return rdp_apply_color_cache_capability_set(dst, src);
4206 case CAPSET_TYPE_FONT:
4207 return rdp_apply_font_capability_set(dst, src);
4208 case CAPSET_TYPE_DRAW_GDI_PLUS:
4209 return rdp_apply_draw_gdiplus_cache_capability_set(dst, src);
4210 case CAPSET_TYPE_RAIL:
4211 return rdp_apply_remote_programs_capability_set(dst, src);
4212 case CAPSET_TYPE_WINDOW:
4213 return rdp_apply_window_list_capability_set(dst, src);
4214 case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
4215 return rdp_apply_multifragment_update_capability_set(dst, src);
4216 case CAPSET_TYPE_LARGE_POINTER:
4217 return rdp_apply_large_pointer_capability_set(dst, src);
4218 case CAPSET_TYPE_COMP_DESK:
4219 return rdp_apply_desktop_composition_capability_set(dst, src);
4220 case CAPSET_TYPE_SURFACE_COMMANDS:
4221 return rdp_apply_surface_commands_capability_set(dst, src);
4222 case CAPSET_TYPE_BITMAP_CODECS:
4223 return rdp_apply_bitmap_codecs_capability_set(dst, src);
4224 case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
4225 return rdp_apply_frame_acknowledge_capability_set(dst, src);
4226 case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID:
4227 return rdp_apply_bitmap_cache_v3_codec_id_capability_set(dst, src);
4228 case CAPSET_TYPE_BITMAP_CACHE:
4229 return rdp_apply_bitmap_cache_capability_set(dst, src);
4230 case CAPSET_TYPE_BITMAP_CACHE_V2:
4231 return rdp_apply_bitmap_cache_v2_capability_set(dst, src);
4232 case CAPSET_TYPE_BRUSH:
4233 return rdp_apply_brush_capability_set(dst, src);
4234 case CAPSET_TYPE_GLYPH_CACHE:
4235 return rdp_apply_glyph_cache_capability_set(dst, src);
4236 case CAPSET_TYPE_OFFSCREEN_CACHE:
4237 return rdp_apply_offscreen_bitmap_cache_capability_set(dst, src);
4238 case CAPSET_TYPE_SOUND:
4239 return rdp_apply_sound_capability_set(dst, src);
4240 case CAPSET_TYPE_CONTROL:
4241 return rdp_apply_control_capability_set(dst, src);
4242 case CAPSET_TYPE_ACTIVATION:
4243 return rdp_apply_window_activation_capability_set(dst, src);
4244 case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
4245 return rdp_apply_draw_nine_grid_cache_capability_set(dst, src);
4246 case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
4247 return rdp_apply_bitmap_cache_host_support_capability_set(dst, src);
4253BOOL rdp_read_capability_set(wLog* log,
wStream* sub, UINT16 type, rdpSettings* settings,
4256 WINPR_ASSERT(settings);
4258 if (type <= CAPSET_TYPE_FRAME_ACKNOWLEDGE)
4260 const size_t size = Stream_Length(sub);
4261 if (size > UINT32_MAX)
4264 WINPR_ASSERT(settings->ReceivedCapabilities);
4265 settings->ReceivedCapabilities[type] = TRUE;
4267 WINPR_ASSERT(settings->ReceivedCapabilityDataSizes);
4268 settings->ReceivedCapabilityDataSizes[type] = (UINT32)size;
4270 WINPR_ASSERT(settings->ReceivedCapabilityData);
4271 void* tmp = realloc(settings->ReceivedCapabilityData[type], size);
4272 if (!tmp && (size > 0))
4274 memcpy(tmp, Stream_Buffer(sub), size);
4275 settings->ReceivedCapabilityData[type] = tmp;
4278 WLog_Print(log, WLOG_WARN,
"not handling capability type %" PRIu16
" yet", type);
4280 BOOL treated = TRUE;
4284 case CAPSET_TYPE_GENERAL:
4285 if (!rdp_read_general_capability_set(log, sub, settings))
4290 case CAPSET_TYPE_BITMAP:
4291 if (!rdp_read_bitmap_capability_set(log, sub, settings))
4296 case CAPSET_TYPE_ORDER:
4297 if (!rdp_read_order_capability_set(log, sub, settings))
4302 case CAPSET_TYPE_POINTER:
4303 if (!rdp_read_pointer_capability_set(log, sub, settings))
4308 case CAPSET_TYPE_INPUT:
4309 if (!rdp_read_input_capability_set(log, sub, settings))
4314 case CAPSET_TYPE_VIRTUAL_CHANNEL:
4315 if (!rdp_read_virtual_channel_capability_set(log, sub, settings))
4320 case CAPSET_TYPE_SHARE:
4321 if (!rdp_read_share_capability_set(log, sub, settings))
4326 case CAPSET_TYPE_COLOR_CACHE:
4327 if (!rdp_read_color_cache_capability_set(log, sub, settings))
4332 case CAPSET_TYPE_FONT:
4333 if (!rdp_read_font_capability_set(log, sub, settings))
4338 case CAPSET_TYPE_DRAW_GDI_PLUS:
4339 if (!rdp_read_draw_gdiplus_cache_capability_set(log, sub, settings))
4344 case CAPSET_TYPE_RAIL:
4345 if (!rdp_read_remote_programs_capability_set(log, sub, settings))
4350 case CAPSET_TYPE_WINDOW:
4351 if (!rdp_read_window_list_capability_set(log, sub, settings))
4356 case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
4357 if (!rdp_read_multifragment_update_capability_set(log, sub, settings))
4362 case CAPSET_TYPE_LARGE_POINTER:
4363 if (!rdp_read_large_pointer_capability_set(log, sub, settings))
4368 case CAPSET_TYPE_COMP_DESK:
4369 if (!rdp_read_desktop_composition_capability_set(log, sub, settings))
4374 case CAPSET_TYPE_SURFACE_COMMANDS:
4375 if (!rdp_read_surface_commands_capability_set(log, sub, settings))
4380 case CAPSET_TYPE_BITMAP_CODECS:
4381 if (!rdp_read_bitmap_codecs_capability_set(log, sub, settings, isServer))
4386 case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
4387 if (!rdp_read_frame_acknowledge_capability_set(log, sub, settings))
4392 case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID:
4393 if (!rdp_read_bitmap_cache_v3_codec_id_capability_set(log, sub, settings))
4410 case CAPSET_TYPE_BITMAP_CACHE:
4411 if (!rdp_read_bitmap_cache_capability_set(log, sub, settings))
4416 case CAPSET_TYPE_BITMAP_CACHE_V2:
4417 if (!rdp_read_bitmap_cache_v2_capability_set(log, sub, settings))
4422 case CAPSET_TYPE_BRUSH:
4423 if (!rdp_read_brush_capability_set(log, sub, settings))
4428 case CAPSET_TYPE_GLYPH_CACHE:
4429 if (!rdp_read_glyph_cache_capability_set(log, sub, settings))
4434 case CAPSET_TYPE_OFFSCREEN_CACHE:
4435 if (!rdp_read_offscreen_bitmap_cache_capability_set(log, sub, settings))
4440 case CAPSET_TYPE_SOUND:
4441 if (!rdp_read_sound_capability_set(log, sub, settings))
4446 case CAPSET_TYPE_CONTROL:
4447 if (!rdp_read_control_capability_set(log, sub, settings))
4452 case CAPSET_TYPE_ACTIVATION:
4453 if (!rdp_read_window_activation_capability_set(log, sub, settings))
4458 case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
4459 if (!rdp_read_draw_nine_grid_cache_capability_set(log, sub, settings))
4465 WLog_Print(log, WLOG_ERROR,
4466 "capability %s(%" PRIu16
") not expected from client",
4467 get_capability_name(type), type);
4476 case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
4477 if (!rdp_read_bitmap_cache_host_support_capability_set(log, sub, settings))
4483 WLog_Print(log, WLOG_ERROR,
4484 "capability %s(%" PRIu16
") not expected from server",
4485 get_capability_name(type), type);
4491 const size_t rest = Stream_GetRemainingLength(sub);
4494 const size_t length = Stream_Capacity(sub);
4495 WLog_Print(log, WLOG_ERROR,
4496 "incorrect offset, type:0x%04" PRIx16
" actual:%" PRIuz
" expected:%" PRIuz
"",
4497 type, length - rest, length);
4502static BOOL rdp_read_capability_sets(wLog* log,
wStream* s, rdpSettings* settings,
4503 rdpSettings* rcvSettings, UINT16 totalLength)
4509 UINT16 numberCapabilities = 0;
4512#ifdef WITH_DEBUG_CAPABILITIES
4513 const size_t capstart = Stream_GetPosition(s);
4517 WINPR_ASSERT(settings);
4519 if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
4522 Stream_Read_UINT16(s, numberCapabilities);
4524 count = numberCapabilities;
4526 start = Stream_GetPosition(s);
4527 while (numberCapabilities > 0 && Stream_GetRemainingLength(s) >= 4)
4534 if (!rdp_read_capability_set_header(log, s, &length, &type))
4536 sub = Stream_StaticInit(&subbuffer, Stream_Pointer(s), length - 4);
4537 if (!Stream_SafeSeek(s, length - 4))
4540 if (!rdp_read_capability_set(log, sub, type, rcvSettings, settings->ServerMode))
4543 if (!rdp_apply_from_received(type, settings, rcvSettings))
4545 numberCapabilities--;
4548 end = Stream_GetPosition(s);
4551 if (numberCapabilities)
4553 WLog_Print(log, WLOG_ERROR,
4554 "strange we haven't read the number of announced capacity sets, read=%d "
4555 "expected=%" PRIu16
"",
4556 count - numberCapabilities, count);
4559#ifdef WITH_DEBUG_CAPABILITIES
4560 rdp_print_capability_sets(log, s, capstart, TRUE);
4563 if (len > totalLength)
4565 WLog_Print(log, WLOG_ERROR,
"Capability length expected %" PRIu16
", actual %" PRIdz,
4569 rc = freerdp_capability_buffer_copy(settings, rcvSettings);
4574BOOL rdp_recv_get_active_header(rdpRdp* rdp,
wStream* s, UINT16* pChannelId, UINT16* length)
4577 WINPR_ASSERT(rdp->context);
4579 if (!rdp_read_header(rdp, s, length, pChannelId))
4582 if (freerdp_shall_disconnect_context(rdp->context))
4585 if (*pChannelId != MCS_GLOBAL_CHANNEL_ID)
4587 UINT16 mcsMessageChannelId = rdp->mcs->messageChannelId;
4589 if ((mcsMessageChannelId == 0) || (*pChannelId != mcsMessageChannelId))
4591 WLog_Print(rdp->log, WLOG_ERROR,
"unexpected MCS channel id %04" PRIx16
" received",
4600BOOL rdp_recv_demand_active(rdpRdp* rdp,
wStream* s, UINT16 pduSource, UINT16 length)
4602 UINT16 lengthSourceDescriptor = 0;
4603 UINT16 lengthCombinedCapabilities = 0;
4606 WINPR_ASSERT(rdp->settings);
4607 WINPR_ASSERT(rdp->context);
4610 rdp->settings->PduSource = pduSource;
4612 if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 8))
4615 Stream_Read_UINT32(s, rdp->settings->ShareId);
4616 Stream_Read_UINT16(s, lengthSourceDescriptor);
4617 Stream_Read_UINT16(s, lengthCombinedCapabilities);
4619 if (!Stream_SafeSeek(s, lengthSourceDescriptor) ||
4620 !Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 4))
4624 if (!rdp_read_capability_sets(rdp->log, s, rdp->settings, rdp->remoteSettings,
4625 lengthCombinedCapabilities))
4627 WLog_Print(rdp->log, WLOG_ERROR,
"rdp_read_capability_sets failed");
4631 if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 4))
4636 Stream_Seek_UINT32(s);
4640 secondary->glyph_v2 = (rdp->settings->GlyphSupportLevel > GLYPH_SUPPORT_FULL);
4643 return tpkt_ensure_stream_consumed(rdp->log, s, length);
4646static BOOL rdp_write_demand_active(wLog* log,
wStream* s, rdpSettings* settings)
4651 UINT16 numberCapabilities = 0;
4652 size_t lengthCombinedCapabilities = 0;
4654 if (!Stream_EnsureRemainingCapacity(s, 64))
4657 Stream_Write_UINT32(s, settings->ShareId);
4658 Stream_Write_UINT16(s, 4);
4659 lm = Stream_GetPosition(s);
4660 Stream_Seek_UINT16(s);
4661 Stream_Write(s,
"RDP", 4);
4662 bm = Stream_GetPosition(s);
4663 Stream_Seek_UINT16(s);
4664 Stream_Write_UINT16(s, 0);
4665 numberCapabilities = 14;
4667 if (!rdp_write_general_capability_set(log, s, settings) ||
4668 !rdp_write_bitmap_capability_set(log, s, settings) ||
4669 !rdp_write_order_capability_set(log, s, settings) ||
4670 !rdp_write_pointer_capability_set(log, s, settings) ||
4671 !rdp_write_input_capability_set(log, s, settings) ||
4672 !rdp_write_virtual_channel_capability_set(log, s, settings) ||
4673 !rdp_write_share_capability_set(log, s, settings) ||
4674 !rdp_write_font_capability_set(log, s, settings) ||
4675 !rdp_write_multifragment_update_capability_set(log, s, settings) ||
4676 !rdp_write_large_pointer_capability_set(log, s, settings) ||
4677 !rdp_write_desktop_composition_capability_set(log, s, settings) ||
4678 !rdp_write_surface_commands_capability_set(log, s, settings) ||
4679 !rdp_write_bitmap_codecs_capability_set(log, s, settings) ||
4680 !rdp_write_frame_acknowledge_capability_set(log, s, settings))
4687 numberCapabilities++;
4689 if (!rdp_write_bitmap_cache_host_support_capability_set(log, s, settings))
4693 if (settings->RemoteApplicationMode)
4695 numberCapabilities += 2;
4697 if (!rdp_write_remote_programs_capability_set(log, s, settings) ||
4698 !rdp_write_window_list_capability_set(log, s, settings))
4702 em = Stream_GetPosition(s);
4703 Stream_SetPosition(s, lm);
4704 lengthCombinedCapabilities = (em - bm);
4705 if (lengthCombinedCapabilities > UINT16_MAX)
4707 Stream_Write_UINT16(
4708 s, (UINT16)lengthCombinedCapabilities);
4709 Stream_SetPosition(s, bm);
4710 Stream_Write_UINT16(s, numberCapabilities);
4711#ifdef WITH_DEBUG_CAPABILITIES
4712 rdp_print_capability_sets(log, s, bm, FALSE);
4714 Stream_SetPosition(s, em);
4715 Stream_Write_UINT32(s, 0);
4719BOOL rdp_send_demand_active(rdpRdp* rdp)
4721 UINT16 sec_flags = 0;
4722 wStream* s = rdp_send_stream_pdu_init(rdp, &sec_flags);
4728 rdp->settings->ShareId = 0x10000 + rdp->mcs->userId;
4729 status = rdp_write_demand_active(rdp->log, s, rdp->settings) &&
4730 rdp_send_pdu(rdp, s, PDU_TYPE_DEMAND_ACTIVE, rdp->mcs->userId, sec_flags);
4735BOOL rdp_recv_confirm_active(rdpRdp* rdp,
wStream* s, UINT16 pduLength)
4737 rdpSettings* settings = NULL;
4738 UINT16 lengthSourceDescriptor = 0;
4739 UINT16 lengthCombinedCapabilities = 0;
4743 settings = rdp->settings;
4744 WINPR_ASSERT(settings);
4746 if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 10))
4749 Stream_Seek_UINT32(s);
4750 Stream_Seek_UINT16(s);
4751 Stream_Read_UINT16(s, lengthSourceDescriptor);
4752 Stream_Read_UINT16(s, lengthCombinedCapabilities);
4754 if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, lengthSourceDescriptor + 4U))
4757 Stream_Seek(s, lengthSourceDescriptor);
4758 if (!rdp_read_capability_sets(rdp->log, s, rdp->settings, rdp->remoteSettings,
4759 lengthCombinedCapabilities))
4762 if (!settings->ReceivedCapabilities[CAPSET_TYPE_SURFACE_COMMANDS])
4765 settings->SurfaceCommandsEnabled = FALSE;
4766 settings->SurfaceFrameMarkerEnabled = FALSE;
4769 if (!settings->ReceivedCapabilities[CAPSET_TYPE_FRAME_ACKNOWLEDGE])
4772 settings->FrameAcknowledge = 0;
4775 if (!settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID])
4778 settings->BitmapCacheV3Enabled = FALSE;
4781 if (!settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CODECS])
4792 if (!settings->ReceivedCapabilities[CAPSET_TYPE_MULTI_FRAGMENT_UPDATE])
4795 settings->MultifragMaxRequestSize = FASTPATH_FRAGMENT_SAFE_SIZE;
4798 if (!settings->ReceivedCapabilities[CAPSET_TYPE_LARGE_POINTER])
4801 settings->LargePointerFlag = 0;
4804 return tpkt_ensure_stream_consumed(rdp->log, s, pduLength);
4807static BOOL rdp_write_confirm_active(wLog* log,
wStream* s, rdpSettings* settings)
4812 UINT16 numberCapabilities = 0;
4813 UINT16 lengthSourceDescriptor = 0;
4814 size_t lengthCombinedCapabilities = 0;
4817 WINPR_ASSERT(settings);
4819 lengthSourceDescriptor =
sizeof(SOURCE_DESCRIPTOR);
4820 Stream_Write_UINT32(s, settings->ShareId);
4821 Stream_Write_UINT16(s, 0x03EA);
4822 Stream_Write_UINT16(s, lengthSourceDescriptor);
4823 lm = Stream_GetPosition(s);
4824 Stream_Seek_UINT16(s);
4825 Stream_Write(s, SOURCE_DESCRIPTOR, lengthSourceDescriptor);
4826 bm = Stream_GetPosition(s);
4827 Stream_Seek_UINT16(s);
4828 Stream_Write_UINT16(s, 0);
4830 numberCapabilities = 15;
4832 if (!rdp_write_general_capability_set(log, s, settings) ||
4833 !rdp_write_bitmap_capability_set(log, s, settings) ||
4834 !rdp_write_order_capability_set(log, s, settings))
4837 if (settings->RdpVersion >= RDP_VERSION_5_PLUS)
4838 ret = rdp_write_bitmap_cache_v2_capability_set(log, s, settings);
4840 ret = rdp_write_bitmap_cache_capability_set(log, s, settings);
4845 if (!rdp_write_pointer_capability_set(log, s, settings) ||
4846 !rdp_write_input_capability_set(log, s, settings) ||
4847 !rdp_write_brush_capability_set(log, s, settings) ||
4848 !rdp_write_glyph_cache_capability_set(log, s, settings) ||
4849 !rdp_write_virtual_channel_capability_set(log, s, settings) ||
4850 !rdp_write_sound_capability_set(log, s, settings) ||
4851 !rdp_write_share_capability_set(log, s, settings) ||
4852 !rdp_write_font_capability_set(log, s, settings) ||
4853 !rdp_write_control_capability_set(log, s, settings) ||
4854 !rdp_write_color_cache_capability_set(log, s, settings) ||
4855 !rdp_write_window_activation_capability_set(log, s, settings))
4860 if (settings->OffscreenSupportLevel)
4862 numberCapabilities++;
4864 if (!rdp_write_offscreen_bitmap_cache_capability_set(log, s, settings))
4868 if (settings->DrawNineGridEnabled)
4870 numberCapabilities++;
4872 if (!rdp_write_draw_nine_grid_cache_capability_set(log, s, settings))
4876 if (settings->ReceivedCapabilities[CAPSET_TYPE_LARGE_POINTER])
4878 if (settings->LargePointerFlag)
4880 numberCapabilities++;
4882 if (!rdp_write_large_pointer_capability_set(log, s, settings))
4887 if (settings->RemoteApplicationMode)
4889 numberCapabilities += 2;
4891 if (!rdp_write_remote_programs_capability_set(log, s, settings) ||
4892 !rdp_write_window_list_capability_set(log, s, settings))
4896 if (settings->ReceivedCapabilities[CAPSET_TYPE_MULTI_FRAGMENT_UPDATE])
4898 numberCapabilities++;
4900 if (!rdp_write_multifragment_update_capability_set(log, s, settings))
4904 if (settings->ReceivedCapabilities[CAPSET_TYPE_SURFACE_COMMANDS])
4906 numberCapabilities++;
4908 if (!rdp_write_surface_commands_capability_set(log, s, settings))
4912 if (settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CODECS])
4914 numberCapabilities++;
4916 if (!rdp_write_bitmap_codecs_capability_set(log, s, settings))
4920 if (!settings->ReceivedCapabilities[CAPSET_TYPE_FRAME_ACKNOWLEDGE])
4921 settings->FrameAcknowledge = 0;
4923 if (settings->FrameAcknowledge)
4925 numberCapabilities++;
4927 if (!rdp_write_frame_acknowledge_capability_set(log, s, settings))
4931 if (settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID])
4933 if (settings->BitmapCacheV3CodecId != 0)
4935 numberCapabilities++;
4937 if (!rdp_write_bitmap_cache_v3_codec_id_capability_set(log, s, settings))
4942 em = Stream_GetPosition(s);
4943 Stream_SetPosition(s, lm);
4944 lengthCombinedCapabilities = (em - bm);
4945 if (lengthCombinedCapabilities > UINT16_MAX)
4947 Stream_Write_UINT16(
4948 s, (UINT16)lengthCombinedCapabilities);
4949 Stream_SetPosition(s, bm);
4950 Stream_Write_UINT16(s, numberCapabilities);
4951#ifdef WITH_DEBUG_CAPABILITIES
4952 rdp_print_capability_sets(log, s, bm, FALSE);
4954 Stream_SetPosition(s, em);
4959BOOL rdp_send_confirm_active(rdpRdp* rdp)
4961 UINT16 sec_flags = 0;
4962 wStream* s = rdp_send_stream_pdu_init(rdp, &sec_flags);
4968 status = rdp_write_confirm_active(rdp->log, s, rdp->settings) &&
4969 rdp_send_pdu(rdp, s, PDU_TYPE_CONFIRM_ACTIVE, rdp->mcs->userId, sec_flags);
4974const char* rdp_input_flag_string(UINT16 flags,
char* buffer,
size_t len)
4976 char prefix[16] = { 0 };
4978 (void)_snprintf(prefix,
sizeof(prefix),
"[0x%04" PRIx16
"][", flags);
4979 winpr_str_append(prefix, buffer, len,
"");
4980 if ((flags & INPUT_FLAG_SCANCODES) != 0)
4981 winpr_str_append(
"INPUT_FLAG_SCANCODES", buffer, len,
"|");
4982 if ((flags & INPUT_FLAG_MOUSEX) != 0)
4983 winpr_str_append(
"INPUT_FLAG_MOUSEX", buffer, len,
"|");
4984 if ((flags & INPUT_FLAG_FASTPATH_INPUT) != 0)
4985 winpr_str_append(
"INPUT_FLAG_FASTPATH_INPUT", buffer, len,
"|");
4986 if ((flags & INPUT_FLAG_UNICODE) != 0)
4987 winpr_str_append(
"INPUT_FLAG_UNICODE", buffer, len,
"|");
4988 if ((flags & INPUT_FLAG_FASTPATH_INPUT2) != 0)
4989 winpr_str_append(
"INPUT_FLAG_FASTPATH_INPUT2", buffer, len,
"|");
4990 if ((flags & INPUT_FLAG_UNUSED1) != 0)
4991 winpr_str_append(
"INPUT_FLAG_UNUSED1", buffer, len,
"|");
4992 if ((flags & INPUT_FLAG_MOUSE_RELATIVE) != 0)
4993 winpr_str_append(
"INPUT_FLAG_MOUSE_RELATIVE", buffer, len,
"|");
4994 if ((flags & TS_INPUT_FLAG_MOUSE_HWHEEL) != 0)
4995 winpr_str_append(
"TS_INPUT_FLAG_MOUSE_HWHEEL", buffer, len,
"|");
4996 if ((flags & TS_INPUT_FLAG_QOE_TIMESTAMPS) != 0)
4997 winpr_str_append(
"TS_INPUT_FLAG_QOE_TIMESTAMPS", buffer, len,
"|");
4998 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.